WASM + WASI + WAGI + Web Assembly Modules in Rust — Part 2

Loading an external Web Assembly Module in Rust

B Shyam Sundar
4 min readAug 3, 2022
Rust and Web Assembly

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

  1. Rust (1.60+)
  2. Docker
  3. CNCF Distribution
  4. 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

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

docker run regitry

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:

justfile snapshot

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

WASM pushed to OCI Registry

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:

modules.toml

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

ping-oci

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

network tab

Notice that the response is the same as what we got from our local WASM-WAGI ping which is

network tab — local wagi

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)

thangchung/webassembly-tour: ⚙️ Take you through a tour of WebAssembly (WASM targets on WASI) with wasmCloud, Krustlet, WAGI, etc. 🌟 Give it a star if you like it. (github.com)

--

--