Skip to content

Commit

Permalink
Merge branch 'main' into feat/specify-dockerfile-name-in-image-build-…
Browse files Browse the repository at this point in the history
…spec
  • Loading branch information
leovct authored Feb 28, 2024
2 parents c239c38 + 7020183 commit d26ca12
Show file tree
Hide file tree
Showing 16 changed files with 481 additions and 54 deletions.
8 changes: 7 additions & 1 deletion core/server/api_container/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package main
import (
"context"
"fmt"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/interpretation_time_value_store"
"net"
"os"
"path"
Expand Down Expand Up @@ -203,6 +204,11 @@ func runMain() error {
return stacktrace.Propagate(err, "An error occurred creating the runtime value store")
}

interpretationTimeValueStore, err := interpretation_time_value_store.CreateInterpretationTimeValueStore(enclaveDb, starlarkValueSerde)
if err != nil {
return stacktrace.Propagate(err, "an error occurred while creating the interpretation time value store")
}

// Load the current enclave plan, in case the enclave is being restarted
enclavePlan, err := enclave_plan_persistence.Load(enclaveDb)
if err != nil {
Expand All @@ -211,7 +217,7 @@ func runMain() error {

// TODO: Consolidate Interpreter, Validator and Executor into a single interface
startosisRunner := startosis_engine.NewStartosisRunner(
startosis_engine.NewStartosisInterpreter(serviceNetwork, gitPackageContentProvider, runtimeValueStore, starlarkValueSerde, serverArgs.EnclaveEnvVars),
startosis_engine.NewStartosisInterpreter(serviceNetwork, gitPackageContentProvider, runtimeValueStore, starlarkValueSerde, serverArgs.EnclaveEnvVars, interpretationTimeValueStore),
startosis_engine.NewStartosisValidator(&kurtosisBackend, serviceNetwork, filesArtifactStore),
startosis_engine.NewStartosisExecutor(starlarkValueSerde, runtimeValueStore, enclavePlan, enclaveDb))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package interpretation_time_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/core/server/api_container/server/startosis_engine/kurtosis_types"
"github.com/kurtosis-tech/stacktrace"
)

type InterpretationTimeValueStore struct {
serviceValues *serviceInterpretationValueRepository
serde *kurtosis_types.StarlarkValueSerde
}

func CreateInterpretationTimeValueStore(enclaveDb *enclave_db.EnclaveDB, serde *kurtosis_types.StarlarkValueSerde) (*InterpretationTimeValueStore, error) {
serviceValuesRepository, err := getOrCreateNewServiceInterpretationTimeValueRepository(enclaveDb, serde)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred creating interpretation time value store")
}
return &InterpretationTimeValueStore{serviceValues: serviceValuesRepository, serde: serde}, nil
}

func (itvs *InterpretationTimeValueStore) PutService(name service.ServiceName, service *kurtosis_types.Service) error {
if err := itvs.serviceValues.PutService(name, service); err != nil {
return stacktrace.Propagate(err, "An error occurred while adding value '%v' for service '%v' to db", service, name)
}
return nil
}

func (itvs *InterpretationTimeValueStore) GetService(name service.ServiceName) (*kurtosis_types.Service, error) {
serviceStarlark, err := itvs.serviceValues.GetService(name)
if err != nil {
return nil, stacktrace.Propagate(err, "An error occurred fetching interpretation time value for '%v' from db", name)
}
return serviceStarlark, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package interpretation_time_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/core/server/api_container/server/startosis_engine/kurtosis_types"
"github.com/kurtosis-tech/stacktrace"
"github.com/sirupsen/logrus"
bolt "go.etcd.io/bbolt"
)

var (
serviceInterpretationValueBucketName = []byte("service-interpretation-value")
emptyValue = []byte{}
)

type serviceInterpretationValueRepository struct {
enclaveDb *enclave_db.EnclaveDB
starlarkValueSerde *kurtosis_types.StarlarkValueSerde
}

func getOrCreateNewServiceInterpretationTimeValueRepository(
enclaveDb *enclave_db.EnclaveDB,
starlarkValueSerde *kurtosis_types.StarlarkValueSerde,
) (*serviceInterpretationValueRepository, error) {
if err := enclaveDb.Update(func(tx *bolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists(serviceInterpretationValueBucketName)
if err != nil {
return stacktrace.Propagate(err, "An error occurred while creating the bucket for the service interpretation time value repository")
}
logrus.Debugf("Service value interpretation time store bucket: '%+v'", bucket)

return nil
}); err != nil {
return nil, stacktrace.Propagate(err, "An error occurred while building service interpretation time value repository")
}

repository := &serviceInterpretationValueRepository{
enclaveDb: enclaveDb,
starlarkValueSerde: starlarkValueSerde,
}

return repository, nil
}

func (repository *serviceInterpretationValueRepository) PutService(name service.ServiceName, service *kurtosis_types.Service) error {
logrus.Debugf("Saving service interpretation value '%v' for service with name '%v' to", service, name)
if err := repository.enclaveDb.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket(serviceInterpretationValueBucketName)

serviceNameKey := getKey(name)
serializedValue := repository.starlarkValueSerde.Serialize(service)

// save it to disk
if err := bucket.Put(serviceNameKey, []byte(serializedValue)); err != nil {
return stacktrace.Propagate(err, "An error occurred while saving service interpretation time value '%v' for service '%v'", serializedValue, serviceNameKey)
}
return nil
}); err != nil {
return stacktrace.Propagate(err, "An error occurred while saving service interpretation time value '%v' for service '%v'", service, name)
}
logrus.Debugf("Succesfully saved service '%v'", name)
return nil
}

func (repository *serviceInterpretationValueRepository) GetService(name service.ServiceName) (*kurtosis_types.Service, error) {
logrus.Debugf("Getting service interpretation time value for service '%v'", name)
var value *kurtosis_types.Service

if err := repository.enclaveDb.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket(serviceInterpretationValueBucketName)

serviceNameKey := getKey(name)

serviceSerializedValue := bucket.Get(serviceNameKey)

// check for existence
if serviceSerializedValue == nil {
return stacktrace.NewError("Service '%v' doesn't exist in the repository", name)
}

isEmptyValue := len(serviceSerializedValue) == len(emptyValue)

serviceSerializedValueStr := string(serviceSerializedValue)

// if an empty value was found we return an error
if isEmptyValue {
return stacktrace.NewError("An empty value was found for service '%v'; this is a bug in Kurtosis", name)
}

deserializedValue, interpretationErr := repository.starlarkValueSerde.Deserialize(serviceSerializedValueStr)
if interpretationErr != nil {
return stacktrace.Propagate(interpretationErr, "an error occurred while deserializing object associated with service '%v' in repository", name)
}

var ok bool
value, ok = deserializedValue.(*kurtosis_types.Service)
if !ok {
return stacktrace.NewError("An error occurred converting the deserialized value '%v' into required internal type", deserializedValue)
}

return nil
}); err != nil {
return nil, stacktrace.Propagate(err, "An error occurred while getting service '%v' from db", name)
}
logrus.Debugf("Successfully got value for '%v'", name)
return value, nil

}

func getKey(name service.ServiceName) []byte {
return []byte(name)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package interpretation_time_value_store

import (
port_spec_core "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/startosis_engine/kurtosis_types"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/port_spec"
"github.com/stretchr/testify/require"
bolt "go.etcd.io/bbolt"
"go.starlark.net/starlark"
"go.starlark.net/starlarkstruct"
"os"
"testing"
)

const (
starlarkThreadName = "thread-for-db-test"
serviceName = service.ServiceName("datastore-1")
serviceNameStarlarkStr = starlark.String(serviceName)
hostName = serviceNameStarlarkStr
ipAddress = starlark.String("172.23.34.44")
)

func TestPutGet_Succeed(t *testing.T) {
repository := getServiceInterpretationTimeValueRepository(t)
require.NotNil(t, repository)

applicationProtocol := ""
maybeUrl := ""

port, interpretationErr := port_spec.CreatePortSpecUsingGoValues(
string(serviceName),
uint16(443),
port_spec_core.TransportProtocol_TCP,
&applicationProtocol,
"10s",
&maybeUrl,
)
require.Nil(t, interpretationErr)
ports := starlark.NewDict(1)
require.NoError(t, ports.SetKey(starlark.String("http"), port))

expectedService, interpretationErr := kurtosis_types.CreateService(serviceNameStarlarkStr, hostName, ipAddress, ports)
require.Nil(t, interpretationErr)

err := repository.PutService(serviceName, expectedService)
require.Nil(t, err)

actualService, err := repository.GetService(serviceName)
require.Nil(t, err)
require.Equal(t, expectedService.AttrNames(), actualService.AttrNames())
require.Equal(t, expectedService.String(), actualService.String())
}

func TestPutGetFail_ForMissingServiceName(t *testing.T) {
repository := getServiceInterpretationTimeValueRepository(t)
require.NotNil(t, repository)

actualService, err := repository.GetService(serviceName)
require.Error(t, err)
require.Nil(t, actualService)
}

func getServiceInterpretationTimeValueRepository(t *testing.T) *serviceInterpretationValueRepository {
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,
}

dummySerde := newDummyStarlarkValueSerDeForTest()

repository, err := getOrCreateNewServiceInterpretationTimeValueRepository(enclaveDb, dummySerde)
require.NoError(t, err)

return repository
}

func newDummyStarlarkValueSerDeForTest() *kurtosis_types.StarlarkValueSerde {
thread := &starlark.Thread{
Name: starlarkThreadName,
Print: nil,
Load: nil,
OnMaxSteps: nil,
Steps: 0,
}
starlarkEnv := starlark.StringDict{
starlarkstruct.Default.GoString(): starlark.NewBuiltin(starlarkstruct.Default.GoString(), starlarkstruct.Make),

kurtosis_types.ServiceTypeName: starlark.NewBuiltin(kurtosis_types.ServiceTypeName, kurtosis_types.NewServiceType().CreateBuiltin()),
port_spec.PortSpecTypeName: starlark.NewBuiltin(port_spec.PortSpecTypeName, port_spec.NewPortSpecType().CreateBuiltin()),
}
return kurtosis_types.NewStarlarkValueSerde(thread, starlarkEnv)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/builtins/import_module"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/builtins/print_builtin"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/builtins/read_file"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/interpretation_time_value_store"
"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_instruction/exec"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/get_service"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/kurtosis_print"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/remove_service"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/render_templates"
Expand Down Expand Up @@ -60,10 +62,12 @@ func KurtosisPlanInstructions(
packageContentProvider startosis_packages.PackageContentProvider,
packageReplaceOptions map[string]string,
nonBlockingMode bool,
interpretationTimeValueStore *interpretation_time_value_store.InterpretationTimeValueStore,
) []*kurtosis_plan_instruction.KurtosisPlanInstruction {
return []*kurtosis_plan_instruction.KurtosisPlanInstruction{
add_service.NewAddService(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions),
add_service.NewAddServices(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions),
add_service.NewAddService(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions, interpretationTimeValueStore),
add_service.NewAddServices(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions, interpretationTimeValueStore),
get_service.NewGetService(interpretationTimeValueStore),
verify.NewVerify(runtimeValueStore),
exec.NewExec(serviceNetwork, runtimeValueStore),
kurtosis_print.NewPrint(serviceNetwork, runtimeValueStore),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/enclave_plan_persistence"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/enclave_structure"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/interpretation_time_value_store"
"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/kurtosis_starlark_framework/builtin_argument"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
Expand All @@ -32,7 +33,8 @@ func NewAddService(
runtimeValueStore *runtime_value_store.RuntimeValueStore,
packageId string,
packageContentProvider startosis_packages.PackageContentProvider,
packageReplaceOptions map[string]string) *kurtosis_plan_instruction.KurtosisPlanInstruction {
packageReplaceOptions map[string]string,
interpretationTimeValueStore *interpretation_time_value_store.InterpretationTimeValueStore) *kurtosis_plan_instruction.KurtosisPlanInstruction {
return &kurtosis_plan_instruction.KurtosisPlanInstruction{
KurtosisBaseBuiltin: &kurtosis_starlark_framework.KurtosisBaseBuiltin{
Name: AddServiceBuiltinName,
Expand Down Expand Up @@ -74,6 +76,8 @@ func NewAddService(

resultUuid: "", // populated at interpretation time
readyCondition: nil, // populated at interpretation time

interpretationTimeValueStore: interpretationTimeValueStore,
}
},

Expand All @@ -97,6 +101,8 @@ type AddServiceCapabilities struct {
packageContentProvider startosis_packages.PackageContentProvider
packageReplaceOptions map[string]string

interpretationTimeValueStore *interpretation_time_value_store.InterpretationTimeValueStore

resultUuid string
}

Expand Down Expand Up @@ -134,6 +140,11 @@ func (builtin *AddServiceCapabilities) Interpret(locatorOfModuleInWhichThisBuilt
if interpretationErr != nil {
return nil, interpretationErr
}

err = builtin.interpretationTimeValueStore.PutService(builtin.serviceName, returnValue)
if err != nil {
return nil, startosis_errors.WrapWithInterpretationError(err, "An error occurred while persisting return value for service '%v'", serviceName)
}
return returnValue, nil
}

Expand Down
Loading

0 comments on commit d26ca12

Please sign in to comment.