diff options
author | Andrew Clayton <a.clayton@nginx.com> | 2023-08-02 17:03:48 +0100 |
---|---|---|
committer | Andrew Clayton <a.clayton@nginx.com> | 2023-08-21 23:24:12 +0100 |
commit | d6ed6a219b31a58526721f96195c80061d41ce54 (patch) | |
tree | 17a1fd6ecf72a327916ff0f8bc7aaf85b981ceff /HOWTO.md | |
download | unit-wasm-d6ed6a219b31a58526721f96195c80061d41ce54.tar.gz unit-wasm-d6ed6a219b31a58526721f96195c80061d41ce54.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 'HOWTO.md')
-rw-r--r-- | HOWTO.md | 203 |
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 +``` |