IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
浏览代码

Got rid of shlex, implemented focker run oneshot.

tags/0.92
父节点
当前提交
2fb23cfef1
共有 2 个文件被更改,包括 51 次插入24 次删除
  1. +5
    -4
      focker.py
  2. +46
    -20
      jail.py

+ 5
- 4
focker.py 查看文件

@@ -21,7 +21,7 @@ from .jail import command_jail_create, \
command_jail_stop, \
command_jail_remove, \
command_jail_exec, \
command_jail_run, \
command_jail_oneshot, \
command_jail_list, \
command_jail_tag, \
command_jail_untag, \
@@ -89,11 +89,12 @@ def create_parser():
parser.add_argument('reference', type=str)
parser.add_argument('command', type=str, nargs=argparse.REMAINDER, default=['/bin/sh'])
parser = subparsers.add_parser('run')
parser.set_defaults(func=command_jail_run)
parser = subparsers.add_parser('oneshot')
parser.set_defaults(func=command_jail_oneshot)
parser.add_argument('image', type=str)
parser.add_argument('--command', '-c', type=str, default='/bin/sh')
parser.add_argument('--env', '-e', type=str, nargs='+', default=[])
parser.add_argument('--mounts', '-m', type=str, nargs='+', default=[])
parser.add_argument('command', type=str, nargs=argparse.REMAINDER, default=['/bin/sh'])
parser = subparsers.add_parser('list')
parser.set_defaults(func=command_jail_list)


+ 46
- 20
jail.py 查看文件

@@ -6,17 +6,39 @@ import json
from tabulate import tabulate
import os
import jailconf
import shlex
from .mount import getmntinfo
def jail_fs_create(image):
image, _ = zfs_find(image, focker_type='image', zfs_type='snapshot')
sha256 = bytes([ random.randint(0, 255) for _ in range(32) ]).hex()
lst = zfs_list(fields=['focker:sha256'], focker_type='image')
lst = list(filter(lambda a: a[0] == sha256, lst))
if lst:
raise ValueError('Whew, a collision...')
poolname = zfs_poolname()
for pre in range(7, 32):
name = poolname + '/focker/jails/' + sha256[:pre]
if not zfs_exists(name):
break
zfs_run(['zfs', 'clone', '-o', 'focker:sha256=' + sha256, image, name])
return name
def gen_env_command(command, env):
env = [ 'export ' + k + '=' + shlex.quote(v) \
env = [ 'export ' + k + '=' + quote(v) \
for (k, v) in env.items() ]
command = ' && '.join(env + [ command ])
return command
def quote(s):
s = s.replace('\\', '\\\\')
s = s.replace('\'', '\\\'')
s = '\'' + s + '\''
return s
def jail_create(path, command, env, mounts, hostname=None):
name = os.path.split(path)[-1]
if os.path.exists('/etc/jail.conf'):
@@ -27,24 +49,26 @@ def jail_create(path, command, env, mounts, hostname=None):
blk['path'] = path
if command:
command = gen_env_command(command, env)
command = quote(command)
print('command:', command)
blk['exec.start'] = command
prestart = [ 'cp /etc/resolv.conf ' +
shlex.quote(os.path.join(path, 'etc/resolv.conf')) ]
quote(os.path.join(path, 'etc/resolv.conf')) ]
poststop = []
if mounts:
for (from_, on) in mounts:
if not from_.startswith('/'):
from_, _ = zfs_find(from_, focker_type='volume')
from_ = zfs_mountpoint(from_)
prestart.append('mount -t nullfs ' + shlex.quote(from_) +
' ' + shlex.quote(os.path.join(path, on.strip('/'))))
prestart.append('mount -t nullfs ' + quote(from_) +
' ' + quote(os.path.join(path, on.strip('/'))))
poststop += [ 'umount -f ' +
os.path.join(path, on.strip('/')) \
for (_, on) in reversed(mounts) ]
if prestart:
blk['exec.prestart'] = shlex.quote(' && '.join(prestart))
blk['exec.prestart'] = quote(' && '.join(prestart))
if poststop:
blk['exec.poststop'] = shlex.quote(' && '.join(poststop))
blk['exec.poststop'] = quote(' && '.join(poststop))
blk['persist'] = True
blk['interface'] = 'lo1'
blk['ip4.addr'] = '127.0.1.0'
@@ -52,6 +76,7 @@ def jail_create(path, command, env, mounts, hostname=None):
blk['exec.clean'] = True
blk['host.hostname'] = hostname or name
conf.write('/etc/jail.conf')
return name
def jail_run_v2(path, command, env, mounts):
@@ -143,18 +168,7 @@ def jail_remove(path):
def command_jail_create(args):
image, _ = zfs_find(args.image, focker_type='image', zfs_type='snapshot')
sha256 = bytes([ random.randint(0, 255) for _ in range(32) ]).hex()
lst = zfs_list(fields=['focker:sha256'], focker_type='image')
lst = list(filter(lambda a: a[0] == sha256, lst))
if lst:
raise ValueError('Whew, a collision...')
poolname = zfs_poolname()
for pre in range(7, 32):
name = poolname + '/focker/jails/' + sha256[:pre]
if not zfs_exists(name):
break
zfs_run(['zfs', 'clone', '-o', 'focker:sha256=' + sha256, image, name])
name = jail_fs_create(args.image)
if args.tags:
zfs_tag(name, args.tags)
path = zfs_mountpoint(name)
@@ -194,7 +208,19 @@ def command_jail_exec(args):
subprocess.run(['jexec', str(jid)] + args.command)
def command_jail_run(args):
def command_jail_oneshot(args):
name = jail_fs_create(args.image)
path = zfs_mountpoint(name)
env = { a.split(':')[0]: ':'.join(a.split(':')[1:]) \
for a in args.env }
mounts = [ [ a.split(':')[0], a.split(':')[1] ] \
for a in args.mounts]
jailname = jail_create(path, ' '.join(map(quote, args.command)), env, mounts)
subprocess.run(['jail', '-c', jailname])
jail_remove(path)
# Deprecated
def command_jail_oneshot_old():
base, _ = zfs_snapshot_by_tag_or_sha256(args.image)
# root = '/'.join(base.split('/')[:-1])
for _ in range(10**6):


正在加载...
取消
保存