Run a Wasm file as an application without a manifest#2479
Run a Wasm file as an application without a manifest#2479itowlson merged 1 commit intospinframework:mainfrom
Conversation
src/commands/up/app_source.rs
Outdated
| match spin_common::paths::resolve_manifest_file_path(path.into()) { | ||
| Ok(file) => Self::File(file), | ||
| Ok(file) => { | ||
| if file.extension().and_then(std::ffi::OsStr::to_str) == Some("wasm") { |
There was a problem hiding this comment.
Might be nice to support *.wat as well. If we want to be really precise we can use wasmparser to peek the special bytes to determine if the file is Wasm.
There was a problem hiding this comment.
we can use
wasmparserto peek the special bytes
...or bytes.starts_with(b"\x00asm") 🙂
There was a problem hiding this comment.
we can use
wasmparserto peek the special bytes...or
bytes.starts_with(b"\x00asm")🙂
There was a problem hiding this comment.
This is absolutely world class bikeshedding, keep it up
There was a problem hiding this comment.
To add to the bikeshedding — do we actually expect users to try this with .wat?
There was a problem hiding this comment.
Most tools in this space accept either wat or wasm interchangeably, so yes...
There was a problem hiding this comment.
I mean no, I don't think we expect users to use .wat, but also it isn't that hard to support apart from this slight inconvenience in detecting file type.
There was a problem hiding this comment.
For now I have checked for the .wasm and .wat extensions, and isolated the "is it a Wasm file" logic into a function that we can evolve with magic numbers and wasmparsers and other such wild excesses if and when people feel strongly about it. And by "we" I mean you Brian
|
Folks, do we have any thoughts on whether to take this forward in its current form? (Ignoring the detail of how we identify Wasm files.) |
|
I remain in favor of my proposal 🙂 |
|
IIUC this would not provide a way to do any IO, because that would require having anything allow-listed, right? If so, I think that's a perfectly valid starting point, but it might make sense to see if we could at least provide slightly better error messages? Such as telling folks that if they want to do outbound http, they have to use a manifest? |
|
@lann Which proposal do you mean? |
|
@tschneidereit That would require either threading "did the app come from a loose Wasm file" all the way through Spin, or majorly reworking our error reporting architecture. This would be a case where the Target Worlds proposal would be helpful, because we can give manifestless apps an implicit target world that doesn't include outbound HTTP, KV stores, etc. etc. Target world validation would, I'm pretty sure, happen at a time and level where we are still threading the origin info through, so it would be easy to customise the world validation failure to talk about supplying a manifest. If that's correct, then we could either punt this until after Target Worlds, or go ahead with this accepting that the errors will be suboptimal for now, with a view to sorting them out in the TW timeframe. |
|
@itowlson that makes sense, and I agree that if getting to better error messages right now is too hard, then that's okay because as you say we have other things in flight that should get us there :) |
|
Next discussion topic is do we put this on |
|
I think |
lann
left a comment
There was a problem hiding this comment.
A few non-blocking suggestions; looks great!
|
|
||
| /// Load a Spin locked app from a standalone Wasm file. | ||
| pub async fn from_wasm_file(wasm_path: impl AsRef<Path>) -> Result<LockedApp> { | ||
| let app_root = std::env::current_dir()?; |
There was a problem hiding this comment.
I would feel slightly better if we used a tempdir here. It shouldn't make any difference as the feature currently works, but as features are added I wouldn't want to accidentally expose content from the cwd.
There was a problem hiding this comment.
Actually, I believe you already have working_dir where this function is called; could probably just pass that through.
There was a problem hiding this comment.
This is the directory relative to which to resolve the Wasm file reference (and, perhaps, in future, other paths). If we use working_dir then we have to copy the Wasm file first (before copying it again), and any file-related errors will show unexpected locations.
The alternative is for app_root to be the directory containing the Wasm file, and to override wasm_path to be only the name of the Wasm file (so that the relative reference resolves correctly), but I'm not sure that's going to be helpful with hypothetical future features where the user will expect paths entered on the CLI to be resolved relative to the current directory. Of course it's hard to know because we haven't defined those features yet!
We could also do a more invasive change that threads multiple "app roots" through the loader, or redefines the app root, or absolutises everything earlier. Or we can have a separate loader path for much longer than this PR does it, e.g. doing any copies needed then jumping straight to building the lockfile instead of leaning on the existing manifestful path.
There was a problem hiding this comment.
Sounds complicated. I retract my feelings.
crates/loader/src/lib.rs
Outdated
| Direct, | ||
| } | ||
|
|
||
| fn single_file_manifest(wasm_path: impl AsRef<Path>) -> spin_manifest::schema::v2::AppManifest { |
There was a problem hiding this comment.
I think you could get away with using the toml! macro here, which would be much less and code and easier to read.
| pub enum AppSource { | ||
| File(PathBuf), | ||
| OciRegistry(String), | ||
| BareWasm(PathBuf), |
There was a problem hiding this comment.
Should we add an explicit CLI arg (e.g. --from-wasm) for this path like we have for the other app sources?
There was a problem hiding this comment.
Yes, I had wondered about this. I'm concerned it would make the docs a bit confusing, given that --from-file (in the current proposal) also accepts Wasm files (because my lawyers inform me that Wasm files are files within the meaning of the Act). I suppose we could deprecate --from-file and define a new --from-manifest flag that forces the file to be interpreted as TOML, but this feels excessive. Although maybe I'll feel differently if I understand what #2529 is about.
There was a problem hiding this comment.
Maybe it would be better to instead have an orthogonal option to differentiate between manifestful and manifestless sources. Anyway, that ought to be backward compatible with this so definitely not a blocker here.
Signed-off-by: itowlson <ivan.towlson@fermyon.com>
Fixes #2477. Or at least it explores what a solution might look like - there are definitely other paths to consider.
For example, this goes the route of constructing an in-memory
spin.toml, because the route fromspin.tomlto locked app to trigger is well-exercised. But we could bypass that and construct a lockfile directly - a lot ofspin.tomlconcerns are not (yet) relevant to manifestless applications.Or we could start planning more extensively for Future Things - this POC doesn't really provide any support in terms of the OCI proposal.
One thing we discussed internally was whether to put this on
spin upor on a new command such asspin serve(by analogy withwasmtime serve). For the sake of this POC I put it onspin upand inferred "bare file or manifest" based on the file extension. This is not intended as a proposal, just a thing to dangle the actual loader code off.Anyway hopefully provides us with something to argue about grin