source: dassmodus/trunk/dassmodus/nosferatu/nosferatu/tools/bacsource2configrules.py@ 953

Last change on this file since 953 was 953, checked in by pstorz, on Sep 28, 2011 at 11:32:32 AM

first checkin

File size: 13.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# $Id: bacsource2configrules.py 11326 2010-10-25 07:56:12Z pstorz $
5
6"""Helper script to generate resource classes from
7bacula c definitions.
8
9Usage:
10c2py_resource.py BACULA_SRC_PATH
11"""
12
13####
14# RESOURCE_TYPE has to be either 'dird', 'console', 'filed' or 'stored'
15# CONF_C_FILE is the corresponding c source e.g. 'dird/dird_conf.c'
16#"""
17
18
19
20
21C_CONFS = (
22 ("dird", "dird_conf.c"),
23 ("console", "console_conf.c"),
24 ("filed", "filed_conf.c"),
25 ("stored", "stored_conf.c"),
26 ("lib", "parse_conf.c"),
27 ("inc" , "inc_conf.c"),
28 )
29
30
31
32import os
33import re
34from nosferatu.config_classes import *
35from resource import Resource
36from nosferatu import prettynames
37import pprint
38
39RXP_RESOURCE = re.compile(r'''
40 ^(?:static\s+)?RES_ITEM(2)?\s+
41 (?P<name>[^[]+)\[\]\s+=\s+\{\s*\n # First line with starting brace
42 (?P<items>.*?) # Non greedy search
43 \n}\s*;
44''', re.M|re.X|re.S)
45
46
47RXP_ITEM = re.compile(r'''
48 ^\s+{"(?P<name>[^"]+)"\s*,
49 \s*(?P<handler>[^,]+)\s*,
50 \s*(?P<value>[^,]+)\s*,
51 \s*(?P<code>[^,]+)\s*,
52 \s*(?P<flags>[^,]+)\s*,
53 \s*(?P<default_value>[^}]+)},?\s*
54''', re.X)
55
56
57RXP_RESTABLE = re.compile(r'''
58 ^(?:static\s+)?RES_TABLE\s+
59 (?P<name>[^[]+)\[\]\s+=\s+\{\s*\n # First line with starting brace
60 (?P<items>.*?) # Non greedy search
61 \n}\s*;
62''', re.M|re.X|re.S)
63
64
65RXP_RESTABLE_ITEM = re.compile(r'''
66 ^\s+{"(?P<name>[^"]+)"\s*,
67 \s*(?P<resitem>[^,]+)\s*,
68 \s*(?P<rcode>[^}]+)},?\s*
69''', re.X)
70
71
72
73RXP_STRUCT_TABLE = re.compile(r'''
74 ^(?:static\s+?)?struct
75 \ss_[a-zA-Z_]+\s(?P<name>[^[^{]+)\[\]\s+=\s+\{\s*\n # First line with starting brace
76 (?P<items>.*?) # Non greedy search
77 \n}\s*;
78''', re.M|re.X|re.S)
79
80RXP_STRUCT_ITEM = re.compile(r'''
81 ^\s+{"(?P<name>[^"]+)"\s*,
82 \s*(?P<resitem>[^,]+)\s*(,
83 \s*(?P<rcode>[^}]+))?},?\s*(/\*.*\*/)?
84''', re.X)
85
86
87
88
89# handler to python type wrapping
90CONF2TYPE = {
91 'store_bool' : bool,
92 'store_pint32' : int,
93 'store_str' : str,
94 'store_name' : str,
95 #'store_dir' : Path,
96 }
97
98CONF2VALUE = {
99 'INT32_MAX' : 0x7fffffffL,
100 'true' : True,
101 'false' : False,
102 'REPLACE_ALWAYS': 0 ,
103 #0 : '0' ,
104 #'0' : '0',
105 0 : None ,
106 '0' : None ,
107
108 '60*60*24*31*12*5' : '160704000',
109 '60*60*24*60' : '5184000',
110 '60*60*24*180': '15552000',
111 '60*60*24*365': '31536000',
112 '3 * 60' : '180',
113 '30 * 60' : '1800',
114 '60 * 30' : '1800',
115 '5 * 60' : '300',
116 }
117
118
119
120
121# Read in Commands Info
122
123RXP_COMMAND_ENTRY = re.compile(r'''
124^\s+{\s+NT_\("(?P<cmdtext>[^"]+)"\),
125\s*(?P<cmd>[^"]+),
126\s*_\("(?P<usage>[^"]*)"\),
127\s+NT_\("(?P<help>[^)]*)"\),
128\s*(?P<inrunscript>\w+)}
129''', re.X|re.M|re.S)
130
131
132RXP_DOT_COMMAND_ENTRY = re.compile(r'''
133^\s+{\s+NT_\("(?P<cmdtext>[^"]+)"\),
134\s*(?P<cmd>[^"]+),
135\s*(?P<help>\w*),
136\s*(?P<inrunscript>\w+)}
137''', re.X|re.M|re.S)
138
139
140
141
142
143
144BOOL_FILESET_OPTIONS = set([
145'portable' ,
146'ignorecase' ,
147'honornodumpflag',
148'exclude' ,
149'enhancedwild' ,
150'hardlinks' ,
151'onefs' ,
152'xattrsupport' ,
153'hfsplussupport' ,
154'aclsupport' ,
155'checkfilechanges' ,
156'keepatime' ,
157'readfifo' ,
158'recurse' ,
159'sparse' ,
160'mtimeonly' ,
161'noatime' ,
162])
163
164def defvalue(type, name, value):
165 if type == 'store_opts':
166 if name in BOOL_FILESET_OPTIONS:
167 if value == 0:
168 defval = False
169 else:
170 defval = True
171 else:
172 defval = value
173
174 elif type == 'store_bool' or type == 'store_bit':
175 if value == 0:
176 defval = False
177 else:
178 defval = True
179 else:
180 defval = CONF2VALUE.get(value,value)
181 return defval
182
183
184
185store_classes = []
186
187def parse_conf_c(filename):
188 """parse a bacula c file for resoure item definitions"""
189 cfg = {}
190 cf = open(filename).read()
191 for block in RXP_RESOURCE.finditer(cf):
192 bl = cfg[block.group("name")] = {}
193 for line in block.group("items").split('\n'):
194 m = RXP_ITEM.search(line)
195 if not m: continue
196 item = m.groupdict()
197 bl[item.pop("name")] = item
198 return cfg
199
200
201def parse_conf_c_for_res_table(filename):
202 """parse a bacula c file for resoure table definitions"""
203 cfg = {}
204 cf = open(filename).read()
205 for block in RXP_RESTABLE.finditer(cf):
206 bl = cfg[block.group("name")] = {}
207 for line in block.group("items").split('\n'):
208 m = RXP_RESTABLE_ITEM.search(line)
209 if not m: continue
210 item = m.groupdict()
211 bl[item.pop("name")] = item
212 return cfg
213
214
215
216def directives(daemon, conf):
217 res = conf.keys()
218 res.sort()
219 for r in res:
220 s = "%s_%s = [\n" % (daemon, r)
221 #s = ' '
222 keys = sorted(conf[r].iterkeys())
223 try: # put name first
224 keys.remove('name')
225 keys.insert(0,'name')
226 except:
227 pass
228 for i in keys:
229 #for i, v in conf[r].iteritems():
230 name = i
231 v = conf[r][i]
232 type = v["handler"]
233 required = v["flags"] == "ITEM_REQUIRED"
234 default = v["flags"] == "ITEM_DEFAULT"
235 defaultvalue = defvalue(type, name, v["default_value"])
236 #defaultvalue = CONF2VALUE.get(v["default_value"],v["default_value"])
237 if default:
238 value = defaultvalue
239 else:
240 value = defvalue(type, name, None)
241 s += " %s,\n" % repr(Item(name, value, defaultvalue, default, type, required))
242 s += "]\n"
243 print s
244
245
246def ressources(daemon, conf):
247 res = conf.keys()
248 res.sort()
249 for r in res:
250 s = "# This is the master resource definition. \n# It must have one item for each of the resources.\n"
251 s += "%s_%s = [\n" % (daemon, r)
252 for i, v in conf[r].iteritems():
253 name = i
254 rcode = v["rcode"]
255 resitem = v["resitem"]
256 #print resitem
257 if resitem == 'NULL': continue
258 if resitem == 'msgs_items': # Message ressource is defined in lib file
259 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, 'lib', resitem)
260 else:
261 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, daemon, resitem)
262 s += "]\n"
263 print s
264
265
266
267
268def parse_conf_c_for_structs(filename):
269 """parse a bacula c file for resoure table definitions"""
270 cfg = {}
271 cf = open(filename).read()
272 for block in RXP_STRUCT_TABLE.finditer(cf):
273 if block.group("name") != "FS_options" and block.group("name") != "FS_option_kw":
274 bl = cfg[block.group("name")] = {}
275 for line in block.group("items").split('\n'):
276 m = RXP_STRUCT_ITEM.search(line)
277 if not m: continue
278 item = m.groupdict()
279 bl[item.pop("name")] = item
280
281 elif block.group("name") == "FS_options":
282 bl = cfg[block.group("name")] = {} # keywords
283 for line in block.group("items").split('\n'):
284 m = RXP_STRUCT_ITEM.search(line)
285 if not m: continue
286 item = m.groupdict()
287 if not item["resitem"] in bl:
288 #print "creating", item["resitem"], item
289 bl[item["resitem"]] = []
290 #else:
291 # print "not creating" , item["resitem"]
292 #bl[item["resitem"]].append(item["name"])
293 #item.pop('rcode')
294 bl[item["resitem"]].append(PrettyNames[item.pop('name')])
295
296 #print " appended to bl[" , item["resitem"] , "]" , item
297
298 elif block.group("name") == "FS_option_kw":
299 bl = cfg[block.group("name")] = {} # keywords
300 for line in block.group("items").split('\n'):
301 m = RXP_STRUCT_ITEM.search(line)
302 if not m: continue
303 item = m.groupdict()
304 if not item["name"] in bl:
305 #print "adding", item["resitem"], item["name"]
306 bl[item["name"]] = []
307 #else:
308 # print "not adding" , item["resitem"]
309 #bl[item["resitem"]].append(item["name"])
310 bl[item["name"]] = item.pop('resitem')
311 #print " appending to bl[" , item["resitem"] , "]"
312 #print cfg
313 return cfg
314
315#def structs(daemon, conf):
316
317
318
319
320if __name__ == "__main__":
321 try:
322 bacula_src = sys.argv[1]
323 #bacula_src = '/home/pstorz/bacula_git/trunk/bacula/src/'
324 except:
325 raise(__doc__)
326
327 rsc = []
328
329 print '''#!/usr/bin/env python
330# -*- coding: utf-8 -*-
331#
332# auto_types.py
333#
334# This file is autogenerated from the bacula sources.
335#
336from auto_types import *
337from command import *
338
339 '''
340
341
342 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
343 conf = parse_conf_c_for_structs(bacula_src + 'lib/parse_conf.c')
344 for r in conf.keys():
345 print r + ' = [' ,
346 #print r, conf[r]
347 for i, v in conf[r].iteritems():
348 if str(i) != ' ':
349 print "'" + i.lower() + "'" +', ',
350
351 print ']'
352
353 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
354 conf = parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
355 for r in conf.keys():
356 print r + ' = [' ,
357 #print r, conf[r]
358 for i, v in conf[r].iteritems():
359 if str(i) != ' ':
360 print "'" + prettynames.prettyName(i.lower()) + "'" +', ',
361 #print "'" + i.lower() + "'" +', ',
362 print ']'
363 #print 'READY1'
364
365
366
367
368 conf = parse_conf_c_for_structs(bacula_src + 'dird/inc_conf.c')
369 #print conf
370
371 for r in conf.keys():
372 if r != 'FS_options' and r != 'FS_option_kw':
373 #print 'R:' + r + ':R'
374 print r + ' = [' ,
375 #print r,type( conf[r] )
376 #if type(conf[r]) == 'type <dict>':
377 for i, v in conf[r].iteritems():
378 if type(v) == 'type <str>':
379 print "'" + i.lower() + "'" +', ',
380 else:
381 print '[' , i,'=',v, ']'
382 #print "i,v:",i,v
383 print ']\n'
384
385 elif r == "FS_option_kw":
386 print r + ' = {' ,
387 for i, v in conf[r].iteritems():
388 #if type(v) == 'type <str>':
389 # print "'" + i.lower() + "'" +', ',
390 #else:
391 #print '[' , i,'=',v, ']'
392
393 #print conf['FS_options']
394 try:
395 options = conf['FS_options'][v]
396 #print conf['FS_options'][v]
397 except:
398 options = ['Yes', 'No']
399 #print "excepting on "
400 print "'" + i + "'" , ':', options, ','
401 #print "i,v:",i,v
402 print '}\n'
403
404
405 #else:
406 # for i in conf[r]:
407 # print i
408 # print ']\n'
409
410 #print 'READY2'
411
412
413 commands = {}
414
415 filename = bacula_src+"/dird/ua_cmds.c"
416
417 cf = open(filename).read()
418 for entry in RXP_COMMAND_ENTRY.finditer(cf):
419 #print entry.groups()
420 commands[entry.group("cmdtext")]= command(
421 entry.group("cmdtext"),
422 entry.group("cmd"),
423 entry.group("usage"),
424 entry.group("help").replace('"','').replace('\n',''),
425 entry.group("inrunscript"),
426 )
427
428 filename = bacula_src+"/dird/ua_dotcmds.c"
429
430 cf = open(filename).read()
431 for entry in RXP_DOT_COMMAND_ENTRY.finditer(cf):
432 #print entry.groups()
433 commands[entry.group("cmdtext")]= command(entry.group("cmdtext"),
434 entry.group("cmd"),
435 '',
436 entry.group("help").replace('"','').replace('\n',''),
437 entry.group("inrunscript"),
438 )
439 print "commands = ",
440 pprint.pprint(commands)
441
442
443
444
445 print '''
446#!/usr/bin/env python
447# -*- coding: utf-8 -*-
448# auto_configrules.py
449#
450# This file is autogenerated from the bacula sources.
451#
452from auto_types import *
453from config_classes import *
454
455
456 '''
457
458
459 inc = False
460
461 for daemon, conf in C_CONFS:
462 if daemon == 'inc':
463 inc = True
464 daemon = 'dird'
465 filename = os.path.join(bacula_src, daemon, conf)
466 if inc:
467 daemon = 'inc'
468 directives(daemon, parse_conf_c(filename))
469
470
471 inc = False
472 for daemon, conf in C_CONFS:
473 if daemon == 'inc':
474 inc = True
475 daemon = 'dird'
476 filename = os.path.join(bacula_src, daemon, conf)
477 if inc:
478 daemon = 'inc'
479 ressources(daemon, parse_conf_c_for_res_table(filename))
480
481 print '''
482# manual configurations
483
484dir_addresses_items = [
485 # no items, just a container
486]
487
488cli_addresses_items = [
489 # no items, just a container
490]
491
492store_addresses_items = [
493 # no items, just a container
494]
495
496
497addresses_ip_items = [
498 Item('port', 9102, 9102, True, 'store_str', False),
499 Item('addr', 0, 0, False, 'store_str', False),
500]
501
502#fs_include_items = [
503# Item('file', 0, 0, False, 'store_dir', False),
504#]
505
506fs_include_items = inc_newinc_items
507 '''
508
509
Note: See TracBrowser for help on using the repository browser.