Beispiel #1
0
def main():
    """
    Main command-line execution loop.
    """
    try:
        # Parse command line options
        parser, options, arguments = parse_options()

        # Handle regular args vs -- args
        arguments = parser.largs
        remainder_arguments = parser.rargs

        # Update env with any overridden option values
        # NOTE: This needs to remain the first thing that occurs
        # post-parsing, since so many things hinge on the values in env.
        for option in env_options:
            state.env[option.dest] = getattr(options, option.dest)

        # Handle --hosts, --roles (comma separated string => list)
        for key in ['hosts', 'roles']:
            if key in state.env and isinstance(state.env[key], str):
                state.env[key] = state.env[key].split(',')

        # Handle output control level show/hide
        update_output_levels(show=options.show, hide=options.hide)

        # Handle version number option
        if options.show_version:
            print("Fabric %s" % state.env.version)
            sys.exit(0)

        # Load settings from user settings file, into shared env dict.
        state.env.update(load_settings(state.env.rcfile))

        # Find local fabfile path or abort
        fabfile = find_fabfile()
        if not fabfile:
            abort("Couldn't find any fabfiles!")

        # Store absolute path to fabfile in case anyone needs it
        state.env.real_fabfile = fabfile

        # Load fabfile (which calls its module-level code, including
        # tweaks to env values) and put its commands in the shared commands
        # dict
        commands.update(load_fabfile(fabfile))

        # Abort if no commands found
        if not commands and not remainder_arguments:
            abort("Fabfile didn't contain any commands!")

        # Now that we're settled on a fabfile, inform user.
        if state.output.debug:
            print("Using fabfile '%s'" % fabfile)

        # Handle list-commands option (now that commands are loaded)
        if options.list_commands:
            list_commands()

        # Handle show (command-specific help) option
        if options.display:
            display_command(options.display)

        # If user didn't specify any commands to run, show help
        if not (arguments or remainder_arguments):
            parser.print_help()
            sys.exit(0) # Or should it exit with error (1)?

        # Parse arguments into commands to run (plus args/kwargs/hosts)
        commands_to_run = parse_arguments(arguments)

        # Parse remainders into a faux "command" to execute
        remainder_command = parse_remainder(remainder_arguments)

        # Figure out if any specified task names are invalid
        unknown_commands = []
        for tup in commands_to_run:
            if tup[0] not in commands:
                unknown_commands.append(tup[0])

        # Abort if any unknown commands were specified
        if unknown_commands:
            abort("Command(s) not found:\n%s" \
                % indent(unknown_commands))

        # Generate remainder command and insert into commands, commands_to_run
        if remainder_command:
            r = '<remainder>'
            commands[r] = lambda: api.run(remainder_command)
            commands_to_run.append((r, [], {}, [], []))

        # At this point all commands must exist, so execute them in order.
        for name, args, kwargs, cli_hosts, cli_roles in commands_to_run:
            # Get callable by itself
            command = commands[name]
            # Set current command name (used for some error messages)
            state.env.command = name
            # Set host list (also copy to env)
            state.env.all_hosts = hosts = get_hosts(
                command, cli_hosts, cli_roles)
            # If hosts found, execute the function on each host in turn
            for host in hosts:
                username, hostname, port = normalize(host)
                state.env.host_string = host
                state.env.host = hostname
                # Preserve user
                prev_user = state.env.user
                state.env.user = username
                state.env.port = port
                # Log to stdout
                if state.output.running:
                    print("[%s] Executing task '%s'" % (host, name))
                # Actually run command
                commands[name](*args, **kwargs)
                # Put old user back
                state.env.user = prev_user
            # If no hosts found, assume local-only and run once
            if not hosts:
                commands[name](*args, **kwargs)
        # If we got here, no errors occurred, so print a final note.
        if state.output.status:
            print("\nDone.")
    except SystemExit:
        # a number of internal functions might raise this one.
        raise
    except KeyboardInterrupt:
        if state.output.status:
            print >> sys.stderr, "\nStopped."
        sys.exit(1)
    except:
        sys.excepthook(*sys.exc_info())
        # we might leave stale threads if we don't explicitly exit()
        sys.exit(1)
    finally:
        # Explicitly disconnect from all servers
        for key in connections.keys():
            if state.output.status:
                print "Disconnecting from %s..." % denormalize(key),
            connections[key].close()
            if state.output.status:
                print "done."
    sys.exit(0)
Beispiel #2
0
def main():
    """
    Main command-line execution loop.
    """
    try:
        # Parse command line options
        parser, options, arguments = parse_options()

        # Handle regular args vs -- args
        arguments = parser.largs
        remainder_arguments = parser.rargs

        # Update env with any overridden option values
        # NOTE: This needs to remain the first thing that occurs
        # post-parsing, since so many things hinge on the values in env.
        for option in env_options:
            env[option.dest] = getattr(options, option.dest)

        # Handle --hosts, --roles (comma separated string => list)
        for key in ['hosts', 'roles']:
            if key in env and isinstance(env[key], str):
                env[key] = env[key].split(',')

        # Handle output control level show/hide
        update_output_levels(show=options.show, hide=options.hide)

        # Handle version number option
        if options.show_version:
            print("Fabric %s" % env.version)
            sys.exit(0)

        # Load settings from user settings file, into shared env dict.
        env.update(load_settings(env.rcfile))

        # Find local fabfile path or abort
        fabfile = find_fabfile()
        if not fabfile and not remainder_arguments:
            abort("Couldn't find any fabfiles!")

        # Store absolute path to fabfile in case anyone needs it
        env.real_fabfile = fabfile

        # Load fabfile (which calls its module-level code, including
        # tweaks to env values) and put its commands in the shared commands
        # dict
        if fabfile:
            docstring, callables = load_fabfile(fabfile)
            commands.update(callables)

        # Autocompletion support
        autocomplete_items = [cmd.replace('_', '-') for cmd in commands]
        if 'autocomplete' in env:
            autocomplete_items += env.autocomplete

        autocomplete(parser, ListCompleter(autocomplete_items))

        # Handle hooks related options
        _disable_hooks = options.disable_hooks
        _enable_hooks = options.enable_hooks

        if _disable_hooks:
            for _hook in _disable_hooks.strip().split():
                DISABLED_HOOKS.append(_hook.strip())

        if _enable_hooks:
            for _hook in _enable_hooks.strip().split():
                ENABLED_HOOKS.append(_hook.strip())

        # Handle the non-execution flow
        if not arguments and not remainder_arguments:

            # Non-verbose command list
            if options.shortlist:
                shortlist()

            # Handle show (command-specific help) option
            if options.display:
                display_command(options.display)

            # Else, show the list of commands and exit
            list_commands(docstring)

        # Now that we're settled on a fabfile, inform user.
        if output.debug:
            if fabfile:
                print("Using fabfile '%s'" % fabfile)
            else:
                print("No fabfile loaded -- remainder command only")

        # Parse arguments into commands to run (plus args/kwargs/hosts)
        commands_to_run, env_update = parse_arguments(arguments)
        env.update(env_update)

        # Parse remainders into a faux "command" to execute
        remainder_command = parse_remainder(remainder_arguments)

        # Figure out if any specified task names are invalid
        unknown_commands = []
        for tup in commands_to_run:
            if tup[0] not in commands:
                unknown_commands.append(tup[0])

        # Abort if any unknown commands were specified
        if unknown_commands:
            abort("Command(s) not found:\n%s" \
                % indent(unknown_commands))

        # Generate remainder command and insert into commands, commands_to_run
        if remainder_command:
            r = '<remainder>'
            commands[r] = lambda: api.run(remainder_command)
            commands_to_run.append((r, [], {}, [], []))

        if output.debug:
            names = ", ".join(x[0] for x in commands_to_run)
            print("Commands to run: %s" % names)

        call_hooks('commands.before', commands, commands_to_run)

        # Initialse context runner
        env()

        # Initialise the default stage if none are given as the first command.
        if 'stages' in env:
            if commands_to_run[0][0] not in env.stages:
                execute_command(
                    (env.stages[0], (), {}, None, None, None), commands
                    )
            else:
                execute_command(commands_to_run.pop(0), commands)

        if env.config_file:
            config_path = realpath(expanduser(env.config_file))
            config_path = join(dirname(fabfile), config_path)
            config_file = open(config_path, 'rb')
            config = load_yaml(config_file.read())
            if not config:
                env.config = AttributeDict()
            elif not isinstance(config, dict):
                abort("Invalid config file found at %s" % config_path)
            else:
                env.config = AttributeDict(config)
            config_file.close()

        call_hooks('config.loaded')
        first_time_env_call = 1

        # At this point all commands must exist, so execute them in order.
        for spec in commands_to_run:
            execute_command(spec, commands)

        # If we got here, no errors occurred, so print a final note.
        if output.status:
            msg = "\nDone."
            if env.colors:
                msg = env.color_settings['finish'](msg)
            print(msg)

    except SystemExit:
        # a number of internal functions might raise this one.
        raise
    except KeyboardInterrupt:
        if output.status:
            msg = "\nStopped."
            if env.colors:
                msg = env.color_settings['finish'](msg)
            print >> sys.stderr, msg
        sys.exit(1)
    except:
        sys.excepthook(*sys.exc_info())
        # we might leave stale threads if we don't explicitly exit()
        sys.exit(1)
    finally:
        call_hooks('commands.after')
        disconnect_all()
    sys.exit(0)
Beispiel #3
0
    :type config_params: dict
    """
    try:
        if isinstance(name, ModuleType):
            m = name
            name = m.__name__
        else:
            m = import_module("{0}.{1}".format(NAME_LIB, name))
    except Exception, e:
        abort("Can't import recipe {0}: {1}".format(name, e))
    docstring, new_style, classic, default = load_tasks_from_module(m)

    tasks = new_style if env.new_style_tasks else classic

    _configure_module_config(m, _namespace_from(m), config_params)
    commands.update(_make_recipe_dict(tasks, _namespace_from(namespace)))
    puts("{0} recipe configured".format(name))
    return True


def _recipe_repr(recipe):
    """Configure recipe

    :param recipe: recipe item (list, string)
    :type param: string, tuple, list
    """
    if isinstance(recipe, (str, unicode)):
        return recipe
    elif isinstance(recipe, ModuleType):
        return recipe.__name__
    elif isinstance(recipe, (tuple, list)):
Beispiel #4
0
def main():
    """
    Main command-line execution loop.
    """
    try:
        # Parse command line options
        parser, options, arguments = parse_options()

        # Handle regular args vs -- args
        arguments = parser.largs
        remainder_arguments = parser.rargs

        # Update env with any overridden option values
        # NOTE: This needs to remain the first thing that occurs
        # post-parsing, since so many things hinge on the values in env.
        for option in env_options:
            env[option.dest] = getattr(options, option.dest)

        # Handle --hosts, --roles (comma separated string => list)
        for key in ['hosts', 'roles']:
            if key in env and isinstance(env[key], str):
                env[key] = env[key].split(',')

        # Handle output control level show/hide
        update_output_levels(show=options.show, hide=options.hide)

        # Handle version number option
        if options.show_version:
            print("Fabric %s" % env.version)
            sys.exit(0)

        # Load settings from user settings file, into shared env dict.
        env.update(load_settings(env.rcfile))

        # Find local fabfile path or abort
        fabfile = find_fabfile()
        if not fabfile and not remainder_arguments:
            abort("Couldn't find any fabfiles!")

        # Store absolute path to fabfile in case anyone needs it
        env.real_fabfile = fabfile

        # Load fabfile (which calls its module-level code, including
        # tweaks to env values) and put its commands in the shared commands
        # dict
        if fabfile:
            docstring, callables = load_fabfile(fabfile)
            commands.update(callables)

        # Autocompletion support
        autocomplete_items = [cmd.replace('_', '-') for cmd in commands]
        if 'autocomplete' in env:
            autocomplete_items += env.autocomplete

        autocomplete(parser, ListCompleter(autocomplete_items))

        # Handle hooks related options
        _disable_hooks = options.disable_hooks
        _enable_hooks = options.enable_hooks

        if _disable_hooks:
            for _hook in _disable_hooks.strip().split():
                DISABLED_HOOKS.append(_hook.strip())

        if _enable_hooks:
            for _hook in _enable_hooks.strip().split():
                ENABLED_HOOKS.append(_hook.strip())

        # Handle the non-execution flow
        if not arguments and not remainder_arguments:

            # Non-verbose command list
            if options.shortlist:
                shortlist()

            # Handle show (command-specific help) option
            if options.display:
                display_command(options.display)

            # Else, show the list of commands and exit
            list_commands(docstring)

        # Now that we're settled on a fabfile, inform user.
        if output.debug:
            if fabfile:
                print("Using fabfile '%s'" % fabfile)
            else:
                print("No fabfile loaded -- remainder command only")

        # Parse arguments into commands to run (plus args/kwargs/hosts)
        commands_to_run, env_update = parse_arguments(arguments)
        env.update(env_update)

        # Parse remainders into a faux "command" to execute
        remainder_command = parse_remainder(remainder_arguments)

        # Figure out if any specified task names are invalid
        unknown_commands = []
        for tup in commands_to_run:
            if tup[0] not in commands:
                unknown_commands.append(tup[0])

        # Abort if any unknown commands were specified
        if unknown_commands:
            abort("Command(s) not found:\n%s" \
                % indent(unknown_commands))

        # Generate remainder command and insert into commands, commands_to_run
        if remainder_command:
            r = '<remainder>'
            commands[r] = lambda: api.run(remainder_command)
            commands_to_run.append((r, [], {}, [], []))

        if output.debug:
            names = ", ".join(x[0] for x in commands_to_run)
            print("Commands to run: %s" % names)

        call_hooks('commands.before', commands, commands_to_run)

        # Initialse context runner
        env()

        # Initialise the default stage if none are given as the first command.
        if 'stages' in env:
            if commands_to_run[0][0] not in env.stages:
                execute_command(
                    (env.stages[0], (), {}, None, None, None), commands
                    )
            else:
                execute_command(commands_to_run.pop(0), commands)

        if env.config_file:
            config_path = realpath(expanduser(env.config_file))
            config_path = join(dirname(fabfile), config_path)
            config_file = open(config_path, 'rb')
            config = load_yaml(config_file.read())
            if not config:
                env.config = AttributeDict()
            elif not isinstance(config, dict):
                abort("Invalid config file found at %s" % config_path)
            else:
                env.config = AttributeDict(config)
            config_file.close()

        call_hooks('config.loaded')
        first_time_env_call = 1

        # At this point all commands must exist, so execute them in order.
        for spec in commands_to_run:
            execute_command(spec, commands)

        # If we got here, no errors occurred, so print a final note.
        if output.status:
            msg = "\nDone."
            if env.colors:
                msg = env.color_settings['finish'](msg)
            print(msg)

    except SystemExit:
        # a number of internal functions might raise this one.
        raise
    except KeyboardInterrupt:
        if output.status:
            msg = "\nStopped."
            if env.colors:
                msg = env.color_settings['finish'](msg)
            print >> sys.stderr, msg
        sys.exit(1)
    except:
        sys.excepthook(*sys.exc_info())
        # we might leave stale threads if we don't explicitly exit()
        sys.exit(1)
    finally:
        call_hooks('commands.after')
        disconnect_all()
    sys.exit(0)
Beispiel #5
0
def main():
    """
    Main command-line execution loop.
    """
    try:
        # Parse command line options
        parser, options, arguments = parse_options()

        # Handle regular args vs -- args
        arguments = parser.largs
        remainder_arguments = parser.rargs

        # Update env with any overridden option values
        # NOTE: This needs to remain the first thing that occurs
        # post-parsing, since so many things hinge on the values in env.
        for option in env_options:
            state.env[option.dest] = getattr(options, option.dest)

        # Handle --hosts, --roles (comma separated string => list)
        for key in ['hosts', 'roles']:
            if key in state.env and isinstance(state.env[key], str):
                state.env[key] = state.env[key].split(',')

        # Handle output control level show/hide
        update_output_levels(show=options.show, hide=options.hide)

        # Handle version number option
        if options.show_version:
            print("Fabric %s" % state.env.version)
            sys.exit(0)

        # Handle case where we were called bare, i.e. just "fab", and print
        # a help message.
        actions = (options.list_commands, options.shortlist, options.display,
                   arguments, remainder_arguments)
        if not any(actions):
            parser.print_help()
            sys.exit(1)

        # Load settings from user settings file, into shared env dict.
        state.env.update(load_settings(state.env.rcfile))

        # Find local fabfile path or abort
        fabfile = find_fabfile()
        if not fabfile and not remainder_arguments:
            abort("Couldn't find any fabfiles!")

        # Store absolute path to fabfile in case anyone needs it
        state.env.real_fabfile = fabfile

        # Load fabfile (which calls its module-level code, including
        # tweaks to env values) and put its commands in the shared commands
        # dict
        if fabfile:
            docstring, callables = load_fabfile(fabfile)
            commands.update(callables)

        # Abort if no commands found
        if not commands and not remainder_arguments:
            abort("Fabfile didn't contain any commands!")

        # Now that we're settled on a fabfile, inform user.
        if state.output.debug:
            if fabfile:
                print("Using fabfile '%s'" % fabfile)
            else:
                print("No fabfile loaded -- remainder command only")

        # Non-verbose command list
        if options.shortlist:
            shortlist()

        # Handle list-commands option (now that commands are loaded)
        if options.list_commands:
            list_commands(docstring)

        # Handle show (command-specific help) option
        if options.display:
            display_command(options.display)

        # If user didn't specify any commands to run, show help
        if not (arguments or remainder_arguments):
            parser.print_help()
            sys.exit(0)  # Or should it exit with error (1)?

        # Parse arguments into commands to run (plus args/kwargs/hosts)
        commands_to_run = parse_arguments(arguments)

        # Parse remainders into a faux "command" to execute
        remainder_command = parse_remainder(remainder_arguments)

        # Figure out if any specified task names are invalid
        unknown_commands = []
        for tup in commands_to_run:
            if tup[0] not in commands:
                unknown_commands.append(tup[0])

        # Abort if any unknown commands were specified
        if unknown_commands:
            abort("Command(s) not found:\n%s" \
                % indent(unknown_commands))

        # Generate remainder command and insert into commands, commands_to_run
        if remainder_command:
            r = '<remainder>'
            commands[r] = lambda: api.run(remainder_command)
            commands_to_run.append((r, [], {}, [], []))

        if state.output.debug:
            names = ", ".join(x[0] for x in commands_to_run)
            print("Commands to run: %s" % names)

        # At this point all commands must exist, so execute them in order.
        for name, args, kwargs, cli_hosts, cli_roles in commands_to_run:
            # Get callable by itself
            command = commands[name]
            # Set current command name (used for some error messages)
            state.env.command = name
            # Set host list (also copy to env)
            state.env.all_hosts = hosts = get_hosts(command, cli_hosts,
                                                    cli_roles)
            # If hosts found, execute the function on each host in turn
            for host in hosts:
                # Preserve user
                prev_user = state.env.user
                # Split host string and apply to env dict
                username, hostname, port = interpret_host_string(host)
                # Log to stdout
                if state.output.running:
                    print("[%s] Executing task '%s'" % (host, name))
                # Actually run command
                commands[name](*args, **kwargs)
                # If interpret_host_string modified the user, restore it
                if state.env.user == username:
                    state.env.user = prev_user
            # If no hosts found, assume local-only and run once
            if not hosts:
                commands[name](*args, **kwargs)
        # If we got here, no errors occurred, so print a final note.
        if state.output.status:
            print("\nDone.")
    except SystemExit:
        # a number of internal functions might raise this one.
        raise
    except KeyboardInterrupt:
        if state.output.status:
            print >> sys.stderr, "\nStopped."
        sys.exit(1)
    except:
        sys.excepthook(*sys.exc_info())
        # we might leave stale threads if we don't explicitly exit()
        sys.exit(1)
    finally:
        disconnect_all()
    sys.exit(0)