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

feat(provider): add wasmer provider #677

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

bnjjj
Copy link

@bnjjj bnjjj commented Sep 10, 2021

Here is the draft to implement wasmer as a runtime to execute wasm in krustlet. It's working with demos, excepting the demo with postman as I didn't already implemented the experimental http methods.

I have few questions regarding my implementation. I added a "provider" crate but it seems all the files are almost the same except the method spawn_wasmtime and spawn_wasmer. Do you think it's a good idea to keep these 2 separated crates or just have only one crate wasi_runtime and put spawn_wasmer methods and so one inside ?

Todo:

  • Add an interrupt mechanism
  • Add wasmer support for wasi-experimental-http
  • Use upstream version of wasmer when changes are merged

@bacongobbler
Copy link
Collaborator

Hey @bnjjj! Thanks for working on this one.

Do you think it's a good idea to keep these 2 separated crates

In general we've started splitting out all of the providers into their own projects. For example the wasmCloud provider now lives at https://github.com/wasmCloud/krustlet-wasmcloud-provider and the wasm3 provider is over at https://github.com/bacongobbler/krustlet-wasm3. Same for the CRI provider: https://github.com/kflansburg/krustlet-cri

Would you be okay with putting this work in its own repository?

Thanks!

@bnjjj
Copy link
Author

bnjjj commented Sep 10, 2021

Yes why not, if it's the way to do that I'm okay. What I suggest is to let this PR as a draft and open for now. I will continue my work and maybe when it's done you will be able to give me a little review/overview before closing this PR and put everything in my own repository. What do you think ?

@thomastaylor312
Copy link
Member

That sounds like a great idea @bnjjj!

@technosophos
Copy link
Collaborator

WHOA! This is so cool! It'll be great to have a Wasmer provider!

@bnjjj
Copy link
Author

bnjjj commented Sep 19, 2021

If you have time to review feel free, I can't implement for now the http experimental part and the interrupt part as some features/documentation are missing on Wasmer. So I plan to put this code into his own repository after your review and then document all current limitations. I will then implement missing features on Wasmer to have all the features for krustlet.

Copy link
Collaborator

@bacongobbler bacongobbler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good first step! Left a bit of feedback around some of the code. Otherwise I think it's in good shape to split out into a separate project. Thanks for your contributions!

use wasmer_wasi::{VirtualFile, WasiFsError};

/// For piping stdio. Stores all output / input in a byte-vector.
pub struct FilePipe {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, is there a reason not to use the newtype pattern? i.e.

pub struct FilePipe(std::fs::File);

https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I will move to this pattern you're right. Thanks

crates/wasmer-provider/src/pipes.rs Show resolved Hide resolved
crates/wasmer-provider/src/pipes.rs Show resolved Hide resolved
crates/wasmer-provider/src/pipes.rs Show resolved Hide resolved
fn try_from(value: File) -> Result<Self, Self::Error> {
Ok(Self {
file: value
.try_into_std()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this will immediately attempt to convert a File to a StdFile without allowing async write operations to complete IIRC. Is there a technical reason why we can't implement From instead of TryFrom to allow a cleaner migration?

https://docs.rs/tokio/1.12.0/tokio/fs/struct.File.html#method.try_into_std

crates/wasmer-provider/src/pipes.rs Show resolved Hide resolved
@@ -66,6 +68,8 @@ pub struct Config {
/// device plugins lives. This is also where device plugins
/// should host their services.
pub device_plugins_dir: PathBuf,
/// Wasm runtime to use to execute your wasm
pub provider: Provider,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So generally speaking we've avoided adding internal implementation details like a Provider type directly into the kubelet crate. The goal of this crate is to implement the kubelet API without leaking any implementation details of Krustlet. That way clients can use the kubelet crate to interact with the Kubernetes API and impersonate a kubelet any way they choose.

Since you're just introducing this type to check a string value.... This seems more appropriate in the provider code itself.

"wasmtime" => Ok(Self::WasmTime),
"wasmer" => Ok(Self::Wasmer),
other => Err(anyhow::anyhow!(
"unknown provider '{:?}', please choose between 'wasmer' and 'wasmtime'",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other providers out there than just these two by the way. For example:

https://github.com/bacongobbler/krustlet-wasm3
https://github.com/kflansburg/krustlet-cri
https://github.com/wasmCloud/krustlet-wasmcloud-provider
https://github.com/deislabs/krustlet-wagi-provider
https://github.com/bacongobbler/krustlet-wasmdome
https://github.com/soenkeliebau/stackable_krustlet

These are just some of the examples I could find through Github's search engine.

I don't think we should be in the business of listing "known providers" in the crate anyways.

@@ -17,7 +17,7 @@ use super::running::Running;
use super::terminated::Terminated;
use super::ContainerState;

pub const MAX_CONNCURRENT_REQUESTS_ANNOTATION_KEY: &str =
pub const MAX_CONCURRENT_REQUESTS_ANNOTATION_KEY: &str =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch.

bors bot added a commit to wasmerio/wasmer that referenced this pull request Oct 6, 2021
2569: refactor(api): add Send + Sync trait when creating an instance r=Amanieu a=bnjjj

# Description

I'm currently implementing wasmer inside Krustlet (krustlet/krustlet#677). Then I had to force the thread safety of trait object used to create a wasmer instance. I know it could be a breaking change and maybe I miss some backgrounds about this. So feel free to let me know what do you think and how we could have a better implementation if needed. I'm open to any suggestions.


Co-authored-by: Benjamin Coenen <[email protected]>
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

Successfully merging this pull request may close these issues.

None yet

4 participants