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.

100 lines
3.1KB

  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. from .jail import jail_fs_create, \
  16. jail_create, \
  17. jail_remove
  18. from .misc import random_sha256_hexdigest, \
  19. find_prefix
  20. import subprocess
  21. import jailconf
  22. import os
  23. def build_volumes(spec):
  24. poolname = zfs_poolname()
  25. for tag in spec.keys():
  26. try:
  27. name, _ = zfs_find(tag, focker_type='volume')
  28. continue
  29. except AmbiguousValueError:
  30. raise
  31. except ValueError:
  32. pass
  33. sha256 = random_sha256_hexdigest()
  34. name = find_prefix(poolname + '/focker/volumes/', sha256)
  35. subprocess.check_output(['zfs', 'create', '-o', 'focker:sha256=' + sha256, name])
  36. zfs_untag([ tag ], focker_type='volume')
  37. zfs_tag(name, [ tag ])
  38. def build_images(spec, path):
  39. # print('build_images(): NotImplementedError')
  40. for (tag, focker_dir) in spec.items():
  41. res = subprocess.run(['focker', 'image', 'build',
  42. os.path.join(path, focker_dir), '-t', tag])
  43. if res.returncode != 0:
  44. raise RuntimeError('Image build failed: ' + str(res.returncode))
  45. def build_jails(spec):
  46. #if os.path.exists('/etc/jail.conf'):
  47. # conf = jailconf.load('/etc/jail.conf')
  48. #else:
  49. # conf = jailconf.JailConf()
  50. for (jailname, jailspec) in spec.items():
  51. try:
  52. name, _ = zfs_find(jailname, focker_type='jail')
  53. jail_remove(zfs_mountpoint(name))
  54. except AmbiguousValueError:
  55. raise
  56. except ValueError:
  57. pass
  58. name = jail_fs_create(jailspec['image'])
  59. zfs_untag([ jailname ], focker_type='jail')
  60. zfs_tag(name, [ jailname ])
  61. path = zfs_mountpoint(name)
  62. jail_create(path,
  63. jailspec.get('exec.start', '/bin/sh /etc/rc'),
  64. jailspec.get('env', {}),
  65. [ [from_, on] \
  66. for (from_, on) in jailspec.get('mounts', {}).items() ],
  67. hostname=jailname,
  68. overrides={
  69. 'exec.stop': jailspec.get('exec.stop', '/bin/sh /etc/rc.shutdown'),
  70. 'ip4.addr': jailspec.get('ip4.addr', '127.0.1.0'),
  71. 'interface': jailspec.get('interface', 'lo1')
  72. })
  73. def command_compose_build(args):
  74. if not os.path.exists(args.filename):
  75. raise ValueError('File not found: ' + args.filename)
  76. path, _ = os.path.split(args.filename)
  77. print('path:', path)
  78. with open(args.filename, 'r') as f:
  79. spec = yaml.safe_load(f)
  80. if 'volumes' in spec:
  81. build_volumes(spec['volumes'])
  82. if 'images' in spec:
  83. build_images(spec['images'], path)
  84. if 'jails' in spec:
  85. build_jails(spec['jails'])
  86. def command_compose_run(args):
  87. raise NotImplementedError