source: trunk/packages/sipb-xen-base/files/usr/share/python-support/sipb-xen-base/invirt/config.py @ 796

Last change on this file since 796 was 796, checked in by price, 16 years ago

use yaml.CSafeDumper and yaml.CSafeLoader everywhere

also break some long lines to fit in 80 columns

File size: 2.1 KB
Line 
1import json
2from invirt.common import *
3from os.path import getmtime
4
5default_src_path   = '/etc/invirt/master.yaml'
6default_cache_path = '/var/lib/invirt/cache.json'
7lock_file          = '/var/lib/invirt/cache.lock'
8
9def load(src_path = default_src_path,
10         cache_path = default_cache_path,
11         force_refresh = False):
12    """
13    Try loading the configuration from the faster-to-load JSON cache at
14    cache_path.  If it doesn't exist or is outdated, load the configuration
15    instead from the original YAML file at src_path and regenerate the cache.
16    I assume I have the permissions to write to the cache directory.
17    """
18    # Namespace container for various state variables, so that they can be
19    # updated by closures.
20    ns = struct()
21
22    if force_refresh:
23        ns.do_refresh = True
24    else:
25        src_mtime = getmtime(src_path)
26        try:            cache_mtime   = getmtime(cache_path)
27        except OSError: ns.do_refresh = True
28        else:           ns.do_refresh = src_mtime > cache_mtime
29
30    if not ns.do_refresh:
31        # Try reading from the cache first.  This must be transactionally
32        # isolated from concurrent writes to prevent reading an incomplete
33        # (changing) version of the data (but the transaction can share the
34        # lock with other concurrent reads).
35        @with_lock_file(lock_file, False)
36        def read_cache():
37            try: ns.cfg = with_closing(file(cache_path)) (
38                lambda f: json.read(f.read()))
39            except: ns.do_refresh = True
40
41    if ns.do_refresh:
42        # Atomically reload the source and regenerate the cache.  The read and
43        # write must be a single transaction, or a stale version may be
44        # written.
45        @with_lock_file(lock_file)
46        def refresh_cache():
47            import yaml
48            ns.cfg = with_closing(file(src_path)) (
49                lambda f: yaml.load(f, yaml.CSafeLoader))
50            try: with_closing(file(cache_path, 'w')) (
51                lambda f: f.write(json.write(ns.cfg)))
52            except: pass # silent failure
53    return ns.cfg
54
55dicts = load()
56structs = dicts2struct(dicts)
57
58# vim:et:sw=4:ts=4
Note: See TracBrowser for help on using the repository browser.