diff options
author | Fabian Affolter <fabian@bernewireless.net> | 2010-12-13 23:22:40 +0100 |
---|---|---|
committer | Fabian Affolter <fabian@bernewireless.net> | 2010-12-13 23:22:40 +0100 |
commit | f5792d907e357c90624ec110d908d42b94296a12 (patch) | |
tree | fc4976fb05c8d4026bc2580e48ad8070d85bd7c7 /build/lib/Bcfg2/Server/Admin | |
parent | 18b3b41b3f993b2dd5a10e1bbb8abf959c57c4e2 (diff) | |
download | bcfg2-f5792d907e357c90624ec110d908d42b94296a12.tar.gz bcfg2-f5792d907e357c90624ec110d908d42b94296a12.tar.bz2 bcfg2-f5792d907e357c90624ec110d908d42b94296a12.zip |
Removed build files
Diffstat (limited to 'build/lib/Bcfg2/Server/Admin')
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Backup.py | 33 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Bundle.py | 100 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Client.py | 64 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Compare.py | 137 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Examples.py | 71 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Group.py | 66 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Init.py | 280 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Minestruct.py | 69 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Perf.py | 37 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Pull.py | 138 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Query.py | 78 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Reports.py | 357 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Snapshots.py | 163 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Tidy.py | 66 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Viz.py | 101 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Web.py | 79 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/Xcmd.py | 49 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/__init__.py | 114 | ||||
-rw-r--r-- | build/lib/Bcfg2/Server/Admin/test.py | 73 |
19 files changed, 0 insertions, 2075 deletions
diff --git a/build/lib/Bcfg2/Server/Admin/Backup.py b/build/lib/Bcfg2/Server/Admin/Backup.py deleted file mode 100644 index d6458f97d..000000000 --- a/build/lib/Bcfg2/Server/Admin/Backup.py +++ /dev/null @@ -1,33 +0,0 @@ -import glob -import os -import sys -import time -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\nbcfg2-admin backup restore") - __usage__ = ("bcfg2-admin backup") - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - # Get Bcfg2 repo directory - opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} - setup = Bcfg2.Options.OptionParser(opts) - setup.parse(sys.argv[1:]) - self.datastore = setup['repo'] - timestamp = time.strftime('%Y%m%d%H%M%S') - format = 'gz' - mode = 'w:' + format - filename = timestamp + '.tar' + '.' + format - 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) diff --git a/build/lib/Bcfg2/Server/Admin/Bundle.py b/build/lib/Bcfg2/Server/Admin/Bundle.py deleted file mode 100644 index 41cd5727e..000000000 --- a/build/lib/Bcfg2/Server/Admin/Bundle.py +++ /dev/null @@ -1,100 +0,0 @@ -import lxml.etree -import glob -import sys -import re -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 <bundle> " - #"\n\nbcfg2-admin bundle del <bundle>" - "\n\nbcfg2-admin bundle list-xml" - "\n\nbcfg2-admin bundle list-genshi" - "\n\nbcfg2-admin bundle show") - __usage__ = ("bcfg2-admin bundle [options] [add|del] [group]") - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - 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} - setup = Bcfg2.Options.OptionParser(opts) - setup.parse(sys.argv[1:]) - repo = setup['repo'] - xml_list = glob.glob("%s/Bundler/*.xml" % repo) - genshi_list = glob.glob("%s/Bundler/*.genshi" % repo) - - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin bundle help for usage.") -# if args[0] == 'add': -# try: -# self.metadata.add_bundle(args[1]) -# except MetadataConsistencyError: -# 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." -# 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) - bundle_name.append(rg.search(bundle_path).group(1)) - for bundle in bundle_name: - 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) - 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 - #details after the user choose one bundle. - #FIXME: Add support for detailed output of genshi bundles - elif args[0] in ['show']: - bundle_name = [] - bundle_list = xml_list + genshi_list - for bundle_path in bundle_list: - 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) * "-") - 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() - if int(lineno) >= int(len(bundle_list)): - print "No line with this number." - else: - if '%s/Bundler/%s' % \ - (repo, bundle_name[int(lineno)]) in genshi_list: - print "Detailed output for *.genshi bundle is not supported." - else: - 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) - names = ['Action', 'Package', 'Path', 'Service'] - for name in names: - for node in tree.findall("//" + name): - print "%s:\t%s" % (name, node.attrib["name"]) - else: - print "No command specified" - raise SystemExit(1) diff --git a/build/lib/Bcfg2/Server/Admin/Client.py b/build/lib/Bcfg2/Server/Admin/Client.py deleted file mode 100644 index 0eee22ae4..000000000 --- a/build/lib/Bcfg2/Server/Admin/Client.py +++ /dev/null @@ -1,64 +0,0 @@ -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 <client> " - "attr1=val1 attr2=val2\n" - "\n\nbcfg2-admin client update <client> " - "attr1=val1 attr2=val2\n" - "\n\nbcfg2-admin client list\n" - "bcfg2-admin client del <client>") - __usage__ = ("bcfg2-admin client [options] [add|del|update|list] [attr=val]") - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin client help for usage.") - if args[0] == 'add': - attr_d = {} - for i in args[2:]: - attr, val = i.split('=', 1) - if attr not in ['profile', 'uuid', 'password', - 'location', 'secure', 'address']: - 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" - raise SystemExit(1) - elif args[0] in ['update', 'up']: - attr_d = {} - for i in args[2:]: - attr, val = i.split('=', 1) - if attr not in ['profile', 'uuid', 'password', - 'location', 'secure', 'address']: - 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" - 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" - 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"] - else: - print "No command specified" - raise SystemExit(1) diff --git a/build/lib/Bcfg2/Server/Admin/Compare.py b/build/lib/Bcfg2/Server/Admin/Compare.py deleted file mode 100644 index f97233b0e..000000000 --- a/build/lib/Bcfg2/Server/Admin/Compare.py +++ /dev/null @@ -1,137 +0,0 @@ -import lxml.etree, os -import Bcfg2.Server.Admin - -class Compare(Bcfg2.Server.Admin.Mode): - __shorthelp__ = ("Determine differences between files or " - "directories of client specification instances") - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin compare <file1> <file2>" - "\nbcfg2-admin compare -r <dir1> <dir2>") - __usage__ = ("bcfg2-admin compare <old> <new>\n\n" - " -r\trecursive") - - 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']} - - 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) - continue - if len(equiv) == 0: - 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')) - continue - noattrmatch = [field for field in self.important[child.tag] if \ - child.get(field) != equiv[0].get(field)] - if not noattrmatch: - new.remove(child) - old.remove(equiv[0]) - else: - 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': - name = 'Base' - else: - name = new.get('name') - both = [] - oldl = ["%s %s" % (entry.tag, entry.get('name')) for entry in old] - newl = ["%s %s" % (entry.tag, entry.get('name')) for entry in new] - for entry in newl: - if entry in oldl: - both.append(entry) - newl.remove(entry) - oldl.remove(entry) - for entry in both: - print " %s differs (in bundle %s)" % (entry, name) - for entry in oldl: - 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) - return False - - def compareSpecifications(self, path1, path2): - try: - new = lxml.etree.parse(path1).getroot() - except IOError: - print "Failed to read %s" % (path1) - raise SystemExit(1) - - try: - old = lxml.etree.parse(path2).getroot() - except IOError: - print "Failed to read %s" % (path2) - raise SystemExit(1) - - for src in [new, old]: - for bundle in src.findall('./Bundle'): - if bundle.get('name')[-4:] == '.xml': - bundle.set('name', bundle.get('name')[:-4]) - - rcs = [] - 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') - continue - if len(equiv) == 1: - if self.compareStructures(bundle, equiv[0]): - new.remove(bundle) - old.remove(equiv[0]) - rcs.append(True) - else: - rcs.append(False) - else: - print "Unmatched bundle %s" % (bundle.get('name')) - rcs.append(False) - i1 = new.find('./Independent') - i2 = old.find('./Independent') - if self.compareStructures(i1, i2): - new.remove(i1) - old.remove(i2) - else: - rcs.append(False) - return False not in rcs - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin compare help for usage.") - if '-r' in args: - args = list(args) - args.remove('-r') - (oldd, newd) = args - (old, new) = [os.listdir(spot) for spot in args] - for item in old: - print "Entry:", item - state = self.__call__([oldd + '/' + item, newd + '/' + item]) - new.remove(item) - if state: - print "Entry:", item, "good" - else: - print "Entry:", item, "bad" - if new: - print "new has extra entries", new - return - try: - (old, new) = args - except IndexError: - print self.__call__.__doc__ - raise SystemExit(1) diff --git a/build/lib/Bcfg2/Server/Admin/Examples.py b/build/lib/Bcfg2/Server/Admin/Examples.py deleted file mode 100644 index 3335c5e10..000000000 --- a/build/lib/Bcfg2/Server/Admin/Examples.py +++ /dev/null @@ -1,71 +0,0 @@ -import dulwich -import time -import tarfile -from subprocess import Popen -import Bcfg2.Server.Admin -from Bcfg2.Server.Plugins.Metadata import MetadataConsistencyError - -class Examples(Bcfg2.Server.Admin.MetadataCore): - __shorthelp__ = "Pulls in the data from the Bcfg2 sample repository" - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin examples pull\n" - "\n\nbcfg2-admin examples update\n" - "bcfg2-admin examples backup") - __usage__ = ("bcfg2-admin examples [options] [add|del|update|list] [attr=val]") - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - - - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.Version.__init__(self) - self.core = core - self.datastore = datastore - - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin examples help for usage.") - - if args[0] == 'pull': - try: - # FIXME: Repo URL is hardcoded for now - Popen(['git', 'clone', 'https://github.com/solj/bcfg2-repo.git', datastore]) - except MetadataConsistencyError: - print "Error in pulling examples." - raise SystemExit(1) - -#fatal: destination path 'bcfg2-test' already exists and is not an empty directory. - - elif args[0] == 'backup': - try: - self.metadata.add_group(args[1], attr_d) - except MetadataConsistencyError: - print "Error in adding group" - raise SystemExit(1) - - - elif args[0] == 'backup': - try: - self.metadata.add_group(args[1], attr_d) - except MetadataConsistencyError: - print "Error in adding group" - raise SystemExit(1) - - else: - print "No command specified" - raise SystemExit(1) - - def repobackup(): - """Make a backup of the existing files in the Bcfg2 repo directory.""" - if os.path.isdir(datastore): - print 'Backup in progress...' - target = time.strftime('%Y%m%d%H%M%S') - - - out = tarfile.open(filename, w.gz) - else: - logger.error("%s doesn't exist." % datastore) - #raise Bcfg2.Server.Plugin.PluginInitError diff --git a/build/lib/Bcfg2/Server/Admin/Group.py b/build/lib/Bcfg2/Server/Admin/Group.py deleted file mode 100644 index 6a1c13775..000000000 --- a/build/lib/Bcfg2/Server/Admin/Group.py +++ /dev/null @@ -1,66 +0,0 @@ -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 <group> " - "attr1=val1 attr2=val2\n" - "\n\nbcfg2-admin group update <group> " - "attr1=val1 attr2=val2\n" - "\n\nbcfg2-admin group list\n" - "bcfg2-admin group del <group>") - __usage__ = ("bcfg2-admin group [options] [add|del|update|list] [attr=val]") - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin group help for usage.") - if args[0] == 'add': - attr_d = {} - for i in args[2:]: - attr, val = i.split('=', 1) - if attr not in ['profile', 'public', 'default', - 'name', 'auth', 'toolset', 'category', - 'comment']: - 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" - raise SystemExit(1) - elif args[0] in ['update', 'up']: - attr_d = {} - for i in args[2:]: - attr, val = i.split('=', 1) - if attr not in ['profile', 'public', 'default', - 'name', 'auth', 'toolset', 'category', - 'comment']: - 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" - 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" - 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"] - else: - print "No command specified" - raise SystemExit(1) diff --git a/build/lib/Bcfg2/Server/Admin/Init.py b/build/lib/Bcfg2/Server/Admin/Init.py deleted file mode 100644 index c6d1f9e3d..000000000 --- a/build/lib/Bcfg2/Server/Admin/Init.py +++ /dev/null @@ -1,280 +0,0 @@ -import getpass -import os -import random -import socket -import string -import subprocess -import Bcfg2.Server.Admin -import Bcfg2.Server.Plugin -import Bcfg2.Options - -# default config file -config = ''' -[server] -repository = %s -plugins = %s - -[statistics] -sendmailpath = %s -database_engine = sqlite3 -# 'postgresql', 'mysql', 'mysql_old', 'sqlite3' or 'ado_mssql'. -database_name = -# Or path to database file if using sqlite3. -#<repository>/etc/brpt.sqlite is default path if left empty -database_user = -# Not used with sqlite3. -database_password = -# Not used with sqlite3. -database_host = -# Not used with sqlite3. -database_port = -# Set to empty string for default. Not used with sqlite3. -web_debug = True - -[communication] -protocol = %s -password = %s -certificate = %s/%s -key = %s/%s -ca = %s/%s - -[components] -bcfg2 = %s -''' - -# Default groups -groups = '''<Groups version='3.0'> - <Group profile='true' public='true' default='true' name='basic'> - <Group name='%s'/> - </Group> - <Group name='ubuntu'/> - <Group name='debian'/> - <Group name='freebsd'/> - <Group name='gentoo'/> - <Group name='redhat'/> - <Group name='suse'/> - <Group name='mandrake'/> - <Group name='solaris'/> -</Groups> -''' - -# Default contents of clients.xml -clients = '''<Clients version="3.0"> - <Client profile="basic" pingable="Y" pingtime="0" name="%s"/> -</Clients> -''' - -# Mapping of operating system names to groups -os_list = [ - ('Red Hat/Fedora/RHEL/RHAS/Centos', 'redhat'), - ('SUSE/SLES', 'suse'), - ('Mandrake', 'mandrake'), - ('Debian', 'debian'), - ('Ubuntu', 'ubuntu'), - ('Gentoo', 'gentoo'), - ('FreeBSD', 'freebsd') - ] - -# Complete list of plugins -plugin_list = ['Account', 'Base', 'Bundler', 'Cfg', - 'Decisions', 'Deps', 'Metadata', 'Packages', - 'Pkgmgr', 'Probes', 'Properties', 'Rules', - 'Snapshots', 'SSHbase', 'Statistics', 'Svcmgr', - 'TCheetah', 'TGenshi'] - -# Default list of plugins to use -default_plugins = ['SSHbase', 'Cfg', 'Pkgmgr', 'Rules', - 'Metadata', 'Base', 'Bundler'] - -def gen_password(length): - """Generates a random alphanumeric password with length characters.""" - chars = string.letters + string.digits - newpasswd = '' - for i in range(length): - newpasswd = newpasswd + random.choice(chars) - return newpasswd - -def create_key(hostname, keypath, certpath): - """Creates a bcfg2.key at the directory specifed by keypath.""" - kcstr = "openssl req -batch -x509 -nodes -subj '/C=US/ST=Illinois/L=Argonne/CN=%s' -days 1000 -newkey rsa:2048 -keyout %s -noout" % (hostname, keypath) - subprocess.call((kcstr), shell=True) - ccstr = "openssl req -batch -new -subj '/C=US/ST=Illinois/L=Argonne/CN=%s' -key %s | openssl x509 -req -days 1000 -signkey %s -out %s" % (hostname, keypath, keypath, certpath) - subprocess.call((ccstr), shell=True) - os.chmod(keypath, 0600) - -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) - if result not in ['Y', 'y']: - print("Leaving %s unchanged" % confpath) - return - try: - open(confpath, "w").write(confdata) - os.chmod(confpath, 0600) - except Exception, e: - print("Error %s occured while trying to write configuration " - "file to '%s'\n" % - (e, confpath)) - raise SystemExit(1) - - -class Init(Bcfg2.Server.Admin.Mode): - __shorthelp__ = ("Interactively initialize a new repository.") - __longhelp__ = __shorthelp__ + "\n\nbcfg2-admin init" - __usage__ = "bcfg2-admin init" - options = { - 'configfile': Bcfg2.Options.CFILE, - 'plugins' : Bcfg2.Options.SERVER_PLUGINS, - 'proto' : Bcfg2.Options.SERVER_PROTOCOL, - 'repo' : Bcfg2.Options.SERVER_REPOSITORY, - 'sendmail' : Bcfg2.Options.SENDMAIL_PATH, - } - repopath = "" - response = "" - def __init__(self, configfile): - Bcfg2.Server.Admin.Mode.__init__(self, configfile) - - def _set_defaults(self): - """Set default parameters.""" - self.configfile = self.opts['configfile'] - self.repopath = self.opts['repo'] - self.password = gen_password(8) - self.server_uri = "https://%s:6789" % socket.getfqdn() - self.plugins = default_plugins - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - - # Parse options - self.opts = Bcfg2.Options.OptionParser(self.options) - self.opts.parse(args) - self._set_defaults() - - # Prompt the user for input - self._prompt_config() - self._prompt_repopath() - self._prompt_password() - self._prompt_hostname() - self._prompt_server() - self._prompt_groups() - - # Initialize the repository - self.init_repo() - - def _prompt_hostname(self): - """Ask for the server hostname.""" - data = raw_input("What is the server's hostname [%s]: " % socket.getfqdn()) - if data != '': - self.shostname = data - else: - self.shostname = socket.getfqdn() - - def _prompt_config(self): - """Ask for the configuration file path.""" - newconfig = raw_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) - if newrepo != '': - self.repopath = newrepo - if os.path.isdir(self.repopath): - response = raw_input("Directory %s exists. Overwrite? [y/N]:"\ - % self.repopath) - if response.lower().strip() == 'y': - break - else: - break - - def _prompt_password(self): - """Ask for a password or generate one if none is provided.""" - newpassword = getpass.getpass( - "Input password used for communication verification " - "(without echoing; leave blank for a random): ").strip() - if len(newpassword) != 0: - self.password = newpassword - - def _prompt_server(self): - """Ask for the server name.""" - newserver = raw_input("Input the server location [%s]: " % self.server_uri) - if newserver != '': - self.server_uri = newserver - - def _prompt_groups(self): - """Create the groups.xml file.""" - prompt = '''Input base Operating System for clients:\n''' - for entry in os_list: - prompt += "%d: %s\n" % (os_list.index(entry) + 1, entry[0]) - prompt += ': ' - while True: - try: - self.os_sel = os_list[int(raw_input(prompt))-1][1] - break - except ValueError: - continue - - def _prompt_plugins(self): - default = raw_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: ") - 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 - if plugins_are_valid: - break - - def _init_plugins(self): - """Initialize each plugin-specific portion of the repository.""" - for plugin in self.plugins: - if plugin == 'Metadata': - Bcfg2.Server.Plugins.Metadata.Metadata.init_repo(self.repopath, groups, self.os_sel, clients) - else: - try: - module = __import__("Bcfg2.Server.Plugins.%s" % plugin, '', - '', ["Bcfg2.Server.Plugins"]) - cls = getattr(module, plugin) - cls.init_repo(self.repopath) - except Exception, e: - print 'Plugin setup for %s failed: %s\n Check that dependencies are installed?' % (plugin, e) - - def init_repo(self): - """Setup a new repo and create the content of the configuration file.""" - keypath = os.path.dirname(os.path.abspath(self.configfile)) - confdata = config % ( - self.repopath, - ','.join(self.opts['plugins']), - self.opts['sendmail'], - self.opts['proto'], - self.password, - keypath, 'bcfg2.crt', - keypath, 'bcfg2.key', - keypath, 'bcfg2.crt', - self.server_uri - ) - - # Create the configuration file and SSL key - create_conf(self.configfile, confdata) - kpath = keypath + '/bcfg2.key' - cpath = keypath + '/bcfg2.crt' - create_key(self.shostname, kpath, cpath) - - # Create the repository - path = "%s/%s" % (self.repopath, 'etc') - try: - os.makedirs(path) - self._init_plugins() - print "Repository created successfuly in %s" % (self.repopath) - except OSError: - print("Failed to create %s." % path) diff --git a/build/lib/Bcfg2/Server/Admin/Minestruct.py b/build/lib/Bcfg2/Server/Admin/Minestruct.py deleted file mode 100644 index 02edf2b75..000000000 --- a/build/lib/Bcfg2/Server/Admin/Minestruct.py +++ /dev/null @@ -1,69 +0,0 @@ -import getopt -import lxml.etree -import sys - -import Bcfg2.Server.Admin - -class Minestruct(Bcfg2.Server.Admin.StructureMode): - """Pull extra entries out of statistics.""" - __shorthelp__ = "Extract extra entry lists from statistics" - __longhelp__ = (__shorthelp__ + - "\n\nbcfg2-admin minestruct [-f filename] " - "[-g groups] client") - __usage__ = ("bcfg2-admin minestruct [options] <client>\n\n" - " %-25s%s\n" - " %-25s%s\n" % - ("-f <filename>", - "build a particular file", - "-g <groups>", - "only build config for groups")) - - def __init__(self, configfile): - Bcfg2.Server.Admin.StructureMode.__init__(self, configfile, - self.__usage__) - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin minestruct help for usage.") - try: - (opts, args) = getopt.getopt(args, 'f:g:h') - except: - self.log.error(self.__shorthelp__) - raise SystemExit(1) - - client = args[0] - output = sys.stdout - groups = [] - - for (opt, optarg) in opts: - if opt == '-f': - try: - output = open(optarg, 'w') - except IOError: - self.log.error("Failed to open file: %s" % (optarg)) - raise SystemExit(1) - elif opt == '-g': - groups = optarg.split(':') - - try: - extra = set() - for source in self.bcore.pull_sources: - for item in source.GetExtra(client): - extra.add(item) - except: - self.log.error("Failed to find extra entry info for client %s" % - client) - raise SystemExit(1) - root = lxml.etree.Element("Base") - self.log.info("Found %d extra entries" % (len(extra))) - add_point = root - for g in groups: - add_point = lxml.etree.SubElement(add_point, "Group", name=g) - for tag, name in extra: - self.log.info("%s: %s" % (tag, name)) - lxml.etree.SubElement(add_point, tag, name=name) - - tree = lxml.etree.ElementTree(root) - tree.write(output, pretty_print=True) diff --git a/build/lib/Bcfg2/Server/Admin/Perf.py b/build/lib/Bcfg2/Server/Admin/Perf.py deleted file mode 100644 index 6f1cb8dbb..000000000 --- a/build/lib/Bcfg2/Server/Admin/Perf.py +++ /dev/null @@ -1,37 +0,0 @@ -import Bcfg2.Options -import Bcfg2.Proxy -import Bcfg2.Server.Admin - -import sys - -class Perf(Bcfg2.Server.Admin.Mode): - __shorthelp__ = ("Query server for performance data") - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin perf") - __usage__ = ("bcfg2-admin perf") - - def __init__(self, configfile): - Bcfg2.Server.Admin.Mode.__init__(self, configfile) - - def __call__(self, args): - output = [('Name', 'Min', 'Max', 'Mean', 'Count')] - optinfo = { - 'ca': Bcfg2.Options.CLIENT_CA, - 'certificate': Bcfg2.Options.CLIENT_CERT, - 'key': Bcfg2.Options.SERVER_KEY, - 'password': Bcfg2.Options.SERVER_PASSWORD, - 'server': Bcfg2.Options.SERVER_LOCATION, - 'user': Bcfg2.Options.CLIENT_USER, - } - setup = Bcfg2.Options.OptionParser(optinfo) - setup.parse(sys.argv[2:]) - proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], - setup['user'], - setup['password'], - key = setup['key'], - cert = setup['certificate'], - ca = setup['ca']) - data = proxy.get_statistics() - for key, value in data.iteritems(): - data = tuple(["%.06f" % (item) for item in value[:-1]] + [value[-1]]) - output.append((key, ) + data) - self.print_table(output) diff --git a/build/lib/Bcfg2/Server/Admin/Pull.py b/build/lib/Bcfg2/Server/Admin/Pull.py deleted file mode 100644 index aa732c67f..000000000 --- a/build/lib/Bcfg2/Server/Admin/Pull.py +++ /dev/null @@ -1,138 +0,0 @@ -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. - """ - __shorthelp__ = ("Integrate configuration information " - "from clients into the server repository") - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin pull [-v] [-f][-I] [-s] " - "<client> <entry type> <entry name>") - __usage__ = ("bcfg2-admin pull [options] <client> <entry type> " - "<entry name>\n\n" - " %-25s%s\n" - " %-25s%s\n" - " %-25s%s\n" - " %-25s%s\n" % - ("-v", - "be verbose", - "-f", - "force", - "-I", - "interactive", - "-s", - "stdin")) - allowed = ['Metadata', 'BB', "DBStats", "Statistics", "Cfg", "SSHbase"] - - def __init__(self, configfile): - Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, - self.__usage__) - self.log = False - self.mode = 'interactive' - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - use_stdin = False - try: - opts, gargs = getopt.getopt(args, 'vfIs') - except: - print self.__shorthelp__ - raise SystemExit(1) - for opt in opts: - if opt[0] == '-v': - self.log = True - elif opt[0] == '-f': - self.mode = 'force' - elif opt[0] == '-I': - self.mode == 'interactive' - elif opt[0] == '-s': - use_stdin = True - - if use_stdin: - for line in sys.stdin: - try: - self.PullEntry(*line.split(None, 3)) - except SystemExit: - print " for %s" % line - except: - print "Bad entry: %s" % line.strip() - elif len(gargs) < 3: - 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} - for plugin in self.bcore.pull_sources: - try: - (owner, group, perms, contents) = \ - plugin.GetCurrentEntry(client, etype, ename) - break - except Bcfg2.Server.Plugin.PluginExecutionError: - if plugin == self.bcore.pull_sources[-1]: - print "Pull Source failure; could not fetch current state" - raise SystemExit(1) - - try: - 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(): - if v: - new_entry[k] = v - #print new_entry - return new_entry - - def Choose(self, choices): - """Determine where to put pull data.""" - if self.mode == 'interactive': - for choice in choices: - print "Plugin returned choice:" - if id(choice) == id(choices[0]): - print "(current entry)", - if choice.all: - print " => global entry" - elif choice.group: - 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']: - return choice - return False - else: - # mode == 'force' - if not choices: - return False - return choices[0] - - def PullEntry(self, client, etype, ename): - """Make currently recorded client state correct for entry.""" - new_entry = self.BuildNewEntry(client, etype, ename) - - meta = self.bcore.build_metadata(client) - # find appropriate plugin in bcore - glist = [gen for gen in self.bcore.generators if - ename in gen.Entries.get(etype, {})] - if len(glist) != 1: - self.errExit("Got wrong numbers of matching generators for entry:" \ - + "%s" % ([g.name for g in glist])) - plugin = glist[0] - if not isinstance(plugin, Bcfg2.Server.Plugin.PullTarget): - self.errExit("Configuration upload not supported by plugin %s" \ - % (plugin.name)) - try: - choices = plugin.AcceptChoices(new_entry, meta) - specific = self.Choose(choices) - if specific: - plugin.AcceptPullData(specific, new_entry, self.log) - except Bcfg2.Server.Plugin.PluginExecutionError: - self.errExit("Configuration upload not supported by plugin %s" \ - % (plugin.name)) - # FIXME svn commit if running under svn diff --git a/build/lib/Bcfg2/Server/Admin/Query.py b/build/lib/Bcfg2/Server/Admin/Query.py deleted file mode 100644 index b5af9bad2..000000000 --- a/build/lib/Bcfg2/Server/Admin/Query.py +++ /dev/null @@ -1,78 +0,0 @@ -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] " - "[-f filename] g=group p=profile") - __usage__ = ("bcfg2-admin query [options] <g=group> <p=profile>\n\n" - " %-25s%s\n" - " %-25s%s\n" - " %-25s%s\n" % - ("-n", - "query results delimited with newlines", - "-c", - "query results delimited with commas", - "-f filename", - "write query to file")) - - def __init__(self, cfile): - logging.root.setLevel(100) - Bcfg2.Logger.setup_logging(100, to_console=False, to_syslog=False) - Bcfg2.Server.Admin.Mode.__init__(self, cfile) - try: - self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(), - ['Metadata', 'Probes'], - 'foo', False, 'UTF-8') - except Bcfg2.Server.Core.CoreInitError, msg: - self.errExit("Core load failed because %s" % msg) - self.bcore.fam.handle_events_in_interval(1) - self.meta = self.bcore.metadata - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - clients = self.meta.clients.keys() - filename_arg = False - filename = None - for arg in args: - if filename_arg == True: - filename = arg - filename_arg = False - continue - if arg in ['-n', '-c']: - continue - if arg in ['-f']: - filename_arg = True - continue - try: - k, v = arg.split('=') - except: - print "Unknown argument %s" % arg - continue - if k == 'p': - nc = self.meta.get_client_names_by_profiles(v.split(',')) - elif k == 'g': - nc = self.meta.get_client_names_by_groups(v.split(',')) - # 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 g in glist: - if g in v.split(','): - nc.append(c) - else: - 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 - else: - 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) diff --git a/build/lib/Bcfg2/Server/Admin/Reports.py b/build/lib/Bcfg2/Server/Admin/Reports.py deleted file mode 100644 index a4dd19064..000000000 --- a/build/lib/Bcfg2/Server/Admin/Reports.py +++ /dev/null @@ -1,357 +0,0 @@ -'''Admin interface for dynamic reports''' -import Bcfg2.Logger -import Bcfg2.Server.Admin -import ConfigParser -import datetime -import os -import logging -import pickle -import platform -import sys -import traceback -from Bcfg2.Server.Reports.importscript import load_stats -from Bcfg2.Server.Reports.updatefix import update_database -from Bcfg2.Server.Reports.utils import * -from lxml.etree import XML, XMLSyntaxError - -# FIXME: Remove when server python dep is 2.5 or greater -if sys.version_info >= (2, 5): - from hashlib import md5 -else: - from md5 import md5 - -# Load django -import django.core.management - -# FIXME - settings file uses a hardcoded path for /etc/bcfg2.conf -try: - import Bcfg2.Server.Reports.settings -except Exception, e: - sys.stderr.write("Failed to load configuration settings. %s\n" % e) - sys.exit(1) - -project_directory = os.path.dirname(Bcfg2.Server.Reports.settings.__file__) -project_name = os.path.basename(project_directory) -sys.path.append(os.path.join(project_directory, '..')) -project_module = __import__(project_name, '', '', ['']) -sys.path.pop() - -# Set DJANGO_SETTINGS_MODULE appropriately. -os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % project_name -from django.db import connection, transaction - -from Bcfg2.Server.Reports.reports.models import Client, Interaction, Entries, \ - Entries_interactions, Performance, \ - Reason, Ping, TYPE_CHOICES, InternalDatabaseVersion - -def printStats(fn): - """ - Print db stats. - - Decorator for purging. Prints database statistics after a run. - """ - def print_stats(*data): - start_client = Client.objects.count() - start_i = Interaction.objects.count() - start_ei = Entries_interactions.objects.count() - start_perf = Performance.objects.count() - start_ping = Ping.objects.count() - - fn(*data) - - print "Clients removed: %s" % (start_client - Client.objects.count()) - print "Interactions removed: %s" % (start_i - Interaction.objects.count()) - print "Interactions->Entries removed: %s" % \ - (start_ei - Entries_interactions.objects.count()) - print "Metrics removed: %s" % (start_perf - Performance.objects.count()) - print "Ping metrics removed: %s" % (start_ping - Ping.objects.count()) - - return print_stats - -class Reports(Bcfg2.Server.Admin.Mode): - '''Admin interface for dynamic reports''' - __shorthelp__ = "Manage dynamic reports" - __longhelp__ = (__shorthelp__) - __usage__ = ("bcfg2-admin reports [command] [options]\n" - " -v|--verbose Be verbose\n" - " -q|--quiet Print only errors\n" - "\n" - " Commands:\n" - " init Initialize the database\n" - " load_stats Load statistics data\n" - " -s|--stats Path to statistics.xml file\n" - " -c|--clients-file Path to clients.xml file\n" - " -O3 Fast mode. Duplicates data!\n" - " purge Purge records\n" - " --client [n] Client to operate on\n" - " --days [n] Records older then n days\n" - " --expired Expired clients only\n" - " scrub Scrub the database for duplicate reasons and orphaned entries\n" - " update Apply any updates to the reporting database\n" - "\n") - - def __init__(self, cfile): - Bcfg2.Server.Admin.Mode.__init__(self, cfile) - self.log.setLevel(logging.INFO) - self.django_commands = [ 'syncdb', 'sqlall', 'validate' ] - self.__usage__ = self.__usage__ + " Django commands:\n " + \ - "\n ".join(self.django_commands) - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - if len(args) == 0 or args[0] == '-h': - print(self.__usage__) - raise SystemExit(0) - - verb = 0 - - if '-v' in args or '--verbose' in args: - self.log.setLevel(logging.DEBUG) - verb = 1 - if '-q' in args or '--quiet' in args: - self.log.setLevel(logging.WARNING) - - # FIXME - dry run - - if args[0] in self.django_commands: - self.django_command_proxy(args[0]) - elif args[0] == 'scrub': - self.scrub() - elif args[0] == 'init': - update_database() - elif args[0] == 'update': - update_database() - elif args[0] == 'load_stats': - quick = '-O3' in args - 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] - 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] - 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 - 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 - 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])) - except: - self.log.error("Invalid number of days: %s" % args[i+1]) - raise SystemExit, -1 - i = i + 1 - elif args[i] == '--expired': - expired=True - i = i + 1 - if expired: - if state: - self.log.error("--state is not valid with --expired") - raise SystemExit, -1 - self.purge_expired(maxdate) - else: - self.purge(client, maxdate, state) - else: - print "Unknown command: %s" % args[0] - - @transaction.commit_on_success - def scrub(self): - ''' Perform a thorough scrub and cleanup of the database ''' - - # Currently only reasons are a problem - try: - start_count = Reason.objects.count() - except Exception, e: - self.log.error("Failed to load reason objects: %s" % e) - return - dup_reasons = [] - - cmp_reasons = dict() - batch_update = [] - for reason in BatchFetch(Reason.objects): - ''' Loop through each reason and create a key out of the data. \ - This lets us take advantage of a fast hash lookup for \ - comparisons ''' - id = reason.id - reason.id = None - key=md5(pickle.dumps(reason)).hexdigest() - reason.id = id - - if key in cmp_reasons: - self.log.debug("Update interactions from %d to %d" \ - % (reason.id, cmp_reasons[key])) - dup_reasons.append([reason.id]) - batch_update.append([cmp_reasons[key], reason.id]) - 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() - 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: - self.log.error("Failed to delete reasons: %s" % ex) - raise - - self.log.info("Found %d dupes out of %d" % (len(dup_reasons), start_count)) - - # Cleanup orphans - start_count = Reason.objects.count() - Reason.prune_orphans() - self.log.info("Pruned %d Reason records" % (start_count - Reason.objects.count())) - - start_count = Entries.objects.count() - Entries.prune_orphans() - self.log.info("Pruned %d Entries records" % (start_count - Entries.objects.count())) - - def django_command_proxy(self, command): - '''Call a django command''' - if command == 'sqlall': - django.core.management.call_command(command, 'reports') - else: - django.core.management.call_command(command) - - def load_stats(self, stats_file=None, clientspath=None, verb=0, quick=False): - '''Load statistics data into the database''' - location = '' - - if not stats_file: - try: - stats_file = "%s/etc/statistics.xml" % self.cfp.get('server', 'repository') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - self.errExit("Could not read bcfg2.conf; exiting") - try: - statsdata = XML(open(stats_file).read()) - except (IOError, XMLSyntaxError): - self.errExit("StatReports: Failed to parse %s"%(stats_file)) - - if not clientspath: - try: - clientspath = "%s/Metadata/clients.xml" % \ - self.cfp.get('server', 'repository') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - self.errExit("Could not read bcfg2.conf; exiting") - try: - clientsdata = XML(open(clientspath).read()) - except (IOError, XMLSyntaxError): - self.errExit("StatReports: Failed to parse %s"%(clientspath)) - - try: - load_stats(clientsdata, statsdata, verb, self.log, quick=quick, location=platform.node()) - except: - pass - - @printStats - 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 - - if not client and not maxdate and not state: - self.errExit("Reports.prune: Refusing to prune all data") - - ipurge = Interaction.objects - if client: - try: - cobj = Client.objects.get(name=client) - ipurge = ipurge.filter(client=cobj) - except Client.DoesNotExist: - self.log.error("Client %s not in database" % client) - 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" - self.log.debug("Filtering by maxdate: %s" % maxdate) - ipurge = ipurge.filter(timestamp__lt=maxdate) - - # Handle ping data as well - ping = Ping.objects.filter(endtime__lt=maxdate) - if client: - ping = ping.filter(client=cobj) - ping.delete() - - if state: - filtered = True - 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) - - count = ipurge.count() - rnum = 0 - try: - while rnum < count: - grp = list(ipurge[:1000].values("id")) - # just in case... - if not grp: - break - Interaction.objects.filter(id__in=[x['id'] for x in grp]).delete() - rnum += len(grp) - self.log.debug("Deleted %s of %s" % (rnum, count)) - except: - self.log.error("Failed to remove interactions") - (a, b, c) = sys.exc_info() - msg = traceback.format_exception(a, b, c, limit=2)[-1][:-1] - del a, b, c - self.log.error(msg) - - # bulk operations bypass the Interaction.delete method - self.log.debug("Pruning orphan Performance objects") - Performance.prune_orphans() - - if client and not filtered: - '''Delete the client, ping data is automatic''' - try: - self.log.debug("Purging client %s" % client) - cobj.delete() - except: - self.log.error("Failed to delete client %s" % client) - (a, b, c) = sys.exc_info() - msg = traceback.format_exception(a, b, c, limit=2)[-1][:-1] - del a, b, c - self.log.error(msg) - - @printStats - def purge_expired(self, maxdate=None): - '''Purge expired clients from the database''' - - if maxdate: - if not isinstance(maxdate, datetime.datetime): - raise TypeError, "maxdate is not a DateTime object" - self.log.debug("Filtering by maxdate: %s" % maxdate) - clients = Client.objects.filter(expiration__lt=maxdate) - else: - clients = Client.objects.filter(expiration__isnull=False) - - for client in clients: - self.log.debug("Purging client %s" % client) - Interaction.objects.filter(client=client).delete() - client.delete() - self.log.debug("Pruning orphan Performance objects") - Performance.prune_orphans() - diff --git a/build/lib/Bcfg2/Server/Admin/Snapshots.py b/build/lib/Bcfg2/Server/Admin/Snapshots.py deleted file mode 100644 index 004de0ddb..000000000 --- a/build/lib/Bcfg2/Server/Admin/Snapshots.py +++ /dev/null @@ -1,163 +0,0 @@ -from datetime import date -import sys - -# prereq issues can be signaled with ImportError, so no try needed -import sqlalchemy, sqlalchemy.orm -import Bcfg2.Server.Admin -import Bcfg2.Server.Snapshots -import Bcfg2.Server.Snapshots.model -from Bcfg2.Server.Snapshots.model import Snapshot, Client, Metadata, Base, \ - File, Group, Package, Service - -class Snapshots(Bcfg2.Server.Admin.Mode): - __shorthelp__ = "Interact with the Snapshots system" - __longhelp__ = (__shorthelp__) - __usage__ = ("bcfg2-admin snapshots [init|query qtype]") - - q_dispatch = {'client':Client, - 'group':Group, - 'metadata':Metadata, - 'package':Package, - 'snapshot':Snapshot} - - def __init__(self, configfile): - Bcfg2.Server.Admin.Mode.__init__(self, configfile) - #self.session = Bcfg2.Server.Snapshots.setup_session(debug=True) - self.session = Bcfg2.Server.Snapshots.setup_session(configfile) - self.cfile = configfile - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - if len(args) == 0 or args[0] == '-h': - print(self.__usage__) - raise SystemExit(0) - - if args[0] == 'query': - if args[1] in self.q_dispatch: - q_obj = self.q_dispatch[args[1]] - if q_obj == Client: - rows = [] - labels = ('Client', 'Active') - for host in \ - self.session.query(q_obj).filter(q_obj.active == False): - rows.append([host.name, 'No']) - for host in \ - self.session.query(q_obj).filter(q_obj.active == True): - rows.append([host.name, 'Yes']) - self.print_table([labels]+rows, - justify='left', - hdr=True, - vdelim=" ", - padding=1) - elif q_obj == Group: - print("Groups:") - for group in self.session.query(q_obj).all(): - print(" %s" % group.name) - else: - results = self.session.query(q_obj).all() - else: - print('error') - raise SystemExit(1) - elif args[0] == 'init': - # Initialize the Snapshots database - dbpath = Bcfg2.Server.Snapshots.db_from_config(self.cfile) - engine = sqlalchemy.create_engine(dbpath, echo=True) - metadata = Base.metadata - metadata.create_all(engine) - Session = sqlalchemy.orm.sessionmaker() - Session.configure(bind=engine) - session = Session() - session.commit() - elif args[0] == 'dump': - client = args[1] - snap = Snapshot.get_current(self.session, unicode(client)) - if not snap: - print("Current snapshot for %s not found" % client) - sys.exit(1) - print("Client %s last run at %s" % (client, snap.timestamp)) - for pkg in snap.packages: - print("C:", pkg.correct, 'M:', pkg.modified) - print("start", pkg.start.name, pkg.start.version) - print("end", pkg.end.name, pkg.end.version) - elif args[0] == 'reports': - # bcfg2-admin reporting interface for Snapshots - if '-a' in args[1:]: - # Query all hosts for Name, Status, Revision, Timestamp - q = self.session.query(Client.name, - Snapshot.correct, - Snapshot.revision, - Snapshot.timestamp)\ - .filter(Client.id==Snapshot.client_id)\ - .group_by(Client.id) - rows = [] - labels = ('Client', 'Correct', 'Revision', 'Time') - for item in q.all(): - cli, cor, time, rev = item - rows.append([cli, cor, time, rev]) - self.print_table([labels]+rows, - justify='left', - hdr=True, vdelim=" ", - padding=1) - elif '-b' in args[1:]: - # Query a single host for bad entries - if len(args) < 3: - print("Usage: bcfg2-admin snapshots -b <client>") - return - client = args[2] - snap = Snapshot.get_current(self.session, unicode(client)) - if not snap: - print("Current snapshot for %s not found" % client) - sys.exit(1) - print("Bad entries:") - bad_pkgs = [self.session.query(Package) - .filter(Package.id==p.start_id).one().name \ - for p in snap.packages if p.correct == False] - for p in bad_pkgs: - print(" Package:%s" % p) - bad_files = [self.session.query(File) - .filter(File.id==f.start_id).one().name \ - for f in snap.files if f.correct == False] - for filename in bad_files: - print(" File:%s" % filename) - bad_svcs = [self.session.query(Service) - .filter(Service.id==s.start_id).one().name \ - for s in snap.services if s.correct == False] - for svc in bad_svcs: - print(" Service:%s" % svc) - elif '-e' in args[1:]: - # Query a single host for extra entries - client = args[2] - snap = Snapshot.get_current(self.session, unicode(client)) - if not snap: - print("Current snapshot for %s not found" % client) - sys.exit(1) - print("Extra entries:") - for pkg in snap.extra_packages: - print(" Package:%s" % pkg.name) - # FIXME: Do we know about extra files yet? - for f in snap.extra_files: - print(" File:%s" % f.name) - for svc in snap.extra_services: - print(" Service:%s" % svc.name) - elif '--date' in args[1:]: - year, month, day = args[2:] - timestamp = date(int(year), int(month), int(day)) - snaps = [] - for client in self.session.query(Client).filter(Client.active == True): - snaps.append(Snapshot.get_by_date(self.session, - client.name, - timestamp)) - rows = [] - labels = ('Client', 'Correct', 'Revision', 'Time') - for snap in snaps: - rows.append([snap.client.name, - snap.correct, - snap.revision, - snap.timestamp]) - self.print_table([labels]+rows, - justify='left', - hdr=True, - vdelim=" ", - padding=1) - else: - print("Unknown options: ", args[1:]) diff --git a/build/lib/Bcfg2/Server/Admin/Tidy.py b/build/lib/Bcfg2/Server/Admin/Tidy.py deleted file mode 100644 index c02ddf110..000000000 --- a/build/lib/Bcfg2/Server/Admin/Tidy.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import re -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]" - __usage__ = ("bcfg2-admin tidy [options]\n\n" - " %-25s%s\n" - " %-25s%s\n" % - ("-f", - "force", - "-I", - "interactive")) - - def __init__(self, cfile): - Bcfg2.Server.Admin.Mode.__init__(self, cfile) - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - badfiles = self.buildTidyList() - if '-f' in args or '-I' in args: - if '-I' in args: - for name in badfiles[:]: - answer = raw_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 - else: - for name in badfiles: - print name - - def buildTidyList(self): - """Clean up unused or unusable files from the repository.""" - hostmatcher = re.compile('.*\.H_(\S+)$') - to_remove = [] - good = [] - bad = [] - - # clean up unresolvable hosts in SSHbase - for name in os.listdir("%s/SSHbase" % (self.get_repo_path())): - if hostmatcher.match(name): - hostname = hostmatcher.match(name).group(1) - if hostname in good + bad: - continue - try: - socket.gethostbyname(hostname) - good.append(hostname) - except: - 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)) - else: - if hostmatcher.match(name).group(1) in bad: - to_remove.append("%s/SSHbase/%s" % - (self.get_repo_path(), name)) - # clean up file~ - # clean up files without parsable names in Cfg - return to_remove diff --git a/build/lib/Bcfg2/Server/Admin/Viz.py b/build/lib/Bcfg2/Server/Admin/Viz.py deleted file mode 100644 index 245ca8398..000000000 --- a/build/lib/Bcfg2/Server/Admin/Viz.py +++ /dev/null @@ -1,101 +0,0 @@ -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] " - "[--includebundles] [--includekey] " - "[-o output.png] [--raw]") - __usage__ = ("bcfg2-admin viz [options]\n\n" - " %-25s%s\n" - " %-25s%s\n" - " %-25s%s\n" - " %-25s%s\n" % - ("-H, --includehosts", - "include hosts in the viz output", - "-b, --includebundles", - "include bundles in the viz output", - "-k, --includekey", - "show a key for different digraph shapes", - "-o, --outfile <file>", - "write viz output to an output file")) - - colors = ['steelblue1', 'chartreuse', 'gold', 'magenta', - 'indianred1', 'limegreen', 'orange1', 'lightblue2', - 'green1', 'blue1', 'yellow1', 'darkturquoise', 'gray66'] - plugin_blacklist = ['DBStats', 'Snapshots', 'Cfg', 'Pkgmgr', 'Packages', - 'Rules', 'Account', 'Decisions', 'Deps', 'Git', 'Svn', - 'Fossil', 'Bzr', 'Bundler', 'TGenshi', 'SGenshi', 'Base'] - - def __init__(self, cfile): - - Bcfg2.Server.Admin.MetadataCore.__init__(self, cfile, - self.__usage__, - pblacklist=self.plugin_blacklist) - - def __call__(self, args): - Bcfg2.Server.Admin.MetadataCore.__call__(self, args) - # First get options to the 'viz' subcommand - try: - opts, args = getopt.getopt(args, 'Hbko:', - ['includehosts', 'includebundles', - 'includekey', 'outfile=']) - except getopt.GetoptError, msg: - print msg - - #FIXME: is this for --raw? - #rset = False - hset = False - bset = False - kset = False - outputfile = False - for opt, arg in opts: - if opt in ("-H", "--includehosts"): - hset = True - elif opt in ("-b", "--includebundles"): - bset = True - elif opt in ("-k", "--includekey"): - kset = True - elif opt in ("-o", "--outfile"): - outputfile = arg - - data = self.Visualize(self.get_repo_path(), hset, bset, - kset, outputfile) - print data - raise SystemExit, 0 - - def Visualize(self, repopath, hosts=False, - bundles=False, key=False, output=False): - """Build visualization of groups file.""" - if output: - format = output.split('.')[-1] - else: - format = 'png' - - cmd = "dot -T%s" % (format) - if output: - cmd += " -o %s" % output - dotpipe = Popen(cmd, shell=True, stdin=PIPE, - stdout=PIPE, close_fds=True) - try: - dotpipe.stdin.write("digraph groups {\n") - except: - 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, - key, self.colors)) - if key: - dotpipe.stdin.write("\tsubgraph cluster_key {\n") - dotpipe.stdin.write('''\tstyle="filled";\n''') - dotpipe.stdin.write('''\tcolor="lightblue";\n''') - dotpipe.stdin.write('''\tBundle [ shape="septagon" ];\n''') - dotpipe.stdin.write('''\tGroup [shape="ellipse"];\n''') - dotpipe.stdin.write('''\tProfile [style="bold", shape="ellipse"];\n''') - dotpipe.stdin.write('''\tHblock [label="Host1|Host2|Host3", shape="record"];\n''') - dotpipe.stdin.write('''\tlabel="Key";\n''') - dotpipe.stdin.write("\t}\n") - dotpipe.stdin.write("}\n") - dotpipe.stdin.close() - return dotpipe.stdout.read() diff --git a/build/lib/Bcfg2/Server/Admin/Web.py b/build/lib/Bcfg2/Server/Admin/Web.py deleted file mode 100644 index 5ad14f2b9..000000000 --- a/build/lib/Bcfg2/Server/Admin/Web.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import sys -import BaseHTTPServer -import SimpleHTTPServer -import daemon -import Bcfg2.Server.Admin -import Bcfg2.Options - -# For debugging output only -import logging -logger = logging.getLogger('Bcfg2.Server.Admin.Web') - -class Web(Bcfg2.Server.Admin.Mode): - __shorthelp__ = "A simple webserver to display the content of the Bcfg2 repos." - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin web start\n" - "\n\nbcfg2-admin web stop") - __usage__ = ("bcfg2-admin web [start|stop]") - - def __init__(self, configfile): - Bcfg2.Server.Admin.Mode.__init__(self, configfile) - - def __call__(self, args): - Bcfg2.Server.Admin.Mode.__call__(self, args) - opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} - setup = Bcfg2.Options.OptionParser(opts) - setup.parse(sys.argv[1:]) - repo = setup['repo'] - - if len(args) == 0 or args[0] == '-h': - print(self.__usage__) - raise SystemExit(0) - - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin web help for usage.") - - if args[0] in ['start', 'up']: - # Change directory to the Bcfg2 repo - if not os.path.exists(repo): - #print "Path '%s' doesn't exisit" % repo - logger.error("%s doesn't exist" % repo) - else: - os.chdir(repo) - self.start_web() - - elif args[0] in ['stop', 'down']: - self.stop_web() - - else: - print "No command specified" - raise SystemExit(1) - - # The web server part with hardcoded port number - def start_web(self, port=6788): - """Starts the webserver for directory listing of the Bcfg2 repo.""" - try: - server_class = BaseHTTPServer.HTTPServer - handler_class = SimpleHTTPServer.SimpleHTTPRequestHandler - server_address = ('', port) - server = server_class(server_address, handler_class) - #server.serve_forever() - # Make the context manager for becoming a daemon process - daemon_context = daemon.DaemonContext() - daemon_context.files_preserve = [server.fileno()] - - # Become a daemon process - with daemon_context: - server.serve_forever() - except: - logger.error("Failed to start webserver") - #raise Bcfg2.Server.Admin.AdminInitError - - def stop_web(self): - """Stops the webserver.""" -# self.shutdown = 1 - self.shutdown() - # self.stopped = True -# self.serve_forever() - diff --git a/build/lib/Bcfg2/Server/Admin/Xcmd.py b/build/lib/Bcfg2/Server/Admin/Xcmd.py deleted file mode 100644 index 80d5cfb25..000000000 --- a/build/lib/Bcfg2/Server/Admin/Xcmd.py +++ /dev/null @@ -1,49 +0,0 @@ -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") - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin xcmd command") - __usage__ = ("bcfg2-admin xcmd <command>") - - def __call__(self, args): - optinfo = { - 'server': Bcfg2.Options.SERVER_LOCATION, - '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 - } - setup = Bcfg2.Options.OptionParser(optinfo) - setup.parse(sys.argv[2:]) - Bcfg2.Proxy.RetryMethod.max_retries = 1 - proxy = Bcfg2.Proxy.ComponentProxy(setup['server'], - setup['user'], - setup['password'], - key = setup['key'], - cert = setup['certificate'], - ca = setup['ca'], timeout=180) - if len(setup['args']) == 0: - print("Usage: xcmd <xmlrpc method> <optional arguments>") - return - cmd = setup['args'][0] - args = () - if len(setup['args']) > 1: - args = tuple(setup['args'][1:]) - try: - data = apply(getattr(proxy, cmd), args) - except xmlrpclib.Fault, flt: - if flt.faultCode == 7: - print("Unknown method %s" % cmd) - return - elif flt.faultCode == 20: - return - else: - raise - if data != None: - print data diff --git a/build/lib/Bcfg2/Server/Admin/__init__.py b/build/lib/Bcfg2/Server/Admin/__init__.py deleted file mode 100644 index bb5c41895..000000000 --- a/build/lib/Bcfg2/Server/Admin/__init__.py +++ /dev/null @@ -1,114 +0,0 @@ -__revision__ = '$Revision$' - -__all__ = ['Mode', 'Client', 'Compare', 'Init', 'Minestruct', 'Perf', - 'Pull', 'Query', 'Reports', 'Snapshots', 'Tidy', 'Viz', - 'Xcmd', 'Group', 'Backup'] - -import ConfigParser -import logging -import lxml.etree -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 - self.log = logging.getLogger('Bcfg2.Server.Admin.Mode') - - def getCFP(self): - if not self.__cfp: - self.__cfp = ConfigParser.ConfigParser() - self.__cfp.read(self.configfile) - return self.__cfp - - cfp = property(getCFP) - - def __call__(self, args): - if len(args) > 0 and args[0] == 'help': - print self.__longhelp__ - raise SystemExit(0) - - def errExit(self, emsg): - print emsg - raise SystemExit(1) - - def get_repo_path(self): - """Return repository path""" - return self.cfp.get('server', 'repository') - - def load_stats(self, client): - stats = lxml.etree.parse("%s/etc/statistics.xml" % - (self.get_repo_path())) - hostent = stats.xpath('//Node[@name="%s"]' % client) - if not hostent: - self.errExit("Could not find stats for client %s" % (client)) - return hostent[0] - - def print_table(self, rows, justify='left', hdr=True, vdelim=" ", padding=1): - """Pretty print a table - - rows - list of rows ([[row 1], [row 2], ..., [row n]]) - hdr - if True the first row is treated as a table header - vdelim - vertical delimiter between columns - padding - # of spaces around the longest element in the column - justify - may be left,center,right - - """ - hdelim = "=" - justify = {'left':str.ljust, - 'center':str.center, - 'right':str.rjust}[justify.lower()] - - """ - Calculate column widths (longest item in each column - plus padding on both sides) - - """ - cols = list(zip(*rows)) - colWidths = [max([len(str(item))+2*padding for \ - item in col]) for col in cols] - borderline = vdelim.join([w*hdelim for w in colWidths]) - - # print out the table - print(borderline) - for row in rows: - print(vdelim.join([justify(str(item), width) for \ - (item, width) in zip(row, colWidths)])) - if hdr: - print(borderline) - hdr = False - -class MetadataCore(Mode): - """Base class for admin-modes that handle metadata.""" - def __init__(self, configfile, usage, pwhitelist=None, pblacklist=None): - Mode.__init__(self, configfile) - options = {'plugins': Bcfg2.Options.SERVER_PLUGINS, - 'configfile': Bcfg2.Options.CFILE} - setup = Bcfg2.Options.OptionParser(options) - 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] - elif pblacklist is not None: - 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'], - 'foo', 'UTF-8') - except Bcfg2.Server.Core.CoreInitError, msg: - self.errExit("Core load failed because %s" % msg) - self.bcore.fam.handle_events_in_interval(5) - self.metadata = self.bcore.metadata - -class StructureMode(MetadataCore): - pass diff --git a/build/lib/Bcfg2/Server/Admin/test.py b/build/lib/Bcfg2/Server/Admin/test.py deleted file mode 100644 index 06271b186..000000000 --- a/build/lib/Bcfg2/Server/Admin/test.py +++ /dev/null @@ -1,73 +0,0 @@ -import os -import time -import tarfile -import sys -datastore = '/var/lib/bcfg2' - -#Popen(['git', 'clone', 'https://github.com/solj/bcfg2-repo.git', datastore]) -#timestamp = time.strftime('%Y%m%d%H%M%S') -#format = 'gz' -#mode = 'w:' + format -#filename = timestamp + '.tar' + '.' + format -#out = tarfile.open('/home/fab/' + filename, mode=mode) - - -#content = os.listdir(os.getcwd()) -#for item in content: -# out.add(item) -#out.close() -#print "Archive %s was stored.\nLocation: %s" % (filename, datastore) - -#print os.getcwd() -#print os.listdir(os.getcwd()) - -#import shlex -#args = shlex.split('env LC_ALL=C git clone https://github.com/solj/bcfg2-repo.git datastore') -#print args - -#Popen("env LC_ALL=C git clone https://github.com/solj/bcfg2-repo.git datastore") - -#timestamp = time.strftime('%Y%m%d%H%M%S') -#format = 'gz' -#mode = 'w:' + format -#filename = timestamp + '.tar' + '.' + format -#out = tarfile.open(name = filename, mode = mode) -##content = os.listdir(datastore) -##for item in content: -## out.add(item) -##out.close() - -###t = tarfile.open(name = destination, mode = 'w:gz') -#out.add(datastore, os.path.basename(datastore)) -#out.close() - -#print datastore, os.path.basename(datastore) - -#content = os.listdir(datastore) -#for item in content: -# #out.add(item) -# print item - -#timestamp = time.strftime('%Y%m%d%H%M%S') -#format = 'gz' -#mode = 'w:' + format -#filename = timestamp + '.tar' + '.' + format - -if len(sys.argv) == 0: - destination = datastore + '/' -else: - destination = sys.argv[1] - -print destination -#out = tarfile.open(destination + filename, mode=mode) -#out.add(self.datastore, os.path.basename(self.datastore)) -#out.close() -#print "Archive %s was stored at %s" % (filename, destination) - -#print 'Die Kommandozeilenparameter sind:' -##for i in sys.argv: -## print i - -#print sys.argv[0] -#print sys.argv[1] -##print sys.argv[2] |