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

Last change on this file since 984 was 984, checked in by pstorz, on Mar 29, 2012 at 2:44:10 PM

fixed problen with default values

File size: 13.2 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 print "-> type=%s, name=%s, value=%s" % (type,name,value)
166 if type == 'store_opts':
167 if name in BOOL_FILESET_OPTIONS:
168 if value == 0:
169 defval = False
170 else:
171 defval = True
172 else:
173 defval = value
174
175 elif type == 'store_bool' or type == 'store_bit':
176 if value == 0 or value == '0' or value == 'false' or value == None:
177 defval = False
178 else:
179 defval = True
180 else:
181 defval = CONF2VALUE.get(value,value)
182 print "<- type=%s, name=%s, defaultvalue=%s" % (type,name,defval)
183 return defval
184
185
186
187store_classes = []
188
189def parse_conf_c(filename):
190 """parse a bacula c file for resoure item definitions"""
191 cfg = {}
192 cf = open(filename).read()
193 for block in RXP_RESOURCE.finditer(cf):
194 bl = cfg[block.group("name")] = {}
195 for line in block.group("items").split('\n'):
196 m = RXP_ITEM.search(line)
197 if not m: continue
198 item = m.groupdict()
199 bl[item.pop("name")] = item
200 return cfg
201
202
203def parse_conf_c_for_res_table(filename):
204 """parse a bacula c file for resoure table definitions"""
205 cfg = {}
206 cf = open(filename).read()
207 for block in RXP_RESTABLE.finditer(cf):
208 bl = cfg[block.group("name")] = {}
209 for line in block.group("items").split('\n'):
210 m = RXP_RESTABLE_ITEM.search(line)
211 if not m: continue
212 item = m.groupdict()
213 bl[item.pop("name")] = item
214 return cfg
215
216
217
218def directives(daemon, conf):
219 res = conf.keys()
220 res.sort()
221 for r in res:
222 s = "%s_%s = [\n" % (daemon, r)
223 #s = ' '
224 keys = sorted(conf[r].iterkeys())
225 try: # put name first
226 keys.remove('name')
227 keys.insert(0,'name')
228 except:
229 pass
230 for i in keys:
231 #for i, v in conf[r].iteritems():
232 name = i
233 v = conf[r][i]
234 type = v["handler"]
235 required = v["flags"] == "ITEM_REQUIRED"
236 default = v["flags"] == "ITEM_DEFAULT"
237 defaultvalue = defvalue(type, name, v["default_value"])
238 #defaultvalue = CONF2VALUE.get(v["default_value"],v["default_value"])
239 if default:
240 value = defaultvalue
241 else:
242 value = defvalue(type, name, None)
243 print "name:%s value:%s defval: %s" % (name,value,defaultvalue)
244 s += " %s,\n" % repr(Item(name, value, defaultvalue, default, type, required))
245 s += "]\n"
246 print s
247
248
249def ressources(daemon, conf):
250 res = conf.keys()
251 res.sort()
252 for r in res:
253 s = "# This is the master resource definition. \n# It must have one item for each of the resources.\n"
254 s += "%s_%s = [\n" % (daemon, r)
255 for i, v in conf[r].iteritems():
256 name = i
257 rcode = v["rcode"]
258 resitem = v["resitem"]
259 #print resitem
260 if resitem == 'NULL': continue
261 if resitem == 'msgs_items': # Message ressource is defined in lib file
262 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, 'lib', resitem)
263 else:
264 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, daemon, resitem)
265 s += "]\n"
266 print s
267
268
269
270
271def parse_conf_c_for_structs(filename):
272 """parse a bacula c file for resoure table definitions"""
273 cfg = {}
274 cf = open(filename).read()
275 for block in RXP_STRUCT_TABLE.finditer(cf):
276 if block.group("name") != "FS_options" and block.group("name") != "FS_option_kw":
277 bl = cfg[block.group("name")] = {}
278 for line in block.group("items").split('\n'):
279 m = RXP_STRUCT_ITEM.search(line)
280 if not m: continue
281 item = m.groupdict()
282 bl[item.pop("name")] = item
283
284 elif block.group("name") == "FS_options":
285 bl = cfg[block.group("name")] = {} # keywords
286 for line in block.group("items").split('\n'):
287 m = RXP_STRUCT_ITEM.search(line)
288 if not m: continue
289 item = m.groupdict()
290 if not item["resitem"] in bl:
291 #print "creating", item["resitem"], item
292 bl[item["resitem"]] = []
293 #else:
294 # print "not creating" , item["resitem"]
295 #bl[item["resitem"]].append(item["name"])
296 #item.pop('rcode')
297 bl[item["resitem"]].append(PrettyNames[item.pop('name')])
298
299 #print " appended to bl[" , item["resitem"] , "]" , item
300
301 elif block.group("name") == "FS_option_kw":
302 bl = cfg[block.group("name")] = {} # keywords
303 for line in block.group("items").split('\n'):
304 m = RXP_STRUCT_ITEM.search(line)
305 if not m: continue
306 item = m.groupdict()
307 if not item["name"] in bl:
308 #print "adding", item["resitem"], item["name"]
309 bl[item["name"]] = []
310 #else:
311 # print "not adding" , item["resitem"]
312 #bl[item["resitem"]].append(item["name"])
313 bl[item["name"]] = item.pop('resitem')
314 #print " appending to bl[" , item["resitem"] , "]"
315 #print cfg
316 return cfg
317
318#def structs(daemon, conf):
319
320
321
322
323if __name__ == "__main__":
324 try:
325 bacula_src = sys.argv[1]
326 #bacula_src = '/home/pstorz/bacula_git/trunk/bacula/src/'
327 except:
328 raise(__doc__)
329
330 rsc = []
331
332 print '''#!/usr/bin/env python
333# -*- coding: utf-8 -*-
334#
335# auto_types.py
336#
337# This file is autogenerated from the bacula sources.
338#
339from auto_types import *
340from command import *
341
342 '''
343
344
345 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
346 conf = parse_conf_c_for_structs(bacula_src + 'lib/parse_conf.c')
347 for r in conf.keys():
348 print r + ' = [' ,
349 #print r, conf[r]
350 for i, v in conf[r].iteritems():
351 if str(i) != ' ':
352 print "'" + i.lower() + "'" +', ',
353
354 print ']'
355
356 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
357 conf = parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
358 for r in conf.keys():
359 print r + ' = [' ,
360 #print r, conf[r]
361 for i, v in conf[r].iteritems():
362 if str(i) != ' ':
363 print "'" + prettynames.prettyName(i.lower()) + "'" +', ',
364 #print "'" + i.lower() + "'" +', ',
365 print ']'
366 #print 'READY1'
367
368
369
370
371 conf = parse_conf_c_for_structs(bacula_src + 'dird/inc_conf.c')
372 #print conf
373
374 for r in conf.keys():
375 if r != 'FS_options' and r != 'FS_option_kw':
376 #print 'R:' + r + ':R'
377 print r + ' = [' ,
378 #print r,type( conf[r] )
379 #if type(conf[r]) == 'type <dict>':
380 for i, v in conf[r].iteritems():
381 if type(v) == 'type <str>':
382 print "'" + i.lower() + "'" +', ',
383 else:
384 print '[' , i,'=',v, ']'
385 #print "i,v:",i,v
386 print ']\n'
387
388 elif r == "FS_option_kw":
389 print r + ' = {' ,
390 for i, v in conf[r].iteritems():
391 #if type(v) == 'type <str>':
392 # print "'" + i.lower() + "'" +', ',
393 #else:
394 #print '[' , i,'=',v, ']'
395
396 #print conf['FS_options']
397 try:
398 options = conf['FS_options'][v]
399 #print conf['FS_options'][v]
400 except:
401 options = ['Yes', 'No']
402 #print "excepting on "
403 print "'" + i + "'" , ':', options, ','
404 #print "i,v:",i,v
405 print '}\n'
406
407
408 #else:
409 # for i in conf[r]:
410 # print i
411 # print ']\n'
412
413 #print 'READY2'
414
415
416 commands = {}
417
418 filename = bacula_src+"/dird/ua_cmds.c"
419
420 cf = open(filename).read()
421 for entry in RXP_COMMAND_ENTRY.finditer(cf):
422 #print entry.groups()
423 commands[entry.group("cmdtext")]= command(
424 entry.group("cmdtext"),
425 entry.group("cmd"),
426 entry.group("usage"),
427 entry.group("help").replace('"','').replace('\n',''),
428 entry.group("inrunscript"),
429 )
430
431 filename = bacula_src+"/dird/ua_dotcmds.c"
432
433 cf = open(filename).read()
434 for entry in RXP_DOT_COMMAND_ENTRY.finditer(cf):
435 #print entry.groups()
436 commands[entry.group("cmdtext")]= command(entry.group("cmdtext"),
437 entry.group("cmd"),
438 '',
439 entry.group("help").replace('"','').replace('\n',''),
440 entry.group("inrunscript"),
441 )
442 print "commands = ",
443 pprint.pprint(commands)
444
445
446
447
448 print '''
449#!/usr/bin/env python
450# -*- coding: utf-8 -*-
451# auto_configrules.py
452#
453# This file is autogenerated from the bacula sources.
454#
455from auto_types import *
456from config_classes import *
457
458
459 '''
460
461
462 inc = False
463
464 for daemon, conf in C_CONFS:
465 if daemon == 'inc':
466 inc = True
467 daemon = 'dird'
468 filename = os.path.join(bacula_src, daemon, conf)
469 if inc:
470 daemon = 'inc'
471 directives(daemon, parse_conf_c(filename))
472
473
474 inc = False
475 for daemon, conf in C_CONFS:
476 if daemon == 'inc':
477 inc = True
478 daemon = 'dird'
479 filename = os.path.join(bacula_src, daemon, conf)
480 if inc:
481 daemon = 'inc'
482 ressources(daemon, parse_conf_c_for_res_table(filename))
483
484 print '''
485# manual configurations
486
487dir_addresses_items = [
488 # no items, just a container
489]
490
491cli_addresses_items = [
492 # no items, just a container
493]
494
495store_addresses_items = [
496 # no items, just a container
497]
498
499
500addresses_ip_items = [
501 Item('port', 9102, 9102, True, 'store_str', False),
502 Item('addr', 0, 0, False, 'store_str', False),
503]
504
505#fs_include_items = [
506# Item('file', 0, 0, False, 'store_dir', False),
507#]
508
509fs_include_items = inc_newinc_items
510 '''
511
512
Note: See TracBrowser for help on using the repository browser.