diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build.py b/build.py new file mode 100644 index 0000000..6812e5d --- /dev/null +++ b/build.py @@ -0,0 +1,24 @@ +from .zfs import * + + +def process_step(step, name): + cmd=['jail', '-c'] + cmd.append('path=' + '/focker/' + name) + + +def process_steps(steps, name): + if isinstance(steps, list): + for step in steps: + process_step(step, name) + else: + process_step(steps, name) + + +def build(spec): + if 'base' not in spec: + raise ValueError('Missing base specification') + base = spec.base + base = zfs_snapshot_by_tag_or_name(base) + + root = '/'.join(base.split('/')[:-1]) + print('base:', base, 'root:', root) diff --git a/focker-compose.yml b/focker-compose.yml index 78f5b21..e4be7a5 100644 --- a/focker-compose.yml +++ b/focker-compose.yml @@ -1,15 +1,23 @@ +variables: + ext_if: em0 + gateway_ip: 127.0.0.2 + defaults: jail: mount.devfs: true interface: lo1 exec.start: /bin/sh /etc/rc exec.stop: /bin/sh /etc/rc.shutdown + pf: | + rdr on $(ext_if) proto tcp from any to any port 80 -> $(jail_ip) services: gateway: image: freebsd-12.1 jail: - ip4.address: 127.0.0.2 + ip4.address: $(gateway_ip) + pf: + - pass on $(ext_if) volumes: gateway-data: {} diff --git a/focker.py b/focker.py index 77a7911..88f10e5 100644 --- a/focker.py +++ b/focker.py @@ -2,6 +2,7 @@ from argparse import ArgumentParser import yaml import os from weir import zfs, process +from .build import build def clone(self, name, props={}, force=False): @@ -20,20 +21,7 @@ def clone(self, name, props={}, force=False): zfs.ZFSSnapshot.clone = clone -def process_step(step, name): - cmd=['jail', '-c'] - cmd.append('path=' + '/focker/' + name) - - -def process_steps(steps, name): - if isinstance(steps, list): - for step in steps: - process_step(step, name) - else: - process_step(steps, name) - - -def build(args): +def command_build(args): fname = os.path.join(args.focker_dir, 'Fockerfile.yml') print('fname:', fname) if not os.path.exists(fname): @@ -41,24 +29,7 @@ def build(args): with open(fname, 'r') as f: spec = yaml.safe_load(f) print('spec:', spec) - if 'from' not in spec: - raise ValueError('Missing base specification') - from_ = zfs.findprops('/', props=['focker:tags']) - from_ = filter(lambda a: a['value'] == spec['from'] \ - and '@' in a['name'], from_) - from_ = list(from_) - if len(from_) == 0: - raise ValueError('Requested base not found') - if len(from_) > 1: - raise ValueError('Ambiguous base specification') - base = from_[0]['name'] - root = '/'.join(base.split('/')[:-1]) - print('base:', base) - print('root:', root) - base = zfs.open(base) - name = '/'.join([root, 'x y z']) - base.clone(name) - process_steps(args['steps'], name) + build(spec) def run(args): @@ -69,7 +40,7 @@ def create_parser(): parser = ArgumentParser() subparsers = parser.add_subparsers() parser_build = subparsers.add_parser('build') - parser_build.set_defaults(func=build) + parser_build.set_defaults(func=command_build) parser_build.add_argument('focker_dir', type=str) parser_run = subparsers.add_parser('run') parser_run.set_defaults(func=run) @@ -82,4 +53,6 @@ def create_parser(): parser = create_parser() args = parser.parse_args() +if not hasattr(args, 'func'): + raise ValueError('You must choose the mode') args.func(args) diff --git a/zfs.py b/zfs.py index 9660e98..f35576d 100644 --- a/zfs.py +++ b/zfs.py @@ -18,3 +18,17 @@ def zfs_parse_output(command): def zfs_get_type(name): lst = zfs_parse_output(['zfs', 'list', '-o', 'name,type', '-H', name]) return lst[0][1] + + +def zfs_snapshot_by_tag_or_name(s): + lst = zfs_parse_output(['zfs', 'list', '-o', 'name,focker:tags,type', '-H']) + lst = list(filter(lambda a: (a[0] == s or s in a[1].split(' ') and a[2] == 'snapshot'))) + if len(lst) == 0: + raise ValueError('Reference not found: ' + s) + if len(lst) > 1: + raise ValueError('Ambiguous reference: ' + s) + return lst[0][0] + + +def zfs_clone(name, target_name): + zfs_run(['zfs', 'clone', name, target_name])