Deploy Definition File Reference

Deploy 3.0

Deploy Definition File Reference

A Complete Guide to the Deploy Definition File

Edition 3.0


Legal Notice

Copyright © 2015 Deploy Foundation. This material may only be distributed subject to the terms and conditions set forth in the GNU Free Documentation License (GFDL), V1.2 or later (the latest version is presently available at http://www.gnu.org/licenses/fdl.txt).
May 2015

Chapter 1.  Introduction

The definition file contains instructions for building system and package repositories. It defines repository content and configuration: name, version, and architecture; packages to include; packages to build; and testing and publishing instructions. Deploy uses definitions to assemble, create and publish repositories. Other programs, such as YUM, Anaconda, and RPM use files in repositories to deploy and update client machines.
The definition is a text-based file in XML format. Within the file are a series of top-level elements that equate to modules, or steps, within the Deploy build process. These elements, in turn, contain their own attributes and elements. The only required top-level element is main; all other top-level elements are optional or conditional, based on the type of repository being defined. Top-level elements can appear in the definition in any order. Indentation is for readability purposes only.
A definition can be located in any local directory and invoked from the command line using the command deploy followed by the full or relative pathname to the file, such as:
deploy /path/to/definition

1.1.  Document Conventions

The arrangement of content in this chapter and other document chapters is alphabetical.
Comments
Comments in XML appear between <!-- and -->, and may span multiple lines.
Definitions
The tag "Definition" gives a description of the top-level element. Definitions include a short explanation of the item’s purpose, what happens when it's used, elements and attributes enclosed within that item, what values it accepts, the default value, whether it is required and the number of times it may appear.
Elements and Attributes
Elements and attributes in XML are referred to by their XPath equivalents. The active node is always considered to be the root, repo; thus, the first element in the XPath expression is the top-level element, while subsequent elements/attributes are its children. For more details on XPath syntax, see XML Path Language.
XPath expressions appear in italics.
Examples
The section heading "Examples" or the phrase "For example" indicate a code example with actual values.
Filenames
Filenames appear in monospace font.
Frequency
Unless otherwise specified, all sub-elements are optional and can occur a maximum of one time underneath the top-level element.
Note
Information items appear with an "Note" tag:

Note

Be sure to escape the < character using <.
Syntax
The heading "Syntax" contains the syntax for a top-level element, common element, or attribute. Elements or attributes that appear between square brackets ([ and ]) are optional. Choices are indicated by parenthesis (( and )), with each individual choice separated by a vertical bar (|). If an element can be repeated multiple times, it is followed by an asterisk (*).

Note

The indicators for optional elements and elements that can occur more than once can be combined:
 <element/>   <!-- 1 required -->
 <element/>*  <!-- 1 required, additional allowed -->
[<element/>]  <!-- 0-1 allowed -->
[<element/>]* <!-- 0 or more allowed -->
Occasionally, a syntax requirement may be expressed in a comment instead of with the above syntax indicators for clarity's sake.
Top-Level Elements and Module Groups
Top-level element names and module group names appear in bold.
Content Types
When an element's text value or attribute accepts a particular class of input, this content type is indicated by monospace font without a leading dollar sign, e.g. BOOLEAN.

1.2.  Example Definition

Following is an example definition for a minimal system repository.

Note

On a system with the Deploy RPM installed, this file can be found as web-server.definition in the templates folder at /usr/share/deploy/templates/el6/httpd.
<?xml version="1.0" encoding="utf-8"?>
<definition>

<macro id='name'>web-server</macro>
<macro id='os'>centos</macro>
<macro id='edition'>server</macro>
<macro id='version'>6</macro>
<macro id='arch'>x86_64</macro>
<macro id='id'>%{name}-%{os}-%{version}-%{arch}</macro>
<macro id='test-install-enabled'>false</macro>

<main>
<fullname>Example Web Server</fullname>
<name>%{name}</name>
<os>%{os}</os>
<version>%{version}</version>
<arch>%{arch}</arch>
<id>%{id}</id>
</main>

<repos>
<include href='%{templates-dir}/%{norm-os}/common/repos.xml'
         xpath="./repo[@id='%{os}-%{edition}-base' or 
                       @id='%{os}-%{edition}-updates']"/>
</repos>

<packages>
<include href="%{templates-dir}/%{norm-os}/common/packages.xml"
         xpath="./packages[@id='core']/*"/>
</packages>

<config-rpms>
<include href='%{templates-dir}/%{norm-os}/iptables/iptables-update.xml'/>
<include href='%{templates-dir}/%{norm-os}/httpd/httpd-config.xml'/>
</config-rpms>

<test-update>
<include href="%{templates-dir}/%{norm-os}/libvirt/deploy.xml"
         xpath="./*"/>
<include href="%{templates-dir}/%{norm-os}/httpd/test-httpd-config.xml"/>
</test-update>

<test-install enabled="%{test-install-enabled}">
<include href="%{templates-dir}/%{norm-os}/libvirt/deploy.xml"
         xpath="./*"/>
<include href="%{templates-dir}/%{norm-os}/httpd/test-httpd-config.xml"/>
</test-install>

</definition>

1.3.  Data Files

Deploy creates a file, referred to as the data file or datfile, to track and maintain Deploy-generated input data. Examples of data in this file include release numbers for generated RPMs, generated GPG signing keys, and generated passwords and crypt passwords. See Chapter 4, RPM Elements and Chapter 5, Deployment Elements for more information on these topics.
Data files are created in data folders. Both are named using the build ID with the .dat extension. For example, given a definition with a build ID of "samba-server-6-x86_64" (taken from the main/id element), Deploy will create a data folder and data file as follows:
samba-server-6-x86_64.dat/samba-server-6-x86_64.dat
By default, Deploy creates the data folder in the definition directory. An alternative directory location can be specified on the deploy command line using the '--data-root' parameter, for example:
deploy samba.definition --data-root /my/dat/root    
See the Section 3.1, “ Main ” element for information on specifying the build ID.

Warning

Care must be taken not to delete the data file. Doing so will cause Deploy to regenerate missing information. As a result, installed client machines may fail to download updated RPMs or may report errors when performing RPM GPG key checking.

Chapter 2.  Templates, Macros and Include Elements

To assist with definition creation and reuse, Deploy supports templates, macros and include elements.
Templates are complete definitions, or segments of definitions, that can be used as a starting point for creating new definitions.
Macros and include elements assist with content substitution. These two methods overlap in some areas, and provide unique functionality in others.
Used together, these three features offer convenience and flexibility in creating definitions. They will be shown in many examples in the remainder of this document, as well as in other Deploy documentation and example files.

2.1. Templates

Deploy includes a number of templates to assist with common definition creation tasks. These templates are located in the default templates folder at /usr/share/deploy/templates/. Individual templates are not discussed in detail here, but are referenced throughout this document.
Users can specify additional template folders in the Deploy Configuration file, /etc/deploy/deploy.conf by default, using templates-path elements. See the Deploy Configuration File Manual Page (man deploy.conf) for additional information. Deploy searches template folders in the order specified in the configuration file.
Templates can be included within definitions using %{templates-dir} and %{norm-os} macros, examples are shown through this document.

Warning

Do not modify files in the /usr/share/deploy/templates folder. Changes to these files will be overwritten when Deploy is updated. Instead, complete the following steps:
1. Create a new templates folder and copy files to it.
mkdir -p /my/templates/folder
cp -a /usr/share/deploy/templates/* /my/templates/folder
2. Add a line to /etc/deploy/deploy.conf as follows:
<deploy>
<templates-path>/my/templates/folder</templates-path>
</deploy>

2.2.  Macros

Macros provide a compact syntax for substituting content for placeholders within a definition. Macro definitions specify a macro id and associated replacement content. Content can include text, element, or mixed text and elements. Macro placeholders specify the location within the definition where the text is to be substituted.
The syntax for macro placeholders is a percent sign preceding a macro id enclosed in braces: %{id}. Placeholders can be used anywhere within the definition.
Deploy supports four types of macros: command-line macros, in-document macros, global run-time macros and per-module run-time macros.

2.2.1.  Command-Line Macros

Command-line macros are specified using one or more macro options on the deploy command line. Macro options use the following syntax: --macro id:value. Macros specified on the command line are the first to be resolved during Deploy processing, and their values override values provided by any other macro element or run-time macro. The example below shows a common usage scenario.
Example - In this example the macro placeholders %{os}, %{version} and %{arch} will be replaced with the values "centos", "6" and "i386", respectively, when Deploy is executed using the following command line:
deploy --macro "os:centos" --macro "version:6" --macro "arch:i386" path/to/definition
This allows a single definition to be used across multiple os, version and arch operating system combinations. The definition is shown below:
<?xml version="1.0" encoding="utf-8"?>
<definition schema-version="1.0">

<main>
<name>example<name>
<os>%{os}<os>
<version>%{version}<version>
<arch>%{arch}<arch>
<id>example-%{os}-%{version}-%{arch}</id>
</main>
...

</definition>

2.2.2. In-Document Macros

In-Document Macros are specified using macro elements. Macro elements can be included anywhere within the definition. They are resolved in order following command-line macros, and they override run-time macros, described in the next section, with the same id.
Multiple macro elements with the same id may exist within the definition. In this case, the value of the first element is used, and all remaining elements are silently ignored.

2.2.2.1. Syntax

[<macro id=TEXT [type=("text"|"script")] [persist="BOOLEAN"]>TEXT</macro>]

2.2.2.2. Attributes

Macro elements accept three attributes, id, type, and persist.
@id
TEXT value identifying the name of the macro.
@type
The type of macro, either text or script. This attribute is optional. The default value is text.
If @type is text the element text identifies content to substitute in place of the macro. For example:
<macro id="version">6</macro>
If @type is script the element provides a script used to determine the element value. Deploy first saves the script to a temporary file named .script located in the data folder. See the section on Section 1.3, “ Data Files ” for more information on data folders. Deploy then executes the script and uses the output as the value for the macro.
If @persist is TRUE (default), Deploy stores script output in the data file. On subsequent runs, Deploy first determines if the script has changed. If so, it executes the script, and uses the new value. If the script has not changed, Deploy retrieves and uses the stored value from the data file.
Following is an example of a script macro that creates and persists a unique identifier:
<macro id="unique-id" type="script">
#!/usr/bin/python
import uuid
print uuid.uuid1()
</macro>
@persist
BOOLEAN value indicating whether the result of script macros should be persisted in the data file for use in subsequent builds.
The @persist attribute is optional. The default value is TRUE. The @persist attribute is ignored for non-script macros.
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.

2.2.2.3. Examples

Example 1 - Global Macros. This example is similar to that in the previous section, with the addition of global in-document macros for name, os, version, arch, and id. When Deploy is executed with the command line from Example 1, the results will be the same as in that example (since command-line macros are resolved first). However, when Deploy is executed with no macros specified on the command line, the values for os, version and macro will be "centos", "6" and "x86_64" respectively. In addition, because "name" and "id" are defined as macros, they will be available for use in other locations within the definition.
In fact, because the configuration shown below is so flexible over time in facilitating migration across operating systems, versions and architecture, we use it in all of our examples, and we highly recommend it as a starting point for every definition.
<?xml version="1.0" encoding="utf-8"?>
<definition schema-version="1.0">

<macro id="name">example<macro>
<macro id="os">centos<macro>
<macro id="edition">server<macro>
<macro id="version">6<macro>
<macro id="arch">x86_64<macro>
<macro id="id">%{name}-%{os}-%{version}-%{arch}<macro>

<main>
<name>%{name}<name>
<os>%{os}<os>
<version>%{version}<version>
<arch>%{arch}<arch>
<id>%{id}<id>
</main>
...

</definition>
Example 2 - Nested Macros. Macros can be nested to support conditional content inclusion. Nested macros are a powerful and practical tool. They allow a single file to be used across multiple operating systems, versions and architectures, even when requirements vary. This is especially useful during system migrations.
The example below shows a packages element containing two groups (core and base), and a nested macro placeholder. The nested placeholder selects additional content based on the value provided for the version macro. In the default case (version=6), the list of groups for the repository will be "core, base and cifs-file-server". If the version macro is set to "5", however, either manually or using a command-line macro, the list of groups will be "core, base and smb-server".
<?xml version="1.0" encoding="utf-8"?>
<definition>

<macro id="version">6<macro>
<macro id="arch">i386<macro>

<packages>
<group>core<group>
<group>base<group>
%{packages-%{version}}
</packages>

<macro id="packages-5">
<group>smb-server</group>
</macro>

<macro id="packages-6">
<group>cifs-file-server</group>
</macro>
...
</definition>

2.2.3. Global Run-Time Macros

Global run-time macros are defined by Deploy during the build process and applied across all Deploy modules. Deploy provides four global run-time macros: %{templates-dir}, %{norm-os}, %{definition-dir}, and %{data-dir}.
%{templates-dir}
The folder location of template files, /usr/share/deploy/templates by default. Additional template locations can be specified using the templates-path element of the Deploy Configuration file. Deploy searches templates folders in the order specified. See man deloy.conf for additional information.
Useful for specifying template files in a hierarchical list of folders.
%{norm-os}
Normalized name and version of the OS as shown in the following table:
OS Name OS Version %{norm-os}
centos 6 el6
rhel 6 el6
centos 7 el6
rhel 7 el6
Useful for organizing template files according to the underlying operating system.
%{definition-dir}
The folder location of the definition file. Useful for specifying files and folders relative to the definition file.
%{data-dir}
The folder location of the Section 1.3, “ Data Files ”. Useful for scripts to store and retrieve persisted, runtime-generated, per-build data such as machine hostnames and ssh keys.
The %{data-dir} macro is not supported within the href and xpointer attributes of include elements.
Global run-time macros are resolved following in-document macros.

2.2.4. Per-Module Run-Time Macros

Per-module run-time macros are macros that are defined by discrete modules within the Deploy build process.
All modules provide at least one run-time macro:
%{module}
Name of the module in which the macro is located, e.g. 'test-install', 'test-update' or 'publish'.
In addition, many modules provide module-specific run-time macros. These modules include config-rpms, srpmbuild, test-install, test-update and publish. See these modules for more information.
Per-module run-time macros are the last to be resolved.

2.3.  Include Elements

Deploy supports a simplified version of XML Inclusions. This section provides a brief overview and examples.
Similar to macros, include elements allow content reuse in definitions. There are two important differences between the two mechanisms, however:
  • Include elements can be used to include content from external files. Macros cannot.
  • Macros can be used within attribute text, e.g. <repo id="centos-%{version}-%{arch}">. Include elements cannot.
Include elements can be nested, e.g. repository1.definition can include content from document2.xml, which can further include content from document3.xml.

Note

When including nested documents, all macros from each document will be resolved prior to performing the include.

2.3.1.  Syntax

<include href=PATH [parse=(text|xml)] [xpath=XPATH]/>

2.3.2. Attributes

Include elements support three attributes: href, parse and xpath.
href
PATH of the file to include. See Section 7.12, “ Content: PATH for information on PATH values.
The href attribute is required.
parse
Specifies whether the file is to be parsed as "text" or "xml"
The parse attribute is optional. The default value is "xml".
xpath
XPATH query identifying a portion of the file to be included. Ignored if the parse attribute is set to "text". See internet resources on "XML Path Language" and "XPath" for query syntax and information.
The xpath attribute is optional. By default the entire file is included.

2.3.3. Examples

The examples below illustrate several common scenarios for using include elements in definitions.
Example 1 - Including an external text document.
The example below includes content from a text file named file.txt. The href attribute identifies the path of the file for inclusion, in this case a file named file.txt in the same folder as the definition. The parse attribute indicates that the file to be included is in text format, rather than XML (the default).
<?xml version="1.0" encoding="utf-8"?>
<definition>
...
<include href="file.txt" parse="text" />
...
</definition>
Example 2 - Including an external XML document.
In this example, an entire xml document, update.xml is included within the definition. This example is similar to Example 1 above, except that the parse attribute is not required since the included file is in the default XML format.
<?xml version="1.0" encoding="utf-8"?>
<definition>
...
<include href="repos.xml"/>
...
</definition>
Example 3 - Including segments of XML documents.
This example shows two documents, repos.xml and example.definition. The repos.xml document contains definitions for several input repositories. Two of these will be included in the example.definition using include elements. The xpath attribute of the include element identifies the segments for inclusion.
repos.xml
<?xml version="1.0" encoding="utf-8"?>
<repos>

<!-- centos base repos -->
<!-- note: server, workstation and desktop point to the same repo, but we
     include them separately here to make it easier to switch between centos
     and rhel -->
<repo id="centos-server-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- centos update repos -->
<!-- note: server, workstation and desktop point to the same repo, but we
     include them separately here to make it easier to switch between centos
     and rhel -->
<repo id="centos-server-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- centos-extras -->
<repo id="centos-server-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- rhel base repos -->
<repo id="rhel-server-base">
<macro id="rhel-server-mirror">http://mirror.company.com/rhel/enterprise/6Server/en/os/%{arch}</macro>
<baseurl>%{rhel-server-mirror}</baseurl>
<gpgkey>%{rhel-server-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-server-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<repo id="rhel-workstation-base">
<macro id="rhel-workstation-mirror">http://mirror.company.com/rhel/enterprise/6Workstation/en/os/%{arch}</macro>
<baseurl>%{rhel-workstation-mirror}</baseurl>
<gpgkey>%{rhel-workstation-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-workstation-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<repo id="rhel-desktop-base">
<macro id="rhel-desktop-mirror">http://mirror.company.com/rhel/enterprise/6Desktop/en/os/%{arch}</macro>
<baseurl>%{rhel-desktop-mirror}</baseurl>
<gpgkey>%{rhel-desktop-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-desktop-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<!-- rhel update repos -->
<repo id="rhel-server-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/server/6/6Server/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/server-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/server-6-key.pem</sslclientkey>
</repo>

<repo id="rhel-workstation-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/workstation/6/6Workstation/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/workstation-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/workstation-6-key.pem</sslclientkey>
</repo>

<repo id="rhel-desktop-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/client/6/6Client/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/desktop-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/desktop-6-key.pem</sslclientkey>
</repo>

<!-- epel repo -->
<repo id='epel'>
<macro id='epel-mirror'>http://dl.fedoraproject.org/pub/epel</macro>
<baseurl>%{epel-mirror}/%{version}/%{arch}</baseurl>
<gpgkey>%{epel-mirror}/RPM-GPG-KEY-EPEL-%{version}</gpgkey>
</repo>

</repos>
example.definition
<?xml version="1.0" encoding="utf-8"?>
<definition>
...
<repos>
<include href='%{templates-dir}/%{norm-os}/common/repos.xml'
         xpath="./repo[@id='%{os}-%{edition}-base' or
                       @id='%{os}-%{edition}-updates']"/>
</repos>

</definition>

Chapter 3.  Basic Elements

3.1.  Main

3.1.1.  Definition

Contains basic information about the repository.

3.1.2.  Syntax

<main>
  <name>TEXT</name>
  <os>(centos|rhel)</os>
  <version>6</version>
  <arch>(i386|x86_64)</arch>
  <id>TEXT</id>
 [<type>(package|system)</type>]
 [<fullname>TEXT</fullname>]
 [<bug-url>URL</bug-url>]
 [<log-file>PATH</log-file>]
</main>

3.1.3.  Elements

name
TEXT value providing the name of the repository. Typically specified using a macro. See Section 2.2.2, “In-Document Macros” for more information.
This element is required.
See Section 7.13, “ Content: TEXT for more information on TEXT values.
os
TEXT value providing the name of the base operating system for the repository. Accepts either "centos" or "rhel". Typically specified using a macro. See Section 2.2.2, “In-Document Macros” for more information.
This element is required.
See Section 7.13, “ Content: TEXT for more information on TEXT values.
version
The version of the base operating system for the repository. Valid values are "6". Typically specified using a macro. See Section 2.2.2, “In-Document Macros” for more information.
This element is required.
arch
The architecture of the base operating system for the repository. Accepts either "i386" or "x86_64". Typically specified using a macro. See Section 2.2.2, “In-Document Macros” for more information.
This element is required.
id
TEXT value providing a unique id for the repository. Used as the default name for deployment local-dir folders. See local-dir for more information. Typically specified using a macro consisting of name, os, version and arch macros. See Section 2.2.2, “In-Document Macros” for more information and an example.
This element is required.
See Section 7.13, “ Content: TEXT for more information on TEXT content.

A Note about Macros in the main/id Element

Because the id element is used for setting up the data file, which is used early in the Deploy process, it has some restrictions on the use of macros. Specifically, any placeholders within the id element must be resolvable using either command line macros, or user-defined macros located within the body of the definition file, i.e. not within xincluded content.
See Section 2.2.2, “In-Document Macros” for an example of using macro placeholders in id element.
type
The type of repository to create. Valid values are "package" and "system".
This element is optional. The default value is 'system'.
See the Deploy User Manual for information on differences between package and system repositories.
fullname
TEXT content specifying a human-friendly name for the repository. Displays during client machine installation.
This element is optional. The default value is %{name}.
See Section 7.13, “ Content: TEXT for more information on TEXT content.
bug-url
URL to a location where users should report installation issues. This value of this element is displayed when an error occurs during system installation.
This element is optional. The default value is https://bugzilla.redhat.com/bugzilla/.
See Section 7.14, “ Content: URL for more information on URL values.
log-file
PATH to a file where Deploy should write the repository’s log information. The file is created if it does not exist.
This element is optional. The default value is /var/log/deploy.log.
See Section 7.12, “ Content: PATH for more information on PATH values

3.1.4.  Examples

<main>
  <name>samba-server</name>
  <os>centos</os>
  <version>6</version>
  <arch>i386</arch>
  <fullname>CentOS Samba Server</fullname>
  <bug-url>http://www.example.com/bugs</bug-url>
  <log-file>/home/deployuser/samba-server.log</log-file>
</main>

3.2.  Repos

3.2.1.  Definition

The repos element specifies repositories that Deploy uses to download required packages.
Repositories are specified using repo elements.
Repo elements can also be specified within config-rpm elements.

3.2.2.  Syntax

[<repos>
  <repo id=TEXT>*
    (<baseurl>URL</baseurl> | 
    [<download>BOOLEAN</download>] | 
    [<exclude>PACKAGE</exclude>]* | 
    [<gpgkey>PATH</gpgkey>]* | 
    [<includepkg>PACKAGE</includepkg>]* | 
    [<sslcacert>PATH</sslcacert>] | 
    [<sslclientcert>PATH</sslclientcert>] | 
    [<sslclientkey>PATH</sslclientkey>] | 
  </repo>
</repos>]

3.2.3.  Elements

repo
A YUM package repository from which to select packages for including in the repository.
Valid repository definitions must include a minimum of one baseurl. Furthermore, all repositories must have a unique id.
This element can occur zero or more times. However, if type is "system", at least one repo must be defined: an operating system base repository. Base repositories are unique in that they contain install image files. These files are located within a folder named images. They are used to create installation images for the system. Base repositories include CentOS and Red Hat Enterprise Linux.
For CentOS, the base repository will be a public or local mirror. For Red Hat Enterprise Linux, it will be an install tree created by using the following command to mount an ISO image file to a local or web-available network location:
mount -o loop isofilemount_location
See the Red Hat Enterprise Linux 6 Installation Guide under the topic Preparing for a Network Installation for more information.
Attributes
id
A unique ID representing this repository. Spaces are not permitted in the ID.
This attribute is required.
If multiple repositories are defined with the same ID, the first repository is used and duplicates are silently ignored.
Elements
baseurl
URL to a valid repository.
Deploy supports an expanded type of repository, a "repository group". A repository group is a collection of repositories within a single baseurl.
For example, if there are three repositories repoA, repoB, and repoC in folder /var/repos, all the repos can be included in Deploy as follows:
<repo id="repogroup">
  <baseurl>/var/repos</baseurl>
</repo>
This repository contains all the packages available in each of the individual repositories repoA, repoB, and repoC.
This element is required.
See Section 7.14, “ Content: URL for information on URL values.
download
BOOLEAN value indicating whether packages from this repository should be downloaded when type is set to package. If TYPE is not set to package, this option is ignored.
This element is optional. The default value is FALSE.
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
exclude
PACKAGE pattern to exclude from the repository.
By default, all packages in all repositories are available for Deploy to use. Packages can be excluded from all repositories using the packages/exclude element. See Section 3.3, “ Packages ” for information.
Available packages for a single repository can be restricted using one or more repo/exclude or repo/includepkg elements. The logic for processing these elements, described below, is the same as YUM's processing of exclude and includepkgs repo options.
Using a repository's repo/includepkg elements, the list of available packages is restricted to only those packages that match one or more of the included package patterns. If no repo/includepkg package patterns are specified, all packages are considered available.
After processing a repository's repo/includepkg elements, Deploy processes repo/exclude elements. Packages matching patterns specified in these elements will be ignored.
This element can occur zero or more times.
See Section 7.11, “ Content: PACKAGE for information on PACKAGE patterns.
See also includepkg .
gpgkey
PATH to a GPG key.
This element can occur zero or more times for any given repository. By default, however, one or more keys must be provided across all repositories. Deploy uses GPG keys to verify that packages are from trusted providers. Verification can be disabled (not recommended) by setting release-rpm/updates@gpgcheck to FALSE.
See Section 7.12, “ Content: PATH for information on PATH values.
See also the release-rpm element.
includepkg
PACKAGE pattern to include from the repository. If one or more repo/includepkg patterns are defined, the repository will include only packages that match these patterns and nothing else.
This element can occur zero or more times.
See Section 7.11, “ Content: PACKAGE for information on PACKAGE patterns.
See also exclude .
sslcacert
PATH to a file or directory containing certificate authority certificates to be used to verify SSL certificates.
This element is required when providing sslclientcert and sslclientkey elements.
See Section 7.12, “ Content: PATH for information on PATH values.
sslclientcert
PATH to a file containing an SSL certificate for connecting to the repository.
This element is required when providing sslcacert and sslclientkey elements.
See Section 7.12, “ Content: PATH for information on PATH values.
sslclientkey
PATH to a file containing an SSL client key for connecting to the repository.
This element is required when providing sslcacert and sslclientcert elements.
See Section 7.12, “ Content: PATH for information on PATH values.

3.2.3.1.  Examples

In the following example, line breaks may have been added to the repos/repo/baseurl to improve readability. In a real repository definition, however, line breaks within PATH-like elements are not allowed.
3.2.3.1.1. Example 1 - repos.xml template
Deploy includes a template to assist with repository definition. The template is located at %{templates-dir}/el6/common/repos.xml. It can be used within a definition as follows:
<repos>
<include href='%{templates-dir}/%{norm-os}/common/repos.xml'
         xpath="./repo[@id='%{os}-%{edition}-base' or
                       @id='%{os}-%{edition}-updates']"/>
</repos>
Users will need to complete additional steps to make effective use of the repos.xml template. These steps include:
  1. Copying the file to a custom templates folder and making Deploy aware of that folder (recommended).
  2. For CentOS-based systems:
    1. Modifying the centos-mirror macro definition to point to a local mirror (optional).
  3. For RHEL-based systems:
    1. Creating a rhel-base repository, which includes downloading an ISO image and making the contents available on the local machine or from a network file location (required).
    2. Modifying the rhel-mirror macro definition to point to the location created above (required).
    3. Obtaining an SSL key and SSL certificates for accessing RHEL repositories using the Red Hat Content Delivery Network (CDN), and place these files in the location specified by the template (required).
These steps are discussed in detail in the Deploy User Manual under "Creating a Definition".
The complete text of repos.xml is shown below:
<?xml version="1.0" encoding="utf-8"?>
<repos>

<!-- centos base repos -->
<!-- note: server, workstation and desktop point to the same repo, but we
     include them separately here to make it easier to switch between centos
     and rhel -->
<repo id="centos-server-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- centos update repos -->
<!-- note: server, workstation and desktop point to the same repo, but we
     include them separately here to make it easier to switch between centos
     and rhel -->
<repo id="centos-server-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-updates">
<baseurl>http://mirror.centos.org/centos/%{version}/updates/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- centos-extras -->
<repo id="centos-server-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-workstation-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<repo id="centos-desktop-extras">
<baseurl>http://mirror.centos.org/centos/%{version}/extras/%{arch}</baseurl>
<gpgkey>http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-%{version}</gpgkey>
</repo>

<!-- rhel base repos -->
<repo id="rhel-server-base">
<macro id="rhel-server-mirror">http://mirror.company.com/rhel/enterprise/6Server/en/os/%{arch}</macro>
<baseurl>%{rhel-server-mirror}</baseurl>
<gpgkey>%{rhel-server-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-server-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<repo id="rhel-workstation-base">
<macro id="rhel-workstation-mirror">http://mirror.company.com/rhel/enterprise/6Workstation/en/os/%{arch}</macro>
<baseurl>%{rhel-workstation-mirror}</baseurl>
<gpgkey>%{rhel-workstation-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-workstation-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<repo id="rhel-desktop-base">
<macro id="rhel-desktop-mirror">http://mirror.company.com/rhel/enterprise/6Desktop/en/os/%{arch}</macro>
<baseurl>%{rhel-desktop-mirror}</baseurl>
<gpgkey>%{rhel-desktop-mirror}/RPM-GPG-KEY-redhat-release</gpgkey>
<gpgkey>%{rhel-desktop-mirror}/RPM-GPG-KEY-redhat-beta</gpgkey>
</repo>

<!-- rhel update repos -->
<repo id="rhel-server-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/server/6/6Server/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/server-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/server-6-key.pem</sslclientkey>
</repo>

<repo id="rhel-workstation-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/workstation/6/6Workstation/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/workstation-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/workstation-6-key.pem</sslclientkey>
</repo>

<repo id="rhel-desktop-updates">
<baseurl>https://cdn.redhat.com/content/dist/rhel/client/6/6Client/%{arch}/os</baseurl>
<macro id="rhsm-dir">%{templates-dir}/%{norm-os}/common/rhsm</macro>
<sslcacert>%{rhsm-dir}/redhat-uep.pem</sslcacert>
<sslclientcert>%{rhsm-dir}/desktop-6.pem</sslclientcert>
<sslclientkey>%{rhsm-dir}/desktop-6-key.pem</sslclientkey>
</repo>

<!-- epel repo -->
<repo id='epel'>
<macro id='epel-mirror'>http://dl.fedoraproject.org/pub/epel</macro>
<baseurl>%{epel-mirror}/%{version}/%{arch}</baseurl>
<gpgkey>%{epel-mirror}/RPM-GPG-KEY-EPEL-%{version}</gpgkey>
</repo>

</repos>
3.2.3.1.2.  Example 2 - using repos/repo/include and repos/repo/exclude
In the following example, two repositories are defined directly in XML. The first repository contains includes all packages except those that match the PACKAGE pattern "xorg-x11-drv*" while the second repository only includes packages that match the same pattern.
<repos>
<repo id="centos-server-base">
<baseurl>http://mirror.centos.org/centos/%{version}/os/%{arch}/</baseurl>

<!-- exclude all xorg-x11-drv packages -->
<exclude>xorg-x11-drv*</exclude>
</repo>

<repo id="livna-drivers">
<baseurl>http://rpm.livna.org/repo/%{version}/%{arch}/<baseurl>

<!-- include only xorg-x11-drv packages -->
<includepkg>xorg-x11-drv*</includepkg>
</repo>
</repos>

3.3.  Packages

3.3.1.  Definition

Specifies required packages and groups.

3.3.2.  Syntax

When the value of type is "system", at least one packages/group or packages/package element is required.
<packages>
  [<group [repoid=TEXT]>TEXT</group>]*
  [<package [dir=PATH] [group=GROUP]>PATTERN</package>]*
  [<exclude>PATTERN</exclude>]*
</packages>

3.3.3.  Elements

group
The unique ID of a required group.
This element can occur zero or more times. However, when the value of type is "system", the packages top-level element must have at least one packages/group or packages/package element.
This element accepts one attribute: @repoid.
@repoid: The id of the repository from which to obtain group packages. This id corresponds to a repoid defined in a repo element. If not specified, Deploy obtains all packages from groups with this name across all repos.
package
PATTERN specifying one or more required packages.
For packages specified in the format name-version-release, Deploy will lock the package to the specified version. As a result, if other packages require older or newer versions of the locked package, Deploy will raise an error during dependency resolution. Locks are established in the order specified in the definition. Only the first lock for a package is recognized, all others are silently ignored.
This element can occur zero or more times. However, when the value of type is "system", the packages top-level element must have at least one packages/group or packages/package element.
See Section 7.11, “ Content: PACKAGE for information on package patterns.
The package element accepts two attributes: @dir and @group.
@dir: A directory PATH, local or URL, from which to obtain the specified package. When the @dir attribute is provided, Deploy uses modified behavior for package selection. Specifically, it treats the PATTERN as a regular expression, searching the directory for matching files and selecting the best match using a combination of package name, architecture, and most current epoch, version and revision. In this case, only a single package may be specified.

Note

Packages obtained from a directory, rather than from a package repository, bypass the standard gpgcheck process. In this case, the downloaded packages are treated as other Deploy-created RPM packages, and automatically signed with the gpgsign key.
@group: The TEXT id of a GROUP into which this package will be added. The group will be created if it does not exist.
This @group attribute is optional. The default value is name .
exclude
Package PATTERN to exclude across all repositories. To exclude a package from a specific repository, see the repo/exclude element.
This element can occur zero or more times.
See Section 7.11, “ Content: PACKAGE for information on package patterns.

3.3.4.  Examples

In the example below, the repository that Deploy generates will include packages from several groups as well as a few individual packages. A template will be used to obtain a minimal set of packages, see Section 2.1, “Templates” for additional information on templates. The "base" group of the "%{os}-%{edition}-base" repository will be included. Packages from the remaining groups will be included, irrespective of the repository in which they are defined. Additionally, the "createrepo" package will be included, as will any packages beginning with the text "httpd". Finally, the "system-config-soundcard" package will be excluded from the repository.
<packages>
  <!-- include a minimal set of packages from the packages.xml template -->
  <include href="%{templates-dir}/%{norm-os}/common/packages.xml
           xpath="./packages[@id='core']/*"/>

  <!-- include packages from the base group of the base repo -->
  <group repoid="%{os}-%{edition}-base">base</group>

  <!-- include packages from these groups defined in any repo -->
  <group>base-x</group>
  <group>gnome-desktop</group>
  <group>smb-server</group>
  <group>admin-tools</group>
  <group>web-server</group>

  <!-- include these packages -->
  <package>httpd*</package>
  <package>createrepo</package>

  <!-- exclude system-config-soundcard from the system -->
  <exclude>system-config-soundcard</exclude>
</packages>

Chapter 4.  RPM Elements

4.1.  Gpgsign

4.1.1.  Definition

Specifies GPG keys to use for signing and verifying Deploy created RPM packages. If not provided, Deploy automatically generates signing keys. This element is optional.
See the Deploy User Manual for more information on creating and using signing keys.

4.1.2.  Syntax

[<gpgsign>
  <public>TEXT</public>
  <secret>TEXT</secret>
  [<passphrase>TEXT</passphrase>]
 </gpgsign>]

4.1.3.  Elements

secret
Section 7.13, “ Content: TEXT of a secret key, alternatively referred to as a private key, to use for signing rpm. This element is required.
public
Section 7.13, “ Content: TEXT of a public key to use for verifying the rpmbuild. This key is included in the published repository. This element is required.
passphrase
Section 7.13, “ Content: TEXT of a passphrase associated with the secret key. This element is optional.

4.1.4.  Examples

<gpgsign>
  <secret>
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)

lQG7BE7iLHkRBACbHdCzgO5Jac4LRbQwKoX+1ltYHrvvc/WsnhuPN5HXhvkPTA+/
rbsCxm8oqzP5puu7rimcnZkHN7pN/8uKj5Vd7EbaVNSWUg7rfhDlxg/KxDAnXPuI
JBhER92JfU0y5D1SOb4SmSJ32E79zrDVFt0XFlOP6biwFS/RGHRJxzjGlwCgnOcN
AYveV6pXd8Ec9OX6Lea+46sD/289sU6VeSg9KruXM67LjDei/P8aDAGsABdhq57F
L7eOcWewZ0UZDQh1zSB+r0DoWF6rpj7oQ/yRWoHWXgFfUX8tL5AV7HuNmsxAfvy/
/xBs8YVgBxieeiWrBGxcBQRdXZDSSOz2WYExir5y4/ehn3Upn5WKeUqkP5uAsQkB
XFOyA/wOOd4azDKd0uouLgluJbqYMSlRDoigNbHWVPAM3PvZdusgzP2JO91IxCHD
JeCpZWgfN29g8py66PkXg7EfsisQqVO3/42me96Tqb/77Y8kSbubWQ4uVQd5YB8z
0sGT71S6NrAnhqyqs7toMjUGO5JuMfnP/hgITk967nV5jZowXwAAnA12xL8lKygY
avXfoZC4hAHepi0VCaS0EHRlc3Qgc2lnbmluZyBrZXmIYAQTEQIAIAUCTuIseQIb
IwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEMrm3ScKl1azjX0An1EuUG9eLZtg
A48S6GUbmLRKZ/VrAKCcJ7zn0e1xP0I6qrOiaKAMHYLkep0BMgRO4ix6EAQAr73g
bYWqQA6gYnOoo3EG7dR2+hP/RwMMbm0aY8pdIPLgtWcX3ECidRk/fNwcf6JLz+96
JSjsVdcZ5aU+w1fuhGLnCBlclueZq8SNxz+6NTsdcL4e3z/6ZumH//zixfZRVId4
dP5mM4qgGn9C/1Zt2lrvR5dNiCU6FYnwAhnphO8AAwUEAKL0zEOZPERtZOYwlKkV
dvNBSiJxNuDP++WGzV8HU5Bn6faZdXHjSdb4ZWYNybh52dLsNKd5Wu1lArrdGn8u
7wkUDw+IPBOe73wRczqYon12xD+VR2t+3oWN4aJJ79Dd1D+xI1sVKIn0otVbFfFj
B3CVcSoLuv/6F7B0OhksqUdWAAD5AfL1s+wz653stZOKhxMX1S9gbq4A9nQesx45
o2iyjegR7ohJBBgRAgAJBQJO4ix6AhsMAAoJEMrm3ScKl1azQO4An3vR7ZjQ80tD
MkKc5Q91TmwC5A7jAJ9jvRPHOVwYC+sHFL4mOt/9XVaFdg==
=k9wN
-----END PGP PRIVATE KEY BLOCK-----
  </secret>

  <public>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)

mQGiBE7iLHkRBACbHdCzgO5Jac4LRbQwKoX+1ltYHrvvc/WsnhuPN5HXhvkPTA+/
rbsCxm8oqzP5puu7rimcnZkHN7pN/8uKj5Vd7EbaVNSWUg7rfhDlxg/KxDAnXPuI
JBhER92JfU0y5D1SOb4SmSJ32E79zrDVFt0XFlOP6biwFS/RGHRJxzjGlwCgnOcN
AYveV6pXd8Ec9OX6Lea+46sD/289sU6VeSg9KruXM67LjDei/P8aDAGsABdhq57F
L7eOcWewZ0UZDQh1zSB+r0DoWF6rpj7oQ/yRWoHWXgFfUX8tL5AV7HuNmsxAfvy/
/xBs8YVgBxieeiWrBGxcBQRdXZDSSOz2WYExir5y4/ehn3Upn5WKeUqkP5uAsQkB
XFOyA/wOOd4azDKd0uouLgluJbqYMSlRDoigNbHWVPAM3PvZdusgzP2JO91IxCHD
JeCpZWgfN29g8py66PkXg7EfsisQqVO3/42me96Tqb/77Y8kSbubWQ4uVQd5YB8z
0sGT71S6NrAnhqyqs7toMjUGO5JuMfnP/hgITk967nV5jZowX7QQdGVzdCBzaWdu
aW5nIGtleYhgBBMRAgAgBQJO4ix5AhsjBgsJCAcDAgQVAggDBBYCAwECHgECF4AA
CgkQyubdJwqXVrONfQCfUS5Qb14tm2ADjxLoZRuYtEpn9WsAoJwnvOfR7XE/Qjqq
s6JooAwdguR6uQENBE7iLHoQBACvveBthapADqBic6ijcQbt1Hb6E/9HAwxubRpj
yl0g8uC1ZxfcQKJ1GT983Bx/okvP73olKOxV1xnlpT7DV+6EYucIGVyW55mrxI3H
P7o1Ox1wvh7fP/pm6Yf//OLF9lFUh3h0/mYziqAaf0L/Vm3aWu9Hl02IJToVifAC
GemE7wADBQQAovTMQ5k8RG1k5jCUqRV280FKInE24M/75YbNXwdTkGfp9pl1ceNJ
1vhlZg3JuHnZ0uw0p3la7WUCut0afy7vCRQPD4g8E57vfBFzOpiifXbEP5VHa37e
hY3hoknv0N3UP7EjWxUoifSi1VsV8WMHcJVxKgu6//oXsHQ6GSypR1aISQQYEQIA
CQUCTuIsegIbDAAKCRDK5t0nCpdWs0DuAKCXthQjeX5H4DL9sZUkxk+k4wiHtgCf
TBefZqqYtL+kacCEgCIYH2Fhm0I=
=9xNj
-----END PGP PUBLIC KEY BLOCK-----
  </public>

  <passphrase>my long passphrase</passphrase>
</gpgsign>

4.2.  Config-rpms

4.2.1.  Definition

Creates RPMs used to install and update repository-specific configuration on client machines.
RPMs defined within the config-rpms element have three primary functions.
  • Install user-provided configuration files specified via files elements.
  • Run user-provided scripts specified via script and trigger elements.
  • Place copies of user-provided scripts in a troubleshooting folder on client machines. The name of the folder is /var/lib/deploy/config/RPMID, where RPMID is specified by the @id attribute of the config-rpm. Files in this folder assist with troubleshooting "scriptlet failed" errors during installation and updates of the rpm. Within the troubleshooting folder, scripts are named according to the script type, e.g. post-script. Triggers are similarly named, but they also include the name provided in the @trigger attribute, e.g. triggerin-drupal-script. See the Deploy User Guide for more information on testing and troubleshooting client machine installation and updates.
The file name for a created config-rpm is in the following format, where RPMID is taken from the @id attribute, %{version} is a global run-time macro, RELEASE is computed at run time, and DIST is an identifier for the base operating system distribution (e.g. 'el6'). See the introduction at release-rpm for additional information on release numbers.
RPMID-%{version}-RELEASE.DIST.noarch.rpm
For example, for a config-rpm with the id "samba-server-config", and a base operating system distribution of CentOS 6, the first time the rpm is generated, the file name would be as follows:
samba-server-config-6-1.el6.noarch.rpm

4.2.2.  Syntax

[<config-rpms>
  <config-rpm id=TEXT>*
    [<summary>TEXT</summary>]
    [<description>TEXT</description>]
    [<license>TEXT</license>]

    [<group>GROUP</group>]

    [<repo>...</repo>]*

    [<requires>CAPABILITY</requires>]*
    [<provides>CAPABILITY</provides>]*
    [<obsoletes>CAPABILITY</obsoletes>]*

    [<prep-script [verbose=FALSE]>TEXT</prep-script>]*

    [<files [destdir=PATH] [destname=BASENAME] [mode=MODE]
            [content=("file"|"text")]>
      (PATH|TEXT)
     </files>]*

    [<script type=("post"|"pre"|"preun"|"postun"|"posttrans")>
      TEXT
     </script>]*

    [<trigger trigger=CAPABILITY type=("triggerin"|"triggerun"|"triggerpostun")
             [interpreter=PATH]>
      TEXT
     </trigger>]*
   </config-rpm>
</config-rpms>]

4.2.3. Macros

Deploy provides two module run-time macros to config-rpms: %{rpm-id} and %{install-dir}.
The %{rpm-id} macro contains the value specified by the @id attribute of the config-rpm element.
The %{install-dir} macro specifies the location where variable data for the config-rpm is installed, specifically /var/lib/deploy/config/%{rpm-id}. This can be useful for scripts specified within files , script and trigger elements, as it provides these scripts with a convenient location for storing their own runtime data.
The ssh-config.xml file located within the templates folder shows an example of using the %{install-dir} macro. See Section 2.1, “Templates” for information on templates.
See Section 2.2, “ Macros ” for more information on macros generally.

4.2.4.  Elements

config-rpm
Container element identifying an individual config rpm to be created by Deploy.
Attributes
@id
TEXT value providing an identifier for the config-rpm. Also serves as the name for the config-rpm. Valid characters are a-z, A-Z, 0-9, _ and -. Spaces are not allowed. For clarity, often specified by appending the term "config", as shown in the following example.
Example
<config-rpm id="example-config">

...

</config-rpm>
Elements
summary
TEXT value providing a summary of the config-rpm.
The summary element is optional. The default value is specified by the @id attribute.
description
TEXT value providing a description of the config-rpm.
The description element is optional. The default value is shown below, where FULLNAME is specified by fullname .
 The %{rpm-id} package provides configuration files and scripts for the FULLNAME repository. 
license
TEXT value providing the name of the license for the RPM.
The license element is optional. The default value is "GPLv2".
group
The TEXT id of a GROUP into which this package will be added. The group will be created if it does not exist.
The group element is optional. If multiple elements are provided, the first will be selected. The default value is name .
repo
repo element as described in the Section 3.2, “ Repos ” section of this document. The repos element is supported within config-rpm elements to facilitation creation and distribution of config-rpm templates.
This element can occur zero or more times
requires
CAPABILITY that must be available on client machines prior to installation of the config-rpm. Capabilities are provided by RPM packages. They can be specified as the name of a package, as a file or virtual capability provided by one or more packages, or as an equation specifying a capability and desired version.
For requirements specified in the format 'name = version-release' or 'name == version-release', Deploy will lock the package to the specified version. As a result, if other packages require older or newer versions of the locked package, Deploy will raise an error during dependency resolution. Locks specified in the packages/package element are established ahead of locks specified in config-rpm/requires elements. Only the first lock for a package is recognized, all others are silently ignored.
See Section 7.7, “ Content: CAPABILITY for more information on specifying CAPABILITY values.
The requires element can occur zero or more times
Examples
<requires>java-1.7.0-openjdk</requires>
<requires>java-1.7.0-openjdk = 1:1.7.0.55-2.4.7.1.el6_5</requires>

A note on requiring package versions

To require a specific package version, you must specify the version using and equation, for example:
httpd = 2.2.15-30.el6_5 # works - an equation
httpd-2.2.15-30.el_6    # does not work
If the package is versioned using an epoch, the epoch must also be specified, for example:
java-1.7.0-openjdk = 1:1.7.0.55-2.4.7.1.el6_5 # works - epoch provided
java-1.7.0-openjdk = 1.7.0.55-2.4.7.1.el6_5   # does not work
When in doubt, view the capabilities for the desired package using rpm, as shown below:
rpm -q --provides name_of_installed_package 
rpm -q --provides -p path/to/uninstalled_file.rpm
And choose a value from the resulting list.
provides
CAPABILITY, or "virtual package", provided by the RPM. Useful for specifying a capability provided by this RPM, which may be provided by one or more additional RPMs. For example, multiple RPMs may provide "iptables-configuration" and these RPMs may be required, without knowing the individual RPM names, by specifying a requirement on "iptables-configuration".
Can occur zero or more times.
See Section 7.7, “ Content: CAPABILITY for more information on CAPABILITY values.
obsoletes
CAPABILITY, typically the name of an RPM package, that must be removed from client machines prior to installation of the config-rpm. Useful for removing conflicting or undesirable software from client machines, particularly for machines without the YUM sync plugin. See also the updates element for information on the YUM sync plugin.
Can occur zero or more times.
See Section 7.7, “ Content: CAPABILITY for more information on CAPABILITY values.
prep-script
TEXT of a script that runs prior to assembling RPM files and scripts. Deploy creates and executes the script from the Deploy cache folder on the build machine. Scripts that need to access content relative to the definition file can make use of the %{definition-dir} macro.
Deploy halts processing if a prep-script either returns a non-zero exit status or writes output to the standard error file descriptor.
Can occur zero or more times.
Accepts one attribute: @verbose.
@verbose: BOOLEAN value indicating whether the Standard Output from the script should be displayed as output from Deploy. This attribute is optional. The default value is FALSE. See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
files
Specifies a file or folder containing files to install to client machines. Can occur zero or more times.
If a file with the same name exists on the client machine, the existing file will be renamed with the extension .rpmsave. On subsequent file removal, the previous file will be restored.
Accepts four attributes: @content, @destdir, @destname, and @mode.
@content: Accepts either "file" or "text". When content is "file", the element's text value is treated as a PATH to a file, whereas when it is "text", the element's text value is interpreted as the raw text to use for creating a file with the name specified using the @destname attribute. The default value is "file".
@destdir: Controls the location to which this file or folder should be installed on client machines. The default value is "/". See Section 7.1, “Attribute: destdir” for more information on the destdir attribute.
@destname: If @content is "text", this attribute is required. See Section 7.2, “ Attribute: destname ” for more information on the destname attribute.
@mode: See Section 7.3, “ Attribute: mode ” for information on the mode attribute.
Example
This example installs a file named smb.conf, located in the same folder as the definition on the build machine, in the /etc/samba folder on client machines.
<config-rpm id="samba-config">

...

<files destdir="/etc/samba">smb.conf</files>

</config-rpm>
script
Specifies a script to run during installation or removal of the config-rpm.
Depending on the script type, it can run each time the RPM is installed, uninstalled or updated. For this reason, it should be written to be idempotent, meaning that it can be run multiple times with the same result. See the section on Configuration Packages in the Deploy User Manual for more information on writing idempotent scripts.
To facilitate debugging, Deploy automatically adds the command set -e at the top of each script. This causes the entire script to exit immediately if any internal command exits with a non-zero status. See man set for additional information on the -e option.
Scripts that create and store data during runtime operation may wish to use the %{install-dir} macro.
Can occur zero or more times.
Accepts one attribute, @type.
@type: Specifies the type of RPM script; must be one of "pre", "post", "preun", "postun" or "posttrans". This attribute is required. For more information on defining scripts in RPM spec files, see the Fedora project's "RPM Guide" by Eric Foster-Johnson and the Fedora project's "Packaging:ScriptletSnippets" web page.
For post-type scripts, Deploy provides an additional runtime variable, $changed. This variable can be used to perform conditional actions based on the status of files installed by the config-rpm. The $changed variable contains a string-separated list of files, currently or previously installed by the configuration package, that meet one or more of the following criteria:
  • added since the last configuration package update
  • modified since the last configuration package update
  • differs from the file on disk
  • removed since the last configuration package update
The space-separated list of files within the $changed variable also has leading and following space characters, for easier pattern matching. See the examples section for a script that makes use of the $changed variable.
Example
The example below defines a script that will run after installation of the config-rpm, specifically, after all files defined by files elements above have been installed. The particular function of this script is to restart the samba service (named smb) and configure it to run at system boot.
<config-rpm id="samba-config">

...

<script type="post">
service smb restart
chkconfig smb on
</script>

</config-rpm>
trigger
Specifies a script to run during installation or removal of another package or capability.
Because the script runs each time the trigger event occurs, it should be written to be idempotent, meaning that it can be run multiple times with the same result. See the section on Configuration Packages in the Deploy User Manual for more information on writing idempotent scripts.
As with regular scripts, Deploy adds the set -e command to each trigger script. This is only done, however, for trigger scripts with the @interpreter attribute set to /bin/sh (the default) or /bin/bash. See the script element for additional information.
Triggers that create and store data during runtime operation may wish to use the %{install-dir} macro.
Can occur zero or more times.
Accepts three attributes: @interpreter, @trigger, and @type.
@interpreter: PATH to the executable language interpreter to use when running the trigger script. The default value is /bin/sh. See Section 7.12, “ Content: PATH for additional information on PATH values.
@trigger: CAPABILITY this script triggers on. This attribute is required. See Section 7.7, “ Content: CAPABILITY for additional information on CAPABILITY values. See also the @type attribute.
@type: Specifies the type of trigger script; must be one of "triggerin", "triggerun", or "triggerpostun". This attribute is required. For more information on defining trigger scripts, see the Fedora project's "RPM Guide" by Eric Foster-Johnson. See also the @trigger attribute.
Example
This example below shows defining a script that will run on client machines each time the bugzilla package is installed or updated. This particular script serves to execute a bugzilla-provided script (checksetup.pl) after first ensuring that a required folder exists.
<config-rpm id="bugzilla-config">

...

<trigger type="triggerin" trigger="bugzilla">
if [[ $1 = 1 ]]; then
  # bugzilla-3.2.10 checksetup.pl fails if this directory doesn't
  # exist. It should create it on its own, but since it doesn't, we will.
  if [ ! -e /usr/share/bugzilla/contrib ]; then
    mkdir /usr/share/bugzilla/contrib
  fi
  # run checksetup.pl
  /usr/share/bugzilla/checksetup.pl
fi
</trigger>
</config-rpm>

4.3.  Srpmbuild

4.3.1.  Definition

Builds RPMs starting from user-provided Source RPMs (SRPMs).
Srpmbuild is a meta-module. It reads the srpmbuild element and creates a new srpm module for each encountered srpm element. The new modules are named as follows, where $SRPMID is taken from the @id provided for the SRPM:
 $SRPMID-srpm 
Individual SRPM modules complete a series of tasks aimed at building, verifying and including one or more RPMs, built from the provided SRPM, in the repository. Those tasks include the following:
  • Obtain the SRPM from a path, repo or script.
  • Create a new instance of Deploy to perform the SRPM build process. This instance is created using a definition template, which can be either the default template provided by Deploy, or a user-provided template specified using the template element. Deploy modifies the template at run time to include repository and SRPM-specific information. See template for more information.
  • Verify the RPMs provided by the external Deploy instance.
  • Include the provided RPMs in the current repository.

4.3.2.  Syntax

[<srpmbuild>
  <srpm id=TEXT>*
    (<path>URL</path> | 
     <repo>PATH</repo> | 
     <script>TEXT</script>)
    [<group>GROUP</group>]
    [<exclude>PACKAGE</exclude>*]
    [<template>PATH</template>]
  </srpm>
  [<template>TEXT</template>]
</srpmbuild>]

4.3.3.  Elements

srpm
A container element specifying information needed to build RPMs starting from a user-provided SRPM.
At least one srpm element is required.
Attributes
id
TEXT value providing an identifier for the SRPM. Valid characters are a-z, A-Z, 0-9, _ and -. Spaces are not allowed.
The @id attribute is required.
Elements
path
PATH value specifying a location for the SRPM. If the specified path ends with ".src.rpm", Deploy attempts to download the SRPM from the location specified. Otherwise, Deploy attempts to find an SRPM beginning with the name specified in the @id attribute in the folder specified. If multiple SRPMs are found, Deploy selects the SRPM with the highest version and release number.
This element is optional; however, one of repo, path or script elements must be provided.
The example below shows specifying an SRPM by providing the full path to the desired file. Line breaks have been added to the path element for improved readability. In a real definition, line breaks are not allowed within PATH content.
<srpm id="rhnlib">
<path>
http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/rhnlib-2.5.22-10.el6.src.rpm
</path>
<srpm>
See Section 7.12, “ Content: PATH for information on PATH values.
repo
URL value specifying a package repository where the SRPM specified using the @id attribute can be located.
This element is optional; however, one of repo, path or script elements must be provided.
The example below shows specifying the URL to an RPM package repository where the SRPM can be located.
<srpm id="rhn-client-tools">
<repo>
http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS
</repo>
<srpm>
See Section 7.14, “ Content: URL for information on URL values.
script
TEXT value providing a script to be executed on the local machine that performs desired actions, and ultimately copies an SRPM to the %{srpm-dir} location. Deploy saves the provided script in the cache folder and executes it with root user permissions. See the Deploy User Manual or the deploy.conf man page for information on the cache folder.
Provides three run-time macros: srpm-id, srpm-dir and srpm-last.
%{srpm-id}: The name of the SRPM as specified by the @id attribute.
%{srpm-dir}: The path to a folder where the script should copy an SRPM upon completion. Note that Deploy allows only a single SRPM file to exist in the srpm-dir. Scripts are responsible for removing any files, e.g. a file cached from a previous build, prior to copying a new SRPM file.
%{srpm-last}: The full path to the last SRPM provided by the script or 'None' if no SRPM was previously provided. Allows scripts to optimize performance by determining whether a new SRPM must be provided.
In addition, scripts can make use of the %{definition-dir} global run-time macro. This macro allows the script, which is saved and executed from the cache folder, to access external content from a relative location.
See Section 2.2, “ Macros ” for more information on macros.
This element is optional; however, one of repo, path or script elements must be provided.
In the example below, the TEXT of a script is provided to perform custom actions, and ultimately copy an SRPM to the location identified by the srpm-dir macro. The script shown below makes a call to a custom external program (fetch.py) providing command line parameters that that the program will use to process and copy the SRPM to the location identified by %{srpm-dir}.
<srpm id="my-package">
<script>
#!/bin/bash
fetch.py %{srpm-id} https://www.deployproject.org/git/public/%{srpm-id} %{srpm-dir} %{srpm-last}
</script>
<srpm>
group
The TEXT id of a GROUP into which packages built by this SRPM will be added. The group will be created if it does not exist.
The group element is optional. If multiple elements are provided, the first will be selected. The default value is name .
exclude
The name of a package provided by the SRPM to exclude from the repository.
This element can occur zero or more times.
The %{exclude-rpms} run-time macro provides a space-separated list of excluded packages.
The example below shows excluding several packages, also known as subpackages, of the rhn-client-tools SRPM.
<srpm id="rhn-client-tools">
<repo>
http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS
</repo>
<exclude>rhnsd</exclude>
<exclude>yum-rhn-plugin</exclude>
<exclude>rhn-setup-gnome</exclude>
<exclude>rhn-setup</exclude>
<exclude>rhn-check</exclude>
<srpm>
template
See the template element below.
template
PATH to a definition template to be used for creating the SRPM build machine and building RPMs.
When used within the srpm element, indicates a template to be used for the given SRPM. When used within the srpmbuild element, indicates a global template to be used across all SRPMS.
The template element is optional. By default, Deploy looks for a template at the location %{templates-dir}/%{norm-os}/common/srpmbuild.xml. See Section 2.1, “Templates” for additional information on templates.
Users can override the default using the template element.
See Section 7.12, “ Content: PATH for additional information on the PATH value.

Note

User-provided srpmbuild templates should provide a unique value for the /main/name element of each template. This results in additional srpmbuild machines (one per template); preventing a single srpmbuild machine from being reinstalled each time an srpm changes.
The default template describes one possible implementation for an SRPM build machine. Using this template, Deploy creates virtual SRPM build machines on the local system. In most cases the default template is sufficient. Users wishing to customize the default template should create a new file and include desired segments of the default template using include elements. See the examples section below for more information.
The template is a complete definition specifying input repositories, packages, config-rpms and deployment scripts needed to create the SRPM build machine and build RPMs.
Deploy modifies the template at run time in the following ways:
  • Adds a config-rpms/rpm element with the name %{id}-$SRPMID-config. This rpm installs the user-provided SRPM on the SRPM build machine. It also ensures that all RPMs required to build the SRPM are installed on the build machine.
  • Adds/replaces repos/repo elements in the template with repos specified in the parent definition.
  • Adds a gpgsign element containing gpgsign keys specified in the parent definition, if any.
  • Resolves the following run-time macros:
    %{build-dir}: The path to the default rpmbuild folder on the SRPM build machine. The summary below shows build-dir values by the operating system version of the SRPM build machine.
    Version 5: /usr/src/redhat
    Version 6: /root/rpmbuild
    %{rpms-dir}: The path to a folder on the Deploy build machine where built RPMs should be copied. This path takes the following form, where $SRPMID is the value of the @id attribute for the srpm element.
    /var/cache/deploy/%{type}s/%{id}/$SRPMID-srpm/rpms
    %{spec}: The full path to the SRPM spec file on the SRPM build machine. This path takes the following form, where $SPECFILE is the Section 7.5, “ Content: BASENAME of the spec file as determined by reading information available within the provided SRPM.
    /%{build-dir}/SPECS/$SPECFILE
    %{srpm}: The full path to the SRPM file on the SRPM build machine. This path takes the following form, where $SRPMFILE is the Section 7.5, “ Content: BASENAME of the provided SRPM.
    %{build-dir}/SPECS/$SRPMFILE
See Section 2.2, “ Macros ” for more information on macros.

4.3.3.1. Examples

4.3.3.1.1. Example 1 - Specifying a custom template
This example shows specifying a custom template. Because the template element is used within an srpm element, the template will be used only for this SRPM.
<srpm id="my-package">
<template>srpmbuild-custom.xml</template>
...
</srpm>
4.3.3.1.2. Example 2 - Creating a custom template
This example shows creating a custom template, using include elements to reuse portions of the default template (shown below). On a system with Deploy installed, this file can be found at /usr/share/deploy/templates/%{norm-os}/common/srpmbuild-custom.xml.
See Section 2.3, “ Include Elements ” for more information on include elements.
srpmbuild-custom.xml
<?xml version="1.0" encoding="utf-8"?>
<definition schema-version="1.0">

<macro id="name">srpmbuild-custom</macro>
<macro id="fullname">Custom RPM Build Virtual Machine</macro>

<include href="srpmbuild.xml"
         xpath="./*[name()!='publish']"/>

<publish>
<script id='update' type='update'>
#!/bin/bash
# the docbook-style-xsl rpm has faulty post scripts; ignore errors on install 
warning=`yum sync -y -q`
if [[ $? != 0 ]] &amp;&amp; [[ ! `echo $warning | grep docbook-style-xsl` ]]; then
  echo 'yum update failed' >&amp;2
  exit 1
fi
</script>

<script id='remove-docbook-style-xsl' type='update' comes-after='copy'>
#!/bin/bash
# the docbook-style-xsl rpm has faulty postun scripts; force removal
if rpm -q docbook-style-xsl; then
  rpm -e docbook-style-xsl --noscripts --nodeps 
fi
</script>
<include href="srpmbuild.xml"
         xpath="./publish/*[name()!='script']"/>
<include href="srpmbuild.xml"
         xpath="./publish/script[@id!='update']"/>
</publish>
</definition>
4.3.3.1.3. Example 3 - Default srpmbuild.xml
The section below shows the complete default srpmbuild.xml as a reference. On a system with Deploy installed, this file can be found at /usr/share/deploy/templates/%{norm-os}/common/srpmbuild.xml.
srpmbuild.xml
<?xml version="1.0" encoding="utf-8"?>
<definition schema-version="1.0">

<macro id="name">srpmbuild</macro>
<macro id="fullname">RPM Build Virtual Machine</macro>
<macro id="os">centos</macro>
<macro id="edition">server</macro>
<macro id="version">6</macro>
<macro id="arch">x86_64</macro>
<macro id="id">%{name}-%{os}-%{version}-%{arch}</macro>

<main>
<name>%{name}</name>
<fullname>%{fullname}</fullname>
<os>%{os}</os>
<version>%{version}</version>
<arch>%{arch}</arch>
<id>%{id}</id>
</main>

<repos>
<include href="%{templates-dir}/%{norm-os}/common/repos.xml"
         xpath="./repo[@id='%{os}-%{edition}-base' or 
                       @id='%{os}-%{edition}-updates']"/>
</repos>

<packages>
<include href="%{templates-dir}/%{norm-os}/common/packages.xml"
         xpath="./packages[@id='core']/*"/>
<package>bash</package>
<package>bzip2</package>
<package>coreutils</package>
<package>cpio</package>
<package>diffutils</package>
<package>findutils</package>
<package>gawk</package>
<package>gcc</package>
<package>gcc-c++</package>
<package>grep</package>
<package>gzip</package>
<package>info</package>
<package>make</package>
<package>patch</package>
<package>rpm-build</package>
<package>rpmlint</package>
<package>sed</package>
<package>shadow-utils</package>
<package>tar</package>
<package>unzip</package>
<package>which</package>
<package>xz</package>
</packages>

<publish>
<kickstart>
skipx
<include href='%{templates-dir}/%{norm-os}/common/ks.xml' xpath="./node()"/>
</kickstart>

<triggers>
kickstart install_scripts post_install_scripts
</triggers>

<script id='rpmbuild' type='update' comes-after='update'>
#!/bin/bash
### build and verify rpm packages ###

# install packages required to build the rpm
yum sync -y -q || (echo 'yum sync failed' >&amp;2; exit 1)

# start clean
(set -e
 for d in BUILD SRPMS SPECS SOURCES RPMS; do 
   rm -rf %{build-dir}/$d
   mkdir %{build-dir}/$d
 done)
if [[ $? != 0 ]]; then echo 'setup failed' >&amp;2; exit 1 ; fi

# install srpm
rpm --quiet -Uvh --nodeps %{srpm} 2>&amp;1
if [[ $? != 0 ]]; then echo 'srpm install failed: %{srpm}' >&amp;2; exit 1 ; fi

# rebuild srpm
rpmbuild --quiet -bs --target %{arch} --define='dist el%{version}' %{spec} 2>&amp;1 
if [[ $? != 0 ]]; then echo 'srpm build failed: %{spec}' >&amp;2; exit 1; fi

# build rpm
rpmbuild --quiet -ba --target %{arch} --define='dist .el%{version}' %{spec} 2>&amp;1
if [[ $? != 0 ]]; then echo 'rpm build failed: %{spec}' >&amp;2; exit 1; fi

# validate rpm
for f in `find %{build-dir}/RPMS -type f -name "*.rpm"`; do 
  rpmlint $f 2>&amp;1
  if [[ $? == 66 ]]; then 
    echo 'rpmlint badness threshold exceeded: $f' >&amp;2; exit 1; 
  fi
done
</script>

<script id="copy" type='update' hostname="localhost" comes-after='rpmbuild'>
#!/bin/sh
set -e

opts="
-o BatchMode=yes
-o UserKnownHostsFile=%{ssh-host-key-file}
"

rpms=$(ssh %{ssh-host} $opts find %{build-dir}/RPMS -name "*.rpm")

for rpm in $rpms; do
  copy=true
  for exclude in %{exclude-rpms}; do 
    if [[ $(echo $(basename $rpm) | sed 's/-[^-]*-[^-]*$//') == $exclude ]] 
    then
      copy=false
      break
    fi
  done
  if [[ $copy == true ]]; then
    echo "get $rpm %{rpms-dir}" | sftp -b - $opts %{ssh-host}
  fi
done
</script>

<include href='%{templates-dir}/%{norm-os}/libvirt/delete.xml'/>

<macro id='file-size'>10</macro>
<include href="%{templates-dir}/%{norm-os}/libvirt/deploy.xml" 
         xpath="./*[name()!='kickstart']"/>
</publish>

</definition>

Chapter 5.  Deployment Elements

Deployment elements, test-install, test-update, publish, support repository testing, deployment and maintenance. These elements follow a common model. The model is described first in Section 5.1, “ Common Model ”. Differences from the model are described in the section for each element.

5.1.  Common Model

5.1.1.  Definition

Deployment elements - test-install, test-update and publish - provide settings to complete the following tasks:
  • Publish a repository to a file system location on the build machine.
  • Assemble files and information related to installing and updating client machines using that repository.
  • Optionally, execute user-provided scripts to perform testing, installation, updates, notification and other deployment-related tasks.

5.1.2.  Syntax

[<ELEMENT>
  [<build-host [fqdn=BOOLEAN] [interface=TEXT]>[TEXT]</build-host>]
  [<local-dir>PATH</local-dir>]
  [<remote-url [https=BOOLEAN] >[TEXT]</remote-url>]

  [<hostname>TEXT</hostname>]
  [<domain>TEXT</domain>]
  [<password>TEXT</password>]
  
  [<boot-options>TEXT</boot-options>]
  [<kickstart>TEXT</kickstart>]
  [<config-rpm.../>]*

  [<group.../>]*
  [<package.../>]*
  [<exclude.../>]*

  [<release-rpm>
    [<group>GROUP</group>]
    [<updates [sync=BOOLEAN] [gpgcheck=BOOLEAN] [sslverify=BOOLEAN] />]
  </release-rpm>]

  [<triggers [exists=BOOLEAN] [activate=BOOLEAN]>[TEXT]</triggers>]

  [<script 
    id=TEXT 
    type=[pre|test-exists|activate|test-triggers|delete|pre-install|install|post-install|save-triggers|update|post]
    [comes-before=TEXT]
    [comes-after=TEXT]
    [hostname=TEXT]
    [known-hosts-file=PATH]
    [modules=TEXT]
    [verbose=BOOLEAN]
    >TEXT
  </script>]*

  [<input-script>TEXT</input-script>]*

<ELEMENT/>]

5.1.3.  Macros

Deployment elements provide the following module macros.
Install Macros - typically used within installation-related elements such as kickstart , and install and delete scripts.
%{build-host} Hostname or IP Address for the build host. Described under the build-host element.
%{build-host-pubkey} TEXT of the ssh public key for the build host. Used for configuring the client machine to accept ssh connections from the build host. See the kickstart element for an example.
%{webroot} URL to the repository on the build host. Described under the remote-url element.
%{localroot} Local PATH to the repository on the build host. Described under the local-dir element.
%{hostname} Host name for a client machine. Takes its value from the hostname element.
%{domain} Domain name for a client machine. Taken from the domain element. Resolves to an empty string if no domain is provided.
%{fqdn}
Fully Qualified Domain Name (FQDN) for a client machine. Determined by concatenating the values of the hostname and domain macros.
%{password} Password for the root user of a client machine, described under the password element.
%{crypt-password} Encrypted version of the %{password} macro. See the password element for additional information.
%{boot-options} Options to be provided to the installer during system boot. Corresponds to the value of the boot-options element.
%{script-id}
Value of the @id attribute for the current script element. See the @id attribute of the script element for more information.
%{ssh-host}
Hostname or ipaddress used for establishing an SSH connection to the client machine prior to executing scripts where the @hostname attribute is set to %{ssh-host}, i.e. post-install, save-trigger, and post scripts.
The default value is %{fqdn}. Scripts can override the default value by creating a file in the location specified by %{ssh-host-file}. The file should contain a single value specifying the desired hostname or ipaddress.
See the @hostname attribute of the script element for more information.
%{ssh-host-file}
PATH to a file in the data folder where Deploy reads the hostname for establishing SSH connections to the client machine.
The value of this macro is as follows:
%{data-dir}/ssh-host-%{module}
See the %{ssh-host} macro for additional information. See also the sections on data files and macros.
%{ssh-host-key-file}
PATH to a file in the data folder where Deploy stores the SSH public key for the client machine. Deploy automatically creates and updates this file following client system installations.
The value of this macro is as follows:
%{data-dir}/ssh-host-key-%{module}
Scripts can use this file to verify the client when communicating directly via SSH. Search "UserKnownHostsFile" in this document to see several examples.
See the @known-hosts-file attribute of the script element for more information. See also the sections on data files and macros.
%{custom-pkgs} Space separated list of names for packages created during the build process using config-rpm or srpm elements. Typically used for performing package testing. See the test-remove-custom-pkgs.xml template for an example.
%{config-dir} Folder location where config-rpm data and scripts are stored on client systems, specifically /var/lib/deploy/config. Used by update scripts for providing informative messages for config-rpm scriptlet failed errors.
%{script-data-dir} Folder location for use by deployment scripts to store and share local runtime data, specifically /var/lib/deploy/scripts/%{id}/data.
Trigger Macros - used within save-triggers and test-triggers scripts. See also the triggers element.
%{trigger-file} PATH to a file on client machines where trigger values are stored.
%{triggers} List of triggers to be evaluated in determining whether Deploy should execute installation-related deployment scripts. Takes its value from the triggers element.
%{release_pkg_csum} MD5 hash of release number for release-rpm. See release-rpm for information on the release-rpm.
%{custom_pkgs_csum} MD5 hash of release numbers for all custom rpms including config-rpm and srpm packages.
%{kickstart_csum} MD5 hash of current kickstart file.
%{treeinfo_csum} MD5 hash of the treeinfo file for the base operating system repository.
%{install_scripts_csum} MD5 hash of all current install scripts.
%{post_install_scripts_csum} MD5 hash of all current post-install scripts.
See Section 2.2, “ Macros ” for more information on macros.

5.1.4.  Elements

build-host
Hostname or ipaddress of the build machine. Used in calculating a remote-url for accessing repository content.
This element is optional. The default value is computed using the values of the @interface and @fqdn attributes.
This element accepts two attributes: @interface and @fqdn.
@interface: TEXT value specifying the network interface name, e.g. "eth1", from which to obtain the %{build-host} of the repository. This attribute only has an effect if @fqdn is FALSE.
This attribute is optional. By default, Deploy uses the first active, non-loopback network interface.
@fqdn: BOOLEAN value that determines whether Deploy uses the build machine's fully qualified domain name or IP address in the automatically-computed remote-url.
This attribute is optional. The default value is FALSE.
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
Examples
In the following examples, the build machine's fully qualified domain name is buildserver.company.com and the IP addresses of "eth0" and "eth1" are 10.10.1.105 and 192.168.0.10, respectively.
Example 1 - no build-host element specified. If no build-host element is specified, the value is automatically computed using the IP address of the first active network interface ("eth0"). The resulting value is -
10.10.1.105
Example 2 - automatic build-host computation using FQDN. In this example, the build-host is automatically computed using the FQDN of the build machine.
<build-host fqdn="true" />
The resulting value is -
buildserver.company.com
Example 3 - automatic build-host computation using a specific interface. In this example, the build-host is automatically computed using the IP address of the specified interface, "eth1".
<build-host interface="eth1"/>
The resulting value is -
192.168.0.10
Example 4 - manual configuration of build-host. In some cases, it is desirable to specify build-host information manually. For example, the build host may be accessible on both local and public networks, but under different names. To use the public network name, you must specify it manually.
As another example, the repository may be created on the build machine, but later moved to a web server, or web server farm, for final publication. In this case, the remote-url must be manually specified.
<build-host>repos.company.com</build-host>
local-dir
PATH to a folder where Deploy will publish content. For content to be accessible on the web, the directory must be in the build machine’s local webroot, e.g. the Apache DocumentRoot.
To prevent tampering with repository content, you should ensure that only trusted users and groups have write access to the local-dir folder.
This element is optional. The default values are as follows, where %{type} is the value of the type element:
Module Default Value
publish /var/www/html/deploy/%{type}s
test-install /var/www/html/deploy/%{type}s/test-install
test-update /var/www/html/deploy/%{type}s/test-update
See Section 7.12, “ Content: PATH for information on the PATH element.
The local-dir is also used in determining the value of the %{localroot} module macro. The %{localroot} macro provides the complete local path to the repository, as follows, where $local-dir is the value from the table above:
$local-dir/%{id}
The %{localroot} macro is commonly used in script elements for copying repository content, e.g. current yum configuration files, to client machines. See update scripts for an example.
Example
<local-dir>/my/web/root/deploy/systems/</local-dir>
remote-url
URL to a directory from which client machines can access repository content.
Remote-url is an optional element. If multiple elements are specified, the first is selected. The default values are listed in the following table, where %{build-host} is taken from the value of the build-host element and %{type} is the value of type .
See Section 7.14, “ Content: URL for information on URL values.
Module Default Value
publish http://%{build-host}/deploy/%{type}s
test-install http://%{build-host}/deploy/%{type}s/test-install
test-update http://%{build-host}/deploy/%{type}s/test-update
The remote-url is also used in determining the value of the %{webroot} module macro. The %{webroot} macro provides the complete web path to the repository, as follows, where $remote-url is the value from the table above:
$remote-url/%{id}
The %{webroot} macro is commonly used in script elements. See install scripts for an example.
This element is optional.
Attributes
@https: BOOLEAN value specifying whether the value "https" should be used in the network protocol portion of the remote url, rather than the default value "http". See also the @sslverify attribute of the release-rpm/updates element.
This attribute is optional. The default value is FALSE. The attribute is ignored if a TEXT value is provided in the content of the remote-url element.
Examples
<remote-url https='true'/>
<remote-url>http://%{build-host}/my/custom/path</remote-url>
hostname
TEXT value providing the name of a host, e.g. samba-server. Allowed characters include a-z, 0-9 and '-'. This value is provided as the module macro %{hostname}.
This element is optional. The default values are shown in the table below, where ID is the value of the %{id} macro, with underscores ('_') automatically converted to hyphens ('_') and uppercase characters converted to lowercase, e.g. 'MyServer-centos-6-x86_64' is converted to 'myserver-centos-6-x86-64':
Module Default Value
publish ID
test-install ID-test-install
test-update ID-test-update
domain
TEXT value providing the domain for a client machine, e.g. local or company.com. This value is provided as the module macro %{domain}.
Domain is an optional element. If multiple elements are specified, the first is selected. The default value is an empty string. A period character "." is prefixed to the provided text if it does not exist, e.g. local is converted to .local.
password
TEXT value to be used as the root user password for the client machine. This value is provided as a module macro %{password}.
This element is optional. If not provided, a random password is automatically generated. The generated password is between 8 and 14 characters and contains at least one each of a lowercase character, an uppercase character and a digit. The generated password is stored in the data file. See Section 1.3, “ Data Files ” for information on the data file.
Deploy also generates an encrypted version of the password and makes it available as the module macro %{crypt-password}. The encrypted password is recommended for use in the kickstart element. See the kickstart element below for an example. The encrypted password is also stored in the data file.
boot-options
TEXT value specifying install boot environment variables, also known as kernel boot arguments, for use during client machine installation. Ignored if the type element is set to package.
Boot options are typically used in combination with a kickstart file to automate client machine installations. See the kickstart element below for more information.
The boot-options element's text value should be a space-separated list of kernel arguments. For more information on available boot options, see the chapter on Boot Options in the Red Hat Enterprise Linux Installation Guide
Provided as a module macro, %{boot-options}, for use within deployment element content, primarily install scripts. See the script element below for more information.
Also used by Deploy during the creation of installation images including boot.iso and images created by the ISO module. See Section 6.2, “ ISO ” for more information on the ISO module.
Boot-options is an optional element. The default value is "lang=en_US keymap=us".
     
<boot-options>lang=el_GR keymap=gr ksdevice=eth0</boot-options>
kickstart
TEXT of a kickstart file. Ignored if the type element is set to package.
A kickstart file allows automating system installation by providing answers to install-time questions such as selection of language, network configuration, keyboard, file system configuration, mouse, timezone and root password.
Deploy makes the kickstart available as a file named ks.cfg in the repository publish folder, e.g. http://server.company.com/deploy/systems/samba-server-6-i386/ks.cfg. It also includes the kickstart in all ISO images including boot.iso.
Complete information on creating kickstart files is available from the Red Hat Enterprise Linux Installation Guide, available from the Red Hat website. See the chapter on Kickstart Installations. Several items of relevance when using kickstart files with Deploy are noted below.
%packages section - Install all packages from the repository as shown below:
%packages --nobase
*
%end
firewall option and %post sections - Where possible, avoid using the firewall and %post kickstart options. They provide configuration that is applied only during client installation. Instead, use config-rpms to apply client configuration. This ensures uniform results whether the client is installed from scratch, or merely updated. See the httpd-config.xml template for an example of firewall configuration using a config-rpm.
Kickstart is an optional element. If multiple elements are specified, the first is selected. If not provided, users will be prompted for information at the time of client installation.
Example 1 - The following example shows a file named ks.xml which is included in the templates folder. The template provides a kickstart file with information required to fully automate client installation. It uses %{fqdn} and %{crypt-password} module macros.
<?xml version="1.0" encoding="utf-8"?>
<kickstart>
<macro id='timezone'>America/Vancouver</macro>
<macro id='kickstart-text'>text</macro>
install
%{kickstart-text}
network --device=link --bootproto=dhcp --hostname %{hostname} --activate
rootpw --iscrypted "%{crypt-password}"
lang en_US
keyboard us
zerombr
bootloader --location=mbr
clearpart --all --initlabel
part / --fstype ext4 --size 1 --grow --asprimary
part swap --recommended
part /boot --fstype ext3 --size 512 --asprimary
timezone --utc %{timezone}
auth --enablemd5 --enableshadow --enablecache
selinux --enforcing
reboot

%packages --nobase
@core
%end
</kickstart>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/ks.xml"/>
Example 2 - This example shows a file named ks-post-ssh.xml which is included in the templates folder. The template uses a kickstart post script to configure the client to accept ssh connections from the build host. It uses the %{build-host-pubkey} macro described under module macros.
<?xml version="1.0" encoding="utf-8"?>
<xml>
%post
# allow build machine to access client via ssh
# set some convenience variables
sshdir=/root/.ssh
authkeys=$sshdir/authorized_keys
pubkey="%{build-host-pubkey}"

# make sshdir if it doesn't exist
[[ -d $sshdir ]] || mkdir $sshdir 

# create authorized_keys file if it doesn't exist
[[ -f $authkeys ]] || touch $authkeys

# copy pubkey into authorized keys if it's not there already
[[ `cat $authkeys` == $pubkey ]] || echo $pubkey >> $authkeys
  
# set permissions
chmod 700 $sshdir
chmod 600 $authkeys
[[ -f /sbin/restorecon ]] &amp;&amp; /sbin/restorecon -r $sshdir
%end
</xml>

The template can be included in a kickstart element as shown below:
<kickstart>
<include href="%{templates-dir}/%{norm-os}/common/ks.xml"
         xpath="./node()"/>
<include href="%{templates-dir}/%{norm-os}/libvirt/ks-post-ssh.xml"/>
         xpath="./node()"/>
</kickstart>
group
group element as described in Section 3.3, “ Packages ”.
package
package element as described in Section 3.3, “ Packages ”.
exclude
exclude element as described in Section 3.3, “ Packages ”.
config-rpm
This element is optional. Multiple elements are allowed.
Examples
Example 1 - The following example shows the text of a config-rpm template. The template defines an RPM with the id deploy-ssh-config. The RPM provides client configuration needed for the build machine to establish SSH connections with the client and execute deployment scripts. See the @hostname attribute of the script element for additional information.
On a system with Deploy installed, this config-rpm template can be found as a file named ssh-config.xml in the examples folder at /usr/share/deploy/templates/el6/common.
<?xml version="1.0" encoding="utf-8"?>
<config-rpm id='deploy-ssh-config'>

<!-- include in core group -->
<group>core</group>

<requires>openssh</requires>
<requires>openssh-clients</requires>
<requires>/usr/sbin/sshd</requires>

<files destname='build-host-pubkey' content='text'>%{build-host-pubkey}</files>
<files mode='750'>%{templates-dir}/%{norm-os}/common/ssh-install-pubkey.sh</files>

<script type='post'>
%{install-dir}/files/ssh-install-pubkey.sh \
    %{install-dir}/files/build-host-pubkey \
    /root/.ssh/authorized_keys
</script>
</config-rpm>
Example 2 - The example below shows including content from the ssh-config.xml template, shown above, within a definition.
<include href="%{templates-dir}/%{norm-os}/common/ssh-config.xml"/>
release-rpm
Creates an RPM used to install and update repository-specific YUM configuration on client machines. Also makes a YUM configuration file available for download directly from the repository publish folder.
  • The RPM created by the release-rpm event is named as follows, where %{name} is a the value of the name element:
    %{name}-release
    See the name element for information on %{name}.
    The file name of the release-rpm is in the following format, where %{name} and %{version} are taken from the corresponding name and version elements, RELEASE is taken from the data file (see Section 1.3, “ Data Files ”), and DIST is an identifier for the base operating system distribution.
     %{name}-release-%{version}-RELEASE.DIST.noarch.rpm
    For example, given a repository with the name "samba-server" and version "5", the first time Deploy creates the repository, the release-rpm will have the following file name:
     samba-server-release-6-1.el6.noarch.rpm
    The release number "1" will be written to the data file. When configuration changes in the future, e.g. when the sync is enabled or disabled, Deploy will increment the release number by 1, create a new release-rpm (in this case "samba-server-release-6-2.noarch.rpm"), and store the new release number ("2") in the data file. The incremented version number allows installed client machines to determine that a new release-rpm is available for download and installation.
  • The release-rpm event also makes a YUM repository configuration file, named repo.conf, available from the repository publish folder, e.g. http://server.company.com/deploy/systems/samba-server-6-i386/repo.conf. This file can be used by automated processes in situations where it is undesirable to install the release-rpm. This is most common when using YUM to install repository packages in a chroot environment, such as when creating system images.
group
The TEXT id of a GROUP into which the release-rpm will be added. The group will be created if it does not exist.
The group element is optional. If multiple elements are provided, the first will be selected. The default value is name .

Note

Because the release-rpm is required by a number of packages in the 'core' group, it will typically be installed during initial system build, even if it is assigned to a group other than 'core'.
updates
Controls inclusion of the YUM sync plugin; also controls whether gpgcheck is performed.
Attributes
@sync: BOOLEAN value indicating whether to include the Deploy-provided YUM sync plugin in the config RPM. The sync plugin overrides YUM's default behavior 1) to disable all repositories other than the system repository and 2) to provide a sync argument that allows adding and removing installed packages on client machines in alignment with available packages in the system repository. When the value of type is "system", the default value is TRUE. When the value of type is "package", the sync attribute is ignored.
@gpgcheck: BOOLEAN value indicating whether packages should be checked for valid GPG signatures. This value controls whether Deploy performs gpgcheck when creating the repository. It also controls whether YUM checks packages from the repository prior to performing client machine updates. The default value is TRUE.
@sslverify: BOOLEAN value controlling whether YUM should verify the SSL certificate of the build host. Useful for allowing YUM to access the repository when the build host is using a self-signed SSL certificate. See remote-url for information on specifying https access to the repository. The default value is None, meaning that the value defined in yum.conf is used (by default True).
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
Release-rpm is an optional element. If multiple elements are specified, the first is selected.
Examples
<publish>
<release-rpm>

  <!-- exclude the yum sync plugin and disable gpgcheck-->
  <updates sync="false" gpgcheck="false"/>

</release-rpm>
</publish>
triggers
Controls execution of installation-related scripts including delete , install , post-install and save-triggers. Applies to test-update and publish elements only. Silently ignored for test-install; see Section 5.2, “ Test-install ” for additional information.
For publish and test-update events, Deploy executes installation-related scripts ( delete , install , post-install and save-triggers) only when one of the following conditions is True.
  1. The value of the triggers/@exists attribute is True (default) and a test-exists script returns exit code 3.
  2. The value of the triggers/@activate attribute is True (non-default) and an activate script returns exit code 3.
  3. A test-triggers script returns exit code 3. Test-triggers scripts make use of the macros described under Trigger Macros in Section 5.1.3, “ Macros ”. See test-triggers for an example. The TEXT value of the triggers element provides a space-separated list of trigger names. These are made available to test-triggers scripts via the %{triggers} module macro. The default TEXT value is an empty string, "".
Deploy gives special meaning to the exit code 3 in these scripts. It interprets this code as 'reinstall required'. Using a special code allows script authors to distinguish between intentional and unexpected script errors, thus avoiding unwanted system reinstallation.
This element is optional.
Attributes
@exists
BOOLEAN value indicating whether Deploy should execute install-related scripts if a test-exists script returns exit code 3.
This is an optional attribute. The default value is TRUE.
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
@activate
BOOLEAN value indicating whether Deploy should execute install-related scripts if an activate script returns exit code 3.
This is an optional attribute. The default value is FALSE.
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
script
TEXT of a script used to perform installation and maintenance tasks on a client machine.
Deploy reads the script from the script element and resolves macros and include elements. It then writes the script to the file /var/lib/deploy/scripts/%{id}/%{script-id} on the target host. Finally, it executes the script on the target host with root privileges. See the @hostname attribute for additional information on target hosts and script execution.
Deploy halts processing if a script either returns a non-zero exit code or writes output to the standard error file descriptor. In the latter case, this is done to assist script authors with error handling and debugging. In certain cases, Deploy gives special meaning to exit code 3. See the triggers element for additional information.
Deployment scripts can be written in any shell scripting language.
This element is optional. Multiple elements are allowed.
The script element allows six attributes: @id, @type, @hostname, @verbose, @comes-before and @comes-after.
Attributes
@id
TEXT value serving as an identifier for the script. Corresponds to the %{script-id} module macro.
This attribute is required.
@type
pre
Pre scripts are executed first. They perform tasks that are required prior to running other scripts.
Example - This example shows a file named create-guestname.xml which is included in the template folder at /usr/share/deploy/templates/el6/libvirt. See Section 2.1, “Templates” for more information on templates.
The template contains the text of a shell script that creates and saves guestnames, which are limited to 50 characters for libvirt machines. Because it runs as a pre script, the created guestnames are available to other scripts including activate, delete and install.
The template makes use of the %{module} run-time macro, described under Section 2.2, “ Macros ”, to create a unique guestname for each deployment module, e.g. test-install, test-update and publish.
<?xml version="1.0" encoding="utf-8"?>
<script id='create-guestname' type='pre'>
<!--
script snippet for use by other scripts (install, delete, shutdown) to
source the stored guestname
-->
<macro id='libvirt-guestname-file'>%{script-data-dir}/libvirt-guestname-%{module}</macro>
<macro id='source-guestname'>
if [ -f %{libvirt-guestname-file} ]; then
  source %{libvirt-guestname-file}
else
  echo "unable to determine guest name - %{libvirt-guestname-file} does not exist"
  exit 1
fi
</macro>

<!--
Libvirt guestnames are limited to 50 characters. Sometimes, however,
Deploy-created hostnames, which contain os, version, arch and install type,
exceed that limit. This script deals with the limit as follows:

* creates a unique guestname based on the hostname
* stores the guestname in a file for inclusion within additional scripts
-->
#!/bin/sh
set -e

# exit if guestname file exists
[ -f %{libvirt-guestname-file} ] &amp;&amp; exit

# else create a guestname less than 50 characters
guestname=%{hostname}

if [[ ${#guestname} -gt 50 ]]; then
  index=1
  while [[ $index -lt 999 ]]
  do
    guestname="${guestname:0:48}-$index"
    virsh dominfo $guestname  || break  # if guestname available, break from loop
    index=`expr $index + 1`
  done
fi

# save guestname for use by other scripts
echo "guestname=$guestname" > %{libvirt-guestname-file}
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/create-guestname.xml"/>
test-exists
Test-exist scripts determine if the specified machine already exists. They are used primarily for determining whether install scripts should run, and should return exit code 3 if the machine does not exists. See the triggers element for additional information.
Example - This example shows a file named test-exists.xml which is included in the template folder at /usr/share/deploy/templates/el6/libvirt. The template contains a Python script that checks for the existence of a virtual machine with a specified guestname. It returns a non-zero value if a virtual machine does not exist.
See Section 2.1, “Templates” for more information on templates.
<?xml version="1.0" encoding="utf-8"?>
<script id='test-exists' type='test-exists'>
#!/usr/bin/python

import libvirt
import os
import sys

from deploy.util import pps
file = pps.path('%{libvirt-guestname-file}')
legacy_file=pps.path('/var/lib/deploy-client/scripts/%{id}/data/libvirt-%{module}')

if file.exists():
  guestname = file.read_text().strip().replace('guestname=', '')
elif legacy_file.exists():
  legacy_file.move(file)
  guestname = file.read_text().strip().replace('guestname=', '')
else:
  sys.stderr.write("guestname file '$file' does not exist\n")
  sys.exit(3)

connection = libvirt.open('qemu:///system')
try: #vm exists?
  vm = connection.lookupByName(guestname)
except libvirt.libvirtError:
  sys.stderr.write("vm does not exist\n")
  sys.exit(3)
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/test-exists.xml"/>
activate
Activate scripts handle client machine activation. These scripts should return exit code 3 if the machine could not be activated and reinstall is required. See the triggers element for additional information.
Example 1 - This example shows a file named activate.xml which is included in the template folder at /usr/share/deploy/templates/el6/libvirt. See Section 2.1, “Templates” for more information on templates.
The template contains the text of a python script. The script attempts to establish a connection to a virtual machine. If the virtual machine does not exist or cannot be activated, the script returns exit code 3.
<?xml version="1.0" encoding="utf-8"?>
<script id='activate' type='activate'>
<include href="test-exists.xml" xpath="./node()"/>
state = vm.state(0)[0]

# if vm is active, exit
if state == 1:
  sys.exit(0)

# if vm is idle blocked on resource, warn but exit success
if state == 2:
  sys.stdout.write("vm is idle blocked on system resources\n")
  sys.exit(1)

# if vm is paused or suspended, attempt to resume it
elif state == 3:
  try:
    vm.resume() 
    sys.exit(0)
  except libvirt.libvirtError, e:
    sys.stderr.write("vm is paused and failed to resume [%s]\n" % e)
    sys.exit(1)

# if vm is being shutdown, print an error and exit
# perhaps in the future wait for shutdown to complete and restart
elif state == 4:
  sys.stderr.write("vm is shutting down, unable to activate\n")
  sys.exit(1)

# if vm is shut off, attempt to start it
elif state == 5:
  try:
    vm.create()
    sys.exit(0)
  except libvirt.libvirtError, e:
    sys.stderr.write("vm is shut off and failed to start [%s]\n" % e)
    sys.exit(3) # reinstall
    
# if vm is crashed, print an error and exit
elif state == 6:
  sys.stderr.write("vm is crashed, unable to activate\n")
  sys.exit(1)

# if vm is suspended by guest power management, attempt to resume it
elif state == 7:
  try:
    vm.pMWakeup(0)
    sys.exit(0)
  except libvirt.libvirtError, e:
    sys.stderr.write("vm is suspended and failed to resume [%s]\n" % e)
    sys.exit(1)

else:
  sys.stderr.write("vm is in an unknown state, unable to activate "
                   "[state code: %s]\n" % state)
  sys.exit(1)
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/activate.xml"/>
Example 2 - This example shows a file named connect.xml which is included in the template folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The template contains the text of a Python script. The script attempts to establish a connection to the machine identified by the %{ssh-host} macro. If a connection cannot be established, the script returns exit code 1.
<script type='activate' id='connect' comes-after='activate'>
#!/usr/bin/python

import socket
import sys
import time
import traceback 

# test if a connection can be established, retry for 120 seconds to allow
# time for the remote system to boot and the ssh daemon to get started.

timeout = 120
sleep = 2
total = 0
try:
  s = socket.socket()
  while True:
    try:
      s.connect(('%{ssh-host}', 22))
      break 
    except (socket.gaierror, socket.error), e:
      # Catch "Name or service not known", "Connection timed out", 
      # "Connection refused", or "No route to host" errors
      if e[0] in [ -2, 110, 111, 113]:
        if total >= timeout:
          msg = ('unable to connect to %{ssh-host} in %s second timeout: \n%s'
                  % (timeout, e))
          sys.stderr.write(msg)
          sys.exit(1)
        else:
          time.sleep(sleep)
          total += sleep
      else:
        sys.stderr.write(traceback.format_exc())
        sys.exit(1)
except Exception:
  sys.stderr.write(traceback.format_exc())
  sys.exit(1)
finally:
  s.close
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/connect.xml"/>
test-triggers
Test-trigger scripts test current trigger values against prior trigger values and return exit code 3 if the values differ. See the triggers element for additional information.
Deploy makes a number of macros available to assist with test-trigger script operation. These are listed in Section 5.1.3, “ Macros ”, under the label Trigger Macros. The example below shows how they can be used in a test-triggers script.
Example - This example shows a file named test-triggers.xml which is included in the templates folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The template first reads a file (identified by the %{trigger-file} macro) of saved trigger values. Using a list of triggers identified by the %{triggers} macro, it then attempts to compare current trigger values to saved trigger values. Deploy calculates a number of current trigger values and makes them available via the %{release_rpm}, %{config_rpms}, %{kickstart}, %{treeinfo}, %{install_scripts} and %{post_install_scripts} macros. If any of the current triggers differs from the corresponding saved trigger, the script returns exit code 3.
<?xml version="1.0" encoding="utf-8"?>
<script id='test-triggers' type='test-triggers'>
#!/bin/bash
TRIGGER_INFO=%{trigger-file}
LEGACY_FILE=/var/lib/deploy-client/scripts/%{id}/data/trigger_info

FAIL=0

# create function to handle trigger failures
fail () {
FAIL=3
echo "$1 changed" >&amp;2
}

# get last trigger variables
if [ -f $TRIGGER_INFO ]; then
  source $TRIGGER_INFO
elif [ -f $LEGACY_FILE ] ; then
  mv $LEGACY_FILE $TRIGGER_INFO
  source $TRIGGER_INFO
else
  FAIL=1
  echo "missing trigger information file '$TRIGGER_INFO'" >&amp;2
fi

# set current trigger variables
curr_triggers='%{triggers}'
curr_release_pkg_csum='%{release_pkg_csum}'
curr_custom_pkgs_csum='%{custom_pkgs_csum}'
curr_kickstart_csum='%{kickstart_csum}'
curr_treeinfo_csum='%{treeinfo_csum}'
curr_install_scripts_csum='%{install_scripts_csum}'
curr_post_install_scripts_csum='%{post_install_scripts_csum}'

# test for changes in trigger list
[[ $curr_triggers == $last_triggers ]] || fail 'trigger list'

# test for changes in individual triggers
for trigger in $curr_triggers; do
  curr="echo \$curr_$trigger"
  last="echo \$last_$trigger"
  [[ `eval $curr` == `eval $last` ]] || fail $trigger
done

exit $FAIL
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/test-triggers.xml"/>
delete
Delete scripts delete or decommission client machines in preparation for system installation. Commonly used with the %{fqdn} module macro.
Example - This example shows a file named delete.xml which is included in the templates folder at /usr/share/deploy/templates/el6/libvirt. See Section 2.1, “Templates” for more information on templates.
In this example, a shell script is used to destroy and undefine a virtual machine specified using the %{fqdn} module macro. The command set -e is used at the beginning of the script to indicate that if any command in the script fails, the script should halt processing.
<?xml version="1.0" encoding="utf-8"?>
<script id='delete' type='delete' modules='test-install'>
#!/bin/bash
set -e

%{source-guestname}

# remove managedsave image, if domain exists
if [[ `/usr/bin/virsh list --all` = *\ $guestname\ * ]]; then 
  /usr/bin/virsh managedsave-remove $guestname 
fi

# destroy domain, if active
if [[ `/usr/bin/virsh list` = *\ $guestname\ * ]]; then
  /usr/bin/virsh destroy $guestname
fi

# undefine domain and delete image, if domain exists
if [[ `/usr/bin/virsh list --all` = *\ $guestname\ * ]]; then 
  /usr/bin/virsh undefine $guestname
  /usr/bin/virsh vol-delete --pool default $guestname.img
fi
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/delete.xml"/>
pre-install
Pre-install scripts performs tasks that are required prior to completing client installation.
Example - This example shows a file named create-ssh-keys.xml which is included in the template folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The template contains the text of a shell script that creates and saves ssh keys. This script type is set as pre-install so that the created keys can be used by install scripts for configuring ssh to the client machine.
<?xml version="1.0" encoding="utf-8"?>
<script id='create-ssh-keys' type='pre-install'>
#!/usr/bin/python

import sys
from deploy.util import pps

lib = pps.path('%{templates-dir}/%{norm-os}/common/ssh_lib.py')
sys.path.insert(0, lib.dirname)

from ssh_lib import *

create_keys('%{data-dir}', 'root')
</script>

The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/create-ssh-keys.xml"/>
install
Install scripts complete activites related to client machine installation. Commonly used with the %{fqdn} and %{webroot} module macros.
Example - This example shows a file named install.xml which is included in the templates folder at /usr/share/deploy/templates/el6/libvirt See Section 2.1, “Templates” for more information on templates.
The install.xml file provides a bash script which completes the actual machine installation. In this case, the script executes the virt-install command to create a new virtual machine. The script uses the %{fqdn} module macro to specify a name for the virtual machine, as well as the filename for the machine's image. It uses the %{webroot} macro to specify the location for the installation files, as well as for the kickstart file.
The set -e command has not been used in this script as it was in the delete example. In this case it is unnecessary because the script contains only a single command, virt-install.
<?xml version="1.0" encoding="utf-8"?>
<script id='install' type='install'>
<macro id='ram'>2048</macro>
<macro id='graphics'>vnc</macro>
<macro id='file-size'>12</macro>
<macro id='image-format'>raw</macro>
#!/bin/bash
set -e

%{source-guestname}

# install machine
virt-install \
  --name $guestname \
  --arch %{arch} \
  --ram %{ram} \
  --graphics %{graphics} \
  --disk path=/var/lib/libvirt/images/$guestname.img,size=%{file-size},format=%{image-format} \
  --location %{webroot} \
  --extra-args "%{boot-options} ks=%{webroot}/ks.cfg" \
  --force \
  --wait=-1 \
  --noreboot 2>&amp;1
</script>

											
</publish>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/install.xml"/>
post-install
Post-install scripts are executed immediately following client installation and handle tasks such as install verification.
Example - This example shows a file named verify-install.xml which is included in the templates folder at /usr/share/deploy/templates/el6/common See Section 2.1, “Templates” for more information on templates.
The file provides a shell script which uses the grep to scan for scriptlet failed errors in the install.log. If errors are found, the script returns exit code 1, indicating that verification failed.
<?xml version="1.0" encoding="utf-8"?>
<script id='verify-install' type='post-install'>
#!/bin/bash
#check install.log for scriptlet failed errors

logfile="/root/install.log"

failed_pkgs=$(grep 'scriptlet failed' $logfile | \
              sed -n "s/[^(]*(\([^)]*\).*$/\1/gp")

# check for scriptlet failed errors in custom pkgs
failed_flag=false
for pkg in $failed_pkgs; do
  if [[ "%{custom-pkgs}" == *$pkg* ]]; then 
    failed_flag=true
    break
  fi
done

if [[ $failed_flag == true ]]; then 
  errors=`grep -v "NOKEY" $logfile | \
  grep -v "*** FINISHED INSTALLING PACKAGES ***" | \
  grep -v "^Installing "`
  echo -e "Errors found in $logfile:\n$errors" >&amp;2
  exit 1
fi
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/verify-install.xml"/>
save-triggers
Save-triggers scripts save trigger values for future use by test-triggers scripts.
Example - This example shows the save-triggers.xml file which is included in the templates folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The script in this template saves trigger values to a file specified by the %{trigger-file} macro. The %{trigger-file} macro, along with other macros used by this script are defined in Section 5.1.3, “ Macros ”.
<?xml version="1.0" encoding="utf-8"?>
<script id='save-triggers' type='save-triggers'>
#!/bin/bash
set -e
# create TRIGGER_INFO file

TRIGGER_INFO=%{trigger-file}
echo "
last_triggers='%{triggers}'
last_release_pkg_csum='%{release_pkg_csum}'
last_custom_pkgs_csum='%{custom_pkgs_csum}'
last_kickstart_csum='%{kickstart_csum}'
last_treeinfo_csum='%{treeinfo_csum}'
last_install_scripts_csum='%{install_scripts_csum}'
last_post_install_scripts_csum='%{post_install_scripts_csum}'
" > $TRIGGER_INFO
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/save-triggers.xml"/>
update
Update scripts perform actions related to updating client machines, typically by executing the yum sync or yum update commands, followed by performing update verification as desired.
Example 1 - update-yum-conf.xml - This example shows a file named update-yum-conf.xml which is included in the template folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The script executes on the localhost, and copies the most current yum configuration to the client machine. The @comes-before attribute ensures it runs before the main update script, shown in Example 2.
<?xml version="1.0" encoding="utf-8"?>
<script id='update-yum-conf' type='update' comes-before='update' hostname='localhost'>
# ensure client is using the latest repo.conf
opts="
-o BatchMode=yes
-o UserKnownHostsFile=%{ssh-host-key-file}
"
scp $opts %{localroot}/repo.conf root@%{ssh-host}:/etc/yum.repos.d/%{name}.repo
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/update-yum-conf.xml"/>
Example 2 - update.xml - This example shows a file named update.xml which is included in the template folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
The script updates the client using the yum sync command. The set -e is used to halt processing if an error occurs at any point within the script.
<?xml version="1.0" encoding="utf-8"?>
<script id='update' type='update'>
#!/usr/bin/python

import os
import re
import sys
import yum

from rpmUtils import miscutils

# using shlib.call() as it allows capturing interleaved output and error text 
<include href="%{templates-dir}/%{norm-os}/common/shlib.py" parse="text"/>

# run yum command(s), checking output for scriptlet failed errors
opts = "-d 0 -e 0 -q -y"

# ensure release-rpm installed
try:
  call('yum %s install %{name}-release' % opts, shell=True, verbose=False)
except ShCalledProcessError as e:
  sys.stderr.write('%s\n' % e.both)
  sys.exit(e.returncode)

# determine commands to run 
if os.path.exists('/usr/lib/yum-plugins/sync.py'):
  commands = ['yum %s sync' % opts]
else:
  commands = [ 'yum %s groupinstall core' % opts,
               'yum %s update' % opts ]

# run commands
for cmd in commands:
  try:
    _,_,both = call(cmd, shell=True, verbose=False)

  # handle regular errors
  except ShCalledProcessError as e:
    sys.stderr.write('%s\n' % e.both)
    sys.exit(e.returncode)

  # check for scriptlet failed errors
  else:
    failed = []
    errlines = []
    pkgs = "%{custom-pkgs}".split()
    for l in both.split('\n'):
      if 'scriptlet failed' in l:
        errlines.append(l)
        pkg = re.search(r'\((.*)\)', l).group(1)
        script = re.search(r'%(.*)\(', l).group(1)
        if pkg in pkgs:
          failed.append((pkg,script))

    # handle scriptlet failed errors
    if failed:
      try:
        call("yum erase %s -y --cacheonly --disableplugin sync"
             % ' '.join([x[0] for x in failed]), shell=True, verbose=False)
      except ShCalledProcessError as e:
        sys.stderr.write('%s\n' % both)
        sys.exit(e.returncode)
      else:
        if len(failed) == 1:
          pkgname = miscutils.splitFilename(failed[0][0])[0]
          scriptname = failed[0][1]
        else:
          pkgname = "&lt;pkg>"
          scriptname = "&lt;script>"

        sys.stderr.write("""\
Scriptlet failed errors ocurred during package installation.  The failed package(s) have been uninstalled to prevent system inconsistencies:

%s

The following commands may assist with troubleshooting. See the Deploy User
Manual for additional information:

# ssh %{ssh-host}
# yum -y install %s 
# vi %{config-dir}/%s/%s

YUM error output below:

%s"""
% ("\n".join([x[0] for x in failed]), pkgname, pkgname, scriptname, both))
        sys.exit(1)
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/update.xml"/>
post
Post scripts perform tasks that should occur each time the deployment module runs, e.g. when deployment scripts change or when RPM packages are updated in the deployment repository. Post tasks might include performing client updates, restarting clients if the kernel package has been updated, or shutting down a client if its purpose has been accomplished during the course of module execution (e.g. building or testing RPMs).
For the publish event, this script is useful for copying published repositories to remote download servers. It can also be used to integrate repositories with enterprise systems management systems, for example to sync repository content with software channels in Red Hat Network or Spacewalk. In scenarios such as these, it is necessary to set the @hostname attribute to the value "localhost".
For the test-install and test-update events, the post script is useful for activities such as completing testing that should run after either install or update, or for powering down test machines between runs.
Example 1 - check-kernel.xml - This example shows a file named check-kernel.xml which is included in the template folder at /usr/share/deploy/templates/el6/common. See Section 2.1, “Templates” for more information on templates.
This script tests to see if the running kernel differs from the installed kernel, and restarts the client if needed.
<?xml version="1.0" encoding="utf-8"?>
<script id='check-kernel' type='update' comes-after='update'
        modules='test-update, publish'>
#!/usr/bin/python
import glob
import os
import socket
import smtplib
import sys
import yum

from email.mime.text import MIMEText

from subprocess import call, Popen, PIPE, STDOUT

# copied from yum.misc for consistent behavior across el5 and el6
def get_running_kernel_pkgtup(ts):
    """This takes the output of uname and figures out the pkgtup of the running
       kernel (name, arch, epoch, version, release)."""
    ver = os.uname()[2]

    # we glob for the file that MIGHT have this kernel
    # and then look up the file in our rpmdb.
    fns = sorted(glob.glob('/boot/vmlinuz*%s*' % ver))
    for fn in fns:
        mi = ts.dbMatch('basenames', fn)
        for h in mi:
            e = h['epoch']
            if h['epoch'] is None:
                e = '0'
            return (h['name'], h['arch'], e, h['version'], h['release'])
    
    return (None, None, None, None, None)

# main process
yb = yum.YumBase()
yb.preconf.init_plugins = False
yb.conf.cache = 1

ts = yb.rpmdb.readOnlyTS()
running_kernel = get_running_kernel_pkgtup(ts) 
arch = running_kernel[1]
latest_kernel = yb.rpmdb.returnNewestByNameArch(('kernel', arch))[0]

if running_kernel != latest_kernel:
  n, a, e, v, r = latest_kernel
  kernel_path = '/boot/vmlinuz-' + '.'.join([v,r])
  p = Popen(['/sbin/grubby', '--default-kernel'], 
             stdin=PIPE, stdout=PIPE, stderr=STDOUT)
  default_kernel = p.communicate()[0].rstrip()
  result = p.returncode

  if result != 0:
    sys.exit("ERROR: check-kernel was unable to determine the default boot kernel. Check your boot configuration manually to ensure the latest kernel '%s' is the default, and restart the machine." % ('-'.join([v,r])))

  elif ('-'.join([v,r]))  not in default_kernel:
    sys.exit("ERROR: check-kernel has determined that the latest kernel '%s' is not the default boot kernel. Uninstall earlier kernel versions manually, and restart the machine." % ('-'.join([v,r])))

  else:
    fqdn = socket.getfqdn()
    from_addr = 'root@%s' % fqdn
    to_addr = 'root'
    msg = MIMEText(
          "Running kernel differs from installed kernel - restart "
          "machine to use the latest kernel.\n\n"
          "running kernel:    %s\n"
          "installed kernel:  %s"
          % ('%s-%s' % (running_kernel[3], running_kernel[4]),
             '%s-%s' % (latest_kernel[3], latest_kernel[4])))
    msg['Subject'] = 'reboot required - %s' % fqdn
    msg['From'] = from_addr
    msg['To'] = to_addr

    server = smtplib.SMTP('localhost')
    server.sendmail(from_addr, to_addr, msg.as_string())
    server.quit()
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/common/check-kernel.xml"/>
Example 2 - This example shows a file named conditional-poweroff.xml which is included in the template folder at /usr/share/deploy/templates/el6/libvirt. See Section 2.1, “Templates” for more information on templates.
The file contains conditional code to shut down the client machine when a module-level macro, such as test-update-poweroff, is set to "true". In the default case, the script does not execute.
<?xml version="1.0" encoding="utf-8"?>
<script id='conditional-poweroff' type='post' hostname='localhost'
        modules='test-update'>
<macro id='test-install-poweroff'>false</macro>
<macro id='test-update-poweroff'>false</macro>
<macro id='publish-poweroff'>false</macro>
#!/bin/bash
# conditionally poweroff a libvirt guest machine 

%{source-guestname}

if [[ %{%{module}-poweroff} == true ]]; then
  virsh shutdown $guestname
fi
</script>
The template can be included in a definition as shown below:
<include href="%{templates-dir}/%{norm-os}/libvirt/conditional-poweroff.xml"/>
This attribute is required.
@comes-before
TEXT value providing a space or comma-separated list of scripts, identified by their @id values, that should execute following this script.
This attribute is optional. The default value is an empty string.
@comes-after
TEXT value providing a space or comma-separated list of scripts, identified by their @id values, that should execute following preceding this script.
This attribute is optional. The default value is an empty string.
@hostname
TEXT value specifying the hostname or IP address of the machine on which Deploy will attempt to execute the script.
The hostname attribute is optional. The default values vary by script type and are shown in the table below:
Script Type Default Value
pre, activate, delete, pre-install, install localhost
test-triggers, post-install, save-triggers, post %{ssh-host}
If the hostname is localhost, the script will be executed on the local machine. Otherwise, the script will be executed on the specified host using SSH.
The value of %{ssh-host} is determined by first attempting to read a file at the location specified by %{ssh-host-file}. If this file does not exist, the value of %{fqdn} is used. The %{ssh-host-file} provides a mechanism for scripts, typically an install script, to specify the client hostname or IP address at runtime. This is useful if the client is not accessible, or not immediately accessible, via DNS. The file can be created by outputting the hostname or IP address to a file at the location specified by the macro, for example:
<script name='install' type='install'>
...
ipaddress="address_of_installed_client"
echo $ipaddress > %{ssh-host-file}
...
</script>
See the Deployment Macros section for more information on the %{fqdn}, %{ssh-host} and %{ssh-host-file} macros.
Hosts specified using the @hostname attribute must be configured to accept SSH connections. Deploy supports public key authentication for SSH connections. Before performing the connection, Deploy will check to see if SSH has been configured for the root user on the build machine. It does this by testing for the existence of a file named /root/.ssh/id_rsa.pub. If this file does not exist, Deploy will attempt to configure SSH for the build machine by executing the following command:
/usr/bin/ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ""
Deploy does not support the use of a passphrase for the root user SSH key.

Note - SSH Configuration for Client Machines

As a final step, users must also configure client machines to allow SSH access from the build machine. This can be accomplished using a config-rpm . Deploy includes an example template to complete this task. On a system with Deploy installed, the file can be found as ssh-config.xml in the templates folder at /usr/share/deploy/templates/el6/common.
See the config-rpm element for an example of using this template. See Section 2.1, “Templates” for more information on templates.
@known-hosts-file
PATH to a file containing a public key for verifying the host specified in the @hostname attribute. Used only when the script is executed via SSH, i.e. @hostname is a value other than localhost.
This attribute is optional. The default value is %{ssh-host-key-file}.
See Section 7.12, “ Content: PATH for more information on PATH values
@modules
TEXT value providing a space or comma-separated list of modules in which this script should execute.
This attribute is optional. The default value is "test-install, test-update, publish".
@verbose
BOOLEAN value indicating whether the Standard Output from the script should be displayed as output from Deploy.
This attribute is optional. The default value is FALSE
See Section 7.6, “ Content: BOOLEAN for information on BOOLEAN values.
input-script
TEXT content of a script used for determining whether the deployment event should run during the current Deploy session. Deploy executes the script on the local machine as the root user.
Provides a single run-time macro:
%{input-dir}: The path to a folder where the input-script should copy files.
Deploy tests for changes in files in the %{input-dir} folder based on filename and timestamp. If any files have changed, it causes the deployment event to run.
The input-script element is optional. One or more elements are allowed.
In most cases this element is not required as Deploy automatically runs the event only when necessary. In some cases, however, it is desirable to cause the event to run based on external factors, such as changes to a file used by one of the scripts described in the previous element.
Example - in the example below, the text of a script is provided. The script tests if the current version of a source code repository matches the version saved to a file in the %{input-dir} folder. If not, it writes the new version to the file. Deploy checks for changes to files in the %{input-dir} and, if so, causes the deployment event to run.
<input-script>
#!/bin/sh
# track the latest source code repository revision so that tests run each
# time the repository changes

set -e
file=%{input-dir}/gitrev
gitrev_curr=`git rev-parse HEAD identify https://example.com/path/to/git/source/code/repo.git`
gitrev_last=`[ -f $file ] && cat $file || echo ''`
if [[ $gitrev_curr != $gitrev_last ]]; then
  echo $gitrev_curr > $file
fi
</input-script>

5.2.  Test-install

5.2.1.  Definition

The test-install top-level element supports automated installation testing. The test-install element is based on the Deployment Elements Common Model. See Section 5.1, “ Common Model ” for a complete description of syntax, macros, attributes and elements.
Deploy accomplishes installation testing using deployment scripts described in the Common Model. Should any of the scripts fail to complete successfully, Deploy halts processing prior to running the publish event.
Because its focus is on installation testing, the test-install event attempts to perform a clean client installation each time changes changes occur to repository content, to the kickstart file, or to installation scripts.
Test-install is an optional element.

5.2.2.  Examples

The following examples configure Deploy to perform a test install to a local virtual machine. See the Deploy User Manual for information on configuring the build machine to support virtual machine installations.
This example makes use of two files:
  • The main repository definition containing a test-install element.
  • A template for deploying systems to local virtual machines. The template file is located in the templates folder as libvirt/deploy.xml.

5.2.2.1. test-install element

This test-install element accomplishes the following:
  • Sets a macro indicating that the test-install machine should be deleted once test-install completes successfully. Deleting the test-install machine is useful once the system is in maintenance mode, as it preserves hard drive space and system resources on the build machine.
  • Includes the libvirt deploy.xml deployment template.
<test-install>
  <macro id='test-install-post-delete'>true</macro>
  <include href="%{templates-dir}/%{norm-os}/libvirt/deploy.xml" xpath="./*"/>
</test-install>

5.2.2.2. deploy.xml template

The libvirt deploy.xml template, shown below, provides the configuration necessary to deploy and maintain a local virtual machine. In addition, it provides module-specific scripts for performing actions such as testing removal of custom packages, deleting the test systems after successful completion, etc. See Section 2.1, “Templates” for information on locating and using templates.
<?xml version="1.0" encoding="utf-8"?>
<xml>
<!-- public access to repositories -->
<include href='%{templates-dir}/%{norm-os}/deploy/deploy-public-repo.xml'
         xpath='./*'/>

<!-- install and update a libvirt vm on the local machine -->
<domain>local</domain>
<kickstart>
<include href='%{templates-dir}/%{norm-os}/common/ks.xml'
         xpath='./node()'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/ks-post-ssh.xml'
         xpath='./node()'/>
</kickstart>
<include href='%{templates-dir}/%{norm-os}/common/acpid-config.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/ssh-config.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/libvirt-guest-config.xml'
         xpath='./*'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/verify-kvm.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/create-guestname.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/test-exists.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/activate.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/connect.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/ssh-write-host-key.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/test-triggers.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/delete.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/ssh-delete-host-key.xml'/>
<include href='%{templates-dir}/%{norm-os}/libvirt/install.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/verify-install.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/save-triggers.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/update-yum-conf.xml'/>
<include href='%{templates-dir}/%{norm-os}/common/update.xml'/>
<include href="%{templates-dir}/%{norm-os}/common/check-kernel.xml"/>
<include href="%{templates-dir}/%{norm-os}/common/conditional-test-remove-custom-pkgs.xml"/>
<include href="%{templates-dir}/%{norm-os}/libvirt/conditional-poweroff.xml"/>
<include href="%{templates-dir}/%{norm-os}/libvirt/conditional-post-delete.xml"/>
</xml>

5.3.  Test-update

5.3.1.  Definition

The test-update element allows testing system updates. As with test-install this testing occurs prior to publishing the final repository.
For complete information on macros, attributes and elements for the test-update top-level element, see the Deployment Elements Common Model at Section 5.1, “ Common Model ”.
Test-update is an optional element.

5.3.2.  Examples

The following examples show configuring Deploy to perform test updates using a local virtual machine. See the Deploy User Manual for information on configuring the build machine to support virtual machine installations.
Similar to the examples shown under Section 5.2, “ Test-install ”, this example makes use of two files: the main definition, and the libvirt deploy.xml template.

5.3.2.1. test-update element

This test-update element accomplishes the following:
  • Sets a macro indicating that the test-update machine should be powered off once test-update completes successfully. Powering down the test-update machine may be useful once the system is in maintenance mode, as it preserves system resources.
  • Includes the libvirt deploy.xml deployment template.
<test-update>
  <macro id='test-update-poweroff'>true</macro>
  <include href="%{templates-dir}/%{norm-os}/libvirt/deploy.xml" xpath="./*"/>
</test-update>

5.4.  Publish

5.4.1.  Definition

The publish top-level element provides information necessary for publishing the final repository, as well as for installing and updating the system on production client machines.
The publish element is based on the Deployment Elements Common Model. See Section 5.1, “ Common Model ” for a complete description of syntax, macros, attributes and elements.
Publish is an optional element.

5.4.2.  Examples

The following example shows a publish element configured to sync published content from the build server to a final production server.
<publish>
  <remote-url>https://repos.company.com/</remote-url>
  <script id="sync-to-production-server" type="post" hostname="localhost">
  #!/bin/bash
  # sync repository to production server 

  echo -e "\nsyncing %{id} repository to production server"
  rsync -a --delete -e ssh \
  "/var/www/html/deploy/systems/%{id}/" \
  "user@repos.company.com:/var/www/html/%{id}" 
  </script>
</publish>

Chapter 6.  Misc. Elements

Deploy supports three additional elements not described elsewhere in this document: bootiso, iso and files.
The bootiso and iso elements control creation of CD/DVD disk images for use during physical machine installation.
The files element allows distributing miscellaneous user-provided files and folders, such as readme or licensing files, or configuration templates, along with system or package repositories.

6.1.  BootISO

6.1.1.  Definition

Creates a minimal ISO image for performing system installation. This image, named boot.iso, is located in the images folder of the system repository. It can be used to boot a system from CD or DVD. Remaining installation content is then downloaded over the network from the system repository.
See the Deployment Guide for Red Hat Enterprise Linux at the Red Hat Documentation website for information on using boot.iso images.

6.1.2.  Syntax

[<bootiso [enabled="BOOLEAN"] />]

6.1.3.  Attributes

enabled
BOOLEAN value specifying whether a boot.iso image should be created. The created file will be located in the "images" folder for the repository.
The enabled attribute is optional. The default value is TRUE.

6.1.4.  Examples

In the following example, a boot.iso image will be created.
<bootiso/>

6.2.  ISO

6.2.1.  Definition

Creates ISO images for performing system installation via CD or DVD.

6.2.2.  Syntax

[<iso>
   <set>TEXT</set>*
 </iso>]

6.2.3.  Elements

set
TEXT value specifying the size per ISO, in bytes, of a set of ISO images to create. May include SI-style suffix ("MB", "GB", etc.). The reserved values "CD" and "DVD" correspond to "640MB" and "4.7GB", respectively.
This element must occur one or more times. Each instance will result in the generation of another set of ISO images.

Note

iso/set values are case- and space-insensitive, and the trailing 'b' is optional. For instance, the following TEXT values are all equivalent: "640000000", "640M", "640 mb", "CD".
By default, sizes are computed using 1000 bytes per megabyte. In order to use 1024 bytes per megabyte, insert an 'i' after the order designator; for example, "640 MIB" or "4.7GiB".
The iso element is ignored if type is set to "component" or "application".

6.2.4.  Examples

In the following example, Deploy will create four sets of ISO images; one with 4.7 gigabytes per disc ("DVD"), one with 400 megabytes per disc ("400000000"), one with 640 megabytes per disc ("640 mb"), and one with 640 mebibytes per disc ("640 mib"). Each set will be configured with keymap and lang boot arguments.
<iso>
  <set>DVD</set>       <!-- 4700000000 bytes/disc -->
  <set>400000000</set> <!--  400000000 bytes/disc -->
  <set>640 mb</set>    <!--  640000000 bytes/disc -->
  <set>640 mib</set>   <!--  671088640 bytes/disc -->
</iso>

6.3.  Files

6.3.1.  Definition

Copies user-specified files and folders to the root of the repository tree.
Accepts one or more files elements.

6.3.2.  Syntax

[<files>
   <files [destdir=PATH] [destname=BASENAME] [mode=MODE]
           [content=("file"|"text")]>
     (PATH|TEXT)
   </files>*
 </files>]

6.3.3.  Elements

files
Specifies a file or folder containing files to copy to the root of the repository tree. One or more files elements are required.
Accepts four attributes: @content, @destdir, @destname and @mode.
@content: Accepts either "file" or "text". When content is "file", the element's text value is treated as a PATH to a file, whereas when it is "text", the element's text value is interpreted as the raw text to use for creating a file with the name specified using the @destname attribute. The default value is "file".
@destdir: Controls the location to which this file or folder should be copied within the repository tree. The default value is the root of the tree, '/'. See Section 7.1, “Attribute: destdir” for additional information.
@destname: Name to be used for the file. If @content is "text", this attribute is required. See Section 7.2, “ Attribute: destname ” for additional information.
@mode: Mode to be used for the file or files. See the Section 7.3, “ Attribute: mode ” for additional information.

6.3.4.  Examples

This example copies two items to the repository tree. The first is a file named README which is created by Deploy using text provided within the element. The second is a folder named templates located in the same folder as the definition on the build machine. Both will be copied to the root of the repository.
<files>
<files content="text" destname="README">
# text of readme file
</files>

<files>templates</files>
</files>

Chapter 7.  Common Components

Common attributes, elements and constants are used throughout this reference document and have been included here to be concise. The descriptions provide a general overview of the item with more detail about values and behavior. Documentation for each top-level element may include variations on the standard behavior.

7.1. Attribute: destdir

7.1.1.  Definition

An absolute or relative DIRNAME (path) to a folder where Deploy will place the specified file or files. Deploy creates this destination folder if it does not exist. If the DIRNAME is absolute, the final file location will ignore the PATH-like element's default destination.

7.1.2.  Examples

In the following example, the default destination is /.
     
<files destdir="etc/samba">smb.conf</files>
The path specified above results in the following destination.
/etc/samba/smb.conf

7.2.  Attribute: destname

7.2.1.  Definition

The filename to use for the specified file or folder after it is copied to its destination. If not given, Deploy uses the basename of the specified file. Used to rename a file or folder.

7.2.2.  Examples

In the following example, the input file is visible within the file system, while the resulting file is hidden.
<files destdir="/root" destname=".bashrc">bashrc</files>
The above example results in the following.
     
/root/.bashrc

7.3.  Attribute: mode

7.3.1.  Definition

The numeric file MODE to apply to the specified file or recursively to all files, including those in subfolders, below the specified folder. If not specified, uses 0644.

7.3.2.  Examples

In the following example, the script config.sh is set to be executable by all system users.
<files mode="755">config.sh</files>

7.4.  Element: PATH-like Element

7.4.1.  Definition

PATH-like elements generally are used to include an input file or folder within the repository. A PATH-like element's text value is the PATH to some file or folder $input to use, while the @destdir, @destname, and @mode attributes control the location, filename, and mode of the destination file. In the case of a folder, the mode is applied to all files within the folder and any subfolders.
Deploy supports reading from $inputs for file, http, and https locations, and writing to file locations. Unless otherwise specified, $input may refer to both file and folder locations. If the $input does not exist or is otherwise unreadable, Deploy typically will raise an error and exit.

7.4.2.  Specifying the destination

PATH-like elements have two important properties when determining the final destination of the $input. The first, $root may be an absolute path on the build machine or a specific disk image. The second, $default, is the default location to which the $input is copied if no @destdir is specified. These values are combined in the following manner in the simplest case:
# $basename is the basename of $input
$root/$default/$basename
Allows overriding the value of $basename by specifying a different value using the @destname attribute:
# destname=outfile.txt
$root/$default/outfile.txt
Allows customizing the final location of the path by specifying a value in the @destdir attribute. The resulting path depends on whether @destdir is an absolute or relative path; if it is absolute, then $default is ignored; otherwise, @destdir is joined onto $default to form the final path.
# destdir=var/www/html  (relative)
$root/$default/var/www/html/$basename
# destdir=/var/www/html (absolute)
$root/var/www/html/$basename
The above two concepts can be combined to allow complete control over the final destination of $input.
# destdir=var/www/html,  basename=outfile.txt
$root/$default/var/www/html/outfile.txt
# destdir=/var/www/html, basename=outfile.txt
$root/var/www/html/outfile.txt

7.4.3.  Syntax

<ELEMENTNAME [destdir=DESTDIR]
             [destname=BASENAME]
             [mode=MODE]>
  $input
</ELEMENTNAME>

7.5.  Content: BASENAME

7.5.1.  Definition

A valid UNIX filename without any leading directory components; may include any characters except null and "/".

7.6.  Content: BOOLEAN

7.6.1.  Definition

A BOOLEAN is an element or attribute text value that may be either TRUE or FALSE. BOOLEAN values are case-insensitive.

7.6.2.  Syntax

FALSE: ("no"|"false"|"off"|"0")
TRUE:  ("yes"|"true"|"on"|"1")

7.7.  Content: CAPABILITY

7.7.1.  Definition

A RPM capability string. Supports mathematical comparison operators. CAPABILITY often refers to the name of a package, but may also indicate a file on disk or be some other arbitrary string (referred to as a virtual capability).

7.7.2.  Syntax

Capability strings have the following syntax:
capability [ comparison_operator  version ]
Comparison operators can be one of the following. Note that the "<" character must be escaped as shown below ("&lt;"), as this character has special meaning in XML documents.
Operator Meaning
> greater than
&lt; less than
= equal
>= greater than or equal
&lt;= less than or equal

7.7.3.  Examples

7.7.3.1.  Example 1 - Package-based

The following examples are capabilities using package names.
centos-release &lt; 5
bash &lt;= 2.5.1
samba

7.7.3.2.  Example 2 - Filename-based

The following examples are capabilities using filenames
/bin/bash
/usr/bin/python
/sbin/chkconfig

7.7.3.3.  Example 3 - Arbitrary string-based

The following examples are virtual capabilities using arbitrary strings.
rpm(CompressedFileNames)
libc.so.6
config(bash) = 3.2-20.fc9

Note

You can view capabilities provided by an RPM package using the rpm command.
# list capabilities of an installed package
rpm -q --provides samba 

# list capabilities of a file on disk
rpm -qp --provides samba-3.0.33-3.29.el5_7.4.i386.rpm

7.8.  Content: DIRNAME

7.8.1.  Definition

The directory component of a PATH without the filename; may include all characters except null.

7.9.  Content: GROUP

7.9.1.  Definition

The TEXT id of a GROUP containing PACKAGES.
Groups allow organizing sets of packages. They are particularly useful for identifying packages that should be installed during system build (which runs in a limited environment) versus those that should be installed after initial system boot.
To ensure that packages are installed during system build, they should be assigned to the 'core' group. Alternatively, they may be assigned to another group which must then be specified in the packages section of the kickstart file.

Note

Packages assigned to non-install groups may still be installed during initial system build if they are required by packages in 'core' or other kickstart-specified groups.

7.10.  Content: MODE

7.10.1.  Definition

A numeric mode in octal.

7.10.2.  Syntax

A mode consists of a string of integers in octal. The preceding "0" character is optional. Modes must define a value for the user, group, and other bits; it may additionally contain special permissions.

7.10.3.  Examples

The following are all examples of valid MODE values. Any of these examples may be preceded by the optional octal indicator, "0".
644
755
1444

7.11.  Content: PACKAGE

7.11.1.  Definition

A pattern representing a package. The variable supports full glob syntax, e.g. *-devel.

7.11.2.  Syntax

Package patterns support a number of possible choices. The full set of choices is listed below. The most common way to refer to a package is simply by its name.
name
name.arch
name-ver
name-ver-rel
name-ver-rel.arch
name-epoch:ver-rel.arch
epoch:name-ver-rel.arch

7.11.3.  Examples

# name=kernel, ver=2.4, rel=10, arch=i686, epoch=0
kernel
kernel.i686
kernel-2.4.1
kernel-2.4.1-10
kernel-2.4.1-10.i686
kernel-0:2.4.1-10.i686
0:kernel-2.4.1-10.i686

7.12.  Content: PATH

7.12.1. Definition

An absolute or relative local or remote path. Relative paths are resolved against the folder location of the definition. Unless otherwise noted, PATH can refer to a file or a folder, and may or may not exist.
PATHs may originate in file, http, or https schemes. Specifying the scheme of file paths is optional; absolute file paths may simply start with a forward slash ("/"). All relative paths are relative to the definition unless otherwise specified.

7.12.2. Syntax

7.12.2.1.  Syntax 1 - local PATHs

Absolute local paths start with a forward slash ("/"). They can be further broken up into DIRNAME and BASENAME components; DIRNAME is the directory component of a PATH without the filename, while BASENAME is the filename. PATHs that contain no leading directory components have an empty DIRNAME.
[DIRNAME/]BASENAME

7.12.2.2.  Syntax 2 - absolute local and remote PATHs

All paths that contain scheme and realm components are considered absolute. These paths break down into DIRNAME and BASENAME components in the same way as local paths do in Syntax 1.
$scheme://[$username[:$password]@][($hostname|$ipaddress)][:$port]/[$path]

7.12.3.  Examples

7.12.3.1.  Syntax 1

Examples of Syntax 1. The first path is an absolute local path while the second is a relative local path.
/var/www/html
data/inputs

7.12.3.2.  Syntax 2

Examples of Syntax 2. Note the first two examples below are equivalent to the first example of Syntax 1, above. All four examples are absolute paths.
file:///var/www/html
file://localhost/var/www/html
http://www.example.com/directory/file
https://myuser:mypassword@www.example.com:443/secure/directory/file

7.13.  Content: TEXT

7.13.1.  Definition

Arbitrary text. Unless otherwise specified, TEXT values may contain any characters, including non-alphanumeric and whitespace characters. See top-level element documentation for specific restrictions.
Typical restricted values might limit characters to alphanumeric characters plus the underscore, dash, and period. Another common limitation is no whitespace characters allowed.

7.14.  Content: URL

7.14.1.  Definition

An absolute path in Uniform Resource Location (URL) format. Supported schemes include file, http, and https.

7.14.1.1. Examples

file:///path/to/file/or/folder
http://example.server.com/path/to/file/or/folder
https://example.server.com/path/to/file/or/folder