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!
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.6KB

  1. import subprocess
  2. from .zfs import *
  3. import random
  4. import shutil
  5. import json
  6. from tabulate import tabulate
  7. def get_jid(path):
  8. data = json.loads(subprocess.check_output(['jls', '--libxo=json']))
  9. lst = data['jail-information']['jail']
  10. lst = list(filter(lambda a: a['path'] == path, lst))
  11. if len(lst) == 0:
  12. raise ValueError('JID not found for path: ' + path)
  13. if len(lst) > 1:
  14. raise ValueError('Ambiguous JID for path: ' + path)
  15. return str(lst[0]['jid'])
  16. def do_mounts(path, mounts):
  17. print('mounts:', mounts)
  18. for (source, target) in mounts:
  19. if source.startswith('/'):
  20. name = source
  21. else:
  22. name, _ = zfs_find(source, focker_type='volume')
  23. name = zfs_mountpoint(name)
  24. while target.startswith('/'):
  25. target = target[1:]
  26. subprocess.check_output(['mount', '-t', 'nullfs', name, os.path.join(path, target)])
  27. def undo_mounts(path, mounts):
  28. for (_, target) in reversed(mounts):
  29. while target.startswith('/'):
  30. target = target[1:]
  31. subprocess.check_output(['umount', '-f', os.path.join(path, target)])
  32. def jail_run(path, command, mounts=[]):
  33. command = ['jail', '-c', 'host.hostname=' + os.path.split(path)[1], 'persist=1', 'mount.devfs=1', 'interface=lo1', 'ip4.addr=127.0.1.0', 'path=' + path, 'command', '/bin/sh', '-c', command]
  34. print('Running:', ' '.join(command))
  35. try:
  36. do_mounts(path, mounts)
  37. shutil.copyfile('/etc/resolv.conf', os.path.join(path, 'etc/resolv.conf'))
  38. res = subprocess.run(command)
  39. finally:
  40. try:
  41. subprocess.run(['jail', '-r', get_jid(path)])
  42. except ValueError:
  43. pass
  44. subprocess.run(['umount', '-f', os.path.join(path, 'dev')])
  45. undo_mounts(path, mounts)
  46. if res.returncode != 0:
  47. # subprocess.run(['umount', os.path.join(path, 'dev')])
  48. raise RuntimeError('Command failed')
  49. def command_jail_run(args):
  50. base, _ = zfs_snapshot_by_tag_or_sha256(args.image)
  51. # root = '/'.join(base.split('/')[:-1])
  52. for _ in range(10**6):
  53. sha256 = bytes([ random.randint(0, 255) for _ in range(32) ]).hex()
  54. name = sha256[:7]
  55. name = base.split('/')[0] + '/focker/jails/' + name
  56. if not zfs_exists(name):
  57. break
  58. zfs_run(['zfs', 'clone', '-o', 'focker:sha256=' + sha256, base, name])
  59. try:
  60. mounts = list(map(lambda a: a.split(':'), args.mounts))
  61. jail_run(zfs_mountpoint(name), args.command, mounts)
  62. # subprocess.check_output(['jail', '-c', 'interface=lo1', 'ip4.addr=127.0.1.0', 'path=' + zfs_mountpoint(name), 'command', command])
  63. finally:
  64. # subprocess.run(['umount', zfs_mountpoint(name) + '/dev'])
  65. zfs_run(['zfs', 'destroy', '-f', name])
  66. # raise
  67. def command_jail_list(args):
  68. lst = zfs_list(fields=['focker:sha256,focker:tags,mountpoint'], focker_type='jail')
  69. jails = subprocess.check_output(['jls', '--libxo=json'])
  70. jails = json.loads(jails)['jail-information']['jail']
  71. jails = { j['path']: j for j in jails }
  72. lst = list(map(lambda a: [ a[1],
  73. a[0] if args.full_sha256 else a[0][:7],
  74. a[2],
  75. jails[a[2]]['jid'] if a[2] in jails else '-' ], lst))
  76. print(tabulate(lst, headers=['Tags', 'SHA256', 'mountpoint', 'JID']))
  77. def command_jail_tag(args):
  78. name, _ = zfs_find(args.reference, focker_type='jail')
  79. zfs_untag(args.tags, focker_type='jail')
  80. zfs_tag(name, args.tags)
  81. def command_jail_untag(args):
  82. zfs_untag(args.tags, focker_type='jail')