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