Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: set service v0 #2372

Merged
merged 27 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ type privateServiceConfig struct {

// Configuration for container engine to pull an in a private registry behind authentication
// If nil, we will use the ContainerImageName and not use any auth
// Mutually exclusive from ImageBuildSpec, ContainerImageName
ImagerRegistrySpec *image_registry_spec.ImageRegistrySpec
// Mutually exclusive from ImageBuildSpec, ContainerImageName, NixBuildSpec
ImageRegistrySpec *image_registry_spec.ImageRegistrySpec

// Configuration for container engine to using Nix
// If nil, we will use the ContainerImageName and not use any Nix
// Mutually exclusive from ImageBuildSpec, ContainerImageName, ImageRegistrySpec
NixBuildSpec *nix_build_spec.NixBuildSpec

PrivatePorts map[string]*port_spec.PortSpec
Expand Down Expand Up @@ -88,7 +91,7 @@ func CreateServiceConfig(
cpuAllocationMillicpus uint64,
memoryAllocationMegabytes uint64,
privateIPAddrPlaceholder string,
minCpuMilliCores uint64,
minCpuMilliCpus uint64,
minMemoryMegaBytes uint64,
labels map[string]string,
user *service_user.ServiceUser,
Expand All @@ -104,7 +107,7 @@ func CreateServiceConfig(
internalServiceConfig := &privateServiceConfig{
ContainerImageName: containerImageName,
ImageBuildSpec: imageBuildSpec,
ImagerRegistrySpec: imageRegistrySpec,
ImageRegistrySpec: imageRegistrySpec,
NixBuildSpec: nixBuildSpec,
PrivatePorts: privatePorts,
PublicPorts: publicPorts,
Expand All @@ -117,7 +120,7 @@ func CreateServiceConfig(
MemoryAllocationMegabytes: memoryAllocationMegabytes,
PrivateIPAddrPlaceholder: privateIPAddrPlaceholder,
// The minimum resources specification is only available for kubernetes
MinCpuAllocationMilliCpus: minCpuMilliCores,
MinCpuAllocationMilliCpus: minCpuMilliCpus,
MinMemoryAllocationMegabytes: minMemoryMegaBytes,
Labels: labels,
User: user,
Expand All @@ -133,18 +136,34 @@ func (serviceConfig *ServiceConfig) GetContainerImageName() string {
return serviceConfig.privateServiceConfig.ContainerImageName
}

func (serviceConfig *ServiceConfig) SetContainerImageName(containerImage string) {
serviceConfig.privateServiceConfig.ContainerImageName = containerImage
}

func (serviceConfig *ServiceConfig) GetImageBuildSpec() *image_build_spec.ImageBuildSpec {
return serviceConfig.privateServiceConfig.ImageBuildSpec
}

func (serviceConfig *ServiceConfig) SetImageBuildSpec(imageBuildSpec *image_build_spec.ImageBuildSpec) {
serviceConfig.privateServiceConfig.ImageBuildSpec = imageBuildSpec
}

func (serviceConfig *ServiceConfig) GetImageRegistrySpec() *image_registry_spec.ImageRegistrySpec {
return serviceConfig.privateServiceConfig.ImagerRegistrySpec
return serviceConfig.privateServiceConfig.ImageRegistrySpec
}

func (serviceConfig *ServiceConfig) SetImageRegistrySpec(imageRegistrySpec *image_registry_spec.ImageRegistrySpec) {
serviceConfig.privateServiceConfig.ImageRegistrySpec = imageRegistrySpec
}

func (serviceConfig *ServiceConfig) GetNixBuildSpec() *nix_build_spec.NixBuildSpec {
return serviceConfig.privateServiceConfig.NixBuildSpec
}

func (serviceConfig *ServiceConfig) SetNixBuildSpec(nixBuildSpec *nix_build_spec.NixBuildSpec) {
serviceConfig.privateServiceConfig.NixBuildSpec = nixBuildSpec
}

func (serviceConfig *ServiceConfig) GetPrivatePorts() map[string]*port_spec.PortSpec {
return serviceConfig.privateServiceConfig.PrivatePorts
}
Expand Down Expand Up @@ -177,10 +196,18 @@ func (serviceConfig *ServiceConfig) GetCPUAllocationMillicpus() uint64 {
return serviceConfig.privateServiceConfig.CpuAllocationMillicpus
}

func (serviceConfig *ServiceConfig) SetCPUAllocationMillicpus(cpuAllocation uint64) {
serviceConfig.privateServiceConfig.CpuAllocationMillicpus = cpuAllocation
}

func (serviceConfig *ServiceConfig) GetMemoryAllocationMegabytes() uint64 {
return serviceConfig.privateServiceConfig.MemoryAllocationMegabytes
}

func (serviceConfig *ServiceConfig) SetMemoryAllocationMegabytes(memoryAllocation uint64) {
serviceConfig.privateServiceConfig.MemoryAllocationMegabytes = memoryAllocation
}

func (serviceConfig *ServiceConfig) GetPrivateIPAddrPlaceholder() string {
return serviceConfig.privateServiceConfig.PrivateIPAddrPlaceholder
}
Expand All @@ -190,27 +217,51 @@ func (serviceConfig *ServiceConfig) GetMinCPUAllocationMillicpus() uint64 {
return serviceConfig.privateServiceConfig.MinCpuAllocationMilliCpus
}

func (serviceConfig *ServiceConfig) SetMinCPUAllocationMillicpus(cpuAllocation uint64) {
serviceConfig.privateServiceConfig.MinCpuAllocationMilliCpus = cpuAllocation
}

// only available for Kubernetes
func (serviceConfig *ServiceConfig) GetMinMemoryAllocationMegabytes() uint64 {
return serviceConfig.privateServiceConfig.MinMemoryAllocationMegabytes
}

func (serviceConfig *ServiceConfig) SetMinMemoryAllocationMegabytes(memoryAllocation uint64) {
serviceConfig.privateServiceConfig.MemoryAllocationMegabytes = memoryAllocation
}

func (serviceConfig *ServiceConfig) GetUser() *service_user.ServiceUser {
return serviceConfig.privateServiceConfig.User
}

func (serviceConfig *ServiceConfig) SetUser(user *service_user.ServiceUser) {
tedim52 marked this conversation as resolved.
Show resolved Hide resolved
serviceConfig.privateServiceConfig.User = user
}

func (serviceConfig *ServiceConfig) GetLabels() map[string]string {
return serviceConfig.privateServiceConfig.Labels
}

func (serviceConfig *ServiceConfig) SetLabels(labels map[string]string) {
serviceConfig.privateServiceConfig.Labels = labels
}

func (serviceConfig *ServiceConfig) GetTolerations() []v1.Toleration {
return serviceConfig.privateServiceConfig.Tolerations
}

func (serviceConfig *ServiceConfig) SetTolerations(tolerations []v1.Toleration) {
serviceConfig.privateServiceConfig.Tolerations = tolerations
}

func (serviceConfig *ServiceConfig) GetImageDownloadMode() image_download_mode.ImageDownloadMode {
return serviceConfig.privateServiceConfig.ImageDownloadMode
}

func (serviceConfig *ServiceConfig) SetImageDownloadMode(mode image_download_mode.ImageDownloadMode) {
serviceConfig.privateServiceConfig.ImageDownloadMode = mode
}

func (serviceConfig *ServiceConfig) MarshalJSON() ([]byte, error) {
return json.Marshal(serviceConfig.privateServiceConfig)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ import (
)

type InterpretationTimeValueStore struct {
serviceValues *serviceInterpretationValueRepository
serde *kurtosis_types.StarlarkValueSerde
serviceConfigValues map[service.ServiceName]*service.ServiceConfig
setServiceConfigValues map[service.ServiceName]*service.ServiceConfig
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
return &InterpretationTimeValueStore{
serviceConfigValues: map[service.ServiceName]*service.ServiceConfig{},
setServiceConfigValues: map[service.ServiceName]*service.ServiceConfig{},
serviceValues: serviceValuesRepository,
serde: serde}, nil
}

func (itvs *InterpretationTimeValueStore) PutService(name service.ServiceName, service *kurtosis_types.Service) error {
Expand Down Expand Up @@ -50,3 +56,32 @@ func (itvs *InterpretationTimeValueStore) RemoveService(name service.ServiceName
}
return nil
}

func (itvs *InterpretationTimeValueStore) PutServiceConfig(name service.ServiceName, serviceConfig *service.ServiceConfig) {
tedim52 marked this conversation as resolved.
Show resolved Hide resolved
itvs.serviceConfigValues[name] = serviceConfig
}

func (itvs *InterpretationTimeValueStore) GetServiceConfig(name service.ServiceName) (*service.ServiceConfig, error) {
serviceConfig, ok := itvs.serviceConfigValues[name]
if !ok {
return nil, stacktrace.NewError("Did not find new service config for '%v' in interpretation time value store.", name)
}
return serviceConfig, nil
}

func (itvs *InterpretationTimeValueStore) SetServiceConfig(name service.ServiceName, serviceConfig *service.ServiceConfig) {
itvs.setServiceConfigValues[name] = serviceConfig
}

func (itvs *InterpretationTimeValueStore) ExistsNewServiceConfigForService(name service.ServiceName) bool {
_, doesConfigFromSetServiceInstructionExists := itvs.setServiceConfigValues[name]
return doesConfigFromSetServiceInstructionExists
}

func (itvs *InterpretationTimeValueStore) GetNewServiceConfig(name service.ServiceName) (*service.ServiceConfig, error) {
newServiceConfig, ok := itvs.setServiceConfigValues[name]
if !ok {
return nil, stacktrace.NewError("Did not find new service config for '%v' in interpretation time value store.", name)
}
return newServiceConfig, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package interpretation_time_value_store

import (
"fmt"
"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_download_mode"
"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"
"github.com/stretchr/testify/require"
bolt "go.etcd.io/bbolt"
"os"
"testing"
)

const (
testServiceName = service.ServiceName("datastore-service")
testContainerImageName = "datastore-image"
enclaveDbFilePerm = 0666
)

func TestGetServiceConfigReturnsError(t *testing.T) {
enclaveDb := getEnclaveDBForTest(t)
dummySerde := shared_helpers.NewDummyStarlarkValueSerDeForTest()
itvs, err := CreateInterpretationTimeValueStore(enclaveDb, dummySerde)
require.NoError(t, err)

// no service config exists in store
_, err = itvs.GetServiceConfig(testServiceName)
require.Error(t, err)
}

func TestPutServiceConfig(t *testing.T) {
enclaveDb := getEnclaveDBForTest(t)
dummySerde := shared_helpers.NewDummyStarlarkValueSerDeForTest()
itvs, err := CreateInterpretationTimeValueStore(enclaveDb, dummySerde)
require.NoError(t, err)

expectedServiceConfig, err := getTestServiceConfigForService(testServiceName, "latest")
require.NoError(t, err)

itvs.PutServiceConfig(testServiceName, expectedServiceConfig)

actualServiceConfig, err := itvs.GetServiceConfig(testServiceName)
require.NoError(t, err)
require.Equal(t, expectedServiceConfig.GetContainerImageName(), actualServiceConfig.GetContainerImageName())
}

func TestPutNewServiceConfig(t *testing.T) {
enclaveDb := getEnclaveDBForTest(t)
dummySerde := shared_helpers.NewDummyStarlarkValueSerDeForTest()
itvs, err := CreateInterpretationTimeValueStore(enclaveDb, dummySerde)
require.NoError(t, err)

oldServiceConfig, err := getTestServiceConfigForService(testServiceName, "older")
require.NoError(t, err)
itvs.PutServiceConfig(testServiceName, oldServiceConfig)

newerServiceConfig, err := getTestServiceConfigForService(testServiceName, "latest")
require.NoError(t, err)
itvs.SetServiceConfig(testServiceName, newerServiceConfig)

actualNewerServiceConfig, err := itvs.GetNewServiceConfig(testServiceName)
require.NoError(t, err)
require.Equal(t, newerServiceConfig.GetContainerImageName(), actualNewerServiceConfig.GetContainerImageName())
}

func getTestServiceConfigForService(name service.ServiceName, imageTag string) (*service.ServiceConfig, error) {
return service.CreateServiceConfig(
fmt.Sprintf("%v-%v:%v", name, testContainerImageName, imageTag),
nil,
nil,
nil,
nil,
nil,
[]string{},
[]string{},
map[string]string{},
nil,
nil,
0,
0,
"IP-ADDRESS",
0,
0,
map[string]string{},
nil,
nil,
nil,
image_download_mode.ImageDownloadMode_Always)
}

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(), enclaveDbFilePerm, nil)
require.NoError(t, err)
enclaveDb := &enclave_db.EnclaveDB{
DB: db,
}

return enclaveDb
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"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"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/request"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/set_service"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/start_service"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/stop_service"
"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/store_service_files"
Expand Down Expand Up @@ -73,6 +74,7 @@ func KurtosisPlanInstructions(
add_service.NewAddServices(serviceNetwork, runtimeValueStore, packageId, packageContentProvider, packageReplaceOptions, interpretationTimeValueStore, imageDownloadMode),
get_service.NewGetService(interpretationTimeValueStore),
get_services.NewGetServices(interpretationTimeValueStore),
set_service.NewSetService(serviceNetwork, interpretationTimeValueStore, packageId, packageContentProvider, packageReplaceOptions, imageDownloadMode),
get_files_artifact.NewGetFilesArtifact(),
verify.NewVerify(runtimeValueStore),
exec.NewExec(serviceNetwork, runtimeValueStore),
Expand Down