summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2011-04-13 14:16:50 -0500
committerSol Jerome <sol.jerome@gmail.com>2011-04-13 14:16:50 -0500
commitdd8594eb5427610ade2f1f8abf465cde8c9568fd (patch)
tree7d8e488523feb78793dcde00989f8198c557f76f
parent1add5c6332fb8f59abf377d4167099ae9c5f1125 (diff)
parentd893117dde07ca3afcc4739245e3670178e1da08 (diff)
downloadbcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.tar.gz
bcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.tar.bz2
bcfg2-dd8594eb5427610ade2f1f8abf465cde8c9568fd.zip
Merge branch 'py3k'
-rw-r--r--src/lib/Server/Admin/Init.py4
-rwxr-xr-xsrc/sbin/bcfg236
-rwxr-xr-xsrc/sbin/bcfg2-admin8
-rwxr-xr-xsrc/sbin/bcfg2-build-reports142
-rwxr-xr-xsrc/sbin/bcfg2-info115
-rwxr-xr-xsrc/sbin/bcfg2-ping-sweep2
-rwxr-xr-xsrc/sbin/bcfg2-repo-validate10
-rwxr-xr-xsrc/sbin/bcfg2-reports38
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: