1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
__revision__ = '$Revision$'
__all__ = ['Mode', 'Client', 'Compare', 'Init', 'Minestruct', 'Perf',
'Pull', 'Query', 'Snapshots', 'Tidy', 'Viz', 'Xcmd']
import ConfigParser
import logging
import lxml.etree
import sys
import Bcfg2.Server.Core
import Bcfg2.Options
class ModeOperationError(Exception):
pass
class Mode(object):
'''Help message has not yet been added for mode'''
__shorthelp__ = 'Shorthelp not defined yet'
__longhelp__ = 'Longhelp not defined yet'
__args__ = []
def __init__(self, configfile):
self.configfile = configfile
self.__cfp = False
self.log = logging.getLogger('Bcfg2.Server.Admin.Mode')
def getCFP(self):
if not self.__cfp:
self.__cfp = ConfigParser.ConfigParser()
self.__cfp.read(self.configfile)
return self.__cfp
cfp = property(getCFP)
def __call__(self, args):
if len(args) > 0 and args[0] == 'help':
print self.__longhelp__
raise SystemExit(0)
def errExit(self, emsg):
print emsg
raise SystemExit(1)
def get_repo_path(self):
'''return repository path'''
return self.cfp.get('server', 'repository')
def load_stats(self, client):
stats = lxml.etree.parse("%s/etc/statistics.xml" %
(self.get_repo_path()))
hostent = stats.xpath('//Node[@name="%s"]' % client)
if not hostent:
self.errExit("Could not find stats for client %s" % (client))
return hostent[0]
def print_table(self, rows, justify='left', hdr=True, vdelim=" ", padding=1):
"""Pretty print a table
rows - list of rows ([[row 1], [row 2], ..., [row n]])
hdr - if True the first row is treated as a table header
vdelim - vertical delimiter between columns
padding - # of spaces around the longest element in the column
justify - may be left,center,right
"""
hdelim = "="
justify = {'left':str.ljust,
'center':str.center,
'right':str.rjust}[justify.lower()]
'''
calculate column widths (longest item in each column
plus padding on both sides)
'''
cols = list(zip(*rows))
colWidths = [max([len(str(item))+2*padding for \
item in col]) for col in cols]
borderline = vdelim.join([w*hdelim for w in colWidths])
# print out the table
print(borderline)
for row in rows:
print(vdelim.join([justify(str(item), width) for \
(item, width) in zip(row, colWidths)]))
if hdr:
print(borderline)
hdr = False
class MetadataCore(Mode):
'''Base class for admin-modes that handle metadata'''
def __init__(self, configfile, usage, pwhitelist=None, pblacklist=None):
Mode.__init__(self, configfile)
options = {'plugins': Bcfg2.Options.SERVER_PLUGINS,
'configfile': Bcfg2.Options.CFILE}
setup = Bcfg2.Options.OptionParser(options)
setup.hm = usage
setup.parse(sys.argv[1:])
if pwhitelist is not None:
setup['plugins'] = [x for x in setup['plugins'] if x in pwhitelist]
elif pblacklist is not None:
setup['plugins'] = [x for x in setup['plugins'] if x not in pblacklist]
try:
self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(),
setup['plugins'],
'foo', 'UTF-8')
except Bcfg2.Server.Core.CoreInitError, msg:
self.errExit("Core load failed because %s" % msg)
self.bcore.fam.handle_events_in_interval(5)
self.metadata = self.bcore.metadata
class StructureMode(MetadataCore):
pass
|