#!/usr/local/bin/python2.3 -i
'''This tool loads the Bcfg2 core into an interactive debugger'''
__revision__ = '$Revision: 3313 $'
import logging, lxml.etree, sys, time, Bcfg2.Logging, Bcfg2.Server.Core, os
import Bcfg2.Server.Plugins.Metadata, Bcfg2.Server.Plugin
def printTabular(rows):
'''print data in tabular format'''
cmax = tuple([max([len(str(row[index])) for row in rows]) + 1 for index in xrange(len(rows[0]))])
fstring = (" %%-%ss |" * len(cmax)) % cmax
fstring = ('|'.join([" %%-%ss "] * len(cmax))) % cmax
print fstring % rows[0]
print (sum(cmax) + (len(cmax) * 2) + (len(cmax) - 1)) * '='
for row in rows[1:]:
print fstring % row
def getInput():
'''read commands from stdin'''
try:
return raw_input('> ').strip().split(" ")
except KeyboardInterrupt:
return ['']
except EOFError:
return ['quit']
def doShowentries(cmd, core):
'''show abstract configuration entries for a given host'''
if len(cmd) not in [2, 3]:
print "Usage: showentries <hostname> <type>"
return
try:
meta = core.metadata.get_metadata(cmd[1])
except Bcfg2.Server.Plugins.Metadata.MetadataConsistencyError:
print "Unable to find metadata for host %s" % cmd[1]
return
structures = core.GetStructures(meta)
output = [('entrytype', 'name')]
if len(cmd) == 2:
for item in structures:
for child in item.getchildren():
output.append((child.tag, child.get('name')))
if len(cmd) == 3:
for item in structures:
for child in item.getchildren():
if child.tag == cmd[2]:
output.append((child.tag, child.get('name')))
printTabular(output)
def doBuild(cmd, core):
'''build client configuration'''
if len(cmd) == 3:
output = open(cmd[2], 'w')
output.write(lxml.etree.tostring(core.BuildConfiguration(cmd[1])))
output.close()
else:
print 'Usage: build <hostname> <output file>'
def doBuildAll(cmd, core):
if len(cmd) != 2:
print "Usage: buildall <directory>"
return
try:
os.mkdir(cmd[1])
except:
pass
for client in core.metadata.clients:
doBuild(['build', client, cmd[1] + '/' + client + '.xml'], core)
def doBuildFile(cmd, core):
'''build a config file for client'''
if len(cmd) == 3:
entry = lxml.etree.Element('ConfigFile', name=cmd[1])
metadata = core.metadata.get_metadata(cmd[2])
core.Bind(entry, metadata)
print lxml.etree.tostring(entry)
else:
print 'Usage: buildfile filename hostname'
def doBundles(_, core):
'''print out group/bundle info'''
data = [('Group', 'Bundles')]
groups = core.metadata.groups.keys()
groups.sort()
for group in groups:
data.append((group, ','.join(core.metadata.groups[group][0])))
printTabular(data)
def doClients(_, core):
'''print out client info'''
data = [('Client', 'Profile')]
clist = core.metadata.clients.keys()
clist.sort()
for client in clist:
data.append((client, core.metadata.clients[client]))
printTabular(data)
def doHelp(_, dummy):
'''print out usage info'''
print 'Commands:'
print 'build <hostname> <filename> - build config for hostname, writing to filename'
print 'buildall <directory> - build configs for all clients in directory'
print 'buildfile <filename> <hostname> - build config file for hostname (not written to disk)'
print 'bundles - print out group/bundle information'
print 'clients - print out client/profile information'
print 'debug - shell out to native python interpreter'
print 'generators - list current versions of generators'
print 'groups - list groups'
print 'help - print this text'
print 'mappings <type*> <name*>- print generator mappings for optional type and name'
print 'quit'
print 'showentries <hostname> <type> - show abstract configuration entries for a given host'
print 'showclient <client1> <client2> - show metadata for given hosts'
print 'update - process pending file events'
print 'version - print version of this tool'
def doGenerators(_, core):
'''print out generator info'''
for generator in core.generators:
print generator.__version__
def doGroups(_, core):
'''print out group info'''
data = [("Groups", "Profile", "Category", "Contains")]
grouplist = core.metadata.groups.keys()
grouplist.sort()
for group in grouplist:
if group in core.metadata.profiles:
prof = 'yes'
else:
prof = 'no'
if core.metadata.categories.has_key(group):
cat = core.metadata.categories[group]
else:
cat = ''
gdata = [grp for grp in core.metadata.groups[group][1]]
if group in gdata:
gdata.remove(group)
data.append((group, prof, cat, ','.join(gdata)))
printTabular(data)
def doShowclient(cmd, core):
''' print host metadata'''
data = [('Client', 'Profile', "Groups", "Bundles")]
for client in cmd[1:]:
if client not in core.metadata.clients:
print "Client %s not defined" % client
continue
profile = core.metadata.clients[client]
bundles, groups, categories = core.metadata.groups[profile]
groups.remove(profile)
numbundles = len(bundles)
numgroups = len(groups)
num = max((numbundles, numgroups))
for i in range(0,num):
if i == 0:
c = client
p = profile
else:
c = ""
p = ""
if i < numbundles:
b = bundles[i]
else:
b = ""
if i < numgroups:
g = groups[i]
else:
g = ""
data.append((c, p, g, b))
if len(data) > 1:
printTabular(data)
def doMappings(cmd, core):
'''print out mapping info'''
# dump all mappings unless type specified
data = [('Plugin', 'Type', 'Name')]
for generator in core.generators:
if len(cmd) == 1:
etypes = generator.Entries.keys()
elif len(cmd) > 1:
etypes = [cmd[1]]
if len(cmd) == 3:
interested = [(etype, [cmd[2]]) for etype in etypes]
else:
interested = [(etype, generator.Entries[etype].keys()) for etype in etypes
if generator.Entries.has_key(etype)]
if [etype for (etype, names) in interested
if generator.Entries.has_key(etype) and [name for name in names
if generator.Entries[etype].has_key(name)]]:
for (etype, names) in interested:
for name in names:
if generator.Entries.has_key(etype) and generator.Entries[etype].has_key(name):
data.append((generator.__name__, etype, name))
printTabular(data)
def doQuit(cmd, core):
'''exit program'''
raise SystemExit, 0
def doUpdate(_, core):
'''Process pending fs events'''
core.fam.Service()
def doVersion(_, dummy):
'''print out code version'''
print __revision__
if __name__ == '__main__':
Bcfg2.Logging.setup_logging('bcfg2-info', to_syslog=False)
logger = logging.getLogger('bcfg2-info')
dispatch = {'build': doBuild, 'buildall': doBuildAll,
'buildfile': doBuildFile, 'bundles': doBundles,
'clients': doClients, 'generators': doGenerators,
'groups': doGroups, 'help': doHelp,
'mappings': doMappings, 'quit': doQuit,
'showentries': doShowentries, 'update': doUpdate,
'version': doVersion, 'showclient': doShowclient}
if '-C' in sys.argv:
cfile = sys.argv[-1]
else:
cfile = '/etc/bcfg2.conf'
try:
bcore = Bcfg2.Server.Core.Core({}, cfile)
except Bcfg2.Server.Core.CoreInitError, msg:
print "Core load failed because %s" % msg
raise SystemExit, 1
for i in range(25):
print "Filesystem check %d of %d" % (i + 1, 25)
bcore.fam.Service()
time.sleep(0.5)
while True:
ucmd = getInput()
if ucmd[0] == 'debug':
break
else:
if dispatch.has_key(ucmd[0]):
try:
dispatch[ucmd[0]](ucmd, bcore)
except SystemExit, code:
raise SystemExit, code
except Bcfg2.Server.Plugin.PluginExecutionError:
continue
except:
logger.error("command failure", exc_info=1)
else:
print "Unknown command: %s" % ucmd[0]
syntax highlighted by Code2HTML, v. 0.9.1