X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=hippotat.git;a=blobdiff_plain;f=hippotat%2F__init__.py;h=60b779f1dcb3253bbe4b9011a1c671004c7d6483;hp=bb1f606f137327b016e94f72fb2ed86b186c98f3;hb=82302bac58d04aa04390ed0d8baebb15bf79829f;hpb=2cf751456040ff2d071f554be97b62a2ab95f9ef diff --git a/hippotat/__init__.py b/hippotat/__init__.py index bb1f606..60b779f 100644 --- a/hippotat/__init__.py +++ b/hippotat/__init__.py @@ -4,6 +4,7 @@ import signal signal.signal(signal.SIGINT, signal.SIG_DFL) import sys +import os from zope.interface import implementer @@ -19,6 +20,7 @@ import ipaddress from ipaddress import AddressValueError from optparse import OptionParser +import configparser from configparser import ConfigParser from configparser import NoOptionError @@ -35,6 +37,7 @@ import hippotat.slip as slip class DBG(twisted.python.constants.Names): INIT = NamedConstant() + CONFIG = NamedConstant() ROUTE = NamedConstant() DROP = NamedConstant() FLOW = NamedConstant() @@ -135,7 +138,7 @@ target_requests_outstanding = 10 # used by server ''' # these need to be defined here so that they can be imported by import * -cfg = ConfigParser() +cfg = ConfigParser(strict=False) optparser = OptionParser() _mimetrans = bytes.maketrans(b'-'+slip.esc, slip.esc+b'-') @@ -401,9 +404,48 @@ def process_cfg_clients(constructor): #---------- startup ---------- -def common_startup(): - optparser.add_option('-c', '--config', dest='configfile', - default='/etc/hippotat/config') +def common_startup(process_cfg): + # ConfigParser hates #-comments after values + trailingcomments_re = regexp.compile('#.*') + cfg.read_string(trailingcomments_re.sub('', defcfg)) + need_defcfg = True + + def readconfig(pathname, mandatory=True): + def log(m, p=pathname): + if not DBG.CONFIG in debug_set: return + print('DBG.CONFIG: %s: %s' % (m, pathname)) + + try: + files = os.listdir(pathname) + + except FileNotFoundError: + if mandatory: raise + log('skipped') + return + + except NotADirectoryError: + cfg.read(pathname) + log('read file') + return + + # is a directory + log('directory') + re = regexp.compile('[^-A-Za-z0-9_]') + for f in os.listdir(cdir): + if re.search(f): continue + subpath = pathname + '/' + f + try: + os.stat(subpath) + except FileNotFoundError: + log('entry skipped', subpath) + continue + cfg.read(subpath) + log('entry read', subpath) + + def oc_config(od,os, value, op): + nonlocal need_defcfg + need_defcfg = False + readconfig(value) def dfs_less_detailed(dl): return [df for df in DBG.iterconstants() if df <= dl] @@ -459,14 +501,28 @@ just `+': all DFLAGs. action='callback', callback= ds_select) + optparser.add_option('-c', '--config', + nargs=1, + type='string', + metavar='CONFIGFILE', + dest='configfile', + action='callback', + callback= oc_config) + (opts, args) = optparser.parse_args() if len(args): optparser.error('no non-option arguments please') - print(repr(debug_set), file=sys.stderr) + if need_defcfg: + readconfig('/etc/hippotat/config', False) + readconfig('/etc/hippotat/config.d', False) + + try: process_cfg() + except (configparser.Error, ValueError): + traceback.print_exc(file=sys.stderr) + print('\nInvalid configuration, giving up.', file=sys.stderr) + sys.exit(12) - re = regexp.compile('#.*') - cfg.read_string(re.sub('', defcfg)) - cfg.read(opts.configfile) + #print(repr(debug_set), file=sys.stderr) log_formatter = twisted.logger.formatEventAsClassicLogText stdout_obs = twisted.logger.FileLogObserver(sys.stdout, log_formatter)