Repository: kurtosis-tech/kurtosis
Pull request #1170 (2023-08-28 13:21:48)

feat: Persist runtime value store
## Description:
Persist runtime value store

## Is this change user-facing?
NO

## References (if applicable):
This is part of the APIC restart project


leoporoli: @victorcolombo don't forget this guy! :)

Patch:
diff --git a/core/server/api_container/main.go b/core/server/api_container/main.go
index 0f3c383a4..da5560488 100644
--- a/core/server/api_container/main.go
+++ b/core/server/api_container/main.go
@@ -162,7 +162,11 @@ func runMain() error {
 		return stacktrace.Propagate(err, "An error occurred creating the service network")
 	}
 
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	if err != nil {
+		return stacktrace.Propagate(err, "An error occurred creating the runtime value store")
+	}
+
 	// TODO: Consolidate Interpreter, Validator and Executor into a single interface
 	startosisRunner := startosis_engine.NewStartosisRunner(
 		startosis_engine.NewStartosisInterpreter(serviceNetwork, gitPackageContentProvider, runtimeValueStore, serverArgs.EnclaveEnvVars),
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
index 27e23ab1e..8683dea56 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
@@ -152,7 +152,9 @@ func (builtin *AddServiceCapabilities) Execute(ctx context.Context, _ *builtin_a
 		return "", stacktrace.Propagate(err, "An error occurred while checking if service '%v' is ready", replacedServiceName)
 	}
 
-	fillAddServiceReturnValueWithRuntimeValues(startedService, builtin.resultUuid, builtin.runtimeValueStore)
+	if err := fillAddServiceReturnValueWithRuntimeValues(startedService, builtin.resultUuid, builtin.runtimeValueStore); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred while adding service return values with result key UUID '%s'", builtin.resultUuid)
+	}
 	instructionResult := fmt.Sprintf("Service '%s' added with service UUID '%s'", replacedServiceName, startedService.GetRegistration().GetUUID())
 	return instructionResult, nil
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
index 4887b6656..d6fb1510b 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
@@ -24,11 +24,14 @@ const (
 	hostnameRuntimeValue  = "hostname"
 )
 
-func fillAddServiceReturnValueWithRuntimeValues(service *service.Service, resultUuid string, runtimeValueStore *runtime_value_store.RuntimeValueStore) {
-	runtimeValueStore.SetValue(resultUuid, map[string]starlark.Comparable{
+func fillAddServiceReturnValueWithRuntimeValues(service *service.Service, resultUuid string, runtimeValueStore *runtime_value_store.RuntimeValueStore) error {
+	if err := runtimeValueStore.SetValue(resultUuid, map[string]starlark.Comparable{
 		ipAddressRuntimeValue: starlark.String(service.GetRegistration().GetPrivateIP().String()),
 		hostnameRuntimeValue:  starlark.String(service.GetRegistration().GetHostname()),
-	})
+	}); err != nil {
+		return stacktrace.Propagate(err, "An error occurred setting value with key '%s' in the runtime value store", resultUuid)
+	}
+	return nil
 }
 
 func makeAddServiceInterpretationReturnValue(serviceName starlark.String, serviceConfig *service.ServiceConfig, resultUuid string) (*kurtosis_types.Service, *startosis_errors.InterpretationError) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
index d06c3d157..3b295a34a 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
@@ -194,7 +194,9 @@ func (builtin *AddServicesCapabilities) Execute(ctx context.Context, _ *builtin_
 	instructionResult := strings.Builder{}
 	instructionResult.WriteString(fmt.Sprintf("Successfully added the following '%d' services:", len(startedServices)))
 	for serviceName, serviceObj := range startedAndUpdatedService {
-		fillAddServiceReturnValueWithRuntimeValues(serviceObj, builtin.resultUuids[serviceName], builtin.runtimeValueStore)
+		if err := fillAddServiceReturnValueWithRuntimeValues(serviceObj, builtin.resultUuids[serviceName], builtin.runtimeValueStore); err != nil {
+			return "", stacktrace.Propagate(err, "An error occurred while adding service return values with result key UUID '%s'", builtin.resultUuids[serviceName])
+		}
 		instructionResult.WriteString(fmt.Sprintf("\n  Service '%s' added with UUID '%s'", serviceName, serviceObj.GetRegistration().GetUUID()))
 	}
 	shouldDeleteAllStartedServices = false
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
index c1fdd2f39..67fc13fd4 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
@@ -168,7 +168,9 @@ func (builtin *ExecCapabilities) Execute(ctx context.Context, _ *builtin_argumen
 		return "", stacktrace.NewError(formatErrorMessage(errorMessage, result["output"].String()))
 	}
 
-	builtin.runtimeValueStore.SetValue(builtin.resultUuid, result)
+	if err := builtin.runtimeValueStore.SetValue(builtin.resultUuid, result); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred setting value '%+v' using key UUID '%s' in the runtime value store", result, builtin.resultUuid)
+	}
 	instructionResult := builtin.execRecipe.ResultMapToString(result)
 	return instructionResult, err
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
index 3d0745f21..635ec478c 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
@@ -179,7 +179,10 @@ func (builtin *RequestCapabilities) Execute(ctx context.Context, _ *builtin_argu
 	if !builtin.skipCodeCheck && !builtin.isAcceptableCode(result) {
 		return "", stacktrace.NewError("Request returned status code '%v' that is not part of the acceptable status codes '%v'", result["code"], builtin.acceptableCodes)
 	}
-	builtin.runtimeValueStore.SetValue(builtin.resultUuid, result)
+	if err := builtin.runtimeValueStore.SetValue(builtin.resultUuid, result); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred setting value '%+v' using key UUID '%s' in the runtime value store", result, builtin.resultUuid)
+	}
+
 	instructionResult := builtin.httpRequestRecipe.ResultMapToString(result)
 	return instructionResult, err
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_python.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_python.go
index 9a1717662..6ce2e29c2 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_python.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_python.go
@@ -310,7 +310,9 @@ func (builtin *RunPythonCapabilities) Execute(ctx context.Context, _ *builtin_ar
 		runResultCodeKey:   starlark.MakeInt(int(runPythonExecutionResult.GetExitCode())),
 	}
 
-	builtin.runtimeValueStore.SetValue(builtin.resultUuid, result)
+	if err := builtin.runtimeValueStore.SetValue(builtin.resultUuid, result); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred setting value '%+v' using key UUID '%s' in the runtime value store", result, builtin.resultUuid)
+	}
 	instructionResult := resultMapToString(result, RunPythonBuiltinName)
 
 	// throw an error as execution of the command failed
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_sh.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_sh.go
index 468b1f643..2b5c56c21 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_sh.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/run_sh.go
@@ -214,7 +214,9 @@ func (builtin *RunShCapabilities) Execute(ctx context.Context, _ *builtin_argume
 		runResultCodeKey:   starlark.MakeInt(int(createDefaultDirectoryResult.GetExitCode())),
 	}
 
-	builtin.runtimeValueStore.SetValue(builtin.resultUuid, result)
+	if err := builtin.runtimeValueStore.SetValue(builtin.resultUuid, result); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred setting value '%+v' using key UUID '%s' in the runtime value store", result, builtin.resultUuid)
+	}
 	instructionResult := resultMapToString(result, RunShBuiltinName)
 
 	// throw an error as execution of the command failed
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
index 946f4a8c0..18d7a250a 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
@@ -261,7 +261,9 @@ func (builtin *WaitCapabilities) Execute(ctx context.Context, _ *builtin_argumen
 		)
 	}
 
-	builtin.runtimeValueStore.SetValue(builtin.resultUuid, lastResult)
+	if err := builtin.runtimeValueStore.SetValue(builtin.resultUuid, lastResult); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred setting value '%+v' using key UUID '%s' in the runtime value store", lastResult, builtin.resultUuid)
+	}
 
 	instructionResult := fmt.Sprintf(
 		"Wait took %d tries (%v in total). Assertion passed with following:\n%s",
diff --git a/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository.go b/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository.go
new file mode 100644
index 000000000..3b48ab691
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository.go
@@ -0,0 +1,177 @@
+package runtime_value_store
+
+import (
+	"encoding/json"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
+	"github.com/kurtosis-tech/stacktrace"
+	"github.com/sirupsen/logrus"
+	bolt "go.etcd.io/bbolt"
+	"go.starlark.net/starlark"
+	"strconv"
+)
+
+var (
+	recipeResultBucketName = []byte("recipe-result-repository")
+	emptyValue             = []byte{}
+)
+
+type recipeResultRepository struct {
+	enclaveDb *enclave_db.EnclaveDB
+}
+
+func getOrCreateNewRecipeResultRepository(enclaveDb *enclave_db.EnclaveDB) (*recipeResultRepository, error) {
+	if err := enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket, err := tx.CreateBucketIfNotExists(recipeResultBucketName)
+		if err != nil {
+			return stacktrace.Propagate(err, "An error occurred while creating the recipe result database bucket")
+		}
+		logrus.Debugf("Recipe result bucket: '%+v'", bucket)
+
+		return nil
+	}); err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred while building the recipe result repository")
+	}
+
+	repository := &recipeResultRepository{
+		enclaveDb: enclaveDb,
+	}
+
+	return repository, nil
+}
+
+func (repository *recipeResultRepository) SaveKey(
+	uuid string,
+) error {
+
+	if err := repository.enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(recipeResultBucketName)
+
+		uuidKey := getUuidKey(uuid)
+
+		// save it to disk
+		if err := bucket.Put(uuidKey, emptyValue); err != nil {
+			return stacktrace.Propagate(err, "An error occurred while registering key UUID '%s' into the enclave db bucket", uuid)
+		}
+		return nil
+	}); err != nil {
+		return stacktrace.Propagate(err, "An error occurred while registering key UUID '%s' into the enclave db", uuid)
+	}
+	return nil
+}
+
+// Save store recipe result values into the repository, and it only accepts comparables of
+// starlark.String and starlark.Int so far
+func (repository *recipeResultRepository) Save(
+	uuid string,
+	value map[string]starlark.Comparable,
+) error {
+
+	if err := repository.enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(recipeResultBucketName)
+
+		uuidKey := getUuidKey(uuid)
+
+		stringifiedValue := map[string]string{}
+
+		for key, comparableValue := range value {
+			//TODO add more kind of comparable types if we want to extend the support
+			//TODO now starlark.Int and starlark.String are enough so far
+			switch valueType := comparableValue.(type) {
+			case starlark.Int:
+				stringifiedValue[key] = comparableValue.String()
+			case starlark.String:
+				comparableStr, ok := comparableValue.(starlark.String)
+				if !ok {
+					return stacktrace.NewError("An error occurred casting comparable type '%v' to Starlark string", comparableValue)
+				}
+				stringifiedValue[key] = comparableStr.GoString()
+			default:
+				return stacktrace.NewError("Unexpected comparable type on recipe result repository, only 'starlark.String and slartark.Int' are allowed but '%v' was received.", valueType)
+			}
+		}
+
+		jsonBytes, err := json.Marshal(stringifiedValue)
+		if err != nil {
+			return stacktrace.Propagate(err, "An error occurred marshalling value '%+v' in the recipe result repository", value)
+		}
+
+		// save it to disk
+		if err := bucket.Put(uuidKey, jsonBytes); err != nil {
+			return stacktrace.Propagate(err, "An error occurred while saving recipe result value '%+v' with UUID '%s' into the enclave db bucket", value, uuid)
+		}
+		return nil
+	}); err != nil {
+		return stacktrace.Propagate(err, "An error occurred while saving recipe result value '%+v' with UUID '%s' into the enclave db", value, uuid)
+	}
+	return nil
+}
+
+func (repository *recipeResultRepository) Get(
+	uuid string,
+) (map[string]starlark.Comparable, error) {
+
+	value := map[string]starlark.Comparable{}
+
+	if err := repository.enclaveDb.View(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(recipeResultBucketName)
+
+		uuidKey := getUuidKey(uuid)
+
+		// first get the bytes
+		jsonBytes := bucket.Get(uuidKey)
+
+		// check for existence
+		if jsonBytes == nil {
+			return stacktrace.NewError("Recipe result value with keu UUID '%s' does not exist on the recipe result repository", uuid)
+		}
+
+		isEmptyValue := len(jsonBytes) == len(emptyValue)
+
+		// this will the case if the key was saved with an empty value
+		if isEmptyValue {
+			return nil
+		}
+
+		stringifiedValue := map[string]string{}
+
+		if err := json.Unmarshal(jsonBytes, &stringifiedValue); err != nil {
+			return stacktrace.Propagate(err, "An error occurred unmarshalling the recipe result value with UUID '%s' from the repository", uuid)
+		}
+
+		for key, stringifiedComparable := range stringifiedValue {
+			var comparableValue starlark.Comparable
+			comparableInt, err := strconv.Atoi(stringifiedComparable)
+			if err != nil {
+				comparableValue = starlark.String(stringifiedComparable)
+			} else {
+				comparableValue = starlark.MakeInt(comparableInt)
+			}
+			value[key] = comparableValue
+		}
+
+		return nil
+	}); err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred while getting the recipe result value with UUID '%s' from the enclave db", uuid)
+	}
+	return value, nil
+}
+
+func (repository *recipeResultRepository) Delete(uuid string) error {
+	if err := repository.enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(recipeResultBucketName)
+
+		uuidKey := getUuidKey(uuid)
+		if err := bucket.Delete(uuidKey); err != nil {
+			return stacktrace.Propagate(err, "An error occurred deleting a recipe result with key '%v' from the recipe result bucket", uuidKey)
+		}
+
+		return nil
+	}); err != nil {
+		return stacktrace.Propagate(err, "An error occurred while deleting a recipe result with key '%v' from the recipe result repository", uuid)
+	}
+	return nil
+}
+
+func getUuidKey(uuid string) []byte {
+	return []byte(uuid)
+}
diff --git a/core/server/api_container/server/startosis_engine/runtime_value_store/runtime_value_store.go b/core/server/api_container/server/startosis_engine/runtime_value_store/runtime_value_store.go
index 9bd214351..1deae3826 100644
--- a/core/server/api_container/server/startosis_engine/runtime_value_store/runtime_value_store.go
+++ b/core/server/api_container/server/startosis_engine/runtime_value_store/runtime_value_store.go
@@ -2,21 +2,34 @@ package runtime_value_store
 
 import (
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/uuid_generator"
 	"github.com/kurtosis-tech/stacktrace"
 	"go.starlark.net/starlark"
 )
 
 type RuntimeValueStore struct {
-	recipeResultMap         map[string]map[string]starlark.Comparable
-	serviceAssociatedValues map[service.ServiceName]string
+	recipeResultRepository            *recipeResultRepository
+	serviceAssociatedValuesRepository *serviceAssociatedValuesRepository
 }
 
-func NewRuntimeValueStore() *RuntimeValueStore {
-	return &RuntimeValueStore{
-		recipeResultMap:         make(map[string]map[string]starlark.Comparable),
-		serviceAssociatedValues: make(map[service.ServiceName]string),
+func CreateRuntimeValueStore(enclaveDb *enclave_db.EnclaveDB) (*RuntimeValueStore, error) {
+	associatedValuesRepository, err := getOrCreateNewServiceAssociatedValuesRepository(enclaveDb)
+	if err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred getting or creating the service associated values repository")
 	}
+
+	recipeResultRepositoryObj, err := getOrCreateNewRecipeResultRepository(enclaveDb)
+	if err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred getting or creating the recipe result repository")
+	}
+
+	runtimeValueStore := &RuntimeValueStore{
+		recipeResultRepository:            recipeResultRepositoryObj,
+		serviceAssociatedValuesRepository: associatedValuesRepository,
+	}
+
+	return runtimeValueStore, nil
 }
 
 func (re *RuntimeValueStore) CreateValue() (string, error) {
@@ -24,31 +37,59 @@ func (re *RuntimeValueStore) CreateValue() (string, error) {
 	if err != nil {
 		return "", stacktrace.Propagate(err, "An error occurred while generating uuid for runtime value")
 	}
-	re.recipeResultMap[uuid] = nil
+
+	if err = re.recipeResultRepository.SaveKey(uuid); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred saving key UUID '%s' on the recipe result repository", uuid)
+	}
+
 	return uuid, nil
 }
 
 func (re *RuntimeValueStore) GetOrCreateValueAssociatedWithService(serviceName service.ServiceName) (string, error) {
-	if uuid, found := re.serviceAssociatedValues[serviceName]; found {
-		delete(re.recipeResultMap, uuid) // deleting old values so that they do not interfere until that are set again
-		return uuid, nil
+
+	exist, err := re.serviceAssociatedValuesRepository.Exist(serviceName)
+	if err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred checking if there are associated values for service '%s' in the service associated values repository", serviceName)
+	}
+	if exist {
+		uuid, getErr := re.serviceAssociatedValuesRepository.Get(serviceName)
+		if getErr != nil {
+			return "", stacktrace.Propagate(err, "An error occurred getting associated values for service '%s'", serviceName)
+		}
+		if uuid != "" {
+			// deleting old values so that they do not interfere until that are set again
+			if err := re.recipeResultRepository.Delete(uuid); err != nil {
+				return "", stacktrace.Propagate(err, "An error occurred deleting recipe result with key '%s' from the repository", uuid)
+			}
+			return uuid, nil
+		}
 	}
 	uuid, err := re.CreateValue()
 	if err != nil {
 		return "", stacktrace.Propagate(err, "An error occurred creating a simple runtime value")
 	}
-	re.serviceAssociatedValues[serviceName] = uuid
+
+	if err := re.serviceAssociatedValuesRepository.Save(serviceName, uuid); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred saving associated values '%s' for service '%s' in the service associated values repository", uuid, serviceName)
+	}
+
 	return uuid, nil
 }
 
-func (re *RuntimeValueStore) SetValue(uuid string, value map[string]starlark.Comparable) {
-	re.recipeResultMap[uuid] = value
+// SetValue store recipe result values into the runtime value store, and it only accepts comparables of
+// starlark.String and starlark.Int so far, make sure to upgrade the recipe result repository if you
+// want to extend this capability supporting more comparable types
+func (re *RuntimeValueStore) SetValue(uuid string, value map[string]starlark.Comparable) error {
+	if err := re.recipeResultRepository.Save(uuid, value); err != nil {
+		return stacktrace.Propagate(err, "An error occurred saving value '%+v' using UUID key '%s' into the recipe result repository", value, uuid)
+	}
+	return nil
 }
 
 func (re *RuntimeValueStore) GetValue(uuid string) (map[string]starlark.Comparable, error) {
-	value, found := re.recipeResultMap[uuid]
-	if !found {
-		return nil, stacktrace.NewError("Runtime UUID '%v' was not found", uuid)
+	value, err := re.recipeResultRepository.Get(uuid)
+	if err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred getting recipe result value with UUID key '%s'", uuid)
 	}
 	if value == nil {
 		return nil, stacktrace.NewError("Runtime UUID '%v' was found, but not set", uuid)
diff --git a/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository.go b/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository.go
new file mode 100644
index 000000000..f7e7e3686
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository.go
@@ -0,0 +1,106 @@
+package runtime_value_store
+
+import (
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
+	"github.com/kurtosis-tech/stacktrace"
+	"github.com/sirupsen/logrus"
+	bolt "go.etcd.io/bbolt"
+)
+
+var (
+	serviceAssociatedValuesBucketName = []byte("service-associated-values-repository")
+)
+
+type serviceAssociatedValuesRepository struct {
+	enclaveDb *enclave_db.EnclaveDB
+}
+
+func getOrCreateNewServiceAssociatedValuesRepository(enclaveDb *enclave_db.EnclaveDB) (*serviceAssociatedValuesRepository, error) {
+	if err := enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket, err := tx.CreateBucketIfNotExists(serviceAssociatedValuesBucketName)
+		if err != nil {
+			return stacktrace.Propagate(err, "An error occurred while creating the service associated values database bucket")
+		}
+		logrus.Debugf("Service associated values bucket: '%+v'", bucket)
+
+		return nil
+	}); err != nil {
+		return nil, stacktrace.Propagate(err, "An error occurred while building the service associated values repository")
+	}
+
+	serviceRuntimeValuesRepository := &serviceAssociatedValuesRepository{
+		enclaveDb: enclaveDb,
+	}
+
+	return serviceRuntimeValuesRepository, nil
+}
+
+func (repository *serviceAssociatedValuesRepository) Save(
+	serviceName service.ServiceName,
+	uuid string,
+) error {
+
+	if err := repository.enclaveDb.Update(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(serviceAssociatedValuesBucketName)
+
+		serviceNameKey := getServiceNameKey(serviceName)
+
+		// save it to disk
+		if err := bucket.Put(serviceNameKey, []byte(uuid)); err != nil {
+			return stacktrace.Propagate(err, "An error occurred while saving service associated value '%s' for service '%s' into the enclave db bucket", uuid, serviceName)
+		}
+		return nil
+	}); err != nil {
+		return stacktrace.Propagate(err, "An error occurred while adding service associated value '%s' for service '%s' into the enclave db", uuid, serviceName)
+	}
+	return nil
+}
+
+func (repository *serviceAssociatedValuesRepository) Get(
+	serviceName service.ServiceName,
+) (string, error) {
+	var uuid string
+
+	if err := repository.enclaveDb.View(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(serviceAssociatedValuesBucketName)
+
+		serviceNameKey := getServiceNameKey(serviceName)
+
+		// first get the bytes
+		uuidBytes := bucket.Get(serviceNameKey)
+
+		uuid = string(uuidBytes)
+
+		return nil
+	}); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred while getting service associated values for service '%s' from the enclave db", serviceName)
+	}
+	return uuid, nil
+}
+
+func (repository *serviceAssociatedValuesRepository) Exist(
+	serviceName service.ServiceName,
+) (bool, error) {
+
+	exist := false
+
+	if err := repository.enclaveDb.View(func(tx *bolt.Tx) error {
+		bucket := tx.Bucket(serviceAssociatedValuesBucketName)
+
+		serviceNameKey := getServiceNameKey(serviceName)
+		bytes := bucket.Get(serviceNameKey)
+		if bytes != nil {
+			exist = true
+		}
+		return nil
+	}); err != nil {
+		return false, stacktrace.Propagate(err, "An error occurred while checking if there are associated values for service '%s' exist in service associated values repository", serviceName)
+	}
+
+	return exist, nil
+}
+
+func getServiceNameKey(serviceName service.ServiceName) []byte {
+	return []byte(serviceName)
+}


Test patch:
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared_test.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared_test.go
index 17ba70246..db696d12b 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared_test.go
@@ -3,10 +3,13 @@ package add_service
 import (
 	"fmt"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
 	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
 	"go.starlark.net/starlark"
+	"os"
 	"testing"
 )
 
@@ -15,13 +18,17 @@ const (
 )
 
 func TestAddServiceShared_EntryPointArgsRuntimeValueAreReplaced(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
+
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err, "error creating a runtime value UUID")
 	runtimeValueName := "value"
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
 		runtimeValueName: starlark.MakeInt(8765),
 	})
+	require.NoError(t, err)
 	runtimeValue := fmt.Sprintf(magic_string_helper.RuntimeValueReplacementPlaceholderFormat, stringValueUuid, runtimeValueName)
 
 	serviceName := service.ServiceName("example-datastore-server-2")
@@ -48,13 +55,16 @@ func TestAddServiceShared_EntryPointArgsRuntimeValueAreReplaced(t *testing.T) {
 }
 
 func TestAddServiceShared_CmdArgsRuntimeValueAreReplaced(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err, "error creating a runtime value UUID")
 	runtimeValueName := "value"
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
 		runtimeValueName: starlark.MakeInt(999999),
 	})
+	require.NoError(t, err)
 	runtimeValue := fmt.Sprintf(magic_string_helper.RuntimeValueReplacementPlaceholderFormat, stringValueUuid, runtimeValueName)
 
 	serviceName := service.ServiceName("example-datastore-server-2")
@@ -81,13 +91,16 @@ func TestAddServiceShared_CmdArgsRuntimeValueAreReplaced(t *testing.T) {
 }
 
 func TestAddServiceShared_EnvVarsWithRuntimeValueAreReplaced(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err, "error creating a runtime value UUID")
 	runtimeValueName := "value"
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
 		runtimeValueName: starlark.MakeInt(8765),
 	})
+	require.NoError(t, err)
 	runtimeValue := fmt.Sprintf(magic_string_helper.RuntimeValueReplacementPlaceholderFormat, stringValueUuid, runtimeValueName)
 
 	serviceName := service.ServiceName("example-datastore-server-2")
@@ -119,13 +132,16 @@ func TestAddServiceShared_EnvVarsWithRuntimeValueAreReplaced(t *testing.T) {
 }
 
 func TestAddServiceShared_ServiceNameWithRuntimeValuesAreReplaced(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err, "error creating a runtime value UUID")
 	valueName := "value"
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{
 		"value": starlark.String("database-1"),
 	})
+	require.NoError(t, err)
 	stringRuntimeValue := fmt.Sprintf(magic_string_helper.RuntimeValueReplacementPlaceholderFormat, stringValueUuid, valueName)
 
 	serviceName := service.ServiceName(stringRuntimeValue)
@@ -149,3 +165,20 @@ func TestAddServiceShared_ServiceNameWithRuntimeValuesAreReplaced(t *testing.T)
 	require.Nil(t, err)
 	require.Equal(t, service.ServiceName("database-1"), replacedServiceName)
 }
+
+func getEnclaveDBForTest(t *testing.T) *enclave_db.EnclaveDB {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+
+	return enclaveDb
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper/magic_string_helper_test.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper/magic_string_helper_test.go
index 75f91a234..9f075c093 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper/magic_string_helper_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper/magic_string_helper_test.go
@@ -2,9 +2,12 @@ package magic_string_helper
 
 import (
 	"fmt"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
 	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
 	"go.starlark.net/starlark"
+	"os"
 	"testing"
 )
 
@@ -17,13 +20,17 @@ const (
 var testIntRuntimeValue = starlark.MakeInt(0)
 
 func TestGetOrReplaceRuntimeValueFromString_BasicFetch(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	require.NoError(t, err)
 	intValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	err = runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	require.NoError(t, err)
 	fetchedStringValue, err := GetOrReplaceRuntimeValueFromString(fmt.Sprintf(RuntimeValueReplacementPlaceholderFormat, stringValueUuid, testRuntimeValueField), runtimeValueStore)
 	require.Nil(t, err)
 	require.Equal(t, fetchedStringValue, testStringRuntimeValue)
@@ -33,13 +40,17 @@ func TestGetOrReplaceRuntimeValueFromString_BasicFetch(t *testing.T) {
 }
 
 func TestGetOrReplaceRuntimeValueFromString_Interpolated(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	require.NoError(t, err)
 	intValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	err = runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	require.NoError(t, err)
 	stringRuntimeValue := fmt.Sprintf(RuntimeValueReplacementPlaceholderFormat, stringValueUuid, testRuntimeValueField)
 	intRuntimeValue := fmt.Sprintf(RuntimeValueReplacementPlaceholderFormat, intValueUuid, testRuntimeValueField)
 	interpolatedString := fmt.Sprintf("%v is not %v", stringRuntimeValue, intRuntimeValue)
@@ -49,13 +60,17 @@ func TestGetOrReplaceRuntimeValueFromString_Interpolated(t *testing.T) {
 }
 
 func TestReplaceRuntimeValueFromString(t *testing.T) {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	stringValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	err = runtimeValueStore.SetValue(stringValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testStringRuntimeValue})
+	require.NoError(t, err)
 	intValueUuid, err := runtimeValueStore.CreateValue()
 	require.Nil(t, err)
-	runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	err = runtimeValueStore.SetValue(intValueUuid, map[string]starlark.Comparable{testRuntimeValueField: testIntRuntimeValue})
+	require.NoError(t, err)
 	stringRuntimeValue := fmt.Sprintf(RuntimeValueReplacementPlaceholderFormat, stringValueUuid, testRuntimeValueField)
 	intRuntimeValue := fmt.Sprintf(RuntimeValueReplacementPlaceholderFormat, intValueUuid, testRuntimeValueField)
 	interpolatedString := fmt.Sprintf("%v is not %v", stringRuntimeValue, intRuntimeValue)
@@ -63,3 +78,20 @@ func TestReplaceRuntimeValueFromString(t *testing.T) {
 	require.Nil(t, err)
 	require.Equal(t, resolvedInterpolatedString, testExpectedInterpolatedString.GoString())
 }
+
+func getEnclaveDBForTest(t *testing.T) *enclave_db.EnclaveDB {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+
+	return enclaveDb
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
index 497a4b9df..c6d38f411 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
@@ -5,6 +5,7 @@ import (
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/container_status"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/port_spec"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
@@ -14,7 +15,9 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
 	"go.starlark.net/starlark"
+	"os"
 	"testing"
 )
 
@@ -34,7 +37,9 @@ func (t *addServiceTestCase) GetId() string {
 
 func (t *addServiceTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().ExistServiceRegistration(TestServiceName).Times(1).Return(false, nil)
 	serviceNetwork.EXPECT().AddService(
@@ -88,3 +93,20 @@ func (t *addServiceTestCase) Assert(interpretationResult starlark.Value, executi
 	expectedExecutionResult := fmt.Sprintf("Service '%s' added with service UUID '%s'", TestServiceName, TestServiceUuid)
 	require.Equal(t, expectedExecutionResult, *executionResult)
 }
+
+func getEnclaveDBForTest(t *testing.T) *enclave_db.EnclaveDB {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+
+	return enclaveDb
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
index 1eaef41d6..ab98a87da 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
@@ -37,7 +37,9 @@ func (t *addServicesTestCase) GetId() string {
 
 func (t *addServicesTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().ExistServiceRegistration(TestServiceName).Times(1).Return(false, nil)
 	serviceNetwork.EXPECT().ExistServiceRegistration(TestServiceName2).Times(1).Return(false, nil)
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/assert_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/assert_framework_test.go
index 76edd14c8..819550a2e 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/assert_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/assert_framework_test.go
@@ -35,10 +35,13 @@ func (t assertTestCase) GetId() string {
 }
 
 func (t assertTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
-	runtimeValueStore.SetValue(t.runtimeValueUuid, map[string]starlark.Comparable{
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
+	err = runtimeValueStore.SetValue(t.runtimeValueUuid, map[string]starlark.Comparable{
 		"value": starlark.String(runtimeValueValue),
 	})
+	require.NoError(t, err)
 	return assert.NewAssert(runtimeValueStore)
 }
 
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
index 867da81f3..0a70df0cb 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
@@ -34,7 +34,9 @@ func (t execTestCase1) GetId() string {
 
 func (t execTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().RunExec(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
index 26cfac6d0..fd04bb2df 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
@@ -30,7 +30,9 @@ func (t execTestCase2) GetId() string {
 
 func (t execTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().RunExec(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_recipe_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_recipe_framework_test.go
index 9b1cdb215..195a2035f 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_recipe_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_recipe_framework_test.go
@@ -21,7 +21,9 @@ type execRecipeTestCase struct {
 }
 
 func newExecRecipeTestCase(t *testing.T) *execRecipeTestCase {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
 	serviceNetwork.EXPECT().RunExec(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_no_extractor_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_no_extractor_test.go
index 454fbf8c9..ff8948545 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_no_extractor_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_no_extractor_test.go
@@ -22,7 +22,9 @@ type getHttpRequestRecipeNoExtractorTestCase struct {
 }
 
 func newGetHttpRequestRecipeNoExtractorTestCase(t *testing.T) *getHttpRequestRecipeNoExtractorTestCase {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
 	serviceNetwork.EXPECT().HttpRequestService(
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_test.go
index b1ebef246..cba9784a0 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/get_http_request_recipe_test.go
@@ -26,7 +26,9 @@ type getHttpRequestRecipeTestCase struct {
 }
 
 func newGetHttpRequestRecipeTestCase(t *testing.T) *getHttpRequestRecipeTestCase {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
 	serviceNetwork.EXPECT().HttpRequestService(
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/kurtosis_print_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/kurtosis_print_framework_test.go
index a285418ec..49107afcd 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/kurtosis_print_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/kurtosis_print_framework_test.go
@@ -31,7 +31,9 @@ func (t *printTestCase) GetId() string {
 
 func (t *printTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	return kurtosis_print.NewPrint(serviceNetwork, runtimeValueStore)
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_minimal_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_minimal_test.go
index d42821f27..e856d3558 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_minimal_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_minimal_test.go
@@ -22,7 +22,9 @@ type postHttpRequestRecipeMinimalTestCase struct {
 }
 
 func newPostHttpRequestRecipeMinimalTestCase(t *testing.T) *postHttpRequestRecipeMinimalTestCase {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
 	serviceNetwork.EXPECT().HttpRequestService(
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_test.go
index 109fe82f5..47d5c6fa1 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/post_http_request_recipe_test.go
@@ -26,7 +26,9 @@ type postHttpRequestRecipeTestCase struct {
 }
 
 func newPostHttpRequestRecipeTestCase(t *testing.T) *postHttpRequestRecipeTestCase {
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
 	serviceNetwork.EXPECT().HttpRequestService(
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_multiple_templates_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_multiple_templates_framework_test.go
index 929100ed0..e0e8665e3 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_multiple_templates_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_multiple_templates_framework_test.go
@@ -61,7 +61,11 @@ func (t renderMultipleTemplatesTestCase) GetId() string {
 }
 
 func (t renderMultipleTemplatesTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	return render_templates.NewRenderTemplatesInstruction(t.serviceNetwork, runtime_value_store.NewRuntimeValueStore())
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
+
+	return render_templates.NewRenderTemplatesInstruction(t.serviceNetwork, runtimeValueStore)
 }
 
 func (t renderMultipleTemplatesTestCase) GetStarlarkCode() string {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_single_templates_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_single_templates_framework_test.go
index c308378db..e3f5ebcb5 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_single_templates_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/render_single_templates_framework_test.go
@@ -46,7 +46,10 @@ func (t renderSingleTemplateTestCase) GetId() string {
 }
 
 func (t renderSingleTemplateTestCase) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	return render_templates.NewRenderTemplatesInstruction(t.serviceNetwork, runtime_value_store.NewRuntimeValueStore())
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
+	return render_templates.NewRenderTemplatesInstruction(t.serviceNetwork, runtimeValueStore)
 }
 
 func (t renderSingleTemplateTestCase) GetStarlarkCode() string {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
index 18b507fee..f8344e78d 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
@@ -43,7 +43,9 @@ func (t *requestTestCase1) GetId() string {
 
 func (t *requestTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
index f609383e6..a66ddf713 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
@@ -32,7 +32,9 @@ func (t *requestTestCase2) GetId() string {
 
 func (t *requestTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
index 16dc8a266..1e288fb98 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
@@ -49,7 +49,9 @@ func (t *waitTestCase1) GetId() string {
 
 func (t *waitTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
index 6bad6ce25..40aa8b7d0 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
@@ -33,7 +33,9 @@ func (t *waitTestCase2) GetId() string {
 
 func (t *waitTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
 	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(t.T)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
diff --git a/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository_test.go b/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository_test.go
new file mode 100644
index 000000000..b6942add3
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/runtime_value_store/recipe_result_repository_test.go
@@ -0,0 +1,146 @@
+package runtime_value_store
+
+import (
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_type_constructor"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/directory"
+	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
+	"go.starlark.net/starlark"
+	"os"
+	"testing"
+)
+
+const (
+	randomUuid = "abcd12a3948149d9afa2ef93abb4ec52"
+
+	notAcceptedComparableTypeErrorMsg   = "Unexpected comparable type"
+	keyDoesNotExistOnRepositoryErrorMsg = "does not exist on the recipe result repository"
+
+	firstKey            = "mykey"
+	secondKey           = "mySecondKey"
+	thirdKey            = "myThirdKey"
+	starlarkStringValue = starlark.String("my-value")
+)
+
+var (
+	starlarkIntValue = starlark.MakeInt(30)
+)
+
+func TestRecipeResultSaveKey_Success(t *testing.T) {
+	repository := getRecipeResultRepositoryForTest(t)
+
+	err := repository.SaveKey(randomUuid)
+	require.NoError(t, err)
+
+	value, err := repository.Get(randomUuid)
+	require.NoError(t, err)
+	require.Empty(t, value)
+}
+
+func TestRecipeResultSaveAndGet_Success(t *testing.T) {
+	repository := getRecipeResultRepositoryForTest(t)
+
+	resultValue := map[string]starlark.Comparable{
+		firstKey:  starlarkStringValue,
+		secondKey: starlarkIntValue,
+	}
+
+	err := repository.Save(randomUuid, resultValue)
+	require.NoError(t, err)
+
+	value, err := repository.Get(randomUuid)
+	require.NoError(t, err)
+	require.NotNil(t, value)
+
+	require.Equal(t, resultValue, value)
+}
+
+func TestRecipeResultGet_DoesNotExist(t *testing.T) {
+	repository := getRecipeResultRepositoryForTest(t)
+
+	value, err := repository.Get(randomUuid)
+	require.Error(t, err)
+	require.ErrorContains(t, err, keyDoesNotExistOnRepositoryErrorMsg)
+	require.Empty(t, value)
+}
+
+func TestRecipeResultSave_ErrorWhenUsingNotStarlarkStringOrInt(t *testing.T) {
+	repository := getRecipeResultRepositoryForTest(t)
+
+	resultValue := map[string]starlark.Comparable{
+		firstKey: starlark.Bool(true),
+	}
+
+	err := repository.Save(randomUuid, resultValue)
+	require.Error(t, err)
+	require.ErrorContains(t, err, notAcceptedComparableTypeErrorMsg)
+
+	resultValue2 := map[string]starlark.Comparable{
+		secondKey: directory.Directory{}, // nolint: exhaustruct
+	}
+
+	err = repository.Save(randomUuid, resultValue2)
+	require.Error(t, err)
+	require.ErrorContains(t, err, notAcceptedComparableTypeErrorMsg)
+
+	resultValue3 := map[string]starlark.Comparable{
+		thirdKey: &kurtosis_type_constructor.KurtosisValueTypeDefault{}, // nolint: exhaustruct
+	}
+
+	err = repository.Save(randomUuid, resultValue3)
+	require.Error(t, err)
+	require.ErrorContains(t, err, notAcceptedComparableTypeErrorMsg)
+
+	resultValue4 := map[string]starlark.Comparable{
+		thirdKey: &starlark.Dict{},
+	}
+
+	err = repository.Save(randomUuid, resultValue4)
+	require.Error(t, err)
+	require.ErrorContains(t, err, notAcceptedComparableTypeErrorMsg)
+}
+
+func TestDelete_Success(t *testing.T) {
+	repository := getRecipeResultRepositoryForTest(t)
+
+	resultValue := map[string]starlark.Comparable{
+		firstKey:  starlarkStringValue,
+		secondKey: starlarkIntValue,
+	}
+
+	err := repository.Save(randomUuid, resultValue)
+	require.NoError(t, err)
+
+	value, err := repository.Get(randomUuid)
+	require.NoError(t, err)
+	require.NotNil(t, value)
+
+	require.Equal(t, resultValue, value)
+
+	err = repository.Delete(randomUuid)
+	require.NoError(t, err)
+
+	value, err = repository.Get(randomUuid)
+	require.Error(t, err)
+	require.Empty(t, value)
+}
+
+func getRecipeResultRepositoryForTest(t *testing.T) *recipeResultRepository {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+	repository, err := getOrCreateNewRecipeResultRepository(enclaveDb)
+	require.NoError(t, err)
+
+	return repository
+}
diff --git a/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository_test.go b/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository_test.go
new file mode 100644
index 000000000..7bd2344d7
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/runtime_value_store/service_associated_values_repository_test.go
@@ -0,0 +1,83 @@
+package runtime_value_store
+
+import (
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
+	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
+	"os"
+	"testing"
+)
+
+const (
+	firstServiceName               = service.ServiceName("first-service-name")
+	secondServiceName              = service.ServiceName("second-service-name")
+	serviceWithoutAssociatedValues = service.ServiceName("no-values-service-name")
+
+	firstServiceAssociatedValueUuid  = "cddc2ea3948149d9afa2ef93abb4ec52"
+	secondServiceAssociatedValueUuid = "ae5c8bf2fbeb4de68f647280b1c79cbb"
+)
+
+func TestSaveAndGet_Success(t *testing.T) {
+	repository := getAssociatedValuesRepositoryForTest(t)
+
+	err := repository.Save(firstServiceName, firstServiceAssociatedValueUuid)
+	require.NoError(t, err)
+
+	err = repository.Save(secondServiceName, secondServiceAssociatedValueUuid)
+	require.NoError(t, err)
+
+	firstServiceAssociatedValues, err := repository.Get(firstServiceName)
+	require.NoError(t, err)
+	require.Equal(t, firstServiceAssociatedValueUuid, firstServiceAssociatedValues)
+
+	secondServiceAssociatedValues, err := repository.Get(secondServiceName)
+	require.NoError(t, err)
+	require.Equal(t, secondServiceAssociatedValueUuid, secondServiceAssociatedValues)
+}
+
+func TestGet_NotAssociateValues(t *testing.T) {
+	repository := getAssociatedValuesRepositoryForTest(t)
+
+	serviceAssociatedValues, err := repository.Get(serviceWithoutAssociatedValues)
+	require.NoError(t, err)
+	require.Empty(t, serviceAssociatedValues)
+}
+
+func TestExist_Success(t *testing.T) {
+	repository := getAssociatedValuesRepositoryForTest(t)
+
+	err := repository.Save(firstServiceName, firstServiceAssociatedValueUuid)
+	require.NoError(t, err)
+
+	exist, err := repository.Exist(firstServiceName)
+	require.NoError(t, err)
+	require.True(t, exist)
+}
+
+func TestNotExist_Success(t *testing.T) {
+	repository := getAssociatedValuesRepositoryForTest(t)
+
+	exist, err := repository.Exist(serviceWithoutAssociatedValues)
+	require.NoError(t, err)
+	require.False(t, exist)
+}
+
+func getAssociatedValuesRepositoryForTest(t *testing.T) *serviceAssociatedValuesRepository {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+	repository, err := getOrCreateNewServiceAssociatedValuesRepository(enclaveDb)
+	require.NoError(t, err)
+
+	return repository
+}
diff --git a/core/server/api_container/server/startosis_engine/startosis_executor_test.go b/core/server/api_container/server/startosis_engine/startosis_executor_test.go
index 19f916166..dbb88a129 100644
--- a/core/server/api_container/server/startosis_engine/startosis_executor_test.go
+++ b/core/server/api_container/server/startosis_engine/startosis_executor_test.go
@@ -5,13 +5,16 @@ import (
 	"errors"
 	"github.com/kurtosis-tech/kurtosis/api/golang/core/kurtosis_core_rpc_api_bindings"
 	"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/binding_constructors"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/instructions_plan"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/mock_instruction"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
+	bolt "go.etcd.io/bbolt"
 	"go.starlark.net/starlark"
+	"os"
 	"strings"
 	"testing"
 )
@@ -34,8 +37,11 @@ var (
 )
 
 func TestExecuteKurtosisInstructions_ExecuteForReal_Success(t *testing.T) {
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, createRuntimeValueStoreErr := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, createRuntimeValueStoreErr)
 
-	executor := NewStartosisExecutor(runtime_value_store.NewRuntimeValueStore())
+	executor := NewStartosisExecutor(runtimeValueStore)
 
 	instructionsPlan := instructions_plan.NewInstructionsPlan()
 	instruction0 := createMockInstruction(t, "instruction0", executeSuccessfully)
@@ -78,7 +84,11 @@ func TestExecuteKurtosisInstructions_ExecuteForReal_Success(t *testing.T) {
 }
 
 func TestExecuteKurtosisInstructions_ExecuteForReal_FailureHalfWay(t *testing.T) {
-	executor := NewStartosisExecutor(runtime_value_store.NewRuntimeValueStore())
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, err)
+
+	executor := NewStartosisExecutor(runtimeValueStore)
 
 	instruction1 := createMockInstruction(t, "instruction1", executeSuccessfully)
 	instruction2 := createMockInstruction(t, "instruction2", throwOnExecute)
@@ -116,7 +126,11 @@ instruction2()
 }
 
 func TestExecuteKurtosisInstructions_DoDryRun(t *testing.T) {
-	executor := NewStartosisExecutor(runtime_value_store.NewRuntimeValueStore())
+	enclaveDb := getEnclaveDBForTest(t)
+	runtimeValueStore, createRuntimeValueStoreErr := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(t, createRuntimeValueStoreErr)
+
+	executor := NewStartosisExecutor(runtimeValueStore)
 
 	instruction1 := createMockInstruction(t, "instruction1", executeSuccessfully)
 	instruction2 := createMockInstruction(t, "instruction2", executeSuccessfully)
@@ -185,3 +199,20 @@ func executeSynchronously(t *testing.T, executor *StartosisExecutor, dryRun bool
 	}
 	return scriptOutput.String(), serializedInstructions, nil
 }
+
+func getEnclaveDBForTest(t *testing.T) *enclave_db.EnclaveDB {
+	file, err := os.CreateTemp("/tmp", "*.db")
+	defer func() {
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+
+	require.NoError(t, err)
+	db, err := bolt.Open(file.Name(), 0666, nil)
+	require.NoError(t, err)
+	enclaveDb := &enclave_db.EnclaveDB{
+		DB: db,
+	}
+
+	return enclaveDb
+}
diff --git a/core/server/api_container/server/startosis_engine/startosis_interpreter_idempotent_test.go b/core/server/api_container/server/startosis_engine/startosis_interpreter_idempotent_test.go
index f79d8efbd..9cc41ac87 100644
--- a/core/server/api_container/server/startosis_engine/startosis_interpreter_idempotent_test.go
+++ b/core/server/api_container/server/startosis_engine/startosis_interpreter_idempotent_test.go
@@ -26,7 +26,10 @@ type StartosisInterpreterIdempotentTestSuite struct {
 
 func (suite *StartosisInterpreterIdempotentTestSuite) SetupTest() {
 	suite.packageContentProvider = mock_package_content_provider.NewMockPackageContentProvider()
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(suite.T())
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(suite.T(), err)
+
 	serviceNetwork := service_network.NewMockServiceNetwork(suite.T())
 	serviceNetwork.EXPECT().GetApiContainerInfo().Maybe().Return(
 		service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), uint16(1234), "0.0.0"),
diff --git a/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go b/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
index b321387fb..4086fd449 100644
--- a/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
+++ b/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
@@ -59,7 +59,10 @@ type StartosisInterpreterTestSuite struct {
 
 func (suite *StartosisInterpreterTestSuite) SetupTest() {
 	suite.packageContentProvider = mock_package_content_provider.NewMockPackageContentProvider()
-	suite.runtimeValueStore = runtime_value_store.NewRuntimeValueStore()
+	enclaveDb := getEnclaveDBForTest(suite.T())
+	runtimeValueStore, err := runtime_value_store.CreateRuntimeValueStore(enclaveDb)
+	require.NoError(suite.T(), err)
+	suite.runtimeValueStore = runtimeValueStore
 	suite.serviceNetwork = service_network.NewMockServiceNetwork(suite.T())
 
 	suite.interpreter = NewStartosisInterpreter(suite.serviceNetwork, suite.packageContentProvider, suite.runtimeValueStore, "")