diff --git a/focker.py b/focker.py index a32ccf9..c9c477c 100644 --- a/focker.py +++ b/focker.py @@ -15,7 +15,8 @@ from .volume import command_volume_create, \ command_volume_untag import sys from .zfs import zfs_init -from .jail import command_jail_run +from .jail import command_jail_run, \ + command_jail_list def create_parser(): @@ -59,6 +60,10 @@ def create_parser(): parser.add_argument('--command', '-c', type=str, default='/bin/sh') parser.add_argument('--mounts', '-m', type=str, nargs='+', default=[]) + parser = subparsers.add_parser('list') + parser.set_defaults(func=command_jail_list) + parser.add_argument('--full-sha256', '-f', action='store_true') + # volume subparsers = subparsers_top.add_parser('volume').add_subparsers() parser = subparsers.add_parser('create') diff --git a/jail.py b/jail.py index f6b33ec..77a89d0 100644 --- a/jail.py +++ b/jail.py @@ -3,6 +3,7 @@ from .zfs import * import random import shutil import json +from tabulate import tabulate def get_jid(path): @@ -59,11 +60,12 @@ def command_jail_run(args): base, _ = zfs_snapshot_by_tag_or_sha256(args.image) # root = '/'.join(base.split('/')[:-1]) for _ in range(10**6): - name = bytes([ random.randint(0, 255) for _ in range(4) ]).hex()[:7] + sha256 = bytes([ random.randint(0, 255) for _ in range(32) ]).hex() + name = sha256[:7] name = base.split('/')[0] + '/focker/jails/' + name if not zfs_exists(name): break - zfs_run(['zfs', 'clone', base, name]) + zfs_run(['zfs', 'clone', '-o', 'focker:sha256=' + sha256, base, name]) try: mounts = list(map(lambda a: a.split(':'), args.mounts)) jail_run(zfs_mountpoint(name), args.command, mounts) @@ -72,3 +74,14 @@ def command_jail_run(args): # subprocess.run(['umount', zfs_mountpoint(name) + '/dev']) zfs_run(['zfs', 'destroy', '-f', name]) # raise + +def command_jail_list(args): + lst = zfs_list(fields=['focker:sha256,focker:tags,mountpoint'], focker_type='jail') + jails = subprocess.check_output(['jls', '--libxo=json']) + jails = json.loads(jails)['jail-information']['jail'] + jails = { j['path']: j for j in jails } + lst = list(map(lambda a: [ a[1], + a[0] if args.full_sha256 else a[0][:7], + a[2], + jails[a[2]]['jid'] if a[2] in jails else '-' ], lst)) + print(tabulate(lst, headers=['Tags', 'SHA256', 'mountpoint', 'JID'])) diff --git a/zfs.py b/zfs.py index f60d3fa..a34401c 100644 --- a/zfs.py +++ b/zfs.py @@ -49,6 +49,15 @@ def zfs_find(reference, focker_type='image', zfs_type='filesystem'): return (lst[0][3], lst[0][0]) +def zfs_list(fields=['name'], focker_type='image', zfs_type='filesystem'): + poolname = zfs_poolname() + fields.append('focker:sha256') + lst = zfs_parse_output(['zfs', 'list', '-o', ','.join(fields), + '-H', '-t', zfs_type, '-r', poolname + '/focker/' + focker_type + 's']) + lst = list(filter(lambda a: a[-1] != '-', lst)) + return lst + + def zfs_prune(focker_type='image'): poolname = zfs_poolname() again = True