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.

131 lines
4.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. from .zfs import *
  8. import os
  9. import yaml
  10. from .steps import create_step
  11. from .snapshot import new_snapshot
  12. from tabulate import tabulate
  13. import subprocess
  14. def build(spec, args):
  15. if 'base' not in spec:
  16. raise ValueError('Missing base in specification')
  17. if 'steps' not in spec:
  18. raise ValueError('Missing steps in specification')
  19. base = spec['base']
  20. base, base_sha256 = zfs_find(base, focker_type='image', zfs_type='snapshot')
  21. root = '/'.join(base.split('/')[:-1])
  22. print('base:', base, 'root:', root)
  23. steps = spec['steps']
  24. if not isinstance(steps, list):
  25. steps = [ steps ]
  26. for st in steps:
  27. st = create_step(st)
  28. st_sha256 = st.hash(base_sha256, args=args)
  29. if zfs_exists_snapshot_sha256(st_sha256):
  30. base = zfs_snapshot_by_sha256(st_sha256)
  31. base_sha256 = st_sha256
  32. print('Reusing:', base)
  33. continue
  34. for pre in range(7, 64):
  35. name = root + '/' + st_sha256[:pre]
  36. if not zfs_exists(name):
  37. break
  38. feed = {
  39. 'focker:sha256': st_sha256
  40. }
  41. def atomic():
  42. st.execute(zfs_mountpoint(name), args=args)
  43. zfs_set_props(name, feed)
  44. snap_name = new_snapshot(base, atomic, name)
  45. # zfs_set_props(name, feed)
  46. # zfs_set_props(snap_name, feed)
  47. base = snap_name
  48. base_sha256 = st_sha256
  49. return (base, base_sha256)
  50. def command_image_build(args):
  51. # os.chdir(args.focker_dir)
  52. fname = os.path.join(args.focker_dir, 'Fockerfile')
  53. print('fname:', fname)
  54. if not os.path.exists(fname):
  55. raise ValueError('No Fockerfile could be found in the specified directory')
  56. with open(fname, 'r') as f:
  57. spec = yaml.safe_load(f)
  58. print('spec:', spec)
  59. image, image_sha256 = build(spec, args)
  60. zfs_untag(args.tags)
  61. zfs_tag(image.split('@')[0], args.tags)
  62. def command_image_tag(args):
  63. zfs_untag(args.tags, focker_type='image')
  64. name, _ = zfs_find(args.reference, focker_type='image', zfs_type='filesystem')
  65. zfs_tag(name, args.tags)
  66. def command_image_untag(args):
  67. zfs_untag(args.tags, focker_type='image')
  68. def command_image_list(args):
  69. lst = zfs_list(fields=['name', 'refer', 'focker:sha256', 'focker:tags', 'origin'],
  70. focker_type='image')
  71. # zfs_parse_output(['zfs', 'list', '-o', 'name,refer,focker:sha256,focker:tags,origin', '-H'])
  72. lst = list(filter(lambda a: a[2] != '-', lst))
  73. lst = list(map(lambda a: [ a[3], a[1],
  74. a[2] if args.full_sha256 else a[2][:7],
  75. a[4].split('/')[-1].split('@')[0] ], lst))
  76. print(tabulate(lst, headers=['Tags', 'Size', 'SHA256', 'Base']))
  77. def command_image_prune(args):
  78. poolname = zfs_poolname()
  79. again = True
  80. while again:
  81. again = False
  82. lst = zfs_list(fields=['focker:sha256', 'focker:tags', 'origin', 'name'],
  83. focker_type='image')
  84. # lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,origin,name', '-H', '-r', poolname + '/focker/images'])
  85. used = set()
  86. for r in lst:
  87. if r[2] == '-':
  88. continue
  89. used.add(r[2].split('@')[0])
  90. for r in lst:
  91. if r[0] == '-' or r[1] != '-':
  92. continue
  93. if r[3] not in used:
  94. print('Removing:', r[3])
  95. zfs_run(['zfs', 'destroy', '-r', '-f', r[3]])
  96. again = True
  97. # zfs_parse_output(['zfs'])
  98. def command_image_remove(args):
  99. snap, snap_sha256 = zfs_find(args.reference, focker_type='image',
  100. zfs_type='snapshot')
  101. ds = snap.split('@')[0]
  102. command = ['zfs', 'destroy', '-r', '-f']
  103. #if args.remove_children:
  104. # command.append('-r')
  105. if args.remove_dependents:
  106. command.append('-R')
  107. command.append(ds)
  108. subprocess.run(command)
  109. # zfs_run(['zfs', 'destroy', ds])