A WASI plugin is a single WebAssembly (.wasm) file that must be made accessible to the operator using a Persistent Volume Claim (PVC).
Once that PVC has been created, you can reference it in a Backup or a Restore by defining a wasiPluginRef in spec.plugins:
In this example,
We’ve listed a wasiPluginRef entry in the list of enabled plugins for a Backup.
A wasiPluginRef has some mandatory properties:
The witVersion tells the engine we are using version 0.1 of the wit definition files (see below).
A claimName that references a persistent volume claim where plugins are stored.
A path that tells the Backup where the plugin is located within the persistent volume.
An optional configuration can be added using the spec field.
It must be a yaml object that will be forwarded as a string to the plugin’s initialization function.
As always, a topicSelector can be used to enable the plugin on only a subset of topics.
Restore resources accept the same kind of configuration.
Writing a WASI plugin
If you wish to write your own plugins,
then you must implement the interface Kannika Armory expects.
Backups and Restores have slightly different needs
so each have their own interface (or world in WIT lingo).
Depending on the kind of plugin you wish to develop,
you will have to implement one or the other.
Below are some guides to get you started in one of these programming languages:
Here’s an example on how to write a repartitioning plugin to be used with a Restore in Rust.
This plugin will accept a number of partitions, no_partition as a configuration option and will
simply overwrite the original partition of the record with that logic:
You will need cargo component to build a WebAssembly component:
Then, create a new library project
and add the serde and serde_yaml crates to de-serialize the plugin’s configuration.
Next, remove the template files in the wit/ folder
and copy types.wit and restore.wit into it instead.
Also, edit the Cargo.toml file to match the package of the WIT files:
Your project should look like this:
And here’s the implementation of the plugin:
All that’s left to do is build the component:
The compiled wasm file will be found in the target/wasm32-wasip1/release/ folder.
and it can be loaded into a Restore as described above:
Enjoy!
In Python
In this example, we’re going to build a plugin meant to be used in a Backup
that will remove a particular header from records before they are saved to the storage.
Let’s start by creating a dev environment for our plugin:
We will need pyyaml to read the configuration:
Then let’s install componentize-py.
This tool will convert our python code into a WebAssembly component.
When that’s done,
copy the backup.wit and types.wit files to a folder called wit/
and generate python code from them:
We can now write our plugin’s implementation:
We now can compile our plugin to a Wasm component:
The plugin is ready to be used in a Backup to have it remove the header called ‘secret’,
before the data is sent to the storage:
That’s all there is to it !
In Go
At this time,
the tooling in Go is not as easy to use as what is available in Rust or Python,
so the process is a little bit more involved.
Here’s a short guide to get you started. We’re going to implement a ‘pass-through’ plugin that does nothing.
It is meant to serve as a template for a more complex plugin.
the wit-bindgen tool to generate bindings from the WIT files;
the wasm-tools to convert the wasm code into a wasi component.
Linux users will most likely find TinyGo in their distro’s packages.
If you’re a Rust user, the wit-bindgen and wasm-tools can be installed through cargo.
Otherwise, both projects offer pre-compiled binaries in their respective GitHub Releases section.
We will then need to copy two libraries in our project’s directory: