IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.7KB

  1. #
  2. # Copyright (C) Stanislaw Adaszewski, 2020
  3. # License: GNU General Public License v3.0
  4. # URL: https://github.com/sadaszewski/focker
  5. # URL: https://adared.ch/focker
  6. #
  7. import os
  8. import yaml
  9. from .zfs import AmbiguousValueError, \
  10. zfs_find, \
  11. zfs_tag, \
  12. zfs_untag, \
  13. zfs_mountpoint, \
  14. zfs_poolname, \
  15. zfs_set_props
  16. from .jail import jail_fs_create, \
  17. jail_create, \
  18. jail_remove, \
  19. backup_file
  20. from .misc import random_sha256_hexdigest, \
  21. find_prefix
  22. import subprocess
  23. import jailconf
  24. import os
  25. from .misc import focker_lock, \
  26. focker_unlock
  27. def build_volumes(spec):
  28. poolname = zfs_poolname()
  29. for tag, params in spec.items():
  30. name = None
  31. try:
  32. name, _ = zfs_find(tag, focker_type='volume')
  33. except ValueError:
  34. pass
  35. if name is None:
  36. sha256 = random_sha256_hexdigest()
  37. name = find_prefix(poolname + '/focker/volumes/', sha256)
  38. subprocess.check_output(['zfs', 'create', '-o', 'focker:sha256=' + sha256, name])
  39. zfs_untag([ tag ], focker_type='volume')
  40. zfs_tag(name, [ tag ])
  41. mountpoint = zfs_mountpoint(name)
  42. print('params:', params)
  43. if 'chown' in params:
  44. os.chown(mountpoint, *map(int, params['chown'].split(':')))
  45. if 'chmod' in params:
  46. os.chmod(mountpoint, params['chmod'])
  47. if 'zfs' in params:
  48. zfs_set_props(name, params['zfs'])
  49. def build_images(spec, path, args):
  50. # print('build_images(): NotImplementedError')
  51. for (tag, focker_dir) in spec.items():
  52. cmd = ['focker', 'image', 'build',
  53. os.path.join(path, focker_dir), '-t', tag]
  54. if args.squeeze:
  55. cmd.append('--squeeze')
  56. focker_unlock()
  57. res = subprocess.run(cmd)
  58. focker_lock()
  59. if res.returncode != 0:
  60. raise RuntimeError('Image build failed: ' + str(res.returncode))
  61. def build_jails(spec):
  62. #if os.path.exists('/etc/jail.conf'):
  63. # conf = jailconf.load('/etc/jail.conf')
  64. #else:
  65. # conf = jailconf.JailConf()
  66. backup_file('/etc/jail.conf')
  67. for (jailname, jailspec) in spec.items():
  68. try:
  69. name, _ = zfs_find(jailname, focker_type='jail')
  70. jail_remove(zfs_mountpoint(name))
  71. except AmbiguousValueError:
  72. raise
  73. except ValueError:
  74. pass
  75. name = jail_fs_create(jailspec['image'])
  76. zfs_untag([ jailname ], focker_type='jail')
  77. zfs_tag(name, [ jailname ])
  78. path = zfs_mountpoint(name)
  79. jail_create(path,
  80. jailspec.get('exec.start', '/bin/sh /etc/rc'),
  81. jailspec.get('env', {}),
  82. [ [from_, on] \
  83. for (from_, on) in jailspec.get('mounts', {}).items() ],
  84. hostname=jailname,
  85. overrides={
  86. 'exec.stop': jailspec.get('exec.stop', '/bin/sh /etc/rc.shutdown'),
  87. 'ip4.addr': jailspec.get('ip4.addr', '127.0.1.0'),
  88. 'interface': jailspec.get('interface', 'lo1')
  89. })
  90. def command_compose_build(args):
  91. if not os.path.exists(args.filename):
  92. raise ValueError('File not found: ' + args.filename)
  93. path, _ = os.path.split(args.filename)
  94. print('path:', path)
  95. with open(args.filename, 'r') as f:
  96. spec = yaml.safe_load(f)
  97. if 'volumes' in spec:
  98. build_volumes(spec['volumes'])
  99. if 'images' in spec:
  100. build_images(spec['images'], path, args)
  101. if 'jails' in spec:
  102. build_jails(spec['jails'])
  103. def command_compose_run(args):
  104. raise NotImplementedError