summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdebian/bcfg2-server.init23
-rw-r--r--debian/changelog6
-rw-r--r--doc/client/tools.txt23
-rw-r--r--doc/conf.py2
-rw-r--r--doc/development/compat.txt2
-rw-r--r--doc/installation/distributions.txt6
-rw-r--r--doc/releases/1.3.5.txt33
-rw-r--r--doc/releases/index.txt1
-rw-r--r--doc/server/plugins/connectors/awstags.txt4
-rw-r--r--doc/server/plugins/connectors/templatehelper.txt2
-rw-r--r--doc/server/plugins/generators/cfg.txt11
-rw-r--r--doc/server/plugins/generators/sslca.txt2
-rw-r--r--doc/server/plugins/structures/bundler/index.txt9
-rw-r--r--misc/bcfg2-selinux.spec2
-rw-r--r--misc/bcfg2.spec4
-rw-r--r--osx/Makefile4
-rw-r--r--osx/macports/Portfile2
-rw-r--r--schemas/packages.xsd8
-rw-r--r--solaris-ips/MANIFEST.bcfg2-server.header2
-rw-r--r--solaris-ips/MANIFEST.bcfg2.header2
-rw-r--r--solaris-ips/Makefile2
-rw-r--r--solaris-ips/pkginfo.bcfg22
-rw-r--r--solaris-ips/pkginfo.bcfg2-server2
-rw-r--r--solaris/Makefile6
-rw-r--r--solaris/gen-prototypes.sh2
-rw-r--r--solaris/pkginfo.bcfg22
-rw-r--r--solaris/pkginfo.bcfg2-server2
-rw-r--r--src/lib/Bcfg2/Client/Client.py3
-rw-r--r--src/lib/Bcfg2/Client/Tools/APT.py2
-rw-r--r--src/lib/Bcfg2/Client/Tools/POSIXUsers.py2
-rw-r--r--src/lib/Bcfg2/Client/Tools/SYSV.py44
-rw-r--r--src/lib/Bcfg2/Client/Tools/YUM.py10
-rw-r--r--src/lib/Bcfg2/Compat.py4
-rw-r--r--src/lib/Bcfg2/Options.py13
-rw-r--r--src/lib/Bcfg2/Proxy.py11
-rw-r--r--src/lib/Bcfg2/Reporting/Storage/DjangoORM.py11
-rw-r--r--src/lib/Bcfg2/Reporting/models.py3
-rw-r--r--src/lib/Bcfg2/Reporting/templates/base.html2
-rw-r--r--src/lib/Bcfg2/Reporting/templates/config_items/item.html2
-rw-r--r--src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py77
-rwxr-xr-xsrc/lib/Bcfg2/Reporting/utils.py12
-rw-r--r--src/lib/Bcfg2/Server/Admin/Init.py2
-rw-r--r--src/lib/Bcfg2/Server/Admin/__init__.py2
-rw-r--r--src/lib/Bcfg2/Server/Core.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugin/helpers.py8
-rw-r--r--src/lib/Bcfg2/Server/Plugins/GroupLogic.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Metadata.py29
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Apt.py3
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Source.py13
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Probes.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Properties.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Reporting.py5
-rw-r--r--src/lib/Bcfg2/settings.py2
-rw-r--r--src/lib/Bcfg2/version.py2
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