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

Last change on this file since 1155 was 1155, checked in by joergs, on Jun 14, 2013 at 12:37:05 PM

adaptions for bareos

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