Skip to content

Create a hotfix

This page explains how to create a hotfix: a new version of a package that delivers a fix ahead of the patch release that will include it. It covers naming and versioning the hotfix package, creating it without editing deployed files in place, and retiring it once the fix ships in a patch release.

Already have a hotfix package?

If you have a hotfix package, deploy it as described in Perform a dynamic upgrade.

Why hotfixes are packages

In KX Sensors, what a process runs is defined by its deployment revision: an ordered directory list of versioned packages, recorded by the system when the deployment is created. KX Sensors treats each package version as immutable. Once you deploy a package, its contents never change; make a change as a new version.

A hotfix follows the same model. It is a new versioned package, built from the package it fixes and applied like any other release. This gives you:

  • One source of truth. The directory list of each deployment revision says exactly which package versions every process is running.
  • An audit trail. kxsctl deploy list records every deployment, the targets it was applied to, and every rollback.
  • Consistency across nodes. The same package directory, byte-for-byte, is deployed to every node.
  • Reproducibility. The exact package that was tested in UAT is the one that is deployed, and can be deployed again to another environment.
  • Rollback. Applying a previous revision returns processes to the previous package versions.
  • No downtime. The DU reloads only the changed files in running processes, so no restart is needed for most fixes.

Never edit a deployed package in place

Unless actively making changes in a development environment, never edit a deployed package in place. Editing in place negates the benefits of a versioned package listed above.

The example scenario

This page uses one example throughout. A system runs a customer package example-1.0.0 alongside the KX packages. A defect has been found: the greeting returned by the gateway (GW) says Hello world. when it should say Hello world!. The text comes from a q function:

/ example-1.0.0/src/example/greet.q
.example.greet:{"Hello world."}

The example fixes q code, but the procedure is the same for any other change a package can contain, such as configuration objects, schemas and APIs. Changes to schemas have some additional considerations, described in the dynamic upgrade caveats.

Naming and versioning hotfixes

Use the following conventions so it is always clear, from kxsctl deploy list or a directory listing, that a hotfix is in effect and which release it applies to.

Item Convention Example
Hotfix version The base release version plus a fourth, numeric segment, starting at 1. 1.0.0.1
Package directory <pkg.name>-<hotfix version> example-1.0.0.1
pkg.name in .pkg Unchanged from the base release. example
pkg.version in .pkg The hotfix version. 1.0.0.1
Next hotfix on the same release Increment the fourth segment. Hotfixes are cumulative: build 1.0.0.2 from 1.0.0.1, not from 1.0.0. example-1.0.0.2
Release that incorporates the fix The next patch release: the third (patch) segment incremented, as in semantic versioning. It must contain every hotfix it replaces. example-1.0.1

A three-segment version is always a release. A four-segment version is always a hotfix to the release named by its first three segments.

Keep hotfix versions numeric

KX Sensors compares package versions segment by segment, treating any non-digit as a separator. This comparison decides whether DBW loads a package's upgrade or downgrade script (see Use custom upgrade and downgrade scripts). Alphabetic suffixes such as 1.0.0-hotfix1 or 1.0.0-hf1 do not compare correctly: 1.0.0-hf1 is treated as older than 1.0.0. Numeric versions order correctly: 1.0.0 < 1.0.0.1 < 1.0.0.2 < 1.0.1.

Create the hotfix package

Ideally, create the hotfix in a test or UAT environment. Start from an exact copy of the package that is currently deployed.

Hotfixes must be cumulative

For the second and later hotfixes on the same release, copy the latest hotfix, not the base release. For example, build example-1.0.0.2 from example-1.0.0.1, not from example-1.0.0. Each hotfix replaces the previous one in the directory list, so any fix it doesn't contain is lost when it is deployed.

cd $KXS_ROOT/packages
cp -a example-1.0.0 example-1.0.0.1

Make the fix in the new directory only:

sed -i 's/"Hello world\."/"Hello world!"/' example-1.0.0.1/src/example/greet.q

Edit example-1.0.0.1/.pkg: set pkg.version to the hotfix version and leave pkg.name unchanged.

$ cat example-1.0.0.1/.pkg
pkg.name=example
pkg.version=1.0.0.1

This edit is required. Every package must contain a .pkg file, and KX Sensors uses its pkg.name and pkg.version to:

  • Repoint the unversioned link (example -> example-1.0.0.1) after the DU. A copied but unedited .pkg leaves two directories claiming the same version.
  • Log the package versions each process loaded at startup, which is how you confirm what is running.
  • Choose the correct upgrade or downgrade script during an on-disk database conversion.

Consider adding hotfix information to a CHANGELOG.md in the package directory.

Review the complete change against the base package. The diff must contain only the intended fixes and the .pkg edit.

Note

If the fix adds a new q file, the file is only loaded by a DU if it is referenced in the libraries property of the process in process.yaml. Moving or renaming an existing q file has the same restriction.

Deploy the hotfix

Deploy the hotfix like any other new package version, as described in Perform a dynamic upgrade. Replace the current version with the hotfix in the directory list:

kxsctl deploy apply -c "example-1.0.0:example-1.0.0.1"

For a later hotfix, replace the current hotfix instead, for example -c "example-1.0.0.1:example-1.0.0.2".

To roll the hotfix back, apply the revision that was in effect before it. See Roll back. If the hotfix itself needs correcting, build the correction as the next hotfix (example-1.0.0.2). Don't modify example-1.0.0.1.

Retire a hotfix

A hotfix should be temporary. Once the fix is included in a patch release:

  1. Confirm the patch release contains every preceding hotfix.
  2. Deploy the patch release in place of the hotfix, as described in Perform a dynamic upgrade:

    kxsctl deploy apply -c "example-1.0.0.1:example-1.0.1"
    

In this example of one hotfix, without a rollback, the final history looks as follows:

$ kxsctl deploy list
Revision  Nodes  Processes/Service Classes  Directory List
--------  -----  -------------------------  --------------------------------------
1         <all>  <all>                      kxs-core-3.0.0;example-1.0.0;env
2         <all>  <all>                      kxs-core-3.0.0;example-1.0.0.1;env
3         <all>  <all>                      kxs-core-3.0.0;example-1.0.1;env

Next steps