| @@ -0,0 +1 @@ | |||||
| __pycache__ | |||||
| @@ -1,58 +1,31 @@ | |||||
| from argparse import ArgumentParser | from argparse import ArgumentParser | ||||
| import yaml | import yaml | ||||
| import os | import os | ||||
| from weir import zfs, process | |||||
| from .build import build | |||||
| # from weir import zfs, process | |||||
| from .image import command_image_build | |||||
| import sys | |||||
| from .zfs import zfs_init | |||||
| def clone(self, name, props={}, force=False): | |||||
| url = zfs._urlsplit(self.name) | |||||
| url_1 = zfs._urlsplit(name) | |||||
| if url.netloc != url_1.netloc: | |||||
| raise ValueError('Clone has to happen on the same host') | |||||
| cmd = ['zfs', 'clone'] | |||||
| for prop, value in props.items(): | |||||
| cmd.append('-o') | |||||
| cmd.append(prop + '=' + str(value)) | |||||
| cmd.append(url.path) | |||||
| cmd.append(url_1.path) | |||||
| process.check_call(cmd, netloc=url.netloc) | |||||
| zfs.ZFSSnapshot.clone = clone | |||||
| def command_build(args): | |||||
| fname = os.path.join(args.focker_dir, 'Fockerfile.yml') | |||||
| print('fname:', fname) | |||||
| if not os.path.exists(fname): | |||||
| raise ValueError('No Fockerfile.yml could be found in the specified directory') | |||||
| with open(fname, 'r') as f: | |||||
| spec = yaml.safe_load(f) | |||||
| print('spec:', spec) | |||||
| build(spec) | |||||
| def create_parser(): | |||||
| parser_top = ArgumentParser() | |||||
| subparsers_top = parser_top.add_subparsers() | |||||
| def run(args): | |||||
| pass | |||||
| subparsers = subparsers_top.add_parser('image').add_subparsers() | |||||
| parser = subparsers.add_parser('build') | |||||
| parser.set_defaults(func=command_image_build) | |||||
| parser.add_argument('focker_dir', type=str) | |||||
| return parser_top | |||||
| def create_parser(): | |||||
| parser = ArgumentParser() | |||||
| subparsers = parser.add_subparsers() | |||||
| parser_build = subparsers.add_parser('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) | |||||
| parser_rm = subparsers.add_parser('rm') | |||||
| parser_rmi = subparsers.add_parser('rmi') | |||||
| parser_ps = subparsers.add_parser('ps') | |||||
| parser_images = subparsers.add_parser('images') | |||||
| return parser | |||||
| def main(): | |||||
| zfs_init() | |||||
| parser = create_parser() | |||||
| args = parser.parse_args() | |||||
| if not hasattr(args, 'func'): | |||||
| sys.exit('You must choose a mode') | |||||
| args.func(args) | |||||
| parser = create_parser() | |||||
| args = parser.parse_args() | |||||
| if not hasattr(args, 'func'): | |||||
| raise ValueError('You must choose the mode') | |||||
| args.func(args) | |||||
| if __name__ == '__main__': | |||||
| main() | |||||
| @@ -1,4 +1,6 @@ | |||||
| from .zfs import * | from .zfs import * | ||||
| import os | |||||
| import yaml | |||||
| def process_step(step, name): | def process_step(step, name): | ||||
| @@ -17,8 +19,19 @@ def process_steps(steps, name): | |||||
| def build(spec): | def build(spec): | ||||
| if 'base' not in spec: | if 'base' not in spec: | ||||
| raise ValueError('Missing base specification') | raise ValueError('Missing base specification') | ||||
| base = spec.base | |||||
| base = zfs_snapshot_by_tag_or_name(base) | |||||
| base = spec['base'] | |||||
| base = zfs_snapshot_by_tag_or_sha256(base) | |||||
| root = '/'.join(base.split('/')[:-1]) | root = '/'.join(base.split('/')[:-1]) | ||||
| print('base:', base, 'root:', root) | print('base:', base, 'root:', root) | ||||
| def command_image_build(args): | |||||
| fname = os.path.join(args.focker_dir, 'Fockerfile') | |||||
| print('fname:', fname) | |||||
| if not os.path.exists(fname): | |||||
| raise ValueError('No Fockerfile could be found in the specified directory') | |||||
| with open(fname, 'r') as f: | |||||
| spec = yaml.safe_load(f) | |||||
| print('spec:', spec) | |||||
| build(spec) | |||||
| @@ -1,10 +1,12 @@ | |||||
| import subprocess | import subprocess | ||||
| import csv | import csv | ||||
| import io | import io | ||||
| import os | |||||
| def zfs_run(command): | def zfs_run(command): | ||||
| out = subprocess.check_output(command) | |||||
| # print('Running:', command) | |||||
| out = subprocess.check_output(command, stderr=subprocess.STDOUT) | |||||
| return out | return out | ||||
| @@ -20,15 +22,42 @@ def zfs_get_type(name): | |||||
| return lst[0][1] | 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'))) | |||||
| def zfs_snapshot_by_tag_or_sha256(s): | |||||
| lst = zfs_parse_output(['zfs', 'list', '-o', 'focker:sha256,focker:tags,type,name', '-H', '-t', 'snapshot']) | |||||
| lst = list(filter(lambda a: (a[0] == s or s in a[1].split(' ')) and a[2] == 'snapshot', lst)) | |||||
| if len(lst) == 0: | if len(lst) == 0: | ||||
| raise ValueError('Reference not found: ' + s) | raise ValueError('Reference not found: ' + s) | ||||
| if len(lst) > 1: | if len(lst) > 1: | ||||
| raise ValueError('Ambiguous reference: ' + s) | raise ValueError('Ambiguous reference: ' + s) | ||||
| return lst[0][0] | |||||
| return lst[0][3] | |||||
| def zfs_clone(name, target_name): | def zfs_clone(name, target_name): | ||||
| zfs_run(['zfs', 'clone', name, target_name]) | zfs_run(['zfs', 'clone', name, target_name]) | ||||
| def zfs_exists(name): | |||||
| try: | |||||
| zfs_run(['zfs', 'list', name]) | |||||
| except subprocess.CalledProcessError as e: | |||||
| return False | |||||
| return True | |||||
| def zfs_init(): | |||||
| poolname = zfs_parse_output(['zfs', 'list', '-H', '/']) | |||||
| if len(poolname) == 0: | |||||
| raise ValueError('Not a ZFS root') | |||||
| poolname = poolname[0][0].split('/')[0] | |||||
| print('poolname:', poolname) | |||||
| for path in ['/focker', '/focker/images', '/focker/volumes', '/focker/jails']: | |||||
| if not os.path.exists(path): | |||||
| os.mkdir(path) | |||||
| if not zfs_exists(poolname + '/focker'): | |||||
| zfs_run(['zfs', 'create', '-o', 'canmount=off', '-o', 'mountpoint=/focker', poolname + '/focker']) | |||||
| if not zfs_exists(poolname + '/focker/images'): | |||||
| zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/images']) | |||||
| if not zfs_exists(poolname + '/focker/volumes'): | |||||
| zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/volumes']) | |||||
| if not zfs_exists(poolname + '/focker/volumes'): | |||||
| zfs_run(['zfs', 'create', '-o', 'canmount=off', poolname + '/focker/jails']) | |||||