@@ -6,3 +6,6 @@ steps: | |||
pkg -y install -y py37-pip | |||
- run: | | |||
pkg install -y py37-yaml | |||
- copy: | |||
- [ '/tmp/x', '/etc/x' ] | |||
- [ 'focker-compose.yml', '/etc/focker-compose.yml' ] |
@@ -18,7 +18,7 @@ def process_steps(steps, name): | |||
process_step(steps, name) | |||
def build(spec): | |||
def build(spec, args): | |||
if 'base' not in spec: | |||
raise ValueError('Missing base in specification') | |||
@@ -37,7 +37,7 @@ def build(spec): | |||
for st in steps: | |||
st = create_step(st) | |||
st_sha256 = st.hash(base_sha256) | |||
st_sha256 = st.hash(base_sha256, args=args) | |||
if zfs_exists_snapshot_sha256(st_sha256): | |||
base = zfs_snapshot_by_sha256(st_sha256) | |||
base_sha256 = st_sha256 | |||
@@ -47,7 +47,7 @@ def build(spec): | |||
name = root + '/' + st_sha256[:pre] | |||
if not zfs_exists(name): | |||
break | |||
snap_name = new_snapshot(base, lambda: st.execute(zfs_mountpoint(name)), name) | |||
snap_name = new_snapshot(base, lambda: st.execute(zfs_mountpoint(name), args=args), name) | |||
feed = { | |||
'focker:sha256': st_sha256 | |||
} | |||
@@ -60,6 +60,7 @@ def build(spec): | |||
def command_image_build(args): | |||
# os.chdir(args.focker_dir) | |||
fname = os.path.join(args.focker_dir, 'Fockerfile') | |||
print('fname:', fname) | |||
if not os.path.exists(fname): | |||
@@ -67,9 +68,10 @@ def command_image_build(args): | |||
with open(fname, 'r') as f: | |||
spec = yaml.safe_load(f) | |||
print('spec:', spec) | |||
image, image_sha256 = build(spec) | |||
image, image_sha256 = build(spec, args) | |||
zfs_untag(args.tag) | |||
zfs_tag(image.split('@')[0], args.tag) | |||
def command_image_untag(args): | |||
zfs_untag(args.tags) |
@@ -2,6 +2,7 @@ import hashlib | |||
import json | |||
from .jail import jail_run | |||
import shutil | |||
import os | |||
def filehash(fname): | |||
@@ -23,13 +24,13 @@ class RunStep(object): | |||
raise ValueError('Run spec must be a list or a string') | |||
self.spec = spec | |||
def hash(self, base): | |||
def hash(self, base, **kwargs): | |||
res = hashlib.sha256( | |||
json.dumps(( base, self.spec )) | |||
.encode('utf-8')).hexdigest() | |||
return res | |||
def execute(self, path): | |||
def execute(self, path, **kwargs): | |||
spec = self.spec | |||
if isinstance(spec, list): | |||
spec = ' && ' .join(self.spec) | |||
@@ -42,24 +43,28 @@ class CopyStep(object): | |||
raise ValueError('CopyStep spec should be a list') | |||
self.spec = spec | |||
def hash(self, base): | |||
def hash(self, base, args, **kwargs): | |||
if len(self.spec) == 0: | |||
fh = [] | |||
elif isinstance(self.spec[0], list): | |||
fh = list(map(lambda a: filehash(a[0]), self.spec)) | |||
fh = list(map(lambda a: filehash(os.path.join(args.focker_dir, a[0])), self.spec)) | |||
else: | |||
fh = [ filehash(self.spec[0]) ] | |||
fh = [ filehash(os.path.join(args.focker_dir, self.spec[0])) ] | |||
res = hashlib.sha256( | |||
json.dumps(( base, fh, self.spec )) | |||
.encode('utf-8')).hexdigest() | |||
return res | |||
def execute(self, path): | |||
def execute(self, path, **kwargs): | |||
lst = [ self.spec ] \ | |||
if not isinstance(self.spec[0], list) \ | |||
else self.spec | |||
for a in lst: | |||
shutil.copyfile(a[0], os.path.join(path, a[1])) | |||
source, target = a | |||
if target.startswith('/'): | |||
target = target[1:] | |||
shutil.copyfile(os.path.join(kwargs['args'].focker_dir, source), | |||
os.path.join(path, target)) | |||
def create_step(spec): | |||