From e9e94e78bb52ca2ec36e3f3402dbde3f8289cdf3 Mon Sep 17 00:00:00 2001 From: Andrew Brestick Date: Thu, 31 Jul 2008 20:50:44 +0000 Subject: added support for alternate metadata plugins in bcfg2-admin git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@4845 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Admin/Client.py | 76 +++++++++------------------------------- src/lib/Server/Admin/Viz.py | 21 +++++------ src/lib/Server/Admin/__init__.py | 31 ++++++++++++++-- 3 files changed, 54 insertions(+), 74 deletions(-) (limited to 'src/lib/Server/Admin') diff --git a/src/lib/Server/Admin/Client.py b/src/lib/Server/Admin/Client.py index c51ac1598..1f784a4f2 100644 --- a/src/lib/Server/Admin/Client.py +++ b/src/lib/Server/Admin/Client.py @@ -1,25 +1,14 @@ -import lxml.etree -import fcntl import Bcfg2.Server.Admin +from Bcfg2.Server.Plugins.Metadata import MetadataConsistencyError -class Client(Bcfg2.Server.Admin.Mode): +class Client(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = 'bcfg2-admin client add attr1=val1 attr2=val2\nbcfg2-admin client del ' __longhelp__ = __shorthelp__ + '\n\tCreate or delete client entries' def __init__(self, configfile): - Bcfg2.Server.Admin.Mode.__init__(self, configfile) - try: - self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(), [], - [], [], 'foo', False, 'UTF-8') - except Bcfg2.Server.Core.CoreInitError, msg: - self.errExit("Core load failed because %s" % msg) - [self.bcore.fam.Service() for _ in range(5)] - while self.bcore.fam.Service(): - pass - self.tree = lxml.etree.parse(self.get_repo_path() + "/Metadata/clients.xml") - self.root = self.tree.getroot() + Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile) def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) + Bcfg2.Server.Admin.MetadataCore.__call__(self, args) if len(args) == 0: self.errExit("Client mode requires at least one argument: or ") if "-h" in args: @@ -30,55 +19,22 @@ class Client(Bcfg2.Server.Admin.Mode): attr_d = {} for i in args[2:]: attr, val = i.split('=', 1) - if attr not in ['profile', 'uuid', 'password', 'address', - 'secure', 'location']: + if attr not in ['profile', 'user', 'state', 'image', + 'action']: print "Attribute %s unknown" % attr raise SystemExit(1) attr_d[attr] = val - self.add_client(args[1], attr_d) + try: + self.metadata.add_client(args[1], attr_d) + except MetadataConsistencyError: + print "Error in adding client" + raise SystemExit(1) elif args[0] in ['delete', 'remove', 'del', 'rm']: - self.del_client(args[1]) + try: + self.metadata.remove_client(args[1]) + except MetadataConsistencyError: + print "Error in deleting client" + raise SystemExit(1) else: print "No command specified" raise SystemExit(1) - client_tree = open(self.get_repo_path() + "/Metadata/clients.xml","w") - fd = client_tree.fileno() - while True: - try: - fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - except IOError: - continue - else: - break - self.tree.write(client_tree) - fcntl.lockf(fd, fcntl.LOCK_UN) - client_tree.close() - - def add_client(self, client, attrs): - '''add a new client''' - element = lxml.etree.Element("Client", name=client) - for key, val in attrs.iteritems(): - element.set(key, val) - node = self.search_client(client) - if node != None: - print "Client \"%s\" already exists" % (client) - raise SystemExit(1) - self.root.append(element) - - def del_client(self, client): - '''delete an existing client''' - node = self.search_client(client) - if node == None: - print "Client \"%s\" not found" % (client) - raise SystemExit(1) - self.root.remove(node) - - def search_client(self, client): - '''find a client''' - for node in self.root: - if node.attrib["name"] == client: - return node - for child in node: - if child.tag == "Alias" and child.attrib["name"] == client: - return node - return None diff --git a/src/lib/Server/Admin/Viz.py b/src/lib/Server/Admin/Viz.py index dfc8b3392..d2eeb3370 100644 --- a/src/lib/Server/Admin/Viz.py +++ b/src/lib/Server/Admin/Viz.py @@ -2,7 +2,7 @@ import getopt, popen2, lxml.etree import Bcfg2.Server.Admin -class Viz(Bcfg2.Server.Admin.Mode): +class Viz(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = '''bcfg2-admin viz [--includehosts] [--includebundles] [--includekey] [-o output.png] [--raw]''' __longhelp__ = __shorthelp__ + '\n\tProduce graphviz diagrams of metadata structures' @@ -11,10 +11,10 @@ class Viz(Bcfg2.Server.Admin.Mode): 'green1', 'blue1', 'yellow1', 'darkturquoise', 'gray66'] def __init__(self, cfile): - Bcfg2.Server.Admin.Mode.__init__(self, cfile) + Bcfg2.Server.Admin.MetadataCore.__init__(self, cfile) def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) + Bcfg2.Server.Admin.MetadataCore.__call__(self, args) # First get options to the 'viz' subcommand try: opts, args = getopt.getopt(args, 'rhbko:', @@ -48,9 +48,7 @@ class Viz(Bcfg2.Server.Admin.Mode): def Visualize(self, repopath, raw=False, hosts=False, bundles=False, key=False, output=False): '''Build visualization of groups file''' - groupdata = lxml.etree.parse(repopath + '/Metadata/groups.xml') - groupdata.xinclude() - groups = groupdata.getroot() + groups = self.metadata.get_groups() if raw: cmd = "dd bs=4M" if output: @@ -78,13 +76,12 @@ class Viz(Bcfg2.Server.Admin.Mode): dotpipe.tochild.write('\trankdir="LR";\n') if hosts: - clients = lxml.etree.parse(repopath + \ - '/Metadata/clients.xml').getroot() - for client in clients.findall('Client'): - if instances.has_key(client.get('profile')): - instances[client.get('profile')].append(client.get('name')) + clients = self.metadata.clients + for client, profile in clients.iteritems(): + if instances.has_key(profile): + instances[profile].append(client) else: - instances[client.get('profile')] = [client.get('name')] + instances[profile] = [client] for profile, clist in instances.iteritems(): clist.sort() dotpipe.tochild.write( diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py index cff9eec6a..a650f64e6 100644 --- a/src/lib/Server/Admin/__init__.py +++ b/src/lib/Server/Admin/__init__.py @@ -3,8 +3,8 @@ __revision__ = '$Revision$' __all__ = ['Mode', 'Client', 'Compare', 'Fingerprint', 'Init', 'Minestruct', 'Pull', 'Query', 'Tidy', 'Viz'] -import ConfigParser, lxml.etree, logging - +import ConfigParser, lxml.etree, logging, sys +import Bcfg2.Server.Core class ModeOperationError(Exception): pass @@ -46,3 +46,30 @@ class Mode(object): self.errExit("Could not find stats for client %s" % (client)) return hostent[0] +class MetadataCore(Mode): + '''Base class for admin-modes that handle metadata''' + def __init__(self, configfile): + Mode.__init__(self, configfile) + options = {'plugins': Bcfg2.Options.SERVER_PLUGINS, + 'structures': Bcfg2.Options.SERVER_STRUCTURES, + 'generators': Bcfg2.Options.SERVER_GENERATORS} + setup = Bcfg2.Options.OptionParser(options) + setup.parse(sys.argv[1:]) + plugins = [plugin for plugin in setup['plugins'] + if plugin in ('BB', 'Metadata')] + structures = [structure for structure in setup['structures'] + if structure in ('BB', 'Metadata')] + generators = [generator for generator in setup['generators'] + if generator in ('BB', 'Metadata')] + try: + self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(), plugins, + structures, generators, 'foo', False, 'UTF-8') + except Bcfg2.Server.Core.CoreInitError, msg: + self.errExit("Core load failed because %s" % msg) + [self.bcore.fam.Service() for _ in range(5)] + while self.bcore.fam.Service(): + pass + self.metadata = self.bcore.metadata + + def __call__(self, args): + Bcfg2.Server.Admin.Mode.__call__(self, args) -- cgit v1.2.3-1-g7c22