diff options
54 files changed, 305 insertions, 131 deletions
diff --git a/debian/bcfg2-server.init b/debian/bcfg2-server.init index b1c3aba21..cd2ad858e 100755 --- a/debian/bcfg2-server.init +++ b/debian/bcfg2-server.init @@ -33,8 +33,8 @@ BCFG2_SERVER_ENABLED=0 test -f "/etc/default/bcfg2-server" && . /etc/default/bcfg2-server if [ "$BCFG2_SERVER_ENABLED" -eq 0 ] ; then - log_failure_msg "bcfg2-server is disabled - see /etc/default/bcfg2-server" - exit 0 + log_failure_msg "bcfg2-server is disabled - see /etc/default/bcfg2-server" + exit 0 fi # Exit if $DAEMON doesn't exist and is not executable @@ -63,10 +63,11 @@ stop () { killproc -p $PIDFILE ${BINARY} STATUS=$? if [ "$STATUS" = 0 ]; then - log_success_msg "bcfg2-server" - test -d /var/lock/subsys && touch /var/lock/subsys/bcfg2-server + [ -e $PIDFILE ] && rm -f $PIDFILE + log_success_msg "bcfg2-server" + test -d /var/lock/subsys && touch /var/lock/subsys/bcfg2-server else - log_failure_msg "bcfg2-server" + log_failure_msg "bcfg2-server" fi return $STATUS } @@ -75,15 +76,15 @@ status () { # Inspired by redhat /etc/init.d/functions status() call PID=$(pidof -x $BINARY -o %PPID) if [ -n "$PID" ]; then - echo "$BINARY (pid $PID) is running..." - return 0 + echo "$BINARY (pid $PID) is running..." + return 0 fi if [ -f $PIDFILE ]; then - if [ -n "$PID" ]; then - log_failure_msg "$BINARY dead but pid file exists..." - return 1 - fi + if [ -n "$PID" ]; then + log_failure_msg "$BINARY dead but pid file exists..." + return 1 + fi fi log_failure_msg "$BINARY is not running" diff --git a/debian/changelog b/debian/changelog index b6d7644b9..3879cc50a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +bcfg2 (1.3.5-0.0) unstable; urgency=low + + * New upstream release + + -- Sol Jerome <sol.jerome@gmail.com> Fri, 05 Sep 2014 07:54:48 -0500 + bcfg2 (1.3.4-0.0) unstable; urgency=low * New upstream release diff --git a/doc/client/tools.txt b/doc/client/tools.txt index 1dbb33b1a..ce8732454 100644 --- a/doc/client/tools.txt +++ b/doc/client/tools.txt @@ -154,7 +154,28 @@ Systemd service support. SYSV ---- -Handles System V Packaging format that is available on Solaris. +Handles `System V Packaging <http://docs.oracle.com/cd/E19683-01/806-7008/index.html>`_ format that is available on Solaris. + +.. note:: + + If the Packages specified in the PackageList are datastream format packages distributed via HTTP, you must specify a simplename attribute. Such packages will be downloaded and installed from a local path. + + datastream format over HTTP: + + .. code-block:: xml + + <PackageList url='http://install/packages' type='sysv' priority='0'> + <Package name='SCbcfg2' version='1.3.4' simplename='bcfg-1.3.4-1' /> + </PackageList> + + File system format over NFS or local path: + + .. code-block:: xml + + <PackageList url='/mnt/install/packages' type='sysv' priority='0'> + <Package name='SCbcfg2' version='1.3.4' /> + </PackageList> + Upstart ------- diff --git a/doc/conf.py b/doc/conf.py index 1b19d92c7..3e877ef80 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -66,7 +66,7 @@ else: # The short X.Y version. version = '1.3' # The full version, including alpha/beta/rc tags. -release = '1.3.4' +release = '1.3.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/development/compat.txt b/doc/development/compat.txt index f90274ce5..8700c46d3 100644 --- a/doc/development/compat.txt +++ b/doc/development/compat.txt @@ -60,6 +60,8 @@ behavior (e.g., :func:`input`) do not cause unexpected side-effects. +---------------------------------+--------------------------------------------------+---------------------------------------------------------+ | urlparse | :func:`urlparse.urlparse` | :func:`urllib.parse.urlparse` | +---------------------------------+--------------------------------------------------+---------------------------------------------------------+ +| urlretrieve | :func:`urllib.urlretrieve` | :func:`urllib.request.urlretrieve` | ++---------------------------------+--------------------------------------------------+---------------------------------------------------------+ | HTTPBasicAuthHandler | :class:`urllib2.HTTPBasicAuthHandler` | :class:`urllib.request.HTTPBasicAuthHandler` | +---------------------------------+--------------------------------------------------+---------------------------------------------------------+ | HTTPPasswordMgrWithDefaultRealm | :class:`urllib2.HTTPPasswordMgrWithDefaultRealm` | :class:`urllib.request.HTTPPasswordMgrWithDefaultRealm` | diff --git a/doc/installation/distributions.txt b/doc/installation/distributions.txt index 306439485..5dad4d860 100644 --- a/doc/installation/distributions.txt +++ b/doc/installation/distributions.txt @@ -36,9 +36,9 @@ Just use `pacman` to perform the installation :: Debian ====== -Packages of Bcfg2 are available for Debian Lenny, Debian Squeeze, and -Debian Sid. The fastest way to get Bcfg2 onto your Debian system -is to use ``apt-get`` or ``aptitude``. :: +Packages of Bcfg2 are available for all current versions of Debian. +The fastest way to get Bcfg2 onto your Debian system is to use ``apt-get`` +or ``aptitude``. :: sudo aptitude install bcfg2 bcfg2-server diff --git a/doc/releases/1.3.5.txt b/doc/releases/1.3.5.txt new file mode 100644 index 000000000..893cdbf39 --- /dev/null +++ b/doc/releases/1.3.5.txt @@ -0,0 +1,33 @@ +.. -*- mode: rst -*- +.. vim: ft=rst + +.. _releases-1.3.5: + +1.3.5 +===== + +We are happy to announce the release of Bcfg2 1.3.5. It is available for +download at: + + ftp://ftp.mcs.anl.gov/pub/bcfg + +This is primarily a bugfix release. + +* Properly close db connections +* Improved error messages +* Fix yum upgrade/downgrade +* Enable bcfg2-yum-helper to depsolve for arches incompatible with + server +* Spec file fixes +* bcfg2-crypet: Default to only (En|De)crypt vars that need it +* Fix email reporting bug +* Fix debsums parsing +* Fix solaris makefile +* SYSV: Implement downloading and installing SYSV packages from HTTP: + http://docs.bcfg2.org/client/tools.html#sysv +* Fix debian bcfg2-server init script + + +Special thanks to the following contributors for this release: John +Morris, Jonathan Billings, Chris Brinker, Tim Laszlo, Matt Kemp, Michael +Fenn, Pavel Labushev, Nathan Olla, Alexander Sulfrian. diff --git a/doc/releases/index.txt b/doc/releases/index.txt index 42a2306f6..1ed644f9c 100644 --- a/doc/releases/index.txt +++ b/doc/releases/index.txt @@ -7,4 +7,5 @@ Release Announcements ===================== +.. include:: 1.3.5.txt .. include:: 1.3.4.txt diff --git a/doc/server/plugins/connectors/awstags.txt b/doc/server/plugins/connectors/awstags.txt index b884ca065..5ac2fbc28 100644 --- a/doc/server/plugins/connectors/awstags.txt +++ b/doc/server/plugins/connectors/awstags.txt @@ -7,8 +7,8 @@ ========= The AWSTags plugin is a connector that retrieves tags from instances -in EC2, and can assign optionally assign -group membership pased on patterns in the tags. See `Using Tags +in EC2, and can optionally assign group membership based on patterns +in the tags. See `Using Tags <http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html>`_ for details on using tags in EC2. diff --git a/doc/server/plugins/connectors/templatehelper.txt b/doc/server/plugins/connectors/templatehelper.txt index 374aeb171..4b1f66aee 100644 --- a/doc/server/plugins/connectors/templatehelper.txt +++ b/doc/server/plugins/connectors/templatehelper.txt @@ -50,7 +50,7 @@ Usage Specific helpers can be referred to in templates as ``metadata.TemplateHelper[<modulename>]``. That accesses -a HelperModule object will has, as attributes, all symbols listed in +a HelperModule object will have, as attributes, all symbols listed in ``__export__``. For example, consider this helper module:: __export__ = ["hello"] diff --git a/doc/server/plugins/generators/cfg.txt b/doc/server/plugins/generators/cfg.txt index 0f0601105..541531581 100644 --- a/doc/server/plugins/generators/cfg.txt +++ b/doc/server/plugins/generators/cfg.txt @@ -297,15 +297,6 @@ processed for any Genshi or Cheetah base file. Cfg/etc/fstab/fstab.H_host.example.com.genshi Cfg/etc/fstab/fstab.G50_server.cheetah -Genshi templates take precence over cheetah templates. For example, if -two files exist named:: - - Cfg/etc/fstab/fstab.genshi - Cfg/etc/fstab/fstab.cheetah - -The Cheetah template is ignored. Exploiting this fact is probably a -pretty bad idea in practice. - You can mix Genshi and Cheetah when using different host-specific or group-specific files. For example:: @@ -600,7 +591,7 @@ Deltas .. warning:: In Bcfg2 1.3, deltas **do not** work with `SSH key or - authorized_keys generation <SSH Keys>`_. + authorized_keys generation <server-plugins-generators-cfg-sshkeys>`_. Bcfg2 has finer grained control over how to deliver configuration files to a host. Let's say we have a Group named file-server. Members diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index 7ef358a31..c27e6be4b 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -340,7 +340,7 @@ Here's what a functional **[communication]** section in a {% end %}\ As a client will not be able to authenticate with certificates it does -not yet posses we need to overcome the chicken and egg scenario the +not yet possess we need to overcome the chicken and egg scenario the first time we try to connect such a client to the server. We can do so using password based auth to boot strap the client manually specifying all the relevant auth parameters like so:: diff --git a/doc/server/plugins/structures/bundler/index.txt b/doc/server/plugins/structures/bundler/index.txt index a19959e66..51f2da60c 100644 --- a/doc/server/plugins/structures/bundler/index.txt +++ b/doc/server/plugins/structures/bundler/index.txt @@ -1,4 +1,5 @@ .. -*- mode: rst -*- +.. vim: ft=rst .. _server-plugins-structures-bundler-index: @@ -114,12 +115,12 @@ Genshi templates ================ Genshi XML templates allow you to use the `Genshi -<http://genshi.edgewall.org>`_ templating system to dynamically -generate a bundle. Genshi templates can be specified one of two ways: +<http://genshi.edgewall.org>`_ templating system to dynamically generate +a bundle. Genshi templates can be specified **one** of two ways: -1. Add an XML-style genshi template to the Bundler directory with a +* Add an XML-style genshi template to the Bundler directory with a ``.genshi`` and the associated namespace attribute. -2. Simply add the appropriate namespace attribute to your existing XML +* Simply add the appropriate namespace attribute to your existing XML bundle. The top-level Bundle tag should look like the following:: diff --git a/misc/bcfg2-selinux.spec b/misc/bcfg2-selinux.spec index d33953e08..c926a1d74 100644 --- a/misc/bcfg2-selinux.spec +++ b/misc/bcfg2-selinux.spec @@ -16,7 +16,7 @@ %global _pre_rc %{?_pre:.pre%{_pre}}%{?_rc:.rc%{_rc}} Name: bcfg2-selinux -Version: 1.3.4 +Version: 1.3.5 Release: 1%{?_pre_rc}%{?dist} Summary: Bcfg2 Client and Server SELinux policy diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index 12be59fd1..c2d3c3c90 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -29,8 +29,8 @@ Name: bcfg2 -Version: 1.3.4 -Release: 2%{?_pre_rc}%{?dist} +Version: 1.3.5 +Release: 1%{?_pre_rc}%{?dist} Summary: A configuration management system %if 0%{?suse_version} diff --git a/osx/Makefile b/osx/Makefile index 55ad9c8f2..ee7b7d565 100644 --- a/osx/Makefile +++ b/osx/Makefile @@ -29,9 +29,9 @@ SITELIBDIR = /Library/Python/${PYVERSION}/site-packages # an Info.plist file for packagemaker to look at for package creation # and substitute the version strings. Major/Minor versions can only be # integers (e.g. "1" and "00" for bcfg2 version 1.0.0. -BCFGVER = 1.3.4 +BCFGVER = 1.3.5 MAJOR = 1 -MINOR = 34 +MINOR = 35 default: clean client diff --git a/osx/macports/Portfile b/osx/macports/Portfile index 28e345c3b..cf6f33ddc 100644 --- a/osx/macports/Portfile +++ b/osx/macports/Portfile @@ -5,7 +5,7 @@ PortSystem 1.0 PortGroup python26 1.0 name bcfg2 -version 1.3.4 +version 1.3.5 categories sysutils python maintainers gmail.com:sol.jerome license BSD diff --git a/schemas/packages.xsd b/schemas/packages.xsd index e538bb0e7..8ed07baa9 100644 --- a/schemas/packages.xsd +++ b/schemas/packages.xsd @@ -211,6 +211,14 @@ </xsd:documentation> </xsd:annotation> </xsd:attribute> + <xsd:attribute type="xsd:string" name="name"> + <xsd:annotation> + <xsd:documentation> + Specifiy an explicit name for the source and do not generate + it automatically. + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> </xsd:complexType> <xsd:complexType name="PackagesGroupType"> diff --git a/solaris-ips/MANIFEST.bcfg2-server.header b/solaris-ips/MANIFEST.bcfg2-server.header index b72adc486..9e6774c87 100644 --- a/solaris-ips/MANIFEST.bcfg2-server.header +++ b/solaris-ips/MANIFEST.bcfg2-server.header @@ -1,4 +1,4 @@ license ../../LICENSE license=simplified_bsd set name=description value="Configuration management server" set name=pkg.summary value="Configuration management server" -set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@1.3.4" +set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@1.3.5" diff --git a/solaris-ips/MANIFEST.bcfg2.header b/solaris-ips/MANIFEST.bcfg2.header index 19fc567fe..97c63107e 100644 --- a/solaris-ips/MANIFEST.bcfg2.header +++ b/solaris-ips/MANIFEST.bcfg2.header @@ -1,5 +1,5 @@ license ../../LICENSE license=simplified_bsd set name=description value="Configuration management client" set name=pkg.summary value="Configuration management client" -set name=pkg.fmri value="pkg://bcfg2/bcfg2@1.3.4" +set name=pkg.fmri value="pkg://bcfg2/bcfg2@1.3.5" file usr/bin/bcfg2 group=bin mode=0755 owner=root path=usr/bin/bcfg2 diff --git a/solaris-ips/Makefile b/solaris-ips/Makefile index 7d59e2456..ec85dccc2 100644 --- a/solaris-ips/Makefile +++ b/solaris-ips/Makefile @@ -1,6 +1,6 @@ #!/usr/bin/gmake -VERS=1.3.4-1 +VERS=1.3.5-1 PYVERSION := $(shell python -c "import sys; print sys.version[0:3]") default: clean package diff --git a/solaris-ips/pkginfo.bcfg2 b/solaris-ips/pkginfo.bcfg2 index 80f26fc0a..57ffaffb8 100644 --- a/solaris-ips/pkginfo.bcfg2 +++ b/solaris-ips/pkginfo.bcfg2 @@ -1,7 +1,7 @@ PKG="SCbcfg2" NAME="bcfg2" ARCH="sparc" -VERSION="1.3.4" +VERSION="1.3.5" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris-ips/pkginfo.bcfg2-server b/solaris-ips/pkginfo.bcfg2-server index 88d0e6dff..50812c4a5 100644 --- a/solaris-ips/pkginfo.bcfg2-server +++ b/solaris-ips/pkginfo.bcfg2-server @@ -1,7 +1,7 @@ PKG="SCbcfg2-server" NAME="bcfg2-server" ARCH="sparc" -VERSION="1.3.4" +VERSION="1.3.5" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris/Makefile b/solaris/Makefile index 995253ea8..7719d7017 100644 --- a/solaris/Makefile +++ b/solaris/Makefile @@ -1,15 +1,15 @@ #!/usr/sfw/bin/gmake PYTHON="/usr/local/bin/python" -VERS=1.3.4-1 -PYVERSION := $(shell $(PYTHON) -c "import sys; print sys.version[0:3]") +VERS=1.3.5-1 +export PYVERSION := $(shell $(PYTHON) -c "import sys; print sys.version[0:3]") default: clean package package: -mkdir tmp tmp/bcfg2-server tmp/bcfg2 -mkdir -p build/lib/$(PYVERSION)/site-packages - -cd ../ && PYTHONPATH=$(PYTHONPATH):$(PWD)/build/lib/python2.6/site-packages/ $(PYTHON) setup.py install --single-version-externally-managed --record=/dev/null --prefix=$(PWD)/build + -cd ../ && PYTHONPATH=$(PYTHONPATH):$(PWD)/build/lib/python$(PYVERSION)/site-packages/ $(PYTHON) setup.py install --single-version-externally-managed --record=/dev/null --prefix=$(PWD)/build #setuptools appears to use a restictive umask -chmod -R o+r build/ -cat build/bin/bcfg2 | sed -e 's!/usr/bin/python!$(PYTHON)!' > build/bin/bcfg2.new && mv build/bin/bcfg2.new build/bin/bcfg2 diff --git a/solaris/gen-prototypes.sh b/solaris/gen-prototypes.sh index 64aff9edb..b0006df16 100644 --- a/solaris/gen-prototypes.sh +++ b/solaris/gen-prototypes.sh @@ -1,6 +1,6 @@ #!/bin/sh cd build -PP="./lib/python/site-packages/" +PP="./lib/python${PYVERSION}/site-packages/" #bcfg2 echo "i pkginfo=./pkginfo.bcfg2" > ../prototype.tmp diff --git a/solaris/pkginfo.bcfg2 b/solaris/pkginfo.bcfg2 index 80f26fc0a..57ffaffb8 100644 --- a/solaris/pkginfo.bcfg2 +++ b/solaris/pkginfo.bcfg2 @@ -1,7 +1,7 @@ PKG="SCbcfg2" NAME="bcfg2" ARCH="sparc" -VERSION="1.3.4" +VERSION="1.3.5" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris/pkginfo.bcfg2-server b/solaris/pkginfo.bcfg2-server index 88d0e6dff..50812c4a5 100644 --- a/solaris/pkginfo.bcfg2-server +++ b/solaris/pkginfo.bcfg2-server @@ -1,7 +1,7 @@ PKG="SCbcfg2-server" NAME="bcfg2-server" ARCH="sparc" -VERSION="1.3.4" +VERSION="1.3.5" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/src/lib/Bcfg2/Client/Client.py b/src/lib/Bcfg2/Client/Client.py index 14fe6768a..090921ab2 100644 --- a/src/lib/Bcfg2/Client/Client.py +++ b/src/lib/Bcfg2/Client/Client.py @@ -139,7 +139,8 @@ class Client(object): allowedServerCNs=self.setup['serverCN'], timeout=self.setup['timeout'], retries=int(self.setup['retries']), - delay=int(self.setup['retry_delay'])) + delay=int(self.setup['retry_delay']), + protocol=self.setup['protocol']) return self._proxy def run_probes(self, times=None): diff --git a/src/lib/Bcfg2/Client/Tools/APT.py b/src/lib/Bcfg2/Client/Tools/APT.py index 39816403a..0a8fe387f 100644 --- a/src/lib/Bcfg2/Client/Tools/APT.py +++ b/src/lib/Bcfg2/Client/Tools/APT.py @@ -91,7 +91,7 @@ class APT(Bcfg2.Client.Tools.Tool): def VerifyDebsums(self, entry, modlist): output = \ self.cmd.run("%s -as %s" % - (self.debsums, entry.get('name'))).stdout.splitlines() + (self.debsums, entry.get('name'))).stderr.splitlines() if len(output) == 1 and "no md5sums for" in output[0]: self.logger.info("Package %s has no md5sums. Cannot verify" % \ entry.get('name')) diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index 6d18cd176..bbae7abcc 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py +++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py @@ -146,7 +146,7 @@ class POSIXUsers(Bcfg2.Client.Tools.Tool): """ Get a list of supplmentary groups that the user in the given entry is a member of """ return [g for g in self.existing['POSIXGroup'].values() - if entry.get("name") in g[3] and g[0] != entry.get("group") + if entry.get("name") in g[3] and self._in_managed_range('POSIXGroup', g[2])] def VerifyPOSIXUser(self, entry, _): diff --git a/src/lib/Bcfg2/Client/Tools/SYSV.py b/src/lib/Bcfg2/Client/Tools/SYSV.py index aca7d593c..a29b49efa 100644 --- a/src/lib/Bcfg2/Client/Tools/SYSV.py +++ b/src/lib/Bcfg2/Client/Tools/SYSV.py @@ -4,6 +4,8 @@ import tempfile from Bcfg2.Compat import any # pylint: disable=W0622 import Bcfg2.Client.Tools import Bcfg2.Client.XML +from Bcfg2.Compat import urlretrieve + # pylint: disable=C0103 noask = ''' @@ -37,6 +39,8 @@ class SYSV(Bcfg2.Client.Tools.PkgTool): # noaskfile needs to live beyond __init__ otherwise file is removed self.noaskfile = tempfile.NamedTemporaryFile() self.noaskname = self.noaskfile.name + # for any pkg files downloaded + self.tmpfiles = [] try: self.noaskfile.write(noask) # flush admin file contents to disk @@ -45,6 +49,42 @@ class SYSV(Bcfg2.Client.Tools.PkgTool): self.pkgtool[1]) except: # pylint: disable=W0702 self.pkgtool = (self.pkgtool[0] % "", self.pkgtool[1]) + self.origpkgtool = self.pkgtool + + def pkgmogrify(self, packages): + """ Take a list of pkg objects, check for a 'simplename' attribute. + If present, insert a _sysv_pkg_path attribute to the package and + download the datastream format SYSV package to a temporary file. + """ + for pkg in packages: + if pkg.get('simplename'): + tmpfile = tempfile.NamedTemporaryFile() + self.tmpfiles.append(tmpfile) + self.logger.info("Downloading %s%s to %s" % (pkg.get('url'), + pkg.get('simplename'), tmpfile.name)) + urlretrieve("%s/%s" % (pkg.get('url'), pkg.get('simplename')), + tmpfile.name) + pkg.set('_sysv_pkg_path', tmpfile.name) + + def _get_package_command(self, packages): + """Override the default _get_package_command, replacing the attribute + 'url' if '_sysv_pkg_path' if necessary in the returned command + string + """ + if hasattr(self, 'origpkgtool'): + if len(packages) == 1 and '_sysv_pkg_path' in packages[0].keys(): + self.pkgtool = (self.pkgtool[0], ('%s %s', + ['_sysv_pkg_path', 'name'])) + else: + self.pkgtool = self.origpkgtool + + pkgcmd = super(SYSV, self)._get_package_command(packages) + self.logger.debug("Calling install command: %s" % pkgcmd) + return pkgcmd + + def Install(self, packages, states): + self.pkgmogrify(packages) + super(SYSV, self).Install(packages, states) def RefreshPackages(self): """Refresh memory hashes of packages.""" @@ -80,8 +120,8 @@ class SYSV(Bcfg2.Client.Tools.PkgTool): self.logger.debug("Package %s not installed" % entry.get("name")) else: - if (self.setup['quick'] or - entry.attrib.get('verify', 'true') == 'false'): + if self.setup['quick'] or \ + entry.attrib.get('verify', 'true') == 'false': return True rv = self.cmd.run("/usr/sbin/pkgchk -n %s" % entry.get('name')) if rv.success: diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index 15ae5ef8b..a584fec86 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -191,6 +191,10 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.logger.debug("Yum: Reinstall on verify fail: %s" % self.do_reinst) self.logger.debug("Yum: installonlypkgs: %s" % self.installonlypkgs) self.logger.debug("Yum: verify_flags: %s" % self.verify_flags) + self.logger.debug("Yum: disabled_plugins: %s" % + self.setup["yum_disabled_plugins"]) + self.logger.debug("Yum: enabled_plugins: %s" % + self.setup["yum_enabled_plugins"]) def _loadYumBase(self, setup=None, logger=None): ''' this may be called before PkgTool.__init__() is called on @@ -216,6 +220,12 @@ class YUM(Bcfg2.Client.Tools.PkgTool): else: debuglevel = 0 + if setup['yum_disabled_plugins']: + rv.preconf.disabled_plugins = setup['yum_disabled_plugins'] + + if setup['yum_enabled_plugins']: + rv.preconf.enabled_plugins = setup['yum_enabled_plugins'] + # pylint: disable=E1121,W0212 try: rv.preconf.debuglevel = debuglevel diff --git a/src/lib/Bcfg2/Compat.py b/src/lib/Bcfg2/Compat.py index 049236e03..b8a75a0c5 100644 --- a/src/lib/Bcfg2/Compat.py +++ b/src/lib/Bcfg2/Compat.py @@ -20,6 +20,7 @@ except ImportError: # urllib imports try: from urllib import quote_plus + from urllib import urlretrieve from urlparse import urljoin, urlparse from urllib2 import HTTPBasicAuthHandler, \ HTTPPasswordMgrWithDefaultRealm, build_opener, install_opener, \ @@ -27,7 +28,8 @@ try: except ImportError: from urllib.parse import urljoin, urlparse, quote_plus from urllib.request import HTTPBasicAuthHandler, \ - HTTPPasswordMgrWithDefaultRealm, build_opener, install_opener, urlopen + HTTPPasswordMgrWithDefaultRealm, build_opener, install_opener, \ + urlopen, urlretrieve from urllib.error import HTTPError, URLError try: diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py index 206c63d4f..9752ab758 100644 --- a/src/lib/Bcfg2/Options.py +++ b/src/lib/Bcfg2/Options.py @@ -1099,6 +1099,16 @@ CLIENT_YUM_VERIFY_FLAGS = \ cf=('YUM', 'verify_flags'), deprecated_cf=('YUMng', 'verify_flags'), cook=list_split) +CLIENT_YUM_DISABLED_PLUGINS = \ + Option("YUM disabled plugins", + default=[], + cf=('YUM', 'disabled_plugins'), + cook=list_split) +CLIENT_YUM_ENABLED_PLUGINS = \ + Option("YUM enabled plugins", + default=[], + cf=('YUM', 'enabled_plugins'), + cook=list_split) CLIENT_POSIX_UID_WHITELIST = \ Option("UID ranges the POSIXUsers tool will manage", default=[], @@ -1280,6 +1290,8 @@ DRIVER_OPTIONS = \ yum_version_fail_action=CLIENT_YUM_VERSION_FAIL_ACTION, yum_verify_fail_action=CLIENT_YUM_VERIFY_FAIL_ACTION, yum_verify_flags=CLIENT_YUM_VERIFY_FLAGS, + yum_disabled_plugins=CLIENT_YUM_DISABLED_PLUGINS, + yum_enabled_plugins=CLIENT_YUM_ENABLED_PLUGINS, posix_uid_whitelist=CLIENT_POSIX_UID_WHITELIST, posix_gid_whitelist=CLIENT_POSIX_GID_WHITELIST, posix_uid_blacklist=CLIENT_POSIX_UID_BLACKLIST, @@ -1292,6 +1304,7 @@ CLIENT_COMMON_OPTIONS = \ drivers=CLIENT_DRIVERS, dryrun=CLIENT_DRYRUN, paranoid=CLIENT_PARANOID, + protocol=SERVER_PROTOCOL, ppath=PARANOID_PATH, max_copies=PARANOID_MAX_COPIES, bundle=CLIENT_BUNDLE, diff --git a/src/lib/Bcfg2/Proxy.py b/src/lib/Bcfg2/Proxy.py index 34080da6b..736325eab 100644 --- a/src/lib/Bcfg2/Proxy.py +++ b/src/lib/Bcfg2/Proxy.py @@ -286,7 +286,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): class XMLRPCTransport(xmlrpclib.Transport): - def __init__(self, key=None, cert=None, ca=None, + def __init__(self, key=None, cert=None, ca=None, protocol=None, scns=None, use_datetime=0, timeout=90): if hasattr(xmlrpclib.Transport, '__init__'): xmlrpclib.Transport.__init__(self, use_datetime) @@ -295,6 +295,7 @@ class XMLRPCTransport(xmlrpclib.Transport): self.ca = ca self.scns = scns self.timeout = timeout + self.protocol = protocol def make_connection(self, host): host, self._extra_headers = self.get_host_info(host)[0:2] @@ -303,7 +304,8 @@ class XMLRPCTransport(xmlrpclib.Transport): cert=self.cert, ca=self.ca, scns=self.scns, - timeout=self.timeout) + timeout=self.timeout, + protocol=self.protocol) def request(self, host, handler, request_body, verbose=0): """Send request to server and return response.""" @@ -343,7 +345,8 @@ class XMLRPCTransport(xmlrpclib.Transport): def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, - allowedServerCNs=None, timeout=90, retries=3, delay=1): + allowedServerCNs=None, timeout=90, retries=3, delay=1, + protocol=None): """Constructs proxies to components. @@ -362,6 +365,6 @@ def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, quote_plus(password, ''), path) else: newurl = url - ssl_trans = XMLRPCTransport(key, cert, ca, + ssl_trans = XMLRPCTransport(key, cert, ca, protocol, allowedServerCNs, timeout=float(timeout)) return xmlrpclib.ServerProxy(newurl, allow_none=True, transport=ssl_trans) diff --git a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py index 2530d2b2b..98226dc4e 100644 --- a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py +++ b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py @@ -167,7 +167,7 @@ class DjangoORM(StorageBase): # TODO - vcs output act_dict['detail_type'] = PathEntry.DETAIL_UNUSED if path_type == 'directory' and entry.get('prune', 'false') == 'true': - unpruned_elist = [e.get('path') for e in entry.findall('Prune')] + unpruned_elist = [e.get('name') for e in entry.findall('Prune')] if unpruned_elist: act_dict['detail_type'] = PathEntry.DETAIL_PRUNED act_dict['details'] = "\n".join(unpruned_elist) @@ -367,10 +367,11 @@ class DjangoORM(StorageBase): """Import the data into the backend""" try: - self._import_interaction(interaction) - except: - self.logger.error("Failed to import interaction: %s" % - traceback.format_exc().splitlines()[-1]) + try: + self._import_interaction(interaction) + except: + self.logger.error("Failed to import interaction: %s" % + traceback.format_exc().splitlines()[-1]) finally: self.logger.debug("%s: Closing database connection" % self.__class__.__name__) diff --git a/src/lib/Bcfg2/Reporting/models.py b/src/lib/Bcfg2/Reporting/models.py index fc9523067..71fa66086 100644 --- a/src/lib/Bcfg2/Reporting/models.py +++ b/src/lib/Bcfg2/Reporting/models.py @@ -715,9 +715,6 @@ class PathEntry(SuccessEntry): def has_detail(self): return self.detail_type != PathEntry.DETAIL_UNUSED - def is_sensitive(self): - return self.detail_type == PathEntry.DETAIL_SENSITIVE - def is_diff(self): return self.detail_type == PathEntry.DETAIL_DIFF diff --git a/src/lib/Bcfg2/Reporting/templates/base.html b/src/lib/Bcfg2/Reporting/templates/base.html index ef6799c2b..a367d8ccb 100644 --- a/src/lib/Bcfg2/Reporting/templates/base.html +++ b/src/lib/Bcfg2/Reporting/templates/base.html @@ -93,7 +93,7 @@ This is needed for Django versions less than 1.5 <div style='clear:both'></div> </div><!-- document --> <div id="footer"> - <span>Bcfg2 Version 1.3.4</span> + <span>Bcfg2 Version 1.3.5</span> </div> <div id="calendar_div" style='position:absolute; visibility:hidden; background-color:white; layer-background-color:white;'></div> diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/item.html b/src/lib/Bcfg2/Reporting/templates/config_items/item.html index b03d48045..c6e6df020 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/item.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/item.html @@ -107,7 +107,7 @@ div.entry_list h3 { {{ item.details|syntaxhilight }} </div> {% else %} - {{ item.details }} + {{ item.details|linebreaks }} {% endif %} </div> {% endif %} diff --git a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py index 489682f30..0ee5cd0d6 100644 --- a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py +++ b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py @@ -111,47 +111,58 @@ def filter_navigator(context): try: path = context['request'].META['PATH_INFO'] view, args, kwargs = resolve(path) + except (Resolver404, KeyError): + return dict() - # Strip any page limits and numbers - if 'page_number' in kwargs: - del kwargs['page_number'] - if 'page_limit' in kwargs: - del kwargs['page_limit'] - - # get a query string - qs = context['request'].GET.urlencode() - if qs: - qs = '?' + qs - - filters = [] - for filter in filter_list: - if filter == 'group': - continue - if filter in kwargs: - myargs = kwargs.copy() - del myargs[filter] + # Strip any page limits and numbers + if 'page_number' in kwargs: + del kwargs['page_number'] + if 'page_limit' in kwargs: + del kwargs['page_limit'] + + # get a query string + qs = context['request'].GET.urlencode() + if qs: + qs = '?' + qs + + filters = [] + for filter in filter_list: + if filter == 'group': + continue + if filter in kwargs: + myargs = kwargs.copy() + del myargs[filter] + try: filters.append((filter, reverse(view, args=args, kwargs=myargs) + qs)) - filters.sort(key=lambda x: x[0]) - - myargs = kwargs.copy() - selected = True - if 'group' in myargs: - del myargs['group'] - selected = False - groups = [('---', - reverse(view, args=args, kwargs=myargs) + qs, - selected)] - for group in Group.objects.values('name'): + except NoReverseMatch: + pass + filters.sort(key=lambda x: x[0]) + + myargs = kwargs.copy() + selected = True + if 'group' in myargs: + del myargs['group'] + selected = False + + groups = [] + try: + groups.append(('---', + reverse(view, args=args, kwargs=myargs) + qs, + selected)) + except NoReverseMatch: + pass + + for group in Group.objects.values('name'): + try: myargs['group'] = group['name'] groups.append((group['name'], reverse(view, args=args, kwargs=myargs) + qs, group['name'] == kwargs.get('group', ''))) + except NoReverseMatch: + pass - return {'filters': filters, 'groups': groups} - except (Resolver404, NoReverseMatch, ValueError, KeyError): - pass - return dict() + return {'filters': filters, 'groups': groups} def _subtract_or_na(mdict, x, y): diff --git a/src/lib/Bcfg2/Reporting/utils.py b/src/lib/Bcfg2/Reporting/utils.py index 0d394fcd8..694f38824 100755 --- a/src/lib/Bcfg2/Reporting/utils.py +++ b/src/lib/Bcfg2/Reporting/utils.py @@ -96,12 +96,12 @@ def filteredUrls(pattern, view, kwargs=None, name=None): tail = mtail.group(1) pattern = pattern[:len(pattern) - len(tail)] for filter in ('/state/(?P<state>\w+)', - '/group/(?P<group>[\w\-\.]+)', - '/group/(?P<group>[\w\-\.]+)/(?P<state>[A-Za-z]+)', - '/server/(?P<server>[\w\-\.]+)', - '/server/(?P<server>[\w\-\.]+)/(?P<state>[A-Za-z]+)', - '/server/(?P<server>[\w\-\.]+)/group/(?P<group>[\w\-\.]+)', - '/server/(?P<server>[\w\-\.]+)/group/(?P<group>[\w\-\.]+)/(?P<state>[A-Za-z]+)'): + '/group/(?P<group>[^/]+)', + '/group/(?P<group>[^/]+)/(?P<state>[A-Za-z]+)', + '/server/(?P<server>[^/]+)', + '/server/(?P<server>[^/]+)/(?P<state>[A-Za-z]+)', + '/server/(?P<server>[^/]+)/group/(?P<group>[^/]+)', + '/server/(?P<server>[^/]+)/group/(?P<group>[^/]+)/(?P<state>[A-Za-z]+)'): results += [(pattern + filter + tail, view, kwargs)] return results diff --git a/src/lib/Bcfg2/Server/Admin/Init.py b/src/lib/Bcfg2/Server/Admin/Init.py index 153d7bea6..fdab5abca 100644 --- a/src/lib/Bcfg2/Server/Admin/Init.py +++ b/src/lib/Bcfg2/Server/Admin/Init.py @@ -113,7 +113,7 @@ def create_key(hostname, keypath, certpath, country, state, location): hostname, keypath)) subprocess.call((kcstr), shell=True) - ccstr = ("openssl req -batch -new -subj '/C=%s/ST=%s/L=%s/CN=%s' -key %s " + ccstr = ("openssl req -batch -new -subj '/C=%s/ST=%s/L=%s/CN=%s' -key %s " "| openssl x509 -req -days 1000 -signkey %s -out %s" % (country, state, location, diff --git a/src/lib/Bcfg2/Server/Admin/__init__.py b/src/lib/Bcfg2/Server/Admin/__init__.py index 8f12a940e..ef5b2a08c 100644 --- a/src/lib/Bcfg2/Server/Admin/__init__.py +++ b/src/lib/Bcfg2/Server/Admin/__init__.py @@ -58,7 +58,7 @@ class Mode(object): def errExit(self, emsg): """ exit with an error """ - print(emsg) + sys.stderr.write('%s\n' % emsg) raise SystemExit(1) def load_stats(self, client): diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 44ba0fee8..f60b68f45 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -78,7 +78,7 @@ def close_db_connection(func): if self._database_available: # pylint: disable=W0212 from django import db self.logger.debug("%s: Closing database connection" % - threading.current_thread().name) + threading.current_thread().getName()) db.close_connection() return rv diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 170af50ac..55dd255cd 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -581,7 +581,13 @@ class XMLFileBacked(FileBacked): if el.findall('./%sfallback' % Bcfg2.Server.XI_NAMESPACE): self.logger.debug(msg) else: - self.logger.warning(msg) + self.logger.error(msg) + # add a FAM monitor for this path. this isn't perfect + # -- if there's an xinclude of "*.xml", we'll watch + # the literal filename "*.xml". but for non-globbing + # filenames, it works fine. + if fpath not in self.extra_monitors: + self.add_monitor(fpath) parent = el.getparent() parent.remove(el) diff --git a/src/lib/Bcfg2/Server/Plugins/GroupLogic.py b/src/lib/Bcfg2/Server/Plugins/GroupLogic.py index d74c16e8b..24547949b 100644 --- a/src/lib/Bcfg2/Server/Plugins/GroupLogic.py +++ b/src/lib/Bcfg2/Server/Plugins/GroupLogic.py @@ -66,7 +66,7 @@ class GroupLogic(Bcfg2.Server.Plugin.Plugin, return [] self._local.building.add(metadata.hostname) rv = [] - for el in self.config.get_xml_value(metadata).findall("Group"): + for el in self.config.get_xml_value(metadata).xpath("//Group"): if el.get("category"): rv.append(MetadataGroup(el.get("name"), category=el.get("category"))) diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index d6febcff6..1e5544c6b 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -787,6 +787,11 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, def _handle_clients_xml_event(self, _): # pylint: disable=R0912 """ handle all events for clients.xml and files xincluded from clients.xml """ + # disable metadata builds during parsing. this prevents + # clients from getting bogus metadata during the brief time it + # takes to rebuild the clients.xml data + self.states['clients.xml'] = False + xdata = self.clients_xml.xdata self.clients = [] self.clientgroups = {} @@ -848,8 +853,9 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.clientgroups[clname].append(profile) except KeyError: self.clientgroups[clname] = [profile] - self.states['clients.xml'] = True self.update_client_list() + self.expire_cache() + self.states['clients.xml'] = True def _get_condition(self, element): """ Return a predicate that returns True if a client meets @@ -877,7 +883,15 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, def _handle_groups_xml_event(self, _): # pylint: disable=R0912 """ re-read groups.xml on any event on it """ + # disable metadata builds during parsing. this prevents + # clients from getting bogus metadata during the brief time it + # takes to rebuild the groups.xml data + self.states['groups.xml'] = False + self.groups = {} + self.group_membership = dict() + self.negated_groups = dict() + self.ordered_groups = [] # first, we get a list of all of the groups declared in the # file. we do this in two stages because the old way of @@ -902,10 +916,6 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, if grp.get('default', 'false') == 'true': self.default = grp.get('name') - self.group_membership = dict() - self.negated_groups = dict() - self.ordered_groups = [] - # confusing loop condition; the XPath query asks for all # elements under a Group tag under a Groups tag; that is # infinitely recursive, so "all" elements really means _all_ @@ -938,6 +948,7 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.group_membership.setdefault(gname, []) self.group_membership[gname].append( self._aggregate_conditions(conditions)) + self.expire_cache() self.states['groups.xml'] = True def expire_cache(self, key=None): @@ -1448,6 +1459,10 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.logger.debug("Metadata: Re-reading client list from database") old = set(self.clients) self.clients = self.list_clients() + + # we could do this with set.symmetric_difference(), but we + # want detailed numbers of added/removed clients for + # logging new = set(self.clients) added = new - old removed = old - new @@ -1455,9 +1470,7 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, (len(added), added)) self.logger.debug("Metadata: Removed %s clients: %s" % (len(removed), removed)) - # we could do this with set.symmetric_difference(), but we - # want detailed numbers of added/removed clients for - # logging + for client in added.union(removed): self.expire_cache(client) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py index 27a725f23..4a78f846f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py @@ -107,7 +107,8 @@ class AptSource(Source): self.pkgnames.add(pkgname) bdeps[barch][pkgname] = [] elif words[0] == 'Essential' and self.essential: - self.essentialpkgs.add(pkgname) + if words[1].strip() == 'yes': + self.essentialpkgs.add(pkgname) elif words[0] in depfnames: vindex = 0 for dep in words[1].split(','): diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index 22073493c..d08c7d285 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -209,6 +209,9 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: The "version" attribute from :attr:`xsource` self.version = xsource.get('version', '') + #: The "name" attribute from :attr:`xsource` + self.name = xsource.get('name', None) + #: A list of predicates that are used to determine if this #: source applies to a given #: :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata` @@ -292,6 +295,7 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 else: setting['baseurl'] = self.rawurl setting['url'] = baseurl % setting + setting['name'] = self.get_repo_name(setting) self.url_map.extend(usettings) @property @@ -395,8 +399,10 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 doing other operations that require repository names. This function tries several approaches: - #. First, if the map contains a ``component`` key, use that as - the name. + #. First, if the source element containts a ``name`` attribute, + use that as the name. + #. If the map contains a ``component`` key, use that as the + name. #. If not, then try to match the repository URL against :attr:`Bcfg2.Server.Plugins.Packages.Source.REPO_RE`. If that succeeds, use the first matched group; additionally, @@ -426,6 +432,9 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 :type url_map: dict :returns: string - the name of the repository. """ + if self.name: + return self.name + if url_map['component']: rname = url_map['component'] else: diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index 48be1ac26..5d846b4bb 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -9,7 +9,7 @@ import operator import lxml.etree import Bcfg2.Server import Bcfg2.Server.Plugin -from Bcfg2.Compat import unicode # pylint: disable=W0622 +from Bcfg2.Compat import any, unicode # pylint: disable=W0622 try: from django.db import models diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py index 6f054fd33..bbca01ead 100644 --- a/src/lib/Bcfg2/Server/Plugins/Properties.py +++ b/src/lib/Bcfg2/Server/Plugins/Properties.py @@ -212,7 +212,7 @@ class XMLPropertyFile(Bcfg2.Server.Plugin.StructFile, PropertyFile): except UnicodeDecodeError: self.logger.info("Properties: Decrypted %s to gibberish, " "skipping" % el.tag) - except Bcfg2.Encryption.EVPError: + except (TypeError, Bcfg2.Encryption.EVPError): strict = self.xdata.get( "decrypt", SETUP.cfp.get(Bcfg2.Encryption.CFG_SECTION, "decrypt", diff --git a/src/lib/Bcfg2/Server/Plugins/Reporting.py b/src/lib/Bcfg2/Server/Plugins/Reporting.py index 3354763d4..fa11d9250 100644 --- a/src/lib/Bcfg2/Server/Plugins/Reporting.py +++ b/src/lib/Bcfg2/Server/Plugins/Reporting.py @@ -57,7 +57,7 @@ class Reporting(Statistics, Threaded, PullSource, Debuggable): self.logger.error(msg) raise PluginInitError(msg) - def start_threads(self): + # This must be loaded here for bcfg2-admin try: self.transport = load_transport_from_config(self.core.setup) except TransportError: @@ -68,6 +68,9 @@ class Reporting(Statistics, Threaded, PullSource, Debuggable): if self.debug_flag: self.transport.set_debug(self.debug_flag) + def start_threads(self): + pass + def set_debug(self, debug): rv = Debuggable.set_debug(self, debug) if self.transport is not None: diff --git a/src/lib/Bcfg2/settings.py b/src/lib/Bcfg2/settings.py index 834b04d36..2c5466abb 100644 --- a/src/lib/Bcfg2/settings.py +++ b/src/lib/Bcfg2/settings.py @@ -125,7 +125,7 @@ def read_config(cfile=DEFAULT_CONFIG, repo=None, quiet=False): # set up basic defaults. this lets manage.py work in all cases read_config(quiet=True) -ADMINS = (('Root', 'root')) +ADMINS = (('Root', 'root'),) MANAGERS = ADMINS # Language code for this installation. All choices can be found here: diff --git a/src/lib/Bcfg2/version.py b/src/lib/Bcfg2/version.py index ae82724f3..61ba7a405 100644 --- a/src/lib/Bcfg2/version.py +++ b/src/lib/Bcfg2/version.py @@ -2,7 +2,7 @@ import re -__version__ = "1.3.4" +__version__ = "1.3.5" class Bcfg2VersionInfo(tuple): # pylint: disable=E0012,R0924 |