# Galleon Documentation

Alexey Loubyansky, Jean-François Denise
version 6.0.0.Final, 2024-04-09

© 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 customized 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;

- detection of the changes in the provisioned distribution (its filesystem content and/or its configuration) applied by the user manually or by means of other management tools

  - to be able to preserve them after a version upgrade (having made sure the changes are compatible in the new version)

  - or create a provisioning configuration that could be used to reproduce the state of the distribution including the user changes;

- exporting the provisioning configuration 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.

Releases of the command line tool are available on the Galleon releases page.

Download and unzip the release zip and add the `bin` dir to your system path. Use `galleon.sh` or `galleon.bat` to launch the tool.

## 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
    |- configs/
    |- feature_groups/
    |- features/
    |- layers/
    |- packages/
    |- plugins/
    |- resources/
    `- feature-pack.xml

Where

- configs - optional directory containing predefined installation configurations;

- feature_groups - optional directory containing feature group descriptions;

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

- layers - optional directory containing predefined configuration layers that can be used to create custom installation configurations;

- 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 (note, that alternatively plugin artifacts can also be referenced from `feature-pack.xml` using their repository coordinates);

- 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.

- (optional) plugins - various provisioning plugins.

- (optional) system-paths - paths to files that should be protected during upgrades.

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

    <feature-pack xmlns="urn:jboss:galleon:feature-pack:3.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>
        <plugins> (5)
            <plugin location="org.jboss.galleon.example:galleon-example-plugin:1.0.0.Final"/>
        </plugins>
        <system-paths> (6)
            <system-path path="modules/system/layers/base"/>
        </system-paths>
    </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
5 | List of provisioning plugins
6 | List of protected system paths

### 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 into feature-pack locations for the feature-packs coming from that universe.

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

Feature-pack producer may configure a default channel, which makes the channel part optional for the feature-packs of that producer.

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#17.0.0.Beta1`

And a shortened version:

`wildfly:current#17.0.0.Beta1`

And assuming `current` is the default channel it becomes

`wildfly#17.0.0.Beta1`

| 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#17.0.0.Beta1

and

    install wildfly#17.0.0.Beta1

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

    install wildfly

#### 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.

#### 2.3.3. Feature-pack Maven Artifact Location

It is also possible to use the feature-pack’s Maven artifact coordinates in place of the feature-pack location expression described above. In that case, after the feature-pack artifact has been resolved, its actual Galleon feature-pack location will be used during provisioning and state persistence. E.g.

    install org.wildfly:wildfly-galleon-pack:17.0.0.Final

will be equivalent to

    install wildfly#17.0.0.Final

## 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:2.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:2.0" name="p1">
        <dependencies>
            <package name="p2"/> (1)
            <package name="p3" optional=”true”/> (2)
        </dependencies>
     </package-spec>

1 | required dependency on package `p2`
2 | optional dependency on package `p3`

A 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 `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. Passive dependencies

An optional dependency may be also marked as passive, e.g.

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

Or, in fact, the example above can be re-written without `optional="true"` since only optional dependencies can be passive, i.e.

     <package-spec xmlns="urn:jboss:galleon:package:2.0" name="p1">
        <dependencies>
            <package name="p2" passive="true"/>
        </dependencies>
     </package-spec>

| A passive dependency on a package is satisified only if all the required dependencies of that package are included into the installation (as the default packages or direct or required dependencies (possibly transitive) of the provisioned configs, layers, feature groups or features).

Passive dependencies affect how the effective package set of a feature-pack is resolved.

#### 4.3.2. 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:2.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. the set of packages which is going to be installed when the feature-pack is installed as-is without any customizations from a user.

Generally speaking, the original effective package set of a feature-pack 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, the default configs and layers, feature groups and features those configs consist of.

While the required package dependencies are always included into the effective package set, the inclusion of optional packages can be controlled with one of the policies specified as the value of provisioning option `optional-packages`: `all`, `none`, `passive` and `passive+`.

Here is the table illustrating which dependency types are automatically included and which are filtered out form the effective package set under each policy:

Table 1. Optional package inclusion policies
| all | passive+ | passive | none
required | + | + | + | +
passive (satisfied) | + | + | + | -
passive (unsatisfied) | + | - | - | -
optional | + | + | - | -

#### 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 default effective package set and simply pick the desired packages explicitly under `dependency` element (in other words, explicitly define the desired 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>

| The `exclude` elements may at first look redundant, given that package inheritance was disabled in the first place. However, it’s important to keep in mind that when a package is included, by default, all its dependencies are also included. `exclude` elements can be used to exclude certain transitive dependencies of the included dependencies.

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. Dependency version convergence

This chapter describes how Galleon picks the version of a dependency to install when multiple versions of that dependency appear on the installation’s dependency tree.

| The first rule is: versions specified in the provisioning configuration of the installation, e.g. `provisioning.xml`, for direct or transitive feature-pack dependencies, represent the user’s choice and are always installed, even if the dependency hierarchy of the installation includes other versions of those feature-packs.

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`.

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

### 7.1. Version convergence of dependency branches

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. 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>

In this case, Galleon will pick version `1.2.0` of `fp3` simply because it was processed first as the dependency of `fp1`.

| By default Galleon will pick the first processed feature-pack version even if other feature-packs of the installation depend on a newer compatible version of the feature-pack from the same channel.

| This behaviour may change in the future in favor of picking the latest compatible version of the feature-pack.

| In the example above both `fp1` and `fp2` depend on the same channel of `fp3`. If they depended on different channels of `fp3`, the provisioning would fail because different channels represent different compatibilty streams.

The user can also resolve this kind of version conflict by either installing `fp3` directly or specifying 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>

### 7.2. Disabling version convergence

There is a provisioning property called `version-convergence` which can be set to `fail` to disable the dependency version convergence that happens when merging dependency branches.

| Even if `version-convergence` is set to `fail`, feature-pack versions that appear higher in the feature-pack dependency hierarchy (i.e. closer to the root in the provisioning configuration) will still override the versions that appear further down in the dependency hierarchy, no matter whether they are higher or lower in comparison.

## 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 may include predefined configurations for the installation. They are stored in feature-pack’s `configs` directory. Every configuration is described in an XML file and in a simple (and perhaps the most common) case, every configuration will represent a specific configuration file in the provisioned installation.

Feature-pack metadata (`feature-pack.xml`) may define which of the predefined configurations should be provisioned by default by referencing them using `config` elements .

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

- the configurable parameters (including their names, default values (if any) and whether they are nillable);

- (optionally) references to other feature specs;

- (optionally) dependencies on other features;

- (optionally) required capabilities;

- (optionally) provided capabilities;

- (optionally) dependencies on packages;

- (optionally) annnotations.

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 name="main">
         <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 2. 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 name="main">
       <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 name="main">
       <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 name="main">
       <feature spec="featureP">
         <param name="parentId" value="parent1"/>
         <feature spec="featureC" parent-ref="parent">
           <param name="childId" value="child1"/>
         </feature>
       </feature>
     </config>

| it is also possible to include a feature-group as a child of the feature.

##### 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 name="main">
         <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.

###### Optional capabilities

In the example above, parameter `interface` in both feature specs is not nillable, which means the capability will always be provided by `interface` and always be required `socket-binding`. There could be cases though, when a parameter referenced from the capability name is nillable. In fact, if the parameter is null, the capability name will fail to resolve and provisioning will fail. However, dynamic capabilities can be marked as optional. Optional dynamic capability will be provided (or required) only if its name could be resolved (i.e. all the parameters referenced were not null). Here is the example illustrating optional capabilities in a feature spec:

     <feature-spec name="specA" xmlns="urn:jboss:galleon:feature-spec:1.0">
       <provides>
         <capability name="$b" optional="true"/>
       </provides>
       <requires>
         <capability name="$c" optional="true"/>
       </requires>
       <params>
         <param name="id" feature-id="true"/>
         <param name="b" nillable="true"/>
         <param name="c" nillable="true"/>
       </params>
     </feature-spec>

#### 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 name="main">
         <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 name="main">
         <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:

1. the configuration of the features included into the group can be overwritten;

2. certain features can be excluded from the group by

   - specifying the feature IDs;

   - specifying the specs features of which have to be excluded;

   - explicitly choosing which features should be included by specifying their feature IDs;

   - explicitly choosing features of which feature specs should be included.

| 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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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 name="main">
      <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

### 8.3. Layers

| A layer is meant to represent a certain configuration flavor that can be used on its own or in combination with other layers to produce the final configuration.

The idea behind layers is to predefine certain technology or some other purpose specific complete configurations (that can be used individually or in combination) and expose them as a multichoice to users composing their desired configuration.

For example, let’s suppose we are provisioning an application server that supports multiple technologies such as EJB, Servlet, Messaging, etc. Those technologies could be viewed as components that make up the complete server but also, possibly, as a user’s choice at installation time, in case the user is actually interested only in a subset of those or perhaps simply one, or something that is not included into the default set.

Layers are defined in feature-pack archive’s `layers` directory. A layer is associated with a name but also, as configuration models, can be associated with a model. If a layer is associated with a model, its definition in the feature-pack archive will appear in `layers/config_model/layer_name/layer-spec.xml` file, otherwise it will end up in `layers/layer_name/layer-spec.xml`.

Layers may depend on other layers. If a configuration includes a layer that depends on another layer, that other layer will be included (unless explicitly excluded by the user) into the configuration as well (prior to the layer declaring the dependency on it).

While layers may be associated with both configuration model and a name, they are always referenced in configuration by simple name. The reason for that is that a layer can be referenced only from a configuration model or another layer and, ultimately, it still goes down to the configuration model that includes the layers. So it is the configuration model that determines which model to use for the layers it includes.

#### 8.3.1. Layers vs feature groups

Layers and feature groups have the following in common:

- both are meant to define a certain (specialized) part of the final configuration;

- both may define package dependencies.

But they also have quite a few significant differences.

##### Origin

The content of a feature group (including its package dependencies, if any) is fully defined in a single file - the feature group spec XML. And so, a feature group has a specific origin - the feature-pack containing the definition of the feature group.

Layers, on the other hand, are a product of merging layer specs with the same identity (configuration model + layer name combination) from all the feature-packs that make up the installation. From this perspective, layers are closer to configuration models than feature groups. And so, a layer might not have a single origin.

##### Dependencies

Feature groups don’t really have the notion of dependencies on other feature groups. A feature group may include other feature groups (their content) into its body.

A layer may define dependencies on other layers, which is not the same as including content of those layers into the layer declaring the dependency. The content of layers is merged directly into the configuration model which includes the layers.

##### Exclusion from configuration

There is no way to exclude feature groups that have been earlier included into the configuration. When a feature group is added to a configuration, its content (features) is merged immediately into the configuration model. In a way, feature groups dissolve in the configuration and there is no way to identify the set of features previously forming the group with the goal to exclude them altogether from the configuration.

Layers, on the other hand, can be excluded from the configuration. When a configuration is resolved, the complete set of layers it includes is determined and then merged into the configuration. A user may provide instructions though to filter certain (or all the) layers out of the configuration.

##### Nesting

Feature groups can be nested under a feature which would serve as a parent feature for all the features included into the nested group directly and initialize the corresponding ID parameters of all the features contained in the group.

Layers can’t be nested under a feature. They are meant to define a complete configuration or a part of it starting from the very top of it.

#### 8.3.2. Layer spec

A layer spec is defined in `layer-spec.xml` file which, for the most part, content-wise is identical to a feature-group spec except it allows to configure dependencies on other layers. Here is an example

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <dependencies>
            <layer name="layerB"/> (1)
            <layer name="layerC" optional="true"/> (2)
        </dependencies>

        <!-- various features and feature groups -->
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p1" value="value"/>
        </feature>
        <feature-group name="groupA"/>

        <packages>
            <package name="packageA"/> (3)
            <package name="packageB" optional="true"/> (4)
        </packages>
    </layer-spec>

1 | required dependency on `layerB` (`layerA` can’t be installed unless `layerB` has been installed)
2 | optional dependency on `layerC` (`layerC` will be installed when `layerA` is installed but if `layerC` has been excluded by the user, `layerA` will still be installed)
3 | required dependency on `packageA` (`layerA` can’t be installed unless `packageA` has been installed)
4 | optional dependency on `packageB` (`packageB` will be installed when `layerA` is installed but if `packageB` has been excluded by the user, `layerA` will still be installed)

#### 8.3.3. Effective layer spec

In the simplest case, when only one feature-pack among all of the feature-packs that make up the installation defines a layer with a specific identity in the corresponding `layer-spec.xml`, whatever is defined in that `layer-spec.xml` is the effective layer spec in the installation.

However, in case an installation includes multiple feature-packs that happen to define a layer with the same identity (model and layer name combination) then the effective layer spec with that identity will be the result of merging all the layer specs from all the feature-packs that make up the installation into one. Merging happens in the order the feature-packs are installed and follow the same principle used for merging configuration models.

For example, let’s supposed we have three feature-packs: `fpA`, `fpB` and `fpC` and `fpB` depends on `fpA`. Every one of those feature-packs defines `layer1`.

fpA layer1

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p1" value="fpA"/>
            <param name="p2" value="fpA"/>
            <param name="p3" value="fpA"/>
        </feature>
        <packages>
            <package name="package-fpA"/>
        </packages>
    </layer-spec>

fpB layer1

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p2" value="fpB"/>
            <param name="p3" value="fpB"/>
        </feature>
        <packages>
            <package name="package-fpB"/>
        </packages>
    </layer-spec>

fpC layer1

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p3" value="fpC"/>
        </feature>
        <packages>
            <package name="package-fpC"/>
        </packages>
    </layer-spec>

Now if we provision an installation using the feature-packs above as

Provisioning configuration

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

1 | `fpB` installs `fpA` as its transitive dependency

The effective layer spec of `layerA` will be resolved as

Effective `layer1` spec

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p1" value="fpA"/>
            <param name="p2" value="fpB"/>
            <param name="p3" value="fpC"/>
        </feature>
        <packages>
            <package name="package-fpA"/>
            <package name="package-fpB"/>
            <package name="package-fpC"/>
        </packages>
    </layer-spec>

| There won’t actually be an XML file generated for the effective layer spec. The XML above is used only for illustration of the effective layer content and its dependencies.

As in case of configuration model merging, feature-packs that appear higher in the feature-pack dependency hierarchy are allowed to use `include` and/or `exclude` elements in their layer specs to include and/or exclude features from the corresponding layers inherited from their feature-pack dependencies. In our example above, `include` and/or `exclude` elements could be used in `layer1` of `fpB` to manipulate the content of `layer1` inherited from `fpA`. E.g.

fpB layer1

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <exclude spec="specA"/>
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p2" value="fpB"/>
            <param name="p3" value="fpB"/>
        </feature>
        <packages>
            <package name="package-fpB"/>
        </packages>
    </layer-spec>

With the rest of the configs unchanged the effective `layer1` spec will become

Effective `layer1` spec

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layerA">
        <feature spec="specA">
            <param name="id" value="1"/>
            <param name="p2" value="fpB"/>
            <param name="p3" value="fpC"/>
        </feature>
        <packages>
            <package name="package-fpA"/>
            <package name="package-fpB"/>
            <package name="package-fpC"/>
        </packages>
    </layer-spec>

In case of `fpC` which doesn’t declare any dependency on neither `fpA` nor `fpB`, using `include` and/or `exclude` in its `layer1` spec won’t make any sense because other `layer1` specs are not 'visible' from `fpC`.

#### 8.3.4. Including layers into configuration models

Layers are included into configuration defined using `config` element under element `layers`, e.g.

    <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
        <layers>
            <include name="layer1"/>
            <include name="layer2"/>
        </layers>
        <!-- the rest of the configuration -->
    </config>

Let’s suppose the configuration above belongs to a feature-pack `prod1`. And `prod1` also predefined another layer - `layer3`, which is not included into the default configuration `model1:name1`. Here is how `layer3` can be added to the final configuration by a user:

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
            <layers>
                <include name="layer3"/>
            </layers>
            <!-- the rest of the configuration -->
        </config>
    </installation>

The resulting `model1:name1` configuration now will include `layer1`, `layer2` and `layer3` and they will be included into the configuration in exactly that order.

| The statement above is valid only if the mentioned layers don’t depend on each other and/or other layers.

#### 8.3.5. Excluding layers from configuration models

Layers that have been included into the configuration can later be excluded from it. The example above demonstrated how to include a layer into the configuration, here is an example of how a layer can be excluded:

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
            <layers>
                <exclude name="layer2"/>
                <include name="layer3"/>
            </layers>
            <!-- the rest of the configuration -->
        </config>
    </installation>

Assuming feature-pack `prod1` included `layer1` and `layer2` into its `model1:name1` configuration (as in the previous example), the resulting `model1:name1` configuration will include only `layer1` and `layer3` (and their dependencies if any).

| An attempt to exclude a layer that would not have otherwise been installed will result in a provisioning error. The error, however, can be suppressed by adding provisioning option `ignore-not-excluded-layers`.

#### 8.3.6. Disabling inheritance of layers

If at some point it is necessary to reset the configuration in terms of layers it consists of and possibly re-define the configuration explicitly, it can be done like this

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
            <layers inherit="false">
                <include name="layer3"/>
            </layers>
            <!-- the rest of the configuration -->
        </config>
    </installation>

`inherit="false"` attribute indicates to the provisioning mechanism to not inherit any layers for the configuration from any of the feature-packs included up to that point. The resulting `model1:name1` configuration will include only `layer3` (plus its dependencies) even if `prod1` included more layers into `model1:name1`.

#### 8.3.7. Adjusting layer configuration

Once layers have been included into the configuration, the set of features, as well as packages, they brought in can be manipulated, i.e. configuration of some or all of those features can be modified or completely excluded.

Here is an example. Let’s suppose `prod1` feature-pack defines `layer1` as

    <layer-spec xmlns="urn:jboss:galleon:layer-spec:1.0" name="layer1">
        <feature spec="specA">
            <param name="id" value="1"/>
        </feature>
        <feature spec="specA">
            <param name="id" value="2"/>
        </feature>
        <feature spec="specB">
            <param name="id" value="1"/>
        </feature>
        <feature spec="specB">
            <param name="id" value="2"/>
        </feature>
        <packages>
            <package name="package1"/>
            <package name="package2" optional="true"/>
            <package name="package3"/>
        </packages>
    </layer-spec>

The user wants to include this layer into its installation but also adjust its configuration. It could look like this

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final">
            <packages>
                <exclude name="package2"/> (1)
            </packages>
        </feature-pack>
        <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
            <layers>
                <include name="layer1"/>
            </layers>
            <exclude feature-id="specA:id=2"/> (2)
            <exclude spec="specB"/> (3)
            <feature spec="specB">
                <param name="id" value="3"/>
            </feature>
        </config>
    </installation>

1 | `package2` `layer1` depends on is excluded from the installation
2 | `specA:id=2` inherited from `layer1` is excluded from the configuration
3 | All the features of `specB` inherited from `layer1` are excluded from the configuration

The resulting installation will consist of:

- `model1:name1` configuration including features:

  - `specA:id=1`

  - `specB:id=3`

- `package1` plus its dependencies, if any;

- `package3` plus its dependencies, if any.

#### 8.3.8. Merging configurations with layers

Layers are merged into configuration at the point where they are included into it with `include` element. It is important to keep that in mind.

Let’s consider the following example. Suppose `prod1` feature-pack defines this configuration:

    <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
        <layers>
            <include name="layer1"/>
            <include name="layer2"/>
        </layers>
        <!-- the rest of the configuration -->
    </config>

`prod2` feature-pack depends on `prod1` and defines this configuration:

    <config xmlns="urn:jboss:galleon:config:1.0" model="model1" name="name1">
        <layers>
            <include name="layer2"/>
            <include name="layer3"/>
        </layers>
        <!-- the rest of the configuration -->
    </config>

When `prod2` is installed, `layer2` will be included into `model1:name1` twice. Which may or may not create a confusion. First of all, in the given example, all the features added to `model1:name` in `prod1` are inherited by `model1:name1` in `prod2`, meaning `model1:name1` in `prod2` does not start empty. `layer1` and `layer2` have already been added to `model1:name1` in `prod1`. Including `layer2` into `model1:name1` in `prod2` does not make sense any more unless `model1:name1` in `prod1` has excluded and/or modified some feature configurations inherited from `layer2` and in `prod2` we want the original version of `layer2` configuration.

Whether including the same layer more than once into the same configuration creates a problem or not depends on the case. It’s important to keep in mind that every include means another merge of the layer.

If the content of the layer has not been adjusted in the configuration, the subsequent merge of the same layer will not result in any visible difference unless the layer includes features that have no identity. If a layer includes features that have no identity, there will be as many copies of those features in the configuration as the number of times the layer has been included into the configuration.

While the example above can easily be adjusted in case the inclusion of `layer2` actually is redundant by simply removing it from the list of layers in `prod2`, there could be situations where it’s more difficult to avoid multiple inclusions of the same layer. For example building up the example above, let’s assume that every one of `layer1`, `layer2` and `layer3` depends on layer called `base`.

In that case, `base` will be included once into `model1:name1` in `prod1` (despite the fact that both `layer1` and `layer2` depend on `base`, the provisioning mechanism will recognize that `base` is a common dependency of those layers and include it only once into `model1:name1` in `prod1`). But later, processing `model1:name` in `prod2`, it will include `base` again as a dependency of `layer3`.

| THIS CAN CHANGE. The mechanism can recognize that `base` has already been included and avoid including it again. The only possible issue is that if `layer3` really expects the original `base` configuration and the already included `base` has been somehow modified in between.

## 9. Provisioned installation configuration

### 9.1. Configuration model attributes

Every configuration must be associated with at least one of the following attributes:

- `name` - name of the configuration;

- `model` - name of the configuration model.

`name` and `model` attributes serve as the 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 the combination of the name and the model will be used as the identity of the configuration.

Feature-pack may include predefined configurations in its `configs` directory whose structure can be described as

    configs/
    |- model1/
    | |- name1/
    | |  `- config.xml
    | | ...
    | |- nameN/
    | |  `- config.xml
    | `- model.xml
    | ...
    |- modelM/
    | |- name1/
    | |  `- config.xml
    | | ...
    | |- nameN/
    | |  `- config.xml
    | `- model.xml
    |- name1/
    |  `-config.xml
    | ...
    `- nameN/
       `-config.xml

If a configuration is associated with a name but not a model then its definition will be located in `configs/config_name/config.xml` and start with the following root element:

    <config xmlns="urn:jboss:galleon:config:1.0" name="config_name">
        <!-- skipped content -->
    </config>

If a configuration is associated only with a model then its definition will located in `configs/config_model/model.xml` and start with the following root element:

    <config xmlns="urn:jboss:galleon:config:1.0" model="config_model">
        <!-- skipped content -->
    </config>

If a configuration is associated with both model and a name its definition will be located in `configs/model_name/config_name/config.xml` and start with the following root element:

    <config xmlns="urn:jboss:galleon:config:1.0" model="model_name" name="config_name">
        <!-- skipped content -->
    </config>

Predefined configuration models can be referenced from `feature-pack.xml` file and customized (manipulated) in the provisioning configuration of the installation (which is also an XML file) using `config` elements. Every `config` element will include the corresponding `name` and possibly `model` attributes to specify the identity of the configuration it is targeting.

| Every `config` element in `feature-pack.xml` or installation provisioning configuration triggers installation of the configuration it is targeting.

That means, when a feature-pack is installed, by default all the configurations referenced from 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 in the provisioning configuration of the installation.

Here is an example of `feature-pack.xml` with `config` elements:

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

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

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

    </feature-pack>

### 9.2. Excluding default configs from the installation

The simplest way to exclude configs from the installation is

    <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.

The example above excludes all the configs, if the goal however is to exclude onyl a specific one, it can be done by providing the identity of the config using `exclude` element. For example, if a configuration was associated with a name but not any model then it would look like this:

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

And if the configuration was associated with a name and a model, both of them will 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. Named (name-only) configurations

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

fp1: 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.Final">
      <config name="config1"/>
    </feature-pack>

fp1: configs/config1/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

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

fp2: feature-pack.xml

    <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-pack>

fp2: configs/config1/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

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

Installation provisioning configuration

    <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` configurations. 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` configuration:

fp2: feature-pack.xml

    <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-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.2. 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.

fp1: 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.Final">
      <config name="main" model="modelA"/>
      <config name="main" model="modelB"/>
    </feature-pack>

fp1: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

fp1: configs/modelB/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

fp2: feature-pack.xml

    <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"/>
      <config name="main" model="modelB"/>
    </feature-pack>

fp2: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp2-modelA"/>
      </feature>
    </config>

fp2: configs/modelB/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelB">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp2-modelB"/>
      </feature>
    </config>

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

Table 3. modelA:main
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp1-modelA | fp2-modelA

Table 4. modelB:main
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp1-modelB | fp2-modelB

#### 9.4.3. Model-only configurations

Model-only configurations are associated only with a model by means of `model` attribute of `config` element but are not associated with any name specific name.

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 configurations are always added into the configuration before the named configurations, i.e. named configurations will be added on top of the model-only ones and will overwrite them.

| At the end, a provisioned installation will only contain the named configurations but not the model-only ones. Model-only configurations are always merged into the named configurations.

| A model-only configuration is merged into all the named configurations of the installation associated with the same model as the model-only configuration.

Let’s look at an example. Suppose we have two feature-packs: `fp1` and `fp2`.

`fp1` is defined as

fp1: 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.Final">
      <config name="main" model="modelB"/>
    </feature-pack>

And includes the following configurations

fp1: configs/modelA/model.xml

    <config xmlns="urn:jboss:galleon:config:1.0" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="a" value="fp1-modelA"/>
        <param name="b" value="fp1-modelA"/>
      </feature>
    </config>

fp1: configs/modelB/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelB">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp1-modelB"/>
      </feature>
    </config>

`fp2` is defined as

fp2: feature-pack.xml

    <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"/>
      <config name="test" model="modelA"/>
      <config name="test" model="modelB"/>
    </feature-pack>

And includes the following configurations

fp2: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp2-modelA"/>
      </feature>
    </config>

fp2: configs/modelA/test/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

fp2: configs/modelB/model.xml

    <config xmlns="urn:jboss:galleon:config:1.0" model="modelB">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="a" value="fp2-modelB"/>
        <param name="b" value="fp2-modelB"/>
      </feature>
    </config>

fp2: configs/modelB/test/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

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

Table 5. modelA:main
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp1-modelA | fp2-modelA

Table 6. modelA:test
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp1-modelA | fp1-modelA
fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature2 | 1 | fp2-modelA | fp2-modelA

Table 7. modelB:main
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp2-modelB | fp1-modelB

Table 8. modelB:test
Feature spec origin | Feature spec | id | a | b
--- | --- | --- | --- | ---
fp1@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature1 | 1 | fp2-modelB | fp2-modelB
fp2@maven(org.jboss.universe:community-universe):1#1.0.0.Final | feature2 | 1 | fp2-modelB | fp2-modelB

##### Excluding model-only configurations with 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 simply be ignored by the provisioning mechanism.

| Configuration model designers are encouraged to model configurations in a way that model-only configurations represent an essential part of any configuration of that model and its runtime dependencies 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 the relevant part of the configuration:

    <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 configurations associated with the specified model.

Let’s imagine we have the following feature-pack `fp1`

fp1: 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.Final">
      <config name="main" model="modelA"/>
    </feature-pack>

with the following configurations

fp1: configs/modelA/model.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

fp1: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp1-modelA-main"/>
      </feature>
    </config>

And feature-pack `fp2`

fp2: feature-pack.xml

    <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-pack>

With the following configuration

fp2: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="c" value="fp2-modelA-main"/>
      </feature>
    </config>

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

Table 9. modelA:main
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.

fp2: feature-pack.xml

    <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-pack>

If we install `fp2` now, the provisioned configuration will contain

Table 10. modelA:main
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 `fp1` is installed as a dependency of `fp2` and its `modelA` configuration is considered being essential for any named configuration of the model. In case it still has to be excluded from the provisioned configuration it can be done by adding `named-only-models="false"` attribute to `exclude` element, e.g.

fp2: feature-pack.xml

    <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-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

Table 11. modelA:main
Feature spec origin | Feature spec | id | c
--- | --- | --- | ---
org.jboss.pm.test:fp1:1.0.0.Final | feature1 | 1 | fp2-modelA-main

##### Disabling inheritance of 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.

fp1: 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.Final">
      <config name="main" model="modelA"/>
    </feature-pack>

fp1: configs/modelA/model.xml

    <config xmlns="urn:jboss:galleon:config:1.0" 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>

fp1: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="b" value="fp1-modelA-main"/>
      </feature>
    </config>

fp2: feature-pack.xml

    <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"/> (1)
        </dependency>
      </dependencies>
      <config name="main" model="modelA"/>
    </feature-pack>

1 | the default configurations from `fp1` are going to be ignored

fp2: configs/modelA/main/config.xml

    <config xmlns="urn:jboss:galleon:config:1.0" name="main" model="modelA">
      <feature spec="feature1">
        <param name="id" value="1"/>
        <param name="c" value="fp2-modelA-main"/>
      </feature>
    </config>

With `inherit="false"` attribute of `default-configs` element we indicated that the default configurations 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 named and model-only configurations:

fp2: feature-pack.xml

    <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-pack>

The installation provisioned from `fp2` will include the following configuration

Table 12. modelA:main
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

| Although this chapter is describing `config` element as a child of `feature-pack` element, the same applies to the root `config` element from `config.xml` and `model.xml` files.

`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);

- layers;

- configs;

- 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. Handling user-managed content

Once an installation has been built, a user or a process (on behalf of the user) may apply certain changes to the content of the installation such as add, edit or remove files and/or directories.

| Since these kind of changes are not performed by the provisioning mechanism, it is the responsibility of the user to apply them in a safe manner and not break the installation by introducing some sort of unsatisfied dependencies or violating integrity constraints.

Since these kind of changes are usually going to be applied after the installation has been built they don’t interfere with the provisioning process. That is until the next (provisioning state) update.

When a user requests a version update or install/uninstall a patch or a feature-pack, or an undo for the installation that contains user-managed content or changes, the provisioning mechanism detects what exactly has changed since the last provisioned state.

If no user changes have been detected, the updated version of the installation will replace the current one. However, if the provisioning mechanism did detect certain changes to the last provisioned state (in the form of added/remove files and/or directories or editted files), those changes will be respected and re-applied to the updated installation state, i.e.

- files and/or directories added to the previous installation state will be added to the updated installation state;

- files and/or directories removed from the previous installation state will be removed from the updated installation state;

- files editted in the previous installation state will be copied over to the updated installation state.

| The provisioning mechanism DOES NOT perform 3-way merges on files that have changed in the updated installation state since the last provisioned state and that have also been modified by the user.

### 11.1. Application of user changes to the updated installation state

Table 13. User-added file
Target in the updated state | Change applied to the updated state
--- | ---
Not found | The user-added file is copied to the updated state
Found and matches the file added by the user | None

Found and is different from the file added by the user

- A copy of the file from the updated state is created with suffix .glnew

- The user-added file is copied to the updated state (replacing the existing one)

Table 14. User-modified file
Target in the updated state | Change applied to the updated state
--- | ---
Not found | The user-modified file is copied to the updated state and a warning is logged saying that the (equivalent of the) file modified in the previous state is not found in the updated state
Found and matches the resulting file modified by the user | None

Found and is different from the resulting file modified by the user

- A copy of the file from the updated state is created with suffix .glnew

- The user-modified file is copied to the updated state (replacing the existing one)

Table 15. User-removed file or directory
Target in the updated state | Change applied to the updated state
--- | ---
Not found | None
Found | The target is removed from the updated installation

Table 16. User-created directory
Target in the updated state | Change applied to the updated state
--- | ---
Not found | The corresponding directory is created in the updated state
Found | None

### 11.2. Protected system files

An installation may contain files and directories that are meant to be managed exclusively by feature-packs and the provisioning tools and not by users. For example, core system libraries of the installation. Such paths can be marked as system-paths in the `feature-pack.xml`.

If during an update a file matching a feature-pack’s system-path was found to be modified by a user, the provisioning mechanism will create a copy of the user-modified file adding the .glold suffix to it and replace the original one with the file provided by the feature-pack.

Table 17. User-added file matching a system-path
Target path in the updated state | Change applied to the target path
--- | ---
Not found | The user-added file is copied to the updated state
Found and matches the file added by the user | None

Found and is different from the file added by the user

- A copy of the user-added file is created with the .glold suffix

- The file from the updated state replaces the existing one

Table 18. User-modified file matching a system-path
Target path in the updated state | Change applied to the target path
--- | ---
Not found | The user-modified file is copied to the updated state and a warning is logged indicating that the (equivalent of the) file modified in the previous state is not found in the updated state
Found and matches the resulting file modified by the user | None

Found and is different from the resulting file modified by the user

- A copy of the user-added file is created with the .glold suffix

- The file from the updated state replaces the existing one

Table 19. User-removed file or directory matching a system-path
Target path in the updated state | Change applied to the target path
--- | ---
Not found | None
Found | The target is restored to the updated state.

Table 20. User-created directory matching a system-path
Target path in the updated state | Change applied to the target path
--- | ---
Not found | The corresponding directory is created in the updated state
Found | None

## 12. Provisioning options

Every provisioning action (such as `provision`, `install`, `uninstall`, etc) may accept provisioning options. Provisioning options may control various things, e.g. enable debug mode in one of the product-specific provisioning plugins, activate a certain provisioning mode, etc.

### 12.1. Persistent and non-persistent options

Provisioning options can be persistent and non-persistent.

Persistent options are persisted in the provisioning configuration file when the provisioning process has succesfully finished. E.g. if `prod1` is installed with `option1`, the provisioned configuration will look like this

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <options>
            <option name="option1" value="true"/>
        </options>
    </installation>

Now if the user installs `prod2`, `option1` will still be effective during re-provisioning and the config will change to

    <installation xmlns="urn:jboss:galleon:provisioning:2.0">
        <feature-pack location="prod1@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <feature-pack location="prod2@maven(org.jboss.universe:community-universe):1#1.0.0.Final"/>
        <options>
            <option name="option1" value="true"/>
        </options>
    </installation>

| Option values are not necessarily `true` or `false`, they may have various values. The only restriction is they must have some value.

Non-persistent options, on the other hand, are not automatically stored in the provisioning configuration. They are used only for the provisioning action they were specified for.

### 12.2. Built-in and product-specific options

Provisioning options can be provided by the core provisioning mechanism itself and the product-specific provisioning plugins.

#### 12.2.1. Built-in provisioning options

Table 21. Built-in provisioning options
Name | Purpose | Value set
config-stability-level | Stability level for configs. This stability level is used to enable the stability level of all features present in the generated configurations. By default the configs stability level set in the feature-pack is used. | `default`, `community`, `preview`, `experimental`
export-system-paths | Store the system paths declared by Feature Packs in .galleon/systempaths.txt | `false` (default), `true`
ignore-not-excluded-layers | Suppresses the error when layers configured to be excluded would not have otherwise been installed | `false` (default), `true`
optional-packages | Optional package dependencies inclusion policy | `all` (default), `none`, `passive`, `passive+`
package-stability-level | Stability level for packages. This stability level is used to set the stability level of all provisioned packages. By default the packages stability level set in the feature-pack is used. | `default`, `community`, `preview`, `experimental`
stability-level | Stability level for both configs and packages. This option is a convenience allowing to set both the config and package stability level using a single option. It can’t be set when `config-stability-level` or `package-stability-level` are set | `default`, `community`, `preview`, `experimental`
store-input-provisioning-config | Store the provisioning config received as input in the generated .galleon/provisioning.xml file | `false` (default), `true`
version-convergence | Disables or enables the dependency version convergence | `first-processed` (default), `fail`

#### 12.2.2. Product provisioning options

Product-specific provisioning options are exposed by the product-specific provisioning plugins attached to the feature-packs.

## 13. Stability Level

A level of stability can be associated to features and packages.

Stability levels are ordered in the following way:

`default` (the higher level of stability) > `community` > `preview` > `experimental` (the lower stability level)

A feature-pack can contain features and packages at different level of stability, allowing to provision installations at different stability levels.

### 13.1. Default stability levels

When building a feature-pack, the `<feature-pack>` XML element contained in the `feature-pack.xml` descriptor can include attributes to specify the default stability levels that will be enabled when using the feature-pack during provisioning. If no such stability levels exist, `default` level is assumed.

The stability attributes are:

- `config-stability-level="<default|community|preview|experimental>"` attribute is used to declare the default stability level of the features present in the provisioned configurations.

- `package-stability-level="<default|community|preview|experimental>"` attribute is used to declare the default stability level of the provisioned packages.

### 13.2. Stability levels can be overridden at provisioning time

It is possible to control the expected level of stability at provisioning time by means of the following Galleon options:

- `config-stability-level=<default|community|preview|experimental>`: To enable a given stability level for the provisioned configurations.

- `package-stability-level=<default|community|preview|experimental>`: To enable a given stability level for the provisioned packages.

- `stability-level=<default|community|preview|experimental>`: An option to enable both configs and packages stability levels. It can’t be set when `config-stability-level` or `package-stability-level` are set.

## 14. 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>6.0.0.Final</version>
    </dependency>

Table 22. 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

Unresolved directive in maven-plugin/index.adoc - include::../../../maven-plugin/target/generated-sources/plugin/install-feature-pack-mojo.adoc[]

### 14.1. provision

#### 14.1.1. galleon:provision

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

#### 14.1.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>

#### 14.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 23. 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 24. Optional Parameters
Name | Type | Since | Description
`[configs]` | `List` | `-` | A list of custom configurations to install. Alias is: `configurations`.
`[customConfig]` | `File` | `-` | Path to a file containing `config` that should be installed. Alias is: `custom-config`.
`[logTime]` | `boolean` | `-` | Whether to log provisioning time at the end Default value is: `false`. Alias is: `log-time`.
`[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: `false`. Alias is: `offline`.
`[pluginOptions]` | `Map` | `-` | Arbitrary plugin options. Alias is: `plugin-options`.
`[recordState]` | `boolean` | `-` | Whether to record provisioned state in .galleon directory. Default value is: `true`. Alias is: `record-state`.
`[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`.
`[skip]` | `boolean` | `4.2.6` | Specifies whether the provisioning should be skipped. Default value is: `false`. User property is: `galleon.skip`.

#### 14.1.4. Parameter Details

configs
A list of custom configurations to install.

- Type: `java.util.List`

- Required: `No`

- Alias: `configurations`

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`

logTime
Whether to log provisioning time at the end

- Type: `boolean`

- Required: `No`

- Default: `false`

- Alias: `log-time`

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: `false`

- Alias: `offline`

pluginOptions
Arbitrary plugin options.

- Type: `java.util.Map`

- Required: `No`

- Alias: `plugin-options`

recordState
Whether to record provisioned state in .galleon directory.

- Type: `boolean`

- Required: `No`

- Default: `true`

- Alias: `record-state`

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`

skip
Specifies whether the provisioning should be skipped.

- Type: `boolean`

- Since: `4.2.6`

- Required: `No`

- User Property: `galleon.skip`

- Default: `false`

Table 25. 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>

### 14.2. provision-file

#### 14.2.1. galleon:provision-file

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

#### 14.2.2. Description

This maven plugin provisions an installation from a provisioning.xml file. If the target installation directory already contains an installation, the existing installation will be fully replaced with the newly provisioned one.

#### 14.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 26. Required Parameters
Name | Type | Since | Description
`[installDir]` | `File` | `-` | The target installation directory. Alias is: `install-dir`.
`[provisioningFile]` | `File` | `-` | Path to a provisioning file located inside the current maven project used to provision the server. Alias is: `provisioning-file`.

Table 27. Optional Parameters
Name | Type | Since | Description
`[logTime]` | `boolean` | `-` | Whether to log provisioning time at the end Default value is: `false`. Alias is: `log-time`.
`[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: `false`. Alias is: `offline`.
`[pluginOptions]` | `Map` | `-` | Arbitrary plugin options. Alias is: `plugin-options`.
`[recordState]` | `boolean` | `-` | Whether to record provisioned state in .galleon directory. Default value is: `true`. Alias is: `record-state`.
`[skip]` | `boolean` | `4.2.6` | Specifies whether the provisioning should be skipped. Default value is: `false`. User property is: `galleon.skip`.

#### 14.2.4. Parameter Details

installDir
The target installation directory.

- Type: `java.io.File`

- Required: `Yes`

- Alias: `install-dir`

logTime
Whether to log provisioning time at the end

- Type: `boolean`

- Required: `No`

- Default: `false`

- Alias: `log-time`

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: `false`

- Alias: `offline`

pluginOptions
Arbitrary plugin options.

- Type: `java.util.Map`

- Required: `No`

- Alias: `plugin-options`

provisioningFile
Path to a provisioning file located inside the current maven project used to provision the server.

- Type: `java.io.File`

- Required: `Yes`

- Alias: `provisioning-file`

recordState
Whether to record provisioned state in .galleon directory.

- Type: `boolean`

- Required: `No`

- Default: `true`

- Alias: `record-state`

skip
Specifies whether the provisioning should be skipped.

- Type: `boolean`

- Since: `4.2.6`

- Required: `No`

- User Property: `galleon.skip`

- Default: `false`

## 15. 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.

Launching the tool without any argument starts an interactive shell. Type exit to exit the tool.
Launching the tool with a command as argument will execute the command and exit, eg: galleon.sh install wildfly-core:current --dir=myinstallation
Launching the tool with --file=<path to script file> will execute the set of commands and exit.
Launching the tool with --help will display the descriptions of all available options and commands.

### 15.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.

### 15.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:

update --feature-packs=wildfly

### 15.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 get-info wildfly:current#1.0.0-Alpha1

### 15.4. Listing latest available feature-packs

[/]$ list-feature-packs [--all-frequencies] [--universe=<universe id>]

This command lists all the final feature packs present in all the installed universes.
The command looks in the current directory and its parent hierarchy for a possible installation in which some universes would have been added. By default the builtin universe is used.
If --all-frequencies option is set, then the latest build of all frequencies are displayed.
If --universe option is set, the command lists the feature packs of this universe.

| The information displayed by this command can be re-used when installing, updating features-packs.

### 15.5. Searching for feature-packs

[/]$ find <pattern> [--universe=<universe id>] [--resolved-only]

This command searches for all the feature pack builds present in all the installed universes that match the provided pattern.
The command looks in the current directory and its parent hierarchy for a possible installation in which some universes would have been added. By default the builtin universe is used.
If --universe option is set, the command searches for feature packs inside this universe.
If --resolved-only option is set, the command only searches for feature packs installed in local repositories.

| The information displayed by this command can be re-used when installing, updating features-packs.

### 15.6. 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 get-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.

### 15.7. Installing a subset of feature-pack configurations

When installing a feature-pack, all its default configurations are installed. Use the --default-configs=<comma separated list of config_model/config_name> option to specify the subset of configurations to install.

### 15.8. Installing feature-pack layers

The install command can be used to install a subset of feature-pack features. Such subset are called layers. When installing layers, a custom configuration is generated.

install <[FPL|FPID] | [--file=<path to fp zip file>]> [--dir=<installation dir>] [--layers=<comma separated list of layers>] [--config=<layers_model/configuration_name>]

In order to exclude an optional layer on which a layer from the list depends on, prefix the excluded layer with '-'. In order to un-exclude a layer already excluded in the current installation, prefix the layer with '+'.

NB: When installing layers, the existing provisioned installation (if any) is updated with the set of layers.

- If some layers to install are already installed, they are ignored.

- If some layers to exclude are already excluded, they are ignored.

- If some layers to install are excluded from the existing installation, they are first un-excluded and installed.

- If some layers to exclude are included in the existing installation, the command will fail. You can only exclude not directly included layers.

- If some layers to un-exclude are not excluded, the command will fail.

- If some layers to exclude are not optional dependencies of the layers to install (or from already installed layers), the command will fail. You can only exclude layers that are optional dependencies.

If no model name is provided, the CLI tries to identify the default model contained in the feature-pack. If no configuration name is provided, the <layers_model>.xml is used as the generated configuration file name.

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

### 15.9. 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.

### 15.10. Un-doing the last provisioning command

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

This will revert the installation to the previous installed state.

### 15.11. 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]

### 15.12. 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.

### 15.13. Checking for updates

check-updates [--dir=<installation dir>] [--include-all-dependencies] [--feature-packs=<list of feature-pack producers>]

If no products are provided, all installed products are checked for updates.

### 15.14. Updating an installation

The update command allows to update an installation to the latest available versions of installed feature-packs.

update [--dir=<installation dir>] [--include-all-dependencies] [--yes] [--feature-packs=<list of feature-pack producers or locations>] [feature-pack specific options]

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

NB: If the option --feature-packs contains feature-pack locations with versions, then these versions are used to update the feature-packs.

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:
installation get-info [--dir=<installation dir>] --type=options
You can then use the listed options (if any) to customize your update command.

### 15.15. Retrieving changes applied to an installation

In order to visualize files you have added, removed or modified, use the command get-changes [--dir=<installation>].
In the CLI output added files are prefixed by '+', removed ones by '-' and modified ones by 'M'.

### 15.16. Persisting changes applied to an installation

Installed feature-packs optionally support persistence of changes into the provisioning configuration. As an example, wildfly feature-packs persist configuration changes into the provisioning config.

Use the command persist-changes [--dir=<installation>] to persist the changes.

NB: If the installed feature-packs don’t support the ability to merge changes into the provisioning configuration, this operation has no side effect.

### 15.17. Observing an installation

[my-dir]$ installation get-info [--dir=installation] --type=[all|configs|dependencies|layers|optional-packages|options|patches|universes]

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

### 15.18. Observing a feature-pack

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

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

### 15.19. Optional packages

When getting information on an installation or a feature-pack, using --type=optional-packages option, you can retrieve the list of optional packages. At installation time the set of optional packages installed is controlled by the option --optional-packages=<all|none|passive|passive+>.

There are 2 kind of optional packages. passive ones, that are installed only if all their dependencies are installed and optional ones that have no requirements on their dependencies. Generally passive optional packages shouldn’t be excluded from an installation. They are needed for the package to properly operate when the other packages on which it depends are provisioned. Optional packages that are not passive can be excluded if not needed (according to the execution context).

When installing a complete feature-pack or installing a default configuration, the default value for --optional-packages is all (all optional and passive packages are installed).

When installing layers with the install commands the default value for --optional-packages is passive+ (all optional and passive packages that have all their dependencies installed are installed).

You can override these default values by using the --optional-packages option. Use none value to not install any optional nor passive packages, passive value to only install passive packages that have all their dependencies installed.

### 15.20. Managing the local cache of feature-packs

When a feature-pack is internally resolved (at install time, to expose information, to retrieve plugin options, …​). The feature-pack is added to a local cache. This cache is re-used to speed-up future resolutions. The CLI cleanup un-used feature-pack from the cache that are older than one month.

You can import (and optionally install in the universe for later resolution) a feature-pack zip file in the cache.

[my-dir]$ feature-pack import <path to fp zip file> [--install-in-universe=<true|false>]

You can clear the cache fully (NB: this will have a performance impact for future resolution).

[my-dir]$ feature-pack clear-cache

### 15.21. Exporting an installation to xml

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

### 15.22. Provisioning an installation from xml

[my-dir]$ 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).

### 15.23. 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:

installation set-history-limit <history size limit> [--dir=<installation dir>]

To retrieve the history size limit do:

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

### 15.24. Managing installation universes

A universe can be added/removed to/from an existing installation.

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

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

### 15.25. Directory option

Some commands (eg: install, get-info, check-updates, …​) allow you to optionally provide a target directory thanks to the --dir=<path> option. If no directory is provided, the command will lookup for an existing installation in the current directory (that you can change with the cd command) and its parent directories hierarchy. If no installation exists, the command will abort.

There are some exceptions to this installation lookup. install and provision commands expect the current directory to be empty or to be the root of an installation. uninstall, undo and update commands expect the current directory to be the root of an installation.

### 15.26. Exploring an installation or a feature-pack.

The tool allows you to switch to a state edit mode in which you can observe and edit a provisioning state in memory (without actually impacting the installation files).

To explore an installation:
[my-dir]$ state edit [<installation dir>]
[!edit!my-dir!/]$
After this point, the tool switched to edit mode with a set of new commands available.

| Type help to list the set of available commands in this mode.

To explore a feature-pack:
[my-dir]$ state new
[!edit!/]$ add-dependency <[FPL|FPID] --default-configs-inherit --packages-inherit

Once exploring, prompt, ls, cd and pwd commands are bound to the feature-pack (or installation) exposed file-system.
Use leave-state to switch the tool back to its nominal mode.

[!edit!/]$ ls
configs
dependencies
feature-specs
packages
[!edit!/]$ leave-state
[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.

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

### 15.27. Searching the current state

When in edit mode, one can search for packages and features.

[!edit!/]$ 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.

### 15.28. 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 dir | path to provisioning XML file>
[!edit!/]$ ls
configs
dependencies
feature-specs
packages

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: undo.

NB: Use leave-state to leave the edit mode.

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

### 15.29. Exporting or provisioning the current state

In edit mode, one can export the provisioning XML file or directly provision from the current state:

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

| Use export to validate that what you get in the XML is in sync with the expose state.

| Exporting a state without any XML target file will display the XML content in the CLI console.

| The command 'get-info' can be used to get high level information.

### 15.30. Adding a feature-pack

[!edit!/]$ add-dependency <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.

### 15.31. Removing a feature-pack

[!edit!/]$ remove-dependency <FPL|FPID>

### 15.32. Including a default configuration

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

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

### 15.33. Removing an included default configuration

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

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

### 15.34. Excluding a default configuration

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

Origin is optional, by default will be excluded from all feature-packs that expose it.

### 15.35. Removing an excluded default configuration

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

The completer only proposes the set of configurations that have been previously excluded. Origin is optional, by default will be removed from all feature-packs that exclude it.

### 15.36. Including layers into a configuration

NB: Prior to be able to include layers into a configuration you need an included default or locally defined configuration. To define a new configuration call define-config --model=<config model> --name=<config name>

[!edit!/]$ include-layers <config model/config name> --layers=<comma separated list of layers>

NB: The completers for both configuration and layers propose you with the existing configurations and layers not already included.

### 15.37. Removing included layers from a configuration

[!edit!/]$ remove-included-layers <config model/config name> --layers=<comma separated list of included layers>

NB: You can only remove layers that have been explicitly included in your local configuration. Layers included in a default configuration can be excluded but their inclusion can’t be removed.

### 15.38. Excluding layers from a configuration

NB: Prior to be able to exclude layers from a configuration you need an included default or locally defined configuration that contain layers.

[!edit!/]$ exclude-layers <config model/config name> --layers=<comma separated list of layers>

NB: The completers for both configuration and layers propose you with the existing configurations and included layers.

### 15.39. Removing excluded layers from a configuration

[!edit!/]$ remove-excluded-layers <config model/config name> --layers=<comma separated list of excluded layers>

NB: You can only remove layers that have been explicitly excluded in your local configuration.

### 15.40. Reseting a configuration

[!edit!/]$ reset-config <model>/<name>

The custom content of this configuration is removed.

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

### 15.41. Including a default package

[!edit!/]$ include-package <fp origin>/<package name>

### 15.42. Removing an included default package

[!edit!/]$ remove-included-package <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 feature-packs that exclude it.

### 15.43. Excluding a default package

[!edit!/]$ exclude-package <fp origin>/<package name>

### 15.44. Removing an excluded default package

[!edit!/]$ remove-excluded-package <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 feature-packs that exclude it.

### 15.45. Adding a new feature

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

For example:
add-feature 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.

### 15.46. Removing a feature

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

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

### 15.47. Managing universes

A universe can be added/removed to/from a state.

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

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

## 16. CLI tool Maven configuration

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

- http://repository.jboss.org/nexus/content/groups/public/

- http://repo1.maven.org/maven2/

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

### 16.1. Relying on maven settings

In order to makes the cli to use a maven settings file call: maven set-settings-file <path to settings xml file> In order to remove the reference to the settings file call: maven reset-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.

The following default repositories are enabled if not already present in the enabled profiles:

- `maven-central`: `https://repo1.maven.org/maven2/`

- `jboss-public-repository-group`: `https://repository.jboss.org/nexus/content/groups/public/`

- `jboss-ga`: `https://maven.repository.redhat.com/ga/`

NB: These default repositories can be mirrored by using their ids.

### 16.2. Adding new remote repositories

Use the following command to add new remote repositories:
maven add-repository --name=myrepo --url=http://foorepo [--release-update-policy=<policy>] [--snapshot-update-policy=<policy>] [--type=<type>] [--enable-release=[true|false] [--enable-snapshot=[true|false]

NB: The type, release update policy, snapshot update policy and enable/disable of snapshot/release are optional and have default values.

### 16.3. Default Repository policies

Daily update for releases, never update for snapshots.
Warn if checksum differs.

Snapshots are not resolved from remote repositories.
Releases are resolved from remote repositories.

Update polices can be changed by calling:
maven set-release-update-policy [<always|daily|interval:|never>]
maven set-snapshot-update-policy [<always|daily|interval:|never>]

Activation of snapshot/release resolution can be changed by calling:
maven enable-snapshot [<true|false>]
maven enable-release [<true|false>]

NB: A reset command can be called for any of these changes to set the value back to its default value.

### 16.4. Advanced maven configuration

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

### 16.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: maven set-local-repository <path to your local repository directory>
In order to reset to the default local maven repository call: maven reset-local-repository

### 16.6. Offline mode

By default maven is in online mode. In order to switch to offline use the command maven enable-offline <true|false>
In order to reset to the default mode call: maven reset-offline

### 16.7. Display maven configuration

Call command: maven get-info

### 16.8. 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.

### 16.9. Resolving 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: maven resolve-feature-pack <feature-pack location> [--verbose]

### 16.10. 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.