From 156dcfffce910034b689e813900543121678f7ca Mon Sep 17 00:00:00 2001 From: Stanislaw Adaszewski Date: Fri, 24 Apr 2020 23:36:25 +0200 Subject: [PATCH] Added ability to mount volumes in focker jail run --- focker.py | 1 + jail.py | 27 +++++++++++++++++++++++++-- volume.py | 7 ++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/focker.py b/focker.py index e061106..a32ccf9 100644 --- a/focker.py +++ b/focker.py @@ -57,6 +57,7 @@ def create_parser(): parser.set_defaults(func=command_jail_run) parser.add_argument('image', type=str) parser.add_argument('--command', '-c', type=str, default='/bin/sh') + parser.add_argument('--mounts', '-m', type=str, nargs='+', default=[]) # volume subparsers = subparsers_top.add_parser('volume').add_subparsers() diff --git a/jail.py b/jail.py index a24bb2e..f6b33ec 100644 --- a/jail.py +++ b/jail.py @@ -16,10 +16,31 @@ def get_jid(path): return str(lst[0]['jid']) -def jail_run(path, command): +def do_mounts(path, mounts): + print('mounts:', mounts) + for (source, target) in mounts: + if source.startswith('/'): + name = source + else: + name, _ = zfs_find(source, focker_type='volume') + name = zfs_mountpoint(name) + while target.startswith('/'): + target = target[1:] + subprocess.check_output(['mount', '-t', 'nullfs', name, os.path.join(path, target)]) + + +def undo_mounts(path, mounts): + for (_, target) in reversed(mounts): + while target.startswith('/'): + target = target[1:] + subprocess.check_output(['umount', '-f', os.path.join(path, target)]) + + +def jail_run(path, command, mounts=[]): 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] print('Running:', ' '.join(command)) try: + do_mounts(path, mounts) shutil.copyfile('/etc/resolv.conf', os.path.join(path, 'etc/resolv.conf')) res = subprocess.run(command) finally: @@ -28,6 +49,7 @@ def jail_run(path, command): except ValueError: pass subprocess.run(['umount', '-f', os.path.join(path, 'dev')]) + undo_mounts(path, mounts) if res.returncode != 0: # subprocess.run(['umount', os.path.join(path, 'dev')]) raise RuntimeError('Command failed') @@ -43,7 +65,8 @@ def command_jail_run(args): break zfs_run(['zfs', 'clone', base, name]) try: - jail_run(zfs_mountpoint(name), args.command) + mounts = list(map(lambda a: a.split(':'), args.mounts)) + jail_run(zfs_mountpoint(name), args.command, mounts) # subprocess.check_output(['jail', '-c', 'interface=lo1', 'ip4.addr=127.0.1.0', 'path=' + zfs_mountpoint(name), 'command', command]) finally: # subprocess.run(['umount', zfs_mountpoint(name) + '/dev']) diff --git a/volume.py b/volume.py index a11e5ed..c64082a 100644 --- a/volume.py +++ b/volume.py @@ -20,11 +20,12 @@ def command_volume_prune(args): def command_volume_list(args): poolname = zfs_poolname() - lst = zfs_parse_output(['zfs', 'list', '-o', 'name,refer,focker:sha256,focker:tags', '-H', '-r', poolname + '/focker/volumes']) + lst = zfs_parse_output(['zfs', 'list', '-o', 'name,refer,focker:sha256,focker:tags,mountpoint', '-H', '-r', poolname + '/focker/volumes']) lst = list(filter(lambda a: a[2] != '-', lst)) lst = list(map(lambda a: [ a[3], a[1], - a[2] if args.full_sha256 else a[2][:7] ], lst)) - print(tabulate(lst, headers=['Tags', 'Size', 'SHA256'])) + a[2] if args.full_sha256 else a[2][:7], + a[4] ], lst)) + print(tabulate(lst, headers=['Tags', 'Size', 'SHA256', 'Mountpoint'])) def command_volume_tag(args):