Chapter 2. Applying Hotfix Patch to Fuse on Apache Karaf
Chapter 2. Applying Hotfix Patch to Fuse on Apache Karaf 2.1. Patching Features and Bundles Patches are ZIP archives that contain the updated versions of files present in Fuse on Apache Karaf installation. These include: Bundles: These are the most common and in the simplest case, hotfix patch may include single bundle. Configuration files and scripts that are present respectively in USDFUSE_HOME/etc and USDFUSE_HOME/bin directories. Libraries that are not ordinary bundles and reside in USDFUSE_HOME/lib directory. Feature definition changes: Normally Karaf features are included in descriptors available in the USDFUSE_HOME/system directory, but hotfix patches do not change these files. Instead, hot fix patch may alter feature override file which is USDFUSE_HOME/etc/org.apache.karaf.features.xml . This allows you to alter feature definitions in hotfix manner by upgrading given feature's bundles or even make given feature use additional bundle. Difference between Upgrading and Hotfix Patches Hotfix Patch: A hotfix patch contains fixes for only one or more critical bugs. These are intended to be applied on top of your current Red Hat Fuse distribution. Its main purpose is to update some of the bundles and libraries in an existing distribution. Upgrading: The Fuse on Apache Karaf upgrade mechanism enables you apply fixes to an Apache Karaf container without needing to reinstall an updated version of Fuse on Karaf. It also allows you to roll back the upgrade, if the upgrade causes problems with your deployed applications. The Fuse on Apache Karaf upgrade process updates any files, including bundle JARs, configuration files, and any static files. For Fuse on Apache Karaf Standalone you can apply the patch using commands from the Karaf console's patch shell. This approach is non-destructive and reversible. Following procedure can also be used for upgrading Red Hat Fuse on Apache Karaf. For more information of upgrading see Upgrading Fuse on Apache Karaf . 2.2. Applying a Hotfix Patch to Red Hat Fuse on Apache Karaf You can use the hotfix mechanism to update the available feature definitions and bundles at the same time. The procedure to apply a hotfix patch to the Fuse on Apache Karaf installation is as follows. Procedure Make a full backup of your Fuse on Apache Karaf installation before upgrading. Open the terminal and start Fuse on Apache karaf server. Optional: Download the required patch from the Customer Portal and skip to Step 5. Enter the patch:find command to find available patches in the Maven repositories. For example: Note You may use the patch:find command with the --add option to find the latest patch and add it to the container's environment. Add the patch to the container's environment by entering the patch:add command. For example: Note Instead of using the patch:add command, you can also add a patch file automatically by copying the .zip patch file into the FUSE_HOME/patches directory. Optional: Enter the patch:update command to update the patch mechanism itself: Simulate installing the patch by entering the patch:simulate command. This generates a log of the changes that will be made to the container when the patch is installed, but will not make any actual changes to the container. Review the simulation log to understand these changes. Enter the patch:list command to view a list of added patches. In this list, the entries under the [name] heading are patch IDs. If the patch contains explicit CVE metadata, you can enter the patch:show command to view more details: Apply a patch to the container by entering the patch:install command and specifying the patch ID for the patch that you want to apply. For example: 2.3. Rolling back a Patch You can rollback the installed hotfix patch and restore it to pre-patch behavior using the patch:rollback command, as follows: Procedure Enter the patch:list command to obtain the patch ID of the most recently installed patch. To rollback the updated bundle enter the following command: 2.4. Patching Red Hat Fuse application Using the new patch-maven-plugin mechanism you can apply a patch to your Red Hat Fuse application. This mechanism allows you to change the individual versions provided by different Red Hat Fuse BOMS, for example, fuse-springboot-bom and fuse-karaf-bom . 2.4.1. About patch-maven-plugin The patch-maven-plugin performs following operations: Retrieve the patch metadata related to current Red Hat Fuse BOMs. Apply the version changes to <dependencyManagement> imported from the BOMs. After the patch-maven-plugin fetches the metadata, it iterates through all managed and direct dependencies of the project where the plugin was declared and replaces the dependency versions (if they match) using CVE/patch metadata. After versions are replaced, Maven build continues and progresses through standard Maven project stages. 2.4.2. Applying patch to Red Hat Fuse applications The purpose of patch-maven-plugin is to update the versions of the dependencies listed in the Red Hat Fuse BOM to the versions specified in the patch metadata of the patch that you wish to apply to your applications. Procedure Following procedure explains how to apply the patch to your application. Add patch-maven-plugin to your project's pom.xml file. The version of the patch-maven-plugin must be the same as the version of the Fuse BOM. <build> <plugins> <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>patch-maven-plugin</artifactId> <version>USD{version.org.jboss-redhat-fuse}</version> <extensions>true</extensions> </plugin> </plugins> </build> When you run any one of the mvn clean deploy or mvn validate or mvn dependency:tree commands, the plugin searches through the project modules to check whether one of Red Hat Fuse BOMs is used. Only two are considered as the supported BOMs: org.jboss.redhat-fuse:fuse-karaf-bom : for Fuse Karaf BOM org.jboss.redhat-fuse:fuse-springboot-bom : for Fuse Spring Boot BOM If none of the above BOMs are found, the plugin will display following messages: If both Fuse BOMs are found, the patch-maven-plugin stops with the following warning: The patch-maven-plugin attempts to fetch one of the following Maven metadata values. For the projects with Fuse Karaf BOM, the org.jboss.redhat-fuse/fuse-karaf-patch-metadata/maven-metadata.xml is resolved. This is the metadata for the artifact with the org.jboss.redhat-fuse:fuse-karaf-patch-metadata:RELEASE coordinates. For the projects with Fuse Spring Boot BOM project, the org.jboss.redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml is resolved. This is the metadata for the artifact with the org.jboss.redhat-fuse:fuse-springboot-patch-metadata:RELEASE coordinates. Example metadata generated by Maven <?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>fuse-springboot-patch-metadata</artifactId> <versioning> <release>7.8.1.fuse-sb2-781025</release> <versions> <version>7.8.0.fuse-sb2-780025</version> <version>7.7.0.fuse-sb2-770010</version> <version>7.7.0.fuse-770010</version> <version>7.8.1.fuse-sb2-781025</version> </versions> <lastUpdated>20201023131724</lastUpdated> </versioning> </metadata> The patch-maven-plugin parses the metadata to select the version which is applicable to the current project. This is possible only for the Maven projects using Fuse BOM with version 7.8.xxx . Only the metadata that matches the version range 7.8, 7.9 or later is applicable and only the latest version of the metadata is fetched. The patch-maven-plugin collects a list of remote Maven repositories to be used when downloading the patch metadata identified by groupId , artifactId and version found in steps. These Maven repositories are the ones that are listed in the project's <repositories> elements in the active profiles and also the repositories from settings.xml file. Optionally, if you wish to use a offline repository, you can use -Dpatch option to specify a ZIP file which is produced by fuse-karaf/fuse-karaf-patch-repository or fuse-springboot/fuse-springboot-patch-repository modules of jboss-fuse/redhat-fuse project. These ZIP files have the same internal structure as the Maven repository structure. For example, Whether the metadata comes from remote repository, local repository or ZIP file, it is analyzed by the patch-maven-plugin . The fetched metadata contains list of CVEs and for each CVE we have a list of affected Maven artifacts (specified by glob patterns and version ranges) together with a version that contains a fix for a given CVE. For example, <?xml version="1.0" encoding="UTF-8" ?> <metadata xmlns="urn:redhat:fuse:patch-metadata:1"> <product-bom groupId="org.jboss.redhat-fuse" artifactId="fuse-springboot-bom" versions="[7.8,7.9)" /> <cves> <cve id="CVE-2020-xyz" description="Jetty can be configured to listen on port 8080" cve-link="https://nvd.nist.gov/vuln/detail/CVE-2020-xyz" bz-link="https://bugzilla.redhat.com/show_bug.cgi?id=42"> <affects groupId="org.eclipse.jetty" artifactId="jetty-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> <affects groupId="org.eclipse.jetty.http2" artifactId="http2-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> </cve> </cves> <fixes /> </metadata> Finally a list of fixes specified in patch metadata is consulted when iterating over all managed dependencies in current project. These dependencies (and managed dependencies) that match are changed to fixed versions. For example: Skipping the patch In case when you do not wish to apply a specific patch to your project, the patch-maven-plugin provides a skip option. Assuming that you have already added patch-maven-plugin to project's pom.xml file, and you don't wish for the versions to be altered, you can use one of the following method to skip the patch. Add the skip option to your project's pom.xml file as follows. Or use -DskipPatch option when running the mvn command as follows. As shown in the above output, the patch-maven-plugin was not invoked, which results in the patch not being applied to the application.
[user@FUSE_HOME/bin ~] USD ./fuse karaf@root()> patch:find Found new remote patch at mvn:org.jboss.redhat-fuse/fuse-karaf-patch-repository/7.8.0.fuse-sb2-780040/zip You can add the patch using "patch:add mvn:org.jboss.redhat-fuse/fuse-karaf-patch-repository/7.8.0.fuse-sb2-780040/zip" command, or simply use "patch:find --add" option. karaf@root()> patch:add mvn:org.jboss.redhat-fuse/fuse-karaf-patch-repository/7.8.0.fuse-sb2-780040/zip [name] [installed] [rollup] [description] [CVEs] fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 false false fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 CVE-2020-28052 Current patch mechanism version: 7.8.0.fuse-780038 New patch mechanism version detected: 7.8.0.fuse-780040 Please run "patch:update" command to upgrade patching mechanism to version 7.8.0.fuse780040 karaf@root()> patch:update Current patch mechanism version: 7.8.0.fuse-780038 New patch mechanism version detected: 7.8.0.fuse-780040 Uninstalling patch features in version 7.8.0.fuse-780038 Installing patch features in version 7.8.0.fuse-780040 karaf@root()> patch:list [name] [installed] [rollup] [description] [CVEs] fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 false false fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 CVE-2020-28052 karaf@root()> patch:show fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 Patch ID: fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 Patch Commit ID: a2d7cf58e21116cde66c97232aea4be1ec304400 #### 1 CVE fix: - CVE-2020-28052: bouncycastle: password bypass in OpenBSDBCrypt.checkPassword utility possible Bugzilla link: https://bugzilla.redhat.com/show_bug.cgi?id=1912881 CVE link: https://cve.mitre.org/cgi-bin/cvename.cgi?name=2020-28052 patch:install fuse-karaf-maintenance-patch-7.8.0.fuse-sb2-780040 karaf@root()> patch:rollback my-patch-x INFO : org.jboss.fuse.modules.patch.patch-management (2): Rolling back non-rollup patch "my-patch-x" removing overriden feature: hawtio-rbac/2.0.0.fuse-000117 refreshing features Enter feature:info command to view the information about the feature. karaf@root()> feature:info hawtio-rbac Feature hawtio-rbac 2.0.0.fuse-000117 Details: Installs the hawtio RBAC enabler bundle(s) Feature has no configuration Feature has no configuration files Feature has no dependencies. Feature contains followed bundles: mvn:io.hawt/hawtio-osgi-jmx/2.0.0.fuse-000117 Feature has no conditionals. <build> <plugins> <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>patch-maven-plugin</artifactId> <version>USD{version.org.jboss-redhat-fuse}</version> <extensions>true</extensions> </plugin> </plugins> </build> mvn clean install [INFO] Scanning for projects [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] No project in the reactor uses Fuse Karaf or Fuse Spring Boot BOM. Skipping patch processing. [INFO] [PATCH] Done in 3ms mvn clean install [INFO] Scanning for projects [INFO] ========== Red Hat Fuse Maven patching ========== [WARNING] [PATCH] Reactor uses both Fuse Karaf and Fuse Spring Boot BOMs. Please use only one. Skipping patch processing. [INFO] [PATCH] Done in 3ms <?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>fuse-springboot-patch-metadata</artifactId> <versioning> <release>7.8.1.fuse-sb2-781025</release> <versions> <version>7.8.0.fuse-sb2-780025</version> <version>7.7.0.fuse-sb2-770010</version> <version>7.7.0.fuse-770010</version> <version>7.8.1.fuse-sb2-781025</version> </versions> <lastUpdated>20201023131724</lastUpdated> </versioning> </metadata> mvn clean install [INFO] Scanning for projects [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories [INFO] [PATCH] - local-nexus: http://everfree.forest:8081/repository/maven-releases/ [INFO] [PATCH] - central: https://repo.maven.apache.org/maven2 Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml mvn clean install -Dpatch=../../../test/resources/patch-3.zip [INFO] Scanning for projects [INFO] ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading metadata and artifacts from /data/sources/github.com/jboss-fuse/redhat-fuse/fuse-tools/patch-maven-plugin/src/test/resources/patch-3.zip Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (406 B at 16 kB/s) Downloading from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml Downloaded from fuse-patch: zip:file:/tmp/patch-3.zip-1742974214598205745/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml (926 B at 309 kB/s) [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-781023/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-781023.xml <?xml version="1.0" encoding="UTF-8" ?> <metadata xmlns="urn:redhat:fuse:patch-metadata:1"> <product-bom groupId="org.jboss.redhat-fuse" artifactId="fuse-springboot-bom" versions="[7.8,7.9)" /> <cves> <cve id="CVE-2020-xyz" description="Jetty can be configured to listen on port 8080" cve-link="https://nvd.nist.gov/vuln/detail/CVE-2020-xyz" bz-link="https://bugzilla.redhat.com/show_bug.cgi?id=42"> <affects groupId="org.eclipse.jetty" artifactId="jetty-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> <affects groupId="org.eclipse.jetty.http2" artifactId="http2-*" versions="[9.4,9.4.32)" fix="9.4.32.v20200930" /> </cve> </cves> <fixes /> </metadata> mvn clean install -U [INFO] Scanning for projects [INFO ========== Red Hat Fuse Maven patching ========== [INFO] [PATCH] Reading patch metadata and artifacts from 2 project repositories [INFO] [PATCH] - local-nexus: http://everfree.forest:8081/repository/maven-releases/ [INFO] [PATCH] - central: https://repo.maven.apache.org/maven2 Downloading from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloading from central: https://repo.maven.apache.org/maven2/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml Downloaded from local-nexus: http://everfree.forest:8081/repository/maven-releases/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/maven-metadata.xml (363 B at 4.3 kB/s) [INFO] [PATCH] Resolved patch descriptor: /home/user/.m2/repository/org/jboss/redhat-fuse/fuse-springboot-patch-metadata/7.8.0.fuse-sb2-780032/fuse-springboot-patch-metadata-7.8.0.fuse-sb2-780032.xml [INFO] [PATCH] Patch metadata found for org.jboss.redhat-fuse/fuse-springboot-bom/[7.8,7.9) [INFO] [PATCH] - patch contains 1 CVE fix [INFO] [PATCH] Processing managed dependencies to apply CVE fixes... (https://nvd.nist.gov/vuln/detail/CVE-2020-xyz, https://bugzilla.redhat.com/show_bug.cgi?id=42_ [INFO] [PATCH] - CVE-2020-xyz: Jetty can be configured to expose itself on port 8080 [INFO] [PATCH] Applying change org.eclipse.jetty/jetty-*/[9.4,9.4.32) -> 9.4.32.v20200930 [INFO] [PATCH] - managed dependency: org.eclipse.jetty/jetty-alpn-client/9.4.30.v20200611 -> 9.4.32.v20200930 [INFO] [PATCH] - managed dependency: org.eclipse.jetty/jetty-openid/9.4.30.v20200611 -> 9.4.32.v20200930 [INFO] [PATCH] Applying change org.eclipse.jetty.http2/http2-*/[9.4,9.4.32) -> 9.4.32.v20200930 [INFO] [PATCH] - managed dependency: org.eclipse.jetty.http2/http2-client/9.4.30.v20200611 -> 9.4.32.v20200930 [INFO] [PATCH] Done in 635ms ================================================= <build> <plugins> <plugin> <groupId>org.jboss.redhat-fuse</groupId> <artifactId>patch-maven-plugin</artifactId> <version>USD{version.org.jboss-redhat-fuse}</version> <extensions>true</extensions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> mvn dependency:tree -DskipPatch [INFO] Scanning for projects [INFO] [INFO] ------< org.jboss.redhat-fuse:cve-dependency-management-module1 >------- [INFO] Building cve-dependency-management-module1 7.8.0.fuse-sb2-780033 [INFO] --------------------------------[ jar ]---------------------------------