summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2011-05-03 14:06:26 -0500
committerSol Jerome <sol.jerome@gmail.com>2011-05-03 14:06:26 -0500
commit136d7397a067d815d986b49e06d6d3217fdb18f8 (patch)
tree2decb82d93bdd67365162ddfcbb472caffdbbd06 /src
parent20ed074b7a05b8b3817b1ca9a11d8a4b09b719ce (diff)
parent71a026b3b7c13fdf242d387b255d6e0daefce0ca (diff)
downloadbcfg2-136d7397a067d815d986b49e06d6d3217fdb18f8.tar.gz
bcfg2-136d7397a067d815d986b49e06d6d3217fdb18f8.tar.bz2
bcfg2-136d7397a067d815d986b49e06d6d3217fdb18f8.zip
Merge branch 'py3k'
Diffstat (limited to 'src')
-rw-r--r--src/lib/Bcfg2Py3Incompat.py2
-rw-r--r--src/lib/Bcfg2Py3k.py51
-rw-r--r--src/lib/Client/Tools/__init__.py52
-rw-r--r--src/lib/Component.py61
-rw-r--r--src/lib/Logger.py8
-rw-r--r--src/lib/Options.py6
-rw-r--r--src/lib/Proxy.py30
-rw-r--r--src/lib/SSLServer.py11
-rw-r--r--src/lib/Server/Admin/Init.py10
-rw-r--r--src/lib/Server/Admin/Query.py3
-rw-r--r--src/lib/Server/Admin/Reports.py13
-rw-r--r--src/lib/Server/Admin/Snapshots.py8
-rw-r--r--src/lib/Server/Admin/Viz.py3
-rw-r--r--src/lib/Server/Admin/Xcmd.py7
-rw-r--r--src/lib/Server/Admin/__init__.py6
-rw-r--r--src/lib/Server/Core.py11
-rw-r--r--src/lib/Server/Plugin.py7
-rw-r--r--src/lib/Server/Plugins/Packages.py22
-rw-r--r--src/lib/Server/Plugins/TGenshi.py2
-rwxr-xr-xsrc/sbin/bcfg222
-rwxr-xr-xsrc/sbin/bcfg2-admin10
-rwxr-xr-xsrc/sbin/bcfg2-build-reports62
-rwxr-xr-xsrc/sbin/bcfg2-info108
-rwxr-xr-xsrc/sbin/bcfg2-lint14
-rwxr-xr-xsrc/sbin/bcfg2-ping-sweep2
-rwxr-xr-xsrc/sbin/bcfg2-reports16
-rwxr-xr-xsrc/sbin/bcfg2-server3
27 files changed, 304 insertions, 246 deletions
diff --git a/src/lib/Bcfg2Py3Incompat.py b/src/lib/Bcfg2Py3Incompat.py
new file mode 100644
index 000000000..6b66e72b0
--- /dev/null
+++ b/src/lib/Bcfg2Py3Incompat.py
@@ -0,0 +1,2 @@
+def fprint(s, f):
+ print(s, file=f)
diff --git a/src/lib/Bcfg2Py3k.py b/src/lib/Bcfg2Py3k.py
index 0f5321a41..c9e48a49b 100644
--- a/src/lib/Bcfg2Py3k.py
+++ b/src/lib/Bcfg2Py3k.py
@@ -1,3 +1,5 @@
+import sys
+
try:
from email.Utils import formatdate
except ImportError:
@@ -5,7 +7,7 @@ except ImportError:
# urllib imports
try:
- from urlparse import urljoin
+ from urlparse import urljoin, urlparse
from urllib2 import HTTPBasicAuthHandler
from urllib2 import HTTPPasswordMgrWithDefaultRealm
from urllib2 import build_opener
@@ -13,7 +15,7 @@ try:
from urllib import urlopen
from urllib2 import HTTPError
except ImportError:
- from urllib.parse import urljoin
+ from urllib.parse import urljoin, urlparse
from urllib.request import HTTPBasicAuthHandler
from urllib.request import HTTPPasswordMgrWithDefaultRealm
from urllib.request import build_opener
@@ -37,10 +39,43 @@ except ImportError:
import pickle as cPickle
try:
- from Queue import Queue
- from Queue import Empty
- from Queue import Full
+ from Queue import Queue, Empty, Full
+except ImportError:
+ from queue import Queue, Empty, Full
+
+# xmlrpc imports
+try:
+ import xmlrpclib, SimpleXMLRPCServer
+except ImportError:
+ import xmlrpc.client as xmlrpclib
+ import xmlrpc.server as SimpleXMLRPCServer
+
+# socketserver import
+try:
+ import SocketServer
+except ImportError:
+ import socketserver as SocketServer
+
+# httplib imports
+try:
+ import httplib
except ImportError:
- from queue import Queue
- from queue import Empty
- from queue import Full
+ import http.client as httplib
+
+# print to file compatibility
+def u_str(string):
+ if sys.hexversion >= 0x03000000:
+ return string
+ else:
+ return unicode(string)
+
+"""
+In order to use the new syntax for printing to a file, we need to do
+a conditional import because there is a syntax incompatibility between
+the two versions of python.
+"""
+if sys.hexversion >= 0x03000000:
+ from Bcfg2.Bcfg2Py3Incompat import fprint
+else:
+ def fprint(s, f):
+ print >> f, s
diff --git a/src/lib/Client/Tools/__init__.py b/src/lib/Client/Tools/__init__.py
index 6a934fe52..88609c2f6 100644
--- a/src/lib/Client/Tools/__init__.py
+++ b/src/lib/Client/Tools/__init__.py
@@ -4,9 +4,9 @@ import warnings
warnings.filterwarnings("ignore", "The popen2 module is deprecated.*",
DeprecationWarning)
import os
-import popen2
import stat
import sys
+from subprocess import Popen, PIPE
import time
import Bcfg2.Client.XML
@@ -25,26 +25,6 @@ class toolInstantiationError(Exception):
pass
-class readonlypipe(popen2.Popen4):
- """This pipe sets up stdin --> /dev/null."""
-
- def __init__(self, cmd, bufsize=-1):
- popen2._cleanup()
- c2pread, c2pwrite = os.pipe()
- null = open('/dev/null', 'w+')
- self.pid = os.fork()
- if self.pid == 0:
- # Child
- os.dup2(null.fileno(), sys.__stdin__.fileno())
- #os.dup2(p2cread, 0)
- os.dup2(c2pwrite, 1)
- os.dup2(c2pwrite, 2)
- self._run_child(cmd)
- os.close(c2pwrite)
- self.fromchild = os.fdopen(c2pread, 'r', bufsize)
- popen2._active.append(self)
-
-
class executor:
"""This class runs stuff for us"""
@@ -53,30 +33,12 @@ class executor:
def run(self, command):
"""Run a command in a pipe dealing with stdout buffer overloads."""
- self.logger.debug('> %s' % command)
-
- runpipe = readonlypipe(command, bufsize=16384)
- output = []
- try: # macosx doesn't like this
- runpipe.fromchild.flush()
- except IOError:
- pass
- line = runpipe.fromchild.readline()
- cmdstat = -1
- while cmdstat == -1:
- while line:
- if len(line) > 0:
- self.logger.debug('< %s' % line[:-1])
- output.append(line[:-1])
- line = runpipe.fromchild.readline()
- time.sleep(0.1)
- cmdstat = runpipe.poll()
- output += [line[:-1] for line in runpipe.fromchild.readlines() \
- if line]
- # The exit code from the program is in the upper byte of the
- # value returned by cmdstat. Shift it down for tools looking at
- # the value.
- return ((cmdstat >> 8), output)
+ p = Popen(command, shell=True, bufsize=16384,
+ stdin=PIPE, stdout=PIPE, close_fds=True)
+ output = p.communicate()[0]
+ for line in output.splitlines():
+ self.logger.debug('< %s' % line)
+ return (p.returncode, output.splitlines())
class Tool:
diff --git a/src/lib/Component.py b/src/lib/Component.py
index 33b1c9289..88dce906e 100644
--- a/src/lib/Component.py
+++ b/src/lib/Component.py
@@ -11,12 +11,12 @@ import pydoc
import sys
import time
import threading
-import urlparse
-import xmlrpclib
import Bcfg2.Logger
from Bcfg2.Statistics import Statistics
from Bcfg2.SSLServer import XMLRPCServer
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import xmlrpclib, urlparse, fprint
logger = logging.getLogger()
@@ -56,11 +56,11 @@ def run_component(component_cls, location, daemon, pidfile_name, to_file,
os.chdir(os.sep)
pidfile = open(pidfile_name or "/dev/null", "w")
- print >> pidfile, os.getpid()
+ fprint(os.getpid(), pidfile)
pidfile.close()
component = component_cls(cfile=cfile, **cls_kwargs)
- up = urlparse.urlparse(location)
+ up = urlparse(location)
port = tuple(up[1].split(':'))
port = (port[0], int(port[1]))
try:
@@ -153,30 +153,31 @@ class Component (object):
automatic == True.
"""
- for name, func in inspect.getmembers(self, callable):
- if getattr(func, "automatic", False):
- need_to_lock = not getattr(func, 'locking', False)
- if (time.time() - func.automatic_ts) > \
- func.automatic_period:
- if need_to_lock:
- t1 = time.time()
- self.lock.acquire()
- t2 = time.time()
- self.instance_statistics.add_value('component_lock', t2-t1)
- try:
- mt1 = time.time()
+ for name, func in inspect.getmembers(self):
+ if name == '__call__':
+ if getattr(func, "automatic", False):
+ need_to_lock = not getattr(func, 'locking', False)
+ if (time.time() - func.automatic_ts) > \
+ func.automatic_period:
+ if need_to_lock:
+ t1 = time.time()
+ self.lock.acquire()
+ t2 = time.time()
+ self.instance_statistics.add_value('component_lock', t2-t1)
try:
- func()
- except:
- self.logger.error("Automatic method %s failed" \
- % (name), exc_info=1)
- finally:
- mt2 = time.time()
-
- if need_to_lock:
- self.lock.release()
- self.instance_statistics.add_value(name, mt2-mt1)
- func.__dict__['automatic_ts'] = time.time()
+ mt1 = time.time()
+ try:
+ func()
+ except:
+ self.logger.error("Automatic method %s failed" \
+ % (name), exc_info=1)
+ finally:
+ mt2 = time.time()
+
+ if need_to_lock:
+ self.lock.release()
+ self.instance_statistics.add_value(name, mt2-mt1)
+ func.__dict__['automatic_ts'] = time.time()
def _resolve_exposed_method(self, method_name):
"""Resolve an exposed method.
@@ -209,7 +210,8 @@ class Component (object):
except NoExposedMethod:
self.logger.error("Unknown method %s" % (method))
raise xmlrpclib.Fault(7, "Unknown method %s" % method)
- except Exception, e:
+ except Exception:
+ e = sys.exc_info()[1]
if getattr(e, "log", True):
self.logger.error(e, exc_info=True)
raise xmlrpclib.Fault(getattr(e, "fault_code", 1), str(e))
@@ -233,7 +235,8 @@ class Component (object):
self.instance_statistics.add_value(method, method_done - method_start)
except xmlrpclib.Fault:
raise
- except Exception, e:
+ except Exception:
+ e = sys.exc_info()[1]
if getattr(e, "log", True):
self.logger.error(e, exc_info=True)
raise xmlrpclib.Fault(getattr(e, "fault_code", 1), str(e))
diff --git a/src/lib/Logger.py b/src/lib/Logger.py
index ae73a6d41..b49a7069f 100644
--- a/src/lib/Logger.py
+++ b/src/lib/Logger.py
@@ -10,6 +10,8 @@ import socket
import struct
import sys
import termios
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import fprint
logging.raiseExceptions = 0
@@ -116,7 +118,7 @@ class FragmentingSysLogHandler(logging.handlers.SysLogHandler):
def emit(self, record):
"""Chunk and deliver records."""
record.name = self.procname
- if str(record.msg) > 250:
+ if len(record.msg) > 250:
msgs = []
error = record.exc_info
record.exc_info = None
@@ -134,7 +136,7 @@ class FragmentingSysLogHandler(logging.handlers.SysLogHandler):
newrec.levelname.lower()),
self.format(newrec))
try:
- self.socket.send(msg)
+ self.socket.send(msg.encode('ascii'))
except socket.error:
for i in range(10):
try:
@@ -229,7 +231,7 @@ def trace_process(**kwargs):
filename = filename[:-1]
name = frame.f_globals["__name__"]
line = linecache.getline(filename, lineno)
- print >> log_file, "%s:%s: %s" % (name, lineno, line.rstrip())
+ fprint("%s:%s: %s" % (name, lineno, line.rstrip()), log_file)
return traceit
sys.settrace(traceit)
diff --git a/src/lib/Options.py b/src/lib/Options.py
index 1973e7091..d5304e696 100644
--- a/src/lib/Options.py
+++ b/src/lib/Options.py
@@ -1,11 +1,12 @@
"""Option parsing library for utilities."""
__revision__ = '$Revision$'
-import ConfigParser
import getopt
import os
import sys
import Bcfg2.Client.Tools
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import ConfigParser
def bool_cook(x):
if x:
@@ -146,7 +147,8 @@ class OptionSet(dict):
try:
opts, args = getopt.getopt(argv, self.buildGetopt(),
self.buildLongGetopt())
- except getopt.GetoptError, err:
+ except getopt.GetoptError:
+ err = sys.exc_info()[1]
self.helpExit(err)
if '-h' in argv:
self.helpExit('', 0)
diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py
index 8b3fcb87c..8a1ad683e 100644
--- a/src/lib/Proxy.py
+++ b/src/lib/Proxy.py
@@ -11,9 +11,6 @@ load_config -- read configuration files
__revision__ = '$Revision: $'
-from xmlrpclib import _Method
-
-import httplib
import logging
import re
import socket
@@ -25,7 +22,7 @@ import socket
try:
import ssl
SSL_LIB = 'py26_ssl'
-except ImportError, e:
+except ImportError:
from M2Crypto import SSL
import M2Crypto.SSL.Checker
SSL_LIB = 'm2crypto'
@@ -33,8 +30,9 @@ except ImportError, e:
import sys
import time
-import urlparse
-import xmlrpclib
+
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import httplib, xmlrpclib, urlparse
version = sys.version_info[:2]
has_py23 = version >= (2, 3)
@@ -51,7 +49,7 @@ class CertificateError(Exception):
self.commonName = commonName
-class RetryMethod(_Method):
+class RetryMethod(xmlrpclib._Method):
"""Method with error handling and retries built in."""
log = logging.getLogger('xmlrpc')
max_retries = 4
@@ -59,21 +57,24 @@ class RetryMethod(_Method):
def __call__(self, *args):
for retry in range(self.max_retries):
try:
- return _Method.__call__(self, *args)
- except xmlrpclib.ProtocolError, err:
+ return xmlrpclib._Method.__call__(self, *args)
+ except xmlrpclib.ProtocolError:
+ err = sys.exc_info()[1]
self.log.error("Server failure: Protocol Error: %s %s" % \
(err.errcode, err.errmsg))
raise xmlrpclib.Fault(20, "Server Failure")
except xmlrpclib.Fault:
raise
- except socket.error, err:
+ except socket.error:
+ err = sys.exc_info()[1]
if hasattr(err, 'errno') and err.errno == 336265218:
self.log.error("SSL Key error")
break
if retry == 3:
self.log.error("Server failure: %s" % err)
raise xmlrpclib.Fault(20, err)
- except CertificateError, ce:
+ except CertificateError:
+ ce = sys.exc_info()[1]
self.log.error("Got unallowed commonName %s from server" \
% ce.commonName)
break
@@ -87,7 +88,7 @@ class RetryMethod(_Method):
raise xmlrpclib.Fault(20, "Server Failure")
# sorry jon
-xmlrpclib._Method = RetryMethod
+_Method = RetryMethod
class SSLHTTPConnection(httplib.HTTPConnection):
@@ -242,7 +243,8 @@ class SSLHTTPConnection(httplib.HTTPConnection):
try:
self.sock.connect((hostname, self.port))
# automatically checks cert matches host
- except M2Crypto.SSL.Checker.WrongHost, wr:
+ except M2Crypto.SSL.Checker.WrongHost:
+ wr = sys.exc_info()[1]
raise CertificateError(wr)
@@ -325,7 +327,7 @@ def ComponentProxy(url, user=None, password=None,
"""
if user and password:
- method, path = urlparse.urlparse(url)[:2]
+ method, path = urlparse(url)[:2]
newurl = "%s://%s:%s@%s" % (method, user, password, path)
else:
newurl = url
diff --git a/src/lib/SSLServer.py b/src/lib/SSLServer.py
index 2395bb84f..a89beabbb 100644
--- a/src/lib/SSLServer.py
+++ b/src/lib/SSLServer.py
@@ -8,10 +8,7 @@ __all__ = [
import os
import sys
-import xmlrpclib
import socket
-import SocketServer
-import SimpleXMLRPCServer
import base64
import select
import signal
@@ -19,6 +16,8 @@ import logging
import ssl
import threading
import time
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import xmlrpclib, SimpleXMLRPCServer, SocketServer
class ForkedChild(Exception):
@@ -51,7 +50,8 @@ class XMLRPCDispatcher (SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
raw_response = xmlrpclib.dumps(response, methodresponse=1,
allow_none=self.allow_none,
encoding=self.encoding)
- except xmlrpclib.Fault, fault:
+ except xmlrpclib.Fault:
+ fault = sys.exc_info()[1]
raw_response = xmlrpclib.dumps(fault,
allow_none=self.allow_none,
encoding=self.encoding)
@@ -258,7 +258,8 @@ class XMLRPCRequestHandler (SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
# If we hit SSL3_WRITE_PENDING here try to resend.
self.wfile.write(response)
break
- except ssl.SSLError, e:
+ except ssl.SSLError:
+ e = sys.exc_info()[1]
if str(e).find("SSL3_WRITE_PENDING") < 0:
raise
self.logger.error("SSL3_WRITE_PENDING")
diff --git a/src/lib/Server/Admin/Init.py b/src/lib/Server/Admin/Init.py
index 9771fd10b..e69412a5e 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,8 +156,9 @@ def create_conf(confpath, confdata):
return
try:
open(confpath, "w").write(confdata)
- os.chmod(keypath, stat.S_IRUSR|stat.S_IWUSR) # 0600
- except Exception, e:
+ os.chmod(keypath, stat.S_IRUSR | stat.S_IWUSR) # 0600
+ except Exception:
+ e = sys.exc_info()[1]
print("Error %s occured while trying to write configuration "
"file to '%s'.\n" %
(e, confpath))
@@ -381,7 +382,8 @@ class Init(Bcfg2.Server.Admin.Mode):
'', ["Bcfg2.Server.Plugins"])
cls = getattr(module, plugin)
cls.init_repo(self.repopath)
- except Exception, e:
+ except Exception:
+ e = sys.exc_info()[1]
print("Plugin setup for %s failed: %s\n"
"Check that dependencies are installed?" % (plugin, e))
diff --git a/src/lib/Server/Admin/Query.py b/src/lib/Server/Admin/Query.py
index 207b65035..9e1d7cc88 100644
--- a/src/lib/Server/Admin/Query.py
+++ b/src/lib/Server/Admin/Query.py
@@ -26,7 +26,8 @@ class Query(Bcfg2.Server.Admin.Mode):
self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(),
['Metadata', 'Probes'],
'foo', False, 'UTF-8')
- except Bcfg2.Server.Core.CoreInitError, msg:
+ except Bcfg2.Server.Core.CoreInitError:
+ msg = sys.exc_info()[1]
self.errExit("Core load failed because %s" % msg)
self.bcore.fam.handle_events_in_interval(1)
self.meta = self.bcore.metadata
diff --git a/src/lib/Server/Admin/Reports.py b/src/lib/Server/Admin/Reports.py
index ee3a4473f..942477a49 100644
--- a/src/lib/Server/Admin/Reports.py
+++ b/src/lib/Server/Admin/Reports.py
@@ -1,7 +1,6 @@
'''Admin interface for dynamic reports'''
import Bcfg2.Logger
import Bcfg2.Server.Admin
-import ConfigParser
import datetime
import os
import logging
@@ -14,6 +13,9 @@ from Bcfg2.Server.Reports.updatefix import update_database
from Bcfg2.Server.Reports.utils import *
from lxml.etree import XML, XMLSyntaxError
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import ConfigParser
+
# FIXME: Remove when server python dep is 2.5 or greater
if sys.version_info >= (2, 5):
from hashlib import md5
@@ -26,7 +28,8 @@ import django.core.management
# FIXME - settings file uses a hardcoded path for /etc/bcfg2.conf
try:
import Bcfg2.Server.Reports.settings
-except Exception, e:
+except Exception:
+ e = sys.exc_info()[1]
sys.stderr.write("Failed to load configuration settings. %s\n" % e)
sys.exit(1)
@@ -185,7 +188,8 @@ class Reports(Bcfg2.Server.Admin.Mode):
# Currently only reasons are a problem
try:
start_count = Reason.objects.count()
- except Exception, e:
+ except Exception:
+ e = sys.exc_info()[1]
self.log.error("Failed to load reason objects: %s" % e)
return
dup_reasons = []
@@ -216,7 +220,8 @@ class Reports(Bcfg2.Server.Admin.Mode):
cursor.executemany('update reports_entries_interactions set reason_id=%s where reason_id=%s', batch_update)
cursor.executemany('delete from reports_reason where id = %s', dup_reasons)
transaction.set_dirty()
- except Exception, ex:
+ except Exception:
+ ex = sys.exc_info()[1]
self.log.error("Failed to delete reasons: %s" % ex)
raise
diff --git a/src/lib/Server/Admin/Snapshots.py b/src/lib/Server/Admin/Snapshots.py
index d58873174..052545b61 100644
--- a/src/lib/Server/Admin/Snapshots.py
+++ b/src/lib/Server/Admin/Snapshots.py
@@ -8,6 +8,8 @@ import Bcfg2.Server.Snapshots
import Bcfg2.Server.Snapshots.model
from Bcfg2.Server.Snapshots.model import Snapshot, Client, Metadata, Base, \
File, Group, Package, Service
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import u_str
class Snapshots(Bcfg2.Server.Admin.Mode):
__shorthelp__ = "Interact with the Snapshots system"
@@ -71,7 +73,7 @@ class Snapshots(Bcfg2.Server.Admin.Mode):
session.commit()
elif args[0] == 'dump':
client = args[1]
- snap = Snapshot.get_current(self.session, unicode(client))
+ snap = Snapshot.get_current(self.session, u_str(client))
if not snap:
print("Current snapshot for %s not found" % client)
sys.exit(1)
@@ -105,7 +107,7 @@ class Snapshots(Bcfg2.Server.Admin.Mode):
print("Usage: bcfg2-admin snapshots -b <client>")
return
client = args[2]
- snap = Snapshot.get_current(self.session, unicode(client))
+ snap = Snapshot.get_current(self.session, u_str(client))
if not snap:
print("Current snapshot for %s not found" % client)
sys.exit(1)
@@ -128,7 +130,7 @@ class Snapshots(Bcfg2.Server.Admin.Mode):
elif '-e' in args[1:]:
# Query a single host for extra entries
client = args[2]
- snap = Snapshot.get_current(self.session, unicode(client))
+ snap = Snapshot.get_current(self.session, u_str(client))
if not snap:
print("Current snapshot for %s not found" % client)
sys.exit(1)
diff --git a/src/lib/Server/Admin/Viz.py b/src/lib/Server/Admin/Viz.py
index a77502b5d..f39e6d7a8 100644
--- a/src/lib/Server/Admin/Viz.py
+++ b/src/lib/Server/Admin/Viz.py
@@ -45,7 +45,8 @@ class Viz(Bcfg2.Server.Admin.MetadataCore):
opts, args = getopt.getopt(args, 'Hbko:',
['includehosts', 'includebundles',
'includekey', 'outfile='])
- except getopt.GetoptError, msg:
+ except getopt.GetoptError:
+ msg = sys.exc_info()[1]
print(msg)
#FIXME: is this for --raw?
diff --git a/src/lib/Server/Admin/Xcmd.py b/src/lib/Server/Admin/Xcmd.py
index e761a5e3d..fd5794f88 100644
--- a/src/lib/Server/Admin/Xcmd.py
+++ b/src/lib/Server/Admin/Xcmd.py
@@ -1,10 +1,12 @@
import sys
-import xmlrpclib
import Bcfg2.Options
import Bcfg2.Proxy
import Bcfg2.Server.Admin
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import xmlrpclib
+
class Xcmd(Bcfg2.Server.Admin.Mode):
__shorthelp__ = ("XML-RPC Command Interface")
@@ -39,7 +41,8 @@ class Xcmd(Bcfg2.Server.Admin.Mode):
args = tuple(setup['args'][1:])
try:
data = getattr(proxy, cmd)(*args)
- except xmlrpclib.Fault, flt:
+ except xmlrpclib.Fault:
+ flt = sys.exc_info()[1]
if flt.faultCode == 7:
print("Unknown method %s" % cmd)
return
diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py
index 411f909ee..8915492a3 100644
--- a/src/lib/Server/Admin/__init__.py
+++ b/src/lib/Server/Admin/__init__.py
@@ -19,13 +19,14 @@ __all__ = [
'Xcmd'
]
-import ConfigParser
import logging
import lxml.etree
import sys
import Bcfg2.Server.Core
import Bcfg2.Options
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import ConfigParser
class ModeOperationError(Exception):
@@ -126,7 +127,8 @@ class MetadataCore(Mode):
self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(),
setup['plugins'],
'foo', 'UTF-8')
- except Bcfg2.Server.Core.CoreInitError, msg:
+ except Bcfg2.Server.Core.CoreInitError:
+ msg = sys.exc_info()[1]
self.errExit("Core load failed because %s" % msg)
self.bcore.fam.handle_events_in_interval(5)
self.metadata = self.bcore.metadata
diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py
index e82e05a89..ac0a51e23 100644
--- a/src/lib/Server/Core.py
+++ b/src/lib/Server/Core.py
@@ -5,14 +5,18 @@ import atexit
import logging
import lxml.etree
import select
+import sys
import threading
import time
-import xmlrpclib
from Bcfg2.Component import Component, exposed
from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError
import Bcfg2.Server.FileMonitor
import Bcfg2.Server.Plugins.Metadata
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import xmlrpclib
+if sys.hexversion >= 0x03000000:
+ from functools import reduce
logger = logging.getLogger('Bcfg2.Server.Core')
@@ -142,7 +146,7 @@ class Core(Component):
try:
mod = getattr(__import__("Bcfg2.Server.Plugins.%s" %
(plugin)).Server.Plugins, plugin)
- except ImportError, e:
+ except ImportError:
try:
mod = __import__(plugin)
except:
@@ -177,7 +181,8 @@ class Core(Component):
plugin.validate_structures(metadata, data)
elif base_cls == Bcfg2.Server.Plugin.GoalValidator:
plugin.validate_goals(metadata, data)
- except Bcfg2.Server.Plugin.ValidationError, err:
+ except Bcfg2.Server.Plugin.ValidationError:
+ err = sys.exc_info()[1]
logger.error("Plugin %s structure validation failed: %s" \
% (plugin.name, err.message))
raise
diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py
index 6351a9eb1..cd2b63656 100644
--- a/src/lib/Server/Plugin.py
+++ b/src/lib/Server/Plugin.py
@@ -18,6 +18,9 @@ import Bcfg2.Options
# py3k compatibility
if sys.hexversion >= 0x03000000:
from functools import reduce
+ from io import FileIO as BUILTIN_FILE_TYPE
+else:
+ BUILTIN_FILE_TYPE = file
from Bcfg2.Bcfg2Py3k import Queue
from Bcfg2.Bcfg2Py3k import Empty
from Bcfg2.Bcfg2Py3k import Full
@@ -346,7 +349,7 @@ class FileBacked(object):
if event and event.code2str() not in ['exists', 'changed', 'created']:
return
try:
- self.data = file(self.name).read()
+ self.data = BUILTIN_FILE_TYPE(self.name).read()
self.Index()
except IOError:
logger.error("Failed to read file %s" % (self.name))
@@ -577,7 +580,7 @@ class XMLSrc(XMLFileBacked):
def HandleEvent(self, _=None):
"""Read file upon update."""
try:
- data = file(self.name).read()
+ data = BUILTIN_FILE_TYPE(self.name).read()
except IOError:
logger.error("Failed to read file %s" % (self.name))
return
diff --git a/src/lib/Server/Plugins/Packages.py b/src/lib/Server/Plugins/Packages.py
index 1178aadaa..19152074e 100644
--- a/src/lib/Server/Plugins/Packages.py
+++ b/src/lib/Server/Plugins/Packages.py
@@ -17,6 +17,12 @@ from Bcfg2.Bcfg2Py3k import install_opener
from Bcfg2.Bcfg2Py3k import build_opener
from Bcfg2.Bcfg2Py3k import urlopen
+# py3k compatibility
+if sys.hexversion >= 0x03000000:
+ from io import FileIO as BUILTIN_FILE_TYPE
+else:
+ BUILTIN_FILE_TYPE = file
+
# FIXME: Remove when server python dep is 2.5 or greater
if sys.version_info >= (2, 5):
from hashlib import md5
@@ -177,7 +183,7 @@ class Source(object):
logger.error("Packages: Failed to fetch url %s. code=%s" \
% (url, h.code))
continue
- file(fname, 'w').write(data)
+ BUILTIN_FILE_TYPE(fname, 'w').write(data)
def applies(self, metadata):
return len([g for g in self.basegroups if g in metadata.groups]) != 0 and \
@@ -231,13 +237,13 @@ class YUMSource(Source):
self.file_to_arch = dict()
def save_state(self):
- cache = file(self.cachefile, 'wb')
+ cache = BUILTIN_FILE_TYPE(self.cachefile, 'wb')
cPickle.dump((self.packages, self.deps, self.provides,
self.filemap, self.url_map), cache, 2)
cache.close()
def load_state(self):
- data = file(self.cachefile)
+ data = BUILTIN_FILE_TYPE(self.cachefile)
(self.packages, self.deps, self.provides, \
self.filemap, self.url_map) = cPickle.load(data)
@@ -378,13 +384,13 @@ class APTSource(Source):
'components': self.components, 'arches': self.arches, 'groups': self.groups}]
def save_state(self):
- cache = file(self.cachefile, 'wb')
+ cache = BUILTIN_FILE_TYPE(self.cachefile, 'wb')
cPickle.dump((self.pkgnames, self.deps, self.provides),
cache, 2)
cache.close()
def load_state(self):
- data = file(self.cachefile)
+ data = BUILTIN_FILE_TYPE(self.cachefile)
self.pkgnames, self.deps, self.provides = cPickle.load(data)
def filter_unknown(self, unknown):
@@ -423,7 +429,7 @@ class APTSource(Source):
print("Failed to read file %s" % fname)
raise
for line in reader.readlines():
- words = line.strip().split(':', 1)
+ words = line.strip().split(b':', 1)
if words[0] == 'Package':
pkgname = words[1].strip().rstrip()
self.pkgnames.add(pkgname)
@@ -500,13 +506,13 @@ class PACSource(Source):
'components': self.components, 'arches': self.arches, 'groups': self.groups}]
def save_state(self):
- cache = file(self.cachefile, 'wb')
+ cache = BUILTIN_FILE_TYPE(self.cachefile, 'wb')
cPickle.dump((self.pkgnames, self.deps, self.provides),
cache, 2)
cache.close()
def load_state(self):
- data = file(self.cachefile)
+ data = BUILTIN_FILE_TYPE(self.cachefile)
self.pkgnames, self.deps, self.provides = cPickle.load(data)
def filter_unknown(self, unknown):
diff --git a/src/lib/Server/Plugins/TGenshi.py b/src/lib/Server/Plugins/TGenshi.py
index cd268e967..83b60c958 100644
--- a/src/lib/Server/Plugins/TGenshi.py
+++ b/src/lib/Server/Plugins/TGenshi.py
@@ -98,7 +98,7 @@ class TemplateFile:
entry.text = textdata
else:
if entry.get('encoding') == 'base64':
- # take care of case where file needs base64 encoding
+ # take care of case where file needs base64 encoding
entry.text = binascii.b2a_base64(textdata)
else:
entry.text = unicode(textdata, self.encoding)
diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2
index 56f98ade4..7f7d8f5c6 100755
--- a/src/sbin/bcfg2
+++ b/src/sbin/bcfg2
@@ -3,18 +3,20 @@
"""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
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import xmlrpclib
import Bcfg2.Proxy
import Bcfg2.Logger
@@ -135,7 +137,9 @@ 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_IRGRP | stat.S_IROTH |
+ stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH |
+ stat.S_IWUSR) # 0755
ret.text = os.popen(script.name).read().strip()
self.logger.info("Probe %s has result:\n%s" % (name, ret.text))
finally:
@@ -188,7 +192,8 @@ class Client:
try:
probe_data = proxy.GetProbes()
- except xmlrpclib.Fault, flt:
+ except xmlrpclib.Fault:
+ flt = sys.exc_info()[1]
self.logger.error("Failed to download probes from bcfg2")
self.logger.error(flt.faultString)
raise SystemExit(1)
@@ -197,7 +202,8 @@ class Client:
try:
probes = Bcfg2.Client.XML.XML(probe_data)
- except Bcfg2.Client.XML.ParseError, syntax_error:
+ except Bcfg2.Client.XML.ParseError:
+ syntax_error = sys.exc_info()[1]
self.fatal_error(
"Server returned invalid probe requests: %s" %
(syntax_error))
@@ -228,7 +234,8 @@ class Client:
self.setup['decision'])
self.logger.info("Got decision list from server:")
self.logger.info(self.setup['decision_list'])
- except xmlrpclib.Fault, f:
+ except xmlrpclib.Fault:
+ f = sys.exc_info()[1]
if f.faultCode == 1:
print("GetDecisionList method not supported by server")
else:
@@ -254,7 +261,8 @@ class Client:
try:
self.config = Bcfg2.Client.XML.XML(rawconfig)
- except Bcfg2.Client.XML.ParseError, syntax_error:
+ except Bcfg2.Client.XML.ParseError:
+ syntax_error = sys.exc_info()[1]
self.fatal_error("The configuration could not be parsed: %s" %
(syntax_error))
return(1)
diff --git a/src/sbin/bcfg2-admin b/src/sbin/bcfg2-admin
index 2c9a43859..36be6ab14 100755
--- a/src/sbin/bcfg2-admin
+++ b/src/sbin/bcfg2-admin
@@ -2,11 +2,12 @@
"""bcfg2-admin is a script that helps to administrate a Bcfg2 deployment."""
from optparse import OptionParser
-from StringIO import StringIO
import logging
import Bcfg2.Server.Core
import Bcfg2.Logger
import Bcfg2.Options
+# Compatibility import
+from Bcfg2.Bcfg2Py3k import StringIO
log = logging.getLogger('bcfg2-admin')
@@ -56,14 +57,15 @@ 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():
modname = args[0].capitalize()
try:
mode_cls = mode_import(modname)
- except ImportError, e:
+ except ImportError:
+ e = sys.exc_info()[1]
log.error("Failed to load admin mode %s: %s" % (modname, e))
raise SystemExit(1)
mode = mode_cls(options.configfile)
@@ -73,7 +75,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..7122fb300 100755
--- a/src/sbin/bcfg2-build-reports
+++ b/src/sbin/bcfg2-build-reports
@@ -13,8 +13,9 @@ import os
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
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import ConfigParser
def generatereport(rspec, nrpt):
"""
@@ -42,9 +43,9 @@ def generatereport(rspec, nrpt):
# This line actually sorts from most recent to oldest.
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")
@@ -52,7 +53,7 @@ def generatereport(rspec, nrpt):
[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")
@@ -64,7 +65,7 @@ def mail(mailbody, confi):
try:
mailer = confi.get('statistics', 'sendmailpath')
- except (NoSectionError, NoOptionError):
+ except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
mailer = "/usr/sbin/sendmail"
# Open a pipe to the mail program and
# write the data to the pipe.
@@ -72,7 +73,7 @@ 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 +99,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"
@@ -119,7 +120,7 @@ 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')
@@ -138,15 +139,15 @@ 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()])),
+ 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 = (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
@@ -157,14 +158,14 @@ if __name__ == '__main__':
cfpath = sys.argv[sys.argv.index('-C') + 1]
else:
cfpath = '/etc/bcfg2.conf'
- c = ConfigParser()
+ c = ConfigParser.ConfigParser()
c.read([cfpath])
configpath = "%s/etc/report-configuration.xml" % c.get('server', 'repository')
statpath = "%s/etc/statistics.xml" % c.get('server', 'repository')
clientsdatapath = "%s/Metadata/clients.xml" % c.get('server', 'repository')
try:
prefix = c.get('server', 'prefix')
- except (NoSectionError, NoOptionError):
+ except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
prefix = '/usr'
transformpath = "/%s/share/bcfg2/xsl-transforms/" % (prefix)
@@ -172,13 +173,14 @@ if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], "C:hAc:Ns:", ["help", "all", "config=","no-ping", "stats="])
- except getopt.GetoptError, mesg:
+ except getopt.GetoptError:
+ mesg = sys.exc_info()[1]
# 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:\nbcfg2-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
@@ -205,17 +207,17 @@ if __name__ == '__main__':
statsdata = XML(open(statpath).read())
except (IOError, XMLSyntaxError):
print("bcfg2-build-reports: Failed to parse %s"%(statpath))
- raise SystemExit, 1
+ raise SystemExit(1)
try:
configdata = XML(open(configpath).read())
except (IOError, XMLSyntaxError):
print("bcfg2-build-reports: Failed to parse %s"%(configpath))
- raise SystemExit, 1
+ raise SystemExit(1)
try:
clientsdata = XML(open(clientsdatapath).read())
except (IOError, XMLSyntaxError):
print("bcfg2-build-reports: Failed to parse %s"%(clientsdatapath))
- raise SystemExit, 1
+ raise SystemExit(1)
# Merge data from three sources.
nodereport = Element("Report", attrib={"time" : asctime()})
@@ -229,7 +231,7 @@ if __name__ == '__main__':
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"):
@@ -242,8 +244,8 @@ if __name__ == '__main__':
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"))
@@ -254,7 +256,7 @@ if __name__ == '__main__':
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')
@@ -269,14 +271,14 @@ if __name__ == '__main__':
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.
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,7 +287,7 @@ 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"):
@@ -295,13 +297,13 @@ if __name__ == '__main__':
outputstring = "To: %s\nFrom: root@%s\n%s"% \
(toastring, socket.getfqdn(), outputstring)
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"):
diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info
index a6d236bc8..161fee441 100755
--- a/src/sbin/bcfg2-info
+++ b/src/sbin/bcfg2-info
@@ -27,6 +27,40 @@ import Bcfg2.Server.Plugins.Metadata
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):
@@ -75,7 +109,8 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core):
encoding)
if event_debug:
self.fam.debug = True
- except Bcfg2.Server.Core.CoreInitError, msg:
+ except Bcfg2.Server.Core.CoreInitError:
+ msg = sys.exc_info()[1]
print("Core load failed because %s" % msg)
raise SystemExit(1)
self.prompt = '> '
@@ -89,7 +124,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core):
try:
self.cmdloop('Welcome to bcfg2-info\n'
'Type "help" for more information')
- except SystemExit, val:
+ except SystemExit:
raise
except Bcfg2.Server.Plugin.PluginExecutionError:
continue
@@ -106,7 +141,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 +171,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 +180,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 +213,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,7 +242,7 @@ 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.')
self.help_builddir()
@@ -262,7 +266,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))
@@ -371,22 +375,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 +406,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-lint b/src/sbin/bcfg2-lint
index e6a530408..18632e316 100755
--- a/src/sbin/bcfg2-lint
+++ b/src/sbin/bcfg2-lint
@@ -6,11 +6,12 @@ __revision__ = '$Revision$'
import sys
import inspect
import logging
-import ConfigParser
import Bcfg2.Logger
import Bcfg2.Options
import Bcfg2.Server.Core
import Bcfg2.Server.Lint
+# Compatibility imports
+from Bcfg2.Bcfg2Py3k import ConfigParser
logger = logging.getLogger('bcfg2-lint')
@@ -29,7 +30,7 @@ class Parser(ConfigParser.ConfigParser):
def run_serverless_plugins(plugins, config=None, setup=None):
logger.debug("Running serverless plugins")
errors = (0, 0)
- for plugin_name, plugin in plugins.items():
+ for plugin_name, plugin in list(plugins.items()):
plugin_errors = run_plugin(plugin, plugin_name,
setup=setup, config=config, files=files)
errors = [errors[n] + plugin_errors[n]
@@ -40,7 +41,7 @@ def run_server_plugins(plugins, config=None, setup=None):
core = load_server(setup)
logger.debug("Running server plugins")
errors = (0, 0)
- for plugin_name, plugin in plugins.items():
+ for plugin_name, plugin in list(plugins.items()):
plugin_errors = run_plugin(plugin, plugin_name, args=[core],
setup=setup, config=config, files=files)
errors = [errors[n] + plugin_errors[n]
@@ -140,7 +141,8 @@ if __name__ == '__main__':
except ImportError:
try:
mod = __import__(plugin_name)
- except Exception, err:
+ except Exception:
+ err = sys.exc_info()[1]
logger.error("Failed to load plugin %s: %s" % (plugin_name,
err))
raise SystemExit(1)
@@ -160,8 +162,8 @@ if __name__ == '__main__':
errors = [errors[n] + perrors[n] for n in range(0, len(errors))]
if errors[0] or errors[1] or setup['verbose']:
- print "%d errors" % errors[0]
- print "%d warnings" % errors[1]
+ print("%d errors" % errors[0])
+ print("%d warnings" % errors[1])
if errors[0]:
raise SystemExit(2)
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-reports b/src/sbin/bcfg2-reports
index 559e9fb43..20288fc5e 100755
--- a/src/sbin/bcfg2-reports
+++ b/src/sbin/bcfg2-reports
@@ -93,13 +93,13 @@ 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 = ""
@@ -137,14 +137,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 +170,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,7 +185,7 @@ 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:
diff --git a/src/sbin/bcfg2-server b/src/sbin/bcfg2-server
index cf44f1699..f4bd5e5b7 100755
--- a/src/sbin/bcfg2-server
+++ b/src/sbin/bcfg2-server
@@ -69,7 +69,8 @@ if __name__ == '__main__':
certfile=setup['cert'],
ca=setup['ca'],
)
- except CoreInitError, msg:
+ except CoreInitError:
+ msg = sys.exc_info()[1]
logger.error(msg)
logger.error("exiting")
sys.exit(1)