From 742fc83dcdb82639b97723ce4cbfade75fb1aa71 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 6 Apr 2011 19:34:30 -0500 Subject: bcfg2-admin: PY3K + PEP8 fixes Signed-off-by: Sol Jerome --- src/lib/Server/Admin/Backup.py | 3 +- src/lib/Server/Admin/Bundle.py | 50 +++++++++-------- src/lib/Server/Admin/Client.py | 15 ++--- src/lib/Server/Admin/Compare.py | 59 +++++++++++--------- src/lib/Server/Admin/Group.py | 15 ++--- src/lib/Server/Admin/Init.py | 116 +++++++++++++++++++++++++++++++-------- src/lib/Server/Admin/Perf.py | 11 ++-- src/lib/Server/Admin/Pull.py | 46 ++++++++++------ src/lib/Server/Admin/Query.py | 15 ++--- src/lib/Server/Admin/Reports.py | 74 +++++++++++++------------ src/lib/Server/Admin/Tidy.py | 14 +++-- src/lib/Server/Admin/Viz.py | 13 +++-- src/lib/Server/Admin/Xcmd.py | 20 ++++--- src/lib/Server/Admin/__init__.py | 25 ++++++--- 14 files changed, 296 insertions(+), 180 deletions(-) (limited to 'src') diff --git a/src/lib/Server/Admin/Backup.py b/src/lib/Server/Admin/Backup.py index fefc9fc9e..9bd644ff9 100644 --- a/src/lib/Server/Admin/Backup.py +++ b/src/lib/Server/Admin/Backup.py @@ -5,6 +5,7 @@ import tarfile import Bcfg2.Server.Admin import Bcfg2.Options + class Backup(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Make a backup of the Bcfg2 repository" __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin backup\n") @@ -29,4 +30,4 @@ class Backup(Bcfg2.Server.Admin.MetadataCore): out = tarfile.open(self.datastore + '/' + filename, mode=mode) out.add(self.datastore, os.path.basename(self.datastore)) out.close() - print "Archive %s was stored under %s" % (filename, self.datastore) + print("Archive %s was stored under %s" % (filename, self.datastore)) diff --git a/src/lib/Server/Admin/Bundle.py b/src/lib/Server/Admin/Bundle.py index 96a7ba59d..9b2a71783 100644 --- a/src/lib/Server/Admin/Bundle.py +++ b/src/lib/Server/Admin/Bundle.py @@ -6,11 +6,11 @@ import Bcfg2.Server.Admin import Bcfg2.Options from Bcfg2.Server.Plugins.Metadata import MetadataConsistencyError + class Bundle(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Create or delete bundle entries" - __longhelp__ = (__shorthelp__ + #"\n\nbcfg2-admin bundle add " - #"\n\nbcfg2-admin bundle del " - "\n\nbcfg2-admin bundle list-xml" + # TODO: add/del functions + __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin bundle list-xml" "\nbcfg2-admin bundle list-genshi" "\nbcfg2-admin bundle show\n") __usage__ = ("bcfg2-admin bundle [options] [add|del] [group]") @@ -21,7 +21,7 @@ class Bundle(Bcfg2.Server.Admin.MetadataCore): def __call__(self, args): Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - reg='((?:[a-z][a-z\\.\\d\\-]+)\\.(?:[a-z][a-z\\-]+))(?![\\w\\.])' + reg = '((?:[a-z][a-z\\.\\d\\-]+)\\.(?:[a-z][a-z\\-]+))(?![\\w\\.])' # Get all bundles out of the Bundle/ directory opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} @@ -38,31 +38,31 @@ class Bundle(Bcfg2.Server.Admin.MetadataCore): # try: # self.metadata.add_bundle(args[1]) # except MetadataConsistencyError: -# print "Error in adding bundle." +# print("Error in adding bundle.") # raise SystemExit(1) # elif args[0] in ['delete', 'remove', 'del', 'rm']: # try: # self.metadata.remove_bundle(args[1]) # except MetadataConsistencyError: -# print "Error in deleting bundle." +# print("Error in deleting bundle.") # raise SystemExit(1) # Lists all available xml bundles elif args[0] in ['list-xml', 'ls-xml']: bundle_name = [] for bundle_path in xml_list: - rg = re.compile(reg,re.IGNORECASE|re.DOTALL) + rg = re.compile(reg, re.IGNORECASE | re.DOTALL) bundle_name.append(rg.search(bundle_path).group(1)) for bundle in bundle_name: - print bundle.split('.')[0] + print(bundle.split('.')[0]) # Lists all available genshi bundles elif args[0] in ['list-genshi', 'ls-gen']: bundle_name = [] for bundle_path in genshi_list: - rg = re.compile(reg,re.IGNORECASE|re.DOTALL) + rg = re.compile(reg, re.IGNORECASE | re.DOTALL) bundle_name.append(rg.search(bundle_path).group(1)) for bundle in bundle_name: - print bundle.split('.')[0] - # Shows a list of all available bundles and prints bundle + print(bundle.split('.')[0]) + # Shows a list of all available bundles and prints bundle # details after the user choose one bundle. # FIXME: Add support for detailed output of genshi bundles # FIXME: This functionality is almost identical with @@ -71,32 +71,34 @@ class Bundle(Bcfg2.Server.Admin.MetadataCore): bundle_name = [] bundle_list = xml_list + genshi_list for bundle_path in bundle_list: - rg = re.compile(reg,re.IGNORECASE|re.DOTALL) + rg = re.compile(reg, re.IGNORECASE | re.DOTALL) bundle_name.append(rg.search(bundle_path).group(1)) text = "Available bundles (Number of bundles: %s)" % \ (len(bundle_list)) - print text - print "%s" % (len(text) * "-") + print(text) + print("%s" % (len(text) * "-")) for i in range(len(bundle_list)): - print "[%i]\t%s" % (i, bundle_name[i]) - print "Enter the line number of a bundle for details:", - lineno = raw_input() + print("[%i]\t%s" % (i, bundle_name[i])) + try: + lineno = raw_input("Enter the line number of a bundle for details: ") + except NameError: + lineno = input("Enter the line number of a bundle for details: ") if int(lineno) >= int(len(bundle_list)): - print "No line with this number." + print("No line with this number.") else: if '%s/Bundler/%s' % \ (repo, bundle_name[int(lineno)]) in genshi_list: - print "Detailed output for *.genshi bundles is not supported." + print("Detailed output for *.genshi bundles is not supported.") else: - print 'Details for the "%s" bundle:' % \ - (bundle_name[int(lineno)].split('.')[0]) + print('Details for the "%s" bundle:' % \ + (bundle_name[int(lineno)].split('.')[0])) tree = lxml.etree.parse(bundle_list[int(lineno)]) #Prints bundle content - #print lxml.etree.tostring(tree) + #print(lxml.etree.tostring(tree)) names = ['Action', 'Package', 'Path', 'Service'] for name in names: for node in tree.findall("//" + name): - print "%s:\t%s" % (name, node.attrib["name"]) + print("%s:\t%s" % (name, node.attrib["name"])) else: - print "No command specified" + print("No command specified") raise SystemExit(1) diff --git a/src/lib/Server/Admin/Client.py b/src/lib/Server/Admin/Client.py index 08bd34151..3af25b15a 100644 --- a/src/lib/Server/Admin/Client.py +++ b/src/lib/Server/Admin/Client.py @@ -2,6 +2,7 @@ import lxml.etree import Bcfg2.Server.Admin from Bcfg2.Server.Plugins.Metadata import MetadataConsistencyError + class Client(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Create, delete, or modify client entries" __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin client add " @@ -27,13 +28,13 @@ class Client(Bcfg2.Server.Admin.MetadataCore): attr, val = i.split('=', 1) if attr not in ['profile', 'uuid', 'password', 'location', 'secure', 'address']: - print "Attribute %s unknown" % attr + print("Attribute %s unknown" % attr) raise SystemExit(1) attr_d[attr] = val try: self.metadata.add_client(args[1], attr_d) except MetadataConsistencyError: - print "Error in adding client" + print("Error in adding client") raise SystemExit(1) elif args[0] in ['update', 'up']: attr_d = {} @@ -41,24 +42,24 @@ class Client(Bcfg2.Server.Admin.MetadataCore): attr, val = i.split('=', 1) if attr not in ['profile', 'uuid', 'password', 'location', 'secure', 'address']: - print "Attribute %s unknown" % attr + print("Attribute %s unknown" % attr) raise SystemExit(1) attr_d[attr] = val try: self.metadata.update_client(args[1], attr_d) except MetadataConsistencyError: - print "Error in updating client" + print("Error in updating client") raise SystemExit(1) elif args[0] in ['delete', 'remove', 'del', 'rm']: try: self.metadata.remove_client(args[1]) except MetadataConsistencyError: - print "Error in deleting client" + print("Error in deleting client") raise SystemExit(1) elif args[0] in ['list', 'ls']: tree = lxml.etree.parse(self.metadata.data + "/clients.xml") for node in tree.findall("//Client"): - print node.attrib["name"] + print(node.attrib["name"]) else: - print "No command specified" + print("No command specified") raise SystemExit(1) diff --git a/src/lib/Server/Admin/Compare.py b/src/lib/Server/Admin/Compare.py index f97233b0e..4c751b55a 100644 --- a/src/lib/Server/Admin/Compare.py +++ b/src/lib/Server/Admin/Compare.py @@ -1,6 +1,9 @@ -import lxml.etree, os +import lxml.etree +import os + import Bcfg2.Server.Admin + class Compare(Bcfg2.Server.Admin.Mode): __shorthelp__ = ("Determine differences between files or " "directories of client specification instances") @@ -11,30 +14,30 @@ class Compare(Bcfg2.Server.Admin.Mode): def __init__(self, configfile): Bcfg2.Server.Admin.Mode.__init__(self, configfile) - self.important = {'Package':['name', 'version'], - 'Service':['name', 'status'], - 'Directory':['name', 'owner', 'group', 'perms'], - 'SymLink':['name', 'to'], - 'ConfigFile':['name', 'owner', 'group', 'perms'], - 'Permissions':['name', 'perms'], - 'PostInstall':['name']} + self.important = {'Package': ['name', 'version'], + 'Service': ['name', 'status'], + 'Directory': ['name', 'owner', 'group', 'perms'], + 'SymLink': ['name', 'to'], + 'ConfigFile': ['name', 'owner', 'group', 'perms'], + 'Permissions': ['name', 'perms'], + 'PostInstall': ['name']} def compareStructures(self, new, old): for child in new.getchildren(): equiv = old.xpath('%s[@name="%s"]' % (child.tag, child.get('name'))) if child.tag in self.important: - print "tag type %s not handled" % (child.tag) + print("tag type %s not handled" % (child.tag)) continue if len(equiv) == 0: - print ("didn't find matching %s %s" % - (child.tag, child.get('name'))) + print("didn't find matching %s %s" % + (child.tag, child.get('name'))) continue elif len(equiv) >= 1: if child.tag == 'ConfigFile': if child.text != equiv[0].text: - print " %s %s contents differ" \ - % (child.tag, child.get('name')) + print(" %s %s contents differ" \ + % (child.tag, child.get('name'))) continue noattrmatch = [field for field in self.important[child.tag] if \ child.get(field) != equiv[0].get(field)] @@ -42,8 +45,8 @@ class Compare(Bcfg2.Server.Admin.Mode): new.remove(child) old.remove(equiv[0]) else: - print " %s %s attributes %s do not match" % \ - (child.tag, child.get('name'), noattrmatch) + print(" %s %s attributes %s do not match" % \ + (child.tag, child.get('name'), noattrmatch)) if len(old.getchildren()) == 0 and len(new.getchildren()) == 0: return True if new.tag == 'Independent': @@ -59,24 +62,26 @@ class Compare(Bcfg2.Server.Admin.Mode): newl.remove(entry) oldl.remove(entry) for entry in both: - print " %s differs (in bundle %s)" % (entry, name) + print(" %s differs (in bundle %s)" % (entry, name)) for entry in oldl: - print " %s only in old configuration (in bundle %s)" % (entry, name) + print(" %s only in old configuration (in bundle %s)" % (entry, + name)) for entry in newl: - print " %s only in new configuration (in bundle %s)" % (entry, name) + print(" %s only in new configuration (in bundle %s)" % (entry, + name)) return False def compareSpecifications(self, path1, path2): try: new = lxml.etree.parse(path1).getroot() except IOError: - print "Failed to read %s" % (path1) + print("Failed to read %s" % (path1)) raise SystemExit(1) try: old = lxml.etree.parse(path2).getroot() except IOError: - print "Failed to read %s" % (path2) + print("Failed to read %s" % (path2)) raise SystemExit(1) for src in [new, old]: @@ -88,7 +93,7 @@ class Compare(Bcfg2.Server.Admin.Mode): for bundle in new.findall('./Bundle'): equiv = old.xpath('Bundle[@name="%s"]' % (bundle.get('name'))) if len(equiv) == 0: - print "couldnt find matching bundle for %s" % bundle.get('name') + print("couldnt find matching bundle for %s" % bundle.get('name')) continue if len(equiv) == 1: if self.compareStructures(bundle, equiv[0]): @@ -98,7 +103,7 @@ class Compare(Bcfg2.Server.Admin.Mode): else: rcs.append(False) else: - print "Unmatched bundle %s" % (bundle.get('name')) + print("Unmatched bundle %s" % (bundle.get('name'))) rcs.append(False) i1 = new.find('./Independent') i2 = old.find('./Independent') @@ -120,18 +125,18 @@ class Compare(Bcfg2.Server.Admin.Mode): (oldd, newd) = args (old, new) = [os.listdir(spot) for spot in args] for item in old: - print "Entry:", item + print("Entry:", item) state = self.__call__([oldd + '/' + item, newd + '/' + item]) new.remove(item) if state: - print "Entry:", item, "good" + print("Entry:", item, "good") else: - print "Entry:", item, "bad" + print("Entry:", item, "bad") if new: - print "new has extra entries", new + print("new has extra entries", new) return try: (old, new) = args except IndexError: - print self.__call__.__doc__ + print(self.__call__.__doc__) raise SystemExit(1) diff --git a/src/lib/Server/Admin/Group.py b/src/lib/Server/Admin/Group.py index 4b2db28ec..1c5d0c12f 100644 --- a/src/lib/Server/Admin/Group.py +++ b/src/lib/Server/Admin/Group.py @@ -2,6 +2,7 @@ import lxml.etree import Bcfg2.Server.Admin from Bcfg2.Server.Plugins.Metadata import MetadataConsistencyError + class Group(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Create, delete, or modify group entries" __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin group add " @@ -28,13 +29,13 @@ class Group(Bcfg2.Server.Admin.MetadataCore): if attr not in ['profile', 'public', 'default', 'name', 'auth', 'toolset', 'category', 'comment']: - print "Attribute %s unknown" % attr + print("Attribute %s unknown" % attr) raise SystemExit(1) attr_d[attr] = val try: self.metadata.add_group(args[1], attr_d) except MetadataConsistencyError: - print "Error in adding group" + print("Error in adding group") raise SystemExit(1) elif args[0] in ['update', 'up']: attr_d = {} @@ -43,24 +44,24 @@ class Group(Bcfg2.Server.Admin.MetadataCore): if attr not in ['profile', 'public', 'default', 'name', 'auth', 'toolset', 'category', 'comment']: - print "Attribute %s unknown" % attr + print("Attribute %s unknown" % attr) raise SystemExit(1) attr_d[attr] = val try: self.metadata.update_group(args[1], attr_d) except MetadataConsistencyError: - print "Error in updating group" + print("Error in updating group") raise SystemExit(1) elif args[0] in ['delete', 'remove', 'del', 'rm']: try: self.metadata.remove_group(args[1]) except MetadataConsistencyError: - print "Error in deleting group" + print("Error in deleting group") raise SystemExit(1) elif args[0] in ['list', 'ls']: tree = lxml.etree.parse(self.metadata.data + "/groups.xml") for node in tree.findall("//Group"): - print node.attrib["name"] + print(node.attrib["name"]) else: - print "No command specified" + print("No command specified") raise SystemExit(1) diff --git a/src/lib/Server/Admin/Init.py b/src/lib/Server/Admin/Init.py index 8f54b836e..eddbd732a 100644 --- a/src/lib/Server/Admin/Init.py +++ b/src/lib/Server/Admin/Init.py @@ -137,20 +137,33 @@ def create_key(hostname, keypath, certpath, country, state, location): keypath, certpath)) subprocess.call((ccstr), shell=True) - os.chmod(keypath, 0600) + # py3k compatibility + try: + os.chmod(keypath, 0600) + except SyntaxError: + os.chmod(keypath, 0o600) def create_conf(confpath, confdata): # Don't overwrite existing bcfg2.conf file if os.path.exists(confpath): - result = raw_input("\nWarning: %s already exists. " - "Overwrite? [y/N]: " % confpath) + # py3k compatibility + try: + result = raw_input("\nWarning: %s already exists. " + "Overwrite? [y/N]: " % confpath) + except NameError: + result = input("\nWarning: %s already exists. " + "Overwrite? [y/N]: " % confpath) if result not in ['Y', 'y']: print("Leaving %s unchanged" % confpath) return try: open(confpath, "w").write(confdata) - os.chmod(confpath, 0600) + # py3k compatibility + try: + os.chmod(keypath, 0600) + except SyntaxError: + os.chmod(keypath, 0o600) except Exception, e: print("Error %s occured while trying to write configuration " "file to '%s'.\n" % @@ -204,7 +217,12 @@ class Init(Bcfg2.Server.Admin.Mode): def _prompt_hostname(self): """Ask for the server hostname.""" - data = raw_input("What is the server's hostname [%s]: " % + # py3k compatibility + try: + data = raw_input("What is the server's hostname [%s]: " % + socket.getfqdn()) + except NameError: + data = input("What is the server's hostname [%s]: " % socket.getfqdn()) if data != '': self.shostname = data @@ -213,21 +231,36 @@ class Init(Bcfg2.Server.Admin.Mode): def _prompt_config(self): """Ask for the configuration file path.""" - newconfig = raw_input("Store Bcfg2 configuration in [%s]: " % - self.configfile) + # py3k compatibility + try: + newconfig = raw_input("Store Bcfg2 configuration in [%s]: " % + self.configfile) + except NameError: + newconfig = input("Store Bcfg2 configuration in [%s]: " % + self.configfile) if newconfig != '': self.configfile = newconfig def _prompt_repopath(self): """Ask for the repository path.""" while True: - newrepo = raw_input("Location of Bcfg2 repository [%s]: " % - self.repopath) + # py3k compatibility + try: + newrepo = raw_input("Location of Bcfg2 repository [%s]: " % + self.repopath) + except NameError: + newrepo = input("Location of Bcfg2 repository [%s]: " % + self.repopath) if newrepo != '': self.repopath = newrepo if os.path.isdir(self.repopath): - response = raw_input("Directory %s exists. Overwrite? [y/N]:" \ - % self.repopath) + # py3k compatibility + try: + response = raw_input("Directory %s exists. Overwrite? [y/N]:" \ + % self.repopath) + except NameError: + response = input("Directory %s exists. Overwrite? [y/N]:" \ + % self.repopath) if response.lower().strip() == 'y': break else: @@ -243,8 +276,13 @@ class Init(Bcfg2.Server.Admin.Mode): def _prompt_server(self): """Ask for the server name.""" - newserver = raw_input("Input the server location [%s]: " % - self.server_uri) + # py3k compatibility + try: + newserver = raw_input("Input the server location [%s]: " % + self.server_uri) + except NameError: + newserver = input("Input the server location [%s]: " % + self.server_uri) if newserver != '': self.server_uri = newserver @@ -256,51 +294,81 @@ class Init(Bcfg2.Server.Admin.Mode): prompt += ': ' while True: try: - self.os_sel = os_list[int(raw_input(prompt))-1][1] + # py3k compatibility + try: + osidx = int(raw_input(prompt)) + except NameError: + osidx = int(input(prompt)) + self.os_sel = os_list[osidx - 1][1] break except ValueError: continue def _prompt_plugins(self): - default = raw_input("Use default plugins? (%s) [Y/n]: " % + # py3k compatibility + try: + default = raw_input("Use default plugins? (%s) [Y/n]: " % + ''.join(default_plugins)).lower() + except NameError: + default = input("Use default plugins? (%s) [Y/n]: " % ''.join(default_plugins)).lower() if default != 'y' or default != '': while True: plugins_are_valid = True - plug_str = raw_input("Specify plugins: ") + # py3k compatibility + try: + plug_str = raw_input("Specify plugins: ") + except NameError: + plug_str = input("Specify plugins: ") plugins = plug_str.split(',') for plugin in plugins: plugin = plugin.strip() if not plugin in plugin_list: plugins_are_valid = False - print "ERROR: Plugin %s not recognized" % plugin + print("ERROR: Plugin %s not recognized" % plugin) if plugins_are_valid: break def _prompt_certificate(self): """Ask for the key details (country, state, and location).""" - print "The following questions affect SSL certificate generation." - print "If no data is provided, the default values are used." - newcountry = raw_input("Country name (2 letter code) for certificate: ") + print("The following questions affect SSL certificate generation.") + print("If no data is provided, the default values are used.") + # py3k compatibility + try: + newcountry = raw_input("Country name (2 letter code) for certificate: ") + except NameError: + newcountry = input("Country name (2 letter code) for certificate: ") if newcountry != '': if len(newcountry) == 2: self.country = newcountry else: while len(newcountry) != 2: - newcountry = raw_input("2 letter country code (eg. US): ") + # py3k compatibility + try: + newcountry = raw_input("2 letter country code (eg. US): ") + except NameError: + newcountry = input("2 letter country code (eg. US): ") if len(newcountry) == 2: self.country = newcountry break else: self.country = 'US' - newstate = raw_input("State or Province Name (full name) for certificate: ") + # py3k compatibility + try: + newstate = raw_input("State or Province Name (full name) for certificate: ") + except NameError: + newstate = input("State or Province Name (full name) for certificate: ") if newstate != '': self.state = newstate else: self.state = 'Illinois' - newlocation = raw_input("Locality Name (eg, city) for certificate: ") + # py3k compatibility + try: + newlocation = raw_input("Locality Name (eg, city) for certificate: ") + except NameError: + newlocation = input("Locality Name (eg, city) for certificate: ") if newlocation != '': self.location = newlocation else: @@ -349,6 +417,6 @@ class Init(Bcfg2.Server.Admin.Mode): try: os.makedirs(path) self._init_plugins() - print "Repository created successfuly in %s" % (self.repopath) + print("Repository created successfuly in %s" % (self.repopath)) except OSError: print("Failed to create %s." % path) diff --git a/src/lib/Server/Admin/Perf.py b/src/lib/Server/Admin/Perf.py index 095180592..af1c83072 100644 --- a/src/lib/Server/Admin/Perf.py +++ b/src/lib/Server/Admin/Perf.py @@ -1,8 +1,9 @@ +import sys + import Bcfg2.Options import Bcfg2.Proxy import Bcfg2.Server.Admin -import sys class Perf(Bcfg2.Server.Admin.Mode): __shorthelp__ = ("Query server for performance data") @@ -27,11 +28,11 @@ class Perf(Bcfg2.Server.Admin.Mode): proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], setup['user'], setup['password'], - key = setup['key'], - cert = setup['certificate'], - ca = setup['ca']) + key=setup['key'], + cert=setup['certificate'], + ca=setup['ca']) data = proxy.get_statistics() - for key, value in data.iteritems(): + for key, value in list(data.items()): data = tuple(["%.06f" % (item) for item in value[:-1]] + [value[-1]]) output.append((key, ) + data) self.print_table(output) diff --git a/src/lib/Server/Admin/Pull.py b/src/lib/Server/Admin/Pull.py index 926eda1b3..47a8be253 100644 --- a/src/lib/Server/Admin/Pull.py +++ b/src/lib/Server/Admin/Pull.py @@ -1,7 +1,9 @@ import getopt import sys + import Bcfg2.Server.Admin + class Pull(Bcfg2.Server.Admin.MetadataCore): """Pull mode retrieves entries from clients and integrates the information into the repository. @@ -38,7 +40,7 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): try: opts, gargs = getopt.getopt(args, 'vfIs') except: - print self.__shorthelp__ + print(self.__shorthelp__) raise SystemExit(1) for opt in opts: if opt[0] == '-v': @@ -55,18 +57,20 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): try: self.PullEntry(*line.split(None, 3)) except SystemExit: - print " for %s" % line + print(" for %s" % line) except: - print "Bad entry: %s" % line.strip() + print("Bad entry: %s" % line.strip()) elif len(gargs) < 3: - print self.__longhelp__ + print(self.__longhelp__) raise SystemExit(1) else: self.PullEntry(gargs[0], gargs[1], gargs[2]) def BuildNewEntry(self, client, etype, ename): - """Construct a new full entry for given client/entry from statistics.""" - new_entry = {'type':etype, 'name':ename} + """Construct a new full entry for + given client/entry from statistics. + """ + new_entry = {'type': etype, 'name': ename} for plugin in self.bcore.pull_sources: try: (owner, group, perms, contents) = \ @@ -74,16 +78,19 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): break except Bcfg2.Server.Plugin.PluginExecutionError: if plugin == self.bcore.pull_sources[-1]: - print "Pull Source failure; could not fetch current state" + print("Pull Source failure; could not fetch current state") raise SystemExit(1) try: - data = {'owner':owner, 'group':group, 'perms':perms, 'text':contents} + data = {'owner': owner, + 'group': group, + 'perms': perms, + 'text': contents} except UnboundLocalError: print("Unable to build entry. " "Do you have a statistics plugin enabled?") raise SystemExit(1) - for k, v in data.iteritems(): + for k, v in list(data.items()): if v: new_entry[k] = v #print new_entry @@ -93,17 +100,22 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): """Determine where to put pull data.""" if self.mode == 'interactive': for choice in choices: - print "Plugin returned choice:" + print("Plugin returned choice:") if id(choice) == id(choices[0]): - print "(current entry)", + print("(current entry) ") if choice.all: - print " => global entry" + print(" => global entry") elif choice.group: - print (" => group entry: %s (prio %d)" % - (choice.group, choice.prio)) + print(" => group entry: %s (prio %d)" % + (choice.group, choice.prio)) else: - print " => host entry: %s" % (choice.hostname) - if raw_input("Use this entry? [yN]: ") in ['y', 'Y']: + print(" => host entry: %s" % (choice.hostname)) + # py3k compatibility + try: + ans = raw_input("Use this entry? [yN]: ") in ['y', 'Y'] + except NameError: + ans = input("Use this entry? [yN]: ") in ['y', 'Y'] + if ans: return choice return False else: @@ -136,7 +148,7 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): self.errExit("Configuration upload not supported by plugin %s" \ % (plugin.name)) # Commit if running under a VCS - for vcsplugin in self.bcore.plugins.values(): + for vcsplugin in list(self.bcore.plugins.values()): if isinstance(vcsplugin, Bcfg2.Server.Plugin.Version): files = "%s/%s" % (plugin.data, ename) comment = 'file "%s" pulled from host %s' % (files, client) diff --git a/src/lib/Server/Admin/Query.py b/src/lib/Server/Admin/Query.py index b5af9bad2..207b65035 100644 --- a/src/lib/Server/Admin/Query.py +++ b/src/lib/Server/Admin/Query.py @@ -2,6 +2,7 @@ import logging import Bcfg2.Logger import Bcfg2.Server.Admin + class Query(Bcfg2.Server.Admin.Mode): __shorthelp__ = "Query clients" __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin query [-n] [-c] " @@ -32,7 +33,7 @@ class Query(Bcfg2.Server.Admin.Mode): def __call__(self, args): Bcfg2.Server.Admin.Mode.__call__(self, args) - clients = self.meta.clients.keys() + clients = list(self.meta.clients.keys()) filename_arg = False filename = None for arg in args: @@ -48,7 +49,7 @@ class Query(Bcfg2.Server.Admin.Mode): try: k, v = arg.split('=') except: - print "Unknown argument %s" % arg + print("Unknown argument %s" % arg) continue if k == 'p': nc = self.meta.get_client_names_by_profiles(v.split(',')) @@ -57,22 +58,22 @@ class Query(Bcfg2.Server.Admin.Mode): # add probed groups (if present) for conn in self.bcore.connectors: if isinstance(conn, Bcfg2.Server.Plugins.Probes.Probes): - for c, glist in conn.cgroups.items(): + for c, glist in list(conn.cgroups.items()): for g in glist: if g in v.split(','): nc.append(c) else: - print "One of g= or p= must be specified" + print("One of g= or p= must be specified") raise SystemExit(1) clients = [c for c in clients if c in nc] if '-n' in args: for client in clients: - print client + print(client) else: - print ','.join(clients) + print(','.join(clients)) if '-f' in args: f = open(filename, "w") for client in clients: f.write(client + "\n") f.close() - print "Wrote results to %s" % (filename) + print("Wrote results to %s" % (filename)) diff --git a/src/lib/Server/Admin/Reports.py b/src/lib/Server/Admin/Reports.py index 1ac94e5e7..39c9eb71e 100644 --- a/src/lib/Server/Admin/Reports.py +++ b/src/lib/Server/Admin/Reports.py @@ -42,7 +42,8 @@ from django.db import connection, transaction from Bcfg2.Server.Reports.reports.models import Client, Interaction, Entries, \ Entries_interactions, Performance, \ - Reason, Ping, TYPE_CHOICES, InternalDatabaseVersion + Reason, Ping + def printStats(fn): """ @@ -72,6 +73,7 @@ def printStats(fn): return print_stats + class Reports(Bcfg2.Server.Admin.Mode): '''Admin interface for dynamic reports''' __shorthelp__ = "Manage dynamic reports" @@ -97,7 +99,7 @@ class Reports(Bcfg2.Server.Admin.Mode): def __init__(self, cfile): Bcfg2.Server.Admin.Mode.__init__(self, cfile) self.log.setLevel(logging.INFO) - self.django_commands = [ 'syncdb', 'sqlall', 'validate' ] + self.django_commands = ['syncdb', 'sqlall', 'validate'] self.__usage__ = self.__usage__ + " Django commands:\n " + \ "\n ".join(self.django_commands) @@ -127,54 +129,54 @@ class Reports(Bcfg2.Server.Admin.Mode): update_database() elif args[0] == 'load_stats': quick = '-O3' in args - stats_file=None - clients_file=None - i=1 + stats_file = None + clients_file = None + i = 1 while i < len(args): if args[i] == '-s' or args[i] == '--stats': - stats_file = args[i+1] + stats_file = args[i + 1] if stats_file[0] == '-': self.errExit("Invalid statistics file: %s" % stats_file) elif args[i] == '-c' or args[i] == '--clients-file': - clients_file = args[i+1] + clients_file = args[i + 1] if clients_file[0] == '-': self.errExit("Invalid clients file: %s" % clients_file) i = i + 1 self.load_stats(stats_file, clients_file, verb, quick) elif args[0] == 'purge': - expired=False - client=None - maxdate=None - state=None - i=1 + expired = False + client = None + maxdate = None + state = None + i = 1 while i < len(args): if args[i] == '-c' or args[i] == '--client': if client: self.errExit("Only one client per run") - client = args[i+1] - print client + client = args[i + 1] + print(client) i = i + 1 elif args[i] == '--days': if maxdate: self.errExit("Max date specified multiple times") try: - maxdate = datetime.datetime.now() - datetime.timedelta(days=int(args[i+1])) + maxdate = datetime.datetime.now() - datetime.timedelta(days=int(args[i + 1])) except: - self.log.error("Invalid number of days: %s" % args[i+1]) - raise SystemExit, -1 + self.log.error("Invalid number of days: %s" % args[i + 1]) + raise SystemExit(-1) i = i + 1 elif args[i] == '--expired': - expired=True + expired = True i = i + 1 if expired: if state: self.log.error("--state is not valid with --expired") - raise SystemExit, -1 + raise SystemExit(-1) self.purge_expired(maxdate) else: self.purge(client, maxdate, state) else: - print "Unknown command: %s" % args[0] + print("Unknown command: %s" % args[0]) @transaction.commit_on_success def scrub(self): @@ -187,7 +189,7 @@ class Reports(Bcfg2.Server.Admin.Mode): self.log.error("Failed to load reason objects: %s" % e) return dup_reasons = [] - + cmp_reasons = dict() batch_update = [] for reason in BatchFetch(Reason.objects): @@ -196,7 +198,7 @@ class Reports(Bcfg2.Server.Admin.Mode): comparisons ''' id = reason.id reason.id = None - key=md5(pickle.dumps(reason)).hexdigest() + key = md5(pickle.dumps(reason)).hexdigest() reason.id = id if key in cmp_reasons: @@ -207,7 +209,7 @@ class Reports(Bcfg2.Server.Admin.Mode): else: cmp_reasons[key] = reason.id self.log.debug("key %d" % reason.id) - + self.log.debug("Done with updates, deleting dupes") try: cursor = connection.cursor() @@ -248,7 +250,7 @@ class Reports(Bcfg2.Server.Admin.Mode): try: statsdata = XML(open(stats_file).read()) except (IOError, XMLSyntaxError): - self.errExit("StatReports: Failed to parse %s"%(stats_file)) + self.errExit("StatReports: Failed to parse %s" % (stats_file)) if not clientspath: try: @@ -259,10 +261,15 @@ class Reports(Bcfg2.Server.Admin.Mode): try: clientsdata = XML(open(clientspath).read()) except (IOError, XMLSyntaxError): - self.errExit("StatReports: Failed to parse %s"%(clientspath)) + self.errExit("StatReports: Failed to parse %s" % (clientspath)) try: - load_stats(clientsdata, statsdata, verb, self.log, quick=quick, location=platform.node()) + load_stats(clientsdata, + statsdata, + verb, + self.log, + quick=quick, + location=platform.node()) except: pass @@ -270,7 +277,7 @@ class Reports(Bcfg2.Server.Admin.Mode): def purge(self, client=None, maxdate=None, state=None): '''Purge historical data from the database''' - filtered = False # indicates whether or not a client should be deleted + filtered = False # indicates whether or not a client should be deleted if not client and not maxdate and not state: self.errExit("Reports.prune: Refusing to prune all data") @@ -282,13 +289,13 @@ class Reports(Bcfg2.Server.Admin.Mode): ipurge = ipurge.filter(client=cobj) except Client.DoesNotExist: self.log.error("Client %s not in database" % client) - raise SystemExit, -1 + raise SystemExit(-1) self.log.debug("Filtering by client: %s" % client) if maxdate: filtered = True if not isinstance(maxdate, datetime.datetime): - raise TypeError, "maxdate is not a DateTime object" + raise TypeError("maxdate is not a DateTime object") self.log.debug("Filtering by maxdate: %s" % maxdate) ipurge = ipurge.filter(timestamp__lt=maxdate) @@ -300,9 +307,9 @@ class Reports(Bcfg2.Server.Admin.Mode): if state: filtered = True - if state not in ('dirty','clean','modified'): - raise TypeError, "state is not one of the following values " + \ - "('dirty','clean','modified')" + if state not in ('dirty', 'clean', 'modified'): + raise TypeError("state is not one of the following values " + \ + "('dirty','clean','modified')") self.log.debug("Filtering by state: %s" % state) ipurge = ipurge.filter(state=state) @@ -346,7 +353,7 @@ class Reports(Bcfg2.Server.Admin.Mode): if maxdate: if not isinstance(maxdate, datetime.datetime): - raise TypeError, "maxdate is not a DateTime object" + raise TypeError("maxdate is not a DateTime object") self.log.debug("Filtering by maxdate: %s" % maxdate) clients = Client.objects.filter(expiration__lt=maxdate) else: @@ -358,4 +365,3 @@ class Reports(Bcfg2.Server.Admin.Mode): client.delete() self.log.debug("Pruning orphan Performance objects") Performance.prune_orphans() - diff --git a/src/lib/Server/Admin/Tidy.py b/src/lib/Server/Admin/Tidy.py index cc8ab4f5e..f79991fd9 100644 --- a/src/lib/Server/Admin/Tidy.py +++ b/src/lib/Server/Admin/Tidy.py @@ -4,6 +4,7 @@ import socket import Bcfg2.Server.Admin + class Tidy(Bcfg2.Server.Admin.Mode): __shorthelp__ = "Clean up useless files in the repo" __longhelp__ = __shorthelp__ + "\n\nbcfg2-admin tidy [-f] [-I]\n" @@ -24,17 +25,21 @@ class Tidy(Bcfg2.Server.Admin.Mode): if '-f' in args or '-I' in args: if '-I' in args: for name in badfiles[:]: - answer = raw_input("Unlink file %s? [yN] " % name) + # py3k compatibility + try: + answer = raw_input("Unlink file %s? [yN] " % name) + except NameError: + answer = input("Unlink file %s? [yN] " % name) if answer not in ['y', 'Y']: badfiles.remove(name) for name in badfiles: try: os.unlink(name) except IOError: - print "Failed to unlink %s" % name + print("Failed to unlink %s" % name) else: for name in badfiles: - print name + print(name) def buildTidyList(self): """Clean up unused or unusable files from the repository.""" @@ -56,7 +61,8 @@ class Tidy(Bcfg2.Server.Admin.Mode): bad.append(hostname) for name in os.listdir("%s/SSHbase" % (self.get_repo_path())): if not hostmatcher.match(name): - to_remove.append("%s/SSHbase/%s" % (self.get_repo_path(), name)) + to_remove.append("%s/SSHbase/%s" % (self.get_repo_path(), + name)) else: if hostmatcher.match(name).group(1) in bad: to_remove.append("%s/SSHbase/%s" % diff --git a/src/lib/Server/Admin/Viz.py b/src/lib/Server/Admin/Viz.py index e3daea84b..a77502b5d 100644 --- a/src/lib/Server/Admin/Viz.py +++ b/src/lib/Server/Admin/Viz.py @@ -1,7 +1,9 @@ import getopt from subprocess import Popen, PIPE + import Bcfg2.Server.Admin + class Viz(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Produce graphviz diagrams of metadata structures" __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin viz [--includehosts] " @@ -27,7 +29,8 @@ class Viz(Bcfg2.Server.Admin.MetadataCore): plugin_blacklist = ['DBStats', 'Snapshots', 'Cfg', 'Pkgmgr', 'Packages', 'Rules', 'Account', 'Decisions', 'Deps', 'Git', 'Svn', - 'Fossil', 'Bzr', 'Bundler', 'TGenshi', 'SGenshi', 'Base'] + 'Fossil', 'Bzr', 'Bundler', 'TGenshi', 'SGenshi', + 'Base'] def __init__(self, cfile): @@ -43,7 +46,7 @@ class Viz(Bcfg2.Server.Admin.MetadataCore): ['includehosts', 'includebundles', 'includekey', 'outfile=']) except getopt.GetoptError, msg: - print msg + print(msg) #FIXME: is this for --raw? #rset = False @@ -63,8 +66,8 @@ class Viz(Bcfg2.Server.Admin.MetadataCore): data = self.Visualize(self.get_repo_path(), hset, bset, kset, outputfile) - print data - raise SystemExit, 0 + print(data) + raise SystemExit(0) def Visualize(self, repopath, hosts=False, bundles=False, key=False, output=False): @@ -82,7 +85,7 @@ class Viz(Bcfg2.Server.Admin.MetadataCore): try: dotpipe.stdin.write("digraph groups {\n") except: - print "write to dot process failed. Is graphviz installed?" + print("write to dot process failed. Is graphviz installed?") raise SystemExit(1) dotpipe.stdin.write('\trankdir="LR";\n') dotpipe.stdin.write(self.metadata.viz(hosts, bundles, diff --git a/src/lib/Server/Admin/Xcmd.py b/src/lib/Server/Admin/Xcmd.py index 8ea98b79c..e761a5e3d 100644 --- a/src/lib/Server/Admin/Xcmd.py +++ b/src/lib/Server/Admin/Xcmd.py @@ -1,9 +1,10 @@ +import sys +import xmlrpclib + import Bcfg2.Options import Bcfg2.Proxy import Bcfg2.Server.Admin -import sys -import xmlrpclib class Xcmd(Bcfg2.Server.Admin.Mode): __shorthelp__ = ("XML-RPC Command Interface") @@ -16,8 +17,8 @@ class Xcmd(Bcfg2.Server.Admin.Mode): 'user': Bcfg2.Options.CLIENT_USER, 'password': Bcfg2.Options.SERVER_PASSWORD, 'key': Bcfg2.Options.SERVER_KEY, - 'certificate' : Bcfg2.Options.CLIENT_CERT, - 'ca' : Bcfg2.Options.CLIENT_CA + 'certificate': Bcfg2.Options.CLIENT_CERT, + 'ca': Bcfg2.Options.CLIENT_CA } setup = Bcfg2.Options.OptionParser(optinfo) setup.parse(sys.argv[2:]) @@ -25,9 +26,10 @@ class Xcmd(Bcfg2.Server.Admin.Mode): proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], setup['user'], setup['password'], - key = setup['key'], - cert = setup['certificate'], - ca = setup['ca'], timeout=180) + key=setup['key'], + cert=setup['certificate'], + ca=setup['ca'], + timeout=180) if len(setup['args']) == 0: print("Usage: xcmd ") return @@ -36,7 +38,7 @@ class Xcmd(Bcfg2.Server.Admin.Mode): if len(setup['args']) > 1: args = tuple(setup['args'][1:]) try: - data = apply(getattr(proxy, cmd), args) + data = getattr(proxy, cmd)(*args) except xmlrpclib.Fault, flt: if flt.faultCode == 7: print("Unknown method %s" % cmd) @@ -46,4 +48,4 @@ class Xcmd(Bcfg2.Server.Admin.Mode): else: raise if data != None: - print data + print(data) diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py index dc3dc8c01..411f909ee 100644 --- a/src/lib/Server/Admin/__init__.py +++ b/src/lib/Server/Admin/__init__.py @@ -27,14 +27,17 @@ 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 @@ -50,11 +53,11 @@ class Mode(object): def __call__(self, args): if len(args) > 0 and args[0] == 'help': - print self.__longhelp__ + print(self.__longhelp__) raise SystemExit(0) def errExit(self, emsg): - print emsg + print(emsg) raise SystemExit(1) def get_repo_path(self): @@ -80,9 +83,9 @@ class Mode(object): """ hdelim = "=" - justify = {'left':str.ljust, - 'center':str.center, - 'right':str.rjust}[justify.lower()] + justify = {'left': str.ljust, + 'center': str.center, + 'right': str.rjust}[justify.lower()] """ Calculate column widths (longest item in each column @@ -90,9 +93,9 @@ class Mode(object): """ cols = list(zip(*rows)) - colWidths = [max([len(str(item))+2*padding for \ + colWidths = [max([len(str(item)) + 2 * padding for \ item in col]) for col in cols] - borderline = vdelim.join([w*hdelim for w in colWidths]) + borderline = vdelim.join([w * hdelim for w in colWidths]) # Print out the table print(borderline) @@ -103,6 +106,7 @@ class Mode(object): print(borderline) hdr = False + class MetadataCore(Mode): """Base class for admin-modes that handle metadata.""" def __init__(self, configfile, usage, pwhitelist=None, pblacklist=None): @@ -113,9 +117,11 @@ class MetadataCore(Mode): 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] + 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] + 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'], @@ -125,5 +131,6 @@ class MetadataCore(Mode): self.bcore.fam.handle_events_in_interval(5) self.metadata = self.bcore.metadata + class StructureMode(MetadataCore): pass -- cgit v1.2.3-1-g7c22