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!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.2KB

  1. import hashlib
  2. import json
  3. from .jail import jail_run
  4. import shutil
  5. import os
  6. import shlex
  7. def filehash(fname):
  8. h = hashlib.sha256()
  9. with open(fname, 'rb') as f:
  10. while True:
  11. data = f.read(1024*1024*4)
  12. if not data:
  13. break
  14. h.update(data)
  15. res = h.hexdigest()
  16. return res
  17. class RunStep(object):
  18. def __init__(self, spec):
  19. if not isinstance(spec, list) and \
  20. not isinstance(spec, str):
  21. raise ValueError('Run spec must be a list or a string')
  22. self.spec = spec
  23. def hash(self, base, **kwargs):
  24. res = hashlib.sha256(
  25. json.dumps(( base, self.spec ))
  26. .encode('utf-8')).hexdigest()
  27. return res
  28. def execute(self, path, **kwargs):
  29. spec = self.spec
  30. if isinstance(spec, list):
  31. spec = ' && ' .join(self.spec)
  32. jail_run(path, spec)
  33. class CopyStep(object):
  34. def __init__(self, spec):
  35. if not isinstance(spec, list):
  36. raise ValueError('CopyStep spec should be a list')
  37. self.spec = spec
  38. def hash(self, base, args, **kwargs):
  39. if len(self.spec) == 0:
  40. fh = []
  41. elif isinstance(self.spec[0], list):
  42. fh = list(map(lambda a: filehash(os.path.join(args.focker_dir, a[0])), self.spec))
  43. else:
  44. fh = [ filehash(os.path.join(args.focker_dir, self.spec[0])) ]
  45. res = hashlib.sha256(
  46. json.dumps(( base, fh, self.spec ))
  47. .encode('utf-8')).hexdigest()
  48. return res
  49. def execute(self, path, **kwargs):
  50. lst = [ self.spec ] \
  51. if not isinstance(self.spec[0], list) \
  52. else self.spec
  53. for (source, target) in lst:
  54. target = target.strip('/')
  55. shutil.copyfile(os.path.join(kwargs['args'].focker_dir, source),
  56. os.path.join(path, target))
  57. def create_step(spec):
  58. if not isinstance(spec, dict):
  59. raise ValueError('Step specification must be a dictionary')
  60. if 'copy' in spec:
  61. return CopyStep(spec['copy'])
  62. elif 'run' in spec:
  63. return RunStep(spec['run'])
  64. raise ValueError('Unrecognized step spec: ' + json.dumps(spec))