def test_command_jail_list_01(monkeypatch): subprocess.check_output([ 'focker', 'jail', 'create', 'test-jail', '--tags', 'test-command-jail-list-01' ]) name, sha256 = zfs_find('test-command-jail-list-01', focker_type='jail') mountpoint = zfs_mountpoint(name) def fake_tabulate(data, headers): data = [ d for d in data \ if d[0] == 'test-command-jail-list-01' ] assert len(data) == 1 data = data[0] assert data[1] == sha256 assert data[2] == mountpoint assert data[3] == '-' assert data[4] == 'test-jail' monkeypatch.setattr(focker.jail, 'tabulate', fake_tabulate) args = lambda: 0 args.images = True args.full_sha256 = True command_jail_list(args) subprocess.check_output( ['focker', 'jail', 'remove', 'test-command-jail-list-01'])
def test_command_image_build(): focker_unlock() subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-command-image-build-base' ]) subprocess.check_output([ 'focker', 'bootstrap', '--empty', '-t', 'test-command-image-build-base' ]) with TemporaryDirectory() as d: args = lambda: 0 with open(os.path.join(d, 'Fockerfile'), 'w') as f: yaml.dump( dict(base='test-command-image-build-base', steps=[ dict(copy=['/etc/localtime', '/etc/localtime']), dict(copy=['/etc/hosts', '/etc/hosts']) ]), f) args.focker_dir = d args.squeeze = False args.tags = ['test-command-image-build'] command_image_build(args) focker_unlock() name, _ = zfs_find('test-command-image-build', focker_type='image') mountpoint = zfs_mountpoint(name) assert os.path.exists(os.path.join(mountpoint, 'etc/localtime')) assert os.path.exists(os.path.join(mountpoint, 'etc/hosts')) subprocess.check_output( ['focker', 'image', 'remove', '-R', 'test-command-image-build-base']) assert not os.path.exists(mountpoint)
def test_command_volume_protect(monkeypatch): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-protect']) subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-protect']) args = lambda: 0 args.references = ['test-command-volume-protect'] command_volume_protect(args) name, sha256 = zfs_find('test-command-volume-protect', focker_type='volume') mountpoint = zfs_mountpoint(name) lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:protect', name]) assert len(lst) == 1 assert lst[0][2] == 'on' with pytest.raises(RuntimeError): zfs_destroy(name) subprocess.check_output(['focker', 'volume', 'untag', 'test-command-volume-protect']) lst = zfs_parse_output(['zfs', 'get', '-H', 'focker:tags', name]) assert len(lst) == 1 assert lst[0][2] == '-' n_called = 0 def fake_run(*args, **kwargs): nonlocal n_called n_called += 1 return zfs_run(*args, **kwargs) monkeypatch.setattr(focker.zfs, 'zfs_run', fake_run) zfs_prune(focker_type='volume') assert not n_called == 1 with pytest.raises(subprocess.CalledProcessError): subprocess.check_output(['focker', 'volume', 'remove', sha256]) subprocess.check_output(['zfs', 'destroy', '-r', '-f', name]) assert not zfs_exists(name) assert not os.path.exists(mountpoint)
def test_build_images(): subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap']) subprocess.check_output(['focker', 'bootstrap', '--empty', '--tags', 'test-focker-bootstrap']) subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-build-images']) with TemporaryDirectory() as d: with open(os.path.join(d, 'Fockerfile'), 'w') as f: yaml.dump({ 'base': 'test-focker-bootstrap', 'steps': [ { 'copy': [ [ '/bin/sh', '/bin/sh', { 'chmod': 0o777 } ], [ '/lib/libedit.so.7', '/lib/libedit.so.7' ], [ '/lib/libncursesw.so.8', '/lib/libncursesw.so.8' ], [ '/lib/libc.so.7', '/lib/libc.so.7' ], [ '/usr/bin/touch', '/usr/bin/touch', { 'chmod': 0o777 } ], [ '/libexec/ld-elf.so.1', '/libexec/ld-elf.so.1', { 'chmod': 0o555 } ] ] }, { 'run': 'touch /test-build-images' } ] }, f) args = lambda: 0 args.squeeze = False build_images({ 'test-build-images': '.' }, d, args) focker_unlock() name, _ = zfs_find('test-build-images', focker_type='image') assert os.path.exists(os.path.join(zfs_mountpoint(name), 'test-build-images')) subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-build-images']) subprocess.check_output(['focker', 'image', 'prune']) subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap'])
def test_build_squeeze(monkeypatch): focker_unlock() subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-build-squeeze-base' ]) subprocess.check_output( ['focker', 'bootstrap', '--empty', '-t', 'test-build-squeeze-base']) spec = dict(base='test-build-squeeze-base', steps=[ dict(copy=['/etc/localtime', '/etc/localtime']), dict(copy=['/etc/hosts', '/etc/hosts']) ]) _, base_sha256 = zfs_find('test-build-squeeze-base', focker_type='image') def fail(sha256, *args, **kwargs): if sha256 != base_sha256: raise RuntimeError( 'No pre-existing layers expected apart from base') monkeypatch.setattr(focker.image, 'zfs_snapshot_by_sha256', fail) with TemporaryDirectory() as d: args = lambda: 0 args.focker_dir = d name, _ = build_squeeze(spec, args) focker_unlock() mountpoint = zfs_mountpoint(name.split('@')[0]) print('name:', name, 'mountpoint:', mountpoint) assert os.path.exists(os.path.join(mountpoint, 'etc/localtime')) assert os.path.exists(os.path.join(mountpoint, 'etc/hosts')) subprocess.check_output( ['focker', 'image', 'remove', '-R', 'test-build-squeeze-base']) assert not os.path.exists(mountpoint)
def test_build_volumes(): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-build-volumes']) err = False try: name, _ = zfs_find('test-build-volumes', focker_type='volume') except: err = True assert err spec = { 'test-build-volumes': { 'chown': '65534:65534', 'chmod': 0o123, 'protect': True, 'zfs': { 'quota': '1G', 'readonly': 'on' } } } build_volumes(spec) name, _ = zfs_find('test-build-volumes', focker_type='volume') st = os.stat(zfs_mountpoint(name)) assert st.st_uid == 65534 assert st.st_gid == 65534 assert ('%o' % st.st_mode)[-3:] == '123' zst = zfs_parse_output(['zfs', 'get', '-H', 'quota,readonly,focker:protect', name]) assert zst[0][2] == '1G' assert zst[1][2] == 'on' assert zst[2][2] == 'on' subprocess.check_output(['zfs', 'destroy', '-r', '-f', name])
def test_command_volume_list(monkeypatch): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-list']) subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-list', 'test-command-volume-list-1', 'test-command-volume-list-2']) name, sha256 = zfs_find('test-command-volume-list', focker_type='volume') mountpoint = zfs_mountpoint(name) args = lambda: 0 args.full_sha256 = True lst = None headers = None def fake_tabulate(*args, **kwargs): nonlocal lst nonlocal headers lst = args[0] headers = kwargs['headers'] monkeypatch.setattr(focker.volume, 'tabulate', fake_tabulate) command_volume_list(args) assert lst is not None assert headers == ['Tags', 'Size', 'SHA256', 'Mountpoint'] assert len(lst) >= 3 match = list(filter(lambda a: sorted(a[0].split(' ')) == ['test-command-volume-list', 'test-command-volume-list-1', 'test-command-volume-list-2'], lst)) assert len(match) == 1 match = match[0] assert match[2] == sha256 assert match[3] == mountpoint subprocess.check_output(['focker', 'volume', 'remove', 'test-command-volume-list'])
def test_command_volume_create(): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-create']) args = lambda: 0 args.tags = ['test-command-volume-create'] command_volume_create(args) name, sha256 = zfs_find('test-command-volume-create', focker_type='volume') assert os.path.exists(zfs_mountpoint(name)) subprocess.check_output(['focker', 'volume', 'remove', 'test-command-volume-create'])
def test_jail_create(): subprocess.check_output( ['focker', 'jail', 'remove', '--force', 'test-jail-create']) subprocess.check_output( ['focker', 'volume', 'remove', '--force', 'test-jail-create']) name = jail_fs_create() zfs_tag(name, ['test-jail-create']) subprocess.check_output( ['focker', 'volume', 'create', '-t', 'test-jail-create']) mountpoint = zfs_mountpoint(name) spec = { 'path': mountpoint, 'exec.start': '/bin/sh /etc/rc', 'env': { 'DUMMY_1': 'foo', 'DUMMY_2': 'bar' }, 'mounts': { 'test-jail-create': '/test-jail-create', '/tmp': '/test-tmp' }, 'ip4.addr': '127.1.2.3', 'host.hostname': 'test-jail-create' } jail_name = os.path.split(mountpoint)[-1] jail_create(spec, jail_name) assert jail_name == os.path.split(mountpoint)[-1] assert os.path.exists(mountpoint) vol_name, _ = zfs_find('test-jail-create', focker_type='volume') vol_mountpoint = zfs_mountpoint(vol_name) assert os.path.exists(vol_mountpoint) conf = jailconf.load('/etc/jail.conf') assert jail_name in conf conf = conf[jail_name] assert conf['path'] == quote(mountpoint) assert conf[ 'exec.start'] == '\'export DUMMY_1=foo && export DUMMY_2=bar && /bin/sh /etc/rc\'' assert conf[ 'exec.prestart'] == f'\'cp /etc/resolv.conf {mountpoint}/etc/resolv.conf && mount -t nullfs {vol_mountpoint} {mountpoint}/test-jail-create && mount -t nullfs /tmp {mountpoint}/test-tmp\'' assert conf['ip4.addr'] == '\'127.1.2.3\'' subprocess.check_output(['focker', 'jail', 'remove', 'test-jail-create']) subprocess.check_output(['focker', 'volume', 'remove', 'test-jail-create'])
def test_command_volume_prune(): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-prune']) subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-prune']) name, sha256 = zfs_find('test-command-volume-prune', focker_type='volume') mountpoint = zfs_mountpoint(name) subprocess.check_output(['focker', 'volume', 'untag', 'test-command-volume-prune']) args = lambda: 0 command_volume_prune(args) assert not zfs_exists(name) assert not os.path.exists(mountpoint)
def test_get_jid_01(): subprocess.check_output([ 'focker', 'jail', 'create', 'test-jail', '--tags', 'test-get-jid-01', '--command', '/usr/bin/true' ]) name, _ = zfs_find('test-get-jid-01', focker_type='jail') mountpoint = zfs_mountpoint(name) subprocess.check_output(['focker', 'jail', 'start', 'test-get-jid-01']) _ = get_jid(mountpoint) subprocess.check_output(['focker', 'jail', 'remove', 'test-get-jid-01'])
def test_jail_run_01(): subprocess.check_output([ 'focker', 'jail', 'create', 'test-jail', '--tags', 'test-jail-run-01' ]) name, _ = zfs_find('test-jail-run-01', focker_type='jail') mountpoint = zfs_mountpoint(name) jail_run(mountpoint, 'echo test-jail-run-01 >/tmp/test.txt') assert os.path.exists(os.path.join(mountpoint, 'tmp/test.txt')) with open(os.path.join(mountpoint, 'tmp/test.txt'), 'r') as f: assert f.read() == 'test-jail-run-01\n' subprocess.check_output(['focker', 'jail', 'remove', 'test-jail-run-01'])
def test_build_jails(): backup_file('/etc/jail.conf') conf = jailconf.load('/etc/jail.conf') for k in list(conf.keys()): if conf[k]['host.hostname'].strip('\'"') in ['test-build-jails-A', 'test-build-jails-B']: del conf[k] conf.write('/etc/jail.conf') subprocess.check_output(['focker', 'jail', 'remove', '--force', 'test-build-jails-A']) subprocess.check_output(['focker', 'jail', 'remove', '--force', 'test-build-jails-B']) subprocess.check_output(['focker', 'image', 'remove', '--force', '-R', 'test-focker-bootstrap']) subprocess.check_output(['focker', 'bootstrap', '--empty', '-t', 'test-focker-bootstrap']) spec = { 'test-build-jails-A': { 'image': 'test-focker-bootstrap', 'exec.start': 'test-exec-start', 'exec.stop': 'test-exec-stop', 'ip4.addr': 'test-ip4-addr', 'interface': 'test-interface', 'host.hostname': 'test-build-jails-A', 'allow.mount': True, 'ip6.addr': 'abcd:abcd::0' } } spec['test-build-jails-B'] = spec['test-build-jails-A'].copy() spec['test-build-jails-B']['host.hostname'] = 'test-build-jails-B' build_jails(spec) conf = jailconf.load('/etc/jail.conf') print(conf.values()) blocks = list(filter(lambda a: a['host.hostname'].strip('"\'') in [ 'test-build-jails-A', 'test-build-jails-B' ], conf.values())) print(blocks) assert len(blocks) == 2 assert blocks[0]['host.hostname'] != blocks[1]['host.hostname'] for i in range(2): jail_sha256_prefix = os.path.split(blocks[i]['path'].strip('\'"'))[-1] assert jail_sha256_prefix in conf for b in blocks: name, _ = zfs_find(b['host.hostname'].strip('\'"'), focker_type='jail') mountpoint = zfs_mountpoint(name) assert b['path'].strip('\'"') == mountpoint assert b['exec.start'].strip('\'"') == 'test-exec-start' assert b['exec.stop'].strip('\'"') == 'test-exec-stop' assert b['ip4.addr'].strip('\'"') == 'test-ip4-addr' assert b['interface'].strip('\'"') == 'test-interface' assert b['allow.mount'] assert b['ip6.addr'] == '\'abcd:abcd::0\'' subprocess.check_output(['focker', 'jail', 'remove', '--force', 'test-build-jails-A']) subprocess.check_output(['focker', 'jail', 'remove', '--force', 'test-build-jails-B']) subprocess.check_output(['focker', 'image', 'remove', '--force', 'test-focker-bootstrap']) for k in list(conf.keys()): if conf[k]['host.hostname'].strip('\'"') in ['test-build-jails-A', 'test-build-jails-B']: del conf[k] conf.write('/etc/jail.conf')
def test_jail_stop_01(): subprocess.check_output([ 'focker', 'jail', 'create', 'test-jail', '--tags', 'test-jail-stop-01' ]) name, _ = zfs_find('test-jail-stop-01', focker_type='jail') mountpoint = zfs_mountpoint(name) with pytest.raises(ValueError): _ = get_jid(mountpoint) subprocess.check_output(['focker', 'jail', 'start', 'test-jail-stop-01']) _ = get_jid(mountpoint) jail_stop(mountpoint) with pytest.raises(ValueError): _ = get_jid(mountpoint) subprocess.check_output(['focker', 'jail', 'remove', 'test-jail-stop-01'])
def test_command_volume_remove(): subprocess.check_output(['focker', 'volume', 'remove', '--force', 'test-command-volume-remove']) subprocess.check_output(['focker', 'volume', 'create', '-t', 'test-command-volume-remove']) name, sha256 = zfs_find('test-command-volume-remove', focker_type='volume') mountpoint = zfs_mountpoint(name) args = lambda: 0 args.references = ['test-command-volume-remove'] args.force = False command_volume_remove(args) with pytest.raises(ValueError): zfs_find('test-command-volume-remove', focker_type='volume') with pytest.raises(ValueError): zfs_find(sha256, focker_type='volume') assert not os.path.exists(mountpoint) assert not zfs_exists(name)
def test_jail_remove_01(): subprocess.check_output([ 'focker', 'jail', 'create', 'test-jail', '--tags', 'test-jail-remove-01' ]) name, _ = zfs_find('test-jail-remove-01', focker_type='jail') mountpoint = zfs_mountpoint(name) with pytest.raises(ValueError): _ = get_jid(mountpoint) subprocess.check_output(['focker', 'jail', 'start', 'test-jail-remove-01']) _ = get_jid(mountpoint) jail_remove(mountpoint) with pytest.raises(ValueError): _ = get_jid(mountpoint) assert not os.path.exists(mountpoint)
def test_jail_fs_create_02(): subprocess.check_output( ['focker', 'jail', 'remove', '--force', 'test-jail-fs-create-02']) name = jail_fs_create() zfs_tag(name, ['test-jail-fs-create-02']) assert zfs_exists(name) mountpoint = zfs_mountpoint(name) assert os.path.exists(mountpoint) with open(os.path.join(mountpoint, 'test.txt'), 'w') as f: f.write('test\n') assert os.path.exists(os.path.join(mountpoint, 'test.txt')) with open(os.path.join(mountpoint, 'test.txt'), 'r') as f: assert f.read() == 'test\n' subprocess.check_output( ['focker', 'jail', 'remove', 'test-jail-fs-create-02']) assert not zfs_exists(name) assert not os.path.exists(mountpoint)
def test_command_image_prune(): focker_unlock() subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-command-image-prune' ]) subprocess.check_output( ['focker', 'bootstrap', '--empty', '-t', 'test-command-image-prune']) name, sha256 = zfs_find('test-command-image-prune', focker_type='image') mountpoint = zfs_mountpoint(name) subprocess.check_output( ['focker', 'image', 'untag', 'test-command-image-prune']) args = lambda: 0 command_image_prune(args) with pytest.raises(ValueError): zfs_find('test-command-image-prune', focker_type='image') with pytest.raises(ValueError): zfs_find(sha256, focker_type='image') assert not os.path.exists(mountpoint)
def test_jail_fs_create_01(): subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-jail-fs-create-01' ]) subprocess.check_output( ['focker', 'bootstrap', '--empty', '-t', 'test-jail-fs-create-01']) name = jail_fs_create('test-jail-fs-create-01') assert zfs_exists(name) mountpoint = zfs_mountpoint(name) assert os.path.exists(mountpoint) with open(os.path.join(mountpoint, 'test.txt'), 'w') as f: f.write('test\n') assert os.path.exists(os.path.join(mountpoint, 'test.txt')) with open(os.path.join(mountpoint, 'test.txt'), 'r') as f: assert f.read() == 'test\n' subprocess.check_output( ['focker', 'image', 'remove', '-R', 'test-jail-fs-create-01']) assert not zfs_exists(name) assert not os.path.exists(mountpoint)
def test_command_image_remove(): focker_unlock() subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-command-image-remove' ]) subprocess.check_output( ['focker', 'bootstrap', '--empty', '-t', 'test-command-image-remove']) name, sha256 = zfs_find('test-command-image-remove', focker_type='image') mountpoint = zfs_mountpoint(name) args = lambda: 0 args.reference = 'test-command-image-remove' args.force = False args.remove_dependents = False command_image_remove(args) with pytest.raises(ValueError): zfs_find('test-command-image-remove', focker_type='image') with pytest.raises(ValueError): zfs_find(sha256, focker_type='image') assert not os.path.exists(mountpoint) assert not zfs_exists(name)
def test_build(monkeypatch): focker_unlock() subprocess.check_output([ 'focker', 'image', 'remove', '--force', '-R', 'test-build-squeeze-base' ]) subprocess.check_output( ['focker', 'bootstrap', '--empty', '-t', 'test-build-squeeze-base']) spec = dict(base='test-build-squeeze-base', steps=[ dict(copy=['/etc/localtime', '/etc/localtime']), dict(copy=['/etc/hosts', '/etc/hosts']) ]) _, base_sha256 = zfs_find('test-build-squeeze-base', focker_type='image') counter = 0 def count_calls(*args, **kwargs): nonlocal counter counter += 1 return zfs_exists_snapshot_sha256(*args, **kwargs) monkeypatch.setattr(focker.image, 'zfs_exists_snapshot_sha256', count_calls) with TemporaryDirectory() as d: args = lambda: 0 args.focker_dir = d name, _ = build(spec, args) assert counter == 2 focker_unlock() mountpoint = zfs_mountpoint(name.split('@')[0]) print('name:', name, 'mountpoint:', mountpoint) assert os.path.exists(os.path.join(mountpoint, 'etc/localtime')) assert os.path.exists(os.path.join(mountpoint, 'etc/hosts')) subprocess.check_output( ['focker', 'image', 'remove', '-R', 'test-build-squeeze-base']) assert not os.path.exists(mountpoint)
def test_command_jail_create_01(): args = lambda: 0 args.image = 'test-jail' args.tags = ['test-command-jail-create-01'] args.command = '/bin/sh /etc/rc' args.env = ['FOO:1', 'BAR:2'] args.mounts = [f'/no/path:/mnt'] args.hostname = 'test-command-jail-create-01' command_jail_create(args) name, _ = zfs_find('test-command-jail-create-01', focker_type='jail') mountpoint = zfs_mountpoint(name) jail_sha256_prefix = name.split('/')[-1] conf = jailconf.load('/etc/jail.conf') assert jail_sha256_prefix in conf blk = conf[jail_sha256_prefix] assert blk['path'] == f'\'{mountpoint}\'' assert blk[ 'exec.start'] == f'\'export FOO=1 && export BAR=2 && {args.command}\'' assert blk[ 'exec.prestart'] == f'\'cp /etc/resolv.conf {mountpoint}/etc/resolv.conf && mount -t nullfs /no/path {mountpoint}/mnt\'' assert blk['host.hostname'] == f'\'{args.hostname}\'' subprocess.check_output( ['focker', 'jail', 'remove', 'test-command-jail-create-01'])