PageRenderTime 43ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/silverlining/commands/run.py

https://bitbucket.org/ianb/silverlining/
Python | 69 lines | 65 code | 3 blank | 1 comment | 7 complexity | cceba43499125423b88fd21d79412419 MD5 | raw file
Possible License(s): GPL-2.0
  1. """Run a remote command"""
  2. import os
  3. import re
  4. from cStringIO import StringIO
  5. import zipfile
  6. from cmdutils import CommandError
  7. from silversupport.shell import ssh
  8. from silversupport.appdata import normalize_location
  9. _tmp_re = re.compile(r'tmp="(.*)"')
  10. def command_run(config):
  11. if not hasattr(config.args, 'unknown_args'):
  12. raise CommandError("You may not place any arguments before 'run'")
  13. args = config.args
  14. out = StringIO()
  15. zip = zipfile.ZipFile(out, 'w')
  16. translated_args = []
  17. any_translated = False
  18. for arg in args.unknown_args:
  19. if '=' in arg:
  20. option, filename = arg.split('=', 1)
  21. else:
  22. option = None
  23. filename = arg
  24. if os.path.exists(filename):
  25. if os.path.isdir(filename):
  26. for dirpath, dirnames, filenames in os.walk(filename):
  27. relpath = dirpath.replace('\\', '/')
  28. relpath = relpath[len(filename):].lstrip('/')
  29. for fn in filenames:
  30. zip.write(
  31. os.path.join(dirpath, fn),
  32. os.path.join(os.path.basename(filename), relpath, fn))
  33. else:
  34. ## FIXME: this basename might be unique
  35. zip.write(filename, os.path.basename(filename))
  36. translated_filename = os.path.join('$TMP', os.path.basename(filename))
  37. any_translated = True
  38. if option:
  39. translated_args.append(option + translated_filename)
  40. else:
  41. translated_args.append(translated_filename)
  42. else:
  43. translated_args.append(arg)
  44. zip.close()
  45. zip_content = out.getvalue()
  46. if args.user not in ['root', 'www-mgr', 'www-data']:
  47. raise CommandError(
  48. "Unknown --user=%s" % args.user)
  49. if any_translated:
  50. stdout, stderr, returncode = ssh(
  51. args.user, config.node_hostname, '/usr/local/share/silverlining/mgr-scripts/save-tmp-file.py',
  52. stdin=zip_content, capture_stdout=True, capture_stderr=True)
  53. match = _tmp_re.search(stdout)
  54. if not match:
  55. raise CommandError(
  56. "Got bad output from save-tmp-file.py:\n%s" % stdout)
  57. tmp_location = match.group(1)
  58. else:
  59. tmp_location = 'NONE'
  60. ssh_args = ['-t'] if args.interactive else []
  61. stdout, stderr, returncode = ssh(
  62. args.user, config.node_hostname,
  63. ['/usr/local/share/silverlining/mgr-scripts/run-command.py',
  64. args.location, tmp_location, args.script] + translated_args,
  65. ssh_args=ssh_args)
  66. return returncode