def testConfigInit(self): env = {'NSSCACHE_CONFIG': 'test.conf'} conf = config.Config(env) self.assertEquals(conf.config_file, env['NSSCACHE_CONFIG'], msg='Failed to override NSSCACHE_CONFIG.')
def setUp(self): # create a directory with a writeable copy of nsscache.conf in it self.workdir = tempfile.mkdtemp() conf_filename = 'nsscache.conf' self.conf_filename = os.path.join(self.workdir, conf_filename) shutil.copy(conf_filename, self.conf_filename) os.chmod(self.conf_filename, 0640) # prepare a config object with this config self.conf = config.Config({}) self.conf.config_file = self.conf_filename
def Run(self, args, env): """Begin execution of nsscache. This method loads our runtime configuration, instantiates the appropriate Source and Cache objects, and invokes the appropriate method based on the command given. NOTE: We avoid calling sys.exit() and instead return an int to our caller, who will exit with that status. Args: args: list of command line arguments env: dictionary of environment variables Returns: POSIX exit status """ # Parse the commandline. try: (options, args) = self.parser.parse_args(args) except SystemExit as e: # OptionParser objects raise SystemExit (error() calls exit() # calls sys.exit()) upon a parser error. # This can be handled better by overriding error or monkeypatching # our parser. return e.code # Initialize a configuration object. conf = config.Config(env) # Process the global flags. if options.verbose: logger = logging.getLogger() logger.setLevel(logging.INFO) if options.debug: logger = logging.getLogger() logger.setLevel(logging.DEBUG) if options.config_file: conf.config_file = options.config_file self.log.info('using nss_cache library, version %s', nss_cache.__version__) self.log.debug('library path is %r', nss_cache.__file__) # Identify the command to dispatch. if not args: print('No command given') self.parser.print_help() return os.EX_USAGE # print global help if command is 'help' with no argument if len(args) == 1 and args[0] == 'help': self.parser.print_help() return os.EX_OK self.log.debug('args: %r' % args) command_name = args.pop(0) self.log.debug('command: %r' % command_name) # Load the configuration from file. config.LoadConfig(conf) # Dispatch the command. try: command_callable = getattr(command, command_name.capitalize()) except AttributeError: self.log.warning('%s is not implemented', command_name) print(('command %r is not implemented' % command_name)) self.parser.print_help() return os.EX_SOFTWARE try: retval = command_callable().Run(conf=conf, args=args) except error.SourceUnavailable as e: self.log.error('Problem with configured data source: %s', e) return os.EX_TEMPFAIL return retval
class NssCacheApp(object): """Main application for building/updating NSS caches.""" def __init__(self): """Set up the application. See the file README.style for logging policy set up here. """ # default to syslog unless on a tty if os.isatty(sys.stdin.fileno()): format_str = ('%(levelname)-8s %(asctime)-15s ' '%(filename)s:%(lineno)d: ' '%(funcName)s: ' '%(message)s') logging.basicConfig(format=format_str) # python2.3's basicConfig doesn't let you set the default level logger = logging.getLogger() logger.setLevel(logging.WARN) else: facility = logging.handlers.SysLogHandler.LOG_DAEMON try: handler = logging.handlers.SysLogHandler(address='/dev/log', facility=facility) except socket.error: print '/dev/log could not be opened; falling back on stderr.' # Omitting an argument to StreamHandler results in sys.stderr being # used. handler = logging.StreamHandler() format_str = (os.path.basename(sys.argv[0]) + '[%(process)d]: %(levelname)s %(message)s') fmt = logging.Formatter(format_str) handler.setFormatter(fmt) handler.setLevel(level=logging.INFO) logging.getLogger('').addHandler(handler) self.log = logging.getLogger('NSSCacheApp') self.parser = self._GetParser() def _GetParser(self): """Sets up our parser for global options. Args: None Returns: # OptionParser is from standard python module optparse OptionParser """ usage = ('nsscache synchronises a local NSS cache against a ' 'remote data source.\n' '\n' 'Usage: nsscache [global options] command [command options]\n' '\n' 'commands:\n') command_descriptions = [] for (name, cls) in command.__dict__.items(): # skip the command base object if name == 'Command': continue if hasattr(cls, 'Help'): short_help = cls().Help(short=True) command_descriptions.append(' %-21s %.40s' % (name.lower(), short_help.lower())) usage += '\n'.join(command_descriptions) version_string = ('nsscache ' + nss_cache.__version__ + '\n' '\n' 'Copyright (c) 2007 Google, Inc.\n' 'This is free software; see the source for copying ' 'conditions. There is NO\n' 'warranty; not even for MERCHANTABILITY or FITNESS ' 'FOR A PARTICULAR PURPOSE.\n' '\n' 'Written by Jamie Wilkinson and Vasilios Hoffman.') parser = optparse.OptionParser(usage, version=version_string) # We do not mix arguments and flags! parser.disable_interspersed_args() # Add options. parser.set_defaults(verbose=False, debug=False) parser.add_option('-v', '--verbose', action='store_true', help='enable verbose output') parser.add_option('-d', '--debug', action='store_true', help='enable debugging output') parser.add_option('-c', '--config-file', type='string', help='read configuration from FILE', metavar='FILE') # filthy monkeypatch hack to remove the prepended 'usage: ' # TODO(jaq): we really ought to subclass OptionParser instead... old_get_usage = parser.get_usage def get_usage(): return old_get_usage()[7:] parser.get_usage = get_usage return parser def Run(self, args, env): """Begin execution of nsscache. This method loads our runtime configuration, instantiates the appropriate Source and Cache objects, and invokes the appropriate method based on the command given. NOTE: We avoid calling sys.exit() and instead return an int to our caller, who will exit with that status. Args: args: list of command line arguments env: dictionary of environment variables Returns: POSIX exit status """ # Parse the commandline. try: (options, args) = self.parser.parse_args(args) except SystemExit, e: # OptionParser objects raise SystemExit (error() calls exit() # calls sys.exit()) upon a parser error. # This can be handled better by overriding error or monkeypatching # our parser. return e.code # Initialize a configuration object. conf = config.Config(env) # Process the global flags. if options.verbose: logger = logging.getLogger() logger.setLevel(logging.INFO) if options.debug: logger = logging.getLogger() logger.setLevel(logging.DEBUG) if options.config_file: conf.config_file = options.config_file self.log.info('using nss_cache library, version %s', nss_cache.__version__) self.log.debug('library path is %r', nss_cache.__file__) # Identify the command to dispatch. if not args: print 'No command given' self.parser.print_help() return os.EX_USAGE # print global help if command is 'help' with no argument if len(args) == 1 and args[0] == 'help': self.parser.print_help() return os.EX_OK self.log.debug('args: %r' % args) command_name = args.pop(0) self.log.debug('command: %r' % command_name) # Load the configuration from file. config.LoadConfig(conf) # Dispatch the command. try: command_callable = getattr(command, command_name.capitalize()) except AttributeError: self.log.warn('%s is not implemented', command_name) print 'command %r is not implemented' % command_name self.parser.print_help() return os.EX_SOFTWARE try: retval = command_callable().Run(conf=conf, args=args) except error.SourceUnavailable, e: self.log.error('Problem with configured data source: %s', e) return os.EX_TEMPFAIL