WASM + WASI + WAGI + Web Assembly Modules in Rust — Part 2
Loading an external Web Assembly Module in Rust
Introduction
This is Part — 2 in a three part series. If you haven’t, please read Part -1 before reading this part.
We had built a very simple Web Assembly module in Part-1. Now we need to find a way to distribute it. Enter wasm-to-oci. We will look at how we can load an external Web Assembly Module.
Prerequisites
- Rust (1.60+)
- Docker
- CNCF Distribution
- wasm-to-oci
WASM-TO-OCI
OCI stands for Open Container Initiative. Wasm-To-OCI is to use OCI registries to distribute Web Assembly Modules. A OCI registry is any registry that complies with OCI registry artifact spec.
ORAS (OCI Registry As Storage) is an implementation for the OCI artifacts Project. It simplifies storing content to OCI registries. Using the ORAS client library easily push and pull WASM modules to OCI registries. According to ORAS documentation, at the moment the following registries support OCI Artifacts
- CNCF Distribution — local/offline verification
- Azure Container Registry
- Amazon Elastic Container Registry
- Google Artifact Registry
- GitHub Packages container registry
- Bundle Bar
For our use case we will use an unauthenticated local CNCF Distribution.
CNCF Distribution
CNCF Distribution is a reference implementation of the OCI distribution-spec. Running distribution locally, as a container, provides local/offline verification of ORAS and OCI Artifacts.
- ORAS Docs
To fire up a local Distribution instance run the following command
#!/bin/bashdocker run -it --rm -p 5000:5000 registry
Note: You need to have docker daemon running in order to execute this command successfully.
If all goes well then you should see something like
Push to OCI Registry
Now that we have our registry spun up. It is time to push our Web Assembly to this OCI Registry.
From our Part-1 we will have the WASM file in ./target/wasm32-wasi/debug/level1.wasm. Before you can continue, kindly make sure you have wasm-to-oci cli installed on your machine.
Add the following line to your justfile
./justfilepush sample:wasm-to-oci push target/wasm32-wasi/debug/{{sample}}.wasm localhost:5000/wagi-{{sample}}-oci:latest
After adding this line the justfile would look like this:
After saving the changes, run the following command to push to your local registry.
#!/bin/bashjust push level1
If all goes well, you should see
Now that we have pushed our Web Assembly to our registry. It is time to use it in another project.
Load External Module
Now edit the modules.toml file and add the following lines
/modules.toml[[module]]
route = "/ping-oci"
module = "oci:localhost:5000/wagi-level1-oci:latest"
After adding this line your modules.toml file should look like:
After this let us fire up level1 by running
#!/bin/bashjust run level1
Now go to your browser and navigate to http://localhost:3000/ping-oci, if everything went well you should see
Would you look at that. We got our response from the WASM that is external just like that.
Let us look at the network tab
Notice that the response is the same as what we got from our local WASM-WAGI ping which is
Wow! We are able to load an external web assembly module without any libraries. This external WASM runs inside a sandbox and doesn’t have access to our file system or anything. The WAGI server runs this code and responds with that “pong”.
In the next part we will look at how this web assembly can be deployed to a Kubernetes Cluster.
References
Introduction to WAGI | Slides + Coverage (fettblog.eu)
https://youtu.be/9NDwHBjLlhQ — Very useful video and the main influence for this article
deislabs/wagi: Write HTTP handlers in WebAssembly with a minimal amount of work (github.com)
Wasm, WASI, Wagi: What are they? | Fermyon Technologies (@FermyonTech)