summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/bcfg2-profile-templates.py110
-rwxr-xr-xtools/bcfg2_local.py9
-rwxr-xr-xtools/export.py43
-rwxr-xr-xtools/posixusers_baseline.py4
-rwxr-xr-xtools/selinux_baseline.py5
-rw-r--r--tools/upgrade/1.3/README5
-rwxr-xr-xtools/upgrade/1.3/migrate_dbstats.py19
-rwxr-xr-xtools/upgrade/1.3/migrate_info.py6
-rwxr-xr-xtools/upgrade/1.3/migrate_perms_to_mode.py5
-rwxr-xr-xtools/upgrade/1.3/migrate_probe_groups_to_db.py68
-rwxr-xr-xtools/yum-listpkgs-xml.py2
11 files changed, 212 insertions, 64 deletions
diff --git a/tools/bcfg2-profile-templates.py b/tools/bcfg2-profile-templates.py
index 3cd3786f9..f4069e454 100755
--- a/tools/bcfg2-profile-templates.py
+++ b/tools/bcfg2-profile-templates.py
@@ -1,25 +1,49 @@
#!/usr/bin/python -Ott
+# -*- coding: utf-8 -*-
""" Benchmark template rendering times """
-import os
import sys
import time
+import math
+import signal
import logging
import operator
import Bcfg2.Logger
+import Bcfg2.Options
import Bcfg2.Server.Core
-LOGGER = None
+
+def stdev(nums):
+ mean = float(sum(nums)) / len(nums)
+ return math.sqrt(sum((n - mean)**2 for n in nums) / float(len(nums)))
+
+
+def get_sigint_handler(core):
+ """ Get a function that handles SIGINT/Ctrl-C by shutting down the
+ core and exiting properly."""
+
+ def hdlr(sig, frame): # pylint: disable=W0613
+ """ Handle SIGINT/Ctrl-C by shutting down the core and exiting
+ properly. """
+ core.shutdown()
+ os._exit(1) # pylint: disable=W0212
+
+ return hdlr
def main():
- optinfo = \
- dict(client=Bcfg2.Options.Option("Benchmark templates for one client",
- cmd="--client",
- odesc="<client>",
- long_arg=True,
- default=None),
- )
+ optinfo = dict(
+ client=Bcfg2.Options.Option("Benchmark templates for one client",
+ cmd="--client",
+ odesc="<client>",
+ long_arg=True,
+ default=None),
+ runs=Bcfg2.Options.Option("Number of rendering passes per template",
+ cmd="--runs",
+ odesc="<runs>",
+ long_arg=True,
+ default=5,
+ cook=int))
optinfo.update(Bcfg2.Options.CLI_COMMON_OPTIONS)
optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS)
setup = Bcfg2.Options.OptionParser(optinfo)
@@ -39,13 +63,13 @@ def main():
logger = logging.getLogger(sys.argv[0])
core = Bcfg2.Server.Core.BaseCore(setup)
+ signal.signal(signal.SIGINT, get_sigint_handler(core))
logger.info("Bcfg2 server core loaded")
+ core.load_plugins()
+ logger.debug("Plugins loaded")
core.fam.handle_events_in_interval(0.1)
logger.debug("Repository events processed")
- # how many times to render each template for each client
- runs = 5
-
if setup['args']:
templates = setup['args']
else:
@@ -57,41 +81,57 @@ def main():
clients = [core.build_metadata(setup['client'])]
times = dict()
+ client_count = 0
for metadata in clients:
- for struct in core.GetStructures(metadata):
- logger.info("Rendering templates from structure %s:%s" %
- (struct.tag, struct.get("name")))
- for entry in struct.xpath("//Path"):
- path = entry.get("name")
- logger.info("Rendering %s..." % path)
- times[path] = dict()
- avg = 0.0
- for i in range(runs):
+ client_count += 1
+ logger.info("Rendering templates for client %s (%s/%s)" %
+ (metadata.hostname, client_count, len(clients)))
+ structs = core.GetStructures(metadata)
+ struct_count = 0
+ for struct in structs:
+ struct_count += 1
+ logger.info("Rendering templates from structure %s:%s (%s/%s)" %
+ (struct.tag, struct.get("name"), struct_count,
+ len(structs)))
+ entries = struct.xpath("//Path")
+ entry_count = 0
+ for entry in entries:
+ entry_count += 1
+ if templates and entry.get("name") not in templates:
+ continue
+ logger.info("Rendering Path:%s (%s/%s)..." %
+ (entry.get("name"), entry_count, len(entries)))
+ ptimes = times.setdefault(entry.get("name"), [])
+ for i in range(setup['runs']):
start = time.time()
try:
core.Bind(entry, metadata)
- avg += (time.time() - start) / runs
+ ptimes.append(time.time() - start)
except:
break
- if avg:
- logger.debug(" %s: %.02f sec" % (metadata.hostname, avg))
- times[path][metadata.hostname] = avg
+ if ptimes:
+ avg = sum(ptimes) / len(ptimes)
+ if avg:
+ logger.debug(" %s: %.02f sec" %
+ (metadata.hostname, avg))
# print out per-file results
tmpltimes = []
- for tmpl, clients in times.items():
+ for tmpl, ptimes in times.items():
try:
- avg = sum(clients.values()) / len(clients)
+ mean = float(sum(ptimes)) / len(ptimes)
except ZeroDivisionError:
continue
- if avg > 0.01 or templates:
- tmpltimes.append((tmpl, avg))
- print("%-50s %s" % ("Template", "Average Render Time"))
- for tmpl, avg in reversed(sorted(tmpltimes, key=operator.itemgetter(1))):
- print("%-50s %.02f" % (tmpl, avg))
-
- # TODO: complain about templates that on average were quick but
- # for which some clients were slow
+ ptimes.sort()
+ median = ptimes[len(ptimes) / 2]
+ std = stdev(ptimes)
+ if mean > 0.01 or median > 0.01 or std > 1 or templates:
+ tmpltimes.append((tmpl, mean, median, std))
+ print("%-50s %-9s %-11s %6s" %
+ ("Template", "Mean Time", "Median Time", "σ"))
+ for info in reversed(sorted(tmpltimes, key=operator.itemgetter(1))):
+ print("%-50s %9.02f %11.02f %6.02f" % info)
+ core.shutdown()
if __name__ == "__main__":
diff --git a/tools/bcfg2_local.py b/tools/bcfg2_local.py
index 2b9d39342..8c164e52e 100755
--- a/tools/bcfg2_local.py
+++ b/tools/bcfg2_local.py
@@ -19,7 +19,8 @@ class LocalCore(BaseCore):
setup['logging'] = None
Bcfg2.Server.Core.BaseCore.__init__(self, setup=setup)
setup['syslog'], setup['logging'] = saved
- self.fam.handle_events_in_interval(4)
+ self.load_plugins()
+ self.fam.handle_events_in_interval(0.1)
def _daemonize(self):
return True
@@ -64,6 +65,12 @@ class LocalClient(Client):
def main():
optinfo = Bcfg2.Options.CLIENT_COMMON_OPTIONS
optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS)
+ if 'bundle_quick' in optinfo:
+ # CLIENT_BUNDLEQUICK option uses -Q, just like the server repo
+ # option. the server repo is more important for this
+ # application.
+ optinfo['bundle_quick'] = Bcfg2.Options.Option('bundlequick',
+ default=False)
setup = Bcfg2.Options.OptionParser(optinfo)
setup.parse(sys.argv[1:])
diff --git a/tools/export.py b/tools/export.py
index 716c831d9..7c3c56db2 100755
--- a/tools/export.py
+++ b/tools/export.py
@@ -136,8 +136,7 @@ E.G. 1.2.0pre1 is a valid version.
tarname = '/tmp/%s-%s.tar.gz' % (pkgname, version)
- newchangelog = \
-"""bcfg2 (%s-0.0) unstable; urgency=low
+ newchangelog = """bcfg2 (%s-0.0) unstable; urgency=low
* New upstream release
@@ -177,7 +176,9 @@ E.G. 1.2.0pre1 is a valid version.
"- New upstream release\n", "\n"]
# write out the new RPM changelog
- specs = ["misc/bcfg2.spec", "misc/bcfg2-selinux.spec", "redhat/bcfg2.spec.in"]
+ specs = ["misc/bcfg2.spec",
+ "misc/bcfg2-selinux.spec",
+ "redhat/bcfg2.spec.in"]
if options.dryrun:
print("*** Add the following to the top of the %%changelog section in %s:\n%s\n"
% (rpmchangelog, " and ".join(specs)))
@@ -227,8 +228,28 @@ E.G. 1.2.0pre1 is a valid version.
'VERSION="%s"\n' % version,
startswith=True,
dryrun=options.dryrun)
- # set new version in setup.py
- find_and_replace('setup.py', 'version=', ' version="%s",\n' % version,
+ # update solaris IPS version
+ find_and_replace('solaris-ips/Makefile', 'VERS=',
+ 'VERS=%s-1\n' % version,
+ startswith=True,
+ dryrun=options.dryrun)
+ find_and_replace('solaris-ips/MANIFEST.bcfg2.header',
+ 'set name=pkg.fmri value="pkg://bcfg2/bcfg2@',
+ 'set name=pkg.fmri value="pkg://bcfg2/bcfg2@%s"' % version,
+ startswith=True,
+ dryrun=options.dryrun)
+ find_and_replace('solaris-ips/MANIFEST.bcfg2-server.header',
+ 'set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@',
+ 'set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@%s"' % version,
+ startswith=True,
+ dryrun=options.dryrun)
+ find_and_replace('solaris-ips/pkginfo.bcfg2', 'VERSION=',
+ 'VERSION="%s"\n' % version,
+ startswith=True,
+ dryrun=options.dryrun)
+ find_and_replace('solaris-ips/pkginfo.bcfg2-server', 'VERSION=',
+ 'VERSION="%s"\n' % version,
+ startswith=True,
dryrun=options.dryrun)
# set new version in Bcfg2/version.py
find_and_replace('src/lib/Bcfg2/version.py',
@@ -252,30 +273,30 @@ E.G. 1.2.0pre1 is a valid version.
else:
find_and_replace('misc/bcfg2.spec', 'Release: ',
'Release: 0.%s.%s\n' %
- (version_info['build'][-1], version_info['build']),
+ (version_info['build'][-1], version_info['build']),
dryrun=options.dryrun)
find_and_replace('misc/bcfg2-selinux.spec', 'Release: ',
'Release: 0.%s.%s\n' %
- (version_info['build'][-1], version_info['build']),
+ (version_info['build'][-1], version_info['build']),
dryrun=options.dryrun)
find_and_replace('misc/bcfg2.spec', '%setup',
'%%setup -q -n %%{name}-%%{version}%s\n' %
- version_info['build'],
+ version_info['build'],
startswith=True,
dryrun=options.dryrun)
find_and_replace('misc/bcfg2-selinux.spec', '%setup',
'%%setup -q -n %%{name}-%%{version}%s\n' %
- version_info['build'],
+ version_info['build'],
startswith=True,
dryrun=options.dryrun)
find_and_replace('misc/bcfg2.spec', 'BuildRoot',
'BuildRoot: %%{_tmppath}/%%{name}-%%{version}%s-%%{release}-root-%%(%%{__id_u} -n)\n' %
- version_info['build'],
+ version_info['build'],
startswith=True,
dryrun=options.dryrun)
find_and_replace('misc/bcfg2-selinux.spec', 'BuildRoot',
'BuildRoot: %%{_tmppath}/%%{name}-%%{version}%s-%%{release}-root-%%(%%{__id_u} -n)\n' %
- version_info['build'],
+ version_info['build'],
startswith=True,
dryrun=options.dryrun)
# fix pre problem noted in
diff --git a/tools/posixusers_baseline.py b/tools/posixusers_baseline.py
index a4abca42d..c45e54f1a 100755
--- a/tools/posixusers_baseline.py
+++ b/tools/posixusers_baseline.py
@@ -61,8 +61,8 @@ def main():
if entry.tag == 'POSIXUser':
entry.set("group", grp.getgrgid(data[3])[0])
for group in users.user_supplementary_groups(entry):
- memberof = lxml.etree.SubElement(entry, "MemberOf")
- memberof.text = group[0]
+ memberof = lxml.etree.SubElement(entry, "MemberOf",
+ group=group[0])
entry.tag = "Bound" + entry.tag
baseline.append(entry)
diff --git a/tools/selinux_baseline.py b/tools/selinux_baseline.py
index b6997bb29..507a16f43 100755
--- a/tools/selinux_baseline.py
+++ b/tools/selinux_baseline.py
@@ -42,7 +42,10 @@ def main():
baseline.append(lxml.etree.Comment("%s entries" % etype))
extra = handler.FindExtra()
for entry in extra:
- entry.tag = "BoundSELinux"
+ if etype != "SEModule":
+ entry.tag = "Bound%s" % etype
+ else:
+ entry.tag = "%s" % etype
baseline.extend(extra)
print(lxml.etree.tostring(baseline, pretty_print=True))
diff --git a/tools/upgrade/1.3/README b/tools/upgrade/1.3/README
index 2831d8f00..1a919f869 100644
--- a/tools/upgrade/1.3/README
+++ b/tools/upgrade/1.3/README
@@ -19,3 +19,8 @@ migrate_dbstats.py
migrate_perms_to_mode.py
- Convert perms attribute to mode (note that if you have info/:info
files, you should run migrate_info.py first)
+
+migrate_probe_groups_to_db.py
+ - Migrate Probe host and group data from XML to DB backend for Metadata
+ and Probe plugins. Does not migrate individual probe return data. Assumes
+ migration to BOTH Metadata and Probe to database backends.
diff --git a/tools/upgrade/1.3/migrate_dbstats.py b/tools/upgrade/1.3/migrate_dbstats.py
index cbd2a6099..07def2ac8 100755
--- a/tools/upgrade/1.3/migrate_dbstats.py
+++ b/tools/upgrade/1.3/migrate_dbstats.py
@@ -21,6 +21,7 @@ logger = logging.getLogger(__name__)
_our_backend = None
+
def _quote(value):
"""
Quote a string to use as a table name or column
@@ -44,12 +45,12 @@ def _migrate_perms():
fperms = {}
logger.info("Creating FilePerms objects")
- for data in ( ('owner', 'group', 'perms'),
+ for data in (('owner', 'group', 'perms'),
('current_owner', 'current_group', 'current_perms')):
for grp in legacy_models.Reason.objects.values_list(*data).distinct():
if grp in fperms:
continue
- fp = new_models.FilePerms(owner=grp[0], group=grp[1], mode=grp[2])
+ fp = new_models.FilePerms(owner=grp[0], group=grp[1], mode=grp[2])
fp.save()
fperms[grp] = fp
@@ -60,7 +61,7 @@ def _migrate_perms():
def _migrate_transaction(inter, entries, fperms):
"""helper"""
- logger.debug("Migrating interaction %s for %s" %
+ logger.debug("Migrating interaction %s for %s" %
(inter.id, inter.client.name))
newint = new_models.Interaction(id=inter.id,
@@ -107,7 +108,7 @@ def _migrate_transaction(inter, entries, fperms):
elif ent.kind == 'Package':
act_dict['target_version'] = ei.reason.version
act_dict['current_version'] = ei.reason.current_version
- logger.debug("Adding package %s %s" %
+ logger.debug("Adding package %s %s" %
(name, act_dict['target_version']))
updates['packages'].append(new_models.PackageEntry.entry_get_or_create(act_dict))
elif ent.kind == 'Path':
@@ -116,7 +117,7 @@ def _migrate_transaction(inter, entries, fperms):
act_dict['target_perms'] = fperms[(
ei.reason.owner,
- ei.reason.group,
+ ei.reason.group,
ei.reason.perms
)]
@@ -141,7 +142,6 @@ def _migrate_transaction(inter, entries, fperms):
act_dict['detail_type'] = new_models.PathEntry.DETAIL_PRUNED
act_dict['details'] = ei.reason.unpruned
-
if ei.reason.is_sensitive:
act_dict['detail_type'] = new_models.PathEntry.DETAIL_SENSITIVE
elif ei.reason.is_binary:
@@ -164,7 +164,7 @@ def _migrate_transaction(inter, entries, fperms):
for entry_type in updates.keys():
i = 0
while(i < len(updates[entry_type])):
- getattr(newint, entry_type).add(*updates[entry_type][i:i+100])
+ getattr(newint, entry_type).add(*updates[entry_type][i:i + 100])
i += 100
for perf in inter.performance_items.all():
@@ -220,8 +220,8 @@ def _restructure():
# run any migrations from the previous schema
try:
- from Bcfg2.Server.Reports.updatefix import update_database
- update_database()
+ from Bcfg2.Server.Reports.updatefix import update_database
+ update_database()
except:
logger.error("Failed to run legacy schema updates", exc_info=1)
return False
@@ -295,4 +295,3 @@ if __name__ == '__main__':
Reports(setup).__call__(['update'])
_restructure()
-
diff --git a/tools/upgrade/1.3/migrate_info.py b/tools/upgrade/1.3/migrate_info.py
index e72599daf..3ccbf0285 100755
--- a/tools/upgrade/1.3/migrate_info.py
+++ b/tools/upgrade/1.3/migrate_info.py
@@ -1,12 +1,16 @@
#!/usr/bin/env python
import os
+import re
import sys
import lxml.etree
import Bcfg2.Options
from Bcfg2.Server.Plugin import INFO_REGEX
+PERMS_REGEX = re.compile(r'perms:\s*(?P<perms>\w+)')
+
+
def convert(info_file):
info_xml = os.path.join(os.path.dirname(info_file), "info.xml")
if os.path.exists(info_xml):
@@ -16,7 +20,7 @@ def convert(info_file):
fileinfo = lxml.etree.Element("FileInfo")
info = lxml.etree.SubElement(fileinfo, "Info")
for line in open(info_file).readlines():
- match = INFO_REGEX.match(line)
+ match = INFO_REGEX.match(line) or PERMS_REGEX.match(line)
if match:
mgd = match.groupdict()
for key, value in list(mgd.items()):
diff --git a/tools/upgrade/1.3/migrate_perms_to_mode.py b/tools/upgrade/1.3/migrate_perms_to_mode.py
index e061558d3..18abffec2 100755
--- a/tools/upgrade/1.3/migrate_perms_to_mode.py
+++ b/tools/upgrade/1.3/migrate_perms_to_mode.py
@@ -13,6 +13,7 @@ def setmodeattr(elem):
elem.set('mode', elem.get('perms'))
del elem.attrib['perms']
return True
+ return False
def writefile(f, xdata):
@@ -32,7 +33,7 @@ def convertinfo(ifile):
return
found = False
for i in xdata.findall('//Info'):
- found = setmodeattr(i)
+ found |= setmodeattr(i)
if found:
writefile(ifile, xdata)
@@ -47,7 +48,7 @@ def convertstructure(structfile):
return
found = False
for path in xdata.xpath('//BoundPath|//Path'):
- found = setmodeattr(path)
+ found |= setmodeattr(path)
if found:
writefile(structfile, xdata)
diff --git a/tools/upgrade/1.3/migrate_probe_groups_to_db.py b/tools/upgrade/1.3/migrate_probe_groups_to_db.py
new file mode 100755
index 000000000..73339e787
--- /dev/null
+++ b/tools/upgrade/1.3/migrate_probe_groups_to_db.py
@@ -0,0 +1,68 @@
+#!/bin/env python
+""" Migrate Probe host and group data from XML to DB backend for Metadata
+and Probe plugins. Does not migrate individual probe return data. Assumes
+migration to BOTH Metadata and Probe to database backends. """
+
+import os
+os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.settings'
+
+import lxml.etree
+import sys
+import Bcfg2.Options
+
+from Bcfg2.Server.Plugins.Metadata import MetadataClientModel
+from Bcfg2.Server.Plugins.Probes import ProbesGroupsModel
+
+def migrate(xclient):
+ """ Helper to do the migration given a <Client/> XML element """
+ client_name = xclient.get('name')
+ try:
+ try:
+ client = MetadataClientModel.objects.get(hostname=client_name)
+ except MetadataClientModel.DoesNotExist:
+ client = MetadataClientModel(hostname=client_name)
+ client.save()
+ except:
+ print("Failed to migrate client %s" % (client))
+ return False
+
+ try:
+ cgroups = []
+ for xgroup in xclient.findall('Group'):
+ group_name = xgroup.get('name')
+ cgroups.append(group_name)
+ try:
+ group = ProbesGroupsModel.objects.get(hostname=client_name, group=group_name)
+ except ProbesGroupsModel.DoesNotExist:
+ group = ProbesGroupsModel(hostname=client_name, group=group_name)
+ group.save()
+
+ ProbesGroupsModel.objects.filter(
+ hostname=client.hostname).exclude(
+ group__in=cgroups).delete()
+
+ except:
+ print("Failed to migrate groups")
+ return False
+ return True
+
+def main():
+ """ Main """
+ opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY)
+ setup = Bcfg2.Options.OptionParser(opts)
+ setup.parse(sys.argv[1:])
+
+ probefile = os.path.join(setup['repo'], 'Probes', "probed.xml")
+
+ try:
+ xdata = lxml.etree.parse(probefile)
+ except lxml.etree.XMLSyntaxError:
+ err = sys.exc_info()[1]
+ print("Could not parse %s, skipping: %s" % (probefile, err))
+
+ for xclient in xdata.findall('Client'):
+ print "Migrating Metadata and Probe groups for %s" % xclient.get('name')
+ migrate(xclient)
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/yum-listpkgs-xml.py b/tools/yum-listpkgs-xml.py
index a052e75af..b4c5f6589 100755
--- a/tools/yum-listpkgs-xml.py
+++ b/tools/yum-listpkgs-xml.py
@@ -39,5 +39,5 @@ try:
sys.argv = [sys.argv[0], '-d', '0', 'list']
yummain.main(sys.argv[1:])
except KeyboardInterrupt:
- print("\n\nExiting on user cancel.", file=sys.stderr)
+ sys.stderr.write("\n\nExiting on user cancel.")
sys.exit(1)