docker.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import os
  2. import platform
  3. import stat
  4. import subprocess
  5. import sys
  6. from .compat import decode
  7. from .log import log
  8. from .system import system
  9. def docker_run(image, extra_cmds, capture=False):
  10. '''Execute commands within a docker container
  11. '''
  12. ARCH = platform.machine()
  13. if image.endswith(ARCH):
  14. bash_arg = '/pwd/run.sh'
  15. elif image.endswith('i686') and ARCH == 'x86_64':
  16. bash_arg = '-c "linux32 /pwd/run.sh"'
  17. elif image.endswith('x86_64') and ARCH == 'i686':
  18. bash_arg = '-c "linux64 /pwd/run.sh"'
  19. else:
  20. raise ValueError('Unsupported Docker image: ' + image)
  21. log('PULL', image)
  22. system(('docker', 'pull', image))
  23. script = [
  24. 'set -e',
  25. 'trap "chown -R {:}:{:} *" EXIT'.format(os.getuid(),
  26. os.getgid()),
  27. 'cd /pwd'
  28. ]
  29. script += extra_cmds
  30. with open('run.sh', 'w') as f:
  31. f.write(os.linesep.join(script))
  32. os.chmod('run.sh', stat.S_IRWXU)
  33. cmd = ' '.join(('docker', 'run', '--mount',
  34. 'type=bind,source={:},target=/pwd'.format(os.getcwd()),
  35. image, '/bin/bash', bash_arg))
  36. if capture:
  37. opts = {'stderr': subprocess.PIPE, 'stdout': subprocess.PIPE}
  38. else:
  39. opts = {}
  40. log('RUN', image)
  41. p = subprocess.Popen(cmd, shell=True, **opts)
  42. r = p.communicate()
  43. if p.returncode != 0:
  44. if p.returncode == 139:
  45. sys.stderr.write("segmentation fault when running Docker (139)\n")
  46. sys.exit(p.returncode)
  47. if capture:
  48. return decode(r[0])