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.

78 line
2.3KB

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