| @@ -6,3 +6,4 @@ __pycache__ | |||||
| /mymailmap | /mymailmap | ||||
| /*.shar | /*.shar | ||||
| /example/gitea/x | /example/gitea/x | ||||
| .pytest_cache/ | |||||
| @@ -9,7 +9,7 @@ from .zfs import zfs_poolname, \ | |||||
| def command_bootstrap(args): | def command_bootstrap(args): | ||||
| version = subprocess.check_output(['freebsd-version']).decode('utf-8') | version = subprocess.check_output(['freebsd-version']).decode('utf-8') | ||||
| print('FreeBSD version:', version) | print('FreeBSD version:', version) | ||||
| tags = [ 'freebsd-' + version.split('-')[0], 'freebsd-latest' ] | |||||
| tags = args.tags or [ 'freebsd-' + version.split('-')[0], 'freebsd-latest' ] | |||||
| sha256 = hashlib.sha256(('FreeBSD ' + version).encode('utf-8')).hexdigest() | sha256 = hashlib.sha256(('FreeBSD ' + version).encode('utf-8')).hexdigest() | ||||
| poolname = zfs_poolname() | poolname = zfs_poolname() | ||||
| name = find_prefix(poolname + '/focker/images/', sha256) | name = find_prefix(poolname + '/focker/images/', sha256) | ||||
| @@ -17,6 +17,7 @@ def command_bootstrap(args): | |||||
| zfs_tag(name, tags) | zfs_tag(name, tags) | ||||
| res = subprocess.run(['bsdinstall', 'jail', zfs_mountpoint(name)]) | res = subprocess.run(['bsdinstall', 'jail', zfs_mountpoint(name)]) | ||||
| if res.returncode != 0: | if res.returncode != 0: | ||||
| zfs_run(['zfs', 'destroy', '-r', '-f', name]) | |||||
| raise ValueError('bsdinstall failed') | raise ValueError('bsdinstall failed') | ||||
| subprocess.check_output(['zfs', 'set', 'rdonly=on', name]) | subprocess.check_output(['zfs', 'set', 'rdonly=on', name]) | ||||
| subprocess.check_output(['zfs', 'snapshot', name + '@1']) | subprocess.check_output(['zfs', 'snapshot', name + '@1']) | ||||
| @@ -78,6 +78,7 @@ def create_parser(): | |||||
| parser = ListForwarder([subparsers_top.add_parser(cmd) for cmd in ['bootstrap', 'boot', 'bs']]) | parser = ListForwarder([subparsers_top.add_parser(cmd) for cmd in ['bootstrap', 'boot', 'bs']]) | ||||
| parser.set_defaults(func=command_bootstrap) | parser.set_defaults(func=command_bootstrap) | ||||
| parser.add_argument('--tags', '-t', type=str, nargs='+', default=None) | |||||
| # image | # image | ||||
| subparsers = ListForwarder([ subparsers_top.add_parser(cmd).add_subparsers(dest='L2_command') \ | subparsers = ListForwarder([ subparsers_top.add_parser(cmd).add_subparsers(dest='L2_command') \ | ||||
| @@ -111,6 +112,7 @@ def create_parser(): | |||||
| parser.add_argument('reference', type=str) | parser.add_argument('reference', type=str) | ||||
| # parser.add_argument('--remove-children', '-r', action='store_true') | # parser.add_argument('--remove-children', '-r', action='store_true') | ||||
| parser.add_argument('--remove-dependents', '-R', action='store_true') | parser.add_argument('--remove-dependents', '-R', action='store_true') | ||||
| parser.add_argument('--force', '-f', action='store_true') | |||||
| # jail | # jail | ||||
| subparsers = ListForwarder([ subparsers_top.add_parser(cmd).add_subparsers(dest='L2_command') \ | subparsers = ListForwarder([ subparsers_top.add_parser(cmd).add_subparsers(dest='L2_command') \ | ||||
| @@ -162,8 +162,15 @@ def command_image_prune(args): | |||||
| def command_image_remove(args): | def command_image_remove(args): | ||||
| snap, snap_sha256 = zfs_find(args.reference, focker_type='image', | |||||
| zfs_type='snapshot') | |||||
| try: | |||||
| snap, snap_sha256 = zfs_find(args.reference, focker_type='image', | |||||
| zfs_type='snapshot') | |||||
| except AmbiguousValueError: | |||||
| raise | |||||
| except ValueError: | |||||
| if args.force: | |||||
| return | |||||
| raise | |||||
| ds = snap.split('@')[0] | ds = snap.split('@')[0] | ||||
| command = ['zfs', 'destroy', '-r', '-f'] | command = ['zfs', 'destroy', '-r', '-f'] | ||||
| #if args.remove_children: | #if args.remove_children: | ||||
| @@ -171,5 +178,7 @@ def command_image_remove(args): | |||||
| if args.remove_dependents: | if args.remove_dependents: | ||||
| command.append('-R') | command.append('-R') | ||||
| command.append(ds) | command.append(ds) | ||||
| subprocess.run(command) | |||||
| res = subprocess.run(command) | |||||
| if res.returncode != 0: | |||||
| raise RuntimeError('zfs destroy failed') | |||||
| # zfs_run(['zfs', 'destroy', ds]) | # zfs_run(['zfs', 'destroy', ds]) | ||||
| @@ -0,0 +1,13 @@ | |||||
| import subprocess | |||||
| from focker.zfs import * | |||||
| import re | |||||
| def test_bootstrap(): | |||||
| subprocess.run(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap']) | |||||
| subprocess.run(['focker', 'bootstrap', '--tags', 'test-focker-bootstrap']) | |||||
| name, sha256 = zfs_find('test-focker-bootstrap', focker_type='volume') | |||||
| assert len(name) >= 7 | |||||
| assert re.search('[a-f]', name[:7]) | |||||
| assert len(sha256) == 64 | |||||
| assert name == sha256[:len(name)] | |||||