Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to restrict import of unused features required by string type? #433

Open
XX opened this issue Dec 30, 2024 · 7 comments
Open

How to restrict import of unused features required by string type? #433

XX opened this issue Dec 30, 2024 · 7 comments

Comments

@XX
Copy link

XX commented Dec 30, 2024

When I make a simple .wit using the string type, like this:

package component:add;

world example {
    export add: func(x: string, y: u8) -> string;
}

after building and running I get a request to add a bunch of additional interfaces:

$ wasm-tools component wit ./target/wasm32-wasip1/release/add.wasm 
package root:component;

world root {
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:io/[email protected];
  import wasi:io/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:clocks/[email protected];
  import wasi:filesystem/[email protected];
  import wasi:filesystem/[email protected];

  export add: func(x: string, y: u8) -> string;
...

In particular, after running:

$ cargo run -p host -- 2 3 target/wasm32-wasip1/release/add.wasm
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.83s
     Running `target/debug/host 2 3 target/wasm32-wasip1/release/add.wasm`
Error: Failed to instantiate the example world

Caused by:
    0: component imports instance `wasi:cli/[email protected]`, but a matching implementation was not found in the linker
    1: instance export `get-environment` has the wrong type
    2: function implementation is missing

But my component should not have the right to get environment variables and do other things. How can I do this?

@vados-cosmonic
Copy link
Contributor

Hey @XX so when you build a component in Rust, those imports are needed for the backtrace machinery.

There's a discussion on Zulip around exactly why that is.

The resulting solutions aren't great (either building for an explicitly non-component target or using nightly rust to remove the default panic machinery), but the discussion should be helpful to you!

Unfortunately to run the component as-is in a host embedding, you'll need to link in WASI dependencies.

@XX
Copy link
Author

XX commented Dec 31, 2024

@vados-cosmonic So there is no way to restrict a component in using environment variables and other things if it uses a string in interfaces? Because only for integer types in the .wit file such imports are not required.

@dicej
Copy link
Collaborator

dicej commented Dec 31, 2024 via email

@XX
Copy link
Author

XX commented Dec 31, 2024

@dicej No, I didn't fully understand what was required. In my case, it was enough to add the necessary interfaces to the linker on the host to make everything work:

let mut linker = Linker::<States>::new(&engine);
wasmtime_wasi::add_to_linker_sync(&mut linker)?;

The component still won't have access to the stdout, file system etc. until I set up access via context. For example, to access stdout:

pub struct States {
    table: ResourceTable,
    ctx: WasiCtx,
}

impl States {
    pub fn new() -> Self {
        let table = ResourceTable::new();
        let ctx = WasiCtxBuilder::new()
            .stdout(wasmtime_wasi::stdout()) // <----- by default stdout is closed, using the host's native stdout
            .build();
        Self { table, ctx }
    }
}

impl WasiView for States {
    fn table(&mut self) -> &mut ResourceTable {
        &mut self.table
    }

    fn ctx(&mut self) -> &mut WasiCtx {
        &mut self.ctx
    }
}

But if I still needed to get rid of unnecessary imports, I would take the advice to use the nightly compiler and recompile the std with panic_immediate_abort feature:
https://bytecodealliance.zulipchat.com/#narrow/channel/217126-wasmtime/topic/wasi.20pulled.20in.20unintentionally/near/490269017
Thank you @vados-cosmonic

@vados-cosmonic
Copy link
Contributor

Hey @XX glad you were able to get the host working (IMO the world is a lot more interesting with the WASI imports :)

That said, hopefully you saw the discussion and Joel's specific recommendation (I should have called it out like he did!) -- for super simple components you can use wasm32-unknown-unknown as a target, and you won't get the WASI deps (by default)

@XX
Copy link
Author

XX commented Jan 1, 2025

@vados-cosmonic Yes, but in my case the component should be able to work with fs, environment variables etc., but only if the user of the host program has granted permissions.

@vados-cosmonic
Copy link
Contributor

Ah thanks for clarifying! Glad you were able to get the issue sorted :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants