PageRenderTime 15ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/silverlining/mgr-scripts/internal-request.py

https://bitbucket.org/ianb/silverlining/
Python | 107 lines | 105 code | 1 blank | 1 comment | 0 complexity | 90a0d0000d545338f127e18eb3c44f64 MD5 | raw file
Possible License(s): GPL-2.0
  1. #!/usr/bin/env python
  2. import sys
  3. sys.path.insert(0, '/usr/local/share/silverlining/lib')
  4. import os
  5. from optparse import OptionParser
  6. import shlex
  7. from silversupport.requests import internal_request
  8. from silversupport.appconfig import AppConfig
  9. from silversupport.appdata import instance_for_location, normalize_location
  10. from silversupport.shell import run
  11. parser = OptionParser(
  12. usage="%prog (--update INSTANCE_NAME) or (INSTANCE_NAME HOSTNAME PATH VAR1=value VAR2=value)",
  13. description="""\
  14. Make an internal request. If --update is given then an internal
  15. request according to the update_fetch configuration in app.ini will be
  16. run.
  17. Without --update, an arbitrary request will be run. This request will
  18. be run on the given INSTANCE_NAME regardless of hostmap.txt. Thus you
  19. can run requests on apps that have not been fully activated. Any
  20. VAR=value assignments will go into the request environ.
  21. """)
  22. parser.add_option(
  23. '--update',
  24. action='store_true',
  25. help="Run the update_fetch command on the given app_name")
  26. parser.add_option(
  27. '--update-location',
  28. action='store_true',
  29. help="Run the update_fetch command on the given location")
  30. def main():
  31. """Run the command, making an internal request"""
  32. options, args = parser.parse_args()
  33. # Buffering can happen because this isn't obviously hooked up to a
  34. # terminal (even though it is indirectly):
  35. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
  36. if options.update:
  37. return run_update(args[0], args[1])
  38. elif options.update_location:
  39. hostname, path = normalize_location(args[0])
  40. instance_name = instance_for_location(hostname, path)
  41. return run_update(instance_name, args[0])
  42. instance_name = args[0]
  43. hostname = args[1]
  44. path = args[2]
  45. environ = {}
  46. body = None
  47. if args[3:]:
  48. body = args[3] or None
  49. for arg in args[4:]:
  50. name, value = arg.split('=', 1)
  51. environ[name] = value
  52. app_config = AppConfig.from_instance_name(instance_name)
  53. status, headers, body = internal_request(
  54. app_config, hostname,
  55. path, body=body, environ=environ)
  56. write_output(status, headers, body)
  57. def write_output(status, headers, body):
  58. sys.stdout.write('%s\n' % status)
  59. sys.stdout.flush()
  60. for name, value in headers:
  61. sys.stdout.write('%s: %s\n' % (name, value))
  62. sys.stdout.flush()
  63. sys.stdout.write(body)
  64. def run_update(instance_name, hostname):
  65. """Run the --update command, running any request configured with
  66. update_fetch in app.ini"""
  67. app_config = AppConfig.from_instance_name(instance_name)
  68. for url in app_config.update_fetch:
  69. if url.startswith('script:'):
  70. script = url[len('script:'):]
  71. print 'Calling update script %s' % script
  72. call_script(app_config, script)
  73. else:
  74. print 'Fetching update URL %s' % url
  75. app_config.activate_services(os.environ)
  76. app_config.activate_path()
  77. status, headers, body = internal_request(
  78. app_config, hostname,
  79. url, environ={'silverlining.update': True},
  80. capture_stdout=False)
  81. if not status.startswith('200'):
  82. sys.stdout.write(status+'\n')
  83. sys.stdout.flush()
  84. if body:
  85. sys.stdout.write(body)
  86. if not body.endswith('\n'):
  87. sys.stdout.write('\n')
  88. sys.stdout.flush()
  89. def call_script(app_config, script):
  90. run([sys.executable, os.path.join(os.path.dirname(__file__), 'call-script.py'),
  91. app_config.app_dir] + shlex.split(script))
  92. if __name__ == '__main__':
  93. main()