Chapter 17. Patching
17.1. Patching a Fabric Container with a Rollup Patch
- Distribution of patched artifacts
- Configuration of the underlying container
patch:*commands from the console of the root container. If you are planning to distribute patch artifacts through the Maven proxy, it is convenient to choose the root container to be the ensemble container that is currently the master of the Maven proxy cluster (see Chapter 14, Fabric Maven Proxies). This would ensure that patch artifacts can immediately be downloaded by other containers in the cluster.
Distribution of patch artifacts
- Through the Maven proxy (default approach)—when you add a rollup patch to your root container (using the
patch:addcommand), the patch artifacts are installed into the root container's
system/directory, whose directory structure is laid out like a Maven repository. The root container can then serve up these patch artifacts to remote containers by behaving as a Maven proxy, enabling remote containers to download the required Maven artifacts (this process is managed by the Fabric agent running on each Fabric container). Alternatively, if you have installed the rollup patch to a container that is not hosting the Maven proxy, you can ensure that the patch artifacts are uploaded to the Maven proxy by invoking the
patch:fabric-installcommand with the
--uploadoption.There is a limitation to the Maven proxy approach, however, if the Fabric ensemble consists of multiple containers. In this case, it can happen that the Maven proxy fails over to a different ensemble container (not the original root container). This can result in the patch artifacts suddenly becoming unavailable to other containers in the fabric. If this occurs during the patching procedure, it will cause problems.NoteContainers that are added to an ensemble do not automatically deploy the Maven proxy. To enable the Maven proxy, make sure that the
fabricprofile is deployed in the container.For more details, see Chapter 14, Fabric Maven Proxies.
- Through a local repository (recommended approach)—to overcome the limitations of the Maven proxy approach, we recommend that you make the patch artifacts available directly to all of the containers in the Fabric by setting up a local repository on the file system. Assuming that you have a networked file system, all containers will be able to access the patch artifacts directly.For example, you might set up a local repository of patch artifacts, as follows:
- Given a rollup patch file, extract the contents of the
system/directory from the rollup patch file into the
repositories/subdirectory of a local Maven repository (which could be
~/.m2/repositoriesor any other location).
- Configure the Fabric agent and the Maven proxy to pick up artifacts from the local repository by editing the current version of the
defaultprofile, as follows:
profile-edit --append --pid io.fabric8.agent/org.ops4j.pax.url.mvn.defaultRepositories="file:///PathToRepository" defaultReplace
PathToRepositoryby the actual location of the local repository on your file system.NoteMake sure that you make the edits to the
defaultprofile for all relevant profile versions. If some of your containers are using a non-default profile version, repeat the
profile-editcommands while specifying the profile version explicitly as the last parameter.
karaf, and so on), the patching mechanism attempts to merge your changes with the changes introduced by the patch.
Configuration of the underlying container
lib/, and so on). When a Fabric container is upgraded to a patched version (for example, using the
fabric:container-upgradecommand), the container's Fabric agent checks whether the underlying container must be patched. If yes, the Fabric agent triggers the patching mechanism to update the underlying container. Moreover, if certain critical files are updated (for example,
lib/karaf.jar), the container status changes to
requires full restartafter the container is upgraded. This status indicates that a full manual restart is required (an automatic restart is not possible in this case).
io.fabric.version in the default profile
io.fabric.versionresource in the
defaultprofile plays a key role in the patching mechanism. This resource defines the version and build of JBoss Fuse and of all of its main components. When upgrading (or rolling back) a Fabric container to a new version, the Fabric agent checks the version and build of JBoss Fuse as defined in the
io.fabric.versionresource. If the JBoss Fuse version changes between the original profile version and the upgraded profile version, the Fabric agent knows that an upgrade of the underlying container is required when upgrading to this profile version.
Patching the patch mechanism
- Download the appropriate patch management package. From the JBoss Fuse 6.3.0 Software Downloads page, select a package named Red Hat JBoss Fuse 6.3.0 Rollup N on Karaf Update Installer, where N is the number of the particular rollup patch you are about to install.ImportantThe rollup number, N, of the downloaded patch management package must match the rollup number of the rollup patch you are about to install. For some rollup patches, there is no corresponding patch management package, in which case you can skip directly to the instructions for installing the rollup patch.
- Extract the contents of the patch management package,
patch-management-for-fuse-630-TargetVersion.zip, on top of the root container (that is, on top of the Fabric container that will be used to perform the remainder of the patching tasks). Use an archive utility to extract the contents on top of the root container installation, merging the contents of the archive
patches/directories with the container
patches/subdirectories.NoteIt does not matter whether the root container is running when you extract these files.
- Start the root container, if it is not already running.
- Create a new version, using the
fabric:version-createcommand (where we assume that the current profile version is
JBossFuse:karaf@root> fabric:version-create --parent 1.0 1.0.1 Created version: 1.0.1 as copy of: 1.0ImportantVersion names are important! The tooling sorts version names based on the numeric version string, according to major.minor numbering, to determine the version on which to base a new one. You can safely add a text description to a version name as long as you append it to the end of the generated default name like this:
1.3 [.description]. If you abandon the default naming convention and use a textual name instead (for example, Patch051312), the next version you create will be based, not on the last version (Patch051312), but on the highest-numbered version determined by dot syntax.
- Update the
patchproperty in the
io.fabric8.versionPID in the version
defaultprofile, by entering the following Karaf console command:
profile-edit --pid io.fabric8.version/patch=1.2.0.redhat-630xxx default 1.0.1Where you must replace
1.2.0.redhat-630xxxwith the actual build version of the patch commands you are installing (for example, the build version
xxxcan be taken from the last three digits of the
TargetVersionin the downloaded patch management package file name).
- Upgrade the root container to use the new patching mechanism, as follows:
container-upgrade 1.0.1 root
- Likewise, for all other containers in your fabric that need to be patched (SSH, child, and so on), provision them with the new patching mechanism by upgrading them to profile version
1.0.1. For example:
container-upgrade 1.0.1 container1 container2 container3
After completing the container-upgrade, if
patchcommands are unavailable or if the console issues a prompt that a container restart is necessary, then restart the upgraded containers to complete the upgrade process.
Applying a rollup patch
- Before applying the rollup patch to your fabric, you must patch the patch mechanism, as described in the section called “Patching the patch mechanism”.
- For every top-level container (that is, any container that is not a child container), perform these steps, one container at a time:
- In the corresponding Karaf installation, remove the
lib/endorsed/org.apache.karaf.exception-2.4.0.redhat-630xxx.jarfile (where the build number,
xxx, depends on the build being patched).
- Restart the container.
- Add the patch to the root container's environment using the patch:add command. For example, to add the
JBossFuse:karaf@root> patch:add file://patch.zip [name] [installed] [description] PatchID false DescriptionImportantIf you have decided to use a local repository to distribute the patch artifacts (recommended), set up the local repository now—see the section called “Distribution of patch artifacts”.
- Create a new version, using the
JBossFuse:karaf@root> fabric:version-create 1.1 Created version: 1.1 as copy of: 1.0.1ImportantVersion names are important! The tooling sorts version names based on the numeric version string, according to major.minor numbering, to determine the version on which to base a new one. You can safely add a text description to a version name as long as you append it to the end of the generated default name like this:
1.3[.description]. If you abandon the default naming convention and use a textual name instead (for example, Patch051312), the next version you create will be based, not on the last version (Patch051312), but on the highest-numbered version determined by dot syntax.
- Apply the patch to the new version, using the
patch:fabric-installcommand. Note that in order to run this command you must provide the credentials,
Password, of a user with
Administratorprivileges. For example, to apply the
PatchIDpatch to version
patch:fabric-install --username Username --password Password --upload --version 1.1 PatchIDNoteWhen you invoke the
patch:fabric-installcommand with the
--uploadoption, Fabric looks up the ZooKeeper registry to discover the URL of the currently active Maven proxy, and uploads all of the patch artifacts to this URL. Using this approach it is possible to make the patch artifacts available through the Maven proxy, even if the container you are currently logged into is not hosting the Maven proxy.
- Delete the old bundle overrides created by the old hot fix patch by modifying the parent profiles of the profile default and removing the old hot fix patch profile as being a parent of the default profile. For example,
JBossFuse:karaf@root> fabric:profile-display --version 1.X default Attributes: parents: acls patch-jboss-fuse-6.2.1.redhat-186-12-r7hf10 JBossFuse:karaf@root> fabric:profile-change-parents --version 1.X default aclsNoteThe parent
patch-jboss-fuse-6.2.1.redhat-186-12-r7hf10is only visible if a hot fix patch was installed previously. The name of the parent patch is different based on the hot fix patch.The above commands shows that default profile has two parents:
- acls - standard and must be present.
- patch-jboss-fuse-6.2.1.redhat-186-12-r7hf10 - a profile that represents hotfix patch.
- Synchronize the patch information across the fabric, to ensure that the profile changes in version
1.1are propagated to all containers in the fabric (particularly remote SSH containers). Enter the following console command:
- Upgrade each existing container in the fabric using the
fabric:container-upgradecommand (but leaving the root container, where you installed the patch, until last). For example, to upgrade a container named
remote, enter the following command:
JBossFuse:karaf@root> fabric:container-upgrade 1.1 remote Upgraded container remote from version 1.0.1 to 1.1At this point, not only does the Fabric agent download and install the patched bundles into the specified container, but the agent also applies the patch to the underlying container (updating any static files in the container, if necessary). If necessary, the agent will then restart the target container automatically or set the container status to
requires full restart(if an automatic restart is not possible), so that any changes made to the static files are applied to the running container.ImportantIt is recommended that you upgrade only one or two containers to the patched profile version, to ensure that the patch does not introduce any new issues.
- If the current status of the upgraded container is
requires full restart, you must now use one of the standard mechanisms to stop and restart the container manually. In some cases, it will be possible to do this using Fabric commands from the console of the root container.For example, you could stop the
remotecontainer as follows:
fabric:container-stop remoteAnd restart the
remotecontainer as follows:
- Upgrade the root container last (that is, the container that you originally installed the patch on):
fabric:container-upgrade 1.1 root
- (Windows only) If the root container status has changed to
requires full restartand it is running on a Windows operating system, you must first shut down all of the root container's child containers (if any) before manually restarting the root container.For example, if the root container has three child containers,
child3, you would first shut them down, as follows:
fabric:container-stop child1 child2 child3You can then shut down the root container with the
Rolling back a rollup patch
fabric:container-rollbackcommand. For example, assuming that
1.0is an unpatched profile version, you can roll the
remotecontainer back to the unpatched version
fabric:container-rollback 1.0 remote
requires full restart(if an automatic restart is not possible), so that any changes made to the static files are applied to the running container.