runwasi
                                
                                 runwasi copied to clipboard
                                
                                    runwasi copied to clipboard
                            
                            
                            
                        feat(wamr): add wasm-mico-runtime shim implementation
this commit adds an additional shim implementation: Wamr using wamr-rust-sdk. At the moment, the shim isn't working with an error "thread signal env initialized failed" which I am not sure exactly sure what it means. Will ask the Wamr team for clarification. There are also some pain points using the newly created wamr-rust-sdk which I wrote as TODOs in the comment.
This PR should close #337
FYI @squillace @0xE282B0 @lum1n0us
this is GREAT!
@Mossaka does wamr work already?
WAMR team can provide help as much as possible.
Hey @macko99, thanks for reaching out! It doesn't work at the moment and this PR needs some love. I am going to refresh it and see if the errors will be resolved by the Wamr SDK. If not, I appreciate the Wamr team to offer some help. FYI @lum1n0us
@Mossaka it would be great if you could check the status of this PR! Keep me posted
@Mossaka I have made a small update to this PR link. The issues are still there. I played around with WAMR, warm-rust-sdk and runwasi without any luck. I'm afraid my understanding of the wamr runtime is holding me back at this point...
Based on the description in https://github.com/bytecodealliance/wasm-micro-runtime/issues/3627.
It requires to config pre-opens of WASI arguments. Here is a reference:
https://github.com/bytecodealliance/wamr-rust-sdk/blob/main/examples/wasi-hello/src/main.rs#L19-#L21
@lum1n0us please take a look at the PR
I do set let wasi_ctx = WasiCtxBuilder::new() .set_pre_open_path(vec!["/"], vec!["/"]) .set_env_vars(envs.iter().map(String::as_str).collect()) .build();
I have also tried with other dirs, just like in an example, it fails with "Error: ExecutionError("Exception: unreachable")"
To clarify: -when setting envs by set_env_vars the shim exists with no error or "thread signal env initialized failed" -when setting set_pre_open_path to "/:/" I get "error running start function: Failed to create instance: InstantiationFailure("error while pre-opening mapped directory: invalid map" -when setting set_pre_open_path to ".:" I get "Error: ExecutionError("Exception: unreachable")"
@macko99 I am thinking about running the PR locally. Is there any guides about how to?
Like, may I ask, if using sudo ctr run --rm --runtime=io.containerd.[ wasmedge | wasmtime | wasmer ].v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm /wasi-demo-app.wasm echo 'hello' to test, how to check the log, especially error info?
Like, may I ask, if using
sudo ctr run --rm --runtime=io.containerd.[ wasmedge | wasmtime | wasmer ].v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm /wasi-demo-app.wasm echo 'hello'to test, how to check the log, especially error info?
The log is containerd's log and containerd is running on your local host as a deamon process. You can try journalctl -u containerd to get containerd logs.
You may also refer to this doc on how to adjust logging levels. Note that you may need to restart containerd after modiying its config files by doing systemctl restart containerd
Thanks. Please don't mind my lack of related knowledge.
- Is there a way to check  println!()messages from runwasi, wamr-rust-sdk and even WAMR library.
- Is there a way that I can use rust-lldbto debug WAMR library behavior.
- Is there a way that I can simplify the demo, I mean to shrink sudo ctr run --rm --runtime=io.containerd.wasmtime.v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm /wasi-demo-app.wasm echo "hello"into few lines?
Is there a way to check println!() messages from runwasi, wamr-rust-sdk and even WAMR library.
If you wanna see logs from runwasi and sdk code, you can put log::info!() and see the messages in Containerd logs.
Is there a way that I can use rust-lldb to debug WAMR library behavior.
I've not tried this but I did try attaching the PID to vscode debugger to debug the shim binary.
Is there a way that I can simplify the demo, I mean to shrink
sudo ctr run --rm --runtime=io.containerd.wasmtime.v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm /wasi-demo-app.wasm echo "hello"into few lines?
What do you mean by this exactly? If you wanna create a simply wasm image, you can do so by authoring a hello world program, compile it to wasm, and package it as a OCI image, and then run it with ctr. You can take a look at crates/wasi-demo-app for how we packaged the wasi-demo application as a container.
Try this command but failed:
$ sudo ctr run --rm --runtime=io.containerd.wasmtime.v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm echo "hi"
ctr: failed to create shim task: Others("exec process failed with error error in executing process : wasmtime executor can't handle spec"): unknown
Using journalctl found.
Jul 23 14:01:28 code-factory-4 containerd[35743]: time="2024-07-23T06:01:28.990386595Z" level=error msg="failed to initialize container process: wasmtime executor can't handle spec"
Jul 23 14:01:28 code-factory-4 containerd[35743]: time="2024-07-23T06:01:28.990472575Z" level=error msg="failed to wait for init ready: exec process failed with error error in executing process : wasmtime executor can't handle spec"
Jul 23 14:01:28 code-factory-4 containerd[35743]: time="2024-07-23T06:01:28.990503254Z" level=error msg="failed to run container process err=Channel(ExecError("error in executing process : wasmtime executor can't handle spec"))"
It is similar with https://github.com/containerd/runwasi/issues/637. Any suggestion?
Try this command but failed:
$ sudo ctr run --rm --runtime=io.containerd.wasmtime.v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm echo "hi" ctr: failed to create shim task: Others("exec process failed with error error in executing process : wasmtime executor can't handle spec"): unknown
Try sudo ctr run --rm --runtime=io.containerd.wasmtime.v1 ghcr.io/containerd/runwasi/wasi-demo-app:latest testwasm /wasi-demo-app.wasm echo 'hi'?
I believe the wasi-demo-app takes the first argument as the wasm file and the second argument as the command.
There is an exception in wasi-demo-app.wasm when driving by WAMR. It is triggered by println!. And I guess it is related to crates/containerd-shim-wasm/src/sandbox/stdio.rs and stdio.redirect(). (Because I am enable to use WAMR to execute the same .wasm successfully). ~~Therefore, I am going to ask  that in order to support sandbox stdio, is there any requirement for a wasm runtime?~~
After some investigation, I learned why println! and eprintln! failed. In this specific execution environment:
- isatty()for STDOUT and STDERR are not a tty.
- fcntl()for STDOUT and STDERR are- O_RDONLY. (this is the root cause. It is supposed to be- R_WRONLY)
Therefore, fd_write() to STDOUT and STDERR (triggered by println!() and eprintln!()) will be rejected and raised an exception.
#00: 0x12ea7 - __rust_start_panic
#01: 0x12c30 - rust_panic
#02: 0x12954 - std::panicking::rust_panic_with_hook
#03: 0x11d0d - std::panicking::begin_panic_handler::{{closure}}
#04: 0x11c74 - std::sys_common::backtrace::__rust_end_short_backtrace
#05: 0x1245c - rust_begin_unwind
#06: 0x18140 - core::panicking::panic_fmt
#07: 0x1112f - std::io::stdio::_print
#08: 0x9cad - wasi_demo_app::main    ;; <-- `"echo" => println!("{}", &args[2..].join(" ")),`
#09: 0x2528 - core::ops::function::FnOnce::call_once
#10: 0x9276 - std::sys_common::backtrace::__rust_begin_short_backtrace
#11: 0xcdab - std::rt::lang_start::{{closure}}
#12: 0xf468 - std::rt::lang_start_internal
#13: 0xcd47 - std::rt::lang_start
#14: 0xa54c - __main_void
#15: 0x05bc - _start
@Mossaka need your help to take a look at below two problems. Both return values in runwasi/containerd are different with other execution environments.
isatty() for STDOUT and STDERR are not a tty. fcntl() for STDOUT and STDERR are O_RDONLY. (this is the root cause. It is supposed to be R_WRONLY)
the shim isn't working with an error "thread signal env initialized failed" which I am not sure exactly sure what it means.
A workaround of this issue is to disable memory bounds check with .define("WAMR_DISABLE_HW_BOUND_CHECK", "1"). Just like https://github.com/containerd/runwasi/pull/508. And latest wamr-rust-sdk has synced it(https://github.com/bytecodealliance/wamr-rust-sdk/blob/main/crates/wamr-sys/build.rs)
But the reason of this problem still bothers me. HW_BOUND_CHECK of WAMR will touch guard pages around wasm linear memory(mprotect() and ) and use a signal handler to catch signals if a memory operation accesses a invalid address. @Mossaka  Does the sandbox of runwasi allow both operations?
@Mossaka. Above unanticipated behaviors of sandbox(read-only stdout and guard page failures) still exist. Hope somebody would take a look. We made some workarounds in WAMR and wamr-rust-sdk. https://github.com/containerd/runwasi/pull/642 should work if following https://github.com/containerd/runwasi/pull/642#issuecomment-2249267192.
@lum1n0us, @Mossaka is on holiday. I'll give this some attention later today / tomorrow.