This prepares for pseudo-root when the CLI doesn't provide one by
improving the error messages in general, as well being consistent about
parameter order.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This implements stat device and inode for WASI and GOOS=js, though it
does not implement the host side for windows, yet. Doing windows
requires plumbing as the values needed aren't exposed in Go. When we
re-do the syscallfs file type to have a stat method, we can address that
glitch. Meanwhile, I can find no Go sourcebase that does any better,
though the closest is the implementation details of os.SameFile.
I verified this with wasi-testsuite which now passes all but 1 case
which is unrelated (we haven't yet implemented `lseek`).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This implements WriterAtOffset, which supports WASI `fd_pwrite` and gojs
`fs.write` with offset, which is used to implement `syscall.Pwrite`.
I confirmed this passes the corresponding test in wasi-testsuite as
well.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This extracts a utility `syscallfs.ReaderAtOffset()` to allow WASI and
gojs to re-use the same logic to implement `syscall.Pread`.
What's different than before is that if WASI passes multiple iovecs an
emulated `ReaderAt` will seek to the read position on each call to
`Read` vs once per loop. This was a design decision to keep the call
sites compatible between files that implement ReaderAt and those that
emulate them with Seeker (e.g. avoid the need for a read-scoped closer/
defer function). The main use case for emulation is `embed.file`, whose
seek function is cheap, so there's little performance impact to this.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This fixes#1027.
WASI-libc prestats every fd from 3 until one returns EBADF.
If any other error is returned, the process exits with code 71 (EX_OSERR).
Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
This rewrites compositeFS to syscallfs.FS following wasi-sdk preopen
rules. Notably, this allows use of read-only mounts now.
For example,
```bash
$ GOOS=js GOARCH=wasm bin/go test -c -o template.wasm text/template
$ wazero run -mount=src/text/template:/ -mount=/tmp:/tmp template.wasm -test.v
=== RUN TestExecute
--- PASS: TestExecute (0.07s)
--snip--
```
This is the first step to native WASI handling of multiple pre-opens.
After this change, it is still the case that there's only one pre-open
FD visible to wasm. A later change will make it possible for WASI to see
multiple pre-opens while `GOOS=js` which doesn't use preopens, remains
on a rootFS.
A future PR may need to add a CLI flag to disable escaping directories,
(e.g. make ../.. EINVAL), similar to `fs.FS` in Go. The simplest way to
allow this is to use a host-side RootFS even in WASI, and wrap that with
a `syscallfs` filename filter.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This slips our 1.0 date a month while we try to get through
implementation issues around filesystems and various bugs.
While not mentioned in the README, we will move our experimental
syscallfs to an experimental package so that people who are ok with
drift can implement it while we try to target it for a 1.x release
ideally by June. Meanhile, our next pre-release will harden the
permanent APIs around implementing filesystems with existing directories
or go's `fs.FS` implementation.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This works around a known glitch in windows where directory entry stat
doesn't match its corresponding file stat (namely times don't). It
consolidates more test files, in the process, to ensure we are more
likely to trigger issues like this earlier.
Future work will finish the last couple places where we still use go's
fstest.MapFS internally, as well introduce stat tests at the syscallfs
abstraction: right now, most tests are still only defined in WASI.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Formerly, we introduced `wazero.Namespace` to help avoid module name or import conflicts while still sharing the runtime's compilation cache. Now that we've introduced `CompilationCache` `wazero.Namespace` is no longer necessary. By removing it, we reduce the conceptual load on end users as well internal complexity. Since most users don't use namespace, the change isn't very impactful.
Users who are only trying to avoid module name conflict can generate a name like below instead of using multiple runtimes:
```go
moduleName := fmt.Sprintf("%d", atomic.AddUint64(&m.instanceCounter, 1))
module, err := runtime.InstantiateModule(ctx, compiled, config.WithName(moduleName))
```
For `HostModuleBuilder` users, we no longer take `Namespace` as the last parameter of `Instantiate` method:
```diff
// log to the console.
_, err := r.NewHostModuleBuilder("env").
NewFunctionBuilder().WithFunc(logString).Export("log").
- Instantiate(ctx, r)
+ Instantiate(ctx)
if err != nil {
log.Panicln(err)
}
```
The following is an example diff a use of namespace can use to keep compilation cache while also ensuring their modules don't conflict:
```diff
func useMultipleRuntimes(ctx context.Context, cache) {
- r := wazero.NewRuntime(ctx)
+ cache := wazero.NewCompilationCache()
for i := 0; i < N; i++ {
- // Create a new namespace to instantiate modules into.
- ns := r.NewNamespace(ctx) // Note: this is closed when the Runtime is
+ r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().WithCompilationCache(cache))
// Instantiate a new "env" module which exports a stateful function.
_, err := r.NewHostModuleBuilder("env").
```
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@achille-roussel mentioned on chat that we have an accident waiting to
happen. This fixes it and backfills the missing test.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This introduces the new API wazero.Cache interface which can be passed to wazero.RuntimeConfig.
Users can configure this to share the underlying compilation cache across multiple wazero.Runtime.
And along the way, this deletes the experimental file cache API as it's replaced by this new API.
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
This consolidates test files and ensures our various implementations of
`syscallfs.FS` pass `fstest.TestFS`.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
FreeBSD is not natively supported by GitHub actions or Docker. To test
it, we had to run vagrant which is both time-consuming (~7minutes), and
frequently fails to setup, resulting in false negatives. Meanwhile the
code related to FreeBSD is quite limited and doesn't change.
This changes our approach to testing FreeBSD to the same as how we deal
with 386, which is to do compilation tests only.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds FS.Path which holds the pre-open path currently only used in
WASI. It also fixes a TODO where we didn't know for sure if the FD
parameter for `path_` functions must always be a pre-open. The TL;DR; is
that usually it is, but it may not be (e.g. in our zig-cc example we can
see any directory FD, not just pre-opens).
Finally, this fixes a bug in our path resolution where we mistook paths
like "foo/foo" for "foo" because we only considered basenames instead of
the full path from the pre-open root.
This also makes pre-open directory lookup lazy because I noticed in
Trivy specifically, this is unnecessary for us to do eagerly, as they
change the FS at runtime per-call. In other words, any value from init
time is invalid later.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Developers don't commonly think about 32-bit platforms and in one
instance we broke a release due to this (quickly fixed in pre.7). This
ensures arm and 386, used by dapr and trivy respectively are tested. It
also helps prove these are in use to avoid a later developer removing
support by thinking they aren't.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This avoids logging activity on stdio file descriptors, in order to help
make troubleshooting easier. Usually, there isn't an issue in these, yet
wasm panics are harder to read if there is also logging of the ..
logging.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This consolidates internal code to syscallfs, which removes the fs.FS
specific path rules, except when adapting one to syscallfs. For example,
this allows the underlying filesystem to decide if relative paths are
supported or not, as well any EINVAL related concerns.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This stubs all remaining syscalls for `GOARCH=wasm GOOS=js` to return
ENOSYS, instead of panic'ing. This allows us to see the parameters it
receives.
For example:
```
==> go.syscall/js.valueCall(fs.truncate(path=/tmp/_Go_TestTruncate135754730,length=0))
<== (err=function not implemented,ok=false)
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This masks interfaces returned by `fs.File` so that we don't
accidentally allow writes when opened for reading. This also adds
`syscall.NewReadFS` which can enforce read-only access in general, such
as would be ideal for tests that try to read files from the host root
filesystem (e.g. /etc/passwd).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
As noted in slack, we are unlikley to long term use fs.FS internally.
This ensures we attempt to cast to syscallfs.FS for all I/O by panicing
on fs.Open.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds ExportedFunctionDefinitions and ExportedMemoryDefinitions to
api.Module so that those who can't access CompileModule can see them.
Fixes#839
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This makes the version, arch, os tuple into a subdirectory to help
troubleshooting and cache management in general. The version is left
inside the binary key regardless.
Note: when installing via `go install ./cmd/wazero/...` the version ends
up as `dev`. This helps make that obvious. For example.
```bash
$ wazero version
dev
$ ./build/tinygo test -target wasi -c -o os.wasm os
$ wazero run -cachedir=$HOME/.wazero -mount=.:/ -env=HOME=. os.wasm -test.v
$ find $HOME/.wazero
/Users/adrian/.wazero
/Users/adrian/.wazero/wazero-dev-amd64-darwin
/Users/adrian/.wazero/wazero-dev-amd64-darwin/1f149f4bf475a33023ce33302780bee29ec08e89bd57cfbdf639c65c6009f1a4
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>