diff options
55 files changed, 309 insertions, 155 deletions
diff --git a/.travis.yml b/.travis.yml index 9ad7dfb19..54f2215de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,13 @@ python: env: - WITH_OPTIONAL_DEPS=yes - WITH_OPTIONAL_DEPS=no -before_install: - - testsuite/before_install.sh install: - testsuite/install.sh - pip install --use-mirrors -e . script: - nosetests testsuite +after_failure: + - pip freeze branches: except: - maint-1.2 diff --git a/doc/appendix/guides/authentication.txt b/doc/appendix/guides/authentication.txt index b8ec82590..93a34c9bc 100644 --- a/doc/appendix/guides/authentication.txt +++ b/doc/appendix/guides/authentication.txt @@ -37,7 +37,6 @@ This is a :ref:`Cheetah template per-client bcfg2.conf from the per-client metadata:: [communication] - protocol = xmlrpc/ssl #if $self.metadata.uuid != None user = $self.metadata.uuid #end if diff --git a/doc/appendix/guides/centos.txt b/doc/appendix/guides/centos.txt index af097fbac..44ee08777 100644 --- a/doc/appendix/guides/centos.txt +++ b/doc/appendix/guides/centos.txt @@ -132,7 +132,6 @@ upon connection:: [communication] - protocol = xmlrpc/ssl password = N41lMNeW ca = /etc/bcfg2.crt diff --git a/doc/appendix/guides/sslca_howto.txt b/doc/appendix/guides/sslca_howto.txt index 9c939dcd3..8ee0b2b42 100644 --- a/doc/appendix/guides/sslca_howto.txt +++ b/doc/appendix/guides/sslca_howto.txt @@ -148,7 +148,6 @@ Here's what a functional **[communication]** section in a ``bcfg2.conf`` genshi template for clients might look like.:: [communication] - protocol = xmlrpc/ssl {% if metadata.uuid != None %}\ user = ${metadata.uuid} {% end %}\ diff --git a/doc/appendix/guides/ubuntu.txt b/doc/appendix/guides/ubuntu.txt index abb894465..24bebf023 100644 --- a/doc/appendix/guides/ubuntu.txt +++ b/doc/appendix/guides/ubuntu.txt @@ -172,7 +172,6 @@ Replace Pkgmgr with Packages in the plugins line of ``bcfg2.conf``:: transport = LocalFilesystem [communication] - protocol = xmlrpc/ssl password = secret certificate = /etc/ssl/bcfg2.crt key = /etc/ssl/bcfg2.key diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt index 62e804553..f619447e2 100644 --- a/doc/getting_started/index.txt +++ b/doc/getting_started/index.txt @@ -255,6 +255,10 @@ Once you have the server setup, you may be interested in Platform-specific Quickstart Notes ================================== -* :ref:`appendix-guides-centos` -* :ref:`appendix-guides-ubuntu` -* :ref:`getting_started-macosx-notes` +.. toctree:: + :maxdepth: 1 + + CentOS </appendix/guides/centos> + Ubuntu </appendix/guides/ubuntu> + Gentoo </appendix/guides/gentoo> + Mac OS X <macosx/notes> diff --git a/doc/installation/prerequisites.txt b/doc/installation/prerequisites.txt index a30a3b26b..8119be06b 100644 --- a/doc/installation/prerequisites.txt +++ b/doc/installation/prerequisites.txt @@ -76,17 +76,3 @@ reporting, such as Apache + mod_wsgi or nginx. +-------------------------------+----------+--------------------------------+ | south | 0.7.5+ | | +-------------------------------+----------+--------------------------------+ - -Bcfg2 Reporting ---------------- - -A webserver capabable of running wsgi applications is required for web reporting, -such as Apache + mod_wsgi or nginx. - -+-------------------------------+----------+--------------------------------+ -| Software | Version | Requires | -+===============================+==========+================================+ -| django | 1.2.0+ | | -+-------------------------------+----------+--------------------------------+ -| south | 0.7.0+ | | -+-------------------------------+----------+--------------------------------+ diff --git a/doc/man/bcfg2-server.txt b/doc/man/bcfg2-server.txt index f85964ae7..33d0df6cf 100644 --- a/doc/man/bcfg2-server.txt +++ b/doc/man/bcfg2-server.txt @@ -22,18 +22,18 @@ configurations to clients based on the data in its repository. Options ------- --C configfile Specify alternate bcfg2.conf location. --D pidfile Daemonize, placing the program pid in *pidfile*. --E encoding Specify the encoding of config files. --Q path Specify the path to the server repository. --S server Manually specify the server location (as opposed to - using the value in bcfg2.conf). This should be in - the format "https://server:port" --d Enable debugging output. --v Run in verbose mode. --h Print usage information. ---ssl-key=key Specify the path to the SSL key. ---no-fam-blocking Synonym for fam_blocking = False in bcfg2.conf +-C configfile Specify alternate bcfg2.conf location. +-D pidfile Daemonize, placing the program pid in *pidfile*. +-E encoding Specify the encoding of config files. +-Q path Specify the path to the server repository. +-S server Manually specify the server location (as opposed to + using the value in bcfg2.conf). This should be in + the format "https://server:port" +-d Enable debugging output. +-v Run in verbose mode. +-h Print usage information. +--ssl-key=key Specify the path to the SSL key. +--no-fam-blocking Synonym for fam_blocking = False in bcfg2.conf See Also -------- diff --git a/doc/man/bcfg2.conf.txt b/doc/man/bcfg2.conf.txt index 9e5da3eb9..825ab2121 100644 --- a/doc/man/bcfg2.conf.txt +++ b/doc/man/bcfg2.conf.txt @@ -447,7 +447,7 @@ settings used for client-server communication. sets the password to use to connect to the server. protocol - Communication protocol to use. Defaults to xmlrpc/ssl. + Communication protocol to use. Defaults to xmlrpc/tlsv1. retries A client-only option. Number of times to retry network @@ -537,6 +537,10 @@ Packages options The following options are specified in the **[packages]** section. + backends + Comma separated list of backends for the dependency resolution. + Default is "Yum,Apt,Pac,Pkgng". + resolver Enable dependency resolution. Default is 1 (true). diff --git a/doc/releases/1.4.0pre1.txt b/doc/releases/1.4.0pre1.txt index 1f92f4665..779873f41 100644 --- a/doc/releases/1.4.0pre1.txt +++ b/doc/releases/1.4.0pre1.txt @@ -50,6 +50,10 @@ deprecated features (will be removed in a future release, likely 1.5) * :ref:`server-plugins-structures-bundler` * Deprecated use of an explicit name attribute + + You can convert your existing bundles using + ``tools/upgrade/1.4/convert_bundles.py``. + * Deprecated :ref:`.genshi bundles <server-plugins-structures-bundler-index-genshi-templates>` (use .xml bundles and specify the genshi namespace instead) diff --git a/doc/releases/1.4.0pre2.txt b/doc/releases/1.4.0pre2.txt new file mode 100644 index 000000000..7bbed5603 --- /dev/null +++ b/doc/releases/1.4.0pre2.txt @@ -0,0 +1,37 @@ +.. -*- mode: rst -*- +.. vim: ft=rst + +.. _releases-1.4.0pre2: + +1.4.0pre2 +========= + +The second prerelease for Bcfg2 1.4.0 is now available at: + + ftp://ftp.mcs.anl.gov/pub/bcfg + +Bcfg2 1.4.0pre2 is a prerelease, and contains many new features, +including some that are backwards-incompatible with Bcfg2 1.3.x and +earlier. Please read the release notes thoroughly. This is a prerelease +and as such is not likely suitable for general production deployment. +That said, please help us test the release in non- and preproduction +environments. + +backwards-incompatible user-facing changes +------------------------------------------ + +* Changed default communication protocol to xmlrpc/tlsv1 + +* Diff output from files sent to the Reports plugin from the client will now be + in a unified diff format rather than the previous n-diff format. + + This fixes potentially long client runs when comparing files that have + diverged significantly. + +Thanks +------ + +Special thanks to the following contributors for this release + + * Alexander Sulfrain + * Matt Kemp diff --git a/doc/releases/index.txt b/doc/releases/index.txt index 42a2306f6..479aa19de 100644 --- a/doc/releases/index.txt +++ b/doc/releases/index.txt @@ -7,4 +7,7 @@ Release Announcements ===================== -.. include:: 1.3.4.txt +.. toctree:: + + 1.4.0pre1 + 1.3.4 diff --git a/doc/server/plugins/generators/packages.txt b/doc/server/plugins/generators/packages.txt index 62cf06eaf..2fe71f895 100644 --- a/doc/server/plugins/generators/packages.txt +++ b/doc/server/plugins/generators/packages.txt @@ -717,6 +717,9 @@ It understands the following directives: +-------------+------------------------------------------------------+----------+-------------------------------------------------------------------+ | Name | Description | Values | Default | +=============+======================================================+==========+===================================================================+ +| backends | List of backends that should be loaded for the | List | Yum,Apt,Pac,Pkgng | +| | dependency resolution. | | | ++-------------+------------------------------------------------------+----------+-------------------------------------------------------------------+ | resolver | Enable dependency resolution | Boolean | True | +-------------+------------------------------------------------------+----------+-------------------------------------------------------------------+ | metadata | Enable metadata processing. Disabling ``metadata`` | Boolean | True | diff --git a/doc/server/plugins/probes/index.txt b/doc/server/plugins/probes/index.txt index 091c85e63..434ce20a8 100644 --- a/doc/server/plugins/probes/index.txt +++ b/doc/server/plugins/probes/index.txt @@ -15,7 +15,7 @@ generate an `/etc/auto.master` autofs config file for each type. Here we will look at how to do this. Probes also allow dynamic group assignment for clients, see -:ref:`_server-plugins-probes-dynamic-groups`. +:ref:`server-plugins-probes-dynamic-groups`. First, create a ``Probes`` directory in our toplevel repository location:: diff --git a/examples/bcfg2.conf b/examples/bcfg2.conf index cac424576..1f0984f0e 100644 --- a/examples/bcfg2.conf +++ b/examples/bcfg2.conf @@ -1,5 +1,4 @@ [communication] -protocol = xmlrpc/ssl password = foobat # certificate = /etc/bcfg2.key # key = /etc/bcfg2.key diff --git a/man/bcfg2.conf.5 b/man/bcfg2.conf.5 index 851f5527d..2772fe78d 100644 --- a/man/bcfg2.conf.5 +++ b/man/bcfg2.conf.5 @@ -448,7 +448,7 @@ the password clients need to use to communicate. On a client, sets the password to use to connect to the server. .TP .B protocol -Communication protocol to use. Defaults to xmlrpc/ssl. +Communication protocol to use. Defaults to xmlrpc/tlsv1. .TP .B retries A client\-only option. Number of times to retry network @@ -554,6 +554,10 @@ The following options are specified in the \fB[packages]\fP section. .INDENT 3.5 .INDENT 0.0 .TP +.B backends +Comma separated list of backends for the dependency resolution. +Default is "Yum,Apt,Pac,Pkgng". +.TP .B resolver Enable dependency resolution. Default is 1 (true). .TP diff --git a/osx/bcfg2.conf b/osx/bcfg2.conf index cac424576..1f0984f0e 100644 --- a/osx/bcfg2.conf +++ b/osx/bcfg2.conf @@ -1,5 +1,4 @@ [communication] -protocol = xmlrpc/ssl password = foobat # certificate = /etc/bcfg2.key # key = /etc/bcfg2.key diff --git a/schemas/acl.xsd b/schemas/acl.xsd index 0c3e3ecdd..ac678b6c1 100644 --- a/schemas/acl.xsd +++ b/schemas/acl.xsd @@ -3,7 +3,7 @@ <xsd:annotation> <xsd:documentation> acl config schema for bcfg2 - Matt Schwager + Matt Schwager </xsd:documentation> </xsd:annotation> diff --git a/schemas/types.xsd b/schemas/types.xsd index a0fb7ed0a..0a55f6355 100644 --- a/schemas/types.xsd +++ b/schemas/types.xsd @@ -487,9 +487,9 @@ <xsd:annotation> <xsd:documentation> This field is typically used to record general information - about the account or its user(s) such as their real name - and phone number. If this is not set, the GECOS will be - the same as the username. + about the account or its user(s) such as their real name + and phone number. If this is not set, the GECOS will be + the same as the username. </xsd:documentation> </xsd:annotation> </xsd:attribute> diff --git a/src/lib/Bcfg2/Client/Proxy.py b/src/lib/Bcfg2/Client/Proxy.py index cf6efac89..679b4c52b 100644 --- a/src/lib/Bcfg2/Client/Proxy.py +++ b/src/lib/Bcfg2/Client/Proxy.py @@ -119,7 +119,7 @@ class SSLHTTPConnection(httplib.HTTPConnection): """ def __init__(self, host, port=None, strict=None, timeout=90, key=None, - cert=None, ca=None, scns=None, protocol='xmlrpc/ssl'): + cert=None, ca=None, scns=None, protocol='xmlrpc/tlsv1'): """Initializes the `httplib.HTTPConnection` object and stores security parameters @@ -144,15 +144,15 @@ class SSLHTTPConnection(httplib.HTTPConnection): specify the same file as `cert` if using a file that contains both. See http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. + for details. Required if using client certificate + authentication. cert : string, optional The file system path to the local endpoint's SSL certificate. May specify the same file as `cert` if using a file that contains both. See http://docs.python.org/library/ssl.html#ssl-certificates - for details. Required if using xmlrpc/ssl with client - certificate authentication. + for details. Required if using client certificate + authentication. ca : string, optional The file system path to a set of concatenated certificate authority certs, which are used to validate certificates @@ -232,7 +232,8 @@ class SSLHTTPConnection(httplib.HTTPConnection): class XMLRPCTransport(xmlrpclib.Transport): def __init__(self, key=None, cert=None, ca=None, - scns=None, use_datetime=0, timeout=90): + scns=None, use_datetime=0, timeout=90, + protocol='xmlrpc/tlsv1'): if hasattr(xmlrpclib.Transport, '__init__'): xmlrpclib.Transport.__init__(self, use_datetime) self.key = key @@ -240,6 +241,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] @@ -248,7 +250,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.""" @@ -291,9 +294,15 @@ class ComponentProxy(xmlrpclib.ServerProxy): """Constructs proxies to components. """ options = [ - Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_key, - Bcfg2.Options.Common.ssl_cert, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_ca, Bcfg2.Options.Common.password, Bcfg2.Options.Common.client_timeout, + Bcfg2.Options.Common.protocol, + Bcfg2.Options.PathOption( + '--ssl-key', cf=('communication', 'key'), dest="key", + help='Path to SSL key'), + Bcfg2.Options.PathOption( + cf=('communication', 'certificate'), dest="cert", + help='Path to SSL certificate'), Bcfg2.Options.Option( "-u", "--user", default="root", cf=('communication', 'user'), help='The user to provide for authentication'), @@ -323,10 +332,12 @@ class ComponentProxy(xmlrpclib.ServerProxy): path) else: url = Bcfg2.Options.setup.server - ssl_trans = XMLRPCTransport(Bcfg2.Options.setup.key, - Bcfg2.Options.setup.cert, - Bcfg2.Options.setup.ca, - Bcfg2.Options.setup.ssl_cns, - Bcfg2.Options.setup.client_timeout) + ssl_trans = XMLRPCTransport( + key=Bcfg2.Options.setup.key, + cert=Bcfg2.Options.setup.cert, + ca=Bcfg2.Options.setup.ca, + scns=Bcfg2.Options.setup.ssl_cns, + timeout=Bcfg2.Options.setup.client_timeout, + protocol=Bcfg2.Options.setup.protocol) xmlrpclib.ServerProxy.__init__(self, url, allow_none=True, transport=ssl_trans) diff --git a/src/lib/Bcfg2/Client/Tools/Action.py b/src/lib/Bcfg2/Client/Tools/Action.py index 5549b1717..dedc50d89 100644 --- a/src/lib/Bcfg2/Client/Tools/Action.py +++ b/src/lib/Bcfg2/Client/Tools/Action.py @@ -36,7 +36,7 @@ class Action(Bcfg2.Client.Tools.Tool): shell = True shell_string = '(in shell) ' - if not Bcfg2.Options.setup.dryrun: + if not Bcfg2.Options.setup.dry_run: if Bcfg2.Options.setup.interactive: prompt = ('Run Action %s%s, %s: (y/N): ' % (shell_string, entry.get('name'), diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/File.py b/src/lib/Bcfg2/Client/Tools/POSIX/File.py index 0452ea258..fc445e07c 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/File.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/File.py @@ -220,8 +220,12 @@ class POSIXFile(POSIXTool): def _diff(self, content1, content2, filename=None): """ Return a unified diff of the two strings """ - fromfile = "%s (on disk)" % filename if filename else "" - tofile = "%s (from bcfg2)" % filename if filename else "" + if filename: + fromfile = "%s (on disk)" % filename + tofile = "%s (from bcfg2)" % filename + else: + fromfile = "" + tofile = "" return difflib.unified_diff(content1.split('\n'), content2.split('\n'), fromfile=fromfile, diff --git a/src/lib/Bcfg2/Client/Tools/RPM.py b/src/lib/Bcfg2/Client/Tools/RPM.py index 173623f61..464b7e389 100644 --- a/src/lib/Bcfg2/Client/Tools/RPM.py +++ b/src/lib/Bcfg2/Client/Tools/RPM.py @@ -1120,7 +1120,7 @@ class RPM(Bcfg2.Client.Tools.PkgTool): help="Install missing packages"), Bcfg2.Options.Option( cf=('RPM', 'erase_flags'), default=["allmatches"], - dest="rpm_erase_flags", + dest="rpm_erase_flags", type=Bcfg2.Options.Types.comma_list, help="RPM erase flags"), Bcfg2.Options.BooleanOption( cf=('RPM', 'fix_version'), default=True, @@ -1131,7 +1131,8 @@ class RPM(Bcfg2.Client.Tools.PkgTool): dest="rpm_reinstall_broken", help="Reinstall packages that fail to verify"), Bcfg2.Options.Option( - cf=('RPM', 'verify_flags'), default=[], dest="rpm_verify_flags", + cf=('RPM', 'verify_flags'), default=[], + dest="rpm_verify_flags", type=Bcfg2.Options.Types.comma_list, help="RPM verify flags")] __execs__ = ['/bin/rpm', '/var/lib/rpm'] diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index ee1cd6fad..21fc05b0d 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -133,7 +133,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): help="Install missing packages"), Bcfg2.Options.Option( cf=('YUM', 'erase_flags'), default=["allmatches"], - dest="yum_erase_flags", + dest="yum_erase_flags", type=Bcfg2.Options.Types.comma_list, help="YUM erase flags"), Bcfg2.Options.BooleanOption( cf=('YUM', 'fix_version'), default=True, @@ -144,8 +144,17 @@ class YUM(Bcfg2.Client.Tools.PkgTool): dest="yum_reinstall_broken", help="Reinstall packages that fail to verify"), Bcfg2.Options.Option( - cf=('YUM', 'verify_flags'), default=[], dest="yum_verify_flags", - help="YUM verify flags")] + cf=('YUM', 'verify_flags'), default=[], + dest="yum_verify_flags", type=Bcfg2.Options.Types.comma_list, + help="YUM verify flags"), + Bcfg2.Options.Option( + cf=('YUM', 'disabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_disabled_plugins", + help="YUM disabled plugins"), + Bcfg2.Options.Option( + cf=('YUM', 'enabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_enabled_plugins", + help="YUM enabled plugins")] pkgtype = 'yum' __execs__ = [] @@ -218,6 +227,10 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.logger.debug("Yum: installonlypkgs: %s" % self.installonlypkgs) self.logger.debug("Yum: verify_flags: %s" % Bcfg2.Options.setup.yum_verify_flags) + self.logger.debug("Yum: disabled_plugins: %s" % + Bcfg2.Options.setup.yum_disabled_plugins) + self.logger.debug("Yum: enabled_plugins: %s" % + Bcfg2.Options.setup.yum_enabled_plugins) def _loadYumBase(self): ''' this may be called before PkgTool.__init__() is called on @@ -240,6 +253,14 @@ class YUM(Bcfg2.Client.Tools.PkgTool): else: debuglevel = 0 + if len(Bcfg2.Options.setup.yum_disabled_plugins) > 0: + rv.preconf.disabled_plugins = \ + Bcfg2.Options.setup.yum_disabled_plugins + + if len(Bcfg2.Options.setup.yum_enabled_plugins) > 0: + rv.preconf.enabled_plugins = \ + Bcfg2.Options.setup.yum_enabled_plugins + # pylint: disable=E1121,W0212 try: rv.preconf.debuglevel = debuglevel diff --git a/src/lib/Bcfg2/Client/__init__.py b/src/lib/Bcfg2/Client/__init__.py index 073aa7694..5f4f15dcc 100644 --- a/src/lib/Bcfg2/Client/__init__.py +++ b/src/lib/Bcfg2/Client/__init__.py @@ -873,15 +873,21 @@ class Client(object): def GenerateStats(self): """Generate XML summary of execution statistics.""" + states = {} + for (item, val) in list(self.states.items()): + if not Bcfg2.Options.setup.only_important or \ + item.get('important', 'false').lower() == 'true': + states[item] = val + feedback = XML.Element("upload-statistics") stats = XML.SubElement(feedback, - 'Statistics', total=str(len(self.states)), + 'Statistics', total=str(len(states)), version='2.0', revision=self.config.get('revision', '-1')) - good_entries = [key for key, val in list(self.states.items()) if val] + good_entries = [key for key, val in list(states.items()) if val] good = len(good_entries) stats.set('good', str(good)) - if any(not val for val in list(self.states.values())): + if any(not val for val in list(states.values())): stats.set('state', 'dirty') else: stats.set('state', 'clean') @@ -890,8 +896,8 @@ class Client(object): for (data, ename) in [(self.modified, 'Modified'), (self.extra, "Extra"), (good_entries, "Good"), - ([entry for entry in self.states - if not self.states[entry]], "Bad")]: + ([entry for entry in states + if not states[entry]], "Bad")]: container = XML.SubElement(stats, ename) for item in data: item.set('qtext', '') diff --git a/src/lib/Bcfg2/DBSettings.py b/src/lib/Bcfg2/DBSettings.py index 12dba7fba..b817ecb94 100644 --- a/src/lib/Bcfg2/DBSettings.py +++ b/src/lib/Bcfg2/DBSettings.py @@ -8,6 +8,7 @@ import Bcfg2.Options try: import django + import django.core.management import django.conf HAS_DJANGO = True except ImportError: diff --git a/src/lib/Bcfg2/Options/Common.py b/src/lib/Bcfg2/Options/Common.py index 8f5cf8f06..620a7604c 100644 --- a/src/lib/Bcfg2/Options/Common.py +++ b/src/lib/Bcfg2/Options/Common.py @@ -107,20 +107,16 @@ class Common(object): '-x', '--password', cf=('communication', 'password'), metavar='<password>', help="Communication Password") - #: Path to SSL key - ssl_key = PathOption( - '--ssl-key', cf=('communication', 'key'), dest="key", - help='Path to SSL key', default="/etc/pki/tls/private/bcfg2.key") - - #: Path to SSL certificate - ssl_cert = PathOption( - cf=('communication', 'certificate'), dest="cert", - help='Path to SSL certificate', default="/etc/pki/tls/certs/bcfg2.crt") - #: Path to SSL CA certificate ssl_ca = PathOption( cf=('communication', 'ca'), help='Path to SSL CA Cert') + #: Communication protocol + protocol = Option( + cf=('communication', 'protocol'), default='xmlrpc/tlsv1', + choices=['xmlrpc/ssl', 'xmlrpc/tlsv1'], + help='Communication protocol to use.') + #: Default Path paranoid setting default_paranoid = Option( cf=('mdata', 'paranoid'), dest="default_paranoid", default='true', diff --git a/src/lib/Bcfg2/Server/BuiltinCore.py b/src/lib/Bcfg2/Server/BuiltinCore.py index 0023e9313..769addf55 100644 --- a/src/lib/Bcfg2/Server/BuiltinCore.py +++ b/src/lib/Bcfg2/Server/BuiltinCore.py @@ -113,7 +113,8 @@ class BuiltinCore(NetworkCore): keyfile=Bcfg2.Options.setup.key, certfile=Bcfg2.Options.setup.cert, register=False, - ca=Bcfg2.Options.setup.ca) + ca=Bcfg2.Options.setup.ca, + protocol=Bcfg2.Options.setup.protocol) except: # pylint: disable=W0702 err = sys.exc_info()[1] self.logger.error("Server startup failed: %s" % err) diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index a2f9499f2..892f2832a 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -1370,8 +1370,16 @@ class NetworkCore(Core): daemonized, etc.""" options = Core.options + [ Bcfg2.Options.Common.daemon, Bcfg2.Options.Common.syslog, - Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_key, - Bcfg2.Options.Common.ssl_cert, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.location, Bcfg2.Options.Common.ssl_ca, + Bcfg2.Options.Common.protocol, + Bcfg2.Options.PathOption( + '--ssl-key', cf=('communication', 'key'), dest="key", + help='Path to SSL key', + default="/etc/pki/tls/private/bcfg2.key"), + Bcfg2.Options.PathOption( + cf=('communication', 'certificate'), dest="cert", + help='Path to SSL certificate', + default="/etc/pki/tls/certs/bcfg2.crt"), Bcfg2.Options.BooleanOption( '--listen-all', cf=('server', 'listen_all'), default=False, help="Listen on all interfaces"), diff --git a/src/lib/Bcfg2/Server/Lint/AWSTags.py b/src/lib/Bcfg2/Server/Lint/AWSTags.py index 25ad4ef61..c6d7a3a30 100644 --- a/src/lib/Bcfg2/Server/Lint/AWSTags.py +++ b/src/lib/Bcfg2/Server/Lint/AWSTags.py @@ -9,6 +9,7 @@ import Bcfg2.Server.Lint class AWSTags(Bcfg2.Server.Lint.ServerPlugin): """ ``bcfg2-lint`` plugin to check all given :ref:`AWSTags <server-plugins-connectors-awstags>` patterns for validity. """ + __serverplugin__ = 'AWSTags' def Run(self): cfg = self.core.plugins['AWSTags'].config diff --git a/src/lib/Bcfg2/Server/Lint/Bundler.py b/src/lib/Bcfg2/Server/Lint/Bundler.py index aee15cb5d..576e157ad 100644 --- a/src/lib/Bcfg2/Server/Lint/Bundler.py +++ b/src/lib/Bcfg2/Server/Lint/Bundler.py @@ -7,6 +7,7 @@ from Bcfg2.Server.Lint import ServerPlugin class Bundler(ServerPlugin): """ Perform various :ref:`Bundler <server-plugins-structures-bundler>` checks. """ + __serverplugin__ = 'Bundler' def Run(self): self.missing_bundles() diff --git a/src/lib/Bcfg2/Server/Lint/Cfg.py b/src/lib/Bcfg2/Server/Lint/Cfg.py index 7716cd5c7..13b04a6b8 100644 --- a/src/lib/Bcfg2/Server/Lint/Cfg.py +++ b/src/lib/Bcfg2/Server/Lint/Cfg.py @@ -10,6 +10,7 @@ from Bcfg2.Server.Plugins.Cfg import CfgGenerator class Cfg(ServerPlugin): """ warn about Cfg issues """ + __serverplugin__ = 'Cfg' def Run(self): for basename, entry in list(self.core.plugins['Cfg'].entries.items()): diff --git a/src/lib/Bcfg2/Server/Lint/Comments.py b/src/lib/Bcfg2/Server/Lint/Comments.py index fc4506c12..fbe84de87 100644 --- a/src/lib/Bcfg2/Server/Lint/Comments.py +++ b/src/lib/Bcfg2/Server/Lint/Comments.py @@ -93,13 +93,21 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): type=Bcfg2.Options.Types.comma_list, default=[], help="Required comments for info.xml files"), Bcfg2.Options.Option( - cf=("Comments", "probe_keywords"), + cf=("Comments", "probes_keywords"), type=Bcfg2.Options.Types.comma_list, default=[], help="Required keywords for probes"), Bcfg2.Options.Option( - cf=("Comments", "probe_comments"), + cf=("Comments", "probes_comments"), type=Bcfg2.Options.Types.comma_list, default=[], - help="Required comments for probes")] + help="Required comments for probes"), + Bcfg2.Options.Option( + cf=("Comments", "metadata_keywords"), + type=Bcfg2.Options.Types.comma_list, default=[], + help="Required keywords for metadata files"), + Bcfg2.Options.Option( + cf=("Comments", "metadata_comments"), + type=Bcfg2.Options.Types.comma_list, default=[], + help="Required comments for metadata files")] def __init__(self, *args, **kwargs): Bcfg2.Server.Lint.ServerPlugin.__init__(self, *args, **kwargs) @@ -248,7 +256,7 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): rtype = "jinja2" elif isinstance(entry, CfgInfoXML): self.check_xml(entry.infoxml.name, - entry.infoxml.pnode.data, + entry.infoxml.xdata, "infoxml") continue if rtype: diff --git a/src/lib/Bcfg2/Server/Lint/Genshi.py b/src/lib/Bcfg2/Server/Lint/Genshi.py index a2581e70b..a2581e70b 100755..100644 --- a/src/lib/Bcfg2/Server/Lint/Genshi.py +++ b/src/lib/Bcfg2/Server/Lint/Genshi.py diff --git a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py index d8142cab9..8ddb9e796 100644 --- a/src/lib/Bcfg2/Server/Lint/GroupPatterns.py +++ b/src/lib/Bcfg2/Server/Lint/GroupPatterns.py @@ -13,6 +13,7 @@ class GroupPatterns(ServerPlugin): :class:`Bcfg2.Server.Plugins.GroupPatterns.PatternMap` object for each pattern, and catching exceptions and presenting them as ``bcfg2-lint`` errors.""" + __serverplugin__ = 'GroupPatterns' def Run(self): cfg = self.core.plugins['GroupPatterns'].config diff --git a/src/lib/Bcfg2/Server/Lint/InfoXML.py b/src/lib/Bcfg2/Server/Lint/InfoXML.py index 4b1513a11..950a86f01 100644 --- a/src/lib/Bcfg2/Server/Lint/InfoXML.py +++ b/src/lib/Bcfg2/Server/Lint/InfoXML.py @@ -15,6 +15,7 @@ class InfoXML(Bcfg2.Server.Lint.ServerPlugin): * Paranoid mode disabled in an ``info.xml`` file; * Required attributes missing from ``info.xml`` """ + __serverplugin__ = 'Cfg' options = Bcfg2.Server.Lint.ServerPlugin.options + [ Bcfg2.Options.Common.default_paranoid, diff --git a/src/lib/Bcfg2/Server/Lint/Jinja2.py b/src/lib/Bcfg2/Server/Lint/Jinja2.py index 333249cc2..333249cc2 100755..100644 --- a/src/lib/Bcfg2/Server/Lint/Jinja2.py +++ b/src/lib/Bcfg2/Server/Lint/Jinja2.py diff --git a/src/lib/Bcfg2/Server/Lint/Metadata.py b/src/lib/Bcfg2/Server/Lint/Metadata.py index 248b1610c..e445892d1 100644 --- a/src/lib/Bcfg2/Server/Lint/Metadata.py +++ b/src/lib/Bcfg2/Server/Lint/Metadata.py @@ -15,6 +15,7 @@ class Metadata(ServerPlugin): * Multiple default groups or a default group that isn't a profile group. """ + __serverplugin__ = 'Metadata' def Run(self): self.nested_clients() diff --git a/src/lib/Bcfg2/Server/Lint/Pkgmgr.py b/src/lib/Bcfg2/Server/Lint/Pkgmgr.py index 3f0b9477c..eed6d4c19 100644 --- a/src/lib/Bcfg2/Server/Lint/Pkgmgr.py +++ b/src/lib/Bcfg2/Server/Lint/Pkgmgr.py @@ -12,6 +12,7 @@ class Pkgmgr(ServerlessPlugin): """ Find duplicate :ref:`Pkgmgr <server-plugins-generators-pkgmgr>` entries with the same priority. """ + __serverplugin__ = 'Pkgmgr' def Run(self): pset = set() diff --git a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py index 5a80a5884..a437c1318 100644 --- a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py +++ b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py @@ -62,7 +62,7 @@ class TemplateAbuse(Bcfg2.Server.Lint.ServerPlugin): # finally, check for executable permissions in info.xml for entry in entryset.entries.values(): if isinstance(entry, CfgInfoXML): - for pinfo in entry.infoxml.pnode.data.xpath("//FileInfo"): + for pinfo in entry.infoxml.xdata.xpath("//FileInfo/Info"): try: mode = int( pinfo.get("mode", diff --git a/src/lib/Bcfg2/Server/Lint/TemplateHelper.py b/src/lib/Bcfg2/Server/Lint/TemplateHelper.py index a952da724..9d05516f1 100644 --- a/src/lib/Bcfg2/Server/Lint/TemplateHelper.py +++ b/src/lib/Bcfg2/Server/Lint/TemplateHelper.py @@ -20,6 +20,7 @@ class TemplateHelper(ServerPlugin): * Bogus symbols listed in ``__export__``, including symbols that don't exist, that are reserved, or that start with underscores. """ + __serverplugin__ = 'TemplateHelper' def __init__(self, *args, **kwargs): ServerPlugin.__init__(self, *args, **kwargs) diff --git a/src/lib/Bcfg2/Server/Lint/Validate.py b/src/lib/Bcfg2/Server/Lint/Validate.py index 0b3f1e24d..cab5d248d 100644 --- a/src/lib/Bcfg2/Server/Lint/Validate.py +++ b/src/lib/Bcfg2/Server/Lint/Validate.py @@ -18,7 +18,7 @@ class Validate(Bcfg2.Server.Lint.ServerlessPlugin): options = Bcfg2.Server.Lint.ServerlessPlugin.options + [ Bcfg2.Options.PathOption( "--schema", cf=("Validate", "schema"), - default="/usr/share/bcfg2/schema", + default="/usr/share/bcfg2/schemas", help="The full path to the XML schema files")] def __init__(self, *args, **kwargs): diff --git a/src/lib/Bcfg2/Server/Lint/__init__.py b/src/lib/Bcfg2/Server/Lint/__init__.py index 9b3e6ece2..526bdf159 100644 --- a/src/lib/Bcfg2/Server/Lint/__init__.py +++ b/src/lib/Bcfg2/Server/Lint/__init__.py @@ -14,6 +14,7 @@ import Bcfg2.Options import Bcfg2.Server.Core import Bcfg2.Server.Plugins from Bcfg2.Compat import walk_packages +from Bcfg2.Options import _debug def _ioctl_GWINSZ(fd): # pylint: disable=C0103 @@ -48,6 +49,11 @@ def get_termsize(): class Plugin(object): """ Base class for all bcfg2-lint plugins """ + #: Name of the matching server plugin or None if there is no + #: matching one. If this is None the lint plugin will only loaded + #: by default if the matching server plugin is enabled, too. + __serverplugin__ = None + options = [Bcfg2.Options.Common.repository] def __init__(self, errorhandler=None, files=None): @@ -291,19 +297,41 @@ class ServerPlugin(Plugin): # pylint: disable=W0223 class LintPluginAction(Bcfg2.Options.ComponentAction): - """ We want to load all lint plugins that pertain to server - plugins. In order to do this, we hijack the __call__() method of - this action and add all of the server plugins on the fly """ - + """ Option parser action to load lint plugins """ bases = ['Bcfg2.Server.Lint'] - def __call__(self, parser, namespace, values, option_string=None): - plugins = getattr(Bcfg2.Options.setup, "plugins", []) - for lint_plugin in walk_packages(path=__path__): - if lint_plugin[1] in plugins: - values.append(lint_plugin[1]) - Bcfg2.Options.ComponentAction.__call__(self, parser, namespace, values, - option_string) + +class LintPluginOption(Bcfg2.Options.Option): + """ Option class for the lint_plugins """ + + def early_parsing_hook(self, namespace): + """ + We want a usefull default for the enabled lint plugins. + Therfore we use all importable plugins, that either pertain + with enabled server plugins or that has no matching plugin. + """ + + plugins = [p.__name__ for p in namespace.plugins] + for loader, name, _is_pkg in walk_packages(path=__path__): + try: + module = loader.find_module(name).load_module(name) + plugin = getattr(module, name) + if plugin.__serverplugin__ is None or \ + plugin.__serverplugin__ in plugins: + _debug("Automatically adding lint plugin %s" % + plugin.__name__) + self.default.append(plugin.__name__) + except ImportError: + pass + + +class _EarlyOptions(object): + """ We need the server.plugins options in an early parsing hook + for determining the default value for the lint_plugins. So we + create a component that is parsed before the other options. """ + + parse_first = True + options = [Bcfg2.Options.Common.plugins] class CLI(object): @@ -313,7 +341,7 @@ class CLI(object): '--lint-config', default='/etc/bcfg2-lint.conf', action=Bcfg2.Options.ConfigFileAction, help='Specify bcfg2-lint configuration file'), - Bcfg2.Options.Option( + LintPluginOption( "--lint-plugins", cf=('lint', 'plugins'), default=[], type=Bcfg2.Options.Types.comma_list, action=LintPluginAction, help='bcfg2-lint plugin list'), @@ -328,28 +356,11 @@ class CLI(object): def __init__(self): parser = Bcfg2.Options.get_parser( description="Manage a running Bcfg2 server", - components=[self]) + components=[self, _EarlyOptions]) parser.parse() self.logger = logging.getLogger(parser.prog) - # automatically add Lint plugins for loaded server plugins - for plugin in Bcfg2.Options.setup.plugins: - try: - Bcfg2.Options.setup.lint_plugins.append( - getattr( - __import__("Bcfg2.Server.Lint.%s" % plugin.__name__, - fromlist=[plugin.__name__]), - plugin.__name__)) - self.logger.debug("Automatically adding lint plugin %s" % - plugin.__name__) - except ImportError: - # no lint plugin for this server plugin - self.logger.debug("No lint plugin for %s" % plugin.__name__) - except AttributeError: - self.logger.error("Failed to load plugin %s: %s" % - (plugin.__name__, sys.exc_info()[1])) - self.logger.debug("Running lint with plugins: %s" % [p.__name__ for p in Bcfg2.Options.setup.lint_plugins]) @@ -428,9 +439,9 @@ class CLI(object): def run_server_plugins(self): """ run plugins that require a running server to run """ core = Bcfg2.Server.Core.Core() - core.load_plugins() - core.block_for_fam_events(handle_events=True) try: + core.load_plugins() + core.block_for_fam_events(handle_events=True) self.logger.debug("Running server plugins: %s" % [p.__name__ for p in self.serverplugins]) for plugin in self.serverplugins: diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 456038c2f..559612d1e 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -947,7 +947,7 @@ class InfoXML(StructFile): _include_tests = copy.copy(StructFile._include_tests) _include_tests['Path'] = lambda el, md, entry, *args: \ - entry.get("name") == el.get("name") + entry.get('realname', entry.get('name')) == el.get("name") def Match(self, metadata, entry): # pylint: disable=W0221 """ Implementation of diff --git a/src/lib/Bcfg2/Server/Plugins/ACL.py b/src/lib/Bcfg2/Server/Plugins/ACL.py index 1c1e54312..37f51a2a1 100644 --- a/src/lib/Bcfg2/Server/Plugins/ACL.py +++ b/src/lib/Bcfg2/Server/Plugins/ACL.py @@ -62,6 +62,7 @@ def ip_matches(ip, entry): class IPACLFile(Bcfg2.Server.Plugin.XMLFileBacked): """ representation of ACL ip.xml, for IP-based ACLs """ + __identifier__ = None actions = dict(Allow=True, Deny=False, Defer=None) diff --git a/src/lib/Bcfg2/Server/Plugins/Decisions.py b/src/lib/Bcfg2/Server/Plugins/Decisions.py index 3d3ef8f8c..b30a9acea 100644 --- a/src/lib/Bcfg2/Server/Plugins/Decisions.py +++ b/src/lib/Bcfg2/Server/Plugins/Decisions.py @@ -31,4 +31,4 @@ class Decisions(Bcfg2.Server.Plugin.Plugin, self.blacklist = DecisionFile(os.path.join(self.data, "blacklist.xml")) def GetDecisions(self, metadata, mode): - return getattr(self, mode).get_decision(metadata) + return getattr(self, mode).get_decisions(metadata) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py index 13f2c84e5..e393cabfe 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py @@ -21,8 +21,7 @@ class PkgngCollection(Collection): overrides nothing, and defers all operations to :class:`PacSource` """ - def __init__(self, metadata, sources, cachepath, basepath, fam, - debug=False): + def __init__(self, metadata, sources, cachepath, basepath, debug=False): # we define an __init__ that just calls the parent __init__, # so that we can set the docstring on __init__ to something # different from the parent __init__ -- namely, the parent @@ -30,7 +29,7 @@ class PkgngCollection(Collection): # which we use to delineate the actual docs from the # .. autoattribute hacks we have to do to get private # attributes included in sphinx 1.0 """ - Collection.__init__(self, metadata, sources, cachepath, basepath, fam, + Collection.__init__(self, metadata, sources, cachepath, basepath, debug=debug) __init__.__doc__ = Collection.__init__.__doc__.split(".. -----")[0] diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py index 0171800a8..d11ac60fe 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py @@ -101,7 +101,8 @@ class Packages(Bcfg2.Server.Plugin.Plugin, cf=("packages", "backends"), dest="packages_backends", help="Packages backends to load", type=Bcfg2.Options.Types.comma_list, - action=PackagesBackendAction, default=['Yum', 'Apt', 'Pac']), + action=PackagesBackendAction, + default=['Yum', 'Apt', 'Pac', 'Pkgng']), Bcfg2.Options.PathOption( cf=("packages", "cache"), dest="packages_cache", help="Path to the Packages cache", diff --git a/src/lib/Bcfg2/Server/SSLServer.py b/src/lib/Bcfg2/Server/SSLServer.py index 5e6846a44..6ad5b5635 100644 --- a/src/lib/Bcfg2/Server/SSLServer.py +++ b/src/lib/Bcfg2/Server/SSLServer.py @@ -72,7 +72,7 @@ class SSLServer(SocketServer.TCPServer, object): def __init__(self, listen_all, server_address, RequestHandlerClass, keyfile=None, certfile=None, reqCert=False, ca=None, - timeout=None, protocol='xmlrpc/ssl'): + timeout=None, protocol='xmlrpc/tlsv1'): """ :param listen_all: Listen on all interfaces :type listen_all: bool @@ -333,7 +333,7 @@ class XMLRPCServer(SocketServer.ThreadingMixIn, SSLServer, """ Component XMLRPCServer. """ def __init__(self, listen_all, server_address, RequestHandlerClass=None, - keyfile=None, certfile=None, ca=None, protocol='xmlrpc/ssl', + keyfile=None, certfile=None, ca=None, protocol='xmlrpc/tlsv1', timeout=10, logRequests=False, register=True, allow_none=True, encoding=None): """ diff --git a/testsuite/Testsrc/Testlib/TestClient/TestTools/Test_init.py b/testsuite/Testsrc/Testlib/TestClient/TestTools/Test_init.py index 0c059b5f3..0e9e3a141 100644 --- a/testsuite/Testsrc/Testlib/TestClient/TestTools/Test_init.py +++ b/testsuite/Testsrc/Testlib/TestClient/TestTools/Test_init.py @@ -17,6 +17,14 @@ while path != "/": path = os.path.dirname(path) from common import * +# try to find true +if os.path.exists("/bin/true"): + TRUE = "/bin/true" +elif os.path.exists("/usr/bin/true"): + TRUE = "/usr/bin/true" +else: + TRUE = None + class TestTool(Bcfg2TestCase): test_obj = Tool @@ -69,10 +77,11 @@ class TestTool(Bcfg2TestCase): ["/test"] + [e.get("name") for e in important]) t.getSupportedEntries.assert_called_with() + @skipIf(TRUE is None, "/bin/true or equivalent not found") def test__check_execs(self): t = self.get_obj() if t.__execs__ == []: - t.__execs__.append("/bin/true") + t.__execs__.append(TRUE) @patch("os.stat") def inner(mock_stat): diff --git a/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py b/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py index cfb0c023b..3da323262 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestEncryption.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import os import sys -from Bcfg2.Compat import b64decode +from Bcfg2.Compat import b64decode, b64encode from mock import Mock, MagicMock, patch # add all parent testsuite directories to sys.path to allow (most) @@ -125,10 +125,28 @@ baz passwd, "also bogus"])) - # test with no good passphrase given nor in config + # test with no good passphrase given nor in config. we use + # something that isn't a valid ciphertext here since a + # ciphertext encrypted with one key may be technically + # decryptable with a different key, although it will decrypt + # to gibberish. nonetheless, it doesn't raise the requisite + # EVPError, so the test fails. self.assertRaises(EVPError, bruteforce_decrypt, - crypted, passphrases=["bogus", "also bogus"]) + b64encode("not an actual ciphertext!"), + passphrases=["bogus", "also bogus"]) + + # test with no good passphrase given nor in config. this + # version of the test uses a valid ciphertext, and looks for + # *either* EVPError or a failed decrypt. + try: + plaintext = bruteforce_decrypt(crypted, + passphrases=["bogus", "also bogus"]) + if plaintext == passwd: + self.fail("Successfully decrypted ciphertext with wrong key") + except EVPError: + # success! + pass # test with good passphrase in config file Bcfg2.Options.setup.passphrases = dict(bogus="bogus", diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py index 1f8449bb6..37beaa26c 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py @@ -1121,6 +1121,25 @@ class TestInfoXML(TestStructFile): self.assertTrue(inc("Path", name="/etc/bar.conf", negate="true")) self.assertTrue(inc("Path", name="/etc/bar.conf", negate="tRUe")) + def test_include_element_altsrc(self): + ix = self.get_obj() + metadata = Mock() + entry = lxml.etree.Element("Path", name="/etc/bar.conf", + realname="/etc/foo.conf") + inc = lambda tag, **attrs: \ + ix._include_element(lxml.etree.Element(tag, **attrs), + metadata, entry) + + self.assertFalse(inc("Path", name="/etc/bar.conf")) + self.assertFalse(inc("Path", name="/etc/foo.conf", negate="true")) + self.assertFalse(inc("Path", name="/etc/foo.conf", negate="tRuE")) + self.assertTrue(inc("Path", name="/etc/foo.conf")) + self.assertTrue(inc("Path", name="/etc/foo.conf", negate="false")) + self.assertTrue(inc("Path", name="/etc/foo.conf", negate="faLSe")) + self.assertTrue(inc("Path", name="/etc/bar.conf", negate="true")) + self.assertTrue(inc("Path", name="/etc/bar.conf", negate="tRUe")) + + def test_BindEntry(self): ix = self.get_obj() entry = lxml.etree.Element("Path", name=self.path) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDecisions.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDecisions.py index 537ceb4ff..8b4df8abb 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDecisions.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDecisions.py @@ -52,9 +52,9 @@ class TestDecisions(TestPlugin, TestDecision): metadata = Mock() self.assertEqual(d.GetDecisions(metadata, "whitelist"), - d.whitelist.get_decision.return_value) - d.whitelist.get_decision.assert_called_with(metadata) + d.whitelist.get_decisions.return_value) + d.whitelist.get_decisions.assert_called_with(metadata) self.assertEqual(d.GetDecisions(metadata, "blacklist"), - d.blacklist.get_decision.return_value) - d.blacklist.get_decision.assert_called_with(metadata) + d.blacklist.get_decisions.return_value) + d.blacklist.get_decisions.assert_called_with(metadata) diff --git a/testsuite/before_install.sh b/testsuite/before_install.sh deleted file mode 100755 index 2c80036cd..000000000 --- a/testsuite/before_install.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -ex - -# before_install script for Travis-CI - -PYVER=$(python -c 'import sys;print(".".join(str(v) for v in sys.version_info[0:2]))') - -sudo apt-get update -qq -sudo apt-get install -qq swig libxml2-utils -if [[ "$WITH_OPTIONAL_DEPS" == "yes" ]]; then - if [[ ${PYVER:0:1} == "2" ]]; then - sudo apt-get install -y yum libaugeas0 augeas-lenses libacl1-dev \ - libssl-dev - fi -fi diff --git a/testsuite/install.sh b/testsuite/install.sh index 6f36d4bef..bbbd9ae76 100755 --- a/testsuite/install.sh +++ b/testsuite/install.sh @@ -2,7 +2,10 @@ # install script for Travis-CI -pip install -r testsuite/requirements.txt --use-mirrors +sudo apt-get update -qq +sudo apt-get install swig libxml2-utils + +pip install -r testsuite/requirements.txt PYVER=$(python -c 'import sys;print(".".join(str(v) for v in sys.version_info[0:2]))') @@ -11,7 +14,10 @@ if [[ ${PYVER:0:1} == "2" && $PYVER != "2.7" ]]; then fi if [[ "$WITH_OPTIONAL_DEPS" == "yes" ]]; then - pip install --use-mirrors PyYAML pyinotify boto pylibacl 'django<1.5' Jinja2 + sudo apt-get install -y yum libaugeas0 augeas-lenses libacl1-dev libssl-dev + + pip install --use-mirrors PyYAML pyinotify boto pylibacl 'django<1.5' \ + Jinja2 easy_install https://fedorahosted.org/released/python-augeas/python-augeas-0.4.1.tar.gz if [[ ${PYVER:0:1} == "2" ]]; then # django supports py3k, but South doesn't, and the django bits |