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トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

139 行
4.7KB

  1. import subprocess
  2. import csv
  3. import io
  4. import os
  5. def zfs_run(command):
  6. # print('Running:', command)
  7. out = subprocess.check_output(command, stderr=subprocess.STDOUT)
  8. return out
  9. def zfs_parse_output(command):
  10. out = zfs_run(command)
  11. s = io.StringIO(out.decode('utf-8'))
  12. r = csv.reader(s, delimiter='\t')
  13. return [a for a in r]
  14. def zfs_get_type(name):
  15. lst = zfs_parse_output(['zfs', 'list', '-o', 'name,type', '-H', name])
  16. return lst[0][1]
  17. def zfs_snapshot_by_tag_or_sha256(s):
  18. lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,type,name', '-H', '-t', 'snapshot'])
  19. lst = list(filter(lambda a: (a[0] == s or s in a[1].split(' ')) and a[2] == 'snapshot', lst))
  20. if len(lst) == 0:
  21. raise ValueError('Reference not found: ' + s)
  22. if len(lst) > 1:
  23. raise ValueError('Ambiguous reference: ' + s)
  24. return (lst[0][3], lst[0][0])
  25. def zfs_find(reference, focker_type='image', zfs_type='filesystem'):
  26. poolname = zfs_poolname()
  27. lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,type,name', '-H', '-t', zfs_type, '-r', poolname + '/focker/' + focker_type + 's'])
  28. def match(sha256, tags, type, name):
  29. if sha256.startswith(reference) or \
  30. any(map(lambda a: a.startswith(reference), tags.split(' '))) or \
  31. name.split('/')[-1].startswith(reference):
  32. return True
  33. return False
  34. lst = list(filter(lambda a: match(*a), lst))
  35. if len(lst) == 0:
  36. raise ValueError('Reference not found: ' + reference)
  37. if len(lst) > 1:
  38. raise ValueError('Ambiguous reference: ' + reference)
  39. return (lst[0][3], lst[0][0])
  40. def zfs_clone(name, target_name):
  41. zfs_run(['zfs', 'clone', name, target_name])
  42. def zfs_exists(name):
  43. try:
  44. zfs_run(['zfs', 'list', name])
  45. except subprocess.CalledProcessError as e:
  46. return False
  47. return True
  48. def zfs_set_props(name, props):
  49. for (k, v) in props.items():
  50. zfs_run(['zfs', 'set', k + '=' + v, name])
  51. def zfs_mountpoint(name):
  52. lst = zfs_parse_output(['zfs', 'list', '-o', 'mountpoint', '-H', name])
  53. return lst[0][0]
  54. def zfs_exists_snapshot_sha256(sha256):
  55. lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256', '-t', 'snap'])
  56. lst = list(filter(lambda a: a[0] == sha256, lst))
  57. if len(lst) == 0:
  58. return False
  59. return True
  60. def zfs_snapshot_by_sha256(sha256):
  61. lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,name', '-t', 'snap', '-H'])
  62. lst = list(filter(lambda a: a[0] == sha256, lst))
  63. if len(lst) == 0:
  64. raise ValueError('Snapshot with given sha256 does not exist: ' + sha256)
  65. if len(lst) > 1:
  66. raise ValueError('Ambiguous snapshot sha256: ' + sha256)
  67. return lst[0][1]
  68. def zfs_tag(name, tags, replace=False):
  69. lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:tags', '-H', name])
  70. if not replace:
  71. tags = list(tags)
  72. tags.extend(lst[0][0].split(' '))
  73. tags = list(set(tags))
  74. tags = list(filter(lambda a: a != '-', tags))
  75. if len(tags) > 0:
  76. zfs_run(['zfs', 'set', 'focker:tags=' + ' '.join(tags), name])
  77. else:
  78. zfs_run(['zfs', 'inherit', 'focker:tags', name])
  79. def zfs_untag(tags):
  80. # print('zfs_untag(), tags:', tags)
  81. lst = zfs_parse_output(['zfs', 'list', '-o', 'name,focker:tags', '-H'])
  82. lst = filter(lambda a: any([b in a[1].split(' ') for b in tags]), lst)
  83. for row in lst:
  84. cur_tags = row[1].split(' ')
  85. for t in tags:
  86. if t in cur_tags:
  87. cur_tags.remove(t)
  88. zfs_tag(row[0], cur_tags, replace=True)
  89. def zfs_poolname():
  90. poolname = zfs_parse_output(['zfs', 'list', '-H', '/'])
  91. if len(poolname) == 0:
  92. raise ValueError('Not a ZFS root')
  93. poolname = poolname[0][0].split('/')[0]
  94. return poolname
  95. def zfs_init():
  96. poolname = zfs_poolname()
  97. print('poolname:', poolname)
  98. for path in ['/focker', '/focker/images', '/focker/volumes', '/focker/jails']:
  99. if not os.path.exists(path):
  100. os.mkdir(path)
  101. if not zfs_exists(poolname + '/focker'):
  102. zfs_run(['zfs', 'create', '-o', 'canmount=off', '-o', 'mountpoint=/focker', poolname + '/focker'])
  103. if not zfs_exists(poolname + '/focker/images'):
  104. zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/images'])
  105. if not zfs_exists(poolname + '/focker/volumes'):
  106. zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/volumes'])
  107. if not zfs_exists(poolname + '/focker/jails'):
  108. zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/jails'])