diff --git a/jsonnetsecure/jsonnet.go b/jsonnetsecure/jsonnet.go index a8fe627a..69efc9fa 100644 --- a/jsonnetsecure/jsonnet.go +++ b/jsonnetsecure/jsonnet.go @@ -111,7 +111,7 @@ func JsonnetTestBinary(t testing.TB) string { cmd.Stderr = &stderr if err := cmd.Run(); err != nil || stderr.Len() != 0 { - t.Fatalf("building the Go binary returned error: %v\n%s", err, string(stderr.String())) + t.Fatalf("building the Go binary returned error: %v\n%s", err, stderr.String()) } return outPath diff --git a/jsonnetsecure/jsonnet_processvm.go b/jsonnetsecure/jsonnet_processvm.go index 391948b0..f057156f 100644 --- a/jsonnetsecure/jsonnet_processvm.go +++ b/jsonnetsecure/jsonnet_processvm.go @@ -13,6 +13,12 @@ import ( "strings" "time" + "go.opentelemetry.io/otel/attribute" + + "github.com/ory/x/otelx" + + "go.opentelemetry.io/otel/trace" + "github.com/cenkalti/backoff/v4" "github.com/pkg/errors" ) @@ -25,11 +31,18 @@ func NewProcessVM(opts *vmOptions) VM { } } -func (p *ProcessVM) EvaluateAnonymousSnippet(filename string, snippet string) (string, error) { +func (p *ProcessVM) EvaluateAnonymousSnippet(filename string, snippet string) (_ string, err error) { + tracer := trace.SpanFromContext(p.ctx).TracerProvider().Tracer("") + ctx, span := tracer.Start(p.ctx, "jsonnetsecure.ProcessVM.EvaluateAnonymousSnippet", trace.WithAttributes(attribute.String("filename", filename))) + defer otelx.End(span, &err) + // We retry the process creation, because it sometimes times out. const processVMTimeout = 1 * time.Second - return backoff.RetryWithData(func() (string, error) { - ctx, cancel := context.WithTimeout(p.ctx, processVMTimeout) + return backoff.RetryWithData(func() (_ string, err error) { + ctx, span := tracer.Start(ctx, "jsonnetsecure.ProcessVM.EvaluateAnonymousSnippet.run") + defer otelx.End(span, &err) + + ctx, cancel := context.WithTimeout(ctx, processVMTimeout) defer cancel() var ( @@ -49,7 +62,7 @@ func (p *ProcessVM) EvaluateAnonymousSnippet(filename string, snippet string) (s cmd.Stderr = &stderr cmd.Env = []string{"GOMAXPROCS=1"} - err := cmd.Run() + err = cmd.Run() if stderr.Len() > 0 { // If the process wrote to stderr, this means it started and we won't retry. return "", backoff.Permanent(fmt.Errorf("jsonnetsecure: unexpected output on stderr: %q", stderr.String())) @@ -59,7 +72,7 @@ func (p *ProcessVM) EvaluateAnonymousSnippet(filename string, snippet string) (s } return stdout.String(), nil - }, backoff.WithContext(backoff.NewExponentialBackOff(), p.ctx)) + }, backoff.WithContext(backoff.NewExponentialBackOff(), ctx)) } func (p *ProcessVM) ExtCode(key string, val string) { diff --git a/jsonnetsecure/jsonnet_test.go b/jsonnetsecure/jsonnet_test.go index 56d8ea68..1904d055 100644 --- a/jsonnetsecure/jsonnet_test.go +++ b/jsonnetsecure/jsonnet_test.go @@ -18,6 +18,8 @@ import ( ) func TestSecureVM(t *testing.T) { + testBinary := JsonnetTestBinary(t) + for _, optCase := range []struct { name string opts []Option @@ -25,7 +27,7 @@ func TestSecureVM(t *testing.T) { {"none", []Option{}}, {"process vm", []Option{ WithProcessIsolatedVM(context.Background()), - WithJsonnetBinary(JsonnetTestBinary(t)), + WithJsonnetBinary(testBinary), }}, } { t.Run("options="+optCase.name, func(t *testing.T) { @@ -114,7 +116,7 @@ func TestSecureVM(t *testing.T) { defer cancel() vm := MakeSecureVM( WithProcessIsolatedVM(ctx), - WithJsonnetBinary(JsonnetTestBinary(t)), + WithJsonnetBinary(testBinary), ) result, err := vm.EvaluateAnonymousSnippet("test", snippet) require.Error(t, err) @@ -161,12 +163,13 @@ func assertEqualVMOutput(t *testing.T, run func(factory func(t *testing.T) VM) s func TestCreateMultipleProcessVMs(t *testing.T) { ctx := context.Background() wg := new(errgroup.Group) + testBinary := JsonnetTestBinary(t) for i := 0; i < 100; i++ { wg.Go(func() error { vm := MakeSecureVM( WithProcessIsolatedVM(ctx), - WithJsonnetBinary(JsonnetTestBinary(t)), + WithJsonnetBinary(testBinary), ) _, err := vm.EvaluateAnonymousSnippet("test", "{a:1}")