Skip to content

Commit

Permalink
feat: Add create enclave utils to SDK (#1550)
Browse files Browse the repository at this point in the history
## Description:
<!-- Describe this change, how it works, and the motivation behind it.
-->
A very idiomatic pattern in Go is to use `defer` and closer functions to
cleanup resources, instead of relying on memory to call the correct SDK
calls when the test/setup is done. This is very common on our test suit
that we have a util, that now is exposed to an external user.

This PR also introduces a single SDK call to get from starlark to
enclave, something that was not possible before.

## Is this change user facing?
YES
<!-- If yes, please add the "user facing" label to the PR -->
<!-- If yes, don't forget to include docs changes where relevant -->

## References (if applicable):
<!-- Add relevant Github Issues, Discord threads, or other helpful
information. -->
#1152
  • Loading branch information
victorcolombo authored Oct 13, 2023
1 parent ccff275 commit dbca010
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
71 changes: 71 additions & 0 deletions api/golang/util/create_enclave.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package util

import (
"context"
"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves"
"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/starlark_run_config"
"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context"
"github.com/kurtosis-tech/stacktrace"
)

func CreateEmptyEnclave(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, func() error, func() error, error) {
kurtosisCtx, err := kurtosis_context.NewKurtosisContextFromLocalEngine()
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to get kurtosis context from local engine. Is the engine running? Try running 'kurtosis engine start'")
}
enclaveCtx, err := kurtosisCtx.CreateEnclave(ctx, enclaveName)
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to create enclave.")
}
stopEnclaveFunc := func() error {
return kurtosisCtx.StopEnclave(ctx, enclaveName)

}
destroyEnclaveFunc := func() error {
return kurtosisCtx.DestroyEnclave(ctx, enclaveName)
}

return enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, nil
}

func combineErrors(starlarkResult *enclaves.StarlarkRunResult, err error) error {
if err != nil {
return stacktrace.Propagate(err, "Failed to run Starlark during setup")
}
if starlarkResult.InterpretationError != nil {
return stacktrace.NewError("Failed to setup enclave using Starlark because of an interpretation error:\n%v", starlarkResult.InterpretationError)
}
if len(starlarkResult.ValidationErrors) > 0 {
return stacktrace.NewError("Failed to setup enclave using Starlark because of an interpretation error:\n%v", starlarkResult.ValidationErrors)
}
if starlarkResult.ExecutionError != nil {
return stacktrace.NewError("Failed to setup enclave using Starlark because of an execution error:\n%v", starlarkResult.ExecutionError)
}
return nil
}

func CreateEnclaveFromStarlarkScript(ctx context.Context, enclaveName string, serializedScript string, runConfig *starlark_run_config.StarlarkRunConfig) (*enclaves.EnclaveContext, func() error, func() error, error) {
enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, err := CreateEmptyEnclave(ctx, enclaveName)
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to create empty enclave")
}
starlarkResult, err := enclaveCtx.RunStarlarkScriptBlocking(ctx, serializedScript, runConfig)
err = combineErrors(starlarkResult, err)
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to setup enclave using Starlark")
}
return enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, nil
}

func CreateEnclaveFromStarlarkRemotePackage(ctx context.Context, enclaveName string, packageId string, runConfig *starlark_run_config.StarlarkRunConfig) (*enclaves.EnclaveContext, func() error, func() error, error) {
enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, err := CreateEmptyEnclave(ctx, enclaveName)
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to create empty enclave")
}
starlarkResult, err := enclaveCtx.RunStarlarkRemotePackageBlocking(ctx, packageId, runConfig)
err = combineErrors(starlarkResult, err)
if err != nil {
return nil, nil, nil, stacktrace.Propagate(err, "Failed to setup enclave using Starlark")
}
return enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, nil
}
17 changes: 7 additions & 10 deletions internal_testsuites/golang/test_helpers/enclave_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"
"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves"
"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context"
"github.com/kurtosis-tech/kurtosis/api/golang/util"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"testing"
Expand All @@ -16,32 +16,29 @@ const (
)

func CreateEnclave(t *testing.T, ctx context.Context, testName string) (resultEnclaveCtx *enclaves.EnclaveContext, resultStopEnclaveFunc func(), resultDestroyEnclaveFunc func() error, resultErr error) {
kurtosisCtx, err := kurtosis_context.NewKurtosisContextFromLocalEngine()
require.NoError(t, err, "An error occurred connecting to the Kurtosis engine for running test '%v'", testName)
enclaveName := fmt.Sprintf(
"%v-%v-%v",
testsuiteNameEnclaveIDFragment,
testName,
time.Now().Unix(),
)
enclaveCtx, err := kurtosisCtx.CreateEnclave(ctx, enclaveName)
enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, err := util.CreateEmptyEnclave(ctx, enclaveName)
require.NoError(t, err, "An error occurred creating enclave '%v'", enclaveName)
stopEnclaveFunc := func() {

if err := kurtosisCtx.StopEnclave(ctx, enclaveName); err != nil {
stopEnclaveFuncWrapped := func() {
if err := stopEnclaveFunc(); err != nil {
logrus.Errorf("An error occurred stopping enclave '%v' that we created for this test:\n%v", enclaveName, err)
logrus.Errorf("ACTION REQUIRED: You'll need to stop enclave '%v' manually!!!!", enclaveName)
}

}
destroyEnclaveFunc := func() error {
if err := kurtosisCtx.DestroyEnclave(ctx, enclaveName); err != nil {
destroyEnclaveFuncWrapped := func() error {
if err := destroyEnclaveFunc(); err != nil {
logrus.Errorf("An error occurred destroying enclave '%v' that we created for this test:\n%v", enclaveName, err)
logrus.Errorf("ACTION REQUIRED: You'll need to destroy enclave '%v' manually!!!!", enclaveName)
return err
}
return nil
}

return enclaveCtx, stopEnclaveFunc, destroyEnclaveFunc, nil
return enclaveCtx, stopEnclaveFuncWrapped, destroyEnclaveFuncWrapped, nil
}

0 comments on commit dbca010

Please sign in to comment.