© 2018 The original authors.

1. Overview

Galleon is a provisioning tool designed to create and maintain software distributions that consist of one or more products (or components). The tool supports:

  • adding products to a distribution;

    • their default and custom configurations;

  • removing products from a distribution;

  • integration of the products in the distribution;

  • resolution and validation of the resulting configuration and runtime dependencies;

  • patching and version updates;

  • product-specific provisioning plugins;

  • identification of the changes to the provisioned distribution (the FS content and/or the configuration) applied manually or using thirdparty tools;

  • exporting the description of the current state of the distribution with the goal to reproduce it later at another location.

The tool includes a command-line interface and a public API. There is also a Maven plugin that allows provisioning a distribution according to the provided configuration.

2. Feature-packs

Feature-pack represents a released unit of software (project, product, component, etc) that can be installed or uninstalled using Galleon tools. Feature-packs are ZIP archives that are normally deployed by the feature-pack producers to artifact repositories (such as Maven) where they can be discovered and consumed by users using Galleon tools.

Feature-pack contains:

  • metadata describing

    • dependencies on other feature-packs;

    • the default configuration(s) of the product the feature-pack represents;

    • the package set that should be installed by default;

  • (optional) a set of packages (that represent various filesystem content);

  • (optional) a set of configuration feature specs (used to define and/or tune parts of the product configuration);

  • (optional) various resources required to properly assemble and configure the product;

  • (optional) product-specific provisioning plug-ins.

Feature-pack may declare dependencies on other feature-packs. Before a feature-pack is installed the tool will make sure its dependencies are satisifed (by installing the missing ones).

2.1. Feature-pack archive structure

Feature-packs are distributed as ZIP archives with the following root entries:

feature-pack.zip
|- feature_groups/
|- features/
|- packages/
|- plugins/
|- resources/
`- feature-pack.xml

Where

  • feature_groups - optional directory containing feature group descriptions;

  • features - optional directory containing feature specs (units of configuration);

  • packages - optional directory containing packages (units of filesystem content);

  • resources - optional directory containing various resources needed to properly assemble and configure the product;

  • plugins - optional directory containing product-specific provisioning plug-ins;

  • feature-pack.xml - metadata describing the feature-pack and the default product configuration.

2.2. Feature-pack metadata (feature-pack.xml)

Generally, feature-pack metadata contains the following information:

  • Feature-pack location - string expression that indicates how to resolve the feature-pack artifact from a remote repository and how it can be identified among other feature-packs;

  • (optional) dependencies - dependencies on other feature-packs.

  • (optional) configuration - the default configurations of the product (there could be more than one default configuration);

  • (optional) default packages - names of the packages that are installed by default.

Here is an illustration of how it may look like in a feature-pack.xml file:

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
    location="wildfly-servlet@maven(org.jboss.universe:community-universe):current#14.0.0.Beta2"> (1)
    <dependencies>
        <dependency location="wildfly-core@maven(org.jboss.universe:community-universe):current#6.0.0.Beta1"/> (2)
    </dependencies>
    <config model="standalone" name="standalone.xml"> (3)
        <feature-group name="standalone"/>
        <feature spec="another-feature">
            <param name="p1" value="v1" />
            <param name="p2" value="v2" />
        </feature>
    </config>
    <config model="domain" name="domain.xml">
        <feature-group name="domain"/>
    </config>
    <config model="host" name="host.xml">
        <feature-group name="host"/>
    </config>
    <default-packages> (4)
        <package name="docs"/>
        <package name="modules.all"/>
    </default-packages>
</feature-pack>
1 Feature-pack location and build info;
2 Dependency on another feature-pack;
3 Description of the default standalone.xml configuration;
4 List of packages that should be installed by default.

2.3. Feature-pack location

Feature-pack location is an expression that is used to resolve the feature-pack artifact from the remote repository and also identify the feature-pack among other feature-packs.

The general and complete feature-pack location format is producer@universe:channel/frequency#build

  • producer - simple name of a feature-pack producer, normally a product or a component name;

  • universe - the universe the producer belongs to (universe is basically a named set of feature-pack producers);

  • channel - source of backward compatible feature-pack builds;

  • frequency - denotes the lowest accepted build quality (e.g. alpha, beta, final, etc) for the feature-pack builds pulled from the channel;

  • build - feature-pack build number or version.

Some of the parts above are or could be optional. For example, a user could add a specific universe as the default one for the distribution (in its provisioning configuration) and then not include it explicitly in feature-pack locations for the feature-packs coming from that universe.

Frequency is, generally, also optional and could be omitted.

With the universe and frequency omitted the location becomes producer:channel#build

Here is an example of a full feature-pack location:

wildfly@maven(org.jboss.universe:community-universe):current/beta#14.0.0.Beta2

And a shortened version:

wildfly:current#14.0.0.Beta2

Galleon CLI tool comes pre-configured with maven(org.jboss.universe:community-universe) as the default universe, which means Galleon CLI users can omit the universe part for wildfly and other feature-pack producers from that universe and also, in general, rely on TAB-completion for feature-pack locations.

Using Galleon CLI

install wildfly@maven(org.jboss.universe:community-universe):current/beta#14.0.0.Beta2

and

install wildfly:current#14.0.0.Beta2

will result in the exact same distribution. And to install the latest (final) version of wildfly a user can simply type

install wildfly:current

2.3.1. Channel

Channel represents a source of backward compatible releases. Channels are defined and configured by feature-pack producers.

As an example, a channel could be mapped to a major version of a product. Suppose, there is product productA with development branches 1.x and 2.x and 2.x branch is not backward compatible with 1.x branch. In this case, the producer of productA could define two channels 1 for branch 1.x and 2 for branch 2.x. Then, to install the latest available (final) release of 1.x branch the user would request the tool to install productA:1 and productA:2 for the latest available (final) release on 2.x branch.

2.3.2. Frequency

Frequency is a channel option that indicates the lowest acceptable build quality when the tool is looking for the latest build of the product. Supported frequencies are defined and configured by feature-pack producers. If the user has not provided any frequency, the default is assumed to be the final (or GA) release.

Frequency is used by the provisioning mechanism only when looking for the latest build. I.e. when installing a product for which the user has not specified the version or when looking for updates for the already installed products.

The following is a valid feature-pack location expression: productA:1#1.0.0.Beta2.

Although the frequency is missing, which means it’s equivalent to productA:1/final#1.0.0.Beta2. Installing productA:1#1.0.0.Beta2 will still install 1.0.0.Beta2, because the user has provided the desired version explicitly.

But if the user requests an update to the latest version, the tool will check the frequency and will look for the latest available release that satisfies the frequency. In the example above, the tool will not update the distribution until 1.0.0.Final becomes available, even if 1.0.0.Beta3 becomes available before that.

However, if the user installed the same feature-pack as productA:1/beta#1.0.0.Beta2 and requested an update to the latest version, the tool would also look for the available beta releases and propose 1.0.0.Beta3 if it’s available.

frequency specifies the lowest quality, which mean installing productA:1/beta may actually install 1.0.0.Final if the final release is available.

3. General provisioning workflow

This is not a precise description of how it happens but a high level overview of the workflow.

  1. The provisioning mechanism determines a set of feature-packs that need to be resolved for the installation

  2. Feature-pack version compatibility is checked

  3. The feature-packs are downloaded from their respective repositories and unpacked in a temporary location

  4. Feature-packs are processed in the order they are specified in the installation provisioning description

    • configuration models and the packages set to be installed is determined for every feature-pack

    • configuration models are merged on-the-fly as soon as they are processed

  5. A staged directory is created

  6. Content from all the feature-pack packages is copied to the staged directory (in the order the feature-packs should be installed)

  7. Feature-pack plugins are invoked

    • The plugins are assumed to generate the configuration files from the provided resolved configuration models and perform other necessary tasks to complete the installation

  8. The provisioned state of the installation is recoded

  9. The installation created in the staged directory is moved to the target installation directory (fully replacing the current one, if it exists)

  10. The temporary directories are deleted

4. Feature-pack packages

A package is a minimal atomic unit of filesystem content that can be included into or excluded from the installation. It could be a set of files and/or provisioning-related resources attached to the package used by the mechanism to provision a piece of filesystem content.

Essentially, a software release (filesystem content-wise) is represented as a set of packages released under a common version.

Package contains:

  • metadata describing the package;

  • (optional) FS content which is copied into the installation when the package is installed;

  • (optional) other provisioning resources that are used during provisioning to generate and/or integrate the content (or what the package represents) properly into the target installation.

Package may declare dependencies on other packages that belong to the same or another feature-pack. Before a package is installed, the tool will make sure all its dependencies are satisifed (which includes automatic installation of the ones that are missing from the installation).

Package is identified by its name. The name must be unique in the scope of the feature-pack the package belongs to.

Packages are not versioned. Only the feature-pack has a version.

4.1. Package directory structure

Packages are stored in the directories (named after the packages) under the feature-pack packages directory.

Package directory contains the following entries:

  • package.xml - the metadata describing the package;

  • (optional) content - directory containing the content of the package which will be copied to the installation when the package is installed;

  • (optional) pm - directory containing various resources needed to properly provision the content of the package.

Here is an illustration of packages entry from a feature-pack archive containing packages p1, p2, p3 and p4:

packages/
|-p1/
| |-content/
| | `-...
| |-pm/
| | `-...
| `-package.xml
|-p2/
| |-content/
| | `-...
| `-package.xml
|-p3/
| |-pm/
| | `-...
| `-package.xml
`-p4/
  `-package.xml

4.2. Package metadata (package.xml)

Package metadata contains the following information:

  • package name;

  • (optional) dependencies - dependencies on other packages from the same and/or other feature-packs;

Here is an illustration of how package.xml might look like:

 <package-spec xmlns="urn:jboss:galleon:package:1.0" name="p1">
    <dependencies>
        <package name="p2"/>
        <package name="p3" optional="true"/>
        <origin name="another-feature-pack">
            <package name="p1"/>
            <package name="p11" optional="true"/>
        </origin>
    </dependencies>
 </package-spec>

Here package p1 declares dependencies on packages p2 and p3 that belong to the same feature-pack as p1 and packages p1 and p11 that belong to another feature-pack referenced by alias another-feature-pack.

4.3. Package dependencies

Package dependency may be required or optional.

Required dependency means that a package cannot be installed unless all its required dependencies are satisfied, i.e. installed. If any required dependency cannot be satisfied (perhaps because a package that happens to be a required dependency has been explicitly excluded from the installation), the provisioning process will fail with an error.

Optional dependency means that the dependency does not have to be satisfied for the package to be installed. For example if package p1 declares an optional dependency on package p2 and p2 is explicitly excluded by the user, p1 will still be installed. An example of an optional dependency could be a package called documentation which declares an optional dependency on package examples. If a user is not interested in examples, the rest of documentation could still be installed.

Package dependencies are also used to determine the effective package set of a feature-pack to be installed described later.

Here is an example of how dependencies are expressed in the XML metadata:

 <package-spec xmlns="urn:jboss:galleon:package:1.0" name="p1">
    <dependencies>
        <package name="p2"/>
        <package name="p3" optional=”true”/>
    </dependencies>
 </package-spec>

In this example p2 is a required dependency of p1 while p3 is an optional one.

Package may declare dependency on a package from the same or another feature-pack. During the dependency resolution, at first, the mechanism is trying to resolve the package dependency locally, i.e. in the current feature-pack. If the dependency could not be resolved locally, the mechanism will look for the package dependency in the feature-packs the current feature-pack depends on (in the order the feature-pack dependencies are listed in the feature-pack.xml of the current feature-pack). The first found matching package will be used as the resolved dependency. If the package dependency could not be resolved, the mechanism will report an error.

Although a package may declare a dependency on a package from another feature-pack, it cannot specify the version of the feature-pack in the package dependency declaration.

4.3.1. Explicit package dependency origin

Feature-pack containing a package with an external dependency must declare an explicit dependency on the feature-pack (specifying its version) the target package of the external dependency belongs to. This feature-pack dependency may also be assigned a name which can later be used as a reference to that feature-pack dependency when declaring dependencies in package.xml file on packages that belong to that feature-pack.

For example, suppose feature-pack fp1 depends on feature-pack fp2 and package fp1:p1 depends on packages fp2:p1 and fp2:p10. The feature-pack.xml of fp1 might look like this:

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0">
            <origin>fp2-dep</origin>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>

And the package.xml file of fp1:p1 might look like this:

 <package-spec xmlns="urn:jboss:galleon:package:1.0" name="p1">
    <dependencies>
        <package name="p2" />
        <origin name=”fp2-dep”>
            <package name=”p1” />
            <package name=”p10” />
        </origin>
        <package name="p3" />
    </dependencies>
 </package-spec>

In general, the origin element is optional, but in some cases it helps to specify explicitly the origin of package dependencies.

4.4. Feature-pack default packages

Feature pack may define a set of default packages. This set of default packages is installed when the user does not provide explicit instructions about which packages from the feature-pack to install.

Default packages are explicitly listed in feature-pack.xml file which is a part of the feature-pack archive. For example:

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <default-packages>
        <package name="package1" />
        <package name="package2" />
    </default-packages>
 </feature-pack>

If this feature-pack is installed without further customizations, package1 and package2 will be installed by default, although the feature-pack above may still contain other packages (not listed as default) that may not get installed.

4.5. Feature-pack non-default packages

Feature-pack may contain packages that are not marked as default in its feature-pack.xml. Non-default packages can be installed either:

  • implicitly, in case a non-default package appears to be a transitive dependency of a default package;

  • explicitly, in case a user explicitly selected a non-default package to be installed.

4.6. Effective package set

This chapter is dedicated to the effective package set of a feature-pack (without dependencies) that is going to be installed, how it is resolved by the mechanism and how it can be adjusted by a user.

4.6.1. Feature-pack original effective package set

Original in the title means not explicitly modified. I.e. a set of packages which is going to be installed when the feature-pack is installed as-is without any customizations from a user.

The feature-pack’s original effective package set consists of all the default packages of the feature-pack plus all the packages that appear to be direct or transitive dependencies of the default packages.

4.6.2. Explicit package exclusion

A package may be explicitly excluded from the feature-pack’s effective package set. For example, given the following feature-pack definition (feature-pack.xml):

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <default-packages>
        <package name="p1" />
        <package name="p2" />
    </default-packages>
 </feature-pack>

and assuming that

  • package p1 has an optional dependency on non-default package p11,

  • package p2 has an optional dependency on non-default package p22.

The original effective package set of fp1 includes p1, p11, p2 and p22.

If a user is interested in a subset of the effective package set, in fact, only in package p1, for example, it can be expressed in the provisioning XML configuration file as

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
         <packages>
             <exclude name="p11"/>
             <exclude name="p2"/>
         </packages>
     </feature-pack>
 </installation>

Packages p11 and p2 are explicitly excluded and package p22 is a non-default package which is not a direct or transitive dependency of the packages to be installed, i.e. p1.

4.6.3. Explicit package inclusion

A package may be explicitly included into the feature-pack’s effective package set. For example, given the following feature-pack definition (feature-pack.xml):

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe:1#1.0.0" >
    <default-packages>
        <package name="p1" />
        <package name="p2" />
    </default-packages>
 </feature-pack>

and assuming that

  • p2 has an optional dependency on non-default package p21,

  • fp1 also contains non-default package p3,

  • p3 has an optional dependency on non-default package p31.

The effective package set of fp1 includes p1, p2 and p21.

A user may explicitly add package p3, exclude p2 and still leave p21 in the effective package set using the following configuration:

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
         <packages>
             <include name="p3"/>
             <exclude name="p2"/>
             <include name="p21"/>
         </packages>
     </feature-pack>
 </installation>

The effective package set now will consist of p1 (default package), p21 (explicitly included non-default), p3 (explicitly included non-default) and p31 (brought in as a dependency of p3).

If, for example, the user wanted to further cut down the effective set to p21 and p3, the configuration would change to

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
         <packages>
             <exclude name="p1"/>
             <exclude name="p2"/>
             <include name="p21"/>
             <include name="p3"/>
             <exclude name="p31"/>
         </packages>
     </feature-pack>
 </installation>

5. Feature-pack dependencies

Feature pack may depend on one or more other feature-packs. Feature-pack dependencies are expressed in feature-pack.xml file. For example:

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.1"/>
        <dependency location="fp3@maven(org.jboss.universe:community-universe):1#1.0.2"/>
    </dependencies>
    <default-packages>
        <package name="package1"/>
        <package name="package2"/>
    </default-packages>
 </feature-pack>

In this case feature-pack fp1 depends on feature-packs fp2 and fp3. And if a user requests to install fp1, feature-packs fp2 and fp3 will be installed by the mechanism implicitly as dependencies of fp1.

If we further assume that fp3 depends on feature-pack fp4 and fp2 and fp4 don’t have any further dependencies. The effective package set of the distribution provisioned from fp1 will consist of:

  • the effective package set of fp1;

  • the effective package set of fp2;

  • the effective package set of fp3;

  • the effective package set of fp4.

fp2 and fp3 are called direct dependencies of fp1, while fp4 is called a transitive dependency of fp1 and a direct dependency of fp3.

5.1. Customizing the effective package set of a dependency

As illustrated in the example above, the effective package set of the dependency contributes to the effective package set of the distribution. The feature-pack declaring the dependency, though, is allowed to customize the effective package set of the dependency (the package set it inherits) using the already mentioned in previous chapters include and exclude XML elements in its feature-pack.xml. For example:

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0">
            <packages>
                <exclude name="p1"/>
                <exclude name="p2"/>
                <include name="p3"/>
                <include name="p4"/>
            </packages>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="p1"/>
        <package name="p2"/>
    </default-packages>
 </feature-pack>

Element packages under dependency in feature-pack.xml has exactly the same structure as element packages in the provisioning XML configuration file, mentioned earlier in the chaper describing the effective package set of a feature-pack.

Now the effective package set of a distribution provisioned from fp1 becomes:

  • fp1 packages p1 and p2;

    • plus their dependencies on non-default packages (if any);

  • the effective package set of fp2;

    • minus packages p1 and p2 from fp2 and their dependencies on other packages;

    • plus packages p3 and p4 from fp2 and their dependencies on other packages.

in case fp2 in its turn depended on other feature-packs then the effective package sets of those feature-packs (possibly customized using include/exclude in the corresponding dependency declaration in the feature-pack.xml of fp2).

5.2. Disabling package inheritance from a dependency

The effective package set of a dependency is inherited by the feature-pack declaring the dependency. However, it is possible to declare the dependency without inheriting its effective package set and simply pick the packages explicity under dependency element (in other words, explicitly define the effective package set of the dependency).

Optional boolean attribute inherit of element packages controls whether package inheritance is enabled or disabled. In case the attribute is not explicitly specified, its value is assumed to be true. Here is an example of a dependency with disabled package inheritance:

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0">
            <packages inherit=”false”>
                <exclude name="p1"/>
                <exclude name="p2"/>
                <include name="p3"/>
                <include name="p4"/>
            </packages>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="p1"/>
        <package name="p2"/>
    </default-packages>
 </feature-pack>

Now the effective package set of the distribution provisioned from fp1 becomes:

  • fp1 packages p1 and p2;

    • plus their dependencies on non-default packages (if any);

  • fp2 packages p3 and p4;

    • plus their dependencies on non-default packages minus packages p1 and p2 from fp2 and their dependencies on other packages.

5.3. Merging package sets of dependencies

Suppose feature-pack fp1 depends on feature-packs fp2 and fp3. Both fp2 and fp3 depend on their own custom package sets of feature-pack fp4. When fp1 is installed, the effective package set of fp4 will be a merge of the custom package sets of fp4 defined in fp2 and fp3 as their dependencies.

For example:

Feature-pack fp1
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0"/>
        <dependency location="fp3@maven(org.jboss.universe:community-universe):2#2.0.0"/>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Feature-pack fp2
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0" >
    <dependencies>
        <dependency location="fp4@maven(org.jboss.universe:community-universe):2#2.0.0">
            <packages>
                <exclude name="p1"/>
                <exclude name="p3"/>
            </packages>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Feature-pack fp3
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp3@maven(org.jboss.universe:community-universe):2#2.0.0" >
    <dependencies>
        <dependency location="fp4@maven(org.jboss.universe:community-universe):2#2.0.0">
            <packages inherit=”false”>
                <!-- assume fp4 also contains non-default package p4 -->
                <include name="p4"/>
            </packages>
        </dependency>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Feature-pack fp4
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp4@maven(org.jboss.universe:community-universe):2#2.0.0" >
    <default-packages>
        <package name="p1"/>
        <package name="p2"/>
        <package name="p3"/>
    </default-packages>
 </feature-pack>

A distribution provisioned from fp1 without further customizations will include:

  • fp1:p1 and its dependencies;

  • fp2:p1 and its dependencies;

  • fp3:p1 and its dependencies;

  • fp4:p2, fp4:p4 and their dependencies.

6. Feature-pack transitive dependencies

Suppose there is feature-pack fp1 that depends on fp2 and fp2 in its turn depends on fp3. In this case, fp2 is a direct dependency of fp1 while fp3 is a transitive dependency of fp1 and a direct dependency of fp2.

Transitive dependencies are the dependencies of the dependencies.

6.1. Customizing package set of a transitive dependency

Let’s suppose we have the following two feature-packs:

Feature-pack fp1
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
     <dependencies>
         <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0">
             <packages inherit="false"> (1)
                 <include name="p3"/>
                 <include name="p4"/>
                 <exclude name="p5"/>
             </packages>
         </dependency>
     </dependencies>
     <default-packages>
         <package name="p1"/>
     </default-packages>
 </feature-pack>
1 Let’s assume fp2 also contains packages p4, p5 among others.
Feature-pack fp2
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0" >
     <default-packages>
         <package name="p1"/>
         <package name="p2"/>
         <package name="p3"/>
     </default-packages>
 </feature-pack>

If we provision a distribution from fp1 like this

Distribution provisioning configuration
 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

its effective package set will include:

  • fp1:p1 plus its dependencies;

  • p3 and p4 from fp2 plus their dependencies excluding p5.

The provisioning mechanism will not install the default configuration of fp2 but its customized version defined by fp1, in other words a subset of fp2 that fp1 needs.

Now if we provision our distribution as

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0"/>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

its effective package set will become:

  • fp1:p1 plus its dependencies;

  • p1, p2, p3 and p4 from fp2 plus their dependencies (not excluding p5).

The provisioning mechanism will install the default configuration of fp2 plus what fp1 needs on top of it.
feature-pack element appearing in the provisioning configuration under installation always points to the default configuration of the feature-pack.

Now let’s suppose we want to add another package from fp2 to our distribution but we want to start from the customized fp2 configuration defined by fp1. One way of achieving that would be

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0">
         <packages inherit="false">
             <include name="p3"/>
             <include name="p4"/>
             <exclude name="p5"/>
             <include name="p6"/> (1)
         </packages>
     </feature-pack>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>
1 the package we want to add to our distribution

That works but is not very practical. We basically copied the customizations of fp2 from fp1 to our provisioning configuration. If the configuration was more sophisticated it wouldn’t be that easy. Here is an easier alternative:

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <transitive>
         <feature-pack location="fp2@maven(org.jboss.universe:community-universe)"> (1)
             <packages>
                 <include name="p6"/>
             </packages>
         </feature-pack>
     </transitive>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>
1 Note, although we could provide the full version of fp2 here, we chose not to, the mechanism will resolve it to the version specified in feature-pack.xml of fp1
By including feature-pack element under transitive we indicate to the provisioning mechanism that the feature-pack we are about to customize appears on a dependency branch of another feature-pack installed in this configuration directly and that we want to adjust the configuration defined by the feature-pack that depends on it instead of the configuration defined in its feature-pack.xml.

7. Overriding dependency versions and resolving conflicts

Suppose we have these feature-packs

Feature-pack fp1
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0"/>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Feature-pack fp2
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0" >
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>

Feature-pack fp1 declares a dependency on version 2.0.0 of fp2. Even if later backward compatible versions of fp2 are available, provisioning a distribution from fp1 will get fp2 version 2.0.0 installed. If we still want to upgrade fp2 there are two ways to do that

1) install the desired version of fp2 directly as

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp2@maven(org.jboss.universe:community-universe):2#2.0.1"/>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

2) use transitive element to override the version of fp2 specified in feature-pack.xml of fp1

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <transitive>
         <feature-pack location="fp2@maven(org.jboss.universe:community-universe):2#2.0.1"/>
     </transitive>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

The advantage of specifying the version in the transitive dependency is that it will override only the version of fp2 w/o affecting its customizations (if any) applied to fp2 by fp1. While installing the new version directly will install the default configuration of fp2.

This example has illustrated the basic version overriding rule.

Feature-pack versions that appear higher in the feature-pack dependency hierarchy (i.e. closer to the root in the provisioning configuration) override versions that appear further down in the dependency hierarchy, no matter whether they are higher or lower in comparison.

7.1. Resolving version conflicts

It is possible to run into a version conflict when feature-packs on different dependency branches delcare dependencies on different versions of the same feature-pack. Since it happens on different branches, the version overriding rule does not apply and the provisioning mechanism cannot automatically pick the version. Here is an example

Feature-pack fp1
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp3@maven(org.jboss.universe:community-universe):1#1.2.0"/>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Feature-pack fp2
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0" >
    <dependencies>
        <dependency location="fp3@maven(org.jboss.universe:community-universe):1#1.3.0"/>
    </dependencies>
    <default-packages>
        <package name="p1"/>
    </default-packages>
 </feature-pack>
Provisioning configuration
 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
     <feature-pack location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

Provisioning of this configuration will fail with the version conflict for feature-pack fp3. fp1 depends on fp3 version 1.2.0 and fp2 depends on fp3 version 1.3.0. fp1 and fp2 are two roots of separate dependency branches, so the version overriding rule does not apply to fp3.

To resolve this kind of version conflict a user cane either install fp3 directly or specify its desired version in the transitive element of the installation. E.g.

 <installation xmlns="urn:jboss:galleon:provisioning:2.0">
     <transitive>
         <feature-pack location="fp3@maven(org.jboss.universe:community-universe):1#1.4.0"/>
     </transitive>
     <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0"/>
     <feature-pack location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0"/>
 </installation>

8. Generic configuration model

In addition to provisioning various filesystem content as packages, the mechanism also allows generation of the configuration files for the target installation taking into account the customizations applied by the user to the feature-pack defaults.

Feature-pack metadata (feature-pack.xml) may include one or more config elements each of which describes a specific type of configuration supported by the resulting installation. In a simple (and perhaps the most common) case, the configuration described under config element will represent a specific configuration file in the provisioned installation.

Installation configuration is described using a generic configuration model. The generic configuration model is based on an abstract schema that describes configurable units and relationships between them. The model allows a user to manipulate the confguration in a generic way by adding to and/or removing parts from it, and/or overwriting some parameter values. The responsibilities of the core provisioning mechanism with regards to the configuration are:

  • resolve the final installation configuration model taking into account the customizations applied to the pre-defined in feature-pack.xml default configuration;

  • make sure the resolved configuration model is valid by:

    • verifying that all the required parameter values are set;

    • checking the referential integrity of the resolved configuration model (i.e. in case certain configuration units imply presence of certain other configuration units);

    • making sure that the capability requirements in the resolved configuration are satisfied;

    • and that packages required by the configuration model are included into the installation;

  • present the units of the resolved configuration to the provisioning plugins in the order the configuration model was populated but also respecting the dependencies of those units.

The generic provisioning mechanism itself does not generate the final configuration files. As indicated above, it only resolves the effective generic configuration model for the provisioned installation and makes sure it does not violate various constraints it might have. It is the responsibility of product-specific provisioning plugins to generate the final configuration file(s) from the already resolved and validated generic configuration model.

8.1. Features

Minimal configurable unit of the generic configuration model is called a feature. A feature is described by a feature specification (or feature spec further in the text). A feature spec describes how a feature can be configured, while a feature is a specific configuration of a feature spec.

Feature specs are identified by their names that must be unique in the scope of the feature-pack.

A feature spec describes

Feature specs are stored in spec.xml files in the directories named after the feature spec names under feature-pack’s features directory. For example

features/
|-feature1/
| `-spec.xml
`-feature2/
  `-spec.xml

8.1.1. Feature ID

A feature may have an identifier (feature id further in the text) which is used to locate a specific feature in the configuration model. Whether a feature has an ID or not is specified in the feature spec.

A feature ID is essential to be able to customize the configuration of a specific feature.

Feature ID consists of a feature spec name plus one or more feature parameters. Feature parameters that are a part of the feature ID include feature-id="true" attribute in their descriptions (and cannot be nillable). For example

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature1">
   <params>
     <param name="name" feature-id="true"/>
     <param name="b" default="bb"/>
     <param name="c" nillable="true"/>
   </params>
 </feature-spec>

Now if a config includes multiple features of feature spec feature1, they could be refered to by feature1:name=unique_name expression, where unique_name is the value of parameter name of the target feature.

Feature ID parameters cannot change values during config customizations. If a user wants to have a different value for an ID parameter of a certain feature, the existing feature has to be excluded from the config and a new feature with the desired ID parameter value has to be added in.

Here is an example of a feature spec with multiple feature ID parameters:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature2">
   <params>
     <param name="p1" feature-id="true"/>
     <param name="p2" feature-id="true"/>
     <param name="p3" nillable="true"/>
   </params>
 </feature-spec>

An ID of a feature of this spec will look like feature2:p1=p1_value,p2=p2_value.

The order of the ID parameters in the feature ID string is not significant.

8.1.2. Feature parameters

Feature parameters are described in feature specs. A parameter is identified by its name (which must be unique in the scope of the feature spec) and may have the following attributes:

  • required string name - the name of the parameter;

  • optional boolean feature-id - indicating whether the parameter is a part of the feature ID (if not present, the default is assumed to be false);

  • optional boolean nillable - indicating whether the parameter allows null as the value in the resolved config (if not present, the default is assumed to be false);

  • optional string default - indicates which value should be used for the parameter, if the parameter was not explicitly initialized in the configuration (if not present, the default is assumed to be null);

  • optional string type - type of the parameter (if not present, the default is assumed to be String).

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature1">
   <params>
     <param name="a" feature-id="true"/> (1)
     <param name="b" default="bb"/> (2)
     <param name="c" nillable="true"/> (3)
     <param name="d"/> (4)
   </params>
 </feature-spec>
1 feature ID parameter, cannot be null and must be explicitly initialized in the configuration
2 parameter will be initialized to bb unless explicitly set to a different value by the user;
3 has no default and may be left uninitialized in the configuration;
4 parameter must be explicitly initialized by the user.

8.1.3. Features in configuration

Here is an example of how features can be used in a configuration.

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
   <config>
     <feature spec="feature1">
       <param name="a" value="a1"/>
       <param name="b" value="b1"/>
       <param name="d" value="d1"/>
     </feature>
     <feature spec="feature1">
       <param name="a" value="a2"/>
       <param name="d" value="d2"/>
     </feature>
     <feature spec="feature1">
       <param name="a" value="a3"/>
       <param name="c" value="c3"/>
       <param name="d" value="d3"/>
     </feature>
   </config>
 </feature-pack>

In this example, the config element describes the default configuration which will be generated when fp1 is installed (unless it is explicitly customized by the user), which includes three features of the same spec. When the final configuration is generated, the features will be processed in the order they appear in the config element.

8.1.4. Feature references

There are cases when a value range of a parameter of one feature spec is defined by a set of existing in the configuration model values of an ID parameter of another feature spec. In other words, a feature spec may declare certain parameters as references to ID parameters of another feature spec. (In a relational database, this would be a foreign key reference).

In a feature spec a simple feature reference would look like this

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP"/>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p"/>
   </params>
 </feature-spec>

Attribute feature of element ref contains the name of the referenced feature-spec. Note that we have not provided which parameter of featureC references the ID parameter of featureP. This example also demonstrates the default (implicit) reference parameter mapping.

The default reference parameter mapping rule is based on the expectation that the feature spec declaring the reference includes parameters with the names matching the ID parameter names of the referenced feature spec.

So the example above will work if one of the following statements is true:

  1. featureP declares parameter p and it is its only feature-id parameter;

  2. featureP declares parameter name and it is its only feature-id parameter;

  3. featureP declares parameters name and p as its feature-id parameters and has not other feature-id parameters.

Table 1. The complete set of a feature reference declaration attributes
Attribute name Required Default Description

dependency

false

null (current feature-pack or its dependencies)

The feature-pack dependency name the referenced feature spec belongs to.

feature

true

null

The name of the referenced feature spec.

name

false

The value of the feature attribute

Unique feature reference name.

nillable

false

false

Whether a reference is nillable or not.

include

false

false

Whether the referenced feature should automatically be included into the config model if it was not explicitly configured.

Non-default reference parameter mapping

Instead of relying on the default reference parameter mapping rule, it is also possible to map the parameters in the reference declaration explicitly. The example below will correspond to the statement 1. from the example above.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP">
       <param name="p" maps-to="p"/>
     </ref>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p"/>
   </params>
 </feature-spec>

Now let’s suppose that featureP ID parameter is in fact name but we still want to use parameter p as the reference to featureP.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP">
       <param name="p" maps-to="name"/>
     </ref>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p"/>
   </params>
 </feature-spec>

If featureP had more than one ID parameter, e.g.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
   <params>
     <param name="id1" feature-id="true"/>
     <param name="id2" feature-id="true"/>
   </params>
 </feature-spec>

Then the reference parameter mapping in featureC could look like:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP">
       <param name="p1" maps-to="id1"/>
       <param name="p2" maps-to="id2"/>
     </ref>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p1"/>
     <param name="p2"/>
   </params>
 </feature-spec>
Nillable feature references
Feature reference resolves to null if one of the feature reference parameters is null.
If a reference resolves to null and its not marked as nillable in the feature spec, the provisioning will fail with an error. Here is an example of a nillable reference declaration:
 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP" nillable="true">
       <param name="p1" maps-to="id1"/>
       <param name="p2" maps-to="id2"/>
     </ref>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p1" nillable="true"/>
     <param name="p2"/>
   </params>
 </feature-spec>
External feature references

A feature may reference a feature from another feature-pack. The other feature-pack must be a (direct or transitive) dependency of the feature-pack the referencing feature belongs to.

Unless the feature-pack of the referenced feature has not been explicitly specified, the mechanism will navigate the dependency tree of the feature-pack of the referencing feature and the first feature-pack containing a feature spec with the referenced feature spec name will be selected as the target.

Otherwise, the target feature-pack can be specified using dependency attribute of the feature reference declaration. The value of dependency attribute must match the value of origin element of the feature-pack dependency (the referenced feature spec belongs to) declaration in the feature-pack.xml file of the referencing feature spec.

For example, suppose, feature-pack fp1 depends on feature-pack fp2.

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
    <dependencies>
        <dependency location="fp2@maven(org.jboss.universe:community-universe):2#2.0.0">
            <origin>fp2-dep</origin>
        </dependency>
    </dependencies>
 </feature-pack>

fp2 includes feature spec featureP.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
   <params>
     <param name="p" feature-id="true"/>
   </params>
 </feature-spec>

And fp1 includes feature spec featureC which declares a reference to featureP

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref dependency="fp2-dep" feature="featureP"/>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p"/>
   </params>
 </feature-spec>
It is expected that in most cases dependency attribute of element ref will not have to be used.
Implicit feature reference parameter initialization

Let’s suppose we have a parent-child relationship between two feature specs, e.g.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
   <params>
     <param name="parentId" feature-id="true"/>
   </params>
 </feature-spec>
 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP"/>
   </refs>
   <params>
     <param name="childId" feature-id="true"/>
     <param name="parentId"/>
   </params>
 </feature-spec>

If we were to add features of these specs to a config, it could look like this

 <config>
   <feature spec="featureP">
     <param name="parentId" value="parent1"/>
   </feature>
   <feature spec="featureC">
     <param name="childId" value="child1"/>
     <param name="parentId" value="parent1"/>
   </feature>
 </config>

This approach is very verbose, the value for parentId parameter is set on every feature. There is a more compact way of expressing the same configuration using nesting, e.g.

 <config>
   <feature spec="featureP">
     <param name="parentId" value="parent1"/>
     <feature spec="featureC">
       <param name="childId" value="child1"/>
     </feature>
   </feature>
 </config>

Here, parentId parameter is initialized only once for the parent feature. parentId of the child feature will be implicitly initialized to the value of parentId of the parent.

When a feature is nested, the tool will look in the feature spec of the nested feature for a reference declaration with the name matching the outer feature spec and, if it is found, the tool will resolve the reference parameter mappings and will initialize the parameters of the child feature referencing the parent.

In case the reference name is different from the referenced feature spec name, i.e. it was explicitly set in the reference spec, e.g.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref feature="featureP" name="parent"/>
   </refs>
   <params>
     <param name="childId" feature-id="true"/>
     <param name="parentId"/>
   </params>
 </feature-spec>

Then the name of the reference has to be explicitly specified when the child feature is nested using the parent-ref attribute, e.g.

 <config>
   <feature spec="featureP">
     <param name="parentId" value="parent1"/>
     <feature spec="featureC" parent-ref="parent">
       <param name="childId" value="child1"/>
     </feature>
   </feature>
 </config>
Implicit inclusion of referenced features into the configuration

It is possible to configure feature references so that when the resolved referenced feature ID is not found in the configuration model, instead of failing with the referential integrity constraint error, implicitly include the referenced feature into the configuration model initializing it with its default values. This is done by simply setting include attribute of the feature reference declaration to true.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
   <refs>
     <ref dependency="fp2-dep" feature="featureP" include="true"/>
   </refs>
   <params>
     <param name="name" feature-id="true"/>
     <param name="p"/>
   </params>
 </feature-spec>
Multiple references to the same feature spec

Suppose a feature needs to declare more than one reference to the same feature spec. For example let’s model a chain using a feature spec called link. link must have an ID parameter, let’s call it id. Then it has to include a parameter to reference the previous link and another parameter to reference the next link in the chain. The following, although looking right from the parameter mapping perspective, will clearly not work

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="link">
   <refs>
     <ref feature="link">
       <param name="prev-id" maps-to="id"/>
     </ref>
     <ref feature="link">
       <param name="next-id" maps-to="id"/>
     </ref>
   </refs>
   <params>
     <param name="id" feature-id="true"/>
     <param name="prev-id" nillable="true"/>
     <param name="next-id" nillable="true"/>
   </params>
 </feature-spec>

Feature references must have a unique name. In this case, both reference names are set to link and the provisioning tool will fail to process this spec. To workaround the error explicit names have to be assigned to the reference declarations, e.g.

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="link">
   <refs>
     <ref name="prev" feature="link">
       <param name="prev-id" maps-to="id"/>
     </ref>
     <ref name="next" feature="link">
       <param name="next-id" maps-to="id"/>
     </ref>
   </refs>
   <params>
     <param name="id" feature-id="true"/>
     <param name="prev-id" nillable="true"/>
     <param name="next-id" nillable="true"/>
   </params>
 </feature-spec>
Processing of features with references

One of the responsibilities of the provisioning tool is to order the features from the resolved configuration model for processing by the provisioning plugins that generate the final installation configuration files. While the general rule is to preserve the order in which the features where added to the configuration model, when feature A references feature B, feature B will get the priority and will be processed by the provisioning plugins before feature A to not break the referential integrity of the generated model (if it is significant for the consuming plugin).

Circular feature references

The provisioning mechanism is capable of identifying circular references (circular reference graphs). It does not throw an error if a circular reference graphs is detected. The responsibility of the provisioning mechanism is to make sure the configuration model is valid and all the referential integrity constraints are satisfied. From this point of view circular references are not illegal.

The issue with circular references is the ordering of the features when configuration model is processed by the product specific plugins that generate the final configuration files. In some cases the order of the features will not be significant but in some cases it will be. So the rule is

When a circular reference graph is identified, the feature that was added to the configuration model first will be processed by the provisioning plugins first, the rest of the features from the graph will be processed respecting the references as usual.

8.1.5. Feature dependencies

While references are a kind of dependencies, they require parameters in the spec of the feature declaring the reference to identify the target. Unlike references, feature dependencies do not use parameters to specify the target. Instead the dependency is declared by specifying the ID of the target feature directly.

Feature spec dependencies

Feature dependencies can be declared in the feature spec and/or on the feature itself. Here is an example of a dependency declaration in the feature spec:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature1">
   <deps>
     <dep feature-id="feature2:id=123"/>
   </deps>
   <params>
     <param name="name" feature-id="true"/>
   </params>
 </feature-spec>

Now all the features of spec feature1 will depend on the feature with ID feature2:id=123.

Feature config dependencies

And here is how a feature dependency can be declared on a specific feature:

 <feature spec="feature1">
   <deps>
     <dep feature-id="feature3:id=789"/>
   </deps>
   <param name="name" value="abc"/>
 </feature>

Now feature feature1:name=abc depends on feature feature2:id=123 (inherited dependency from the spec) and feature feature3:id=789.

External feature dependencies

It is allowed to delcalre dependencies on features that come from other feature-packs. If the specs of those features come from feature-packs that appear to be dependencies of the feature-pack the feature dependencies are configured in then those feature specs will most probably be located by the mechanism automatically (by navigating the feature-pack dependency tree). The mechanism might need some help resolving the specs of the dependencies only if they belong to a feature-pack that doesn’t appear to be a dependency of the feature-pack where the dependencies are defined or if there are multiple feature specs with the same name in the feature-pack dependency hierarchy and it’s not obvious which one is targeted by the dependency.

the feature spec resolution mechanism will pick the first feature spec with the matching name met while navigating the feature-pack dependency tree.

There is a way though to specify the origin of the feature spec used in the dependency. If feature3 spec was from another feature-pack than feature1 spec then to be precise we could have added the origin of feature3 spec to the dependency declaration. Assuming that the feature-pack feature1 spec belongs to declared a dependecy named fp2 on the feature-pack feature3 spec belongs to, the dependency declaration would look like this:

 <feature spec="feature1">
   <deps>
     <dep feature-id="feature3:id=789" dependency="fp2"/>
   </deps>
   <param name="name" value="abc"/>
 </feature>
Implicit inclusion of feature dependencies

Like references, dependencies also support include attribute. If the dependency is declared with include=true, the target of the dependency will implicitly be included into the configuration unless it is already present. Here is an example of an implicitly included feature dependency:

 <feature spec="feature1">
   <deps>
     <dep feature-id="feature3:id=789" include="true"/>
   </deps>
   <param name="name" value="abc"/>
 </feature>

8.1.6. Feature capabilities

In the actual provisioned installation, the components that are represented as features in the configuration model may provide certain runtime capabilities that other components, also represented as features in the configuration model, may depend upon. There are two reasons why this may be important when resolving the configuration model for the installation to be provisioned:

  1. to make sure the configuration is consistent in a sense that the runtime requirements of its components are satisfied;

  2. to order the features in the configuration model for processing by the provisioning plugins based on their dependencies and runtime requirements.

Capabilities are represented as strings with a dot serving as a word separator. Here is an example of a feature spec providing a capability:

 <feature-spec name="interface" xmlns="urn:jboss:galleon:feature-spec:1.0">
   <provides>
     <capability name="org.wildfly.network.interface"/>
   </provides>
   <params>
     <param name="name" feature-id="true"/>
     <param name="inet-address"/>
   </params>
 </feature-spec>

And here is a feature spec that requires the capability provided above

 <feature-spec name="socket-binding" xmlns="urn:jboss:galleon:feature-spec:1.0">
   <requires>
     <capability name="org.wildfly.network.interface"/>
   </requires>
   <params>
     <param name="name" feature-id="true"/>
     <param name="port"/>
   </params>
 </feature-spec>
In the examples above the capabilities were configured using constant values. This type of a capability is called a static capability. As a consequence, all the features of spec interface will provide the same capability org.wildfly.network.interface. And all the features of spec socket-binding will require the same capabality org.wildfly.network.interface.
Dynamic capabilities

It is also possible, however, to provide and/or require a capability that depends on the parameters of a specific feature. Dynamic capabilities are following the same dot-separated string format but include feature parameter names prefixed with $ character. The examples above could be enhanced with dynamic capabilities as

 <feature-spec name="interface" xmlns="urn:jboss:galleon:feature-spec:1.0">
   <provides>
     <capability name="org.wildfly.network.interface.$name"/>
   </provides>
   <params>
     <param name="name" feature-id="true"/>
     <param name="inet-address" nillable="true"/>
   </params>
 </feature-spec>
 <feature-spec name="socket-binding" xmlns="urn:jboss:galleon:feature-spec:1.0">
   <requires>
     <capability name="org.wildfly.network.interface.$interface"/>
   </requires>
   <params>
     <param name="name" feature-id="true"/>
     <param name="interface"/>
     <param name="port" nillable="true"/>
   </params>
 </feature-spec>

Let’s see how it will look like in an actual configuration

 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
   <config>
     <feature spec="interface">
       <param name="name" value="public"/>
     </feature>
     <feature spec="interface">
       <param name="name" value="secure"/>
     </feature>
     <feature spec="socket-binding">
       <param name="name" value="http"/>
       <param name="interface" value="public"/>
     </feature>
     <feature spec="socket-binding">
       <param name="name" value="https"/>
       <param name="interface" value="secure"/>
     </feature>
   </config>
 </feature-pack>

In the example above feature interface:name=public provides capability org.wildfly.network.interface.public which is required by feature socket-binding:name=http. And feature interface:name=secure provides capability org.wildfly.network.interface.secure which is required by feature socket-binding:name=https.

More than one parameter could be used in a capability name. The parameters may appear in any part of the name, not necessarily at the end as in the example. The only rule is to use dot as a separator for the parameters and the static parts of the name.

8.1.7. Feature package dependencies

Feature specs representing configurable components of the installation may include dependencies on feature-pack packages that contain certain binary content (e.g. JAR files) of those installation components. So that, when a feature is included into configuration, the packages the feature will require at runtime will automatically be added to the list of the installed packages.

Package dependencies are configured under packages element of the feature spec which is equivalent to the dependencies element of the package spec metadata. Here is an example

 <feature-spec name="feature1" xmlns="urn:jboss:galleon:feature-spec:1.0">
   <params>
     <param name="id" feature-id="true"/>
   </params>
   <packages>
     <package name="p1"/>
     <package name="p2" optional="true"/>
     <origin name="another-feature-pack">
       <package name="p2"/>
       <package name="p3" optional="true"/>
     </origin>
   </packages>
 </feature-spec>

In this case, any feature of spec feature1 will have:

  • a required dependency on package p1;

  • an optional dependency on package p2;

  • a required dependency on package p2 from the feature-pack dependency refered to as another-feature-pack;

  • an optional dependency on package p3 from the feature-pack dependency refered to as another-feature-pack.

8.1.8. Feature annotations

Feature specs may include a list of annotations. The provisioning mechanism includes a few pre-defined annotations. Product-specific annotations are also supported, they are simply parsed and attached to feature specs and are available to the provisioning plugins for processing. Here is an example of an annotated feature spec:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature1">
   <annotation name="name1">
     <elem name="elem1" value="value1"/>
   </annotation>
   <annotation name="name2">
     <elem name="elem1" value="value1"/>
     <elem name="elem1" value="value1"/>
   </annotation>
   <params>
     <param name="id" feature-id="true"/>
   </params>
 </feature-spec>

8.2. Feature groups

A feature spec represents a minimal configuration unit. When a configuration model reaches a certain level of complexity though, using and manipulating features to define the final configuration may become impractical. Feature groups allow to group a set of features that represent a certain part of the configuration together and then include them all into the final configuration as a group. For example

 <feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">
   <feature spec="feature1">
     <param name="id" value="a1"/>
     <feature spec="feature2">
       <param name="id" value="b1"/>
     </feature>
   </feature>
   <feature spec="feature3">
     <param name="id" value="c1"/>
   </feature>
 </feature-group-spec>
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
   <config>
     <feature-group name="group1"/>
   </config>
 </feature-pack>

First, we defined a feature group named group1 which includes three features.

The name of the group must be unique in the scope of the feature-pack.

Feature groups are saved in the feature-pack’s feature_groups directory in XML files named after the feature groups (group1.xml in this example).

Then in the default configuration of the feature-pack we simply included group1, which is equivalent to including the mentioned three features into the config directly.

Besides features, feature groups may also include other feature groups. Continuing the example above:

 <feature-group-spec name="group2" xmlns="urn:jboss:galleon:feature-group:1.0">
   <feature-group name="group1"/>
   <feature spec="feature4">
     <param name="id" value="d1"/>
   </feature>
 </feature-group-spec>
 <feature-pack xmlns="urn:jboss:galleon:feature-pack:1.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
   <config>
     <feature-group name="group2"/>
   </config>
 </feature-pack>

The final configuration will now include all the four features.

The order of the features in the resolved configuration will reflect the order in which the features were included into the configuration but also respecting the feature references and the dependencies, i.e.
  1. feature1:id=a1

  2. feature2:id=b1

  3. feature3:id=c1

  4. feature4:id=d1

8.2.1. Including customized feature groups

When a feature group is included (into another feature group or a config element of a feature-pack configuration) the set of its features can be customized. There are two main kinds of customizations that are allowed when including a feature group:

When a feature group is included into another feature group or a config element, the list of its direct entries (features and feature groups) defined by the feature group spec cannot be extended by applying customizations. There is a way though to extend the feature set of the included feature group indirectly.

All the feature group customizations are expressed in the body of feature-group XML element.

Overwriting parameters of features from a feature group

The configuration of a feature can be customized by adding include element with feature-id attribute targeting its ID to the body of the feature-group element. E.g. suppose this is our feature spec:

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="feature1">
  <params>
    <param name="a" feature-id="true"/>
    <param name="b" default="bb"/>
    <param name="c" nillable="true"/>
    <param name="d"/>
  </params>
</feature-spec>

This is our feature group spec:

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">
  <feature spec="feature1">
    <param name="a" value="a1"/>
    <param name="c" value="group1"/>
    <param name="d" value="group1"/>
  </feature>
</feature-group-spec>

And this is our config:

<config>
  <feature-group name="group1">
    <include feature-id="feature1:a=a1">
      <param name="d" value="config"/>
    </include>
  </feature-group>
</config>

The resolved configuration will consist of one feature with the following configuration

Feature spec a b c d

feature1

a1

bb

group1

config

Let’s now suppose that we have two feature specs with a parent-child relationship

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
  <params>
    <param name="parent" feature-id="true"/>
  </params>
</feature-spec>
<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
  <refs>
    <ref feature="featureP">
  </refs>
  <params>
    <param name="parent" feature-id="true"/>
    <param name="child" feature-id="true"/>
    <param name="a"/>
    <param name="b"/>
  </params>
</feature-spec>

The group is defined as

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">
  <feature spec="featureP">
    <param name="parent" value="p1"/>
    <feature spec="featureC">
      <param name="child" value="c1"/>
      <param name="a" value="group1"/>
      <param name="b" value="group1"/>
    </feature>
  </feature>
</feature-group-spec>

And we want to customize the child feature when including group1 into the config.

<config>
  <feature-group name="group1">
    <include feature-id="featureC:parent=p1,child=c1">
      <param name="b" value="config"/>
    </include>
  </feature-group>
</config>

The resolved configuration will contain two features:

Feature spec parent

featureP

p1

Feature spec child a b

featureC

p1

c1

group1

Excluding features from a group by IDs

When a feature group is included into another group or a config, certain features can be excluded from the included feature set by simply specifying their IDs.

Suppose, we have defined the following group:

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="feature1">
    <param name="id" value="a1"/>
  </feature>
  <feature spec="feature1">
    <param name="id" value="a2"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b1"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b2"/>
  </feature>

</feature-group-spec>

Here is how feature1:id=a1 and feature2:id=b1 can be excluded when group1 is added a configuration:

<config>
  <feature-group name="group1">
    <exclude feature-id="feature1:id=a1"/>
    <exclude feature-id="feature2:id=b1"/>
  </feature-group>
</config>

The config will include feature1:id=a2 and feature2:id=b2.

Excluding features from a group by specs

When a feature group is included into another group or a config, all the features of a specific feature spec can be excluded from the included feature set by simply specifying the feature spec.

Suppose, we have the following group spec:

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="feature1">
    <param name="id" value="a1"/>
  </feature>
  <feature spec="feature1">
    <param name="id" value="a2"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b1"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b2"/>
  </feature>

</feature-group-spec>

Here is how all the feature of spec feature1 can be excluded:

<config>
  <feature-group name="group1">
    <exclude spec="feature1"/>
  </feature-group>
</config>

The config will include feature2:id=b1 and feature2:id=b2.

Picking features from a group by IDs

When a feature group is included into another feature group or a config, by default all the features it contains are included into the configuration. It is possible though to pick which ones exactly should be included.

Suppose, we have the following group spec:

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="feature1">
    <param name="id" value="a1"/>
  </feature>
  <feature spec="feature1">
    <param name="id" value="a2"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b1"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b2"/>
  </feature>

</feature-group-spec>

Here is how feature1:id=a1 and feature2:id=b1 can be picked into the configuration:

<config>
  <feature-group name="group1" inherit-features="false">
    <include feature-id="feature1:id=a1"/>
    <include feature-id="feature2:id=b1"/>
  </feature-group>
</config>
inherit-features attribute indicates whether the whole feature set of the group should be included into the config or not. If this attribute is not specified, its value is assumed to be true.

Then include elements are picking the features that need to be included into the configuration.

The config will include feature1:id=a1 and feature2:id=b1.

include elements can also be used to pick features from the excluded feature specs. The config below is equivalent to the config above.
<config>
  <feature-group name="group1" inherit-features="true">
    <exclude spec="feature1"/>
    <exclude spec="feature2"/>
    <include feature-id="feature1:id=a1"/>
    <include feature-id="feature2:id=b1"/>
  </feature-group>
</config>
Including features of specific feature specs from a group

When a feature group is included into another group or a config, by default all the features it contains are added to the configuration. There is a way though to pick features of which feature specs should be included.

Suppose, we have the following group spec:

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="feature1">
    <param name="id" value="a1"/>
  </feature>
  <feature spec="feature1">
    <param name="id" value="a2"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b1"/>
  </feature>
  <feature spec="feature2">
    <param name="id" value="b2"/>
  </feature>

</feature-group-spec>

Here is how all the features of spec feature1 can be included into the config:

<config>
  <feature-group name="group1" inherit-features="false">
    <include spec="feature1"/>
  </feature-group>
</config>
inherit-features attribute indicates whether the whole feature set of the group should be included into the config or not. If this attribute is not specified, its value is assumed to be true.

Then include element is specifying the feature spec features of which should be included into the config.

The config will include feature1:id=a1 and feature1:id=a2.

<exclude feature-id="xxx"/> elements can be used to exclude certain features from the feature set of the included feature spec.
Extending feature groups by including features indirectly

While the list of the feature group spec enrties (features and feature groups) is fixed and cannot be extended, new features and feature groups can be added as children of the features that have already been included into the feature group. Let’s edit the example from the previous paragraph to demonstrate that. The feature specs will remain the same.

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
  <params>
    <param name="parent" feature-id="true"/>
  </params>
</feature-spec>
<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureC">
  <refs>
    <ref feature="featureP">
  </refs>
  <params>
    <param name="parent" feature-id="true"/>
    <param name="child" feature-id="true"/>
    <param name="a"/>
    <param name="b"/>
  </params>
</feature-spec>

The group definition will now include only parent feature

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">
  <feature spec="featureP">
    <param name="parent" value="p1"/>
  </feature>
</feature-group-spec>

And now we will include the child feature as a configuration customization of the parent feature.

<config>
  <feature-group name="group1">
    <include feature-id="featureP:parent=p1">
      <feature spec="featureC">
        <param name="child" value="c1"/>
        <param name="a" value="config"/>
        <param name="b" value="config"/>
      </feature>
    </include>
  </feature-group>
</config>

The resolved configuration will contain both features:

Feature spec parent

featureP

p1

Feature spec parent child a b

featureC

p1

c1

config

config

8.2.2. Including features and feature groups from other feature-packs

Feature groups, as well as config elements in feature-pack.xml, may include features and feature groups from other feature-packs. If those feature-packs appear to be dependencies (direct or transitive) of the feature-pack that uses their feature specs and groups in its configuration, the mechanism will most probably be able to resolve the origins of those feature specs and groups by navigating the feature-pack dependency tree.

However, if there are multiple feature specs or feature groups with the same name in the feature-pack dependency hierarchy, it may become confusing which feature spec or feature group was meant as the target. In this case, the origin of those feature specs and feature groups can be specified with element origin and its attribute 'name' referencing the corresponding feature-pack dependency declared in the feature-pack.xml. For example

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="feature1">
    <param name="id" value="a1"/>
  </feature>

  <origin name="another-feature-pack">
    <feature-group name="group2"/>
    <feature spec="feature2">
      <param name="id" value="b1"/>
    </feature>
  </origin>

  <feature-group name="group3"/>

  <origin name="another-feature-pack">
    <feature-group name="group3"/>
  </origin>

</feature-group-spec>

In this case, the order of the features in the resolved feature group will be

  1. feature1:id=a1 from the local feature-pack;

  2. features from group2 from another-feature-pack;

  3. feature2:id=b1 from another-feature-pack;

  4. features from group3 from the local feature-pack;

  5. features from group3 from another-feature-pack.

8.2.3. Nesting feature groups under features

It was mentioned in an earlier chapter that a feature may nest other features that reference it. It is also possible to nest a feature group under a feature with the condition that all the features included directly into the definition of the feature group reference the same parent feature.

For example, suppose we have a parent feature spec featureP and child feature specs featureA and featureB:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureP">
   <params>
     <param name="parent" feature-id="true"/>
   </params>
 </feature-spec>
 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureA">
   <refs>
     <ref feature="featureP"/>
   </refs>
   <params>
     <param name="parent" feature-id="true"/>
     <param name="a" feature-id="true"/>
   </params>
 </feature-spec>
 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureB">
   <refs>
     <ref feature="featureP"/>
   </refs>
   <params>
     <param name="parent" feature-id="true"/>
     <param name="b" feature-id="true"/>
   </params>
 </feature-spec>

Now let’s suppose that there is a group which includes features of featureA and featureB specs.

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="featureA">
    <param name="a" value="a1"/>
  </feature>
  <feature spec="featureB">
    <param name="id" value="b1"/>
  </feature>

</feature-group-spec>

This group can be nested under any instance of featureP and parameter parent of the features in the group will implicitly be initialized to the value of parameter parent of the outer featureP instance.

<config>
  <feature spec="featureP">
    <param name="parent" value="p1"/>
    <feature-group name="group1"/>
  </feature>
  <feature spec="featureP">
    <param name="parent" value="p2"/>
    <feature-group name="group1"/>
  </feature>
</config>

The resulting config will include:

  1. featureP:parent=p1;

  2. featureP:parent=p2;

  3. featureA:parent=p1,a=a1;

  4. featureA:parent=p2,a=a1;

  5. featureB:parent=p1,b=b1;

  6. featureB:parent=p2,b=b1.

8.2.4. Merging feature groups

There could be a situation when the same feature group is brought into the config as a dependency of a few other feature groups. Which means its basic feature set is included into the final configuration multiple times but, taking into account possible customizations, each time it might be slightly different.

In that case the feature configurations will be merged. The features that are included later in the config will overwrite the common parameters of the corresponding features included earlier. But they will not completely replace the feature configurations that were added earlier.

For example, suppose we have these feature specs:

 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureA">
   <params>
     <param name="name" feature-id="true"/>
     <param name="p1" default="feature-spec"/>
     <param name="p2" default="feature-spec"/>
     <param name="p3" default="feature-spec"/>
   </params>
 </feature-spec>
 <feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="featureB">
   <params>
     <param name="name" feature-id="true"/>
     <param name="p1" default="feature-spec"/>
     <param name="p2" default="feature-spec"/>
     <param name="p3" default="feature-spec"/>
   </params>
 </feature-spec>

and these feature groups

<feature-group-spec name="group1" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature spec="featureA">
    <param name="name" value="a1"/>
    <param name="p1" value="group1"/>
    <param name="p2" value="group1"/>
    <param name="p3" value="group1"/>
  </feature>
  <feature spec="featureA">
    <param name="name" value="a2"/>
  </feature>
  <feature spec="featureA">
    <param name="name" value="a3"/>
  </feature>
  <feature spec="featureB">
    <param name="name" value="b1"/>
    <param name="p1" value="gorup1"/>
    <param name="p2" value="group1"/>
    <param name="p3" value="group1"/>
  </feature>
  <feature spec="featureB">
    <param name="name" value="b2"/>
  </feature>

</feature-group-spec>
<feature-group-spec name="group2" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature-group name="group1">
    <include feature-id="featureA:name="a1">
      <param name="p1" value="group2"/>
      <param name="p2" value="group2"/>
    </feature>
    <exclude feature-id="featureA:name=a3"/>
    <include feature-id="featureB:name="b1">
      <param name="p2" value="group2"/>
    </feature>
    <exclude feature-id="featureB:name=b2"/>
  </feature-group>

</feature-group-spec>
<feature-group-spec name="group3" xmlns="urn:jboss:galleon:feature-group:1.0">

  <feature-group name="group1">
    <include feature-id="featureA:name="a1">
      <param name="p1" value="group3"/>
    </feature>
    <exclude feature-id="featureA:name=a2"/>
    <include feature-id="featureB:name="b1">
      <param name="p3" value="group3"/>
    </feature>
    <exclude feature-id="featureB:name=b2"/>
  </feature-group>

</feature-group-spec>

Now this configuration

<config>
  <feature-group name="group2"/>
  <feature-group name="group3"/>
</config>

will contain

Feature spec name p1 p2 p3

featureA

a1

group3

group2

group1

featureA

a2

feature-spec

feature-spec

feature-spec

featureA

a3

feature-spec

feature-spec

feature-spec

featureB

b1

group1

group2

group3

9. Provisioned installation configuration

9.1. Configuration model attributes

Configuration models are described in feature-pack.xml file using config elements. feature-pack.xml file may contain zero, one or more config elements. Each configuration may include the following optional attributes:

  • name - the name of the configuration;

  • model - the name of the configuration model.

In XML it could look like this (the content of the config elements has been left out as not important in this example):

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
  <config>
    <!-- anonymous config -->
  </config>

  <config name="config1">
    <!-- named config -->
  </config>

  <config model="model1">
    <!-- model1 model-only config -->
  </config>

  <config model="model1" name="config1">
    <!-- named model1 config -->
  </config>

</feature-pack>

name and model attributes are optional, which means it is well possible to define a configuration w/o those attributes. This kind of configuration is called anonymous. A feature pack may define zero, one or more anonymous configs.

name and model attributes serve as an identity of the configuration. They are essential when customizing and merging configurations.

If a configuration is associated only with a name (and no model) then only the name will be used as the identity of the configuration.

If a configuration is associated with a name and a model then a combination of the name and the model will be used as the identity of the configuration.

In the example above configuration named config1 and configuration model1:config1 are two unrelated configurations.

When a feature-pack is installed, by default all the configurations defined in its feature-pack.xml are installed. Users may explicitly specify though which configurations should the final distribution include and customize those and/or provide their own custom configurations.

9.2. Excluding default configs from the installation

To be able to exclude a configuration, it needs to be identifiable. I.e. it must have an identity in the form of a name or a model:name combination. If a config doesn’t have a name it still can be excluded but only altogether with the other configs like this

<installation xmlns="urn:jboss:galleon:provisioning:1.0">
    <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">

        <default-configs inherit="false"/>

    </feature-pack>
</installation>

inherit="false" attribute indicates that none of the configs should be included into the distribution by default. If the attribute is not present, its value is assumed to be true.

feature-pack element in the example above could as well appear under dependecies element of feature-pack.xml. Meaning the XML type of these elements are equivalent - they both describe a customized feature-pack. The examples below will be showing only feature-pack element.

If a configuration was given a name but not any model then it can be excluded by specifying its name, e.g.

<feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
    <default-configs>
        <exclude name="config1"/>
    </default-configs>
</feature-pack>

If a configuration was associated with a name and a model, both of them have to be specified, e.g.

<feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
    <default-configs>
        <exclude name="config1" model="model1"/>
    </default-configs>
</feature-pack>

In case there are multiple named configs that are associated with the same model, e.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:1.0"
                location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">

  <config model="model1" name="config1">
    <!-- config body -->
  </config>
  <config model="model1" name="config2">
    <!-- config body -->
  </config>

  <config model="model2" name="config1">
    <!-- config body -->
  </config>
  <config model="model2" name="config2">
    <!-- config body -->
  </config>

</feature-pack>

They can be excluded altogether by specifying the model name, e.g.

<installation xmlns="urn:jboss:galleon:provisioning:1.0">
    <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
        <default-configs>
            <exclude model="model1"/>
        </default-configs>
    </feature-pack>
</installation>

This installation will include configs model2:config1 and model2:config2.

9.3. Picking default configs into the installation

There are two scenarios when including a configuration could be necessary:

  1. when the configuration was excluded with <exclude model="model_name"/>;

  2. when inhertance of the default configurations was disabled with <default-configs inherit="false">.

The first one of course assumes that the configuration is associated with both name and model. It could look like this:

<feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
    <default-configs>
        <exclude model="model1"/>
        <include name="config1" model="model1"/>
    </default-configs>
</feature-pack>

The example above excludes all the model1 configurations except config1.

Here is an example for the second scenario

<feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
    <default-configs inherit="false">
        <include name="config1"/>
        <include name="config1" model="model1"/>
    </default-configs>
</feature-pack>

The example above picks only config1 and model1:config1 from all the default configurations to be included into the distribution.

It is also possible to include configurations of a specific model, e.g.

<feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
    <default-configs inherit="false">
        <include model="model1"/>
    </default-configs>
</feature-pack>

In this case, all the default configurations of model1 will be included into the distribution.

9.4. Configuration model merges

Configuration model merging is a way to integrate various products in the same installation. Lets suppose we want to add new product to an existing installation. Besides adding its filesystem content to the installation, normally, the configuration files of the existing installation will have to be adjusted to include the configuration of the product to be added.

In the provisioning terms, this scenarios can be described as:

  • there is a feature-pack (or a few) of the main installation (defining its FS content as well as the configurations);

  • there is the other product’s feature-pack defining its filesystem content and its default configuration that should be added to the main installation as part of its integration.

How exactly the configuration of the new product is integrated into the existing installation will depend on every specific case but there are a few basic ways it can happen:

  1. the product comes with its own standalone configuration which will not affect the existing installation configuration in any way;

  2. the product configuration will have to be added to the existing configuration of the installation;

  3. a combination of the two above: the standalone configuration and a piece of the configuration that needs to be added to the existing configuration of the installation.

The first one is simple: we just need to create two separate configurations: one for the main installation and one for the product we integrate.

In the second case, we need to actually merge the configurations from the existing installation and the feature-pack which represents the new product into a single confguration.

The third one effectively means that we’ve got multiple configuration models some of which should be merged and some should remain standalone. The tricky part is to identify which one is which. This is where the configuration name and model attributes are useful.

The provisioned installation may contain only one configuration model of a specific identity (which is the product of config name and model attribute values).

When the provisioning mechanism analysing the installation being provisioned discovers multiple configuration models with the same identity, it does not throw an error but merges the configuration models into a single one (which may still result in an error, of course, if the resulting model contains unsatisfied requirements).

9.4.1. Anonymous configurations

Anonymous configurations are associated with neither name nor model. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0">
  <config>
    <!-- config body -->
  </config>
</feature-pack>

Which means anonymous configurations have no identity. They cannot be customized and they are not merged.

Each anonymous configuration is a standalone configuration.

9.4.2. Named (name-only) configurations

The simplest way to provide an identity for a configuration is to give it a name. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config name="config1">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1"/>
      <param name="b" value="fp1"/>
    </feature>
    <feature spec="feature2">
      <param name="id" value="1"/>
    </feature>
  </config>
</feature-pack>

Now if another feature-pack provides a configuration with the same name, e.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config name="config1">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp2"/>
    </feature>
    <feature spec="feature3">
      <param name="id" value="1"/>
    </feature>
  </config>
</feature-pack>

And we include both of these feature packs into the same installation

<installation xmlns="urn:jboss:galleon:provisioning:1.0">
  <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
  <feature-pack location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
</installation>

The provisioned config1 will be the result of merging config1 from fp2 into config1 from fp1.

Which config overwrites which (assuming they contain common parts) depends on the order in which the feature-packs are listed under installation element.

Here is the content of the provisioned config1:

Feature spec origin Feature spec id a b

fp1@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature1

1

fp1

fp1

Feature spec origin Feature spec id

fp1@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature2

1

Feature spec origin Feature spec id b

fp2@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature1

1

fp2

Feature spec origin Feature spec id

fp2@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature3

1

The features of feature1 spec are not merged although they appear to have the same ID. The reason is that fp2 does not declare the dependency on fp1 and its feature specs are not available in fp2 configs. So this example assumes that both fp1 and fp2 include feature spec feature1.

Here is how feature-pack.xml of fp2 had to be written so that feature1 spec could be re-used in fp2 config:

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe)1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe)1#1.0.0.Final"/>
  </dependencies>
  <config name="config1">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp2"/>
    </feature>
    <feature spec="feature3">
      <param name="id" value="1"/>
    </feature>
  </config>
</feature-pack>

With this feature-pack configuration the resulting config1 will include the following features:

Feature spec origin Feature spec id a b

fp1@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature1

1

fp1

fp2

Feature spec origin Feature spec id

fp1@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature2

1

Feature spec origin Feature spec id

fp2@maven(org.jboss.universe:community-universe)1#1.0.0.Final

feature3

1

9.4.3. Named model configurations

There are a couple of reasons for adding model attribute to the configuration identity. One of them is to define the scope for values of attribute name. In this sense, a model could be thought of as a namespace. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config name="main" model="modelA">
    <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="a" value="fp1-modelA"/>
        <param name="b" value="fp1-modelA"/>
    </feature>
  </config>
  <config name="main" model="modelB">
    <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="a" value="fp1-modelB"/>
        <param name="b" value="fp1-modelB"/>
    </feature>
  </config>
</feature-pack>
<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp2-modelA"/>
    </feature>
  </config>
  <config name="main" model="modelB">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp2-modelB"/>
    </feature>
  </config>
</feature-pack>

Installing these two feature-packs (fp2 following fp1) will result in the following two configurations:

Config model Config name Feature spec origin Feature spec id a b

modelA

main

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelA

fp2-modelA

Config model Config name Feature spec origin Feature spec id a b

modelB

main

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelB

fp2-modelB

9.4.4. Model-only configurations

Model-only configurations are the ones associated with a specific model using model attribute of config element but are not associated with any name.

Model-only configurations are meant to be merged into other configurations. The provisioned installation will contain only anonymous or named configs but not the model-only ones.
A model-only configuration is merged into all the named configurations of the installation associated with the same model as the model-only configuration.
A model-only configuration will simply be ignored if the installation does not include any named configuration with the same model as the model-only configuration.

The idea behind the model-only configurations is to be able to define the base for a configuration of a specific model that every final configuration of that model should include. Model-only configs are always added into the configuration before the named model configs, i.e. the named configs will be added on top of the model-only ones and will overwrite them.

Here is an example:

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1-modelA"/>
      <param name="b" value="fp1-modelA"/>
    </feature>
  </config>
  <config name="main" model="modelB">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp1-modelB"/>
    </feature>
  </config>
</feature-pack>
<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp2-modelA"/>
    </feature>
  </config>
  <config name="test" model="modelA">
    <feature spec="feature2">
      <param name="id" value="1"/>
      <param name="a" value="fp2-modelA"/>
      <param name="b" value="fp2-modelA"/>
    </feature>
  </config>
  <config model="modelB">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp2-modelB"/>
      <param name="b" value="fp2-modelB"/>
    </feature>
  </config>
  <config name="test" model="modelB">
    <feature spec="feature2">
      <param name="id" value="1"/>
      <param name="a" value="fp2-modelB"/>
      <param name="b" value="fp2-modelB"/>
    </feature>
  </config>
</feature-pack>

Installing these two feature-packs will result in the following configurations:

Config model Config name Feature spec origin Feature spec id a b

modelA

main

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelA

fp2-modelA

Config model Config name Feature spec origin Feature spec id a b

modelA

test

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelA

fp1-modelA

modelA

test

fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature2

1

fp2-modelA

fp2-modelA

Config model Config name Feature spec origin Feature spec id a b

modelB

main

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp2-modelB

fp1-modelB

Config model Config name Feature spec origin Feature spec id a b

modelB

test

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp2-modelB

fp2-modelB

modelB

test

fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature2

1

fp2-modelB

fp2-modelB

Excluding model-only configurations with the exclude element

Normally, model-only configurations are not supposed to be explicitly excluded. If a user excludes all the named configs of a specific model, the model-only configs of that model will implicitly be ignored by the provisioning mechanism.

Configuration model designers are encouraged to design configurations in a way that model-only configurations represent essential configuration and don’t need to be excluded explicitly by users or should be excluded in exceptional cases.

In a previous chapter it was described how the default configurations could be excluded from the provisioned installation by specifying their model name. Here is an example once again

<installation xmlns="urn:jboss:galleon:provisioning:1.0">
    <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
        <default-configs>
            <exclude model="model1"/>
        </default-configs>
    </feature-pack>
</installation>

exclude element above does not affect the model-only configurations. It affects only the named configs. And in this specific example this fact will not make any difference on the result which is why, users shouldn’t care about it, since if the named configurations are excluded, the model-only configurations will automatically be ignored by the provisioning mechanism. Let’s look at an example where it makes a real difference.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1-modelA"/>
      <param name="b" value="fp1-modelA"/>
      <param name="c" value="fp1-modelA"/>
    </feature>
  </config>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp1-modelA-main"/>
    </feature>
  </config>
</feature-pack>
<feature-pack xmlns="urn:jboss:galleon:feature-pack:1.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="c" value="fp2-modelA-main"/>
    </feature>
  </config>
</feature-pack>

If we install these feature-packs the resulting config will contain

Feature spec origin Feature spec id a b c

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelA

fp1-modelA-main

fp2-modelA-main

If we exclude modelA like it was shown in the previous example in the declaration of the dependency on fp1, i.e.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
      <default-configs>
        <exclude model="modelA"/>
      </default-configs>
    </dependency>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="c" value="fp2-modelA-main"/>
    </feature>
  </config>
</feature-pack>

If we install fp2, the provisioned configuration will contain

Feature spec origin Feature spec id a b c

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp1-modelA

fp1-modelA

fp2-modelA-main

The model-only configuration from fp1 is still effective because it is considered being essential for any named configuration of modelA. In case it still has to be excluded from the provisioned configuration you can add named-only-models="false" attribute to exclude element, e.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
      <default-configs>
        <exclude model="modelA" named-only-models="false"/>
      </default-configs>
    </dependency>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="c" value="fp2-modelA-main"/>
    </feature>
  </config>
</feature-pack>

exclude element above affects both named and model-only configurations of modelA from feature-pack fp1.

named-only-models attribute is optional and if abscent its value is assumed to be true.

The provisioned configuration of fp2 will now contain

Feature spec origin Feature spec id c

org.jboss.pm.test:fp1:1.0.0.Final

feature1

1

fp2-modelA-main

Disabling inheritance of the model-only configurations

In an earlier chapter it was shown how the default configurations of a feature-pack could be suppressed. Let’s now include a model-only configuration in the example.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1-modelA"/>
      <param name="b" value="fp1-modelA"/>
      <param name="c" value="fp1-modelA"/>
    </feature>
  </config>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="b" value="fp1-modelA-main"/>
    </feature>
  </config>
</feature-pack>
<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
      <default-configs inherit="false"/>
    </dependency>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="c" value="fp2-modelA-main"/>
    </feature>
  </config>
</feature-pack>

With inherit="false" attribute of default-configs element we indicated that the default configs of fp1 should not be included into the distribution provisioned from fp2. But it does not affect the model-only configs. So the model-only modelA configuration will still be effective in fp2.

inherit-unnamed-models attributes of default-configs element controls whether the model-only configs are inherited or not. The attribute is optional and if not present, its value is assumed to be true.

Here is an example that disables the inheritance of all the anonymous, named and model-only configs:

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
      <default-configs inherit="false" inherit-unnamed-models="false"/>
    </dependency>
  </dependencies>
  <config name="main" model="modelA">
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="c" value="fp2-modelA-main"/>
    </feature>
  </config>
</feature-pack>

The provisioned configuration of fp2 will now contain

Feature spec origin Feature spec id c

fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final

feature1

1

fp2-modelA-main

9.5. Content of config element

config element is basically an extended version of feature-group element. Meaning that everything that is allowed in the body of feature-group (which is feature, feature-group and origin elements for explicit dependency origins) is allowed in config element.

Besides that config element supports already mentioned in an earlier chapter the config attributes and props element.

When a config element appears in a feature-pack.xml file or as a child of installation element in the provisioning configuration of the installation, it represents all the configurations with the matching identity from all the feature-packs dependency hierarchy up to the current point merged into one configuration model.

E.g. if feature-pack fp1 depends on feature-pack fp2 which includes configuration model m1 named n1. Element config with attributes model="m1" name="n1" added to fp1 will represent the corresponding configuration from fp2 (unless the configuration inheritance was explicitly disabled in fp1), i.e. the content of configuration m1:n1 from fp2 may be manipulated in config element in fp1 by excluding certain features or overwriting their parameters.

The same applies to config elements under installation element. If installation includes feature-packs fp3 and fp4, both of which include configs m1:n1, config element with attributes model="m1" name="n1" added under the installation element will represent the result of merging configs m1:n1 from feature-packs fp3 and fp4.

9.5.1. Configuration properties

props element allows to attach various properties to the configuration that can be meaningful to the provisioning plugins processing the configuration. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config name="main" model="modelA">
    <props>
      <prop name="save-to-file" value="model-a.xml"/>
      <prop name="other" value="thing"/>
    </props>
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1-modelA"/>
    </feature>
  </config>
</feature-pack>

9.5.2. Overwriting configuration properties during inclusion

When a default configuration is included, its properties can be overwritten, e.g.

<installation xmlns="urn:jboss:galleon:provisioning:1.0">
    <feature-pack location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
        <default-configs>
            <include name="main" model="modelA">
              <props>
                <prop name="save-to-file" value="main-model-a.xml"/>
              </props>
            </include>
        </default-configs>
    </feature-pack>
</installation>

The resolved configuration will include the following properties:

  • save-to-file=main-model-a.xml;

  • other=thing.

9.5.3. Overwriting configuration properties during merging

When the configurations are merged, their properties are also merged. The configuration that is included later into the installation overwrites the properties of the configuration which was added earlier. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config model="modelA">
    <props>
      <prop name="save-to-file" value="model-a.xml"/>
      <prop name="other" value="thing"/>
    </props>
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp1-modelA"/>
    </feature>
  </config>
</feature-pack>
<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <dependencies>
    <dependency location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
  </dependencies>
  <config name="main" model="modelA">
    <props>
      <prop name="save-to-file" value="main-model-a.xml"/>
    </props>
    <feature spec="feature1">
      <param name="id" value="1"/>
      <param name="a" value="fp2-modelA"/>
    </feature>
  </config>
</feature-pack>

The resolved configuration modelA:main will contain the following properties:

  • save-to-file=main-model-a.xml;

  • other=thing.

9.6. Configuration package dependencies

config elements may include feature-pack package dependencies. So that when a configuration is included into the installation, the relevant packages required by the configuration are automatically included as well. Package dependencies are configured using the same elements described in the feature package dependencies. E.g.

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
              location="fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
  <config model="modelA">
    <packages>
     <package name="p1"/>
     <package name="p2" optional="true"/>
    </packages>
  </config>
</feature-pack>

Now every configuration of modelA will depend on and bring into the installation the specified packages.

9.7. Configuration dependencies

When all the configuration models have been resolved by the provisioning mechanism, the plugins attached to the installed feature-packs are invoked to generate the final configuration files. The plugins will see the resolved configurations as a list. Certain configuration models though may depend on other configuration models being generated first. To eliminate the trouble of ordering the configurations according to their dependencies in the plugins, configuration dependencies can be expressed in config elements. E.g.

    <config model="host">
        <config-deps>
            <config-dep id="domain-dep" model="domain"/>
        </config-deps>
    </config>

In the example above all the configurations of model host will appear in the resolved config list after all the configurations of model domain. config-dep id is used to identify the configuration dependencies when the configuration models are merged.

The example above illustrates a dependency on a configuration model. But config-dep may also include name attribute.

9.8. Arranging features in configurations

Resolved configuration models are meant to be further processed by the provisioning plugins that actually generate the final configuration files. A resolved configuration is basically a set of features and properties. Plugins simply iterate through the features in the resolved configuration and generate the corresponding configuration fragments for the installation.

The order in which features appear in the resolved configuration may be significant. By default the order of the features in the resolved configuration reflects the order in which the features were added to the configuration, i.e. the order in which the features appeared in the config element. Although, in case there are dependencies between features, the mechanism will re-order the features according to their dependencies, i.e. if feature F1 depends on feature F2, even if F1 was added to the configuration before F2, in the resolved configuration F2 will appear before F1.

9.8.1. Feature branches

Features in the resolved configuration are actually organized into branches. In the simplest case, there is only one branch for all the features of the configuration.

There are cases though, when a certain set of features has to be handled in a different way than the rest of the features in the same configuration. E.g. there could be a few features that form a circular dependency. The mechanism automatically detects those and notifies the plugins in case they need to handle them in a special way. Other examples of branches will be described below.

9.8.2. Batches

Batch is a branch features of which have to be handled atomically. E.g. if processing a feature by a plugin changes a certain state of the model during generation of the final configuration then to avoid a potentionally temporary inconsistent state, batches indicate to the plugins that a specific set of features has to be processed together as a unit and as a single configuration change.

One example could be features that form circular dependencies. Handling them one by one may result in referential integrity (or some other kind of) constraint violation during the final configuration generation.

By default, branches are not flagged as batches. This can be configured though with property config.branch-is-batch. E.g.

    <config model="standalone">
        <props>
            <prop name="config.branch-is-batch" value="true"/>
        </props>
        <!-- the rest is skipped -->

The fragment above makes all the branches of all the standalone configuration models in the installation batches by default.

Batch flag can further be enabled or disabled for a specific branch with feature spec annotations.

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="core-service.management">
    <annotation name="feature-branch">
        <elem name="id" value="core-service.management"/>
        <elem name="batch" value="true"/>
    </annotation>
        <!-- the rest is skipped -->

This marks branch core-service.management as batch.

9.8.3. Branch per feature spec

In some cases it might be useful to arrange features in the resolved configuration by their specs. Some plugins may find it more optimal to process, e.g., all the features of Spec1 first then all the features of Spec2, etc. The mechanism can be instructed to do that by including property config.branch-per-spec in config element, e.g.

    <config model="standalone">
        <props>
            <prop name="config.branch-per-spec" value="true"/>
        </props>
        <!-- the rest is skipped -->
the resulting branches of the configuration will be ordered according to the feature dependencies. E.g. if features of Spec1 reference features of Spec2, the branch of features Spec2 will appear in the configuration before the branch of features Spec1.

The example above is arranging all the features in the configuration by specs. In some cases though it would be useful to group only features of specific specs together and leave the rest of the features as they are. This can be configured by adding the following feature spec annotation

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="core-service.management">
    <annotation name="feature-branch">
        <elem name="spec" value="true"/>
    </annotation>
        <!-- the rest is skipped -->

9.8.4. Isolating circular dependencies

The mechanism may identify circular dependencies between features in a configuration and create a separate branch for them. Here is how to enable this

    <config model="standalone">
        <props>
            <prop name="config.isolate-circular-deps" value="true"/>
        </props>
        <!-- the rest is skipped -->

9.8.5. Parent-children branch

Often features in configurations form parent-children relationships. Some plugins may find it useful to receive features arranged as parent-children branches. This can be configured per feature spec. E.g.

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="SpecP">
    <annotation name="feature-branch">
        <elem name="parent-children"/>
    </annotation>
    <!-- the rest is skipped -->

Which means every feature of spec SpecP will start a branch containing all the features that are children (direct or transitive) of the SpecP feature.

9.8.6. Branches with explicit IDs

When a branch is created, the mechanism assigns an ID to the branch. A user may instruct the mechanism to group features of certain specs on a branch with a given ID. E.g.

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="Spec1">
    <annotation name="feature-branch">
        <elem name="id" value="Branch1"/>
    </annotation>
    <!-- the rest is skipped -->
</feature-spec>

<feature-spec xmlns="urn:jboss:galleon:feature-spec:1.0" name="Spec2">
    <annotation name="feature-branch">
        <elem name="id" value="Branch1"/>
    </annotation>
    <!-- the rest is skipped -->
</feature-spec>

In the example above features of Spec1 and Spec2 will be collected on the same branch Branch1.

9.8.7. Merging independent branches

After a configuration has been resolved, it may appear that some branches share certain common characteristics. E.g. most probably some features in the configuration will depend other features. Which makes the corresponding feature branches depend on other feature branches. There could be a few branches though that don’t depend on other branches (although there could be branches that depend on them). To reduce the total number of branches per configuration, independent branches could be merged into a single independent branch. This can be configured by adding the following property to the config element

    <config model="standalone">
        <props>
            <prop name="config.merge-independent-branches" value="true"/>
        </props>
        <!-- the rest is skipped -->

9.8.8. Merging branches with the same dependencies

While the previous option merges only the independent branches, this one identifies branches with the same dependencies on other branches and merges them into a single branch. It can be enabled by adding the following property

    <config model="standalone">
        <props>
            <prop name="config.config.merge-same-deps-branches" value="true"/>
        </props>
        <!-- the rest is skipped -->

10. Patches

The provisioning mechanism also supports feature-pack patching. Once a feature-pack has been released, the producer of the feature-pack may release patches for it. A patch could overwrite certain content of the feature-pack it applies to (i.e. certain packages or resources) and/or overwrite or re-define a part of the configuration.

A patch itself is also a feature-pack. The only thing that differentiates it from a usual feature-pack is element patch in its feature-pack.xml. Here is an example:

<feature-pack xmlns="urn:jboss:galleon:feature-pack:2.0"
    location="producer1@maven(org.jboss.universe:community-universe):1#1.0.0.Patch1.Final">

    <patch for="prod1@maven(org.jboss.galleon.universe.test:test-universe):1#1.0.0.Final"/> (1)

    <default-packages>
        <package name="p1"/>
    </default-packages>
</feature-pack>
1 indicates that the feature-pack is a patch which applies to the feature-pack specified as the value of for attribute
There is not currently any restriction on the patch feature-pack versioning. 1.0.0.Patch1.Final above is just a random example.
Patches can only be applied to a specific version of the feature-pack. An attempt to apply a patch to an installation that does not include the feature-pack version the patch was built for will result in a failure.

As any other feature-pack, a patch can be installed and uninstalled.

It is possible to apply multiple patches to the same feature-pack in the installation.

10.1. What can be patched

Patch basically provides a new version of certain content and/or redefines some configuration from the feature-pack it targets. Here is what can be patched:

  • packages (including their content and definitions);

  • feature specs (by providing updated feature specs);

  • feature groups (by providing updated feature groups);

  • various feature-pack resources;

  • provisioning plugins (by including new versions of the plugins).

Patches may also include content that is not present in the feature-pack that apply to (i.e. new packages, feature specs, groups, resources, plugins).

10.2. Multiple patches for the same feature-pack

As it was mentioned earlier, it is possible to apply multiple patches for the same feature-pack. In case patches don’t overlap in terms of what they patch, the order in which they are applied is not significant. If patches do overlap, the order in which they are applied most probably becomes significant. Because the patch that is applied last will overwrite patches that were applied before it.

Like any other feature-pack, patches may declare dependencies on other patches. That could be one of the ways to control the order in which the patches will be applied.

10.3. Applying patches

feature-pack element may include element patches which lists patches that should be installed for the feature-pack. E.g.

<installation xmlns="urn:jboss:galleon:provisioning:2.0">
    <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
        <patches>
            <patch id="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Patch1.Final"/>
            <patch id="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Patch2.Final"/>
        </patches>
    </feature-pack>
</installation>

10.3.1. Patching transitive dependencies

It is also possible to apply patches to transitive dependencies. E.g.

<installation xmlns="urn:jboss:galleon:provisioning:2.0">
    <transitive>
        <feature-pack location="prod2@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
            <patches>
                <patch id="prod2@maven(org.jboss.universe:community-universe):1#1.0.0.Patch1.Final"/>
                <patch id="prod2@maven(org.jboss.universe:community-universe):1#1.0.0.Patch2.Final"/>
            </patches>
        </feature-pack>
    </transitive>
    <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
</installation>

11. Maven plugin

The Maven plugin allows to install a specific feature-pack into a new location or an existing installation or provision an installation the consists of multiple feature-packs.

The coordinates of the Maven plugin are

<dependency>
    <groupId>org.jboss.galleon</groupId>
    <artifactId>galleon-maven-plugin</artifactId>
    <version>2.0.0.Final</version>
</dependency>
Table 2. Goals

install-feature-pack

Installs a feature-pack into an empty directory or into an existing installation

provision

Provisions an installation that consists of one or more feature-packs at a specified location

11.1. install-feature-pack

11.1.1. galleon:install-feature-pack

Full name: org.jboss.galleon:galleon-maven-plugin:2.0.0.Final:install-feature-pack

11.1.2. Description

This maven plugin installs a feature-pack into an empty directory or a directory that already contains an installation, in which case the product the feature-pack represents will be integrated into an existing installation.

11.1.3. Attributes

  • Requires a Maven project to be executed.

  • Requires dependency resolution of artifacts in scope: compile+runtime.

  • Binds by default to the lifecycle phase: process-test-resources.

Table 3. Required Parameters

Name

Type

Since

Description

[installDir]

File

-

The target installation directory.
Alias is: install-dir.

Table 4. Optional Parameters

Name

Type

Since

Description

[customConfig]

File

-

Path to a file containing config that should be installed.
Alias is: custom-config.

[excludedPackages]

List

-

Explicitly excluded packages from the installation.
Alias is: excluded-packages.

[featurePack]

ArtifactItem

-

Legacy Galleon 1.x feature-pack artifact coordinates as (groupId - artifactId - version) if not specified the feature-pack must be a transitive dependency of a feature-pack with the version specified. NOTE: either this parameter or 'location' must be configured.
Alias is: feature-pack.

[includedConfigs]

List

-

Default feature-pack configs that should be included.
Alias is: included-configs.

[includedPackages]

List

-

Explicitly included packages to install.
Alias is: included-packages.

[inheritConfigs]

boolean

-

Whether to inherit the default feature-pack configs.
Default value is: true.
Alias is: inherit-configs.

[inheritPackages]

boolean

-

Whether to install the default package set.
Default value is: true.
Alias is: inherit-packages.

[location]

String

-

Galleon2 feature-pack location NOTE: either this parameter or 'feature-pack' must be configured.

[pluginOptions]

Map

-

Arbitrary plugin options recognized by the plugins attached to the feature-pack being installed.
Alias is: plugin-options.

11.1.4. Parameter Details

customConfig
Path to a file containing config that should be installed.

  • Type: java.io.File

  • Required: No

  • Alias: custom-config

excludedPackages
Explicitly excluded packages from the installation.

  • Type: java.util.List

  • Required: No

  • Alias: excluded-packages

featurePack
Legacy Galleon 1.x feature-pack artifact coordinates as (groupId - artifactId - version) if not specified the feature-pack must be a transitive dependency of a feature-pack with the version specified. NOTE: either this parameter or 'location' must be configured.

  • Type: org.jboss.galleon.maven.plugin.util.ArtifactItem

  • Required: No

  • Alias: feature-pack

includedConfigs
Default feature-pack configs that should be included.

  • Type: java.util.List

  • Required: No

  • Alias: included-configs

includedPackages
Explicitly included packages to install.

  • Type: java.util.List

  • Required: No

  • Alias: included-packages

inheritConfigs
Whether to inherit the default feature-pack configs.

  • Type: boolean

  • Required: No

  • Default: true

  • Alias: inherit-configs

inheritPackages
Whether to install the default package set.

  • Type: boolean

  • Required: No

  • Default: true

  • Alias: inherit-packages

installDir
The target installation directory.

  • Type: java.io.File

  • Required: Yes

  • Alias: install-dir

location
Galleon2 feature-pack location NOTE: either this parameter or 'feature-pack' must be configured.

  • Type: java.lang.String

  • Required: No

pluginOptions
Arbitrary plugin options recognized by the plugins attached to the feature-pack being installed.

  • Type: java.util.Map

  • Required: No

  • Alias: plugin-options

11.2. provision

11.2.1. galleon:provision

Full name: org.jboss.galleon:galleon-maven-plugin:2.0.0.Final:provision

11.2.2. Description

This maven plugin provisions an installation that consists of one or more feature-packs. If the target installation directory already contains an installation, the existing installation will be fully replaced with the newly provisioned one. <p>In other words, the configuration provided for this goal fully describes the state of the final installation.</p>

11.2.3. Attributes

  • Requires a Maven project to be executed.

  • Requires dependency resolution of artifacts in scope: compile+runtime.

  • Binds by default to the lifecycle phase: process-test-resources.

Table 5. Required Parameters

Name

Type

Since

Description

[featurePacks]

List

-

A list of feature-pack configurations to install.
Alias is: feature-packs.

[installDir]

File

-

The target installation directory.
Alias is: install-dir.

Table 6. Optional Parameters

Name

Type

Since

Description

[customConfig]

File

-

Path to a file containing config that should be installed.
Alias is: custom-config.

[offline]

boolean

-

Whether to use offline mode when the plugin resolves an artifact. In offline mode the plugin will only use the local Maven repository for an artifact resolution.
Default value is: true.
Alias is: offline.

[pluginOptions]

Map

-

Arbitrary plugin options.
Alias is: plugin-options.

[resolveLocals]

List

-

A list of artifacts and paths pointing to feature-pack archives that should be resolved locally without involving the universe-based feature-pack resolver at provisioning time.
Alias is: resolve-locals.

11.2.4. Parameter Details

customConfig
Path to a file containing config that should be installed.

  • Type: java.io.File

  • Required: No

  • Alias: custom-config

featurePacks
A list of feature-pack configurations to install.

  • Type: java.util.List

  • Required: Yes

  • Alias: feature-packs

installDir
The target installation directory.

  • Type: java.io.File

  • Required: Yes

  • Alias: install-dir

offline
Whether to use offline mode when the plugin resolves an artifact. In offline mode the plugin will only use the local Maven repository for an artifact resolution.

  • Type: boolean

  • Required: No

  • Default: true

  • Alias: offline

pluginOptions
Arbitrary plugin options.

  • Type: java.util.Map

  • Required: No

  • Alias: plugin-options

resolveLocals
A list of artifacts and paths pointing to feature-pack archives that should be resolved locally without involving the universe-based feature-pack resolver at provisioning time.

  • Type: java.util.List

  • Required: No

  • Alias: resolve-locals

Table 7. Feature-pack parameters

Name

Required

Default value

Description

groupId

yes

-

Feature-pack Maven artifact groupId.

artifactId

yes

-

Feature-pack Maven artifactId.

version

no

-

Feature-pack artifact version (if not specified the feature-pack must be a transitive dependency of a feature-pack with the version specified.

inherit-configs

no

true

Whether to inherit the default feature-pack configs

included-configs

no

-

Default feature-pack configs that should be included.

excluded-configs

no

-

Default feature-pack configs that should be excluded.

inherit-packages

no

true

Whether to inherit the default feature-pack packages.

included-packages

no

-

Default feature-pack packages that should be included.

excluded-packages

no

-

Default feature-pack packages that should be excluded.

Example

<plugin>
    <groupId>org.jboss.galleon</groupId>
    <artifactId>galleon-maven-plugins</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>provision</goal>
            </goals>
            <configuration>
                <install-dir>${project.build.directory}/${project.build.finalName}</install-dir>
                <feature-packs>
                    <feature-pack>
                        <groupId>org.wildfly.core</groupId>
                        <artifactId>wildfly-core-galleon-pack</artifactId>
                        <inherit-configs>false</inherit-configs>
                        <excluded-packages>
                            <name>product.conf</name>
                            <name>docs.schema</name>
                        </excluded-packages>
                    </feature-pack>
                    <feature-pack>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>wildfly-servlet-galleon-pack</artifactId>
                        <version>${project.version}</version>
                            <excluded-packages>
                            <name>product.conf</name>
                            <name>docs.schema</name>
                        </excluded-packages>
                    </feature-pack>
                </feature-packs>
                <plugin-options>
                    <jboss-maven-dist/>
                </plugin-options>
            </configuration>
        </execution>
    </executions>
</plugin>

12. Galleon CLI tool

This command line tool (bin/galleon.[sh|bat]) allows you to provision/manage any products/installations that comply with galleon feature-packs. Although being a generic tool, a builtin support is offered for products available from maven jboss community universe (eg: wildfly).
Possible actions that you can operate from the tool: install, uninstall, check for updates, patch, update, undo last provisioning command.

12.1. Feature-pack

A key concept in galleon system is the notion of feature-pack. A feature-pack is a content container. It can be a full product (eg: wildfly) or part of a product (eg: a wildfly subsystem packaged as a feature-pack). With the tool you are going to install/uninstall/update/…​ feature-packs.
NB: A galleon installation can be composed of 1 or more feature-packs.

A feature-pack can be a file on your local file system or located inside a universe (a product catalog).

The tool helps you identify the feature-pack that you can use for the task you want to achieve. In order to take benefit of the full capabilities offered by the tool, one needs to understand how products are identified inside a universe.

12.2. Universe feature-pack location (FPL)

A feature-pack location (FPL) is the way to identify a product inside a universe without actually expressing any build numbers. A lot to commands require that you provide FPL.

The main (non exhaustive) FPL syntax is: <product>[@universe]:[version]/[qualifier]
Some examples of FPL to identify wildfly products:

  • wildfly:current =⇒ Final (released) wildfly product current version

  • wildfly:current/alpha =⇒ The latest release of wildfly product current version that is at least of alpha quality.

The things to notice:

  • Universe (from where the product comes from) is optional for products located in jboss maven community universe.

  • No actual version nor build (eg: 1.0.0-Alpha1-SNAPHOT) is provided. The syntax of FPL is abstract it allows you to express a level of expected quality without hard-coding any version number.

  • Pointed by an FPL is an actual feature-pack artifact (a zipped file) that the tool will download/install,…​

  • A completer helps you compose FPL when the command you are calling expect one (eg: install).

For example, if one installs wildfly product using the following command:

install wildfly:current/alpha --dir=myInstallation

Then, later, when checking for updates or upgrading myInstallation directory, the latest build that is at least of quality alpha will be used to update. If a final release is available then it will be installed when upgrading.

NB: Products being unique inside an installation, some commands (eg: state update) only require the product part (<product>[@universe]) of an FPL. For example:

state update --products=wildfly

12.3. Universe feature-pack id (FPID)

A feature-pack id (FPID) is the way to identify a product inside a universe by expressing a build number. This is the syntax to use when you want to deal with specific builds of a product.

The FPID syntax is: <product>[@universe]:[version]#[buildID]
Some examples of FPID to identify wildfly products:

  • wildfly:current#1.0.0-Final

  • wildfly:current#1.0.0-Alpha1

The things to notice:

  • Universe (from where the poduct comes from) is optional for products located in jboss maven community universe.

  • Pointed by an FPID is an actual feature-pack artifact (a zipped file)

  • A completer helps you compose your FPID when the command you are calling expect one (eg: install).

For example, to retrieve the informations of alpha1 build:

feature-pack info wildfly:current#1.0.0-Alpha1

12.4. Installing a feature-pack

install <[FPL|FPID] | [--file=<path to fp zip file>]> [--dir=<installation dir>] [--verbose] [feature-pack specific options]

This creates a directory containing the installed feature-pack content (binaries, configs).

NB: Using completion, when an installation directory has been identified, the options that are specific to the feature-pack to install are proposed. When installing for the first time a feature-pack this can take some time (a matter of few seconds up to minutes if the feature-pack needs to be downloaded from a remote location).

You can retrieve the set of feature-pack specific options without relying on completion, to do so call:
feature-pack info <[FPL|FPID] | [--file=<path to fp zip file>]> --type=options
You can then use the listed options (if any) to customize your install command.

12.5. Un-installing a feature-pack

uninstall [FPID] [--dir=<installation dir>] [--verbose] [feature-pack specific options]

This will remove the content installed by the feature-pack identified by the FPID. Some feature-pack specific options can be provided, they will be used when re-provisioning the remaining (if any) feature-packs.

NB: Completer proposes the FPID you can un-install from the installation (products and patches). Completion of feature-pack specific options are handled the same way as in the install command.

12.6. Un-doing the last provisioning command

state undo [--dir=<installation dir>] [--verbose]

This will revert the installation to the previous installed state.

12.7. Patching an installation

Use the install command to patch an existing installation.

install <[FPL|FPID] | [--file=<path to patch zip file>]> [--dir=<installation dir>] [--verbose] [feature-pack specific options]

12.8. Un-installing a patch

Use the uninstall command to remove a given patch or use state undo if the last provisioning command has been a patch installation.

12.9. Checking for updates

state check-updates [--dir=<installation dir>] [--include-all-dependencies] [--products=<list of products>]

If no directory is provided, the current directory is used. If no products are provided, all installed products are checked for updates.

12.10. Updating an installation

state update [--dir=<installation dir>] [--include-all-dependencies] [--yes] [--products=<list of products>] [feature-pack specific options]

Display the list of available updates/patches then update. If no directory is provided, the current directory is used. If --yes is provided, the command will proceed without asking for confirmation.

NB: Using completion, when an installation directory has been identified, the options that are specific to the installed feature-pack(s) are proposed. When updating an installation for the first time this can take some time (a matter of few seconds up to minutes if the feature-pack needs to be downloaded from a remote location).

You can retrieve the set of feature-pack specific options without relying on completion, to do so call:
state info [--dir=<installation dir>] --type=options
You can then use the listed options (if any) to customize your update command.

12.11. Observing an installation

[my-dir]$ state info [--dir=installation] --type=[all|configs|dependencies|patches]

Display the set of installed feature-packs FPID. In addition can display configurations, dependencies and patches.
NB: If some patches are applied, the applied patches information is displayed.

12.12. Observing a feature-pack

[my-dir]$ feature-pack info <[FPL|FPID] | [--file=<path to fp zip file>]> --type=[all|configs|dependencies|options]

Display the FPID of a feature-pack. In addition can display dependencies, configurations and options usable when installing/provisioning/upgrading.

12.13. Exporting an installation to xml

[my-dir]$ state export <new generated xml file> --dir=<installation>

12.14. Provisioning an installation from xml

[my-dir]$ state provision <xml file> --dir=<target installation directory> [feature-pack specific options]

NB: Using completion, when an installation directory has been identified, the options that are specific to the feature-pack(s) located in the XML configuration file are proposed. When provisioning an installation for the first time this can take some time (a matter of few seconds up to minutes if the feature-pack needs to be downloaded from a remote location).

12.15. Managing the history of an installation

By default the history keeps the state of the last 100 provisioning operations. This should be enough to cover simple undo of provisioned state. Nevertheless you can increase/decrease this value by using the following command: state set-history-limit <history size limit> [--dir=<installation dir>]

To retrieve the history size limit do:

state get-history-limit [--dir=<installation dir>]

12.16. Exploring an installation or a feature-pack.

To explore an installation:
[my-dir]$ state explore --dir=installation

To explore a feature-pack:
[my-dir]$ feature-pack explore <[FPL|FPID] | [--file=<path to fp zip file>]

Once exploring, prompt, ls, cd and pwd commands are bound to the feature-pack (or installation) exposed file-system.

[/]$ ls
configs
feature-specs
packages
[/]$ state leave
[my-dir]$

The fs is composed of:
/configs/final/<model>/<name>/<features>
/feature-specs/<origin>/<feature-specs>
/packages/<origin>/<packages>
Features and feature-specs are organized as a file system with containment.
The set of available commands is limited when in “navigation mode”. Only “cd, ls, pwd and state info|leave” are available. Use state leave to exit this mode.

Use ‘ls’ to visualize any item. Use ‘cd’ to navigate to a given node.

12.17. Searching the current state

When exploring, editing or composing a new state, one can search the packages and features.

[/]$search [--query=<some text> | --package=<package name>]

When searching with --query all packages and features are looked-up for a match. If packages are matched, the features that depend directly or indirectly on these packages will be shown in the result.

When searching with --package, the package completer can be used. The features that depend directly or indirectly on this package will be shown in the result.

12.18. Creating a new state (or editing an existing state from an installation or provisioning XML file)

This allow to start from an empty installation or re-use an installation and iteratively add/suppress content.

[my-dir]$ state new | state edit <path to installation | path to provisioning XML file>
[/]$ <TAB>
cd feature-pack ls pwd state
[/]$ ls
configs
dependencies
feature-specs
packages

The filesystem is similar to explore, with the addition of dependencies that contains full content of all added feature-packs.

NB: Each action as the effect to build a runtime with the current state. The filesystem reflects the current state.

NB: Each action applied to a state in edition can be undone: state undo. Use state leave to exit the composition mode.

NB: The set of exposed commands by completer is dynamic and is adjusted according to the current state.

12.19. Managing universes

A universe can be added/removed to/from an existing installation or to a new/edited state.
NB: In order to add/remove a universe to/from an installation you must first cd in the directory of the installation.

Add a named or default (without using the --name option) universe to the current provisioning state or installation.
[/]$ universe add [--name=<universe name>] --factory=<universe factory> --location=<universe location>

Remove a named or default (without using the --name option) universe from the current provisioning state or installation.
[/]$ universe remove [--name=<universe name>]

12.20. Listing products of universes

[/]$ universe list

This command lists all the products and available builds present in all the installed universes.

You can search for products that match a given pattern using --product=<pattern>.
For example:
[/]$ universe list --product=wildfly*

12.21. Exporting or provisioning the current state

At any time, one can export the provisioning XML file or directly provision from the current state:

[/]$ state export <path to generated xml file> | state provision <dir of new installation>

Use state export to validate that what you get in the XML is in sync with the expose state. In case you find something wrong, shout to me ;-)!
Exporting a state without any XML target file will display the XML content in the CLI console.
The command state info can be used to get high level information.

12.22. Adding a feature-pack

[/]$ fp add <FPL|FPID> [--default-configs-inherit] [--packages-inherit]

By default nothing is inherited. Once at least one feature-pack has been added, configurations or packages can be handled.

NB: A runtime based on the added full feature-pack is built in order to retrieve dependencies content and some completion content. This structure is cached for re-use.

12.23. Removing a feature-pack

[/]$ fp remove <FPL|FPID>

12.24. Including a default configuration

[/]$ config include <model>/<name> [--origin=<fp origin>]

Origin is optional, by default will be included from all fp that expose it.

12.25. Removing an included default configuration

[/]$ config remove-included <model>/<name> [--origin=<fp origin>]

The completer only proposes the set of configurations that have been previously included. Same for fp. Origin is optional, by default will be remove from all fp that include it.

12.26. Excluding a default configuration

[/]$ config exclude <model>/<name> [--origin=<fp origin>]

Origin is optional, by default will be excluded from all fp that expose it.

12.27. Removing an excluded default configuration

[/]$ config remove-excluded <model>/<name> [--origin=<fp origin>]

The completer only proposes the set of configurations that have been previously excluded. Same for fp. Origin is optional, by default will be remove from all fp that exclude it.

12.28. Reseting a configuration

[/]$ config reset <model>/<name>

The custom content of this configuration is removed.

NB: This has no effect on included/excluded configurations.

12.29. Including a default package

[/]$ packages include <fp origin>/<package name>

12.30. Removing an included default package

[/]$ packages remove-included <package name> [--origin=<fp origin>]

The completer only proposes the set of packages that have been previously included. The origin is optional, the package will be removed from all fp that exclude it.

12.31. Excluding a default package

[/]$ packages exclude <fp origin>/<package name>

12.32. Removing an excluded default package

[/]$ packages remove-excluded <package name> [--origin=<fp origin>]

The completer only proposes the set of packages that have been previously excluded. The origin is optional, the package will be removed from all fp that exclude it.

12.33. Adding a new feature

[/]$ feature add <config model/name> <path to feature-spec> <dynamic set of feature param=<value>>

For example:
feature add standalone/standalone.xml org.wildfly.core:wildfly-core-galleon-pack/interface --interface=toto --inet-address=127.0.0.1

NB: All parameters are exposed as command option.

NB: All parameters that are not nillable and have no default values are required. The command being aborted if there are missing required parameters.

NB: If the parameter is not present, its default value is injected when creating the feature.

NB: The current location (thanks to cd) is not yet taken into account when completing/adding the feature. That is a TODO.

NB: A feature with the same feature-id can’t exist. A single feature with the given feature-id per config.

12.34. Removing a feature

[/]$ feature remove <full path to feature inside a configuration>

For example:
feature remove standalone/standalone.xml/interface/toto

13. CLI tool Maven configuration

By default the following maven repositories are used to retrieve FP.

The cli allows you to change the path to the local repository and add/remove remote maven repositories.

13.1. Relying on maven settings

In order to makes the cli to use a maven settings file call: mvn set-settings-file <path to settings xml file> In order to remove the reference to the settings file call: mvn set-settings-file

NB: Advanced mirroring (eg: external:*) is not supported.
NB: Any other cli maven configuration items will be overridden when a settings xml file is set.
NB: If no local repository is set in settings file, the local repository (default or configured) is used.

13.2. Adding new remote repositories

Type the following commands:
mvn add-repository --name=myrepo --url=http://foorepo

13.3. Repository policies (this could be made configurable)

Daily update.
Warn if checksum differs.

13.4. Advanced maven configuration

Proxy, authentication, mirroring and offline are only supported when setting a maven xml settings file.

13.5. Local repository

By default the local maven repository is located in <user.home>/.m2/repository. You can change this directory by using the command: mvn set-local-repository <path to your local repository directory>
In order to reset to the default local maven repository call: mvn set-local-repository

13.6. Display maven configuration

Call command: mvn info

13.7. Impact on Universe

Any change made to the maven configuration makes the CLI to re-resolve universe(s). This means that stream resolution stays in sync with maven configuration.

13.8. Fetching feature-packs

When remote repositories are set, feature-packs are automatically downloaded at install time. You can download feature-pack explicitly to the local repository by using the command: mvn fetch-feature-pack <stream name> [--verbose]

13.9. Maven tracing

When enabling "verbose" at installation and provisioning time, any artifact retrieved from a remote repository is advertised in the console. This also applies when fetching explicitly feature-packs.