A virtual jailed shell environment for Go apps backed by an io/fs#FS.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 76 lines 2.0 kB view raw
1package python3 2 3import ( 4 "context" 5 _ "embed" 6 "errors" 7 8 "github.com/tetratelabs/wazero" 9 "github.com/tetratelabs/wazero/experimental/sysfs" 10 "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" 11 wsys "github.com/tetratelabs/wazero/sys" 12 "mvdan.cc/sh/v3/interp" 13 "tangled.org/xeiaso.net/kefka/command" 14 "tangled.org/xeiaso.net/kefka/wasm/billyfs" 15) 16 17//go:embed python.wasm 18var pyWASM []byte 19 20var ( 21 runtime wazero.Runtime 22 compiled wazero.CompiledModule 23) 24 25func init() { 26 ctx := context.Background() 27 runtime = wazero.NewRuntime(ctx) 28 wasi_snapshot_preview1.MustInstantiate(ctx, runtime) 29 30 var err error 31 compiled, err = runtime.CompileModule(ctx, pyWASM) 32 if err != nil { 33 panic(err) 34 } 35} 36 37type Impl struct{} 38 39func (Impl) Exec(ctx context.Context, ec *command.ExecContext, args []string) error { 40 // Bare `python3` would otherwise slurp stdin to EOF before executing 41 // (the non-TTY default), which hangs the REPL under sophia. Force 42 // interactive mode so it eval-prints line by line. -S skips site.py, 43 // which under -i would inject cwd ('/') into sys.path and try to 44 // import readline by listdir-walking '/' — that path fails on s3fs 45 // and brings down the REPL before the first prompt. 46 if len(args) == 0 { 47 args = []string{"-i", "-S"} 48 } 49 50 fsConfig := wazero.NewFSConfig().(sysfs.FSConfig). 51 WithSysFSMount(billyfs.New(ec.FS), "/") 52 53 config := wazero.NewModuleConfig(). 54 WithStdin(ec.Stdin). 55 WithStdout(ec.Stdout). 56 WithStderr(ec.Stderr). 57 WithArgs(append([]string{"python3"}, args...)...). 58 WithName("python3"). 59 WithEnv("PYTHONUNBUFFERED", "1"). 60 WithFSConfig(fsConfig). 61 WithSysNanosleep(). 62 WithSysNanotime(). 63 WithSysWalltime() 64 65 mod, err := runtime.InstantiateModule(ctx, compiled, config) 66 if err != nil { 67 if exitErr, ok := errors.AsType[*wsys.ExitError](err); ok { 68 if code := exitErr.ExitCode(); code != 0 { 69 return interp.ExitStatus(uint8(code)) 70 } 71 return nil 72 } 73 return err 74 } 75 return mod.Close(ctx) 76}