Ejemplo n.º 1
0
def parse_args(parser, argv=None):
    """Parse aguments."""
    # Parse general arguments, extract the command, add command-specific
    # arguments, and then re-parse everything again.
    # The argparse module provides subparser support, and we could have
    # used that. However, there a serious usability issue with that, because
    # "command <subcmd> --foo" is an error if --foo is a valid argument
    # for command but not for the sub-command. Given that is very common
    # to mistakenly pass options out of order, we imlement our own solution
    # here that accepts the options in this case.
    try:
        args = parser.parse_args(argv)
    except argparse.ParseError as e:
        args = e.namespace
        if not (args.help or args.version) and not args.subcmd:
            console.write_err(parser.format_usage())
            console.error(str(e))
            error.exit(error.EX_USAGE)
    if args.help and not args.subcmd:
        console.write_err(parser.format_help())
        error.exit(error.EX_OK)
    if args.version and not args.subcmd:
        console.writeln_err(_version.version_string)
        error.exit(error.EX_OK)
    subcmd = args.subcmd
    if subcmd not in subcommands:
        console.error("Unknown command: '{0}'.", subcmd)
        error.exit(error.EX_USAGE)
    add_args = subcommands[subcmd][1]
    add_args(parser)
    try:
        args = parser.parse_args(argv)
    except argparse.ParseError as e:
        args = e.namespace
        if not args.help:
            console.write_err(parser.format_usage())
            console.error(str(e))
            error.exit(error.EX_USAGE)
    if args.help:
        console.write_err(parser.format_help())
        error.exit(error.EX_OK)
    return args
Ejemplo n.º 2
0
def main(argv=None):
    """The "ravtest" main entry point."""
    if sys.platform.startswith('win'):
        console.error('Windows is not currently supported by "ravtest".\n'
                      'Please use the Fabric front-end.')
        error.exit(1)
    parser = create_parser()
    args = parse_args(parser, argv)
    create_environment(args)
    setup_logging()
    command = subcommands[args.subcmd][0]
    try:
        ret = command(args, env)
    except KeyboardInterrupt:
        console.complete_partial_line()
        console.writeln('Exiting at user request.')
        ret = error.EX_INTERRUPTED
    except SystemExit as e:
        console.complete_partial_line()
        if env.debug:
            console.error('SystemExit caught')
            lines = traceback.format_exception(*sys.exc_info())
            console.writeln_err('Raised from:')
            console.writeln_err(''.join(lines))
        ret = e[0]
    except Exception as e:
        console.complete_partial_line()
        console.error(str(e))
        if env.debug:
            lines = ['An uncaught exception occurred:']
            lines += traceback.format_exception(*sys.exc_info())
            console.writeln_err()
            console.writeln_err(''.join(lines))
            console.writeln_err('Environment: {!r}'.format(env))
        ret = getattr(e, 'exitstatus', error.EX_SOFTWARE)
    return ret
Ejemplo n.º 3
0
def run_all_tasks(app, vms):
    """Run the runbook for an application ``app``."""
    hosts = []
    host_info = {}
    appname = app['name'].split(':')[1]
    for appdef in env.manifest['applications']:
        if appdef['name'] == appname:
            break
    else:
        error.raise_error('Application definition not found?')

    for vm in app['vms']:
        if vm['name'] not in vms:
            continue
        ipaddr = vm['dynamicMetadata']['externalIp']
        hosts.append(ipaddr)
        host_info[ipaddr] = vm['name']

    env.test_id = os.urandom(16).encode('hex')
    console.info('Starting run `{0}`.', env.test_id)
    env.host_info = host_info
    env.start_time = int(time.time())
    env.lock = multiprocessing.Lock()
    manager = multiprocessing.Manager()
    env.shared_state = manager.dict()
    for vmname in vms:
        vmstate = {}
        vmstate['exited'] = False
        vmstate['completed_tasks'] = {}
        vmstate['shell_env_update'] = {}
        env.shared_state[vmname] = vmstate
    env.appdef = appdef
    env.application = app
    env.vms = vms

    fab.env.user = '******'
    fab.env.key_filename = env.private_key_file
    fab.env.disable_known_hosts = True
    fab.env.remote_interrupt = True
    fab.env.hosts = hosts
    fab.env.parallel = True
    fab.env.output_prefix = env.debug
    fabric.state.output.running = env.debug
    fabric.state.output.output = True
    fabric.state.output.status = env.debug

    # This is where it all happens...
    noun = inflect.plural_noun('virtual machine', len(vms))
    console.info('Executing tasks on {0} {1}...', len(vms), noun)

    fabric.tasks.execute(run_tasklist, env)

    errors = set()
    for vmname in vms:
        vmstate = env.shared_state[vmname]
        for taskname,status in vmstate['completed_tasks'].items():
            if status != 0:
                errors.add('`{0}` on `{1}`'.format(taskname, vmname))

    if not errors:
        console.info('All tasks were executed succesfully!')
    else:
        what = inflect.plural_noun('task', len(errors))
        errapps = ', '.join(errors)
        console.error('The following {0} failed: {1}', what, errapps)

    fabric.network.disconnect_all()
    return len(errors)