2. Provisioning Applications and Content

Provisioning is a way that administrators can define and control applications, from development to production. The ultimate effect of the provisioning system is simplifying how applications are deployed. Administrators can control which versions of the same application are deployed to different resources, from different content sources, within the same application definition (the bundle definition). Resources can be reverted to different versions or jump ahead in deployment.

2.1. An Introduction to Provisioning Content Bundles

Provisioning takes one set of files (a bundle) and then pushes it to a platform or an application server (the destination). There are more complex ways of defining the content, the destinations, and the rules for that deployment, but the core of the way that provisioning handles content is to take versioned bundles and send it to the designated resource.
Provisioning works with compatible groups, not individual resources. Administrators can define groups based on disparate environments and consistently apply application changes (upgrades, new deployments, or reversions) across all group members, simultaneously.
And the type of content which can be deployed, itself, is flexible. A bundle can contain raw configuration files, scripts, ZIP archives, JAR files, or full application servers — the definition of content is fairly loose.
This is in contrast to the resource-level content management in JBoss ON. The type of content is relatively limited. Patches or configuration is applied per-resource. New applications can only be deployed as children of existing resources and it has to be another resource type.
Provisioning focuses on application management, not purely resource management.

2.1.1. Bundles: Content and Recipes

A bundle is a set of content, packaged in an archive. In real life, a bundle is usually an application, but it can also contain a set of configuration files, scripts, libraries, or any other content required to set up an application or a resource.
The purpose of a bundle is to take that defined set of content and allow JBoss ON to copy it onto a remote resource. The provisioning process basically builds the application on the targeted resource, so in that sense, the bundle is an application distribution. Each bundle version has its own recipe which tells JBoss ON what files exist in the bundle, any tokens which need to have real values supplied at deployment, and how to handle the bundle and existing files on the remote machine.
The recipe, configuration files, and content are all packaged together into the bundle. This is usually a ZIP file, which the agent unpacks during provisioning.
As with other content managed in JBoss ON, the bundle is versioned. Different versions can be deployed to different resources, which is good for handling different application streams in different environments (say, QA and production). Versioning bundles also allows JBoss ON to revert or upgrade bundles easily.
The bundle can contain almost any kind of content, but it has to follow a certain structure for it to be properly deployed by JBoss ON. The recipe is an Ant build file called deploy.xml; this must always be located in the top level of the bundle archive.
Past the placement of the recipe, the files and directories within the bundle can be located anywhere in the archive. In fact, the files do not necessarily need to be included in the bundle file at all; when the bundle is created, any or all files for the bundle can be pulled off a URL, which allows the content to be taken from an SVN or GIT repository, FTP server, or website.
Bundle Layout

Figure 1. Bundle Layout


The bundle archive can contain other archives, such as JAR, WAR, and ZIP files. Provisioning uses Ant to build out bundles on the target machine, so any files which Ant can process can be processed as part of the bundle. The Ant provisioning system can process WAR, JAR, and ZIP archive files.

2.1.2. Destinations (and Bundle Deployments)

Uploading a bundle to JBoss ON does not push the bundle anywhere, so it is not automatically associated with a resource or group. (Bundles, unlike content, is resource-independent. It exists as its own definition in JBoss ON, apart from the inventory.) When the bundle is actually provisioned, then the provisioning wizard prompts for the administrator to define the definition.
A destination is the place where bundles get deployed. The destination is the combination of three elements:
  • A compatible resource group (of either platforms or JBoss servers)
  • A base location, which is the root directory to use to deploy the bundle. Resource plug-ins define a base location for that specific resource type in the <bundle-target> element. This can be the root directory or, for JBoss servers, common directories like the profile directory. There may be multiple available base locations.
  • The deployment directory, which is a subdirectory beneath the base directory where the bundle content is actually sent.
For example, an administrator wants to deploy a web application to a JBoss EAP 5 server, in the deploy/myApp/ directory. The JBoss AS5 plug-in defines two possible base locations, one for the installation directory and one for the profile directory. The administrator chooses the profile directory, since the application is an exploded JAR file. The agent then derives the real, absolute path of the application from those three elements:
JBoss AS group + {$PROFILE_DIR} + deploy/myApp/
If the PROFILE_DIR is /opt/jbossas/default/server/, then the destination is:
/opt/jbossas/default/server/deploy/myApp/
If the same resource group contains a JBoss EAP instance running on a Windows server, with a PROFILE_DIR of C:\jbossas\server\, then the path is derived slightly differently, appropriate for the platform:
C:\jbossas\default\server\deploy\myApp
It is up to the agent, based on the platform and resource information for its inventory, to determine the absolute path for the destination to which the bundle should be deployed.
Once a bundle is actually deployed to a destination, then that association — bundle version and destination — is the bundle deployment.
Bundles, Versions, and Destinations

Figure 2. Bundles, Versions, and Destinations


2.1.3. File Handling During Provisioning

A bundle file just contains a set of files and directories that should be pushed to a resource. However, the provisioning process does not merely copy the files over to the deployment directory; provisioning treats a bundle as, essentially, a template that defines the entire content structure for the deployment directory.
For example, a bundle contains these files:
app.conf
lib/myapp.jar
If the deployment directory is deploy/, then the final directory configuration is going to be:
deploy/app.conf
deploy/lib/myapp.jar
By default, if there are any files in deploy/, then they will be removed before the bundle is copied over, so that the deployment directory looks exactly the way the bundle is configured.
For an application-specific destination, like deploy/myApp/, then that behavior is totally acceptable because the defined application content should be the only content in that directory. However, bundles can contain a variety of different files and directories and can be deployed almost anywhere on a platform or within a JBoss server. In a lot of deployment scenarios, the deployment directory will have existing data that should be preserved.
The deployment directory is the root directory for the bundle. The bundle can define a parameter that tells the provisioning process how to handle data in that root directory. The manageRootDir option tells provisioning to delete everything and force the directory to match the bundle content. In other words, the bundle defines the content and structure of the root directory. Alternatively, if the data in that directory must be saved, the manageRootDir option can be set to false, which means that provisioning will copy over the bundle and create the appropriate files and subdirectories, but it will not manage (remove) the existing content in the directory.

NOTE

Any existing content in the root directory is backed up before it is deleted, so it can be restored later.
After the initial deployment, there can be instances where files are added to the deployment directory, such as log files or additional data.
Within the deployment directory, the provisioning process overwrites any bundle-associated files with the latest version and removes any files that are not part of the bundle. Log files, other bundles files, and other data — as with the root directory — need to be preserved between upgrades. Those known files and directories can be called out in the recipe using the <rhq:ignore> element, which tells the provisioning process to ignore those files within the deployment directory.
Setting these options in the recipe is described in Section 2.3.2.2, “Saving Files During Provisioning”.

IMPORTANT

Purging a bundle deployment removes all of the bundle files from the target resources.
The exact files that are purged mirrors how the bundle manages the deployment directory. By default, purging includes deleting the deployment directory (manageRootDir=true). If the deployment directory is used by other applications – like an app server deploy/ directory — then those other applications or files will also be deleted. After purging, there is no live deployment and nothing to revert.

2.1.4. Requirements and Resource Types

By default, three resource types support bundles:
  • Platforms, all types
  • JBoss AS 4
  • JBoss AS 5 and any server which uses the JBoss AS 5 plug-in
Bundle support is defined in the plug-in descriptor, so custom plug-ins can be created that add bundle support for those resource types. For examples of writing agent plug-ins with bundle support, see "Writing Custom JBoss ON Plug-ins."

2.1.5. Additional Ant References

Provisioning relies on Ant configuration and tasks, so a good understanding of the Ant build process is beneficial. There are several resources for additional Ant information: