From 59043506d4ee71e39e89fc3216c2bb5cde92604e Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 30 Aug 2013 14:35:32 -0400 Subject: Client: Add entries processed as important to list of entries when determining if a bundle has been modified --- src/lib/Bcfg2/Client/Frame.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/Bcfg2/Client/Frame.py b/src/lib/Bcfg2/Client/Frame.py index 1b26450a6..2eb41e837 100644 --- a/src/lib/Bcfg2/Client/Frame.py +++ b/src/lib/Bcfg2/Client/Frame.py @@ -329,11 +329,13 @@ class Frame(object): if bundle.tag != 'Bundle': continue bmodified = len([item for item in bundle - if item in self.whitelist]) + if item in self.whitelist or + item in self.modified]) actions = [a for a in bundle.findall('./Action') if (a.get('timing') != 'post' and (bmodified or a.get('when') == 'always'))] - # now we process all "always actions" + # now we process all "pre" and "both" actions that are either + # always or the bundle has been modified if self.setup['interactive']: self.promptFilter(iprompt, actions) self.DispatchInstallCalls(actions) -- cgit v1.2.3-1-g7c22 From 05542e5ff0366fb2a7bdf9530cf716c530253fa1 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 30 Aug 2013 14:35:51 -0400 Subject: doc: Updated Client Actions doc to include BoundActions and another example schemas: Fixed Action `when` attribute description --- doc/client/tools/actions.txt | 24 ++++++++++++++++++++---- schemas/types.xsd | 9 +++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/doc/client/tools/actions.txt b/doc/client/tools/actions.txt index 81486ecd1..e5fdb1f39 100644 --- a/doc/client/tools/actions.txt +++ b/doc/client/tools/actions.txt @@ -31,10 +31,11 @@ central reporting of action failure is desired, set this attribute to 'check'. Also note that Action entries included in Base will not be executed. -Actions cannot be completely defined inside of a bundle; they are a bound -entry, much like Packages, Services or Paths. The Rules plugin can bind -these entries. For example to include the above action in a bundle, -first the Action entry must be included in the bundle: +Actions may be completely defined inside of a bundle with the use of +:ref:`server-configurationentries`, much like Packages, Services or Paths. +The Rules plugin can also bind these entries. For example to include the +above action in a bundle, first the Action entry must be included in the +bundle: .. code-block:: xml @@ -70,3 +71,18 @@ requires this key. + +Example BoundAction (add RPM GPG keys) +====================================== + +This example will add the RPM-GPG-KEY-redhat-release key to the RPM +GPG keyring **before** Package entries are handled on the client run. + +.. code-block:: xml + + + + + + + diff --git a/schemas/types.xsd b/schemas/types.xsd index 4e3dfd70f..17b7f05f0 100644 --- a/schemas/types.xsd +++ b/schemas/types.xsd @@ -122,7 +122,10 @@ - When the action is run. + When the action is run. Actions with "pre" timing are run + after important entries have been installed and before + bundle entries are installed. Actions with "post" timing + are run after bundle entries are installed. @@ -130,9 +133,7 @@ If the action is always run, or is only run when a bundle - has been modified. Actions that run before bundle - installation ("pre" and "both") ignore the setting of - ``when`` and are always run regardless. + has been modified. -- cgit v1.2.3-1-g7c22 From 730179b581e0dcdaa93a4819acbeb207db6980ef Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 30 Aug 2013 14:57:32 -0400 Subject: Fix pep8 errors --- src/lib/Bcfg2/Client/Frame.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Bcfg2/Client/Frame.py b/src/lib/Bcfg2/Client/Frame.py index 2eb41e837..ad718749e 100644 --- a/src/lib/Bcfg2/Client/Frame.py +++ b/src/lib/Bcfg2/Client/Frame.py @@ -329,12 +329,12 @@ class Frame(object): if bundle.tag != 'Bundle': continue bmodified = len([item for item in bundle - if item in self.whitelist or - item in self.modified]) + if item in self.whitelist or + item in self.modified]) actions = [a for a in bundle.findall('./Action') if (a.get('timing') != 'post' and (bmodified or a.get('when') == 'always'))] - # now we process all "pre" and "both" actions that are either + # now we process all "pre" and "both" actions that are either # always or the bundle has been modified if self.setup['interactive']: self.promptFilter(iprompt, actions) -- cgit v1.2.3-1-g7c22 From 110861ec9d8cd70dc75ca8ca33b66db8060e761c Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 30 Aug 2013 16:03:23 -0400 Subject: XMLFileBacked: Monitor XIncludes whenever a FAM is available This monitors XIncluded files even if should_monitor=False, since the object monitoring the base file will not monitor XIncludes. This ensures that XIncluded files are properly monitored whenever possible, particularly for Bundler and Properties. This is a partial backport of 5b66845 -- as much of a backport as is possible without a module-level FAM object. --- src/lib/Bcfg2/Server/Plugin/helpers.py | 7 ++++--- src/lib/Bcfg2/Server/Plugins/Bundler.py | 9 +++++---- .../Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py | 14 +++----------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 81dc1d736..3a994606c 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -606,15 +606,16 @@ class XMLFileBacked(FileBacked): def add_monitor(self, fpath): """ Add a FAM monitor to a file that has been XIncluded. This - is only done if the constructor got both a ``fam`` object and - ``should_monitor`` set to True. + is only done if the constructor got a ``fam`` object, + regardless of whether ``should_monitor`` is set to True (i.e., + whether or not the base file is monitored). :param fpath: The full path to the file to monitor :type fpath: string :returns: None """ self.extra_monitors.append(fpath) - if self.fam and self.should_monitor: + if self.fam: self.fam.AddMonitor(fpath, self) def __iter__(self): diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py index eef176cca..fb327f7ef 100644 --- a/src/lib/Bcfg2/Server/Plugins/Bundler.py +++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py @@ -38,9 +38,9 @@ if HAS_GENSHI: Bcfg2.Server.Plugin.StructFile): """ Representation of a Genshi-templated bundle XML file """ - def __init__(self, name, specific, encoding): + def __init__(self, name, specific, encoding, fam=None): TemplateFile.__init__(self, name, specific, encoding) - Bcfg2.Server.Plugin.StructFile.__init__(self, name) + Bcfg2.Server.Plugin.StructFile.__init__(self, name, fam=fam) self.logger = logging.getLogger(name) def get_xml_value(self, metadata): @@ -106,13 +106,14 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, nsmap['py'] == 'http://genshi.edgewall.org/')): if HAS_GENSHI: spec = Bcfg2.Server.Plugin.Specificity() - return BundleTemplateFile(name, spec, self.encoding) + return BundleTemplateFile(name, spec, self.encoding, + fam=self.core.fam) else: raise Bcfg2.Server.Plugin.PluginExecutionError("Genshi not " "available: %s" % name) else: - return BundleFile(name, self.fam) + return BundleFile(name, fam=self.fam) def BuildStructures(self, metadata): """Build all structures for client (metadata).""" diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py index 94866cf39..5ae0dfcba 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py @@ -623,17 +623,9 @@ class TestXMLFileBacked(TestFileBacked): self.assertIn("/test/test2.xml", xfb.extra_monitors) fam = Mock() - if self.should_monitor is not True: - fam.reset_mock() - xfb = self.get_obj(fam=fam) - fam.reset_mock() - xfb.add_monitor("/test/test3.xml") - self.assertFalse(fam.AddMonitor.called) - self.assertIn("/test/test3.xml", xfb.extra_monitors) - - if self.should_monitor is not False: - fam.reset_mock() - xfb = self.get_obj(fam=fam, should_monitor=True) + fam.reset_mock() + xfb = self.get_obj(fam=fam) + if xfb.fam: xfb.add_monitor("/test/test4.xml") fam.AddMonitor.assert_called_with("/test/test4.xml", xfb) self.assertIn("/test/test4.xml", xfb.extra_monitors) -- cgit v1.2.3-1-g7c22 From 43571190e263ed9bfb372806baf1037b711914d2 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 3 Sep 2013 08:30:30 -0400 Subject: bcfg2_local.py: Fixed addresspair port --- tools/bcfg2_local.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/bcfg2_local.py b/tools/bcfg2_local.py index 3c90a3ea5..78a46ba5c 100755 --- a/tools/bcfg2_local.py +++ b/tools/bcfg2_local.py @@ -47,7 +47,10 @@ class LocalProxy(object): func = getattr(self.core, attr) if func.exposed: def inner(*args, **kwargs): - args = ((self.ipaddr, self.hostname), ) + args + # the port portion of the addresspair tuple isn't + # actually used, so it's safe to hardcode 6789 + # here. + args = ((self.ipaddr, 6789), ) + args return func(*args, **kwargs) return inner raise AttributeError(attr) -- cgit v1.2.3-1-g7c22 From 5c9cd24767bcbc8cdb39eebf2fd81e9c814c01af Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 4 Sep 2013 15:27:02 -0400 Subject: Cfg: More flexible and complete way to specify authorized keys options --- doc/server/plugins/generators/cfg.txt | 3 +- schemas/authorizedkeys.xsd | 70 +++++++++++++++++++++- .../Plugins/Cfg/CfgAuthorizedKeysGenerator.py | 17 ++++-- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/doc/server/plugins/generators/cfg.txt b/doc/server/plugins/generators/cfg.txt index e3768a3ba..0f0601105 100644 --- a/doc/server/plugins/generators/cfg.txt +++ b/doc/server/plugins/generators/cfg.txt @@ -541,7 +541,8 @@ Example - + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDw/rgKQeARRAHK5bQQhAAe1b+gzdtqBXWrZIQ6cIaLgxqj76TwZ3DY4A6aW9RgC4zzd0p4a9MfsScUIB4+UeZsx9GopUj4U6H8Vz7S3pXxrr4E9logVLuSfOLFbI/wMWNRuOANqquLYQ+JYWKeP4kagkVp0aAWp7mH5IOI0rp0A6qE2you4ep9N/nKvHDrtypwhYBWprsgTUXXMHnAWGmyuHGYWxNYBV9AARPdAvZfb8ggtuwibcOULlyK4DdVNbDTAN1/BDBE1ve6WZDcrc386KhqUGj/yoRyPjNZ46uZiOjRr3cdY6yUZoCwzzxvm5vle6mEbLjHgjGEMQMArzM9 vendor@example.com diff --git a/schemas/authorizedkeys.xsd b/schemas/authorizedkeys.xsd index 848f99bae..dbf32cc25 100644 --- a/schemas/authorizedkeys.xsd +++ b/schemas/authorizedkeys.xsd @@ -42,6 +42,43 @@ + + + + An **OptionContainerType** is a tag used to provide logic. + Child entries of an OptionContainerType tag only apply to + machines that match the condition specified -- either + membership in a group, or a matching client name. + :xml:attribute:`OptionContainerType:negate` can be set to + negate the sense of the match. + + + + + + + + + + + + The name of the client or group to match on. Child entries + will only apply to this client or group (unless + :xml:attribute:`OptionContainerType:negate` is set). + + + + + + + Negate the sense of the match, so that child entries only + apply to a client if it is not a member of the given group + or does not have the given name. + + + + + @@ -50,6 +87,9 @@ + + + @@ -77,12 +117,36 @@ + + + + Specify options for public key authentication and connection. + See :manpage:`sshd(8)` for details on allowable options. + + + + + + The name of the sshd option. + + + + + + + The value of the sshd option. This can be omitted for + options that take no value. + + + + + - Specify parameters for public key authentication and - connection. See :manpage:`sshd(8)` for details on allowable - parameters. + **Deprecated** way to specify options for public key + authentication and connection. See :manpage:`sshd(8)` for + details on allowable parameters. diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py index 824d01023..f304891d5 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py @@ -50,10 +50,19 @@ class CfgAuthorizedKeysGenerator(CfgGenerator, StructFile): spec = self.XMLMatch(metadata) rv = [] for allow in spec.findall("Allow"): - params = '' + options = [] if allow.find("Params") is not None: - params = ",".join("=".join(p) - for p in allow.find("Params").attrib.items()) + self.logger.warning("Use of in authorized_keys.xml " + "is deprecated; use