Skip to content

Commit

Permalink
Implement proc/
Browse files Browse the repository at this point in the history
  • Loading branch information
lthibault committed Nov 14, 2024
1 parent c3a4d80 commit c0fdccc
Show file tree
Hide file tree
Showing 20 changed files with 1,132 additions and 451 deletions.
100 changes: 27 additions & 73 deletions cmd/internal/run/run.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package run

import (
"context"
"fmt"
"io"
"io/fs"
"log/slog"
"net/http"
"strings"

"github.com/ipfs/boxo/path"
"github.com/ipfs/kubo/client/rpc"
Expand Down Expand Up @@ -79,21 +74,32 @@ func run() cli.ActionFunc {
}
defer d.Close()

// fetches <path> for `ww run <path>`
bootloader := unixFSNode{
Name: c.Args().First(),
Unix: ipfs.Unixfs()}
r := wazero.NewRuntimeWithConfig(c.Context, wazero.NewRuntimeConfig().
// WithCompilationCache().
WithDebugInfoEnabled(c.Bool("debug")).
WithCloseOnContextDone(true))
defer r.Close(c.Context)

root, err := path.NewPath(c.Args().First())
if err != nil {
return err
}

unixFS := system.IPFS{
Ctx: c.Context,
Unix: ipfs.Unixfs(),
}

return ww.Env{
IPFS: ipfs,
Host: h,
Boot: bootloader,
WASM: wazero.NewRuntimeConfig().
WithDebugInfoEnabled(c.Bool("debug")).
WithCloseOnContextDone(true),
Module: moduleConfig(c, system.FSConfig{
IPFS: ipfs,
Host: h}),
Args: c.Args().Slice(),
Vars: c.StringSlice("env"),
Stdin: maybeStdin(c),
Stdout: maybeStdout(c),
Stderr: maybeStderr(c),
Host: h,
Runtime: r,
Root: root.String(),
FS: unixFS,
}.Serve(c.Context)
}
}
Expand All @@ -119,61 +125,9 @@ func (s peerStorer) HandlePeerFound(info peer.AddrInfo) {
}
}

type unixFSNode struct {
Name string
Unix iface.UnixfsAPI
}

func (u unixFSNode) Load(ctx context.Context) ([]byte, error) {
p, err := path.NewPath(u.Name)
if err != nil {
return nil, err
}

n, err := u.Unix.Get(ctx, p)
if err != nil {
return nil, err
}
defer n.Close()

return io.ReadAll(n.(io.Reader))
}

func moduleConfig(c *cli.Context, fs fs.FS) wazero.ModuleConfig {
config := wazero.NewModuleConfig().
WithArgs(c.Args().Tail()...).
WithName(c.Args().Tail()[0]).
WithStdin(maybeStdin(c)).
WithStdout(maybeStdout(c)).
WithStderr(maybeStderr(c)).
WithFSConfig(wazero.NewFSConfig().
WithFSMount(fs, "/p2p/").
WithFSMount(fs, "/ipfs/").
WithFSMount(fs, "/ipns/").
WithFSMount(fs, "/ipld/"))
return withEnvironment(c, config)
}

func withEnvironment(c *cli.Context, config wazero.ModuleConfig) wazero.ModuleConfig {
version := fmt.Sprintf("WW_VERSION=%s", ww.Version)
root := fmt.Sprintf("WW_ROOT=%s", c.Args().First())
env := append(c.StringSlice("env"), version, root)

for _, v := range env {
if maybePair := strings.SplitN(v, "=", 2); len(maybePair) == 2 {
config = config.WithEnv(maybePair[0], maybePair[1])
} else {
slog.DebugContext(c.Context, "ignoring invalid environment variable",
"value", v)
}
}

return config
}

func maybeStdin(c *cli.Context) io.Reader {
if c.Bool("interactive") {
return c.App.Reader
return c.App.Reader // TODO: wrap with libreadline
}

return nil
Expand All @@ -184,13 +138,13 @@ func maybeStdout(c *cli.Context) io.Writer {
return c.App.Writer
}

return nil
return io.Discard // TODO: handle stdout
}

func maybeStderr(c *cli.Context) io.Writer {
if c.Bool("interactive") {
return c.App.ErrWriter
}

return nil
return io.Discard // TODO: handle stderr
}
51 changes: 51 additions & 0 deletions examples/deliver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//go:generate tinygo build -o main.wasm -target=wasi -scheduler=none main.go

package main

import (
"context"
"io"
"log/slog"
"os"

"github.com/urfave/cli/v2"
)

func main() {
ctx := context.TODO()

app := &cli.App{
Name: "deliver",
Usage: "read message from stdn and send to `PID`",
ArgsUsage: "<PID>",
// Flags: []cli.Flag{},
Action: deliver,
}

if err := app.RunContext(ctx, os.Args); err != nil {
slog.ErrorContext(ctx, "application failed",
"reason", err)
os.Exit(1)
}
}

func deliver(c *cli.Context) error {
name := c.Args().First()
f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()

r := io.LimitReader(c.App.Reader, 1<<32-1) // max unit32

if n, err := io.Copy(f, r); err != nil {
return err
} else {
slog.DebugContext(c.Context, "delivered message",
"size", n,
"dest", name)
}

return nil
}
Binary file added examples/deliver/main.wasm
Binary file not shown.
11 changes: 8 additions & 3 deletions examples/echo/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:generate env GOOS=wasip1 GOARCH=wasm go build -o main.wasm
//go:generate tinygo build -o main.wasm -target=wasi -scheduler=none main.go

package main

Expand All @@ -7,6 +7,11 @@ import (
"os"
)

func main() {
io.Copy(os.Stdout, os.Stdin)
//export echo
func echo() {
if _, err := io.Copy(os.Stdout, os.Stdin); err != nil {
panic(err)
}
}

func main() {}
Binary file modified examples/echo/main.wasm
100755 → 100644
Binary file not shown.
23 changes: 23 additions & 0 deletions examples/print-env/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:generate tinygo build -o main.wasm -target=wasi -scheduler=none main.go

package main

import (
"fmt"
"io"
"os"
)

//export environment
func environment(size uint32) {
// Defensive: clear out any data that the user may have sent,
// even if we aren't expecting it.
defer io.Copy(io.Discard, os.Stdin)

// Calmly print the environment to stdout
for _, v := range os.Environ() {
fmt.Fprintln(os.Stdout, v)
}
}

func main() {}
Binary file added examples/print-env/main.wasm
Binary file not shown.
Loading

0 comments on commit c0fdccc

Please sign in to comment.