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

Last change on this file since 988 was 988, checked in by pstorz, on Apr 6, 2012 at 7:56:31 AM

fixed wrong default values

File size: 13.3 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 or value == '0' or value == 'false' or value == None:
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 if defaultvalue == None:
243 defaultvalue = ''
244 if required == True:
245 required = 'Ja'
246 else:
247 required = 'Nein'
248 type = type.replace('store_','').replace('_','\_')
249 s += "%s & %s & %s & %s \\\\ \n" % (PrettyNames[name], defaultvalue ,type, required)
250 s += "]\n"
251 print s
252
253
254def ressources(daemon, conf):
255 res = conf.keys()
256 res.sort()
257 for r in res:
258 s = "# This is the master resource definition. \n# It must have one item for each of the resources.\n"
259 s += "%s_%s = [\n" % (daemon, r)
260 for i, v in conf[r].iteritems():
261 name = i
262 rcode = v["rcode"]
263 resitem = v["resitem"]
264 #print resitem
265 if resitem == 'NULL': continue
266 if resitem == 'msgs_items': # Message ressource is defined in lib file
267 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, 'lib', resitem)
268 else:
269 s += " [ \'%s\' , \'%s\', %s_%s ], \n" % (name, rcode, daemon, resitem)
270 s += "]\n"
271 print s
272
273
274
275
276def parse_conf_c_for_structs(filename):
277 """parse a bacula c file for resoure table definitions"""
278 cfg = {}
279 cf = open(filename).read()
280 for block in RXP_STRUCT_TABLE.finditer(cf):
281 if block.group("name") != "FS_options" and block.group("name") != "FS_option_kw":
282 bl = cfg[block.group("name")] = {}
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 bl[item.pop("name")] = item
288
289 elif block.group("name") == "FS_options":
290 bl = cfg[block.group("name")] = {} # keywords
291 for line in block.group("items").split('\n'):
292 m = RXP_STRUCT_ITEM.search(line)
293 if not m: continue
294 item = m.groupdict()
295 if not item["resitem"] in bl:
296 #print "creating", item["resitem"], item
297 bl[item["resitem"]] = []
298 #else:
299 # print "not creating" , item["resitem"]
300 #bl[item["resitem"]].append(item["name"])
301 #item.pop('rcode')
302 bl[item["resitem"]].append(PrettyNames[item.pop('name')])
303
304 #print " appended to bl[" , item["resitem"] , "]" , item
305
306 elif block.group("name") == "FS_option_kw":
307 bl = cfg[block.group("name")] = {} # keywords
308 for line in block.group("items").split('\n'):
309 m = RXP_STRUCT_ITEM.search(line)
310 if not m: continue
311 item = m.groupdict()
312 if not item["name"] in bl:
313 #print "adding", item["resitem"], item["name"]
314 bl[item["name"]] = []
315 #else:
316 # print "not adding" , item["resitem"]
317 #bl[item["resitem"]].append(item["name"])
318 bl[item["name"]] = item.pop('resitem')
319 #print " appending to bl[" , item["resitem"] , "]"
320 #print cfg
321 return cfg
322
323#def structs(daemon, conf):
324
325
326
327
328if __name__ == "__main__":
329 try:
330 bacula_src = sys.argv[1]
331 #bacula_src = '/home/pstorz/bacula_git/trunk/bacula/src/'
332 except:
333 raise(__doc__)
334
335 rsc = []
336
337 print '''#!/usr/bin/env python
338# -*- coding: utf-8 -*-
339#
340# auto_types.py
341#
342# This file is autogenerated from the bacula sources.
343#
344from auto_types import *
345from command import *
346
347 '''
348
349
350 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
351 conf = parse_conf_c_for_structs(bacula_src + 'lib/parse_conf.c')
352 for r in conf.keys():
353 print r + ' = [' ,
354 #print r, conf[r]
355 for i, v in conf[r].iteritems():
356 if str(i) != ' ':
357 print "'" + i.lower() + "'" +', ',
358
359 print ']'
360
361 # for parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
362 conf = parse_conf_c_for_structs(bacula_src + 'dird/dird_conf.c')
363 for r in conf.keys():
364 print r + ' = [' ,
365 #print r, conf[r]
366 for i, v in conf[r].iteritems():
367 if str(i) != ' ':
368 print "'" + prettynames.prettyName(i.lower()) + "'" +', ',
369 #print "'" + i.lower() + "'" +', ',
370 print ']'
371 #print 'READY1'
372
373
374
375
376 conf = parse_conf_c_for_structs(bacula_src + 'dird/inc_conf.c')
377 #print conf
378
379 for r in conf.keys():
380 if r != 'FS_options' and r != 'FS_option_kw':
381 #print 'R:' + r + ':R'
382 print r + ' = [' ,
383 #print r,type( conf[r] )
384 #if type(conf[r]) == 'type <dict>':
385 for i, v in conf[r].iteritems():
386 if type(v) == 'type <str>':
387 print "'" + i.lower() + "'" +', ',
388 else:
389 print '[' , i,'=',v, ']'
390 #print "i,v:",i,v
391 print ']\n'
392
393 elif r == "FS_option_kw":
394 print r + ' = {' ,
395 for i, v in conf[r].iteritems():
396 #if type(v) == 'type <str>':
397 # print "'" + i.lower() + "'" +', ',
398 #else:
399 #print '[' , i,'=',v, ']'
400
401 #print conf['FS_options']
402 try:
403 options = conf['FS_options'][v]
404 #print conf['FS_options'][v]
405 except:
406 options = ['Yes', 'No']
407 #print "excepting on "
408 print "'" + i + "'" , ':', options, ','
409 #print "i,v:",i,v
410 print '}\n'
411
412
413 #else:
414 # for i in conf[r]:
415 # print i
416 # print ']\n'
417
418 #print 'READY2'
419
420
421 commands = {}
422
423 filename = bacula_src+"/dird/ua_cmds.c"
424
425 cf = open(filename).read()
426 for entry in RXP_COMMAND_ENTRY.finditer(cf):
427 #print entry.groups()
428 commands[entry.group("cmdtext")]= command(
429 entry.group("cmdtext"),
430 entry.group("cmd"),
431 entry.group("usage"),
432 entry.group("help").replace('"','').replace('\n',''),
433 entry.group("inrunscript"),
434 )
435
436 filename = bacula_src+"/dird/ua_dotcmds.c"
437
438 cf = open(filename).read()
439 for entry in RXP_DOT_COMMAND_ENTRY.finditer(cf):
440 #print entry.groups()
441 commands[entry.group("cmdtext")]= command(entry.group("cmdtext"),
442 entry.group("cmd"),
443 '',
444 entry.group("help").replace('"','').replace('\n',''),
445 entry.group("inrunscript"),
446 )
447 print "commands = ",
448 pprint.pprint(commands)
449
450
451
452
453 print '''
454#!/usr/bin/env python
455# -*- coding: utf-8 -*-
456# auto_configrules.py
457#
458# This file is autogenerated from the bacula sources.
459#
460from auto_types import *
461from config_classes import *
462
463
464 '''
465
466
467 inc = False
468
469 for daemon, conf in C_CONFS:
470 if daemon == 'inc':
471 inc = True
472 daemon = 'dird'
473 filename = os.path.join(bacula_src, daemon, conf)
474 if inc:
475 daemon = 'inc'
476 directives(daemon, parse_conf_c(filename))
477
478
479 inc = False
480 for daemon, conf in C_CONFS:
481 if daemon == 'inc':
482 inc = True
483 daemon = 'dird'
484 filename = os.path.join(bacula_src, daemon, conf)
485 if inc:
486 daemon = 'inc'
487 ressources(daemon, parse_conf_c_for_res_table(filename))
488
489 print '''
490# manual configurations
491
492dir_addresses_items = [
493 # no items, just a container
494]
495
496cli_addresses_items = [
497 # no items, just a container
498]
499
500store_addresses_items = [
501 # no items, just a container
502]
503
504
505addresses_ip_items = [
506 Item('port', 9102, 9102, True, 'store_str', False),
507 Item('addr', 0, 0, False, 'store_str', False),
508]
509
510#fs_include_items = [
511# Item('file', 0, 0, False, 'store_dir', False),
512#]
513
514fs_include_items = inc_newinc_items
515 '''
516
517
Note: See TracBrowser for help on using the repository browser.