JBoss Community

Experimenting with Single Installation Patching

modified by Brian Stansberry in JBoss AS 7 Development - View the full document

Initial draft; I haven't verified everything in this doc yet!!!

 

Instructions for experimenting with the "Single Installation Patching" feature currently being developed.

 

These instructions assume basic git knowledge and knowledge of how to work with the AS 7 code base. See "Hacking on JBoss AS7" for basic background.

 

Getting and Building the Source

 

The patching feature is currently on a topic branch being maintained by Emanuel Muckenhuber. Until that branch is merged into master:

 

1) If you haven't already, clone the AS repo

 

$ git clone git://github.com/jbossas/jboss-as.git

 

2) Add Emanuel's github repo as a remote

 

$ cd jboss-as
$ git remote add -f emanuel git://github.com/emuckenhuber/jboss-as.git

 

3) Checkout a new branch "patches-master" to track Emanuel's branch

 

$ git checkout -t emanuel/patches-master

 

4) Build the AS

 

$ ./build.sh

 

add the -DskipTests option to skip running tests if you want the build to go a bit faster.

 

Generating Patches

 

To generate a patch, you'll need 5 things:

 

  1. An unzipped AS distribution representing the AS release being patched. This is the "applies-to-dist". This can be any AS7 release distribution, or the output of any successful build of the AS7 codebase since 7.1.0.Final was released. (Even earlier would probably work fine.)
  2. An unzipped AS distribution representing the "patched" AS release. This is the "updated-dist". This is a distribution built from code that is newer than whatever went into the "applies-to" distribution. It can be a later release or build, or even the same distribution as the "applies-to-dist" that you've manually modified in some fashion.
  3. An AS distribution you built following the instructions in the "Getting and Building the Source" section above. The patch generation tool is included in this distribution. If the distribution you are using for the "updated-dist" was built in that manner, then you can use it; you don't need a separate distribution. At some point we'll distribute the patch generation tool as a separate distribution, but for now it's simplest just to use an AS distribution. In the rest of this section, we'll refer to this as the "patch generation tool distribution."
  4. A patch-config.xml file providing instructions about how to create the patch. See details below.
  5. The filesystem location where you want the patch file to be written (including the name of the file.)

 

To run the patch generation tool:

 

$ cd /root/of/the/patch/generation/tool/distribution
$ java -jar jboss-modules.jar -mp modules org.jboss.as.patching.generator --help
INFO  [org.jboss.modules] JBoss Modules version 1.1.3.GA

Usage: patch-gen.sh [args...]
where args include:
    --applies-to-dist=<file>  Filesystem path of a pristine unzip of 
                              the distribution of the version of the 
                              software to which the generated patch 
                              applies 

    -h, --help                Display this message and exit

    --output-file=<file>      Filesystem location to which the 
                              generated patch file should be written

    --patch-config=<file>     Filesystem path of the patch generation 
                              configuration file to use

    --updated-dist=<file>     Filesystem path of a pristine unzip of 
                              a distribution of software which 
                              contains the changes that should be 
                              incorporated in the patch

    -v, --version             Print version and exit

 

To actually run the patch generation tool and not just get help output, you will need to append the --applies-to-dist, --updated-dist, --patch-config and --output-file arguments described above to the process launch command (instead of --help), with the appropriate value for each included.

 

The java command above is pretty lengthy, so we've written a shell script that does the same thing. In the source code it can be found at patching/src/main/resources/patch-gen.sh. Copy that to the bin/ dir of the patch generation tool distribution and then you can get the output above by simply doing:

 

$ bin/patch-gen.sh --help

 

TODO: the patch-gen tool should use sensible defaults for --applies-to-dist, --updated-dist and --output-file such that only --patch-config needs to be specified. Or, allow those locations to be specified in the patch-config.xml file itself.

  • Default for --updated-dist can be the current working dir, or its parent if the current working dir is named bin/. Apply some simple sanity checks, e.g. check for jboss-modules.jar etc. The assumption here is the tool is being run from the --updated-dist (which is the newest dist and thus will have the newest version of the tool)
  • Default for --applies-to-dist can be a sibling of the root of --applies-to-dist, named the same as the applies-to-version in the patch-config.xml.
  • Default for --output-file can be patch.par in the current working dir, assuming no such file already exists

 

Methods of Patch Generation

 

There are two basic methods of patch generation. Which the tool should use is declared in the patch-config.xml file:


  • generate-by-diff: The patch generation tool itself compares the contents of the --applies-to-dist and the --updated-dist and creates a patch. This is most useful for CP patches. TODO for one-off patches allow an option where the diffing algorithm ignore will timestamps as described by Jeff Mesnil.
  • specified-content: The patch-config.xml file declares in detail what modules, bundles and misc files are to be added, updated or removed via the patch. This is most useful for one-off patches where the patch author knows what has changed.

 

The patch-config.xml File

 

The patch-config.xml file provides basic metadata about the patch, along with instructions on how to generate it. The person preparing the patch creates the patch-config.xml file.

 

Note: the file doesn't have to be named patch-config.xml; it can be named anything.

 

The simplest way to describe the file is to show a couple of examples. The full xsd for the file can be found in the AS source dist at patching/src/main/resources/patch-config.xsd.

 

An example patch-config file for a generate-by-diff patch:

 

<?xml version='1.0' encoding='UTF-8'?>
<patch-config xmlns="urn:jboss:patch-config:1.0">

    <name>6.1.0-to-6.1.1</name>
    <description>Cumulative patch to move from EAP 6.1.0.GA to EAP 6.1.1.GA</description>
    <cumulative applies-to-version="EAP 6.1.0.GA" resulting-version="EAP 6.1.1.GA"/> 

    <generate-by-diff/> 

</patch-config>

 

 

An example patch-config file for a specified-content patch:

 

<?xml version='1.0' encoding='UTF-8'?>
<patch-config xmlns="urn:jboss:patch-config:1.0">

    <name>JBPAPP6-123</name>
    <description>One off patch to fix JBPAPP6-123</description>

    <one-off>
        <applies-to-version>EAP 6.1.0.GA</applies-to-version>
    </one-off> 

    <specified-content>

        <modules>
            <added-module name="org.jboss.as.foo" />
            <updated-module name="org.jboss.as.bar" slot="eap"/>
            <removed-module name="org.jboss.as.fubar" />
        </modules> 

        <misc-files>
            <updated-misc-content path="bin/standalone.sh" /> 
            <updated-misc-content path="bin/standalone.bat" />
        </misc-files> 

    </specified-content> 

</patch-config>

 

 

Applying Patches

 

Only an AS release that includes the patching feature can be patched using the patching tool. So, that means you can only experiment with applying patches to an AS distribution you built following the instructions in the "Getting and Building the Source" section above. That limits things a bit as far as what patches you can try to apply; for example you couldn't generate a patch that represents the difference between 7.1.2.Final and 7.1.3.Final and then apply it to 7.1.2.Final.

 

To apply a patch, you need:

 

  1. A patch file, prepared as described in the "Generating Patches" section.
  2. An unzipped AS distribution that represents the "applies-to" distribution. This can be the exact same "applies-to" distribution you used when creating the patch, or, if you want to experiment with how the patch tool deals with the (typical) situation where the user has in some way modified a standard AS version, you can make some sort of modification.

 

To actually apply the patch, the installation being patched needs to actually be running. It can be running a standalone server or the managed domain processes; either is ok. It can be running normally or in --admin-only mode.

 

We use the standard AS CLI tool to provide the user interface for the patch application tool. To see how to apply the patch, cd into the root of the installation being patched, launch the CLI, connecting it to the target process and get the help for the "patch" command:

 

$ bin/jboss-cli.sh -c
[standalone@localhost:9999 /] patch --help
SYNOPSIS

    patch
      <action> <action_arguments>*
      [--override-all]
      [--override-modules]
      [--override=path(,path)*]
      [--preserve=path(,path)*]
      [--host=<host>]

          where <action> can be

  apply           - apply a patch
  rollback        - rollback a patch that has been applied

          and <action_arguments> depends on the <action>

ACTION: apply

   Apply a patch


   ....

This document won't include any more details on actually executing the patch command. Part of the goal of experimenting with it is to see if the --help output is adequate for users to understand what to do.

 

The patch command only stages the patch (i.e. modifies the filesystem in a way that should not impact the running target process.) To actually have the patch take effect in the runtime, the target process needs to be restarted:

 

[standalone@localhost:9999 /] :shutdown(restart=true)
{"outcome" => "success"}

 

Note that simply reloading the target process (using the :reload operation) is insufficient.

 

TODO add options to the patch command to automatically restart the process if staging is successful.

 

Following Progress

 

The patching feature is still under active development, so if you want update your build and see what's new:

 

1) cd into the git repo you cloned in step 1) of "Getting and Building the Source" above.

 

2) Pull down the latest

 

$ git fetch emanuel

 

3) Make sure you have a clean repo

 

$ git status

 

4) Rebase your branch onto the latest

 

$ git checkout patches-master

$ git rebase emanuel/patches-master

 

5) Build again

Comment by going to Community

Create a new document in JBoss AS 7 Development at Community