Overview

As with many other types of software, toolkit releases can be versioned, and can define logic that handles upgrading between versions.

Included in the Toolkit DevKit (available from our download site) are three example source trees which illustrate this topic. Each represent different releases of the same toolkit:

  • versioning-original contains a simple toolkit which defines some of its own datatypes.
  • versioning-patch makes a bugfix, but makes no datatype changes.

  • versioning-upgrade changes datatypes and provides upgrade scripts.

Identifying Your Toolkit's Version

A toolkit must define its version using a three-part string of the form X.Y.Z Here "X" is the "major number", "Y" is the "minor number", and "Z" is a patch level. This is defined inside the toolkit's main.json file.

  • Minor and major numbers are integers. See other restrictions below.
  • Patch level can be any sequence of letters, numbers or underscores. 

Examples of valid version strings:

  • 1.0.0
  • 4.3.7
  • 2.2.fix_sorting_bug

Rules for New Toolkit Releases

There are three different types of toolkit releases, and they have different rules around what you are allowed to change, and what you must change.

Rules for a new major release:

  • The major number in the version string must be incremented. That is, it must be 1 greater than the previous release's major number.
  • The minor number must be reset to 0.
  • You are allowed to change any/all of the schemas defined in the main.json file.
  • You must provide upgrade scripts. These scripts will convert data written by an old version of your toolkit to the format expected by your new toolkit version.

Rules for a new minor release:

  • The minor number in the version string must be incremented relative to the previous release.
  • The major number must be unchanged from the previous release.
  • You are allowed to change any/all of the schemas defined in the main.json file.
  • You must provide upgrade scripts. These scripts will convert data written by an old version of your toolkit to the format expected by your new toolkit version.

Rules for a new patch releases:

  • Neither the minor number nor the major number may change.
  • The patch level must change. Any valid patch string is allowed.
  • You may not change any of the schemas in the main.json file.
  • You do not need to provide any upgrade scripts.

In summary, if you need to change a datatype, you must make a new major or minor release. If you do not need to change a datatype, you may choose to make a new major, minor, or patch release. Apart from these constraints, it is up to the toolkit developer to decide which kinds of changes count as "major", "minor", or "patch".

For examples of different types of toolkit releases, see the "versioning" toolkits in the downloadable Toolkit DevKit.

Rules For Versions and Upgrading

If an engine does not already have a version of your toolkit installed, then there are no special rules about which versions will be accepted. Any valid version string will be allowed.

However, if the engine already does have a version of your toolkit, then there are some constriants about which new versions will be accepted:

  • Major/minor numbers must never decrease. It is never allowed to "downgrade" to a lower major or minor number when uploading a toolkit.
  • Each new major or minor release can only be installed on top of the previous one. It is not possible to "skip" a release. If a user is on version 1.0 of a toolkit, and versions 1.1, 1.2, and 2.0 have been released, then the user must follow the upgrade chain and sequentially install 1.1, then 1.2, then 2.0 – they cannot install 2.0 directly on top of 1.1.

Note that there is no defined ordering of patch levels. So long as the major and minor numbers are unchanged, any patch level may be uploaded to replace any other patch level.

As described above, the patch level is just a string. You may, of course, choose to use numbers as your patch levels. For example it's okay to call your releases "2.1.0" "2.1.1" and "2.1.2". Just be aware that Delphix does not enforce any ordering of patch releases, and thus there is nothing preventing a user from changing from a "2.1.2" release to a "2.1.1" toolkit. If you want to prevent a user from "downgrading", you must change the major or minor number.


Defining Upgrade Logic

A toolkit defines a number of data formats by including schemas in its main.json file. As a user interacts with the toolkit, objects are created in these formats, and these objects are stored for later use.

For example, when a user takes a snapshot of a dSource or VDB, the toolkit's postSnapshot Lua script is run. This script returns an object conforming to the snapshotSchema in the toolkit's main.json. This object is stored away. Later, if a user wants to provision a new VDB from this snapshot, this object will be retrieved and passed into the toolkit's configure Lua script.

But, now consider a case where a new version of a toolkit is released, and this new version makes some changes to the snapshotSchema. Obviously, this new toolkit version's code will expect to see snapshots in the "new" format, as defined in its snapshotSchema.

This is where upgrade scripts come in. An upgrade script's job is to modify an "old" object that conforms to the previous version's schema. It must return a "new-format" object that conforms to the new version's schema.

There are four upgrade scripts:

  • upgradeLinkedSource
  • upgradeVirtualSource
  • upgradeSourceConfig
  • upgradeSnapshot

Each of these scripts live in a nested subdirectory upgrade/<version>, where "version" is only the major and minor parts of the version that your scripts are upgrading from. So for example, if your new toolkit is version 5.4.x, and your most recently released toolkit was version 5.3.x, then you would put your upgrade scripts in the upgrade/5.3 directory.

Examples

For a simple example, consider a case where a new toolkit version adds a new property to a schema. First, compare the following two virtualSourceSchema entries:

versioning-original main.json

"virtualSourceDefinition": {
        "type": "ToolkitVirtualSource",
        "parameters": {
            "type" : "object",
            "additionalProperties" : false,
            "required": ["dataPath"],
            "properties" : {
                "dataPath" : {
                    "type": "string",
                    "prettyName": "Data Path",
                    "description": "Where the data should be mounted on the target host"
                },
                "comment" : {
                    "type": "string",
                    "prettyName": "Comment",
                    "description": "User comment"
                }
            }
        }
    },

versioning-upgrade main.json

    "virtualSourceDefinition": {
        "type": "ToolkitVirtualSource",
        "parameters": {
            "type" : "object",
            "additionalProperties" : false,
            "required": ["dataPath", "dataDescription"],
            "properties" : {
                "dataPath" : {
                    "type": "string",
                    "prettyName": "Data Path",
                    "description": "Where the data should be mounted on the target host"
                },
                "dataDescription": {
                    "type": "string",
                    "prettyName": "Data Descrption",
                    "description": "Brief description of what data this VDB holds"
                }
            }
        }
    },


Notice that there are two changes. First, there is a new string property called "dataDescription" that has been added in the new toolkit version. This new property is marked as required. But, of course any objects created by the old version of the toolkit will not have this property. Therefore, we must write an upgrade script that knows how to take an old object and add a value for this new property. Similarly, the property "comment" has disappeared, and so our upgrade script must remove this property from the old objects.


versioning-upgrade upgrade/1.0/upgradeVirtualSource.lua

-- This script's job is to modify a virtual source's parameters. We need to change it from the format used by the old
-- toolkit version to the format expected by this new version.



-- In this version, we are adding a new required property to virtual sources called "dataDescription".
-- Therefore, we must add a new field called "dataDescription" to our parameter set.

parameters.dataDescription = "Data located at " .. parameters.dataPath



-- In this version, we no longer support a "comment" property on virtual sources.
-- Therefore, we must remove the "comment" field from our parameter set.

parameters.comment = nil




-- Now that all the required modifications have been made, we can return the parameter set.
return parameters


In some cases, a schema might not change at all in a new major/minor version. In that case, the upgrade script can simply return the old-format object as-is, making no changes to the object at all.

versioning-upgrade upgrade/1.0/upgradeSourceConfig.lua

-- We are making no changes to the sourceConfigSchema, so we don't need to change anything here.
-- We can simply return the old object unchanged.

return config


For examples of upgrade scripts that handle more complicated changes to schemas, please see the toolkits in the downloadable Toolkit DevKit.


The inputs to the different upgrade scripts are called different things! This is done for consistency for other scripts. So, for example, upgradeSnapshot.lua gets an input called snapshot, because that's what this object is called in other toolkit scripts. Similarly, the input to upgradeSourceConfig.lua is called config.  And upgradeLinkedSource.lua and upgradeVirtualSource.lua both get an input called parameters.