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)
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)
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()
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)
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)
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)
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)
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)
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()
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)
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)
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 ``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)
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)
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)
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()
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)