.. -*- mode: rst -*- .. vim: ft=rst .. _server-plugins-structures-bundler: ======= Bundler ======= Bundler is used to describe groups of inter-dependent configuration entries, such as the combination of packages, configuration files, and service activations that comprise typical Unix daemons. Bundles are used to add groups of configuration entries to the inventory of client configurations, as opposed to describing particular versions of those entries. For example, a bundle could say that the configuration file ``/etc/passwd`` should be included in a configuration, but will not describe the particular version of ``/etc/passwd`` that a given client will receive. Group and Client tags can be used inside of bundles to differentiate which entries particular clients will recieve; this is useful for the case where entries are named differently across systems; for example, one Linux distro may have a package called ``openssh`` while another uses the name ``ssh``. See :ref:`xml-group-client-tags` for details and a longer example. A brief example: .. code-block:: xml Note that we do not specify *how* a given entry should be managed, only that it should be. The concrete specification of each entry will be provided by a different plugin such as :ref:`server-plugins-generators-cfg`, :ref:`server-plugins-generators-rules`, or :ref:`server-plugins-generators-packages`. Alternatively, you can use fully-bound entries in Bundler, which has various uses. For instance: .. code-block:: xml In this example, both Service tags and one Package tag are fully bound -- i.e., all information required by the client to manage those entries is provided in the bundle itself. .. _server-plugins-structures-bundler-magic: Bundle "Magic" ============== Bundles are collections of *related* entries. That point is very, very important, because a bundle performs certain "magic" actions when one or more entries in it are modified: * :xml:type:`Service ` entries whose ``restart`` attribute is ``true`` (the default) will be restarted. * :xml:type:`Action ` entries whose ``when`` attribute is ``modified`` will be run. Because of these two magic actions, it's extremely important to structure your bundles around Service and Action entries, rather than around some loose idea of which entries are related. For instance, in order to manage a Bcfg2 server, a number of packages, paths, services, etc. must be managed. But not all of these entries would require ``bcfg2-server`` to be restarted, so to limit restarts it's wise to split these entries into two bundles. See :ref:`server-plugins-structures-bundler-bcfg2-server` for an example of this. .. _server-plugins-structures-bundler-index-disabling-magic: Disabling Magic --------------- Disabling magic bundler actions can be done in one of two ways: * On a per-entry basis. Set ``restart="false"`` on a Service to prevent it from being restarted when the bundle is modified. Set ``when="always"`` on an Action to cause it to run every time, regardless of whether or not the bundle was modified. * On a per-bundle basis. Set ``independent="true"`` on the top-level ``Bundle`` tag to signify that the bundle is a collection of independent (i.e., unrelated) entries, and to prevent any magic actions from being performed. (This is similar to the ``Base`` plugin in older versions of Bcfg2.) This was added in Bcfg2 1.4. Service entries in independent bundles are never restarted, and Action entries in independent bundles are only executed if ``when="always"``. (I.e., an Action entry in an independent bundle with ``when="modified"`` is useless.) .. _server-plugins-structures-bundler-index-genshi-templates: Genshi templates ================ Genshi XML templates allow you to use the `Genshi `_ 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 ``.genshi`` and the associated namespace attribute. *This is deprecated as of Bcfg2 1.4.* 2. Add the Genshi namespace to your existing XML bundle. See :ref:`xml-genshi-templating` for details. Troubleshooting --------------- To render a bundle for a given client, you can run:: bcfg2-info buildbundle This will render the template; it will not fully bind all of the entries in the bundle. See :ref:`bcfg2-info ` for more details. .. _server-plugins-structures-bundler-index-dependencies: Dependencies ============ Dependencies on other bundles can be specified by adding a RequiredBundle tag that adds another bundle by name, e.g.: .. code-block:: xml ... The dependent bundle is added to the list of bundles sent to the client, *not* to the parent bundle itself. If you want to propagate the modification flag from the required bundle, you can add ``inherit_modification="true"`` to the RequiredBundle tag. An example: ``nfs-client.xml``: .. code-block:: xml ``automount.xml``: .. code-block:: xml If a new ``nfs-utils`` package was installed, the ``nfslock``, ``rpcbind``, and ``nfs`` services would be restarted, but *not* the ``autofs`` service. If you would add ``inherit_modification="true"`` to the RequiredBundle tag, you would ensure the propagation of the modification flag and the ``autofs`` service would be restarted, too. But if a new ``/etc/auto.misc`` file was sent out, *only* the ``autofs`` service would be restarted, but the ``nfslock``, ``rpcbind``, and ``nfs`` services would not be restarted (independent of the ``inherit_modification`` flag). Altsrc ====== .. toctree:: :maxdepth: 1 ../altsrc Examples ======== In some cases, configuration files need to include the client's hostname in their name. The following template produces such a config file entry. .. code-block:: xml Depending on the circumstance, these configuration files can either be handled by individual entries in :ref:`server-plugins-generators-cfg`, or can be mapped to a single entry by using the :ref:`server-plugins-structures-altsrc` feature. In this example, configuration file names are built using probed results from the client. getmac is a probe that gathers client MAC addresses and returns them in a newline delimited string. .. code-block:: xml .. note:: * The use of the altsrc directive causes all ifcfg files to be handled by the same plugin and entry. * The blocks have only been available in genshi since 0.4 (http://genshi.edgewall.org/ticket/84) If you want a file to be only on a per-client basis, you can use an if declaration. .. code-block:: xml or alternately .. code-block:: xml or yet another way .. code-block:: xml The final form is preferred if there is no code inside the block that would fail on other clients. While these examples are simple, the test in the if block can in fact be any python statement. .. _server-plugins-structures-bundler-index-examples: Other examples ============== Some simple examples of Bundles can be found in the `Bcfg2 example repository`_. .. _Bcfg2 example repository: https://github.com/solj/bcfg2-repo In addition to the example repository, the following is a list of some more complex example Bundles. .. toctree:: :maxdepth: 1 bcfg2 kernel moab nagios ntp snmpd torque yp