|
@@ -1,5 +1,7 @@ |
|
|
import hashlib
|
|
|
import hashlib
|
|
|
import json
|
|
|
import json
|
|
|
|
|
|
from jail import jail_run
|
|
|
|
|
|
import shutil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def filehash(fname):
|
|
|
def filehash(fname):
|
|
@@ -15,25 +17,32 @@ def filehash(fname): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RunStep(object):
|
|
|
class RunStep(object):
|
|
|
def __init__(self, base, spec):
|
|
|
|
|
|
self.base = base
|
|
|
|
|
|
|
|
|
def __init__(self, spec):
|
|
|
|
|
|
if not isinstance(spec, list) and \
|
|
|
|
|
|
not isinstance(spec, str):
|
|
|
|
|
|
raise ValueError('Run spec must be a list or a string')
|
|
|
self.spec = spec
|
|
|
self.spec = spec
|
|
|
|
|
|
|
|
|
def hash(self):
|
|
|
|
|
|
|
|
|
def hash(self, base):
|
|
|
res = hashlib.sha256(
|
|
|
res = hashlib.sha256(
|
|
|
json.dumps(( self.base, self.spec ))
|
|
|
|
|
|
|
|
|
json.dumps(( base, self.spec ))
|
|
|
.encode('utf-8')).hexdigest()
|
|
|
.encode('utf-8')).hexdigest()
|
|
|
return res
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
def execute(self, path):
|
|
|
|
|
|
spec = self.spec
|
|
|
|
|
|
if isinstance(spec, list)
|
|
|
|
|
|
spec = ' && ' .join(self.spec)
|
|
|
|
|
|
jail_run(path, spec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CopyStep(object):
|
|
|
class CopyStep(object):
|
|
|
def __init__(self, base, spec):
|
|
|
|
|
|
|
|
|
def __init__(self, spec):
|
|
|
if not isinstance(spec, list):
|
|
|
if not isinstance(spec, list):
|
|
|
raise ValueError('CopyStep spec should be a list')
|
|
|
raise ValueError('CopyStep spec should be a list')
|
|
|
self.base = base
|
|
|
|
|
|
self.spec = spec
|
|
|
self.spec = spec
|
|
|
|
|
|
|
|
|
def hash(self):
|
|
|
|
|
|
|
|
|
def hash(self, base):
|
|
|
if len(self.spec) == 0:
|
|
|
if len(self.spec) == 0:
|
|
|
fh = []
|
|
|
fh = []
|
|
|
elif isinstance(self.spec[0], list):
|
|
|
elif isinstance(self.spec[0], list):
|
|
@@ -41,6 +50,23 @@ class CopyStep(object): |
|
|
else:
|
|
|
else:
|
|
|
fh = [ filehash(self.spec[0]) ]
|
|
|
fh = [ filehash(self.spec[0]) ]
|
|
|
res = hashlib.sha256(
|
|
|
res = hashlib.sha256(
|
|
|
json.dumps(( self.base, fh, self.spec ))
|
|
|
|
|
|
|
|
|
json.dumps(( base, fh, self.spec ))
|
|
|
.encode('utf-8')).hexdigest()
|
|
|
.encode('utf-8')).hexdigest()
|
|
|
return res
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
def execute(self, path):
|
|
|
|
|
|
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]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_step(spec):
|
|
|
|
|
|
if not isinstance(spec, dict):
|
|
|
|
|
|
raise ValueError('Step specification must be a dictionary')
|
|
|
|
|
|
if 'copy' in spec:
|
|
|
|
|
|
return CopyStep(spec['copy'])
|
|
|
|
|
|
elif 'run' in spec:
|
|
|
|
|
|
return RunStep(spec['run'])
|
|
|
|
|
|
raise ValueError('Unrecognized step spec: ' + json.dumps(spec))
|