From 72c0f2275d22d5f46c836e297a2276da46bda8e0 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Thu, 3 Apr 2025 06:41:24 +0530 Subject: [PATCH] add variables support for wasip2 sdk Signed-off-by: Rajat Jindal --- v2/examples/variables/go.mod | 12 ++++++++ v2/examples/variables/go.sum | 4 +++ v2/examples/variables/main.go | 24 +++++++++++++++ v2/examples/variables/spin.toml | 22 ++++++++++++++ v2/go.mod | 15 ---------- v2/go.sum | 35 ---------------------- v2/integration_test.go | 28 ++++++++++++++++-- v2/variables/testdata/variables/go.mod | 12 ++++++++ v2/variables/testdata/variables/go.sum | 4 +++ v2/variables/testdata/variables/main.go | 23 +++++++++++++++ v2/variables/testdata/variables/spin.toml | 22 ++++++++++++++ v2/variables/variables.go | 36 +++++++++++++++++++++++ 12 files changed, 185 insertions(+), 52 deletions(-) create mode 100644 v2/examples/variables/go.mod create mode 100644 v2/examples/variables/go.sum create mode 100644 v2/examples/variables/main.go create mode 100644 v2/examples/variables/spin.toml create mode 100644 v2/variables/testdata/variables/go.mod create mode 100644 v2/variables/testdata/variables/go.sum create mode 100644 v2/variables/testdata/variables/main.go create mode 100644 v2/variables/testdata/variables/spin.toml create mode 100644 v2/variables/variables.go diff --git a/v2/examples/variables/go.mod b/v2/examples/variables/go.mod new file mode 100644 index 0000000..3d0a5f5 --- /dev/null +++ b/v2/examples/variables/go.mod @@ -0,0 +1,12 @@ +module github.com/spinframework/spin-go-sdk/v2/examples/variables + +go 1.24.1 + +require github.com/spinframework/spin-go-sdk/v2 v2.0.0 + +require ( + github.com/julienschmidt/httprouter v1.3.0 // indirect + go.bytecodealliance.org/cm v0.2.2 // indirect +) + +replace github.com/spinframework/spin-go-sdk/v2 => ../../ diff --git a/v2/examples/variables/go.sum b/v2/examples/variables/go.sum new file mode 100644 index 0000000..c1ebfdf --- /dev/null +++ b/v2/examples/variables/go.sum @@ -0,0 +1,4 @@ +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= +go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= diff --git a/v2/examples/variables/main.go b/v2/examples/variables/main.go new file mode 100644 index 0000000..e0a4091 --- /dev/null +++ b/v2/examples/variables/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "net/http" + + spinhttp "github.com/spinframework/spin-go-sdk/v2/http" + "github.com/spinframework/spin-go-sdk/v2/variables" +) + +func init() { + spinhttp.Handle(func(w http.ResponseWriter, r *http.Request) { + + // Get variable value `message` defined in spin.toml. + val, err := variables.Get("message") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintln(w, "message: ", val) + }) +} + +func main() {} diff --git a/v2/examples/variables/spin.toml b/v2/examples/variables/spin.toml new file mode 100644 index 0000000..6c9fdb6 --- /dev/null +++ b/v2/examples/variables/spin.toml @@ -0,0 +1,22 @@ +spin_manifest_version = 2 + +[application] +name = "variables-example" +authors = ["Fermyon Engineering "] +description = "A simple Spin application written in (Tiny)Go." +version = "1.0.0" + +[variables] +object = { default = "teapot" } + +[[trigger.http]] +route = "/..." +component = "variables" + +[component.variables] +source = "main.wasm" +[component.variables.variables] +message = "I'm a {{object}}" + +[component.hello.build] +command = "tinygo build -target=wasip2 --wit-package $(go list -mod=readonly -m -f '{{.Dir}}' github.com/spinframework/spin-go-sdk/v2)/wit --wit-world http-trigger -gc=leaking -no-debug -o main.wasm main.go" \ No newline at end of file diff --git a/v2/go.mod b/v2/go.mod index e8a8927..ac994dc 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -4,20 +4,5 @@ go 1.23.2 require ( github.com/julienschmidt/httprouter v1.3.0 - go.bytecodealliance.org v0.6.2 go.bytecodealliance.org/cm v0.2.2 ) - -require ( - github.com/coreos/go-semver v0.3.1 // indirect - github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/regclient/regclient v0.8.2 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/tetratelabs/wazero v1.9.0 // indirect - github.com/ulikunitz/xz v0.5.12 // indirect - github.com/urfave/cli/v3 v3.0.0-beta1 // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/sys v0.30.0 // indirect -) diff --git a/v2/go.sum b/v2/go.sum index c2db9ff..c1ebfdf 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -1,39 +1,4 @@ -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/regclient/regclient v0.8.2 h1:23BQ3jWgKYHHIXUhp/S9laVJDHDoOQaQCzXMJ4undVE= -github.com/regclient/regclient v0.8.2/go.mod h1:uGyetv0o6VLyRDjtfeBqp/QBwRLJ3Hcn07/+8QbhNcM= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= -github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli/v3 v3.0.0-beta1 h1:6DTaaUarcM0wX7qj5Hcvs+5Dm3dyUTBbEwIWAjcw9Zg= -github.com/urfave/cli/v3 v3.0.0-beta1/go.mod h1:FnIeEMYu+ko8zP1F9Ypr3xkZMIDqW3DR92yUtY39q1Y= -go.bytecodealliance.org v0.4.0 h1:SRwgZIcXR54AmbJg9Y3AMgDlZlvD8dffteBYW+nCD3k= -go.bytecodealliance.org v0.4.0/go.mod h1:hkdjfgQ/bFZYUucnm9cn0Q8/SHO3iT0rzskYlkV4Jy0= -go.bytecodealliance.org v0.6.2 h1:Jy4u5DVmSkXgsnwojBhJ+AD/YsJsR3VzVnxF0xRCqTQ= -go.bytecodealliance.org v0.6.2/go.mod h1:gqjTJm0y9NSksG4py/lSjIQ/SNuIlOQ+hCIEPQwtJgA= go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/v2/integration_test.go b/v2/integration_test.go index 7fb4470..0fd458d 100644 --- a/v2/integration_test.go +++ b/v2/integration_test.go @@ -42,7 +42,7 @@ type testSpin struct { cmd *exec.Cmd } -func startSpin(t *testing.T, dir string) *testSpin { +func startSpin(t *testing.T, dir string, extraArgs ...string) *testSpin { buildApp(t, dir) url := getFreePort(t) @@ -50,7 +50,7 @@ func startSpin(t *testing.T, dir string) *testSpin { // long timeout because... ci ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) - cmd := exec.CommandContext(ctx, spinBinary, "up", "--listen", url) + cmd := exec.CommandContext(ctx, spinBinary, append([]string{"up", "--listen", url}, extraArgs...)...) cmd.Dir = dir stderr := new(bytes.Buffer) cmd.Stderr = stderr @@ -144,6 +144,30 @@ func TestKeyValue(t *testing.T) { } } +func TestVariables(t *testing.T) { + spin := startSpin(t, "variables/testdata/variables") + defer spin.cancel() + + resp := retryGet(t, spin.url) + spin.cancel() + if resp.Body == nil { + t.Fatal("body is nil") + } + t.Log(resp.Status) + b, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + t.Fatal(err) + } + + // assert response body + want := "message: I'm a teapot\n" + got := string(b) + if want != got { + t.Fatalf("body is not equal: want = %q got = %q", want, got) + } +} + // TestBuildExamples ensures that the tinygo examples will build successfully. func TestBuildExamples(t *testing.T) { examples, err := os.ReadDir("examples") diff --git a/v2/variables/testdata/variables/go.mod b/v2/variables/testdata/variables/go.mod new file mode 100644 index 0000000..74ae187 --- /dev/null +++ b/v2/variables/testdata/variables/go.mod @@ -0,0 +1,12 @@ +module github.com/spinframework/spin-go-sdk/v2/examples/variables + +go 1.24.1 + +require github.com/spinframework/spin-go-sdk/v2 v2.0.0 + +require ( + github.com/julienschmidt/httprouter v1.3.0 // indirect + go.bytecodealliance.org/cm v0.2.2 // indirect +) + +replace github.com/spinframework/spin-go-sdk/v2 => ../../../ diff --git a/v2/variables/testdata/variables/go.sum b/v2/variables/testdata/variables/go.sum new file mode 100644 index 0000000..c1ebfdf --- /dev/null +++ b/v2/variables/testdata/variables/go.sum @@ -0,0 +1,4 @@ +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +go.bytecodealliance.org/cm v0.2.2 h1:M9iHS6qs884mbQbIjtLX1OifgyPG9DuMs2iwz8G4WQA= +go.bytecodealliance.org/cm v0.2.2/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI= diff --git a/v2/variables/testdata/variables/main.go b/v2/variables/testdata/variables/main.go new file mode 100644 index 0000000..bd16daf --- /dev/null +++ b/v2/variables/testdata/variables/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "net/http" + + spinhttp "github.com/spinframework/spin-go-sdk/v2/http" + "github.com/spinframework/spin-go-sdk/v2/variables" +) + +func init() { + spinhttp.Handle(func(w http.ResponseWriter, r *http.Request) { + // Get variable value `message` defined in spin.toml. + val, err := variables.Get("message") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintln(w, "message: ", val) + }) +} + +func main() {} diff --git a/v2/variables/testdata/variables/spin.toml b/v2/variables/testdata/variables/spin.toml new file mode 100644 index 0000000..f51dd6d --- /dev/null +++ b/v2/variables/testdata/variables/spin.toml @@ -0,0 +1,22 @@ +spin_manifest_version = 2 + +[application] +name = "variables-example" +authors = ["Fermyon Engineering "] +description = "A simple Spin application written in (Tiny)Go." +version = "1.0.0" + +[variables] +object = { default = "teapot" } + +[[trigger.http]] +route = "/..." +component = "variables" + +[component.variables] +source = "main.wasm" +[component.variables.variables] +message = "I'm a {{object}}" + +[component.variables.build] +command = "tinygo build -target=wasip2 --wit-package $(go list -mod=readonly -m -f '{{.Dir}}' github.com/spinframework/spin-go-sdk/v2)/wit --wit-world http-trigger -gc=leaking -no-debug -o main.wasm main.go" \ No newline at end of file diff --git a/v2/variables/variables.go b/v2/variables/variables.go new file mode 100644 index 0000000..7223fdd --- /dev/null +++ b/v2/variables/variables.go @@ -0,0 +1,36 @@ +package variables + +import ( + "fmt" + + "github.com/spinframework/spin-go-sdk/v2/internal/fermyon/spin/v2.0.0/variables" +) + +// Get an application variable value for the current component. +// +// The name must match one defined in in the component manifest. +func Get(key string) (string, error) { + result := variables.Get(key) + if result.IsErr() { + return "", errorVariantToError(*result.Err()) + } + + return *result.OK(), nil +} + +func errorVariantToError(err variables.Error) error { + switch { + case err.InvalidName() != nil: + return fmt.Errorf(*err.InvalidName()) + case err.Provider() != nil: + return fmt.Errorf(*err.Provider()) + case err.Undefined() != nil: + return fmt.Errorf(*err.Undefined()) + default: + if err.Other() != nil { + return fmt.Errorf(*err.Other()) + } + + return fmt.Errorf("no error provided by host implementation") + } +}