summaryrefslogtreecommitdiffhomepage
path: root/HOWTO.md
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2023-08-02 17:03:48 +0100
committerAndrew Clayton <a.clayton@nginx.com>2023-08-21 23:24:12 +0100
commitd6ed6a219b31a58526721f96195c80061d41ce54 (patch)
tree17a1fd6ecf72a327916ff0f8bc7aaf85b981ceff /HOWTO.md
downloadunit-wasm-0.1.0.tar.gz
unit-wasm-0.1.0.tar.bz2
Initial commitv0.1.0
libunit-wasm and example C and Rust WebAssembly modules for NGINX Unit. Co-developed-by: Timo Stark <t.stark@nginx.com> Co-developed-by: Liam Crilly <liam@nginx.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to '')
-rw-r--r--HOWTO.md203
1 files changed, 203 insertions, 0 deletions
diff --git a/HOWTO.md b/HOWTO.md
new file mode 100644
index 0000000..c2d2ae7
--- /dev/null
+++ b/HOWTO.md
@@ -0,0 +1,203 @@
+Trying it out
+=============
+
+For a quick and simple 'hello world' experience, you can use docker with
+
+```shell
+$ make docker
+```
+
+which will create two images:
+
+ 1. `unit:wasm` (based on the Docker Official image, with Wasm Module)
+ 2. `unit:demo-wasm` (based on the Wasm image, with demo application)
+
+Manual build instructions below.
+
+## Prerequisites and Assumptions
+
+You will need:
+ * Modern Linux platform (might work on others, not yet tested).
+ * Ability to build Unit from source.
+ If you haven't done this before, please first run through the
+[Building From Source how-to guide](https://unit.nginx.org/howto/source/).
+ * Additional build tools (required for the demo Wasm Module)
+ - clang
+ - llvm
+ - lld
+
+## Building the Wasm Language Module
+
+0. Do a test build of Unit from source ([see docs](https://unit.nginx.org/howto/source/)) with this PR/patch applied. The following steps assume you're
+starting in the `unit` directory and used `./configure --prefix=$PWD/build`.
+
+2. Download and extract the Wasmtime C API (newer versions may or may not
+work). Notice that we use `$(arch)` to substitute-in the appropriate CPU
+architecture. This works for **x86_64** and **aarch64** (ARM) platforms.
+```
+wget -O- https://github.com/bytecodealliance/wasmtime/releases/download/v11.0.0/wasmtime-v11.0.0-$(arch)-linux-c-api.tar.xz | tar Jxfv -
+```
+
+3. Configure the Wasm Language Module for Unit
+```
+./configure wasm --include-path=$PWD/wasmtime-v11.0.0-$(arch)-linux-c-api/include \
+ --lib-path=$PWD/wasmtime-v11.0.0-$(arch)-linux-c-api/lib --rpath
+```
+
+4. Build the Wasm Language Module
+```
+make
+```
+
+5. Test that **unitd** Can Load the Language Module
+
+Run `unitd` in the foreground (attached to the console) to check that Unit
+can discover and load the `wasm` Language Module at startup. You should see
+console output similar to this:
+```
+$ $PWD/build/sbin/unitd --no-daemon --log /dev/stderr
+2023/06/15 11:29:31 [info] 1#1 unit 1.31.0 started
+2023/06/15 11:29:31 [info] 43#43 discovery started
+2023/06/15 11:29:31 [notice] 43#43 module: wasm 0.1 "/path/to/modules/wasm.unit.so"
+```
+
+## Building the demo application
+
+From a suitable directory...
+
+Clone the [unit-wasm](https://github.com/nginx/unit-wasm) repository
+
+```shell
+$ git clone https://github.com/nginx/unit-wasm.git
+```
+
+Download and extract the wasi-sysroot from the [WASI SDK](https://github.com/WebAssembly/wasi-sdk)
+
+```shell
+wget -O- https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sysroot-20.0.tar.gz | tar zxfv -
+```
+
+Next Compile the C demo Wasm Modules to `.wasm` files. This requires at least
+the following; make and clang, llvm, compiler-rt, and lld from LLVM 8.0+
+
+```shell
+$ cd unit-wasm
+$ make WASI_SYSROOT=../wasi-sysroot examples
+```
+
+If the above fails like
+
+```
+wasm-ld: error: cannot open /usr/lib/llvm-11/lib/clang/11.0.1/lib/wasi/libclang_rt.builtins-wasm32.a: No such file or directory
+clang: error: linker command failed with exit code 1 (use -v to see invocation)
+```
+Then you need to download the wasm32 clang runtime and copy it into the
+location mentioned in the error message.
+
+E.g
+
+In the above case we would untar
+*libclang_rt.builtins-wasm32-wasi-20.0.tar.gz* into
+*/usr/lib/llvm-11/lib/clang/11.0.1/*
+
+On Fedora this would be more like */usr/lib64/clang/16/*
+
+Adjust the tar '-C ...' option accordingly below...
+
+```shell
+wget -O- https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/libclang_rt.builtins-wasm32-wasi-20.0.tar.gz | sudo tar -xvzf - -C /usr/lib/llvm-11/lib/clang/11.0.1
+```
+
+Then try again...
+
+If everything built OK then you should have the following two WASM modules
+
+```
+examples/c/luw-echo-request.wasm
+examples/c/luw-upload-reflector.wasm
+```
+
+## Configure Unit to run the demo application
+
+```json
+ {
+ "listeners": {
+ "[::1]:8080": {
+ "pass": "routes"
+ }
+ },
+
+ "settings": {
+ "http": {
+ "max_body_size": 1073741824
+ }
+ },
+
+ "routes": [
+ {
+ "match": {
+ "uri": "/echo*"
+ },
+ "action": {
+ "pass": "applications/luw-echo-request"
+ }
+ },
+ {
+ "match": {
+ "uri": "/upload*"
+ },
+ "action": {
+ "pass": "applications/luw-upload-reflector"
+ }
+ }
+ ],
+
+ "applications": {
+ "luw-echo-request": {
+ "type": "wasm",
+ "module": "/path/to/unit-wasm/examples/c/luw-echo-request.wasm",
+ "request_handler": "luw_request_handler",
+ "malloc_handler": "luw_malloc_handler",
+ "free_handler": "luw_free_handler",
+ "module_init_handler": "luw_module_init_handler",
+ "module_end_handler": "luw_module_end_handler",
+ "access": {
+ "filesystem": [
+ "/tmp",
+ "/foo/bar"
+ ]
+ }
+ },
+ "luw-upload-reflector": {
+ "type": "wasm",
+ "module": "/path/to/unit-wasm/examples/c/luw-upload-reflector.wasm",
+ "request_handler": "luw_request_handler",
+ "malloc_handler": "luw_malloc_handler",
+ "free_handler": "luw_free_handler",
+ "request_end_handler": "luw_request_end_handler",
+ "response_end_handler": "luw_response_end_handler"
+ }
+ }
+}
+
+```
+
+Apply the above configuration to the **/config** URI of Unit's Control API.
+With the JSON in a file, you can use the CLI to apply it.
+```
+cat conf.json | tools/unitc /config
+```
+
+The following messages should then appear in the Unit log file (or console if
+running with `--no-daemon`).
+```
+2023/07/26 13:28:14 [info] 182585#182585 "luw-echo-request" prototype started
+2023/07/26 13:28:14 [info] 182590#182590 "luw-echo-request" application started
+2023/07/26 13:28:14 [info] 182591#182591 "luw-upload-reflector" prototype started
+2023/07/26 13:28:14 [info] 182596#182596 "luw-upload-reflector" application started
+```
+
+Now make a request to the demo application.
+```
+curl http://localhost:8080/echo
+```