Example #1
0
def main():
    """Command line interface for the ``dwim`` program."""
    from dwim import DEFAULT_PROFILE, dwim
    # Initialize logging to the terminal.
    coloredlogs.install()
    # Define the command line option defaults.
    profile_script = DEFAULT_PROFILE
    # Parse the command line arguments.
    try:
        options, _ = getopt.getopt(sys.argv[1:], 'c:vqh', [
            'config=', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-c', '--config'):
                profile_script = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Execute the requested action(s).
    try:
        dwim(profile_script)
    except Exception:
        logger.exception("Caught a fatal exception! Terminating ..")
        sys.exit(1)
Example #2
0
def cryptdisks_stop_cli():
    """
    Usage: cryptdisks-stop-fallback NAME

    Reads /etc/crypttab and locks the encrypted filesystem with the given NAME.

    This program emulates the functionality of Debian's cryptdisks_stop program,
    but it only supports LUKS encryption and a small subset of the available
    encryption options.
    """
    # Enable logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Get the name of the encrypted filesystem from the command line arguments
    # and show a simple usage message when no name is given as an argument.
    try:
        target = sys.argv[1]
    except IndexError:
        usage(dedent(cryptdisks_stop_cli.__doc__))
    else:
        # Call our Python implementation of `cryptdisks_stop'.
        try:
            cryptdisks_stop(target)
        except ValueError as e:
            # cryptdisks_stop() raises ValueError when the given target isn't
            # listed in /etc/crypttab. This doesn't deserve a traceback on the
            # terminal.
            warning("Error: %s", e)
            sys.exit(1)
        except Exception as e:
            # Any other exceptions are logged to the terminal and system log.
            logger.exception("Aborting due to exception!")
            sys.exit(1)
Example #3
0
def main():
    """Command line interface for the ``coloredlogs`` program."""
    actions = []
    try:
        # Parse the command line arguments.
        options, arguments = getopt.getopt(sys.argv[1:], 'cdh', [
            'convert', 'to-html', 'demo', 'help',
        ])
        # Map command line options to actions.
        for option, value in options:
            if option in ('-c', '--convert', '--to-html'):
                actions.append(functools.partial(convert_command_output, *arguments))
                arguments = []
            elif option in ('-d', '--demo'):
                actions.append(demonstrate_colored_logging)
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Programming error: Unhandled option!"
        if not actions:
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    for function in actions:
        function()
Example #4
0
def main():
    """Command line interface for the ``auto-adjust-display-brightness`` program."""
    # Initialize logging to the terminal.
    coloredlogs.install()
    # Parse the command line arguments.
    step_brightness = None
    try:
        options, arguments = getopt.getopt(
            sys.argv[1:], 'fvqh', ['force', 'verbose', 'quiet', 'help'])
        for option, value in options:
            if option in ('-f', '--force'):
                step_brightness = False
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Load the configuration file(s).
    try:
        config = load_config()
    except ConfigurationError as e:
        warning("%s", e)
        sys.exit(1)
    # Determine whether to change the brightness at once or gradually.
    if step_brightness is None:
        if find_system_uptime() < 60 * 5:
            logger.info(
                "Changing brightness at once (system has just booted).")
            step_brightness = False
        else:
            logger.info(
                "Changing brightness gradually (system has been running for a while)."
            )
            step_brightness = True
    else:
        logger.info("Changing brightness at once (-f or --force was given).")
    # Change the brightness of the configured display(s).
    dark_outside = is_it_dark_outside(
        latitude=float(config['location']['latitude']),
        longitude=float(config['location']['longitude']),
        elevation=float(config['location']['elevation']))
    method = 'decrease_brightness' if dark_outside else 'increase_brightness'
    num_success, num_failed = 0, 0
    for controller in config['controllers']:
        try:
            getattr(controller, method)(10 if step_brightness else 100)
            num_success += 1
        except Exception as e:
            logger.warning("Failed to change brightness of %s! (%s)",
                           controller, e)
            num_failed += 1
    if num_failed > 0 and num_success == 0:
        sys.exit(1)
Example #5
0
def parse_arguments(arguments):
    """
    Parse the command line arguments.

    :param arguments: A list of strings with command line arguments.
    :returns: ``True`` if a dry run was requested, ``False`` otherwise.
    """
    dry_run = False
    try:
        options, arguments = getopt.gnu_getopt(
            arguments, 'nvqh', ['dry-run', 'verbose', 'quiet', 'help'])
        for option, value in options:
            if option in ('-n', '--dry-run'):
                dry_run = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(USAGE_TEXT)
                sys.exit(0)
            else:
                assert False, "Unhandled option!"
        return dry_run
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
Example #6
0
def parse_arguments(arguments):
    """
    Parse the command line arguments.

    :param arguments: A list of strings with command line options and/or arguments.
    :returns: A list of strings with the positional arguments.
    """
    try:
        options, arguments = getopt.gnu_getopt(arguments, 'vqh', [
            'verbose', 'quiet', 'help'
        ])
        for option, value in options:
            if option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(USAGE_TEXT)
                sys.exit(0)
            else:
                assert False, "Unhandled option!"
        if not arguments:
            usage(USAGE_TEXT)
            sys.exit(0)
        return arguments
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
Example #7
0
def main():
    """Command line interface for the ``coloredlogs`` program."""
    actions = []
    try:
        # Parse the command line arguments.
        options, arguments = getopt.getopt(sys.argv[1:], 'cdh', [
            'convert', 'to-html', 'demo', 'help',
        ])
        # Map command line options to actions.
        for option, value in options:
            if option in ('-c', '--convert', '--to-html'):
                actions.append(functools.partial(convert_command_output, *arguments))
                arguments = []
            elif option in ('-d', '--demo'):
                actions.append(demonstrate_colored_logging)
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Programming error: Unhandled option!"
        if not actions:
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    for function in actions:
        function()
Example #8
0
def main():
    """Command line interface for the ``qpass`` program."""
    # Initialize logging to the terminal.
    coloredlogs.install()
    # Prepare for command line argument parsing.
    action = show_matching_entry
    program_opts = dict(exclude_list=[])
    show_opts = dict(filters=[], use_clipboard=is_clipboard_supported())
    verbosity = 0
    # Parse the command line arguments.
    try:
        options, arguments = getopt.gnu_getopt(
            sys.argv[1:],
            "elnp:f:x:vqh",
            ["edit", "list", "no-clipboard", "password-store=", "filter=", "exclude=", "verbose", "quiet", "help"],
        )
        for option, value in options:
            if option in ("-e", "--edit"):
                action = edit_matching_entry
            elif option in ("-l", "--list"):
                action = list_matching_entries
            elif option in ("-n", "--no-clipboard"):
                show_opts["use_clipboard"] = False
            elif option in ("-p", "--password-store"):
                stores = program_opts.setdefault("stores", [])
                stores.append(PasswordStore(directory=value))
            elif option in ("-f", "--filter"):
                show_opts["filters"].append(value)
            elif option in ("-x", "--exclude"):
                program_opts["exclude_list"].append(value)
            elif option in ("-v", "--verbose"):
                coloredlogs.increase_verbosity()
                verbosity += 1
            elif option in ("-q", "--quiet"):
                coloredlogs.decrease_verbosity()
                verbosity -= 1
            elif option in ("-h", "--help"):
                usage(__doc__)
                return
            else:
                raise Exception("Unhandled option! (programming error)")
        if not (arguments or action == list_matching_entries):
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Execute the requested action.
    try:
        show_opts["quiet"] = verbosity < 0
        kw = show_opts if action == show_matching_entry else {}
        action(QuickPass(**program_opts), arguments, **kw)
    except PasswordStoreError as e:
        # Known issues don't get a traceback.
        logger.error("%s", e)
        sys.exit(1)
    except KeyboardInterrupt:
        # If the user interrupted an interactive prompt they most likely did so
        # intentionally, so there's no point in generating more output here.
        sys.exit(1)
Example #9
0
def main():
    """Command line interface for the ``negotiator-guest`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    list_commands = False
    execute_command = None
    start_daemon = False
    timeout = DEFAULT_TIMEOUT
    character_device = None
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'le:dt:c:vqh', [
            'list-commands', 'execute=', 'daemon', 'timeout=',
            'character-device=', 'verbose', 'quiet', 'help'
        ])
        for option, value in options:
            if option in ('-l', '--list-commands'):
                list_commands = True
            elif option in ('-e', '--execute'):
                execute_command = value
            elif option in ('-d', '--daemon'):
                start_daemon = True
            elif option in ('-t', '--timeout'):
                timeout = int(value)
            elif option in ('-c', '--character-device'):
                character_device = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
        if not (list_commands or execute_command or start_daemon):
            usage(__doc__)
            sys.exit(0)
    except Exception:
        warning("Error: Failed to parse command line arguments!")
        sys.exit(1)
    # Start the guest daemon.
    try:
        if not character_device:
            channel_name = HOST_TO_GUEST_CHANNEL_NAME if start_daemon else GUEST_TO_HOST_CHANNEL_NAME
            character_device = find_character_device(channel_name)
        ga = GuestAgent(character_device)
        if start_daemon:
            ga.enter_main_loop()
        elif list_commands:
            with TimeOut(timeout):
                print('\n'.join(ga.call_remote_method('list_commands')))
        elif execute_command:
            with TimeOut(timeout):
                timer = Timer()
                output = ga.call_remote_method('execute', *shlex.split(execute_command), capture=True)
                logger.debug("Took %s to execute remote command.", timer)
                print(output.rstrip())
    except Exception:
        logger.exception("Caught a fatal exception! Terminating ..")
        sys.exit(1)
def main():
    """Command line interface for ``debuntu-nodejs-installer``."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    silence_urllib_logger()
    # Parse the command line arguments.
    action = None
    context_opts = dict()
    installer_opts = dict()
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'iV:s:r:vqh', [
            'install',
            'version=',
            'sources-file=',
            'remote-host=',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-i', '--install'):
                action = 'install'
            elif option in ('-V', '--version'):
                installer_opts['nodejs_version'] = value
            elif option in ('-s', '--sources-file'):
                installer_opts['sources_file'] = value
            elif option in ('-r', '--remote-host'):
                context_opts['ssh_alias'] = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                raise Exception("Unhandled option!")
        if arguments:
            raise Exception(
                "This program doesn't accept any positional arguments!")
        if not action:
            usage(__doc__)
            sys.exit(0)
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Execute the requested action.
    context = create_context(**context_opts)
    try:
        installer = NodeInstaller(context=context, **installer_opts)
        getattr(installer, action)()
    except (UnsupportedSystemError, ExternalCommandFailed) as e:
        logger.error("%s", e)
        sys.exit(1)
    except Exception:
        logger.exception("Encountered unexpected exception on %s!", context)
        sys.exit(1)
Example #11
0
def main():
    """Command line interface for the ``humanfriendly`` program."""
    enable_ansi_support()
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'cd:l:n:s:bt:h', [
            'run-command',
            'format-table',
            'delimiter=',
            'format-length=',
            'format-number=',
            'format-size=',
            'binary',
            'format-timespan=',
            'parse-length=',
            'parse-size=',
            'demo',
            'help',
        ])
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    actions = []
    delimiter = None
    should_format_table = False
    binary = any(o in ('-b', '--binary') for o, v in options)
    for option, value in options:
        if option in ('-d', '--delimiter'):
            delimiter = value
        elif option == '--parse-size':
            actions.append(functools.partial(print_parsed_size, value))
        elif option == '--parse-length':
            actions.append(functools.partial(print_parsed_length, value))
        elif option in ('-c', '--run-command'):
            actions.append(functools.partial(run_command, arguments))
        elif option in ('-l', '--format-length'):
            actions.append(functools.partial(print_formatted_length, value))
        elif option in ('-n', '--format-number'):
            actions.append(functools.partial(print_formatted_number, value))
        elif option in ('-s', '--format-size'):
            actions.append(
                functools.partial(print_formatted_size, value, binary))
        elif option == '--format-table':
            should_format_table = True
        elif option in ('-t', '--format-timespan'):
            actions.append(functools.partial(print_formatted_timespan, value))
        elif option == '--demo':
            actions.append(demonstrate_ansi_formatting)
        elif option in ('-h', '--help'):
            usage(__doc__)
            return
    if should_format_table:
        actions.append(functools.partial(print_formatted_table, delimiter))
    if not actions:
        usage(__doc__)
        return
    for partial in actions:
        partial()
Example #12
0
def main():
    """Command line interface for the ``qpass`` program."""
    # Initialize logging to the terminal.
    coloredlogs.install()
    # Prepare for command line argument parsing.
    action = show_matching_entry
    program_opts = dict()
    show_opts = dict(use_clipboard=is_clipboard_supported())
    # Parse the command line arguments.
    try:
        options, arguments = getopt.gnu_getopt(sys.argv[1:], 'elnp:vqh', [
            'edit',
            'list',
            'no-clipboard',
            'password-store=',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-e', '--edit'):
                action = edit_matching_entry
            elif option in ('-l', '--list'):
                action = list_matching_entries
            elif option in ('-n', '--no-clipboard'):
                show_opts['use_clipboard'] = False
            elif option in ('-p', '--password-store'):
                stores = program_opts.setdefault('stores', [])
                stores.append(PasswordStore(directory=value))
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                raise Exception("Unhandled option! (programming error)")
        if not (arguments or action == list_matching_entries):
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Execute the requested action.
    try:
        action(QuickPass(**program_opts), arguments,
               **(show_opts if action == show_matching_entry else {}))
    except PasswordStoreError as e:
        # Known issues don't get a traceback.
        logger.error("%s", e)
        sys.exit(1)
    except KeyboardInterrupt:
        # If the user interrupted an interactive prompt they most likely did so
        # intentionally, so there's no point in generating more output here.
        sys.exit(1)
Example #13
0
def main():
    """Command line interface for the ``negotiator-host`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    actions = []
    context = Context()
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'gce:t:dvqh', [
            'list-guests', 'list-commands', 'execute=', 'timeout=', 'daemon',
            'verbose', 'quiet', 'help'
        ])
        for option, value in options:
            if option in ('-g', '--list-guests'):
                actions.append(context.print_guest_names)
            elif option in ('-c', '--list-commands'):
                assert len(arguments) == 1, \
                    "Please provide the name of a guest as the 1st and only positional argument!"
                actions.append(
                    functools.partial(context.print_commands, arguments[0]))
            elif option in ('-e', '--execute'):
                assert len(arguments) == 1, \
                    "Please provide the name of a guest as the 1st and only positional argument!"
                actions.append(
                    functools.partial(context.execute_command, arguments[0],
                                      value))
            elif option in ('-t', '--timeout'):
                context.timeout = int(value)
            elif option in ('-d', '--daemon'):
                actions.append(HostDaemon)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
        if not actions:
            usage(__doc__)
            sys.exit(0)
    except Exception:
        warning("Failed to parse command line arguments!")
        sys.exit(1)
    # Execute the requested action(s).
    try:
        for action in actions:
            action()
    except GuestDiscoveryError as e:
        # Don't spam the logs with tracebacks when the libvirt daemon is down.
        logger.error("%s", e)
        sys.exit(1)
    except Exception:
        # Do log a traceback for `unexpected' exceptions.
        logger.exception("Caught a fatal exception! Terminating ..")
        sys.exit(1)
Example #14
0
def main():
    """Command line interface for ``debuntu-kernel-manager``."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    action = 'render_summary'
    context_opts = dict()
    manager_opts = dict()
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'cfp:r:vqh', [
            'clean',
            'remove',
            'force',
            'preserve-count=',
            'remote-host=',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-c', '--clean', '--remove'):
                action = 'cleanup_packages'
            elif option in ('-f', '--force'):
                manager_opts['force'] = True
            elif option in ('-p', '--preserve-count'):
                manager_opts['preserve_count'] = int(value)
            elif option in ('-r', '--remote-host'):
                context_opts['ssh_alias'] = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                raise Exception("Unhandled option!")
        # Any positional arguments are passed to apt-get.
        manager_opts['apt_options'] = arguments
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Execute the requested action(s).
    context = create_context(**context_opts)
    try:
        manager = KernelPackageManager(context=context, **manager_opts)
        getattr(manager, action)()
    except (CleanupError, ExternalCommandFailed) as e:
        logger.error("%s", e)
        sys.exit(1)
    except Exception:
        logger.exception("Encountered unexpected exception on %s!", context)
        sys.exit(1)
Example #15
0
def main():
    """Command line interface for the ``update-dotdee`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    context_opts = {}
    program_opts = {}
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'fur:vqh', [
            'force',
            'use-sudo',
            'remote-host=',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-f', '--force'):
                program_opts['force'] = True
            elif option in ('-u', '--use-sudo'):
                context_opts['sudo'] = True
            elif option in ('-r', '--remote-host'):
                context_opts['ssh_alias'] = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                # Programming error...
                assert False, "Unhandled option!"
        if not arguments:
            usage(__doc__)
            sys.exit(0)
        if len(arguments) != 1:
            raise Exception(
                "Expected a filename as the first and only argument!")
        program_opts['filename'] = arguments[0]
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Run the program.
    try:
        # Initialize the execution context.
        program_opts['context'] = create_context(**context_opts)
        # Initialize the program and update the file.
        UpdateDotDee(**program_opts).update_file()
    except Exception as e:
        logger.exception("Encountered unexpected exception, aborting!")
        sys.exit(1)
Example #16
0
def main():
    """Command line interface for the ``negotiator-host`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    actions = []
    context = Context()
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'gce:t:dvqh', [
            'list-guests', 'list-commands', 'execute=', 'timeout=', 'daemon',
            'verbose', 'quiet', 'help'
        ])
        for option, value in options:
            if option in ('-g', '--list-guests'):
                actions.append(context.print_guest_names)
            elif option in ('-c', '--list-commands'):
                assert len(arguments) == 1, \
                    "Please provide the name of a guest as the 1st and only positional argument!"
                actions.append(functools.partial(context.print_commands, arguments[0]))
            elif option in ('-e', '--execute'):
                assert len(arguments) == 1, \
                    "Please provide the name of a guest as the 1st and only positional argument!"
                actions.append(functools.partial(context.execute_command, arguments[0], value))
            elif option in ('-t', '--timeout'):
                context.timeout = int(value)
            elif option in ('-d', '--daemon'):
                actions.append(HostDaemon)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
        if not actions:
            usage(__doc__)
            sys.exit(0)
    except Exception:
        warning("Failed to parse command line arguments!")
        sys.exit(1)
    # Execute the requested action(s).
    try:
        for action in actions:
            action()
    except GuestDiscoveryError as e:
        # Don't spam the logs with tracebacks when the libvirt daemon is down.
        logger.error("%s", e)
        sys.exit(1)
    except Exception:
        # Do log a traceback for `unexpected' exceptions.
        logger.exception("Caught a fatal exception! Terminating ..")
        sys.exit(1)
Example #17
0
def main():
    """Command line interface for ``debuntu-kernel-manager``."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    action = "render_summary"
    context_opts = dict()
    manager_opts = dict()
    try:
        options, arguments = getopt.getopt(
            sys.argv[1:],
            "cfp:r:vqh",
            [
                "clean", "remove", "force", "preserve-count=", "remote-host=",
                "verbose", "quiet", "help"
            ],
        )
        for option, value in options:
            if option in ("-c", "--clean", "--remove"):
                action = "cleanup_packages"
            elif option in ("-f", "--force"):
                manager_opts["force"] = True
            elif option in ("-p", "--preserve-count"):
                manager_opts["preserve_count"] = int(value)
            elif option in ("-r", "--remote-host"):
                context_opts["ssh_alias"] = value
            elif option in ("-v", "--verbose"):
                coloredlogs.increase_verbosity()
            elif option in ("-q", "--quiet"):
                coloredlogs.decrease_verbosity()
            elif option in ("-h", "--help"):
                usage(__doc__)
                return
            else:
                raise Exception("Unhandled option!")
        # Any positional arguments are passed to apt-get.
        manager_opts["apt_options"] = arguments
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Execute the requested action(s).
    context = create_context(**context_opts)
    try:
        manager = KernelPackageManager(context=context, **manager_opts)
        getattr(manager, action)()
    except (CleanupError, ExternalCommandFailed) as e:
        logger.error("%s", e)
        sys.exit(1)
    except Exception:
        logger.exception("Encountered unexpected exception on %s!", context)
        sys.exit(1)
def main():
    """Command line interface for the ``humanfriendly`` program."""
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'cd:hn:s:t:', [
            'delimiter=',
            'format-length=',
            'format-number=',
            'format-size=',
            'format-table',
            'format-timespan=',
            'parse-length=',
            'parse-size=',
            'run-command',
            'help',
        ])
    except getopt.GetoptError as e:
        sys.stderr.write("Error: %s\n" % e)
        sys.exit(1)
    actions = []
    delimiter = None
    should_format_table = False
    for option, value in options:
        if option in ('-d', '--delimiter'):
            delimiter = value
        elif option == '--parse-size':
            actions.append(functools.partial(print_parsed_size, value))
        elif option == '--parse-length':
            actions.append(functools.partial(print_parsed_length, value))
        elif option in ('-c', '--run-command'):
            actions.append(functools.partial(run_command, arguments))
        elif option in ('-l', '--format-length'):
            actions.append(functools.partial(print_formatted_length, value))
        elif option in ('-n', '--format-number'):
            actions.append(functools.partial(print_formatted_number, value))
        elif option in ('-s', '--format-size'):
            actions.append(functools.partial(print_formatted_size, value))
        elif option == '--format-table':
            should_format_table = True
        elif option in ('-t', '--format-timespan'):
            actions.append(functools.partial(print_formatted_timespan, value))
        elif option in ('-h', '--help'):
            usage(__doc__)
            return
    if should_format_table:
        actions.append(functools.partial(print_formatted_table, delimiter))
    if not actions:
        usage(__doc__)
        return
    for partial in actions:
        partial()
def main():
    """Command line interface for ``reboot-remote-system``."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    do_shell = False
    try:
        options, arguments = getopt.gnu_getopt(sys.argv[1:], 'svqh', [
            'shell',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-s', '--shell'):
                do_shell = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                raise Exception("Unhandled option!")
        if not arguments:
            usage(__doc__)
            sys.exit(0)
        elif len(arguments) > 1:
            raise Exception("only one positional argument allowed")
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Reboot the remote system.
    try:
        account = RemoteAccount(arguments[0])
        context = get_post_context(arguments[0])
        reboot_remote_system(context=context, name=account.ssh_alias)
        if do_shell:
            start_interactive_shell(context)
    except EncryptedSystemError as e:
        logger.error("Aborting due to error: %s", e)
        sys.exit(2)
    except Exception:
        logger.exception("Aborting due to unexpected exception!")
        sys.exit(3)
Example #20
0
def main():
    """Command line interface for the ``humanfriendly`` program."""
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'cd:l:n:s:bt:h', [
            'run-command', 'format-table', 'delimiter=', 'format-length=',
            'format-number=', 'format-size=', 'binary', 'format-timespan=',
            'parse-length=', 'parse-size=', 'demo', 'help',
        ])
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    actions = []
    delimiter = None
    should_format_table = False
    binary = any(o in ('-b', '--binary') for o, v in options)
    for option, value in options:
        if option in ('-d', '--delimiter'):
            delimiter = value
        elif option == '--parse-size':
            actions.append(functools.partial(print_parsed_size, value))
        elif option == '--parse-length':
            actions.append(functools.partial(print_parsed_length, value))
        elif option in ('-c', '--run-command'):
            actions.append(functools.partial(run_command, arguments))
        elif option in ('-l', '--format-length'):
            actions.append(functools.partial(print_formatted_length, value))
        elif option in ('-n', '--format-number'):
            actions.append(functools.partial(print_formatted_number, value))
        elif option in ('-s', '--format-size'):
            actions.append(functools.partial(print_formatted_size, value, binary))
        elif option == '--format-table':
            should_format_table = True
        elif option in ('-t', '--format-timespan'):
            actions.append(functools.partial(print_formatted_timespan, value))
        elif option == '--demo':
            actions.append(demonstrate_ansi_formatting)
        elif option in ('-h', '--help'):
            usage(__doc__)
            return
    if should_format_table:
        actions.append(functools.partial(print_formatted_table, delimiter))
    if not actions:
        usage(__doc__)
        return
    for partial in actions:
        partial()
Example #21
0
def main():
    """Command line interface for the ``humanfriendly`` program."""
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'cd:hn:s:t:', [
            'delimiter=', 'format-length=', 'format-number=', 'format-size=',
            'format-table', 'format-timespan=', 'parse-length=',
            'parse-size=', 'run-command', 'help',
        ])
    except getopt.GetoptError as e:
        sys.stderr.write("Error: %s\n" % e)
        sys.exit(1)
    actions = []
    delimiter = None
    should_format_table = False
    for option, value in options:
        if option in ('-d', '--delimiter'):
            delimiter = value
        elif option == '--parse-size':
            actions.append(functools.partial(print_parsed_size, value))
        elif option == '--parse-length':
            actions.append(functools.partial(print_parsed_length, value))
        elif option in ('-c', '--run-command'):
            actions.append(functools.partial(run_command, arguments))
        elif option in ('-l', '--format-length'):
            actions.append(functools.partial(print_formatted_length, value))
        elif option in ('-n', '--format-number'):
            actions.append(functools.partial(print_formatted_number, value))
        elif option in ('-s', '--format-size'):
            actions.append(functools.partial(print_formatted_size, value))
        elif option == '--format-table':
            should_format_table = True
        elif option in ('-t', '--format-timespan'):
            actions.append(functools.partial(print_formatted_timespan, value))
        elif option in ('-h', '--help'):
            usage(__doc__)
            return
    if should_format_table:
        actions.append(functools.partial(print_formatted_table, delimiter))
    if not actions:
        usage(__doc__)
        return
    for partial in actions:
        partial()
Example #22
0
def main():
    """Command line interface for the ``apache-manager`` program."""
    # Configure logging output.
    coloredlogs.install()
    # Command line option defaults.
    data_file = '/tmp/apache-manager.txt'
    dry_run = False
    max_memory_active = None
    max_memory_idle = None
    max_ss = None
    watch = False
    zabbix_discovery = False
    verbosity = 0
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'wa:i:t:f:znvqh', [
            'watch', 'max-memory-active=', 'max-memory-idle=', 'max-ss=',
            'max-time=', 'data-file=', 'zabbix-discovery', 'dry-run',
            'simulate', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-w', '--watch'):
                watch = True
            elif option in ('-a', '--max-memory-active'):
                max_memory_active = parse_size(value)
            elif option in ('-i', '--max-memory-idle'):
                max_memory_idle = parse_size(value)
            elif option in ('-t', '--max-ss', '--max-time'):
                max_ss = parse_timespan(value)
            elif option in ('-f', '--data-file'):
                data_file = value
            elif option in ('-z', '--zabbix-discovery'):
                zabbix_discovery = True
            elif option in ('-n', '--dry-run', '--simulate'):
                logger.info("Performing a dry run ..")
                dry_run = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
                verbosity += 1
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
                verbosity -= 1
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
    except Exception as e:
        sys.stderr.write("Error: %s!\n" % e)
        sys.exit(1)
    # Execute the requested action(s).
    manager = ApacheManager()
    try:
        if max_memory_active or max_memory_idle or max_ss:
            manager.kill_workers(
                max_memory_active=max_memory_active,
                max_memory_idle=max_memory_idle,
                timeout=max_ss,
                dry_run=dry_run,
            )
        if watch and connected_to_terminal(sys.stdout):
            watch_metrics(manager)
        elif zabbix_discovery:
            report_zabbix_discovery(manager)
        elif data_file != '-' and verbosity >= 0:
            for line in report_metrics(manager):
                if line_is_heading(line):
                    line = ansi_wrap(line, color=HIGHLIGHT_COLOR)
                print(line)
    finally:
        if (not watch) and (data_file == '-' or not dry_run):
            manager.save_metrics(data_file)
Example #23
0
def main():
    """Command line interface for the ``executor`` program."""
    # Enable logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    command_timeout = 0
    exclusive = False
    fudge_factor = 0
    lock_name = None
    lock_timeout = 0
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'eT:l:t:f:vqh', [
            'exclusive', 'lock-timeout=', 'lock-file=', 'timeout=',
            'fudge-factor=', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-e', '--exclusive'):
                exclusive = True
            elif option in ('-T', '--lock-timeout'):
                lock_timeout = parse_timespan(value)
            elif option in ('-l', '--lock-file'):
                lock_name = value
            elif option in ('-t', '--timeout'):
                command_timeout = parse_timespan(value)
            elif option in ('-f', '--fudge-factor'):
                fudge_factor = parse_timespan(value)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                assert False, "Unhandled option!"
        # Make sure the operator provided a program to execute.
        if not arguments:
            usage(__doc__)
            sys.exit(0)
        # Make sure the program actually exists.
        program_name = arguments[0]
        if not os.path.isfile(program_name):
            # Only search the $PATH if the given program name
            # doesn't already include one or more path segments.
            if program_name == os.path.basename(program_name):
                matching_programs = which(program_name)
                if matching_programs:
                    program_name = matching_programs[0]
        # The subprocess.Popen() call later on doesn't search the $PATH so we
        # make sure to give it the absolute pathname to the program.
        arguments[0] = program_name
    except Exception as e:
        warning("Failed to parse command line arguments: %s", e)
        sys.exit(1)
    # Apply the requested fudge factor.
    apply_fudge_factor(fudge_factor)
    # Run the requested command.
    try:
        if exclusive:
            # Select a default lock file name?
            if not lock_name:
                lock_name = os.path.basename(arguments[0])
                logger.debug("Using base name of command as lock file name (%s).", lock_name)
            lock_file = get_lock_path(lock_name)
            lock = InterProcessLock(path=lock_file, logger=logger)
            logger.debug("Trying to acquire exclusive lock: %s", lock_file)
            if lock.acquire(blocking=(lock_timeout > 0), max_delay=lock_timeout):
                logger.info("Successfully acquired exclusive lock: %s", lock_file)
                run_command(arguments, timeout=command_timeout)
            else:
                logger.error("Failed to acquire exclusive lock: %s", lock_file)
                sys.exit(1)
        else:
            run_command(arguments, timeout=command_timeout)
    except ExternalCommandFailed as e:
        logger.error("%s", e.error_message)
        sys.exit(e.command.returncode)
Example #24
0
def main():
    """Command line interface for the ``executor`` program."""
    # Enable logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    command_timeout = 0
    exclusive = False
    fudge_factor = 0
    lock_name = None
    lock_timeout = 0
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'eT:l:t:f:vqh', [
            'exclusive', 'lock-timeout=', 'lock-file=', 'timeout=',
            'fudge-factor=', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-e', '--exclusive'):
                exclusive = True
            elif option in ('-T', '--lock-timeout'):
                lock_timeout = parse_timespan(value)
            elif option in ('-l', '--lock-file'):
                lock_name = value
            elif option in ('-t', '--timeout'):
                command_timeout = parse_timespan(value)
            elif option in ('-f', '--fudge-factor'):
                fudge_factor = parse_timespan(value)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                assert False, "Unhandled option!"
        # Make sure the operator provided a program to execute.
        if not arguments:
            usage(__doc__)
            sys.exit(0)
        # Make sure the program actually exists.
        program_name = arguments[0]
        if not os.path.isfile(program_name):
            # Only search the $PATH if the given program name
            # doesn't already include one or more path segments.
            if program_name == os.path.basename(program_name):
                matching_programs = which(program_name)
                if matching_programs:
                    program_name = matching_programs[0]
        # The subprocess.Popen() call later on doesn't search the $PATH so we
        # make sure to give it the absolute pathname to the program.
        arguments[0] = program_name
    except Exception as e:
        warning("Failed to parse command line arguments: %s", e)
        sys.exit(1)
    # Apply the requested fudge factor.
    apply_fudge_factor(fudge_factor)
    # Run the requested command.
    try:
        if exclusive:
            # Select a default lock file name?
            if not lock_name:
                lock_name = os.path.basename(arguments[0])
                logger.debug("Using base name of command as lock file name (%s).", lock_name)
            lock_file = get_lock_path(lock_name)
            lock = InterProcessLock(path=lock_file, logger=logger)
            logger.debug("Trying to acquire exclusive lock: %s", lock_file)
            if lock.acquire(blocking=(lock_timeout > 0), max_delay=lock_timeout):
                logger.info("Successfully acquired exclusive lock: %s", lock_file)
                run_command(arguments, timeout=command_timeout)
            else:
                logger.error("Failed to acquire exclusive lock: %s", lock_file)
                sys.exit(1)
        else:
            run_command(arguments, timeout=command_timeout)
    except ExternalCommandFailed as e:
        logger.error("%s", e.error_message)
        sys.exit(e.command.returncode)
def main():
    """Command line interface for the ``rotate-backups`` program."""
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    config_file = None
    dry_run = False
    exclude_list = []
    include_list = []
    io_scheduling_class = None
    rotation_scheme = {}
    use_sudo = False
    strict = True
    # Internal state.
    selected_locations = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'H:d:w:m:y:I:x:ri:c:r:unvqh', [
            'hourly=', 'daily=', 'weekly=', 'monthly=', 'yearly=', 'include=',
            'exclude=', 'relaxed', 'ionice=', 'config=', 'use-sudo', 'dry-run',
            'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-H', '--hourly'):
                rotation_scheme['hourly'] = coerce_retention_period(value)
            elif option in ('-d', '--daily'):
                rotation_scheme['daily'] = coerce_retention_period(value)
            elif option in ('-w', '--weekly'):
                rotation_scheme['weekly'] = coerce_retention_period(value)
            elif option in ('-m', '--monthly'):
                rotation_scheme['monthly'] = coerce_retention_period(value)
            elif option in ('-y', '--yearly'):
                rotation_scheme['yearly'] = coerce_retention_period(value)
            elif option in ('-I', '--include'):
                include_list.append(value)
            elif option in ('-x', '--exclude'):
                exclude_list.append(value)
            elif option in ('-r', '--relaxed'):
                strict = False
            elif option in ('-i', '--ionice'):
                value = value.lower().strip()
                expected = ('idle', 'best-effort', 'realtime')
                if value not in expected:
                    msg = "Invalid I/O scheduling class! (got %r while valid options are %s)"
                    raise Exception(msg % (value, concatenate(expected)))
                io_scheduling_class = value
            elif option in ('-c', '--config'):
                config_file = parse_path(value)
            elif option in ('-u', '--use-sudo'):
                use_sudo = True
            elif option in ('-n', '--dry-run'):
                logger.info("Performing a dry run (because of %s option) ..", option)
                dry_run = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option! (programming error)"
        if rotation_scheme:
            logger.debug("Parsed rotation scheme: %s", rotation_scheme)
        if arguments:
            # Rotation of the locations given on the command line.
            selected_locations.extend(coerce_location(value, sudo=use_sudo) for value in arguments)
        else:
            # Rotation of all configured locations.
            selected_locations.extend(location for location, rotation_scheme, options in load_config_file(config_file))
        # Show the usage message when no directories are given nor configured.
        if not selected_locations:
            usage(__doc__)
            return
    except Exception as e:
        logger.error("%s", e)
        sys.exit(1)
    # Rotate the backups in the selected directories.
    for location in selected_locations:
        RotateBackups(
            rotation_scheme=rotation_scheme,
            include_list=include_list,
            exclude_list=exclude_list,
            io_scheduling_class=io_scheduling_class,
            dry_run=dry_run,
            config_file=config_file,
            strict=strict,
        ).rotate_backups(location)
Example #26
0
def main():
    """Command line interface for the ``deb-pkg-tools`` program."""
    # Configure logging output.
    coloredlogs.install()
    # Command line option defaults.
    prompt = True
    actions = []
    control_file = None
    control_fields = {}
    directory = None
    # Initialize the package cache.
    cache = get_default_cache()
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(
            sys.argv[1:], 'i:c:C:p:s:b:u:a:d:w:yvh', [
                'inspect=', 'collect=', 'check=', 'patch=', 'set=', 'build=',
                'update-repo=', 'activate-repo=', 'deactivate-repo=',
                'with-repo=', 'gc', 'garbage-collect', 'yes', 'verbose', 'help'
            ])
        for option, value in options:
            if option in ('-i', '--inspect'):
                actions.append(
                    functools.partial(show_package_metadata, archive=value))
            elif option in ('-c', '--collect'):
                directory = check_directory(value)
            elif option in ('-C', '--check'):
                actions.append(
                    functools.partial(check_package,
                                      archive=value,
                                      cache=cache))
            elif option in ('-p', '--patch'):
                control_file = os.path.abspath(value)
                assert os.path.isfile(
                    control_file), "Control file does not exist!"
            elif option in ('-s', '--set'):
                name, _, value = value.partition(':')
                control_fields[name] = value.strip()
            elif option in ('-b', '--build'):
                actions.append(
                    functools.partial(
                        build_package,
                        check_directory(value),
                        repository=tempfile.gettempdir(),
                    ))
            elif option in ('-u', '--update-repo'):
                actions.append(
                    functools.partial(update_repository,
                                      directory=check_directory(value),
                                      cache=cache))
            elif option in ('-a', '--activate-repo'):
                actions.append(
                    functools.partial(activate_repository,
                                      check_directory(value)))
            elif option in ('-d', '--deactivate-repo'):
                actions.append(
                    functools.partial(deactivate_repository,
                                      check_directory(value)))
            elif option in ('-w', '--with-repo'):
                actions.append(
                    functools.partial(with_repository_wrapper,
                                      directory=check_directory(value),
                                      command=arguments,
                                      cache=cache))
            elif option in ('--gc', '--garbage-collect'):
                actions.append(
                    functools.partial(cache.collect_garbage, force=True))
            elif option in ('-y', '--yes'):
                prompt = False
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
        # We delay the patch_control_file() and collect_packages() partials
        # until all command line options have been parsed, to ensure that the
        # order of the command line options doesn't matter.
        if control_file:
            if not control_fields:
                raise Exception(
                    "Please specify one or more control file fields to patch!")
            actions.append(
                functools.partial(patch_control_file, control_file,
                                  control_fields))
        if directory:
            actions.append(
                functools.partial(collect_packages,
                                  archives=arguments,
                                  directory=directory,
                                  prompt=prompt,
                                  cache=cache))
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Execute the selected action.
    try:
        if actions:
            for action in actions:
                action()
            cache.collect_garbage()
        else:
            usage(__doc__)
    except Exception:
        logger.exception("An error occurred! Aborting..")
        sys.exit(1)
Example #27
0
def main():
    """Command line interface for the ``apt-smart`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    context = LocalContext()
    updater = AptMirrorUpdater(context=context)
    limit = MAX_MIRRORS
    url_char_len = URL_CHAR_LEN
    actions = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:],
                                           'r:fF:blL:c:aux:m:vVR:qh', [
                                               'remote-host=',
                                               'find-current-mirror',
                                               'find-best-mirror',
                                               'file-to-read=',
                                               'list-mirrors',
                                               'url-char-len=',
                                               'change-mirror',
                                               'auto-change-mirror',
                                               'update',
                                               'update-package-lists',
                                               'exclude=',
                                               'max=',
                                               'verbose',
                                               'version',
                                               'create-chroot=',
                                               'quiet',
                                               'help',
                                           ])
        for option, value in options:
            if option in ('-r', '--remote-host'):
                if actions:
                    msg = "The %s option should be the first option given on the command line!"
                    raise Exception(msg % option)
                context = RemoteContext(value)
                updater = AptMirrorUpdater(context=context)
            elif option in ('-f', '--find-current-mirror'):
                actions.append(
                    functools.partial(report_current_mirror, updater))
            elif option in ('-F', '--file-to-read'):
                updater.custom_mirror_file_path = value
            elif option in ('-b', '--find-best-mirror'):
                actions.append(functools.partial(report_best_mirror, updater))
            elif option in ('-l', '--list-mirrors'):
                actions.append(
                    functools.partial(report_available_mirrors, updater))
            elif option in ('-L', '--url-char-len'):
                url_char_len = int(value)
            elif option in ('-c', '--change-mirror'):
                if value.strip().startswith(('http://', 'https://', 'ftp://')):
                    actions.append(
                        functools.partial(updater.change_mirror, value))
                else:
                    raise Exception("\'%s\' is not a valid mirror URL" % value)
            elif option in ('-a', '--auto-change-mirror'):
                actions.append(updater.change_mirror)
            elif option in ('-u', '--update', '--update-package-lists'):
                actions.append(updater.smart_update)
            elif option in ('-x', '--exclude'):
                actions.insert(0,
                               functools.partial(updater.ignore_mirror, value))
            elif option in ('-m', '--max'):
                limit = int(value)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-V', '--version'):
                output("Version: %s on Python %i.%i", updater_version,
                       sys.version_info[0], sys.version_info[1])
                return
            elif option in ('-R', '--create-chroot'):
                actions.append(functools.partial(updater.create_chroot, value))
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
        if not actions:
            usage(__doc__)
            return
        # Propagate options to the Python API.
        updater.max_mirrors = limit
        updater.url_char_len = url_char_len
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)" % e)
        sys.exit(1)
    # Perform the requested action(s).
    try:
        for callback in actions:
            callback()
    except Exception:
        logger.exception("Encountered unexpected exception! Aborting ..")
        sys.exit(1)
Example #28
0
def main():
    """Command line interface for the ``rsync-system-backup`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    context_opts = dict()
    program_opts = dict()
    dest_opts = dict()
    try:
        options, arguments = getopt.gnu_getopt(sys.argv[1:], 'bsrm:c:t:i:unx:fvqh', [
            'backup', 'snapshot', 'rotate', 'mount=', 'crypto=', 'tunnel=',
            'ionice=', 'no-sudo', 'dry-run', 'multi-fs', 'exclude=', 'force',
            'disable-notifications', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-b', '--backup'):
                enable_explicit_action(program_opts, 'backup_enabled')
            elif option in ('-s', '--snapshot'):
                enable_explicit_action(program_opts, 'snapshot_enabled')
            elif option in ('-r', '--rotate'):
                enable_explicit_action(program_opts, 'rotate_enabled')
            elif option in ('-m', '--mount'):
                program_opts['mount_point'] = value
            elif option in ('-c', '--crypto'):
                program_opts['crypto_device'] = value
            elif option in ('-t', '--tunnel'):
                ssh_user, _, value = value.rpartition('@')
                ssh_alias, _, port_number = value.partition(':')
                tunnel_opts = dict(
                    ssh_alias=ssh_alias,
                    ssh_user=ssh_user,
                    # The port number of the rsync daemon.
                    remote_port=RSYNCD_PORT,
                )
                if port_number:
                    # The port number of the SSH server.
                    tunnel_opts['port'] = int(port_number)
                dest_opts['ssh_tunnel'] = SecureTunnel(**tunnel_opts)
            elif option in ('-i', '--ionice'):
                value = value.lower().strip()
                validate_ionice_class(value)
                program_opts['ionice'] = value
            elif option in ('-u', '--no-sudo'):
                program_opts['sudo_enabled'] = False
            elif option in ('-n', '--dry-run'):
                logger.info("Performing a dry run (because of %s option) ..", option)
                program_opts['dry_run'] = True
            elif option in ('-f', '--force'):
                program_opts['force'] = True
            elif option in ('-x', '--exclude'):
                program_opts.setdefault('exclude_list', [])
                program_opts['exclude_list'].append(value)
            elif option == '--multi-fs':
                program_opts['multi_fs'] = True
            elif option == '--disable-notifications':
                program_opts['notifications_enabled'] = False
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                raise Exception("Unhandled option! (programming error)")
        if len(arguments) > 2:
            msg = "Expected one or two positional arguments! (got %i)"
            raise Exception(msg % len(arguments))
        if len(arguments) == 2:
            # Get the source from the first of two arguments.
            program_opts['source'] = arguments.pop(0)
        if arguments:
            # Get the destination from the second (or only) argument.
            dest_opts['expression'] = arguments[0]
            program_opts['destination'] = Destination(**dest_opts)
        elif not os.environ.get('RSYNC_MODULE_PATH'):
            # Show a usage message when no destination is given.
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    try:
        # Inject the source context into the program options.
        program_opts['source_context'] = create_context(**context_opts)
        # Initialize the program with the command line
        # options and execute the requested action(s).
        RsyncSystemBackup(**program_opts).execute()
    except Exception as e:
        if isinstance(e, RsyncSystemBackupError):
            # Special handling when the backup disk isn't available.
            if isinstance(e, MissingBackupDiskError):
                # Check if we're connected to a terminal to decide whether the
                # error should be propagated or silenced, the idea being that
                # rsync-system-backup should keep quiet when it's being run
                # from cron and the backup disk isn't available.
                if not connected_to_terminal():
                    logger.info("Skipping backup: %s", e)
                    sys.exit(0)
            # Known problems shouldn't produce
            # an intimidating traceback to users.
            logger.error("Aborting due to error: %s", e)
        else:
            # Unhandled exceptions do get a traceback,
            # because it may help fix programming errors.
            logger.exception("Aborting due to unhandled exception!")
        sys.exit(1)
Example #29
0
def main():
    """Command line interface for the ``crypto-drive-manager`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Define command line option defaults.
    image_file = '/root/encryption-keys.img'
    mapper_name = 'encryption-keys'
    mount_point = '/mnt/keys'
    install_workaround = False
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'i:n:m:vqh', [
            'image-file=', 'mapper-name=', 'mount-point=',
            'install-systemd-workaround',
            'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-i', '--image-file'):
                image_file = value
            elif option in ('-n', '--mapper-name'):
                mapper_name = value
            elif option in ('-m', '--mount-point'):
                mount_point = value
            elif option == '--install-systemd-workaround':
                install_workaround = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Make sure we're running as root (after parsing the command
    # line so that root isn't required to list the usage message).
    if os.getuid() != 0:
        warning("Error: Please run this command as root!")
        sys.exit(1)
    # Decide if the systemd workaround is being executed based on sys.argv[0].
    if systemd_workaround_requested():
        update_systemd_services()
        # In this case none of the other code should run.
        return
    # Check if the operator wants to install the systemd workaround.
    if install_workaround:
        install_systemd_workaround()
    # Initialize the keys device and use it to unlock the managed drives?
    # Only if we didn't just install the systemd workaround OR the operator
    # requested to unlock specific drives.
    if (not install_workaround) or arguments:
        try:
            initialize_keys_device(
                image_file=image_file,
                mapper_name=mapper_name,
                mount_point=mount_point,
                volumes=arguments,
            )
        except KeyboardInterrupt:
            logger.error("Interrupted by Control-C, terminating ..")
            sys.exit(1)
        except Exception:
            logger.exception("Terminating due to unexpected exception!")
            sys.exit(1)
def main():
    """Command line interface for the ``apt-mirror-updater`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    context = LocalContext()
    updater = AptMirrorUpdater(context=context)
    limit = MAX_MIRRORS
    actions = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'r:fblc:aux:m:vqh', [
            'remote-host=',
            'find-current-mirror',
            'find-best-mirror',
            'list-mirrors',
            'change-mirror',
            'auto-change-mirror',
            'update',
            'update-package-lists',
            'exclude=',
            'max=',
            'verbose',
            'quiet',
            'help',
        ])
        for option, value in options:
            if option in ('-r', '--remote-host'):
                if actions:
                    msg = "The %s option should be the first option given on the command line!"
                    raise Exception(msg % option)
                context = RemoteContext(value)
                updater = AptMirrorUpdater(context=context)
            elif option in ('-f', '--find-current-mirror'):
                actions.append(
                    functools.partial(report_current_mirror, updater))
            elif option in ('-b', '--find-best-mirror'):
                actions.append(functools.partial(report_best_mirror, updater))
            elif option in ('-l', '--list-mirrors'):
                actions.append(
                    functools.partial(report_available_mirrors, updater))
            elif option in ('-c', '--change-mirror'):
                actions.append(functools.partial(updater.change_mirror, value))
            elif option in ('-a', '--auto-change-mirror'):
                actions.append(updater.change_mirror)
            elif option in ('-u', '--update', '--update-package-lists'):
                actions.append(updater.smart_update)
            elif option in ('-x', '--exclude'):
                actions.insert(0,
                               functools.partial(updater.ignore_mirror, value))
            elif option in ('-m', '--max'):
                limit = int(value)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
        if not actions:
            usage(__doc__)
            return
        # Propagate options to the Python API.
        updater.max_mirrors = limit
    except Exception as e:
        warning("Error: Failed to parse command line arguments! (%s)" % e)
        sys.exit(1)
    # Perform the requested action(s).
    try:
        for callback in actions:
            callback()
    except Exception:
        logger.exception("Encountered unexpected exception! Aborting ..")
        sys.exit(1)
Example #31
0
def main():
    """Command line interface for the ``py2deb`` program."""
    # Configure terminal output.
    coloredlogs.install()
    try:
        # Initialize a package converter.
        converter = PackageConverter()
        # Parse and validate the command line options.
        options, arguments = getopt.getopt(sys.argv[1:], 'c:r:yvh', [
            'config=', 'repository=', 'use-system-package=', 'name-prefix=',
            'no-name-prefix=', 'rename=', 'install-prefix=',
            'install-alternative=', 'python-callback=', 'report-dependencies=',
            'yes', 'verbose', 'help',
        ])
        control_file_to_update = None
        for option, value in options:
            if option in ('-c', '--config'):
                converter.load_configuration_file(value)
            elif option in ('-r', '--repository'):
                converter.set_repository(value)
            elif option == '--use-system-package':
                python_package_name, _, debian_package_name = value.partition(',')
                converter.use_system_package(python_package_name, debian_package_name)
            elif option == '--name-prefix':
                converter.set_name_prefix(value)
            elif option == '--no-name-prefix':
                converter.rename_package(value, value)
            elif option == '--rename':
                python_package_name, _, debian_package_name = value.partition(',')
                converter.rename_package(python_package_name, debian_package_name)
            elif option == '--install-prefix':
                converter.set_install_prefix(value)
            elif option == '--install-alternative':
                link, _, path = value.partition(',')
                converter.install_alternative(link, path)
            elif option == '--python-callback':
                converter.set_python_callback(value)
            elif option == '--report-dependencies':
                control_file_to_update = value
                if not os.path.isfile(control_file_to_update):
                    msg = "The given control file doesn't exist! (%s)"
                    raise Exception(msg % control_file_to_update)
            elif option in ('-y', '--yes'):
                converter.set_auto_install(True)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
    except Exception as e:
        warning("Failed to parse command line arguments: %s", e)
        sys.exit(1)
    # Convert the requested package(s).
    try:
        if arguments:
            archives, relationships = converter.convert(arguments)
            if relationships and control_file_to_update:
                patch_control_file(control_file_to_update, dict(depends=relationships))
        else:
            usage(__doc__)
    except Exception:
        logger.exception("Caught an unhandled exception!")
        sys.exit(1)
Example #32
0
def main():
    """Command line interface for the ``deb-pkg-tools`` program."""
    # Configure logging output.
    coloredlogs.install()
    # Command line option defaults.
    prompt = True
    actions = []
    control_file = None
    control_fields = {}
    directory = None
    # Initialize the package cache.
    cache = get_default_cache()
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'i:c:C:p:s:b:u:a:d:w:yvh', [
            'inspect=', 'collect=', 'check=', 'patch=', 'set=', 'build=',
            'update-repo=', 'activate-repo=', 'deactivate-repo=', 'with-repo=',
            'gc', 'garbage-collect', 'yes', 'verbose', 'help'
        ])
        for option, value in options:
            if option in ('-i', '--inspect'):
                actions.append(functools.partial(show_package_metadata, archive=value))
            elif option in ('-c', '--collect'):
                directory = check_directory(value)
            elif option in ('-C', '--check'):
                actions.append(functools.partial(check_package, archive=value, cache=cache))
            elif option in ('-p', '--patch'):
                control_file = os.path.abspath(value)
                assert os.path.isfile(control_file), "Control file does not exist!"
            elif option in ('-s', '--set'):
                name, _, value = value.partition(':')
                control_fields[name] = value.strip()
            elif option in ('-b', '--build'):
                actions.append(functools.partial(
                    build_package,
                    check_directory(value),
                    repository=tempfile.gettempdir(),
                ))
            elif option in ('-u', '--update-repo'):
                actions.append(functools.partial(update_repository,
                                                 directory=check_directory(value),
                                                 cache=cache))
            elif option in ('-a', '--activate-repo'):
                actions.append(functools.partial(activate_repository, check_directory(value)))
            elif option in ('-d', '--deactivate-repo'):
                actions.append(functools.partial(deactivate_repository, check_directory(value)))
            elif option in ('-w', '--with-repo'):
                actions.append(functools.partial(with_repository_wrapper,
                                                 directory=check_directory(value),
                                                 command=arguments,
                                                 cache=cache))
            elif option in ('--gc', '--garbage-collect'):
                actions.append(functools.partial(cache.collect_garbage, force=True))
            elif option in ('-y', '--yes'):
                prompt = False
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
        # We delay the patch_control_file() and collect_packages() partials
        # until all command line options have been parsed, to ensure that the
        # order of the command line options doesn't matter.
        if control_file:
            if not control_fields:
                raise Exception("Please specify one or more control file fields to patch!")
            actions.append(functools.partial(patch_control_file, control_file, control_fields))
        if directory:
            actions.append(functools.partial(collect_packages,
                                             archives=arguments,
                                             directory=directory,
                                             prompt=prompt,
                                             cache=cache))
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Execute the selected action.
    try:
        if actions:
            for action in actions:
                action()
            cache.collect_garbage()
        else:
            usage(__doc__)
    except Exception as e:
        logger.exception("An error occurred!")
        sys.exit(1)
Example #33
0
def main():
    """Command line interface for the ``rotate-backups`` program."""
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    rotation_scheme = {}
    kw = dict(include_list=[], exclude_list=[])
    parallel = False
    use_sudo = False
    # Internal state.
    selected_locations = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:],
                                           'M:H:d:w:m:y:I:x:jpri:c:r:uC:nvqh',
                                           [
                                               'minutely=',
                                               'hourly=',
                                               'daily=',
                                               'weekly=',
                                               'monthly=',
                                               'yearly=',
                                               'include=',
                                               'exclude=',
                                               'parallel',
                                               'prefer-recent',
                                               'relaxed',
                                               'ionice=',
                                               'config=',
                                               'use-sudo',
                                               'dry-run',
                                               'removal-command=',
                                               'verbose',
                                               'quiet',
                                               'help',
                                           ])
        for option, value in options:
            if option in ('-M', '--minutely'):
                rotation_scheme['minutely'] = coerce_retention_period(value)
            elif option in ('-H', '--hourly'):
                rotation_scheme['hourly'] = coerce_retention_period(value)
            elif option in ('-d', '--daily'):
                rotation_scheme['daily'] = coerce_retention_period(value)
            elif option in ('-w', '--weekly'):
                rotation_scheme['weekly'] = coerce_retention_period(value)
            elif option in ('-m', '--monthly'):
                rotation_scheme['monthly'] = coerce_retention_period(value)
            elif option in ('-y', '--yearly'):
                rotation_scheme['yearly'] = coerce_retention_period(value)
            elif option in ('-I', '--include'):
                kw['include_list'].append(value)
            elif option in ('-x', '--exclude'):
                kw['exclude_list'].append(value)
            elif option in ('-j', '--parallel'):
                parallel = True
            elif option in ('-p', '--prefer-recent'):
                kw['prefer_recent'] = True
            elif option in ('-r', '--relaxed'):
                kw['strict'] = False
            elif option in ('-i', '--ionice'):
                value = validate_ionice_class(value.lower().strip())
                kw['io_scheduling_class'] = value
            elif option in ('-c', '--config'):
                kw['config_file'] = parse_path(value)
            elif option in ('-u', '--use-sudo'):
                use_sudo = True
            elif option in ('-n', '--dry-run'):
                logger.info("Performing a dry run (because of %s option) ..",
                            option)
                kw['dry_run'] = True
            elif option in ('-C', '--removal-command'):
                removal_command = shlex.split(value)
                logger.info("Using custom removal command: %s",
                            removal_command)
                kw['removal_command'] = removal_command
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option! (programming error)"
        if rotation_scheme:
            logger.verbose("Rotation scheme defined on command line: %s",
                           rotation_scheme)
        if arguments:
            # Rotation of the locations given on the command line.
            location_source = 'command line arguments'
            selected_locations.extend(
                coerce_location(value, sudo=use_sudo) for value in arguments)
        else:
            # Rotation of all configured locations.
            location_source = 'configuration file'
            selected_locations.extend(
                location
                for location, rotation_scheme, options in load_config_file(
                    configuration_file=kw.get('config_file'), expand=True))
        # Inform the user which location(s) will be rotated.
        if selected_locations:
            logger.verbose("Selected %s based on %s:",
                           pluralize(len(selected_locations), "location"),
                           location_source)
            for number, location in enumerate(selected_locations, start=1):
                logger.verbose(" %i. %s", number, location)
        else:
            # Show the usage message when no directories are given nor configured.
            logger.verbose("No location(s) to rotate selected.")
            usage(__doc__)
            return
    except Exception as e:
        logger.error("%s", e)
        sys.exit(1)
    # Rotate the backups in the selected directories.
    program = RotateBackups(rotation_scheme, **kw)
    if parallel:
        program.rotate_concurrent(*selected_locations)
    else:
        for location in selected_locations:
            program.rotate_backups(location)
Example #34
0
def main():
    """Command line interface for the ``chat-archive`` program."""
    # Enable logging to the terminal.
    coloredlogs.install()
    # Parse the command line options.
    program_opts = dict()
    command_name = None
    try:
        options, arguments = getopt.gnu_getopt(
            sys.argv[1:],
            "C:fl:c:p:vqh",
            [
                "context=",
                "force",
                "log-file=",
                "color=",
                "colour=",
                "profile=",
                "verbose",
                "quiet",
                "help",
            ],
        )
        for option, value in options:
            if option in ("-C", "--context"):
                program_opts["context"] = int(value)
            elif option in ("-f", "--force"):
                program_opts["force"] = True
            elif option in ("-l", "--log-file"):
                handler = logging.FileHandler(parse_path(value))
                handler.setFormatter(
                    logging.Formatter(
                        fmt=
                        "%(asctime)s %(name)s[%(process)d] %(levelname)s %(message)s",
                        datefmt="%Y-%m-%d %H:%M:%S"))
                handler.setLevel(logging.DEBUG)
                logging.root.addHandler(handler)
                logging.root.setLevel(logging.NOTSET)
            elif option in ("-c", "--color", "--colour"):
                mapping = dict(always=True, never=False)
                program_opts["use_colors"] = mapping[
                    value] if value in mapping else coerce_boolean(value)
            elif option in ("-p", "--profile"):
                program_opts["profile_file"] = parse_path(value)
            elif option in ("-v", "--verbose"):
                coloredlogs.increase_verbosity()
            elif option in ("-q", "--quiet"):
                coloredlogs.decrease_verbosity()
            elif option in ("-h", "--help"):
                usage(__doc__)
                sys.exit(0)
            else:
                assert False, "Unhandled option!"
        # Make sure the operator provided a command.
        if not arguments:
            usage(__doc__)
            sys.exit(0)
    except Exception as e:
        warning("Failed to parse command line arguments: %s", e)
        sys.exit(1)
    try:
        # We extract any search keywords from the command line arguments before
        # initializing an instance of the UserInterface class, to enable
        # initialization of the KeywordHighlighter class.
        if arguments[0] == "search":
            program_opts["keywords"] = arguments[1:]
        # Initialize the chat archive.
        with UserInterface(**program_opts) as program:
            # Validate the requested command.
            command_name = arguments.pop(0)
            method_name = "%s_cmd" % command_name
            if not hasattr(program, method_name):
                warning("Error: Invalid command name '%s'!", command_name)
                sys.exit(1)
            # Execute the requested command.
            command_fn = getattr(program, method_name)
            command_fn(arguments)
    except KeyboardInterrupt:
        logger.notice("Interrupted by Control-C ..")
        sys.exit(1)
    except Exception:
        logger.exception("Aborting due to unexpected exception!")
        sys.exit(1)
Example #35
0
def main():
    """Command line interface for the ``apache-manager`` program."""
    # Configure logging output.
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    data_file = '/tmp/apache-manager.txt'
    dry_run = False
    max_memory_active = None
    max_memory_idle = None
    max_ss = None
    watch = False
    zabbix_discovery = False
    verbosity = 0
    # Parse the command line options.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'wa:i:t:f:znvqh', [
            'watch', 'max-memory-active=', 'max-memory-idle=', 'max-ss=',
            'max-time=', 'data-file=', 'zabbix-discovery', 'dry-run',
            'simulate', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-w', '--watch'):
                watch = True
            elif option in ('-a', '--max-memory-active'):
                max_memory_active = parse_size(value)
            elif option in ('-i', '--max-memory-idle'):
                max_memory_idle = parse_size(value)
            elif option in ('-t', '--max-ss', '--max-time'):
                max_ss = parse_timespan(value)
            elif option in ('-f', '--data-file'):
                data_file = value
            elif option in ('-z', '--zabbix-discovery'):
                zabbix_discovery = True
            elif option in ('-n', '--dry-run', '--simulate'):
                logger.info("Performing a dry run ..")
                dry_run = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
                verbosity += 1
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
                verbosity -= 1
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
    except Exception as e:
        sys.stderr.write("Error: %s!\n" % e)
        sys.exit(1)
    # Execute the requested action(s).
    manager = ApacheManager()
    try:
        if max_memory_active or max_memory_idle or max_ss:
            manager.kill_workers(
                max_memory_active=max_memory_active,
                max_memory_idle=max_memory_idle,
                timeout=max_ss,
                dry_run=dry_run,
            )
        elif watch and connected_to_terminal(sys.stdout):
            watch_metrics(manager)
        elif zabbix_discovery:
            report_zabbix_discovery(manager)
        elif data_file != '-' and verbosity >= 0:
            for line in report_metrics(manager):
                if line_is_heading(line):
                    line = ansi_wrap(line, color=HIGHLIGHT_COLOR)
                print(line)
    finally:
        if (not watch) and (data_file == '-' or not dry_run):
            manager.save_metrics(data_file)
Example #36
0
def main():
    """Command line interface for the ``rotate-backups-s3`` program."""
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    aws_access_key_id = None
    aws_secret_access_key = None
    aws_host = 's3.amazonaws.com'
    config_file = None
    dry_run = False
    exclude_list = []
    include_list = []
    rotation_scheme = {}
    prefer_recent = False
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:],
                                           'U:P:H:d:w:m:y:I:x:c:nvhp', [
                                               'aws-access-key-id=',
                                               'aws-secret-access-key=',
                                               'aws-host=',
                                               'hourly=',
                                               'daily=',
                                               'weekly=',
                                               'monthly=',
                                               'yearly=',
                                               'include=',
                                               'exclude=',
                                               'config=',
                                               'dry-run',
                                               'verbose',
                                               'help',
                                               'prefer-recent',
                                           ])
        for option, value in options:
            if option in ('-H', '--hourly'):
                rotation_scheme['hourly'] = coerce_retention_period(value)
            elif option in ('-d', '--daily'):
                rotation_scheme['daily'] = coerce_retention_period(value)
            elif option in ('-w', '--weekly'):
                rotation_scheme['weekly'] = coerce_retention_period(value)
            elif option in ('-m', '--monthly'):
                rotation_scheme['monthly'] = coerce_retention_period(value)
            elif option in ('-y', '--yearly'):
                rotation_scheme['yearly'] = coerce_retention_period(value)
            elif option in ('-I', '--include'):
                include_list.append(value)
            elif option in ('-x', '--exclude'):
                exclude_list.append(value)
            elif option in ('-c', '--config'):
                config_file = parse_path(value)
            elif option in ('-U', '--aws-access-key-id'):
                aws_access_key_id = value
            elif option in ('-P', '--aws-secret-access-key'):
                aws_secret_access_key = value
            elif option in ('--aws-host'):
                aws_host = value
            elif option in ('-n', '--dry-run'):
                logger.info("Performing a dry run (because of %s option) ..",
                            option)
                dry_run = True
            elif option in ('-p', '--prefer-recent'):
                prefer_recent = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option! (programming error)"
        if rotation_scheme:
            logger.debug("Parsed rotation scheme: %s", rotation_scheme)

        # If no arguments are given but the system has a configuration file
        # then the backups in the configured directories are rotated.
        if not arguments:
            arguments.extend(s3path
                             for s3path, _, _ in load_config_file(config_file))
        # Show the usage message when no directories are given nor configured.
        if not arguments:
            usage(__doc__)
            return
    except Exception as e:
        logger.error("%s", e)
        sys.exit(1)
    # Rotate the backups in the given or configured directories.
    for s3path in arguments:
        prefix = ''
        bucket = s3path[5:] if s3path.startswith('s3://') else s3path

        pos = bucket.find('/')
        if pos != -1:
            prefix = bucket[pos:].strip('/')
            bucket = bucket[:pos]

        S3RotateBackups(
            rotation_scheme=rotation_scheme,
            aws_access_key_id=aws_access_key_id,
            aws_secret_access_key=aws_secret_access_key,
            aws_host=aws_host,
            include_list=include_list,
            exclude_list=exclude_list,
            dry_run=dry_run,
            prefer_recent=prefer_recent,
        ).rotate_backups(bucket, prefix)
Example #37
0
def main():
    """Command line interface for ``unlock-remote-system``."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    program_opts = {}
    identity_file = None
    do_shell = False
    do_watch = False
    watch_all = False
    try:
        options, arguments = getopt.gnu_getopt(sys.argv[1:], 'i:k:p:r:swavqh',
                                               [
                                                   'identity-file=',
                                                   'known-hosts=',
                                                   'password='******'remote-host=',
                                                   'shell',
                                                   'watch',
                                                   'all',
                                                   'verbose',
                                                   'quiet',
                                                   'help',
                                               ])
        for option, value in options:
            if option in ('-i', '--identity-file'):
                identity_file = parse_path(value)
            elif option in ('-k', '--known-hosts'):
                program_opts['known_hosts_file'] = parse_path(value)
            elif option in ('-p', '--password'):
                program_opts['password'] = get_password_from_store(value)
            elif option in ('-r', '--remote-host'):
                program_opts['ssh_proxy'] = value
            elif option in ('-s', '--shell'):
                do_shell = True
            elif option in ('-w', '--watch'):
                do_watch = True
            elif option in ('-a', '--all'):
                watch_all = True
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
            else:
                raise Exception("Unhandled option!")
        if not arguments:
            usage(__doc__)
            sys.exit(0)
        elif len(arguments) > 2:
            raise Exception("only two positional arguments allowed")
        # Create a ConfigLoader object and prepare to pass it to the program to
        # avoid scanning for configuration files more than once (which isn't a
        # real problem but does generate somewhat confusing log output).
        loader = ConfigLoader(program_name='unlock-remote-system')
        program_opts['config_loader'] = loader
        # Check if a single positional argument was given that matches the name
        # of a user defined configuration section.
        if len(arguments) == 1 and arguments[0] in loader.section_names:
            logger.info("Loading configuration section '%s' ..", arguments[0])
            program_opts['config_section'] = arguments[0]
        else:
            # The SSH connection profile of the pre-boot environment
            # is given as the first positional argument.
            program_opts['pre_boot'] = ConnectionProfile(
                expression=arguments[0], identity_file=identity_file)
            # The SSH connection profile of the post-boot environment
            # can be given as the second positional argument, otherwise
            # it will be inferred from the connection profile of
            # the pre-boot environment.
            if len(arguments) == 2:
                program_opts['post_boot'] = ConnectionProfile(
                    expression=arguments[1])
            else:
                # By default we don't use root to login to the post-boot environment.
                program_opts['post_boot'] = ConnectionProfile(
                    expression=arguments[0])
                program_opts['post_boot'].username = find_local_username()
            # Prompt the operator to enter the disk encryption password for the remote host?
            if not program_opts.get('password'):
                program_opts['password'] = prompt_for_password(
                    program_opts['pre_boot'].hostname)
    except Exception as e:
        warning("Failed to parse command line arguments! (%s)", e)
        sys.exit(1)
    # Try to unlock the remote system.
    try:
        if do_watch and watch_all:
            watch_all_systems(loader)
        else:
            with EncryptedSystem(**program_opts) as program:
                if do_watch:
                    program.watch_system()
                else:
                    program.unlock_system()
                    if do_shell:
                        start_interactive_shell(program.post_context)
    except EncryptedSystemError as e:
        logger.error("Aborting due to error: %s", e)
        sys.exit(2)
    except Exception:
        logger.exception("Aborting due to unexpected exception!")
        sys.exit(3)
Example #38
0
def main():
    """Command line interface for the ``rotate-backups`` program."""
    coloredlogs.install(syslog=True)
    # Command line option defaults.
    rotation_scheme = {}
    kw = dict(include_list=[], exclude_list=[])
    parallel = False
    use_sudo = False
    # Internal state.
    selected_locations = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'M:H:d:w:m:y:I:x:jpri:c:r:uC:nvqh', [
            'minutely=', 'hourly=', 'daily=', 'weekly=', 'monthly=', 'yearly=',
            'include=', 'exclude=', 'parallel', 'prefer-recent', 'relaxed',
            'ionice=', 'config=', 'use-sudo', 'dry-run', 'removal-command=',
            'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-M', '--minutely'):
                rotation_scheme['minutely'] = coerce_retention_period(value)
            elif option in ('-H', '--hourly'):
                rotation_scheme['hourly'] = coerce_retention_period(value)
            elif option in ('-d', '--daily'):
                rotation_scheme['daily'] = coerce_retention_period(value)
            elif option in ('-w', '--weekly'):
                rotation_scheme['weekly'] = coerce_retention_period(value)
            elif option in ('-m', '--monthly'):
                rotation_scheme['monthly'] = coerce_retention_period(value)
            elif option in ('-y', '--yearly'):
                rotation_scheme['yearly'] = coerce_retention_period(value)
            elif option in ('-I', '--include'):
                kw['include_list'].append(value)
            elif option in ('-x', '--exclude'):
                kw['exclude_list'].append(value)
            elif option in ('-j', '--parallel'):
                parallel = True
            elif option in ('-p', '--prefer-recent'):
                kw['prefer_recent'] = True
            elif option in ('-r', '--relaxed'):
                kw['strict'] = False
            elif option in ('-i', '--ionice'):
                value = validate_ionice_class(value.lower().strip())
                kw['io_scheduling_class'] = value
            elif option in ('-c', '--config'):
                kw['config_file'] = parse_path(value)
            elif option in ('-u', '--use-sudo'):
                use_sudo = True
            elif option in ('-n', '--dry-run'):
                logger.info("Performing a dry run (because of %s option) ..", option)
                kw['dry_run'] = True
            elif option in ('-C', '--removal-command'):
                removal_command = shlex.split(value)
                logger.info("Using custom removal command: %s", removal_command)
                kw['removal_command'] = removal_command
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option! (programming error)"
        if rotation_scheme:
            logger.verbose("Rotation scheme defined on command line: %s", rotation_scheme)
        if arguments:
            # Rotation of the locations given on the command line.
            location_source = 'command line arguments'
            selected_locations.extend(coerce_location(value, sudo=use_sudo) for value in arguments)
        else:
            # Rotation of all configured locations.
            location_source = 'configuration file'
            selected_locations.extend(
                location for location, rotation_scheme, options
                in load_config_file(configuration_file=kw.get('config_file'), expand=True)
            )
        # Inform the user which location(s) will be rotated.
        if selected_locations:
            logger.verbose("Selected %s based on %s:",
                           pluralize(len(selected_locations), "location"),
                           location_source)
            for number, location in enumerate(selected_locations, start=1):
                logger.verbose(" %i. %s", number, location)
        else:
            # Show the usage message when no directories are given nor configured.
            logger.verbose("No location(s) to rotate selected.")
            usage(__doc__)
            return
    except Exception as e:
        logger.error("%s", e)
        sys.exit(1)
    # Rotate the backups in the selected directories.
    program = RotateBackups(rotation_scheme, **kw)
    if parallel:
        program.rotate_concurrent(*selected_locations)
    else:
        for location in selected_locations:
            program.rotate_backups(location)
Example #39
0
def main():
    """The command line interface."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line options.
    try:
        options, arguments = getopt.gnu_getopt(
            sys.argv[1:],
            "b:m:Wc:B:l:nvqh",
            [
                "block-size=",
                "hash-method=",
                "whole-file",
                "concurrency=",
                "benchmark=",
                "listen=",
                "dry-run",
                "verbose",
                "quiet",
                "help",
            ],
        )
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Command line option defaults.
    client_opts = {}
    server_opts = {}
    # Map parsed options to variables.
    for option, value in options:
        if option in ("-b", "--block-size"):
            client_opts["block_size"] = parse_size(value)
        elif option in ("-m", "--hash-method"):
            client_opts["hash_method"] = value
        elif option in ("-W", "--whole-file"):
            client_opts["delta_transfer"] = False
        elif option in ("-c", "--concurrency"):
            client_opts["concurrency"] = int(value)
            server_opts["concurrency"] = int(value)
        elif option in ("-B", "--benchmark"):
            client_opts["benchmark"] = int(value)
        elif option in ("-l", "--listen"):
            server_opts["address"] = value
        elif option in ("-n", "--dry-run"):
            client_opts["dry_run"] = True
        elif option in ("-v", "--verbose"):
            coloredlogs.increase_verbosity()
        elif option in ("-q", "--quiet"):
            coloredlogs.decrease_verbosity()
        elif option in ("-h", "--help"):
            usage(__doc__)
            sys.exit(0)
    # Execute the requested action.
    try:
        if arguments:
            if len(arguments) != 2:
                warning("Error: Two positional arguments expected!")
                sys.exit(1)
            client_opts['source'] = arguments[0]
            client_opts['target'] = arguments[1]
            run_client(**client_opts)
        else:
            run_server(**server_opts)
    except Exception:
        logger.exception("Program terminating due to exception!")
        sys.exit(1)
Example #40
0
def main():
    """Command line interface for the ``negotiator-guest`` program."""
    # Initialize logging to the terminal and system log.
    coloredlogs.install(syslog=True)
    # Parse the command line arguments.
    list_commands = False
    execute_command = None
    start_daemon = False
    timeout = DEFAULT_TIMEOUT
    character_device = None
    try:
        options, arguments = getopt.getopt(sys.argv[1:], 'le:dt:c:vqh', [
            'list-commands', 'execute=', 'daemon', 'timeout=',
            'character-device=', 'verbose', 'quiet', 'help'
        ])
        for option, value in options:
            if option in ('-l', '--list-commands'):
                list_commands = True
            elif option in ('-e', '--execute'):
                execute_command = value
            elif option in ('-d', '--daemon'):
                start_daemon = True
            elif option in ('-t', '--timeout'):
                timeout = int(value)
            elif option in ('-c', '--character-device'):
                character_device = value
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                sys.exit(0)
        if not (list_commands or execute_command or start_daemon):
            usage(__doc__)
            sys.exit(0)
    except Exception:
        warning("Error: Failed to parse command line arguments!")
        sys.exit(1)
    # Start the guest daemon.
    try:
        if not character_device:
            channel_name = HOST_TO_GUEST_CHANNEL_NAME if start_daemon else GUEST_TO_HOST_CHANNEL_NAME
            character_device = find_character_device(channel_name)
        if start_daemon:
            agent = GuestAgent(character_device=character_device, retry=False)
            agent.enter_main_loop()
        elif list_commands:
            with TimeOut(timeout):
                agent = GuestAgent(character_device, retry=True)
                print('\n'.join(agent.call_remote_method('list_commands')))
        elif execute_command:
            with TimeOut(timeout):
                timer = Timer()
                agent = GuestAgent(character_device, retry=True)
                output = agent.call_remote_method(
                    'execute', *shlex.split(execute_command), capture=True)
                logger.debug("Took %s to execute remote command.", timer)
                print(output.rstrip())
    except Exception:
        logger.exception("Caught a fatal exception! Terminating ..")
        sys.exit(1)
Example #41
0
def main():
    """
    Command line interface for the ``py2deb`` program.
    """
    # Configure terminal output.
    coloredlogs.install()
    try:
        # Initialize a package converter.
        converter = PackageConverter()
        # Parse and validate the command line options.
        options, arguments = getopt.getopt(sys.argv[1:], 'c:r:yvh', [
            'config=', 'repository=', 'name-prefix=', 'no-name-prefix=',
            'rename=', 'install-prefix=', 'install-alternative=',
            'python-callback=', 'report-dependencies=',
            'yes', 'verbose', 'help',
        ])
        control_file_to_update = None
        for option, value in options:
            if option in ('-c', '--config'):
                converter.load_configuration_file(value)
            elif option in ('-r', '--repository'):
                converter.set_repository(value)
            elif option == '--name-prefix':
                converter.set_name_prefix(value)
            elif option == '--no-name-prefix':
                converter.rename_package(value, value)
            elif option == '--rename':
                python_package_name, _, debian_package_name = value.partition(',')
                converter.rename_package(python_package_name, debian_package_name)
            elif option == '--install-prefix':
                converter.set_install_prefix(value)
            elif option == '--install-alternative':
                link, _, path = value.partition(',')
                converter.install_alternative(link, path)
            elif option == '--python-callback':
                converter.set_python_callback(value)
            elif option == '--report-dependencies':
                control_file_to_update = value
                if not os.path.isfile(control_file_to_update):
                    msg = "The given control file doesn't exist! (%s)"
                    raise Exception(msg % control_file_to_update)
            elif option in ('-y', '--yes'):
                converter.set_auto_install(True)
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
            else:
                assert False, "Unhandled option!"
    except Exception as e:
        warning("Failed to parse command line arguments: %s", e)
        sys.exit(1)
    # Convert the requested package(s).
    try:
        if arguments:
            archives, relationships = converter.convert(arguments)
            if relationships and control_file_to_update:
                patch_control_file(control_file_to_update, dict(depends=relationships))
        else:
            usage(__doc__)
    except Exception:
        logger.exception("Caught an unhandled exception!")
        sys.exit(1)
Example #42
0
def main():
    """The command line interface of the ``vcs-tool`` program."""
    # Initialize logging to the terminal.
    coloredlogs.install()
    # Command line option defaults.
    repository = None
    revision = None
    actions = []
    # Parse the command line arguments.
    try:
        options, arguments = getopt.gnu_getopt(sys.argv[1:], 'r:dnisume:vqh', [
            'repository=', 'rev=', 'revision=', 'release=', 'find-directory',
            'find-revision-number', 'find-revision-id', 'list-releases',
            'select-release=', 'sum-revisions', 'vcs-control-field', 'update',
            'merge-up', 'export=', 'verbose', 'quiet', 'help',
        ])
        for option, value in options:
            if option in ('-r', '--repository'):
                value = value.strip()
                assert value, "Please specify the name of a repository! (using -r, --repository)"
                repository = coerce_repository(value)
            elif option in ('--rev', '--revision'):
                revision = value.strip()
                assert revision, "Please specify a nonempty revision string!"
            elif option == '--release':
                # TODO Right now --release and --merge-up cannot be combined
                #      because the following statements result in a global
                #      revision id which is immutable. If release objects had
                #      something like an optional `mutable_revision_id' it
                #      should be possible to support the combination of
                #      --release and --merge-up.
                assert repository, "Please specify a repository first!"
                release_id = value.strip()
                assert release_id in repository.releases, "The given release identifier is invalid!"
                revision = repository.releases[release_id].revision.revision_id
            elif option in ('-d', '--find-directory'):
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(print_directory, repository))
            elif option in ('-n', '--find-revision-number'):
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(print_revision_number, repository, revision))
            elif option in ('-i', '--find-revision-id'):
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(print_revision_id, repository, revision))
            elif option == '--list-releases':
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(print_releases, repository))
            elif option == '--select-release':
                assert repository, "Please specify a repository first!"
                release_id = value.strip()
                assert release_id, "Please specify a nonempty release identifier!"
                actions.append(functools.partial(print_selected_release, repository, release_id))
            elif option in ('-s', '--sum-revisions'):
                assert len(arguments) >= 2, "Please specify one or more repository/revision pairs!"
                actions.append(functools.partial(print_summed_revisions, arguments))
                arguments = []
            elif option == '--vcs-control-field':
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(print_vcs_control_field, repository, revision))
            elif option in ('-u', '--update'):
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(repository.update))
            elif option in ('-m', '--merge-up'):
                assert repository, "Please specify a repository first!"
                actions.append(functools.partial(
                    repository.merge_up,
                    target_branch=revision,
                    feature_branch=arguments[0] if arguments else None,
                ))
            elif option in ('-e', '--export'):
                directory = value.strip()
                assert repository, "Please specify a repository first!"
                assert directory, "Please specify the directory where the revision should be exported!"
                actions.append(functools.partial(repository.export, directory, revision))
            elif option in ('-v', '--verbose'):
                coloredlogs.increase_verbosity()
            elif option in ('-q', '--quiet'):
                coloredlogs.decrease_verbosity()
            elif option in ('-h', '--help'):
                usage(__doc__)
                return
        if not actions:
            usage(__doc__)
            return
    except Exception as e:
        warning("Error: %s", e)
        sys.exit(1)
    # Execute the requested action(s).
    try:
        for action in actions:
            action()
    except Exception:
        logger.exception("Failed to execute requested action(s)!")
        sys.exit(1)