Ignore:
Timestamp:
Jul 28, 2008, 12:25:19 PM (16 years ago)
Author:
y_z
Message:
  • added timestamp-based JSON caching of configuration for faster loading
  • exposed (more) options to command-line frontend
  • improved error messages/handling/help
  • removed all python 2.5-isms
  • reformatted to fit project style conventions
Location:
trunk/packages/sipb-xen-base/files/usr
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/sipb-xen-base/files/usr/sbin/invirt-getconf

    r733 r771  
    1 #!/usr/bin/env python2.5
     1#!/usr/bin/env python
    22
    33"""
     
    2020from optparse import OptionParser
    2121
    22 class invirt_exception( Exception ): pass
     22class invirt_exception(Exception): pass
    2323
    24 def main( argv ):
     24def main(argv):
    2525    try:
    26         parser = OptionParser()
    27         parser.add_option('-f', '--file', default = '/etc/invirt/master.yaml',
    28                 help = 'the configuration file to read from')
    29         options, args = parser.parse_args()
     26        parser = OptionParser(usage = '%prog [options] key',
     27                description = __doc__.strip().split('\n\n')[0])
     28        parser.add_option('-s', '--src',
     29                default = '/etc/invirt/master.yaml',
     30                help = 'the source YAML configuration file to read from')
     31        parser.add_option('-c', '--cache',
     32                default = '/var/lib/invirt/invirt.json',
     33                help = 'path to the JSON cache')
     34        parser.add_option('-r', '--refresh',
     35                action = 'store_true',
     36                help = 'force the cache to be regenerated')
     37        opts, args = parser.parse_args()
    3038
    3139        try: [key] = args
    32         except: raise invirt_exception( __doc__ )
     40        except: raise invirt_exception(__doc__.strip())
    3341
    34         conf = load()
     42        conf = load(opts.src, opts.cache, opts.refresh)
    3543        components = key.split('.')
    36         for i, component in enumerate( components ):
    37             progress = lambda: '.'.join( components[:i] )
    38             if type( conf ) not in [ dict, list ]:
     44        for i, component in enumerate(components):
     45            progress = '.'.join(components[:i])
     46            if type(conf) not in [dict, list]:
    3947                raise invirt_exception(
    40                         'prematurely arrived at an atomic datum in the tree:\n'
    41                         '%s has no children' % progress() )
    42             if type( conf ) == list:
    43                 try: component = int( component )
     48                        '%s: node has no children (atomic datum)' % progress)
     49            if type(conf) == list:
     50                try: component = int(component)
    4451                except: raise invirt_exception(
    45                         '%s is a list, requires an integral path component '
    46                         'but got "%s"' % ( progress(), component ) )
    47             try: conf = conf[ component ]
     52                        '%s: node a list; integer path component required, '
     53                        'but got "%s"' % (progress, component))
     54            try: conf = conf[component]
    4855            except KeyError: raise invirt_exception(
    49                     '"%s" not in "%s"' % ( component, progress() ) )
     56                    '%s: key "%s" not found' % (progress, component))
     57            except IndexError: raise invirt_exception(
     58                    '%s: index %s out of range' % (progress, component))
    5059        print conf
    51     except invirt_exception, ex:
     60    except (invirt_exception, OSError), ex:
    5261        print >> stderr, ex
    5362        return 1
    5463
    55 if __name__ == '__main__': exit( main( argv ) )
     64if __name__ == '__main__':
     65    exit(main(argv))
    5666
    5767# vim:et:sw=4:ts=4
  • trunk/packages/sipb-xen-base/files/usr/share/python-support/sipb-xen-base/invirt/config.py

    r766 r771  
    1 import yaml
     1import json, yaml
     2from os import error, makedirs
     3from os.path import dirname, getmtime
    24
    3 default_path = '/etc/invirt/master.yaml'
     5default_src_path   = '/etc/invirt/master.yaml'
     6default_cache_path = '/var/lib/invirt/invirt.json'
    47
    58try:    default_loader = yaml.CSafeLoader
    69except: default_loader = yaml.SafeLoader
    710
    8 def load( path = default_path ):
    9     return yaml.load( file(path), default_loader )
     11def wrap(rsrc, func):
     12    "Utility to that emulates with Python 2.5's `with closing(rsrc)`."
     13    try: return func(rsrc)
     14    finally: rsrc.close()
     15
     16def load(src_path = default_src_path,
     17         cache_path = default_cache_path,
     18         force_refresh = False):
     19    """
     20    Try loading the configuration from the faster-to-load JSON cache at
     21    cache_path.  If it doesn't exist or is outdated, load the configuration
     22    instead from the original YAML file at src_path and regenerate the cache.
     23    I assume I have the permissions to write to the cache directory.
     24    """
     25    if force_refresh:
     26        do_refresh = True
     27    else:
     28        src_mtime = getmtime(src_path)
     29        try:            cache_mtime = getmtime(cache_path)
     30        except OSError: do_refresh  = True
     31        else:           do_refresh  = src_mtime > cache_mtime
     32
     33    if do_refresh:
     34        # reload the source and regenerate the cache
     35        cfg = wrap(file(src_path), lambda f: yaml.load(f, default_loader))
     36        wrap(file(cache_path, 'w'), lambda f: f.write(json.write(cfg)))
     37    else:
     38        cfg = wrap(file(cache_path), lambda f: json.read(f.read()))
     39    return cfg
    1040
    1141# vim:et:sw=4:ts=4
Note: See TracChangeset for help on using the changeset viewer.