diff options
author | Sol Jerome <sol.jerome@gmail.com> | 2011-04-13 14:16:50 -0500 |
---|---|---|
committer | Sol Jerome <sol.jerome@gmail.com> | 2011-04-13 14:16:50 -0500 |
commit | dd8594eb5427610ade2f1f8abf465cde8c9568fd (patch) | |
tree | 7d8e488523feb78793dcde00989f8198c557f76f /src | |
parent | 1add5c6332fb8f59abf377d4167099ae9c5f1125 (diff) | |
parent | d893117dde07ca3afcc4739245e3670178e1da08 (diff) | |
download | bcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.tar.gz bcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.tar.bz2 bcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.zip |
Merge branch 'py3k'
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/Server/Admin/Init.py | 4 | ||||
-rwxr-xr-x | src/sbin/bcfg2 | 36 | ||||
-rwxr-xr-x | src/sbin/bcfg2-admin | 8 | ||||
-rwxr-xr-x | src/sbin/bcfg2-build-reports | 142 | ||||
-rwxr-xr-x | src/sbin/bcfg2-info | 115 | ||||
-rwxr-xr-x | src/sbin/bcfg2-ping-sweep | 2 | ||||
-rwxr-xr-x | src/sbin/bcfg2-repo-validate | 10 | ||||
-rwxr-xr-x | src/sbin/bcfg2-reports | 38 |
8 files changed, 203 insertions, 152 deletions
diff --git a/src/lib/Server/Admin/Init.py b/src/lib/Server/Admin/Init.py index 9771fd10b..1c12aee24 100644 --- a/src/lib/Server/Admin/Init.py +++ b/src/lib/Server/Admin/Init.py @@ -138,7 +138,7 @@ def create_key(hostname, keypath, certpath, country, state, location): keypath, certpath)) subprocess.call((ccstr), shell=True) - os.chmod(keypath, stat.S_IRUSR|stat.S_IWUSR) # 0600 + os.chmod(keypath, stat.S_IRUSR | stat.S_IWUSR) # 0600 def create_conf(confpath, confdata): @@ -156,7 +156,7 @@ def create_conf(confpath, confdata): return try: open(confpath, "w").write(confdata) - os.chmod(keypath, stat.S_IRUSR|stat.S_IWUSR) # 0600 + os.chmod(keypath, stat.S_IRUSR | stat.S_IWUSR) # 0600 except Exception, e: print("Error %s occured while trying to write configuration " "file to '%s'.\n" % diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 9bc50fe65..fe962211c 100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -3,24 +3,26 @@ """Bcfg2 Client""" __revision__ = '$Revision$' +import fcntl import logging import os import signal +import stat import sys import tempfile import time import xmlrpclib -import fcntl -import Bcfg2.Options + import Bcfg2.Client.XML import Bcfg2.Client.Frame import Bcfg2.Client.Tools - -import Bcfg2.Proxy +import Bcfg2.Options import Bcfg2.Logger +import Bcfg2.Proxy logger = logging.getLogger('bcfg2') + def cb_sigint_handler(signum, frame): """Exit upon CTRL-C.""" os._exit(1) @@ -105,9 +107,11 @@ class Client: self.logger.info(Bcfg2.Client.Tools.drivers) raise SystemExit(0) if self.setup['remove'] and 'services' in self.setup['remove']: - self.logger.error("Service removal is nonsensical, disable services to get former behavior") + self.logger.error("Service removal is nonsensical, " + "disable services to get former behavior") if self.setup['remove'] not in [False, 'all', 'services', 'packages']: - self.logger.error("Got unknown argument %s for -r" % (self.setup['remove'])) + self.logger.error("Got unknown argument %s for -r" % + (self.setup['remove'])) if (self.setup["file"] != False) and (self.setup["cache"] != False): print("cannot use -f and -c together") raise SystemExit(1) @@ -130,13 +134,17 @@ class Client: script.write(probe.text) script.close() os.close(scripthandle) - os.chmod(script.name, 0755) + os.chmod(script.name, stat.S_IRUSR | stat.S_IWUSR | + stat.S_IXUSR | stat.S_IRGRP | + stat.S_IXGRP | stat.S_IROTH | + stat.S_IXOTH) # 0755 ret.text = os.popen(script.name).read().strip() self.logger.info("Probe %s has result:\n%s" % (name, ret.text)) finally: os.unlink(script.name) except: - self.logger.error("Failed to execute probe: %s" % (name), exc_info=1) + self.logger.error("Failed to execute probe: %s" % (name), + exc_info=1) raise SystemExit(1) return ret @@ -169,10 +177,10 @@ class Client: proxy = Bcfg2.Proxy.ComponentProxy(self.setup['server'], self.setup['user'], self.setup['password'], - key = self.setup['key'], - cert = self.setup['certificate'], - ca = self.setup['ca'], - allowedServerCNs = self.setup['serverCN']) + key=self.setup['key'], + cert=self.setup['certificate'], + ca=self.setup['ca'], + allowedServerCNs=self.setup['serverCN']) if self.setup['profile']: try: @@ -210,7 +218,9 @@ class Client: if len(probes.findall(".//probe")) > 0: try: # upload probe responses - proxy.RecvProbeData(Bcfg2.Client.XML.tostring(probedata, encoding='UTF-8', xml_declaration=True)) + proxy.RecvProbeData(Bcfg2.Client.XML.tostring(probedata, + encoding='UTF-8', + xml_declaration=True)) except: self.logger.error("Failed to upload probe data", exc_info=1) raise SystemExit(1) diff --git a/src/sbin/bcfg2-admin b/src/sbin/bcfg2-admin index 2c9a43859..f8b82d201 100755 --- a/src/sbin/bcfg2-admin +++ b/src/sbin/bcfg2-admin @@ -12,6 +12,7 @@ log = logging.getLogger('bcfg2-admin') import Bcfg2.Server.Admin + def mode_import(modename): """Load Bcfg2.Server.Admin.<mode>.""" modname = modename.capitalize() @@ -19,10 +20,12 @@ def mode_import(modename): (modname)).Server.Admin, modname) return getattr(mod, modname) + def get_modes(): """Get all available modes, except for the base mode.""" return [x.lower() for x in Bcfg2.Server.Admin.__all__ if x != 'mode'] + def create_description(): """Create the description string from the list of modes.""" modes = get_modes() @@ -36,6 +39,7 @@ def create_description(): continue return description.getvalue() + def main(): Bcfg2.Logger.setup_logging('bcfg2-admin', to_console=True, level=40) usage = "Usage: %prog [options] MODE [args]" @@ -56,7 +60,7 @@ def main(): else: # Print short help for all modes parser.print_help() - print create_description() + print(create_description()) raise SystemExit(0) if args[0] in get_modes(): @@ -73,7 +77,7 @@ def main(): else: log.error("Unknown mode %s" % args[0]) parser.print_help() - print create_description() + print(create_description()) raise SystemExit(1) if __name__ == '__main__': diff --git a/src/sbin/bcfg2-build-reports b/src/sbin/bcfg2-build-reports index 231f52105..6b3e24e84 100755 --- a/src/sbin/bcfg2-build-reports +++ b/src/sbin/bcfg2-build-reports @@ -14,7 +14,9 @@ import socket import sys from time import asctime, strptime from ConfigParser import ConfigParser, NoSectionError, NoOptionError -from lxml.etree import XML, XSLT, parse, Element, ElementTree, SubElement, tostring, XMLSyntaxError +from lxml.etree import XML, XSLT, parse, Element, ElementTree, \ + SubElement, tostring, XMLSyntaxError + def generatereport(rspec, nrpt): """ @@ -24,12 +26,12 @@ def generatereport(rspec, nrpt): reportspec = copy.deepcopy(rspec) nodereprt = copy.deepcopy(nrpt) - reportgood = reportspec.get("good", default = 'Y') - reportmodified = reportspec.get("modified", default = 'Y') + reportgood = reportspec.get("good", default='Y') + reportmodified = reportspec.get("modified", default='Y') current_date = asctime()[:10] """Build regex of all the nodes we are reporting about.""" - pattern = re.compile( '|'.join([item.get("name") for item in reportspec.findall('Machine')])) + pattern = re.compile('|'.join([item.get("name") for item in reportspec.findall('Machine')])) for node in nodereprt.findall('Node'): if not (node.findall("Statistics") and pattern.match(node.get('name'))): @@ -40,25 +42,27 @@ def generatereport(rspec, nrpt): # Reduce to most recent Statistics entry. statisticslist = node.findall('Statistics') # This line actually sorts from most recent to oldest. - statisticslist.sort(lambda y, x: cmp(strptime(x.get("time")), strptime(y.get("time")))) + statisticslist.sort(lambda y, x: cmp(strptime(x.get("time")), + strptime(y.get("time")))) stats = statisticslist[0] - + [node.remove(item) for item in node.findall('Statistics')] - + # Add a good tag if node is good and we wnat to report such. if reportgood == 'Y' and stats.get('state') == 'clean': - SubElement(stats,"Good") + SubElement(stats, "Good") [stats.remove(item) for item in stats.findall("Bad") + stats.findall("Modified") if \ item.getchildren() == []] [stats.remove(item) for item in stats.findall("Modified") if reportmodified == 'N'] - + # Test for staleness -if stale add Stale tag. if stats.get("time").find(current_date) == -1: - SubElement(stats,"Stale") + SubElement(stats, "Stale") node.append(stats) return nodereprt + def mail(mailbody, confi): """mail mails a previously generated report.""" @@ -72,7 +76,8 @@ def mail(mailbody, confi): pipe.write(mailbody) exitcode = pipe.close() if exitcode: - print "Exit code: %s" % exitcode + print("Exit code: %s" % exitcode) + def rss(reportxml, delivery, report): """rss appends a new report to the specified rss file @@ -98,7 +103,7 @@ def rss(reportxml, delivery, report): chantitle = SubElement(channel, "title") chantitle.text = report.attrib['name'] chanlink = SubElement(channel, "link") - + # This can later link to WWW report if one gets published # simultaneously? chanlink.text = "http://www.mcs.anl.gov/cobalt/bcfg2" @@ -115,17 +120,19 @@ def rss(reportxml, delivery, report): fil.write(tree) fil.close() + def www(reportxml, delivery): """www outputs report to.""" # This can later link to WWW report if one gets published - # simultaneously? + # simultaneously? for destination in delivery.findall('Destination'): fil = open(destination.attrib['address'], 'w') fil.write(reportxml) fil.close() + def fileout(reportxml, delivery): """Outputs to plain text file.""" for destination in delivery.findall('Destination'): @@ -134,25 +141,29 @@ def fileout(reportxml, delivery): fil.write(reportxml) fil.close() + def pretty_print(element, level=0): """Produce a pretty-printed text representation of element.""" if element.text: - fmt = "%s<%%s %%s>%%s</%%s>" % (level*" ") - data = (element.tag, (" ".join(["%s='%s'" % keyval for keyval in element.attrib.iteritems()])), + fmt = "%s<%%s %%s>%%s</%%s>" % (level * " ") + data = (element.tag, (" ".join(["%s='%s'" % keyval for keyval in + list(element.attrib.items())])), element.text, element.tag) if element._children: - fmt = "%s<%%s %%s>\n" % (level*" ",) + (len(element._children) * "%s") + "%s</%%s>\n" % (level*" ") - data = (element.tag, ) + (" ".join(["%s='%s'" % keyval for keyval in element.attrib.iteritems()]),) - data += tuple([pretty_print(entry, level+2) for entry in element._children]) + (element.tag, ) + fmt = "%s<%%s %%s>\n" % (level * " ",) + (len(element._children) * "%s") + "%s</%%s>\n" % (level * " ") + data = (element.tag, ) + (" ".join(["%s='%s'" % keyval for keyval in + list(element.attrib.items())]),) + data += tuple([pretty_print(entry, level + 2) for entry in element._children]) + (element.tag, ) else: fmt = "%s<%%s %%s/>\n" % (level * " ") - data = (element.tag, " ".join(["%s='%s'" % keyval for keyval in element.attrib.iteritems()])) + data = (element.tag, " ".join(["%s='%s'" % keyval for keyval in + list(element.attrib.items())])) return fmt % data if __name__ == '__main__': - ping=True - all=False + ping = True + all = False if '-C' in sys.argv: cfpath = sys.argv[sys.argv.index('-C') + 1] else: @@ -171,17 +182,24 @@ if __name__ == '__main__': #websrcspath = "/usr/share/bcfg2/web-rprt-srcs/" try: - opts, args = getopt.getopt(sys.argv[1:], "C:hAc:Ns:", ["help", "all", "config=","no-ping", "stats="]) + opts, args = getopt.getopt(sys.argv[1:], + "C:hAc:Ns:", + ["help", "all", "config=", "no-ping", + "stats="]) except getopt.GetoptError, mesg: # Print help information and exit: - print "%s\nUsage:\nbcfg2-build-reports [-h][-A (include ALL clients)] [-c <configuration-file>] [-s <statistics-file>][-N (do not ping clients)]" % (mesg) - raise SystemExit, 2 + print("%s\nUsage:\n" + "bcfg2-build-reports [-h] [-A (include ALL clients)] " + "[-c <configuration-file>] [-s <statistics-file>] " + "[-N (do not ping clients)]" % (mesg)) + raise SystemExit(2) for o, a in opts: if o in ("-h", "--help"): - print "Usage:\nbcfg2-build-reports [-h] [-c <configuration-file>] [-s <statistics-file>]" + print("Usage:\nbcfg2-build-reports [-h] [-c <configuration-file>] " + "[-s <statistics-file>]") raise SystemExit if o in ("-A", "--all"): - all=True + all = True if o in ("-c", "--config"): configpath = a if o in ("-N", "--no-ping"): @@ -189,94 +207,96 @@ if __name__ == '__main__': if o in ("-s", "--stats"): statpath = a - # See if hostinfo.xml exists, and is less than 23.5 hours old #try: #hostinstat = os.stat(hostinfopath) #if (time() - hostinstat[9])/(60*60) > 23.5: if ping: - os.system('bcfg2-ping-sweep -C %s' % cfpath) # bcfg2-ping-sweep needs to be in path + os.system('bcfg2-ping-sweep -C %s' % cfpath) # bcfg2-ping-sweep needs to be in path #except OSError: # os.system('GenerateHostInfo')#Generate HostInfo needs to be in path - """Reads data & config files.""" try: statsdata = XML(open(statpath).read()) except (IOError, XMLSyntaxError): - print("bcfg2-build-reports: Failed to parse %s"%(statpath)) - raise SystemExit, 1 + print("bcfg2-build-reports: Failed to parse %s" % (statpath)) + raise SystemExit(1) try: configdata = XML(open(configpath).read()) except (IOError, XMLSyntaxError): - print("bcfg2-build-reports: Failed to parse %s"%(configpath)) - raise SystemExit, 1 + print("bcfg2-build-reports: Failed to parse %s" % (configpath)) + raise SystemExit(1) try: clientsdata = XML(open(clientsdatapath).read()) except (IOError, XMLSyntaxError): - print("bcfg2-build-reports: Failed to parse %s"%(clientsdatapath)) - raise SystemExit, 1 + print("bcfg2-build-reports: Failed to parse %s" % (clientsdatapath)) + raise SystemExit(1) # Merge data from three sources. - nodereport = Element("Report", attrib={"time" : asctime()}) + nodereport = Element("Report", attrib={"time": asctime()}) # Should all of the other info in Metadata be appended? # What about all of the package stuff for other types of reports? for client in clientsdata.findall("Client"): - nodel = Element("Node", attrib={"name" : client.get("name")}) + nodel = Element("Node", attrib={"name": client.get("name")}) nodel.append(client) for nod in statsdata.findall("Node"): if client.get('name').find(nod.get('name')) == 0: for statel in nod.findall("Statistics"): nodel.append(statel) nodereport.append(nodel) - + if all: for nod in statsdata.findall("Node"): for client in clientsdata.findall("Client"): if client.get('name').find(nod.get('name')) == 0: break else: - nodel = Element("Node", attrib={"name" : nod.get("name")}) - client = Element("Client", attrib={"name" : nod.get("name"), "profile" : "default"}) + nodel = Element("Node", attrib={"name": nod.get("name")}) + client = Element("Client", attrib={"name": nod.get("name"), + "profile": "default"}) nodel.append(client) for statel in nod.findall("Statistics"): nodel.append(statel) nodereport.append(nodel) - - + for reprt in configdata.findall('Report'): nodereport.set("name", reprt.get("name", default="BCFG Report")) if reprt.get('refresh-time') != None: - nodereport.set("refresh-time", reprt.get("refresh-time", default="600")) + nodereport.set("refresh-time", reprt.get("refresh-time", + default="600")) procnodereport = generatereport(reprt, nodereport) for deliv in reprt.findall('Delivery'): # Is a deepcopy of procnodereport necessary? - + delivtype = deliv.get('type', default='nodes-digest') deliverymechanism = deliv.get('mechanism', default='www') # Apply XSLT, different ones based on report type, and options - if deliverymechanism == 'null-operator': # Special Cases - fileout(tostring(ElementTree(procnodereport).getroot(), encoding='UTF-8', xml_declaration=True), deliv) + if deliverymechanism == 'null-operator': # Special Cases + fileout(tostring(ElementTree(procnodereport).getroot(), + encoding='UTF-8', + xml_declaration=True), + deliv) break transform = delivtype + '-' + deliverymechanism + '.xsl' - try: # Make sure valid stylesheet is selected. + try: # Make sure valid stylesheet is selected. os.stat(transformpath + transform) except: print("bcfg2-build-reports: Invalid report type or delivery mechanism.\n Can't find: "\ + transformpath + transform) - raise SystemExit, 1 + raise SystemExit(1) - try: # Try to parse stylesheet. + try: # Try to parse stylesheet. stylesheet = XSLT(parse(transformpath + transform)) except: print("bcfg2-build-reports: invalid XSLT transform file.") - raise SystemExit, 1 - + raise SystemExit(1) + if deliverymechanism == 'mail': if delivtype == 'nodes-individual': reportdata = copy.deepcopy(procnodereport) @@ -285,35 +305,37 @@ if __name__ == '__main__': reportdata.append(noden) result = stylesheet.apply(ElementTree(reportdata)) outputstring = stylesheet.tostring(result) - + if not outputstring == None: toastring = '' for desti in deliv.findall("Destination"): toastring = "%s%s " % \ (toastring, desti.get('address')) # Prepend To: and From: - outputstring = "To: %s\nFrom: root@%s\n%s"% \ + outputstring = "To: %s\nFrom: root@%s\n%s" % \ (toastring, socket.getfqdn(), outputstring) - mail(outputstring, c) #call function to send - + mail(outputstring, c) # call function to send + else: reportdata = copy.deepcopy(procnodereport) result = stylesheet.apply(ElementTree(reportdata)) outputstring = stylesheet.tostring(result) - + if not outputstring == None: toastring = '' for desti in deliv.findall("Destination"): toastring = "%s%s " % \ (toastring, desti.get('address')) # Prepend To: and From: - outputstring = "To: %s\nFrom: root@%s\n%s"% \ + outputstring = "To: %s\nFrom: root@%s\n%s" % \ (toastring, socket.getfqdn(), outputstring) - mail(outputstring, c) #call function to send + mail(outputstring, c) # call function to send else: - outputstring = tostring(stylesheet.apply(ElementTree(procnodereport)).getroot(), encoding='UTF-8', xml_declaration=True) + outputstring = tostring(stylesheet.apply(ElementTree(procnodereport)).getroot(), + encoding='UTF-8', + xml_declaration=True) if deliverymechanism == 'rss': rss(outputstring, deliv, reprt) - else: # Must be deliverymechanism == 'www': + else: # Must be deliverymechanism == 'www': www(outputstring, deliv) diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index a6d236bc8..f78b3a7f4 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -5,7 +5,6 @@ __revision__ = '$Revision$' from code import InteractiveConsole import cmd -import errno import getopt import logging import lxml.etree @@ -28,6 +27,42 @@ import Bcfg2.Server.Plugin logger = logging.getLogger('bcfg2-info') +USAGE = """Commands + +build <hostname> <filename> - Build config for hostname, writing to filename +builddir <hostname> <dirname> - Build config for hostname, writing separate files to dirname +buildall <directory> - Build configs for all clients in directory +buildfile <filename> <hostname> - Build config file for hostname (not written to disk) +bundles - Print out group/bundle information +clients - Print out client/profile information +config - Print out the configuration of the Bcfg2 server +debug - Shell out to native python interpreter +event_debug - Display filesystem events as they are processed +generators - List current versions of generators +groups - List groups +help - Print this list of available commands +mappings <type*> <name*> - Print generator mappings for optional type and name +profile <command> <args> - Profile a single bcfg2-info command +quit - Exit the bcfg2-info command line +showentries <hostname> <type> - Show abstract configuration entries for a given host +showclient <client1> <client2> - Show metadata for given hosts +update - Process pending file events +version - Print version of this tool""" + +BUILDDIR_USAGE = """Usage: builddir [-f] <hostname> <output dir> + +Generates a config for client <hostname> and writes the +individual configuration files out separately in a tree +under <output dir>. The <output dir> directory must be +rooted under /tmp unless the -f argument is provided, in +which case it can be located anywhere. + +NOTE: Currently only handles file entries and writes +all content with the default owner and permissions. These +could be much more permissive than would be created by the +Bcfg2 client itself.""" + + class mockLog(object): def error(self, *args, **kwargs): pass @@ -38,18 +73,22 @@ class mockLog(object): def debug(self, *args, **kwargs): pass + class dummyError(Exception): """This is just a dummy.""" pass + class FileNotBuilt(Exception): """Thrown when File entry contains no content.""" def __init__(self, value): Exception.__init__(self) self.value = value + def __str__(self): return repr(self.value) + def printTabular(rows): """Print data in tabular format.""" cmax = tuple([max([len(str(row[index])) for row in rows]) + 1 \ @@ -61,11 +100,13 @@ def printTabular(rows): for row in rows[1:]: print(fstring % row) + def displayTrace(trace, num=80, sort=('time', 'calls')): stats = pstats.Stats(trace) stats.sort_stats('cumulative', 'calls', 'time') stats.print_stats(200) + class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): """Main class for bcfg2-info.""" def __init__(self, repo, plgs, passwd, encoding, event_debug): @@ -106,7 +147,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): try: opts, _ = getopt.getopt(args.split(), 'nf:') except: - print "Usage: debug [-n] [-f <command list>]" + print("Usage: debug [-n] [-f <command list>]") return self.cont = False scriptmode = False @@ -136,7 +177,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): Exit program. Usage: [quit|exit] """ - for plugin in self.plugins.values(): + for plugin in list(self.plugins.values()): plugin.shutdown() os._exit(0) @@ -145,27 +186,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): def do_help(self, _): """Print out usage info.""" - print 'Commands:' - print 'build <hostname> <filename> - Build config for hostname, writing to filename' - print 'builddir <hostname> <dirname> - Build config for hostname, writing separate files to dirname' - 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 'config - Print out the configuration of the Bcfg2 server' - print 'debug - Shell out to native python interpreter' - print 'event_debug - Display filesystem events as they are processed' - print 'generators - List current versions of generators' - print 'groups - List groups' - print 'help - Print this list of available commands' - print 'mappings <type*> <name*> - Print generator mappings for optional type and name' - print 'profile <command> <args> - Profile a single bcfg2-info command' - print 'quit - Exit the bcfg2-info command line' - 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' - + print(USAGE) def do_update(self, _): """Process pending filesystem events.""" @@ -198,18 +219,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): def help_builddir(self): """Display help for builddir command.""" - print('Usage: builddir [-f] <hostname> <output dir>') - print('') - print('Generates a config for client <hostname> and writes the') - print('individual configuration files out separately in a tree') - print('under <output dir>. The <output dir> directory must be') - print('rooted under /tmp unless the -f argument is provided, in') - print('which case it can be located anywhere.') - print('') - print('NOTE: Currently only handles file entries and writes') - print('all content with the default owner and permissions. These') - print('could be much more permissive than would be created by the') - print('Bcfg2 client itself.') + print(BUILDDIR_USAGE) def do_builddir(self, args): """Build client configuration as separate files within a dir.""" @@ -238,9 +248,9 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): p = Bcfg2.Client.Tools.POSIX.POSIX(log, setup, client_config) states = dict() p.Inventory(states) - p.Install(states.keys(), states) + p.Install(list(states.keys()), states) else: - print('Error: Incorrect number of parameters.') + print("Error: Incorrect number of parameters.") self.help_builddir() def do_buildall(self, args): @@ -262,7 +272,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): try: metadata = self.build_metadata(client) self.Bind(entry, metadata) - print(lxml.etree.tostring(entry, encoding="UTF-8", + print(lxml.etree.tostring(entry, encoding="UTF-8", xml_declaration=True)) except: print("Failed to build entry %s for host %s" % (fname, client)) @@ -307,7 +317,6 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): ] printTabular(output) - def do_generators(self, _): """Print out generator info.""" for generator in self.generators: @@ -371,22 +380,22 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): except: print("Client %s not defined" % client) continue - print "Hostname:\t", client_meta.hostname - print "Profile:\t", client_meta.profile - print "Groups:\t\t", list(client_meta.groups)[0] + print("Hostname:\t", client_meta.hostname) + print("Profile:\t", client_meta.profile) + print("Groups:\t\t", list(client_meta.groups)[0]) for grp in list(client_meta.groups)[1:]: - print '\t\t%s' % grp + print("\t\t%s" % grp) if client_meta.bundles: - print "Bundles:\t", list(client_meta.bundles)[0] + print("Bundles:\t", list(client_meta.bundles)[0]) for bnd in list(client_meta.bundles)[1:]: - print '\t\t%s' % bnd + print("\t\t%s" % bnd) if client_meta.connectors: - print "Connector data" - print "=" * 80 + print("Connector data") + print("=" * 80) for conn in client_meta.connectors: if getattr(client_meta, conn): - print "%s:\t" % (conn), getattr(client_meta, conn) - print "=" * 80 + print("%s:\t" % (conn), getattr(client_meta, conn)) + print("=" * 80) def do_mappings(self, args): """Print out mapping info.""" @@ -402,11 +411,11 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): interested = [(etype, [args.split()[1]]) for etype in etypes] else: - interested = [(etype, generator.Entries[etype]) - for etype in etypes + interested = [(etype, generator.Entries[etype]) + for etype in etypes if etype in generator.Entries] for etype, names in interested: - for name in [name for name in names if name in + for name in [name for name in names if name in generator.Entries.get(etype, {})]: data.append((generator.name, etype, name)) printTabular(data) diff --git a/src/sbin/bcfg2-ping-sweep b/src/sbin/bcfg2-ping-sweep index 718ad69d0..70f718690 100755 --- a/src/sbin/bcfg2-ping-sweep +++ b/src/sbin/bcfg2-ping-sweep @@ -33,7 +33,7 @@ if __name__ == '__main__': osname = uname()[0] while hostlist or pids: - if hostlist and len(pids.keys()) < 15: + if hostlist and len(list(pids.keys())) < 15: host = hostlist.pop() pid = fork() if pid == 0: diff --git a/src/sbin/bcfg2-repo-validate b/src/sbin/bcfg2-repo-validate index d4eb0ffd2..595613d8a 100755 --- a/src/sbin/bcfg2-repo-validate +++ b/src/sbin/bcfg2-repo-validate @@ -6,18 +6,18 @@ repos against their respective XML schemas. """ __revision__ = '$Revision$' +import fnmatch import glob import lxml.etree import os import sys -import fnmatch import Bcfg2.Options if __name__ == '__main__': opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY, 'verbose': Bcfg2.Options.VERBOSE, 'configfile': Bcfg2.Options.CFILE, - 'schema' : Bcfg2.Options.SCHEMA_PATH, + 'schema': Bcfg2.Options.SCHEMA_PATH, 'stdin': Bcfg2.Options.FILES_ON_STDIN} setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) @@ -28,7 +28,7 @@ if __name__ == '__main__': repo = setup['repo'] if setup['stdin']: - file_list = map(lambda s: s.strip(), sys.stdin.readlines()) + file_list = [s.strip() for s in sys.stdin.readlines()] info_list = [f for f in file_list if os.path.basename(f) == 'info.xml'] metadata_list = fnmatch.filter(file_list, "*/Metadata/*.xml") clients_list = fnmatch.filter(file_list, "*/Metadata/clients.xml") @@ -46,7 +46,7 @@ if __name__ == '__main__': gp_list = fnmatch.filter(file_list, "*/GroupPatterns/config.xml") else: # not reading files from stdin - + # Get a list of all info.xml files in the bcfg2 repository info_list = [] for infodir in ['Cfg', 'TGenshi', 'TCheetah']: @@ -240,7 +240,7 @@ if __name__ == '__main__': genshibundle not in allbundles): print("*** Warning: Bundle %s referenced, but does not " "exist." % bundle) - + # verify bundle name attribute matches filename for bundle in (bundle_list + genshibundle_list): fname = bundle.split('Bundler/')[1].split('.')[0] diff --git a/src/sbin/bcfg2-reports b/src/sbin/bcfg2-reports index 559e9fb43..c6cc766c6 100755 --- a/src/sbin/bcfg2-reports +++ b/src/sbin/bcfg2-reports @@ -26,15 +26,18 @@ from getopt import getopt import datetime import fileinput + def timecompare(client1, client2): """Compares two clients by their timestamps.""" return cmp(client1.current_interaction.timestamp, \ client2.current_interaction.timestamp) + def namecompare(client1, client2): """Compares two clients by their names.""" return cmp(client1.name, client2.name) + def statecompare(client1, client2): """Compares two clients by their states.""" clean1 = client1.current_interaction.isclean() @@ -47,6 +50,7 @@ def statecompare(client1, client2): else: return 0 + def crit_compare(criterion, client1, client2): """Compares two clients by the criteria provided in criterion.""" for crit in criterion: @@ -57,12 +61,13 @@ def crit_compare(criterion, client1, client2): comp = statecompare(client1, client2) elif crit == 'time': comp = timecompare(client1, client2) - + if comp != 0: return comp - + return 0 + def print_fields(fields, cli, max_name, entrydict): """ Prints the fields specified in fields of cli, max_name @@ -93,14 +98,15 @@ def print_fields(fields, cli, max_name, entrydict): if len(entrydict) > 0: display += " " display += str(entrydict[cli]) - print display + print(display) + def print_entry(item, max_name): fmt = ("%%-%ds " % (max_name)) fdata = item.entry.kind + ":" + item.entry.name display = fmt % (fdata) - print display - + print(display) + fields = "" sort = "" badentry = "" @@ -137,14 +143,14 @@ if expire != "": if expire == c_inst.name: if c_inst.expiration == None: c_inst.expiration = datetime.datetime.now() - print "Host expired." + print("Host expired.") else: c_inst.expiration = None - print "Host un-expired." + print("Host un-expired.") c_inst.save() elif '-h' in args: - print """Usage: bcfg2-reports [option] ... + print("""Usage: bcfg2-reports [option] ... Options and arguments (and corresponding environment variables): -a : shows all hosts, including expired hosts @@ -170,13 +176,13 @@ Options and arguments (and corresponding environment variables): (name,time,state) --sort=ARG1,ARG2,... : sorts output on ARG1,ARG2,... (name,time,state) --stale : shows hosts which haven't run in the last 24 hours -""" +""") elif singlehost != "": for c_inst in c_list: if singlehost == c_inst.name: baditems = c_inst.current_interaction.bad() if len(baditems) > 0 and ('-b' in args or '-s' in args): - print "Bad Entries:" + print("Bad Entries:") max_name = -1 for item in baditems: if len(item.entry.name) > max_name: @@ -185,14 +191,14 @@ elif singlehost != "": print_entry(item, max_name) extraitems = c_inst.current_interaction.extra() if len(extraitems) > 0 and ('-e' in args or '-s' in args): - print "Extra Entries:" + print("Extra Entries:") max_name = -1 for item in extraitems: if len(item.entry.name) > max_name: max_name = len(item.entry.name) for item in extraitems: print_entry(item, max_name) - + else: if fields == "": @@ -208,19 +214,19 @@ else: if extraentry != "": extraentry = extraentry.split(',') - + # stale hosts if '--stale' in args: for c_inst in c_list: if c_inst.current_interaction.isstale(): result.append(c_inst) # clean hosts - elif '-c' in args: + elif '-c' in args: for c_inst in c_list: if c_inst.current_interaction.isclean(): result.append(c_inst) # dirty hosts - elif '-d' in args: + elif '-d' in args: for c_inst in c_list: if not c_inst.current_interaction.isclean(): result.append(c_inst) @@ -281,7 +287,7 @@ else: if sort != "": result.sort(lambda x, y: crit_compare(sort, x, y)) - + if fields != "": for c_inst in result: if '-a' in args or c_inst.expiration == None: |