diff options
Diffstat (limited to 'src/sbin')
-rwxr-xr-x | src/sbin/bcfg2 | 1 | ||||
-rwxr-xr-x | src/sbin/bcfg2-admin | 6 | ||||
-rwxr-xr-x | src/sbin/bcfg2-build-reports | 2 | ||||
-rwxr-xr-x | src/sbin/bcfg2-info | 202 | ||||
-rwxr-xr-x | src/sbin/bcfg2-lint | 33 | ||||
-rwxr-xr-x | src/sbin/bcfg2-ping-sweep | 2 | ||||
-rwxr-xr-x | src/sbin/bcfg2-reports | 1 | ||||
-rwxr-xr-x | src/sbin/bcfg2-server | 45 | ||||
-rwxr-xr-x | src/sbin/bcfg2-test | 4 | ||||
-rwxr-xr-x | src/sbin/bcfg2-yum-helper | 2 |
10 files changed, 180 insertions, 118 deletions
diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 1d1cc8424..fb34e627b 100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -1,7 +1,6 @@ #!/usr/bin/env python """Bcfg2 Client""" -__revision__ = '$Revision$' import fcntl import logging diff --git a/src/sbin/bcfg2-admin b/src/sbin/bcfg2-admin index 5cb69d747..007dd0af3 100755 --- a/src/sbin/bcfg2-admin +++ b/src/sbin/bcfg2-admin @@ -3,7 +3,6 @@ import sys import logging -import Bcfg2.Server.Core import Bcfg2.Logger import Bcfg2.Options import Bcfg2.Server.Admin @@ -31,7 +30,7 @@ def create_description(): for mode in modes: try: description.write((" %-15s %s\n" % - (mode, mode_import(mode).__shorthelp__))) + (mode, mode_import(mode).__shorthelp__))) except (ImportError, SystemExit): pass return description.getvalue() @@ -50,8 +49,7 @@ def main(): } setup = Bcfg2.Options.OptionParser(optinfo) # override default help message to include description of all modes - setup.hm = "Usage:\n %s\n%s" % (setup.buildHelpMessage(), - create_description()) + setup.hm = "%s\n%s" % (setup.buildHelpMessage(), create_description()) setup.parse(sys.argv[1:]) log_args = dict(to_syslog=False, to_console=logging.WARNING) diff --git a/src/sbin/bcfg2-build-reports b/src/sbin/bcfg2-build-reports index 7122fb300..7fa08110a 100755 --- a/src/sbin/bcfg2-build-reports +++ b/src/sbin/bcfg2-build-reports @@ -4,8 +4,6 @@ bcfg2-build-reports generates & distributes reports of statistic information for Bcfg2.""" -__revision__ = '$Revision$' - import copy import getopt import re diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index e09b7ed87..8598a58eb 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -1,17 +1,16 @@ #!/usr/bin/env python - """This tool loads the Bcfg2 core into an interactive debugger.""" -__revision__ = '$Revision$' -from code import InteractiveConsole +import os +import sys import cmd import errno import getopt +import fnmatch import logging -import lxml.etree -import os -import sys import tempfile +import lxml.etree +from code import InteractiveConsole try: try: @@ -34,7 +33,8 @@ 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 +buildall <directory> [<hostnames*>] - Build configs for all clients in directory +buildallfile <directory> <filename> [<hostnames*>] - Build config file for all clients in directory buildfile <filename> <hostname> - Build config file for hostname (not written to disk) buildbundle <bundle> <hostname> - Render a templated bundle for hostname (not written to disk) bundles - Print out group/bundle information @@ -51,8 +51,7 @@ 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""" +update - Process pending file events""" BUILDDIR_USAGE = """Usage: builddir [-f] <hostname> <output dir> @@ -78,10 +77,12 @@ 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): @@ -90,6 +91,30 @@ class FileNotBuilt(Exception): def __str__(self): return repr(self.value) + +def getClientList(hostglobs): + """ given a host glob, get a list of clients that match it """ + # special cases to speed things up: + if '*' in hostglobs: + return list(self.metadata.clients.keys()) + has_wildcards = False + for glob in hostglobs: + # check if any wildcard characters are in the string + if set('*?[]') & set(glob): + has_wildcards = True + break + if not has_wildcards: + return hostglobs + + rv = set() + clist = set(self.metadata.clients.keys()) + for glob in hostglobs: + for client in clist: + if fnmatch.fnmatch(client, glob): + rv.update(client) + clist.difference_update(rv) + return list(rv) + def printTabular(rows): """Print data in tabular format.""" cmax = tuple([max([len(str(row[index])) for row in rows]) + 1 \ @@ -108,11 +133,13 @@ def displayTrace(trace, num=80, sort=('time', 'calls')): class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): """Main class for bcfg2-info.""" - def __init__(self, repo, plgs, passwd, encoding, event_debug, filemonitor='default'): + def __init__(self, repo, plgs, passwd, encoding, event_debug, + filemonitor='default', setup=None): cmd.Cmd.__init__(self) try: Bcfg2.Server.Core.Core.__init__(self, repo, plgs, passwd, - encoding, filemonitor=filemonitor) + encoding, filemonitor=filemonitor, + setup=setup) if event_debug: self.fam.debug = True except Bcfg2.Server.Core.CoreInitError: @@ -197,10 +224,6 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): """Process pending filesystem events.""" self.fam.handle_events_in_interval(0.1) - def do_version(self, _): - """Print out code version.""" - print(__revision__) - def do_build(self, args): """Build client configuration.""" alist = args.split() @@ -257,42 +280,101 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): self.help_builddir() def do_buildall(self, args): - if len(args.split()) != 1: - print("Usage: buildall <directory>") + alist = args.split() + if len(alist) < 1: + print("Usage: buildall <directory> [<hostnames*>]") return + + destdir = alist[0] + try: + os.mkdir(destdir) + except OSError: + err = sys.exc_info()[1] + if err.errno != 17: + print("Could not create %s: %s" % (destdir, err)) + if len(alist) > 1: + clients = getClientList(alist[1:]) + else: + clients = list(self.metadata.clients.keys()) + for client in clients: + self.do_build("%s %s" % (client, os.path.join(destdir, + client + ".xml"))) + + def do_buildallfile(self, args): + """Build a config file for all clients.""" + usage = 'Usage: buildallfile [--altsrc=<altsrc>] <directory> <filename> [<hostnames*>]' try: - os.mkdir(args) + opts, args = getopt.gnu_getopt(args.split(), '', ['altsrc=']) except: - pass - for client in self.metadata.clients: - self.do_build("%s %s/%s.xml" % (client, args, client)) + print(usage) + return + altsrc = None + for opt in opts: + if opt[0] == '--altsrc': + altsrc = opt[1] + if len(args) < 2: + print(usage) + return + + destdir = args[0] + filename = args[1] + try: + os.mkdir(destdir) + except OSError: + err = sys.exc_info()[1] + if err.errno != 17: + print("Could not create %s: %s" % (destdir, err)) + if len(args) > 2: + clients = getClientList(args[1:]) + else: + clients = list(self.metadata.clients.keys()) + if altsrc: + args = "--altsrc %s -f %%s %%s %%s" % altsrc + else: + args = "-f %s %s %s" + for client in clients: + self.do_buildfile(args % (os.path.join(destdir, client), + filename, client)) def do_buildfile(self, args): """Build a config file for client.""" - usage = 'Usage: buildfile [--altsrc=<altsrc>] filename hostname' + usage = 'Usage: buildfile [-f <outfile>] [--altsrc=<altsrc>] filename hostname' try: - opts, alist = getopt.gnu_getopt(args.split(), '', ['altsrc=']) + opts, alist = getopt.gnu_getopt(args.split(), 'f:', ['altsrc=']) except: print(usage) return altsrc = None + outfile = None for opt in opts: if opt[0] == '--altsrc': altsrc = opt[1] - if len(alist) == 2: - fname, client = alist - entry = lxml.etree.Element('Path', type='file', name=fname) - if altsrc: - entry.set("altsrc", altsrc) - try: - metadata = self.build_metadata(client) - self.Bind(entry, metadata) - print(lxml.etree.tostring(entry, encoding="UTF-8", - xml_declaration=True)) - except: - print("Failed to build entry %s for host %s" % (fname, client)) - else: + elif opt[0] == '-f': + outfile = opt[1] + if len(alist) != 2: print(usage) + return + + fname, client = alist + entry = lxml.etree.Element('Path', type='file', name=fname) + if altsrc: + entry.set("altsrc", altsrc) + try: + metadata = self.build_metadata(client) + self.Bind(entry, metadata) + data = lxml.etree.tostring(entry, encoding="UTF-8", + xml_declaration=True) + if outfile: + open(outfile, 'w').write(data) + else: + print(data) + except IOError: + err = sys.exc_info()[1] + print("Could not write to %s: %s" % (outfile, err)) + print(data) + except Exception: + print("Failed to build entry %s for host %s" % (fname, client)) + raise def do_buildbundle(self, args): """Render a bundle for client.""" @@ -533,7 +615,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): if len(source.whitelist): print(" Whitelist: %s" % ", ".join(source.whitelist)) print("") - + def do_profile(self, arg): """.""" if not have_profile: @@ -557,27 +639,25 @@ if __name__ == '__main__': optinfo = { 'configfile': Bcfg2.Options.CFILE, 'help': Bcfg2.Options.HELP, - } - optinfo.update({ - 'event debug': Bcfg2.Options.DEBUG, - 'profile': Bcfg2.Options.CORE_PROFILE, - 'encoding': Bcfg2.Options.ENCODING, - # Server options - 'repo': Bcfg2.Options.SERVER_REPOSITORY, - 'plugins': Bcfg2.Options.SERVER_PLUGINS, - 'password': Bcfg2.Options.SERVER_PASSWORD, - 'mconnect': Bcfg2.Options.SERVER_MCONNECT, - 'filemonitor': Bcfg2.Options.SERVER_FILEMONITOR, - 'location': Bcfg2.Options.SERVER_LOCATION, - 'static': Bcfg2.Options.SERVER_STATIC, - 'key': Bcfg2.Options.SERVER_KEY, - 'cert': Bcfg2.Options.SERVER_CERT, - 'ca': Bcfg2.Options.SERVER_CA, - 'password': Bcfg2.Options.SERVER_PASSWORD, - 'protocol': Bcfg2.Options.SERVER_PROTOCOL, - # More options - 'logging': Bcfg2.Options.LOGGING_FILE_PATH - }) + 'event debug': Bcfg2.Options.DEBUG, + 'profile': Bcfg2.Options.CORE_PROFILE, + 'encoding': Bcfg2.Options.ENCODING, + # Server options + 'repo': Bcfg2.Options.SERVER_REPOSITORY, + 'plugins': Bcfg2.Options.SERVER_PLUGINS, + 'password': Bcfg2.Options.SERVER_PASSWORD, + 'mconnect': Bcfg2.Options.SERVER_MCONNECT, + 'filemonitor': Bcfg2.Options.SERVER_FILEMONITOR, + 'location': Bcfg2.Options.SERVER_LOCATION, + 'static': Bcfg2.Options.SERVER_STATIC, + 'key': Bcfg2.Options.SERVER_KEY, + 'cert': Bcfg2.Options.SERVER_CERT, + 'ca': Bcfg2.Options.SERVER_CA, + 'password': Bcfg2.Options.SERVER_PASSWORD, + 'protocol': Bcfg2.Options.SERVER_PROTOCOL, + # More options + 'logging': Bcfg2.Options.LOGGING_FILE_PATH + } setup = Bcfg2.Options.OptionParser(optinfo) setup.hm = "Usage:\n %s\n%s" % (setup.buildHelpMessage(), USAGE) @@ -590,12 +670,14 @@ if __name__ == '__main__': prof = profile.Profile() loop = prof.runcall(infoCore, setup['repo'], setup['plugins'], setup['password'], setup['encoding'], - setup['event debug'], setup['filemonitor']) + setup['event debug'], setup['filemonitor'], + setup) displayTrace(prof) else: if setup['profile']: print("Profiling functionality not available.") loop = infoCore(setup['repo'], setup['plugins'], setup['password'], - setup['encoding'], setup['event debug'], setup['filemonitor']) + setup['encoding'], setup['event debug'], + setup['filemonitor'], setup) loop.Run(setup['args']) diff --git a/src/sbin/bcfg2-lint b/src/sbin/bcfg2-lint index 2d371f4aa..78b833f02 100755 --- a/src/sbin/bcfg2-lint +++ b/src/sbin/bcfg2-lint @@ -1,7 +1,6 @@ #!/usr/bin/env python """This tool examines your Bcfg2 specifications for errors.""" -__revision__ = '$Revision$' import sys import inspect @@ -63,7 +62,9 @@ def get_errorhandler(config): def load_server(setup): """ load server """ core = Bcfg2.Server.Core.Core(setup['repo'], setup['plugins'], - setup['password'], setup['encoding']) + setup['password'], setup['encoding'], + filemonitor=setup['filemonitor'], + setup=setup) if setup['event debug']: core.fam.debug = True core.fam.handle_events_in_interval(4) @@ -74,8 +75,6 @@ if __name__ == '__main__': 'configfile': Bcfg2.Options.CFILE, 'help': Bcfg2.Options.HELP, 'verbose': Bcfg2.Options.VERBOSE, - } - optinfo.update({ 'event debug': Bcfg2.Options.DEBUG, 'encoding': Bcfg2.Options.ENCODING, # Server options @@ -102,7 +101,7 @@ if __name__ == '__main__': 'showerrors': Bcfg2.Options.Option('Show error handling', False, cmd='--list-errors', long_arg=True), - }) + } setup = Bcfg2.Options.OptionParser(optinfo) setup.parse(sys.argv[1:]) @@ -115,21 +114,6 @@ if __name__ == '__main__': config.read(setup['configfile']) config.read(setup['config']) - if setup['showerrors']: - if config.has_section("errors"): - econf = dict(config.items("errors")) - else: - econf = dict() - - print("%-35s %-35s" % ("Error name", "Handler (Default)")) - for err, default in Bcfg2.Server.Lint.ErrorHandler._errors.items(): - if err in econf and econf[err] != default: - handler = "%s (%s)" % (econf[err], default) - else: - handler = default - print("%-35s %-35s" % (err, handler)) - raise SystemExit(0) - # get list of plugins to run if setup['args']: allplugins = setup['args'] @@ -170,6 +154,15 @@ if __name__ == '__main__': errorhandler = get_errorhandler(config) + if setup['showerrors']: + for plugin in serverplugins.values() + serverlessplugins.values(): + errorhandler.RegisterErrors(getattr(plugin, 'Errors')()) + + print("%-35s %-35s" % ("Error name", "Handler")) + for err, handler in errorhandler._handlers.items(): + print("%-35s %-35s" % (err, handler.__name__)) + raise SystemExit(0) + run_serverless_plugins(serverlessplugins, errorhandler=errorhandler, config=config, setup=setup) diff --git a/src/sbin/bcfg2-ping-sweep b/src/sbin/bcfg2-ping-sweep index 70f718690..be8994be3 100755 --- a/src/sbin/bcfg2-ping-sweep +++ b/src/sbin/bcfg2-ping-sweep @@ -3,8 +3,6 @@ """Generates hostinfo.xml at a regular interval.""" -__revision__ = '$Revision$' - from os import dup2, execl, fork, uname, wait import sys import time diff --git a/src/sbin/bcfg2-reports b/src/sbin/bcfg2-reports index 6acdd27e3..1f101b9a7 100755 --- a/src/sbin/bcfg2-reports +++ b/src/sbin/bcfg2-reports @@ -1,6 +1,5 @@ #!/usr/bin/env python """Query reporting system for client status.""" -__revision__ = '$Revision$' import os import sys diff --git a/src/sbin/bcfg2-server b/src/sbin/bcfg2-server index 546d5a249..757172464 100755 --- a/src/sbin/bcfg2-server +++ b/src/sbin/bcfg2-server @@ -1,7 +1,6 @@ #!/usr/bin/env python """The XML-RPC Bcfg2 server.""" -__revision__ = '$Revision$' import logging import os.path @@ -16,7 +15,6 @@ from Bcfg2.Server.Core import CoreInitError logger = logging.getLogger('bcfg2-server') if __name__ == '__main__': - OPTINFO = { 'configfile': Bcfg2.Options.CFILE, 'daemon' : Bcfg2.Options.DAEMON, @@ -24,26 +22,22 @@ if __name__ == '__main__': 'help' : Bcfg2.Options.HELP, 'verbose' : Bcfg2.Options.VERBOSE, 'to_file' : Bcfg2.Options.LOGGING_FILE_PATH, + 'repo' : Bcfg2.Options.SERVER_REPOSITORY, + 'plugins' : Bcfg2.Options.SERVER_PLUGINS, + 'password' : Bcfg2.Options.SERVER_PASSWORD, + 'fm' : Bcfg2.Options.SERVER_FILEMONITOR, + 'key' : Bcfg2.Options.SERVER_KEY, + 'cert' : Bcfg2.Options.SERVER_CERT, + 'ca' : Bcfg2.Options.SERVER_CA, + 'listen_all': Bcfg2.Options.SERVER_LISTEN_ALL, + 'location' : Bcfg2.Options.SERVER_LOCATION, + 'passwd' : Bcfg2.Options.SERVER_PASSWORD, + 'static' : Bcfg2.Options.SERVER_STATIC, + 'encoding' : Bcfg2.Options.ENCODING, + 'filelog' : Bcfg2.Options.LOGGING_FILE_PATH, + 'protocol' : Bcfg2.Options.SERVER_PROTOCOL, } - OPTINFO.update({'repo' : Bcfg2.Options.SERVER_REPOSITORY, - 'plugins' : Bcfg2.Options.SERVER_PLUGINS, - 'password' : Bcfg2.Options.SERVER_PASSWORD, - 'fm' : Bcfg2.Options.SERVER_FILEMONITOR, - }) - - OPTINFO.update({'key' : Bcfg2.Options.SERVER_KEY, - 'cert' : Bcfg2.Options.SERVER_CERT, - 'ca' : Bcfg2.Options.SERVER_CA, - 'listen_all' : Bcfg2.Options.SERVER_LISTEN_ALL, - 'location' : Bcfg2.Options.SERVER_LOCATION, - 'passwd' : Bcfg2.Options.SERVER_PASSWORD, - 'static' : Bcfg2.Options.SERVER_STATIC, - 'encoding' : Bcfg2.Options.ENCODING, - 'filelog' : Bcfg2.Options.LOGGING_FILE_PATH, - 'protocol' : Bcfg2.Options.SERVER_PROTOCOL, - }) - setup = Bcfg2.Options.OptionParser(OPTINFO) setup.parse(sys.argv[1:]) try: @@ -54,9 +48,9 @@ if __name__ == '__main__': Bcfg2.Component.run_component(Bcfg2.Server.Core.Core, listen_all=setup['listen_all'], location=setup['location'], - daemon = setup['daemon'], - pidfile_name = setup['daemon'], - protocol = setup['protocol'], + daemon=setup['daemon'], + pidfile_name=setup['daemon'], + protocol=setup['protocol'], to_file=setup['to_file'], cfile=setup['configfile'], register=False, @@ -66,10 +60,11 @@ if __name__ == '__main__': 'encoding':setup['encoding'], 'ca':setup['ca'], 'filemonitor':setup['fm'], - 'start_fam_thread':True}, + 'start_fam_thread':True, + 'setup':setup}, keyfile=setup['key'], certfile=setup['cert'], - ca=setup['ca'], + ca=setup['ca'] ) except CoreInitError: msg = sys.exc_info()[1] diff --git a/src/sbin/bcfg2-test b/src/sbin/bcfg2-test index 01a2a4893..e3cfd27cc 100755 --- a/src/sbin/bcfg2-test +++ b/src/sbin/bcfg2-test @@ -71,6 +71,7 @@ def main(): 'verbose': Bcfg2.Options.VERBOSE, 'noseopts': Bcfg2.Options.TEST_NOSEOPTS, 'ignore': Bcfg2.Options.TEST_IGNORE, + 'validate': Bcfg2.Options.CFG_VALIDATION, } setup = Bcfg2.Options.OptionParser(optinfo) setup.hm = \ @@ -86,7 +87,8 @@ def main(): setup['plugins'], setup['password'], setup['encoding'], - filemonitor='pseudo' + filemonitor='pseudo', + setup=setup ) ignore = dict() diff --git a/src/sbin/bcfg2-yum-helper b/src/sbin/bcfg2-yum-helper index dc46bb81a..2da7c6336 100755 --- a/src/sbin/bcfg2-yum-helper +++ b/src/sbin/bcfg2-yum-helper @@ -5,8 +5,6 @@ the right way to get around that in long-running processes it to have a short-lived helper. No, seriously -- check out the yum-updatesd code. It's pure madness. """ -__revision__ = '$Revision$' - import os import sys import yum |