Overlays & Patches
For some context
Take a look at:
- Quickstart: Deploying Analytics: DAP for another example
- Package Spec Reference for the full object definition specification (i.e. everything you can patch)
Questions
What are Patches ?
- Patches are partial configuration blocks that can be "overlaid" onto a given
Package
object. - We can store them and ship them with a package in order to provide us a quick way to modify settings in the package.
- We can also use them to generate different packages from a given base package by entities defined in that base and "overlaying" patches on top of it until we get our desired state
How does it work ?
Patches work by utilizing the Package
object model and manipulating it using kustomize
.
The functionality is a little bit pared back to remove scope for user error.
The name
parameter of any given object is used as a key and array types will be merged according to the strategic merge mechanism.
There's no mechanism to patch code files currently, only config
Using Patches
E.g. Adding pipeline
In order to create a patch we can simply do the usual add
command, in this case specifying patch
as your new object:
kxi package -q init mypkg --force
kxi package -q add --to mypkg patch --name my-first-patch
cat mypkg/patches/my-first-patch.yaml
kind: Package
apiVersion: pakx/v1
metadata:
name: target
spec:
manifest: {}
databases: []
pipelines: []
router: null
deployment_config: null
This will add a patch
file in the patches
directory, the patches
file will basically be empty but gives you an idea of how to structure your patch further.
What to do with this template patch
- Do not modify anything above the
spec:
field - Good practice to remove everything inside
spec:
except for what you want to patch
Understanding the package object model
Check out the Package Spec Reference for the full object defintion
We can see the patch object is also present in the manifest file:
kxi package info mypkg
==PATH==
/builds/kxdev/kxinsights/documentation/code-kx-com/mypkg
==OBJECT==
Package
==Manifest==
name: mypkg
version: 0.0.1
metadata:
description: ''
authors:
- name: root
email: ''
entrypoints:
default: init.q
patches:
- name: my-first-patch
Let's modify the patch
to add a new pipeline
.
patchspec=$(cat mypkg/patches/my-first-patch.yaml | grep spec: -B10 | cat - <(echo " pipelines: [{name: mynewpipeline, spec: init.q}]"))
echo "$patchspec" > mypkg/patches/my-first-patch.yaml
cat mypkg/patches/my-first-patch.yaml
kind: Package
apiVersion: pakx/v1
metadata:
name: target
spec:
pipelines: [{name: mynewpipeline, spec: init.q}]
We can then apply or "overlay" this patch onto our current package using the overlay
command:
Without specifying any other information, the overlay command resolves All the patches found in the manifest
kxi package overlay mypkg
kxi package info mypkg | grep pipelines: -A5
Found patch to overlay: mypkg/patches/my-first-patch.yaml
Writing /builds/kxdev/kxinsights/documentation/code-kx-com/mypkg/manifest.yaml
pipelines:
mynewpipeline:
file: pipelines/mynewpipeline.yaml
router: ''
deployment_config: ''
patches:
When we specify patches after the package name, we can select any valid patch file, they dont even need to be located inside a package!
kxi package overlay mypkg mypkg/patches/my-first-patch.yaml
kxi package info mypkg | grep pipelines: -A5
Writing /builds/kxdev/kxinsights/documentation/code-kx-com/mypkg/manifest.yaml
pipelines:
mynewpipeline:
file: pipelines/mynewpipeline.yaml
router: ''
deployment_config: ''
patches:
E.g. Modifying Tables
Because Tables are contained inside the Database
construct we must patch the Database:
kxi package -q init mypkg --force
kxi package -q add --to mypkg database --name mydb
# This automatically populates a "default" table
kxi package -q add --to mypkg patch --name my-db-patch
read -r -d '' dbspec <<'EOF'
databases:
- name: mydb
tables:
schemas:
- name: default
columns:
- name: myfloat
type: float
description: we've added a new float column called myfloat
- name: x2
type: symbol
description: The default x2 column has changed type
description: We've changed the default table's description too!
EOF
# The patch might look a little complex, but it's just a few nested structs
# N.B We have indented it here to nest it under the `spec` field
patchspec=$(cat mypkg/patches/my-db-patch.yaml | grep spec: -B10 | cat - <(echo " $dbspec"))
echo "$patchspec" > mypkg/patches/my-db-patch.yaml
# This is just to stitch the header with the dbspec we wrote
cat mypkg/patches/my-db-patch.yaml
kxi package overlay mypkg
echo""
echo "----Resultant schema for 'default' table----"
echo "--------------------------------------------"
cat mypkg/databases/mydb/schema.yaml
kind: Package
apiVersion: pakx/v1
metadata:
name: target
spec:
databases:
- name: mydb
tables:
schemas:
- name: default
columns:
- name: myfloat
type: float
description: we've added a new float column called myfloat
- name: x2
type: symbol
description: The default x2 column has changed type
description: We've changed the default table's description too!
Found patch to overlay: mypkg/patches/my-db-patch.yaml
Writing /builds/kxdev/kxinsights/documentation/code-kx-com/mypkg/manifest.yaml
----Resultant schema for 'default' table----
--------------------------------------------
schemas:
- name: default
columns:
- description: we've added a new float column called myfloat
name: myfloat
type: float
- description: The default x2 column has changed type
name: x2
type: symbol
- description: test col t1
name: t1
type: timestamp
description: We've changed the default table's description too!
prtnCol: t1
type: partitioned
Column Ordering
After patching we can observe the columns have changed order. The new column has been added in at the top. If your application requires a specific column ordering then you will need to do this manually.
Referencing Deps Patches
We are able to reference patches held in other packages too so that we don't need to continually copy patch specs that we like!
Referenced Dep must already be installed
Referencing a patch from a dependency can only be done after that dep is installed.
In the below example we explicitly run: kxi package install myotherdep
This allows the kxi package
to resolve it properly when we then call overlay
We do this in the following way:
kxi package -q init myotherpkg --force
# setup
kxi package -q add --to myotherpkg patch --name patch-from-afar
patchspec=$(cat myotherpkg/patches/patch-from-afar.yaml | grep spec: -B10 | cat - <(echo " pipelines: [{name: mynewpipeline, spec: init.q}]"))
echo "$patchspec" > myotherpkg/patches/patch-from-afar.yaml
# add a patch to myother pkg
_=$(kxi package -q install myotherpkg)
# install myotherpkg so that we can reference it
kxi package -q add --to mypkg dep --name myotherpkg --version 0.0.1
# add a dependency on myotherpkg to mypkg
kxi package -q add --to mypkg patch --name patch-from-afar --dep myotherpkg
# add a patch in mypkg referencing a patch in myotherpkg
kxi package -q overlay mypkg
# see that we've successfully used the patch adding a new pipeline from myotherpkg!
kxi package info mypkg | grep pipelines: -A5
pipelines:
mynewpipeline:
file: pipelines/mynewpipeline.yaml
router: ''
deployment_config: ''
patches: