commit f7c96b7220f64c5c76d6c4e6127ea7f7cbe3fe1a Author: Damian Johnson atagar@torproject.org Date: Fri Dec 27 22:13:17 2013 -0800
Moving expand_events() to the arguments module
Revising the logPanel's expandEvents() function and moving it to the arguments module. This is a function for... well, parsing an argument so this is the perfect place for it. Also renaming our '--event' argument to '--log'. --- arm/arguments.py | 108 +++++++++++++++++++++++++++++++++++++++++++----- arm/config/strings.cfg | 6 ++- arm/controller.py | 3 +- arm/logPanel.py | 71 +++---------------------------- arm/starter.py | 29 +++++-------- 5 files changed, 118 insertions(+), 99 deletions(-)
diff --git a/arm/arguments.py b/arm/arguments.py index cc512bd..17e2958 100644 --- a/arm/arguments.py +++ b/arm/arguments.py @@ -9,6 +9,7 @@ import os import arm
import stem.connection +import stem.util.log
from arm.util import msg
@@ -25,18 +26,26 @@ DEFAULT_ARGS = { 'print_help': False, }
-OPT = "i:s:c:d:be:vh" +OPT = "i:s:c:d:bl:vh"
OPT_EXPANDED = [ "interface=", "socket=", "config=", "debug=", - "event=", + "log=", "version", "help", ]
+TOR_EVENT_TYPES = { + "d": "DEBUG", "a": "ADDRMAP", "k": "DESCCHANGED", "s": "STREAM", + "i": "INFO", "f": "AUTHDIR_NEWDESCS", "g": "GUARD", "r": "STREAM_BW", + "n": "NOTICE", "h": "BUILDTIMEOUT_SET", "l": "NEWCONSENSUS", "t": "STATUS_CLIENT", + "w": "WARN", "b": "BW", "m": "NEWDESC", "u": "STATUS_GENERAL", + "e": "ERR", "c": "CIRC", "p": "NS", "v": "STATUS_SERVER", + "j": "CLIENTS_SEEN", "q": "ORCONN"} +
def parse(argv): """ @@ -54,7 +63,7 @@ def parse(argv): args = dict(DEFAULT_ARGS)
for opt, arg in getopt.getopt(argv, OPT, OPT_EXPANDED)[0]: - if opt in ("-i", "--interface"): + if opt in ('-i', '--interface'): if ':' in arg: address, port = arg.split(':', 1) else: @@ -62,27 +71,32 @@ def parse(argv):
if address is not None: if not stem.util.connection.is_valid_ipv4_address(address): - raise ValueError("'%s' isn't a valid IPv4 address" % address) + raise ValueError(msg('usage.not_a_valid_address', address_input = address))
args['control_address'] = address
if not stem.util.connection.is_valid_port(port): - raise ValueError("'%s' isn't a valid port number" % port) + raise ValueError(msg('usage.not_a_valid_port', port_input = port))
args['control_port'] = int(port) args['user_provided_port'] = True - elif opt in ("-s", "--socket"): + elif opt in ('-s', '--socket'): args['control_socket'] = arg args['user_provided_socket'] = True - elif opt in ("-c", "--config"): + elif opt in ('-c', '--config'): args['config'] = arg - elif opt in ("-d", "--debug"): + elif opt in ('-d', '--debug'): args['debug_path'] = os.path.expanduser(arg) - elif opt in ("-e", "--event"): + elif opt in ('-l', '--log'): + try: + expand_events(arg) + except ValueError as exc: + raise ValueError(msg('usage.unrecognized_log_flags', flags = exc)) + args['logged_events'] = arg - elif opt in ("-v", "--version"): + elif opt in ('-v', '--version'): args['print_version'] = True - elif opt in ("-h", "--help"): + elif opt in ('-h', '--help'): args['print_help'] = True
# translates our args dict into a named tuple @@ -119,3 +133,75 @@ def get_version(): version = arm.__version__, date = arm.__release_date__, ) + + +def expand_events(flags): + """ + Expands event abbreviations to their full names. Beside mappings provided in + TOR_EVENT_TYPES this recognizes the following special events and aliases: + + * A - all events + * X - no events + * U - UKNOWN events + * DINWE - runlevel and higher + * 12345 - arm/stem runlevel and higher (ARM_DEBUG - ARM_ERR) + + For example... + + :: + + >>> expand_events('inUt') + ["INFO", "NOTICE", "UNKNOWN", "STREAM_BW"] + + >>> expand_events('N4') + ["NOTICE", "WARN", "ERR", "ARM_WARN", "ARM_ERR"] + + >>> expand_events('cfX') + [] + + :param str flags: character flags to be expanded + + :raises: **ValueError** with invalid input if any flags are unrecognized + """ + + expanded_events, invalid_flags = set(), '' + arm_runlevels = ['ARM_' + runlevel for runlevel in stem.util.log.Runlevel] + + for flag in flags: + if flag == 'A': + expanded_events = set(list(TOR_EVENT_TYPES) + arm_runlevels + ['UNKNOWN']) + break + elif flag == 'X': + expanded_events = set() + break + elif flag in 'DINWE12345': + # all events for a runlevel and higher + + if flag in 'D1': + runlevel_index = 1 + elif flag in 'I2': + runlevel_index = 2 + elif flag in 'N3': + runlevel_index = 3 + elif flag in 'W4': + runlevel_index = 4 + elif flag in 'E5': + runlevel_index = 5 + + if flag in 'DINWE': + runlevels = list(stem.util.log.Runlevel)[runlevel_index:] + elif flag in '12345': + runlevels = arm_runlevels[runlevel_index:] + + expanded_events.update(set(runlevels)) + elif flag == 'U': + expanded_events.add('UNKNOWN') + elif flag in TOR_EVENT_TYPES: + expanded_events.add(TOR_EVENT_TYPES[flag]) + else: + invalid_flags += flag + + if invalid_flags: + raise ValueError(invalid_flags) + else: + return expanded_events diff --git a/arm/config/strings.cfg b/arm/config/strings.cfg index 7451cde..cc204c1 100644 --- a/arm/config/strings.cfg +++ b/arm/config/strings.cfg @@ -42,7 +42,9 @@ msg.tracker.unable_to_use_all_resolvers We were unable to use any of your system msg.tracker.unable_to_use_resolver Unable to query connections with {old_resolver}, trying {new_resolver}
msg.usage.invalid_arguments {error} (for usage provide --help) -msg.usage.unrecognized_log_flag Unrecognized event flag: {flag} +msg.usage.not_a_valid_address '{address_input}' isn't a valid IPv4 address +msg.not_a_valid_port '{port_input}' isn't a valid port number +msg.usage.unrecognized_log_flags Unrecognized event flags: {flags}
msg.connect.missing_password_bug |BUG: You provided a password but despite this stem reported that it was @@ -108,7 +110,7 @@ msg.usage.help_output | -c, --config CONFIG_PATH loaded configuration options, CONFIG_PATH | defaults to: {config} | -d, --debug LOG_PATH writes all arm logs to the given location -| -e, --event EVENT_FLAGS event types in message log (default: {events}) +| -l, --log EVENT_FLAGS event types to be logged (default: {events}) |{event_flags} | -v, --version provides version information | -h, --help presents this help diff --git a/arm/controller.py b/arm/controller.py index 6382acd..8193971 100644 --- a/arm/controller.py +++ b/arm/controller.py @@ -9,6 +9,7 @@ import curses import sys import threading
+import arm.arguments import arm.menu.menu import arm.popups import arm.headerPanel @@ -103,7 +104,7 @@ def initController(stdscr, startTime): firstPagePanels.append(arm.graphing.graphPanel.GraphPanel(stdscr))
if CONFIG["features.panels.show.log"]: - expandedEvents = arm.logPanel.expandEvents(CONFIG["startup.events"]) + expandedEvents = arm.arguments.expand_events(CONFIG["startup.events"]) firstPagePanels.append(arm.logPanel.LogPanel(stdscr, expandedEvents))
if firstPagePanels: pagePanels.append(firstPagePanels) diff --git a/arm/logPanel.py b/arm/logPanel.py index ac1cb7f..cdb2081 100644 --- a/arm/logPanel.py +++ b/arm/logPanel.py @@ -16,18 +16,11 @@ from stem.control import State from stem.response import events from stem.util import conf, log, system
+import arm.arguments import arm.popups from arm import __version__ from arm.util import panel, torTools, uiTools
-TOR_EVENT_TYPES = { - "d": "DEBUG", "a": "ADDRMAP", "k": "DESCCHANGED", "s": "STREAM", - "i": "INFO", "f": "AUTHDIR_NEWDESCS", "g": "GUARD", "r": "STREAM_BW", - "n": "NOTICE", "h": "BUILDTIMEOUT_SET", "l": "NEWCONSENSUS", "t": "STATUS_CLIENT", - "w": "WARN", "b": "BW", "m": "NEWDESC", "u": "STATUS_GENERAL", - "e": "ERR", "c": "CIRC", "p": "NS", "v": "STATUS_SERVER", - "j": "CLIENTS_SEEN", "q": "ORCONN"} - RUNLEVEL_EVENT_COLOR = {log.DEBUG: "magenta", log.INFO: "blue", log.NOTICE: "green", log.WARN: "yellow", log.ERR: "red"} DAYBREAK_EVENT = "DAYBREAK" # special event for marking when the date changes @@ -97,60 +90,6 @@ def daysSince(timestamp=None): if timestamp == None: timestamp = time.time() return int((timestamp - TIMEZONE_OFFSET) / 86400)
-def expandEvents(eventAbbr): - """ - Expands event abbreviations to their full names. Beside mappings provided in - TOR_EVENT_TYPES this recognizes the following special events and aliases: - U - UKNOWN events - A - all events - X - no events - DINWE - runlevel and higher - 12345 - arm/stem runlevel and higher (ARM_DEBUG - ARM_ERR) - Raises ValueError with invalid input if any part isn't recognized. - - Examples: - "inUt" -> ["INFO", "NOTICE", "UNKNOWN", "STREAM_BW"] - "N4" -> ["NOTICE", "WARN", "ERR", "ARM_WARN", "ARM_ERR"] - "cfX" -> [] - - Arguments: - eventAbbr - flags to be parsed to event types - """ - - expandedEvents, invalidFlags = set(), "" - - for flag in eventAbbr: - if flag == "A": - armRunlevels = ["ARM_" + runlevel for runlevel in log.Runlevel] - expandedEvents = set(list(TOR_EVENT_TYPES) + armRunlevels + ["UNKNOWN"]) - break - elif flag == "X": - expandedEvents = set() - break - elif flag in "DINWE12345": - # all events for a runlevel and higher - if flag in "D1": runlevelIndex = 1 - elif flag in "I2": runlevelIndex = 2 - elif flag in "N3": runlevelIndex = 3 - elif flag in "W4": runlevelIndex = 4 - elif flag in "E5": runlevelIndex = 5 - - if flag in "DINWE": - runlevelSet = [runlevel for runlevel in list(log.Runlevel)[runlevelIndex:]] - expandedEvents = expandedEvents.union(set(runlevelSet)) - elif flag in "12345": - runlevelSet = ["ARM_" + runlevel for runlevel in list(log.Runlevel)[runlevelIndex:]] - expandedEvents = expandedEvents.union(set(runlevelSet)) - elif flag == "U": - expandedEvents.add("UNKNOWN") - elif flag in TOR_EVENT_TYPES: - expandedEvents.add(TOR_EVENT_TYPES[flag]) - else: - invalidFlags += flag - - if invalidFlags: raise ValueError(invalidFlags) - else: return expandedEvents - def getMissingEventTypes(): """ Provides the event types the current tor connection supports but arm @@ -162,7 +101,7 @@ def getMissingEventTypes():
if torEventTypes: torEventTypes = torEventTypes.split(" ") - armEventTypes = TOR_EVENT_TYPES.values() + armEventTypes = arm.arguments.TOR_EVENT_TYPES.values() return [event for event in torEventTypes if not event in armEventTypes] else: return None # GETINFO call failed
@@ -621,7 +560,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): color = "magenta" elif isinstance(event, events.GuardEvent): color = "yellow" - elif not event.type in TOR_EVENT_TYPES.values(): + elif not event.type in arm.arguments.TOR_EVENT_TYPES.values(): color = "red" # unknown event type
self.registerEvent(LogEntry(event.arrived_at, event.type, msg, color)) @@ -762,7 +701,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): userInput = arm.popups.inputPrompt("Events to log: ") if userInput: userInput = userInput.replace(' ', '') # strips spaces - try: self.setLoggedEvents(expandEvents(userInput)) + try: self.setLoggedEvents(arm.arguments.expand_events(userInput)) except ValueError, exc: arm.popups.showMsg("Invalid flags: %s" % str(exc), 2) finally: arm.popups.finalize() @@ -1107,7 +1046,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): events.add("WARN") events.remove("WARNING")
- torEvents = events.intersection(set(TOR_EVENT_TYPES.values())) + torEvents = events.intersection(set(arm.arguments.TOR_EVENT_TYPES.values())) armEvents = events.intersection(set(["ARM_%s" % runlevel for runlevel in log.Runlevel.keys()]))
# adds events unrecognized by arm if we're listening to the 'UNKNOWN' type diff --git a/arm/starter.py b/arm/starter.py index a8824a7..021ed68 100644 --- a/arm/starter.py +++ b/arm/starter.py @@ -34,7 +34,7 @@ import stem.util.system
from arm.util import init_controller, msg, trace, info, notice, warn, load_settings
-CONFIG = stem.util.conf.config_dict("arm", { +CONFIG = stem.util.conf.config_dict('arm', { 'tor.chroot': '', 'tor.password': None, }) @@ -78,16 +78,6 @@ def main(): _load_armrc(args.config) _validate_chroot()
- # validates and expands log event flags - - try: - arm.logPanel.expandEvents(args.logged_events) - except ValueError as exc: - for flag in str(exc): - print msg('usage.unrecognized_log_flag', flag = flag) - - sys.exit(1) - try: controller = _get_controller(args) _authenticate(controller, CONFIG['tor.password']) @@ -247,11 +237,12 @@ def _setup_debug_logging(args): datefmt = '%m/%d/%Y %H:%M:%S' ))
- stem.util.log.get_logger().addHandler(debug_handler) + logger = stem.util.log.get_logger() + logger.addHandler(debug_handler)
- if not os.path.exists(args.config): - armrc_content = "[file doesn't exist]" - else: + armrc_content = "[file doesn't exist]" + + if os.path.exists(args.config): try: with open(args.config) as armrc_file: armrc_content = armrc_file.read() @@ -290,7 +281,7 @@ def _validate_chroot(): """
config = stem.util.conf.get_config('arm') - chroot = CONFIG['tor.chroot'].strip().rstrip(os.path.sep) + chroot = config.get('tor.chroot', '').strip().rstrip(os.path.sep)
if chroot and not os.path.exists(chroot): notice('setup.chroot_doesnt_exist', path = chroot) @@ -306,13 +297,13 @@ def _setup_freebsd_chroot(controller): :param stem.control.Controller controller: tor controller connection """
- if not CONFIG['tor.chroot'] and platform.system() == 'FreeBSD': + config = stem.util.conf.get_config('arm') + + if not config.get('tor.chroot', None) and platform.system() == 'FreeBSD': jail_chroot = stem.util.system.get_bsd_jail_path(controller.get_pid(0))
if jail_chroot and os.path.exists(jail_chroot): info('setup.set_freebsd_chroot', path = jail_chroot) - - config = stem.util.conf.get_config('arm') config.set('tor.chroot', jail_chroot)
tor-commits@lists.torproject.org