[853] | 1 | #!/usr/bin/env python
|
---|
| 2 | # -*- coding: utf-8 -*-
|
---|
| 3 | """Helper script to generate resource classes from
|
---|
| 4 | bacula c definitions.
|
---|
| 5 |
|
---|
| 6 | Usage:
|
---|
| 7 | c2py_resource.py BACULA_SRC_PATH
|
---|
| 8 | """
|
---|
| 9 | # RESOURCE_TYPE has to be either 'dird', 'console', 'filed' or 'stored'
|
---|
| 10 | # CONF_C_FILE is the corresponding c source e.g. 'dird/dird_conf.c'
|
---|
| 11 | #"""
|
---|
| 12 |
|
---|
| 13 | C_CONFS = (
|
---|
| 14 | ("dird", "dird_conf.c"),
|
---|
| 15 | ("console", "console_conf.c"),
|
---|
| 16 | ("filed", "filed_conf.c"),
|
---|
| 17 | ("stored", "stored_conf.c"),
|
---|
| 18 | )
|
---|
| 19 |
|
---|
| 20 |
|
---|
| 21 | import sys
|
---|
| 22 | import os
|
---|
| 23 | import re
|
---|
| 24 | from directive import *
|
---|
| 25 | from resource import Resource
|
---|
| 26 | import pprint
|
---|
| 27 |
|
---|
| 28 | RXP_RESOURCE = re.compile(r'''
|
---|
| 29 | ^(?:static\s+)?RES_ITEM\s+
|
---|
| 30 | (?P<name>[^[]+)\[\]\s+=\s+\{\s*\n # First line with starting brace
|
---|
| 31 | (?P<items>.*?) # Non greedy search
|
---|
| 32 | \n}\s*;
|
---|
| 33 | ''', re.M|re.X|re.S)
|
---|
| 34 |
|
---|
| 35 | RXP_ITEM = re.compile(r'''
|
---|
| 36 | ^\s+{"(?P<name>[^"]+)"\s*,
|
---|
| 37 | \s*(?P<handler>[^,]+)\s*,
|
---|
| 38 | \s*(?P<value>[^,]+)\s*,
|
---|
| 39 | \s*(?P<code>[^,]+)\s*,
|
---|
| 40 | \s*(?P<flags>[^,]+)\s*,
|
---|
| 41 | \s*(?P<default_value>[^}]+)},?\s*
|
---|
| 42 | ''', re.X)
|
---|
| 43 |
|
---|
| 44 | # handler to python type wrapping
|
---|
| 45 | CONF2TYPE = {
|
---|
| 46 | 'store_bool' : bool,
|
---|
| 47 | 'store_pint32' : int,
|
---|
| 48 | 'store_str' : str,
|
---|
| 49 | 'store_name' : str,
|
---|
| 50 | 'store_dir' : Path,
|
---|
| 51 | 'store_password': Password,
|
---|
| 52 | 'store_time' : Time,
|
---|
| 53 | 'store_bit' : bool,
|
---|
| 54 | 'store_size' : int,
|
---|
| 55 | 'store_acl' : Acl,
|
---|
| 56 | 'store_strname' : str,
|
---|
| 57 | 'store_res' : Res
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | def parse_conf_c(filename):
|
---|
| 61 | """parce a bacula c file for resoure item definitions"""
|
---|
| 62 | cfg = {}
|
---|
| 63 | cf = open(filename).read()
|
---|
| 64 | for block in RXP_RESOURCE.finditer(cf):
|
---|
| 65 | bl = cfg[block.group("name")] = {}
|
---|
| 66 | for line in block.group("items").split('\n'):
|
---|
| 67 | m = RXP_ITEM.search(line)
|
---|
| 68 | if not m: continue
|
---|
| 69 | item = m.groupdict()
|
---|
| 70 | bl[item.pop("name")] = item
|
---|
| 71 | return cfg
|
---|
| 72 |
|
---|
| 73 | def directives(daemon, conf):
|
---|
| 74 | res = conf.keys()
|
---|
| 75 | res.sort()
|
---|
| 76 | for r in res:
|
---|
| 77 | items = []
|
---|
| 78 | for i, v in conf[r].iteritems():
|
---|
| 79 | name = i
|
---|
| 80 | if v["flags"] == "ITEM_DEFAULT":
|
---|
| 81 | default = v["default_value"]
|
---|
| 82 | else:
|
---|
| 83 | default = None
|
---|
| 84 | type = CONF2TYPE.get(v["handler"], v["handler"])
|
---|
| 85 | required = v["flags"] == "ITEM_REQUIRED"
|
---|
| 86 | items.append(Item(name, default, type, required))
|
---|
| 87 | items.sort()
|
---|
| 88 | print "%s_%s = %s\n" % (daemon, r, pprint.pformat(items, 2))
|
---|
| 89 | print "\n".join([str(i) for i in items])
|
---|
| 90 |
|
---|
| 91 | if __name__ == "__main__":
|
---|
| 92 | try:
|
---|
| 93 | bacula_src = sys.argv[1]
|
---|
| 94 | except:
|
---|
| 95 | raise(__doc__)
|
---|
| 96 |
|
---|
| 97 | rsc = []
|
---|
| 98 |
|
---|
| 99 | for daemon, conf in C_CONFS:
|
---|
| 100 | filename = os.path.join(bacula_src, daemon, conf)
|
---|
| 101 | directives(daemon, parse_conf_c(filename))
|
---|
| 102 |
|
---|
| 103 |
|
---|