Cross-posted from the wasmCloud blog.
In wash v0.28, we introduced wash plugins: a simple system for extending the wasmCloud Shell (wash) CLI with WebAssembly components. Users can install plugins from OCI registries, local files, or over HTTP, then execute the plugin as a subcommand to wash
. Plugin developers simply build a given piece of CLI functionality as a component.
In this post, we'll show you how to install your first plugin. In themselves, plugins represent powerful, versatile tools that will accelerate workflows and help developers tailor tooling to their needs. But wash plugins are also a great example of how modular CLIs can be implemented with WebAssembly—and how components can accelerate development across a team.
Faster development with components
Using components for plugin functionality means that very little of the implementation is particular to wash or wasmCloud. Taylor Thomas, who built the plugin system, describes it as "essentially a thin shim around wasi:cli/run
." In fact, you can run plugins in Wasmtime with minimal configuration. The common interface of WASI makes components ideally suited to building modular CLIs, and even reusing plugins across different component-powered CLIs.
Because the plugin design is so firmly rooted in standards, the feature could be spun out of only a few days' work during the wasmCloud maintainers' Spring Hackathon. About a week after the Hackathon, plugins were merged into wash—a few days after that, Brooks Townsend had his wit2wadm
project working as a plugin. The wasmCloud project has been all-in on components for a while now, but the team was a bit surprised by just how quickly these projects could go from independent ideas to integrated releases.
Getting started with wash plugins
If you have wash v0.28 or later installed, you've got everything you need. (If not, head on over to the Installation page.) You can run wash -V
to check your version.
With wash installed, installing a plugin is just a matter of running wash plugin install
against a target, whether that's a local file, an OCI registry, or an HTTP address. For this example, we'll use the wit2wadm
plugin which is available as an OCI artifact hosted on GitHub Packages. wit2wadm
will let us generate application deployment manifests automatically from a components' defined interfaces, cutting way down on time spent writing YAML and speeding up local development workflows.
wash plugin install oci://ghcr.io/brooksmtownsend/wit2wadm:0.2.0
We can see our installed plugins:
wash plugin list
Now we can generate deployment manifests by targeting a component with the wit2wadm
subcommand. For the purposes of our demo, we'll create a new "Hello world" component:
wash new component hello --template-name hello-world-rust
Now we can navigate to the project directory and build our component from the Rust template:
cd hello
wash build
To generate the manifest, we'll simply target the .wasm
file generated by our build:
wash wit2wadm ./build/http_hello_world_s.wasm
And here's our manifest:
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: wit2wadm
annotations:
description: A wasmCloud Application
version: v0.1.0
labels:
generated-by: wit2wadm
spec:
components:
- name: wit2wadm
type: component
properties:
image: myregistry.io/wit2wadm:v0.1.0
traits:
- type: spreadscaler
properties:
instances: 1
- name: wasi:http-source
type: capability
properties:
image: ghcr.io/wasmcloud/http-server:canary
traits:
- type: link
properties:
target: wit2wadm
namespace: wasi
package: http
interfaces:
- incoming-handler
The wit2wadm
plugin extrapolates and defines things like links from the component, and then fills in unknown values (like the component's name or registry source) with placeholder values. We can use CLI flags to define those values as well:
wash wit2wadm --name demo --version 0.2.0 --description "Say hello" ./build/http_hello_world_s.wasm
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: demo
annotations:
description: Say hello
version: 0.2.0
labels:
generated-by: wit2wadm
spec:
components:
- name: demo
type: component
properties:
image: myregistry.io/demo:0.2.0
traits:
- type: spreadscaler
properties:
instances: 1
- name: wasi:http-source
type: capability
properties:
image: ghcr.io/wasmcloud/http-server:canary
traits:
- type: link
properties:
target: demo
namespace: wasi
package: http
interfaces:
- incoming-handler
You can learn more about the wit2wadm
project in the GitHub repo, and more about using wash plugin
in the wasmCloud documentation.
Developing wash plugins
If you're interested in developing wash plugins, the wasmCloud documentation includes a wash plugin developer guide. The developer guide breaks down the plugin API (a small wrapper around the wasi:cli/run
interface) along with details on implementing the run
function, accessing local files, plugin configuration, and more.
Join the community
We're excited to see what the community does with wash plugins, both as users and developers. If you have questions, want to share a plugin, give feedback on the feature, or just talk components and wasmCloud, join us on the wasmCloud community Slack!