diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go index d5ac56df8e..d4c4695b85 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go @@ -2,11 +2,12 @@ package docker_kurtosis_backend import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "io" "sync" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + "github.com/sirupsen/logrus" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions" @@ -536,6 +537,10 @@ func (backend *DockerKurtosisBackend) GetAvailableCPUAndMemory(ctx context.Conte return availableMemory, availableCpu, isResourceInformationComplete, nil } +func (backend *DockerKurtosisBackend) LoadImage(ctx context.Context, image io.ReadCloser) error { + return backend.dockerManager.LoadImage(ctx, image) +} + func (backend *DockerKurtosisBackend) BuildImage(ctx context.Context, imageName string, imageBuildSpec *image_build_spec.ImageBuildSpec) (string, error) { return backend.dockerManager.BuildImage(ctx, imageName, imageBuildSpec) } diff --git a/container-engine-lib/lib/backend_impls/docker/docker_manager/docker_manager.go b/container-engine-lib/lib/backend_impls/docker/docker_manager/docker_manager.go index 75abbb375a..ddc5674ac9 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_manager/docker_manager.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_manager/docker_manager.go @@ -11,13 +11,8 @@ import ( "context" "encoding/json" "fmt" - "github.com/docker/docker/api/types/registry" - "github.com/docker/go-units" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/uuid_generator" - "github.com/kurtosis-tech/kurtosis/utils" "io" + "io/ioutil" "math" "net" "regexp" @@ -25,6 +20,13 @@ import ( "sync" "time" + "github.com/docker/docker/api/types/registry" + "github.com/docker/go-units" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/uuid_generator" + "github.com/kurtosis-tech/kurtosis/utils" + "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -1312,6 +1314,16 @@ func (manager *DockerManager) FetchImage(ctx context.Context, image string, regi return pulledFromRemote, imageArchitecture, nil } +func (manager *DockerManager) LoadImage(ctx context.Context, image io.ReadCloser) error { + response, err := manager.dockerClient.ImageLoad(ctx, image, true) + if err != nil { + return stacktrace.Propagate(err, "Fail to load docker image") + } + responseBody, err := ioutil.ReadAll(response.Body) + logrus.Infof("Docker image loaded: %s", responseBody) + return nil +} + func (manager *DockerManager) BuildImage(ctx context.Context, imageName string, imageBuildSpec *image_build_spec.ImageBuildSpec) (string, error) { buildContextDirPath := imageBuildSpec.GetBuildContextDir() buildContextTarReader, err := getBuildContextReader(buildContextDirPath) diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go index 43e1c4b1fb..f3455bfa61 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go @@ -2,9 +2,11 @@ package kubernetes_kurtosis_backend import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "io" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" apiv1 "k8s.io/api/core/v1" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/engine_functions" @@ -483,6 +485,11 @@ func (backend *KubernetesKurtosisBackend) BuildImage(ctx context.Context, imageN return "", stacktrace.NewError("Building images isn't yet implemented in Kubernetes.") } +func (backend *KubernetesKurtosisBackend) LoadImage(ctx context.Context, image io.ReadCloser) error { + // TODO IMPLEMENT + return stacktrace.NewError("Loading images isn't yet implemented in Kubernetes.") +} + // ==================================================================================================== // // Private Helper Functions diff --git a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go index 3adc276992..a7efcd0ccb 100644 --- a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go @@ -2,11 +2,13 @@ package metrics_reporting import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "io" "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/api_container" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/compute_resources" @@ -464,3 +466,7 @@ func (backend *MetricsReportingKurtosisBackend) GetAvailableCPUAndMemory(ctx con func (backend *MetricsReportingKurtosisBackend) BuildImage(ctx context.Context, imageName string, imageBuildSpec *image_build_spec.ImageBuildSpec) (string, error) { return backend.underlying.BuildImage(ctx, imageName, imageBuildSpec) } + +func (backend *MetricsReportingKurtosisBackend) LoadImage(ctx context.Context, image io.ReadCloser) error { + return backend.underlying.LoadImage(ctx, image) +} diff --git a/container-engine-lib/lib/backend_interface/kurtosis_backend.go b/container-engine-lib/lib/backend_interface/kurtosis_backend.go index 06da782443..02efc4c25d 100644 --- a/container-engine-lib/lib/backend_interface/kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/kurtosis_backend.go @@ -2,11 +2,13 @@ package backend_interface import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "io" "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/api_container" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/compute_resources" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/enclave" @@ -353,4 +355,7 @@ type KurtosisBackend interface { // BuildImage builds a container image based on the [imageBuildSpec] with [imageName] // Returns image architecture and if error occurred BuildImage(ctx context.Context, imageName string, imageBuildSpec *image_build_spec.ImageBuildSpec) (string, error) + + // Load docker image file (tar.gz format) into docker + LoadImage(ctx context.Context, image io.ReadCloser) error } diff --git a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go index 128bb9473c..07ef74e1f6 100644 --- a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go @@ -1624,6 +1624,49 @@ func (_c *MockKurtosisBackend_GetUserServices_Call) RunAndReturn(run func(contex return _c } +// LoadImage provides a mock function with given fields: ctx, image +func (_m *MockKurtosisBackend) LoadImage(ctx context.Context, image io.ReadCloser) error { + ret := _m.Called(ctx, image) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, io.ReadCloser) error); ok { + r0 = rf(ctx, image) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockKurtosisBackend_LoadImage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadImage' +type MockKurtosisBackend_LoadImage_Call struct { + *mock.Call +} + +// LoadImage is a helper method to define mock.On call +// - ctx context.Context +// - image io.ReadCloser +func (_e *MockKurtosisBackend_Expecter) LoadImage(ctx interface{}, image interface{}) *MockKurtosisBackend_LoadImage_Call { + return &MockKurtosisBackend_LoadImage_Call{Call: _e.mock.On("LoadImage", ctx, image)} +} + +func (_c *MockKurtosisBackend_LoadImage_Call) Run(run func(ctx context.Context, image io.ReadCloser)) *MockKurtosisBackend_LoadImage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(io.ReadCloser)) + }) + return _c +} + +func (_c *MockKurtosisBackend_LoadImage_Call) Return(_a0 error) *MockKurtosisBackend_LoadImage_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockKurtosisBackend_LoadImage_Call) RunAndReturn(run func(context.Context, io.ReadCloser) error) *MockKurtosisBackend_LoadImage_Call { + _c.Call.Return(run) + return _c +} + // PruneUnusedImages provides a mock function with given fields: ctx func (_m *MockKurtosisBackend) PruneUnusedImages(ctx context.Context) ([]string, error) { ret := _m.Called(ctx) diff --git a/container-engine-lib/lib/backend_interface/objects/image_load/image_load.go b/container-engine-lib/lib/backend_interface/objects/image_load/image_load.go new file mode 100644 index 0000000000..eb0c8e0d94 --- /dev/null +++ b/container-engine-lib/lib/backend_interface/objects/image_load/image_load.go @@ -0,0 +1,48 @@ +package image_load + +import ( + "encoding/json" + + "github.com/kurtosis-tech/stacktrace" +) + +type ImageLoad struct { + // we do this way in order to have exported fields which can be marshalled + // and an unexported type for encapsulation + privateImageLoad *privateImageLoad +} + +// ImageLoad contains the information need for building a container image. +type privateImageLoad struct { + // Location of the container image to load (eg. tar.gz) on the machine + ContainerImageFilePath string +} + +func NewImageLoad(containerImageFilePath string) *ImageLoad { + internalImageLoad := &privateImageLoad{ + ContainerImageFilePath: containerImageFilePath, + } + return &ImageLoad{internalImageLoad} +} + +func (imageLoad *ImageLoad) GetContainerImageFilePath() string { + return imageLoad.privateImageLoad.ContainerImageFilePath +} + +func (imageLoad *ImageLoad) MarshalJSON() ([]byte, error) { + return json.Marshal(imageLoad.privateImageLoad) +} + +func (imageLoad *ImageLoad) UnmarshalJSON(data []byte) error { + + // Suppressing exhaustruct requirement because we want an object with zero values + // nolint: exhaustruct + unmarshalledPrivateStructPtr := &privateImageLoad{} + + if err := json.Unmarshal(data, unmarshalledPrivateStructPtr); err != nil { + return stacktrace.Propagate(err, "An error occurred unmarshalling the private struct") + } + + imageLoad.privateImageLoad = unmarshalledPrivateStructPtr + return nil +} diff --git a/container-engine-lib/lib/backend_interface/objects/service/service_config.go b/container-engine-lib/lib/backend_interface/objects/service/service_config.go index 0b7b56b805..43ad4f26a7 100644 --- a/container-engine-lib/lib/backend_interface/objects/service/service_config.go +++ b/container-engine-lib/lib/backend_interface/objects/service/service_config.go @@ -2,7 +2,9 @@ package service import ( "encoding/json" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_load" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "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_directory" @@ -28,7 +30,11 @@ 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 + // Reference to a image file that can be loaded into a backend image + // This is one of the options to reference a image and this value is optional (i.e. nil) + ImageLoad *image_load.ImageLoad PrivatePorts map[string]*port_spec.PortSpec @@ -67,6 +73,7 @@ func CreateServiceConfig( containerImageName string, imageBuildSpec *image_build_spec.ImageBuildSpec, imageRegistrySpec *image_registry_spec.ImageRegistrySpec, + imageLoad *image_load.ImageLoad, privatePorts map[string]*port_spec.PortSpec, publicPorts map[string]*port_spec.PortSpec, entrypointArgs []string, @@ -124,6 +131,10 @@ func (serviceConfig *ServiceConfig) GetImageRegistrySpec() *image_registry_spec. return serviceConfig.privateServiceConfig.ImagerRegistrySpec } +func (serviceConfig *ServiceConfig) GetImageLoad() *image_load.ImageLoad { + return serviceConfig.privateServiceConfig.ImageLoad +} + func (serviceConfig *ServiceConfig) GetPrivatePorts() map[string]*port_spec.PortSpec { return serviceConfig.privateServiceConfig.PrivatePorts } diff --git a/container-engine-lib/lib/backend_interface/objects/service/service_config_test.go b/container-engine-lib/lib/backend_interface/objects/service/service_config_test.go index 5a2acb97de..e05fb5a96e 100644 --- a/container-engine-lib/lib/backend_interface/objects/service/service_config_test.go +++ b/container-engine-lib/lib/backend_interface/objects/service/service_config_test.go @@ -2,15 +2,18 @@ package service import ( "encoding/json" + + "testing" + "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_load" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "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_directory" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service_user" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" - "testing" - "time" ) func TestServiceConfigMarshallers(t *testing.T) { @@ -64,6 +67,7 @@ func getServiceConfigForTest(t *testing.T, imageName string) *ServiceConfig { imageName, testImageBuildSpec(), testImageRegistrySpec(), + testImageLoad(), testPrivatePorts(t), testPublicPorts(t), []string{"bin", "bash", "ls"}, @@ -200,3 +204,7 @@ func testToleration() []v1.Toleration { TolerationSeconds: &tolerationSeconds, }} } + +func testImageLoad() *image_load.ImageLoad { + return image_load.NewImageLoad("/path/to/image") +} diff --git a/container-engine-lib/lib/database_accessors/enclave_db/service_registration/repository_test.go b/container-engine-lib/lib/database_accessors/enclave_db/service_registration/repository_test.go index 85d497dff7..4647324f07 100644 --- a/container-engine-lib/lib/database_accessors/enclave_db/service_registration/repository_test.go +++ b/container-engine-lib/lib/database_accessors/enclave_db/service_registration/repository_test.go @@ -2,6 +2,12 @@ package service_registration import ( "fmt" + "math/rand" + "net" + "os" + "testing" + "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/enclave" "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" @@ -9,11 +15,6 @@ import ( "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db" "github.com/stretchr/testify/require" bolt "go.etcd.io/bbolt" - "math/rand" - "net" - "os" - "testing" - "time" ) const ( @@ -306,6 +307,7 @@ func getServiceConfigForTest(t *testing.T, imageName string) *service.ServiceCon imageName, nil, nil, + nil, testPrivatePorts(t), testPublicPorts(t), []string{"bin", "bash", "ls"}, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go index e8a4f6a8ac..5fbdb1f9e1 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go @@ -113,6 +113,7 @@ func KurtosisTypeConstructors() []*starlark.Builtin { starlark.NewBuiltin(service_config.ReadyConditionTypeName, service_config.NewReadyConditionType().CreateBuiltin()), starlark.NewBuiltin(service_config.ImageBuildSpecTypeName, service_config.NewImageBuildSpecType().CreateBuiltin()), starlark.NewBuiltin(service_config.ImageRegistrySpecTypeName, service_config.NewImageRegistrySpec().CreateBuiltin()), + starlark.NewBuiltin(service_config.ImageLoadTypeName, service_config.NewImageLoadType().CreateBuiltin()), starlark.NewBuiltin(service_config.UserTypeName, service_config.NewUserType().CreateBuiltin()), starlark.NewBuiltin(service_config.TolerationTypeName, service_config.NewTolerationType().CreateBuiltin()), } 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 da32109423..94d3377bbc 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 @@ -3,6 +3,8 @@ package add_service import ( "context" "fmt" + "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service_directory" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network" @@ -17,7 +19,6 @@ import ( "github.com/kurtosis-tech/stacktrace" "github.com/sirupsen/logrus" "go.starlark.net/starlark" - "time" ) const ( @@ -110,6 +111,8 @@ func validateSingleService(validatorEnvironment *startosis_validator.ValidatorEn validatorEnvironment.AppendRequiredImageBuild(serviceConfig.GetContainerImageName(), serviceConfig.GetImageBuildSpec()) } else if serviceConfig.GetImageRegistrySpec() != nil { validatorEnvironment.AppendImageToPullWithAuth(serviceConfig.GetContainerImageName(), serviceConfig.GetImageRegistrySpec()) + } else if serviceConfig.GetImageLoad() != nil { + validatorEnvironment.AppendRequiredImageLoad(serviceConfig.GetContainerImageName(), serviceConfig.GetImageLoad()) } else { validatorEnvironment.AppendRequiredImagePull(serviceConfig.GetContainerImageName()) } @@ -202,6 +205,7 @@ func replaceMagicStrings( serviceConfig.GetContainerImageName(), serviceConfig.GetImageBuildSpec(), serviceConfig.GetImageRegistrySpec(), + serviceConfig.GetImageLoad(), serviceConfig.GetPrivatePorts(), serviceConfig.GetPublicPorts(), entrypoints, 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 430f9701e8..b89cedb8ca 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 @@ -2,6 +2,9 @@ package add_service import ( "fmt" + "os" + "testing" + "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" @@ -10,8 +13,6 @@ import ( "github.com/stretchr/testify/require" bolt "go.etcd.io/bbolt" "go.starlark.net/starlark" - "os" - "testing" ) const ( @@ -42,6 +43,7 @@ func TestAddServiceShared_EntryPointArgsRuntimeValueAreReplaced(t *testing.T) { nil, nil, nil, + nil, []string{"-- " + runtimeValue}, nil, nil, @@ -88,6 +90,7 @@ func TestAddServiceShared_CmdArgsRuntimeValueAreReplaced(t *testing.T) { nil, nil, nil, + nil, []string{"bash", "-c", "sleep " + runtimeValue}, nil, nil, @@ -134,6 +137,7 @@ func TestAddServiceShared_EnvVarsWithRuntimeValueAreReplaced(t *testing.T) { nil, nil, nil, + nil, map[string]string{ "PORT": runtimeValue, }, @@ -187,6 +191,7 @@ func TestAddServiceShared_ServiceNameWithRuntimeValuesAreReplaced(t *testing.T) nil, nil, nil, + nil, 0, 0, "", diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/tasks_shared.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/tasks_shared.go index e8addad386..943fc2d923 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/tasks_shared.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/tasks/tasks_shared.go @@ -3,6 +3,10 @@ package tasks import ( "context" "fmt" + "reflect" + "strings" + "time" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/exec_result" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service_directory" @@ -19,9 +23,6 @@ import ( "github.com/sirupsen/logrus" "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" - "reflect" - "strings" - "time" ) // shared constants @@ -255,6 +256,7 @@ func getServiceConfig(image string, filesArtifactExpansion *service_directory.Fi nil, nil, nil, + nil, // This make sure that the container does not stop as soon as it starts // This only is needed for kubernetes at the moment // TODO: Instead of creating a service and running exec commands 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 615790499f..03221a8b30 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 @@ -2,9 +2,10 @@ package test_engine import ( "fmt" - "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider" "testing" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/container" "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" @@ -36,6 +37,7 @@ func (suite *KurtosisPlanInstructionTestSuite) TestAddService() { testContainerImageName, nil, nil, + nil, map[string]*port_spec.PortSpec{}, map[string]*port_spec.PortSpec{}, nil, 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 87a2247e3b..5e9dd1710e 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 @@ -2,13 +2,14 @@ package test_engine import ( "fmt" - "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider" "io" "net/http" "net/url" "strings" "testing" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages/mock_package_content_provider" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/container" "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" @@ -52,6 +53,7 @@ func (suite *KurtosisPlanInstructionTestSuite) TestAddServices() { testContainerImageName, nil, nil, + nil, map[string]*port_spec.PortSpec{}, map[string]*port_spec.PortSpec{}, nil, @@ -77,6 +79,7 @@ func (suite *KurtosisPlanInstructionTestSuite) TestAddServices() { testContainerImageName, nil, nil, + nil, map[string]*port_spec.PortSpec{}, map[string]*port_spec.PortSpec{}, nil, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_image_build_spec_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_image_build_spec_test.go index 037e9e441a..d14aa2b478 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_image_build_spec_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_image_build_spec_test.go @@ -2,6 +2,8 @@ package test_engine import ( "fmt" + "testing" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" "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" @@ -10,7 +12,6 @@ import ( "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/service_config" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages" "github.com/stretchr/testify/require" - "testing" ) type serviceConfigImageBuildSpecTestCase struct { @@ -71,6 +72,7 @@ func (t *serviceConfigImageBuildSpecTestCase) Assert(typeValue builtin_argument. testContainerImageName, expectedImageBuildSpec, nil, + nil, map[string]*port_spec.PortSpec{}, map[string]*port_spec.PortSpec{}, nil, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_minimal_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_minimal_framework_test.go index a3b955d12a..35ebe6f9a9 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_minimal_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_minimal_framework_test.go @@ -2,6 +2,8 @@ package test_engine import ( "fmt" + "testing" + "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/core/server/api_container/server/service_network" @@ -9,7 +11,6 @@ import ( "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/service_config" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages" "github.com/stretchr/testify/require" - "testing" ) type serviceConfigMinimalTestCase struct { @@ -48,6 +49,7 @@ func (t *serviceConfigMinimalTestCase) Assert(typeValue builtin_argument.Kurtosi testContainerImageName, nil, nil, + nil, map[string]*port_spec.PortSpec{}, map[string]*port_spec.PortSpec{}, nil, diff --git a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/image_load_spec.go b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/image_load_spec.go new file mode 100644 index 0000000000..69bf86d540 --- /dev/null +++ b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/image_load_spec.go @@ -0,0 +1,136 @@ +package service_config + +import ( + "path" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_load" + "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_type_constructor" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_constants" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors" + "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages" + "go.starlark.net/starlark" +) + +const ( + ImageLoadTypeName = "ImageLoad" + LoadImageAttr = "image_file_path" +) + +func NewImageLoadType() *kurtosis_type_constructor.KurtosisTypeConstructor { + return &kurtosis_type_constructor.KurtosisTypeConstructor{ + KurtosisBaseBuiltin: &kurtosis_starlark_framework.KurtosisBaseBuiltin{ + Name: ImageLoadTypeName, + Arguments: []*builtin_argument.BuiltinArgument{ + { + Name: LoadImageAttr, + IsOptional: false, + ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String], + Validator: func(value starlark.Value) *startosis_errors.InterpretationError { + return builtin_argument.NonEmptyString(value, LoadImageAttr) + }, + }, + { + Name: TargetStageAttr, + IsOptional: true, + ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String], + Validator: func(value starlark.Value) *startosis_errors.InterpretationError { + return builtin_argument.NonEmptyString(value, TargetStageAttr) + }, + }, + }, + }, + Instantiate: instantiateImageLoad, + } +} + +func instantiateImageLoad(arguments *builtin_argument.ArgumentValuesSet) (builtin_argument.KurtosisValueType, *startosis_errors.InterpretationError) { + kurtosisValueType, err := kurtosis_type_constructor.CreateKurtosisStarlarkTypeDefault(ImageLoadTypeName, arguments) + if err != nil { + return nil, err + } + return &ImageLoad{ + KurtosisValueTypeDefault: kurtosisValueType, + }, nil +} + +// ImageLoad is a starlark.Value that holds all the information for the startosis_engine to initiate an image Load +type ImageLoad struct { + *kurtosis_type_constructor.KurtosisValueTypeDefault +} + +func (imageLoad *ImageLoad) Copy() (builtin_argument.KurtosisValueType, error) { + copiedValueType, err := imageLoad.KurtosisValueTypeDefault.Copy() + if err != nil { + return nil, err + } + return &ImageLoad{ + KurtosisValueTypeDefault: copiedValueType, + }, nil +} + +// Name to give image built from ImageLoad +func (imageLoad *ImageLoad) GetImagePathOnDisk() (string, *startosis_errors.InterpretationError) { + imageName, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.String](imageLoad.KurtosisValueTypeDefault, LoadImageAttr) + if interpretationErr != nil { + return "", interpretationErr + } + if !found { + return "", startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'", + LoadImageAttr, ImageLoadTypeName) + } + imageNameStr := imageName.GoString() + return imageNameStr, nil +} + +func (imageLoad *ImageLoad) ToKurtosisType( + locatorOfModuleInWhichThisBuiltInIsBeingCalled string, + packageId string, + packageContentProvider startosis_packages.PackageContentProvider, + packageReplaceOptions map[string]string) (*image_load.ImageLoad, *startosis_errors.InterpretationError) { + // get locator of context directory (relative or absolute) + imagePathOnDisk, interpretationErr := imageLoad.GetImagePathOnDisk() + if interpretationErr != nil { + return nil, interpretationErr + } + + containerImageFilePathOnDisk, interpretationErr := getOnDiskImageLoadPath( + imagePathOnDisk, + packageId, + locatorOfModuleInWhichThisBuiltInIsBeingCalled, + packageContentProvider, + packageReplaceOptions) + if interpretationErr != nil { + return nil, interpretationErr + } + + return image_load.NewImageLoad(containerImageFilePathOnDisk), nil +} + +// Returns the filepath of the Load context directory and container image on APIC based on package info +func getOnDiskImageLoadPath( + imageFilePathOnDisk string, + packageId string, + locatorOfModuleInWhichThisBuiltInIsBeingCalled string, + packageContentProvider startosis_packages.PackageContentProvider, + packageReplaceOptions map[string]string) (string, *startosis_errors.InterpretationError) { + if packageId == startosis_constants.PackageIdPlaceholderForStandaloneScript { + return "", startosis_errors.NewInterpretationError("Cannot use ImageLoad in a standalone script; create a package and rerun to use ImageLoad.") + } + + // get absolute locator of context directory + contextDirAbsoluteLocator, interpretationErr := packageContentProvider.GetAbsoluteLocator(packageId, locatorOfModuleInWhichThisBuiltInIsBeingCalled, imageFilePathOnDisk, packageReplaceOptions) + if interpretationErr != nil { + return "", interpretationErr + } + + // get on disk directory path of Dockerfile + containerImageAbsoluteLocator := path.Join(contextDirAbsoluteLocator, defaultContainerImageFileName) + containerImagePathOnDisk, interpretationErr := packageContentProvider.GetOnDiskAbsoluteFilePath(containerImageAbsoluteLocator) + if interpretationErr != nil { + return "", interpretationErr + } + + return containerImagePathOnDisk, nil +} diff --git a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go index e043956d98..51335eadec 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go @@ -2,7 +2,12 @@ package service_config import ( "fmt" + + "math" + "path" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_load" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "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" @@ -22,8 +27,6 @@ import ( "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_packages" "go.starlark.net/starlark" v1 "k8s.io/api/core/v1" - "math" - "path" ) const ( @@ -243,6 +246,7 @@ func (config *ServiceConfig) ToKurtosisType( var imageName string var maybeImageBuildSpec *image_build_spec.ImageBuildSpec var maybeImageRegistrySpec *image_registry_spec.ImageRegistrySpec + var maybeImageLoad *image_load.ImageLoad rawImageAttrValue, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.Value](config.KurtosisValueTypeDefault, ImageAttr) if interpretationErr != nil { return nil, interpretationErr @@ -250,7 +254,7 @@ func (config *ServiceConfig) ToKurtosisType( if !found { return nil, startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'", ImageAttr, ServiceConfigTypeName) } - imageName, maybeImageBuildSpec, maybeImageRegistrySpec, interpretationErr = convertImage( + imageName, maybeImageBuildSpec, maybeImageRegistrySpec, maybeImageLoad, interpretationErr = convertImage( rawImageAttrValue, locatorOfModuleInWhichThisBuiltInIsBeingCalled, packageId, @@ -480,6 +484,7 @@ func (config *ServiceConfig) ToKurtosisType( imageName, maybeImageBuildSpec, maybeImageRegistrySpec, + maybeImageLoad, privatePorts, publicPorts, entryPointArgs, @@ -650,32 +655,48 @@ func convertImage( locatorOfModuleInWhichThisBuiltInIsBeingCalled string, packageId string, packageContentProvider startosis_packages.PackageContentProvider, - packageReplaceOptions map[string]string) (string, *image_build_spec.ImageBuildSpec, *image_registry_spec.ImageRegistrySpec, *startosis_errors.InterpretationError) { + packageReplaceOptions map[string]string) (string, *image_build_spec.ImageBuildSpec, *image_registry_spec.ImageRegistrySpec, *image_load.ImageLoad, *startosis_errors.InterpretationError) { + imageBuildSpecStarlarkType, isImageBuildSpecStarlarkType := image.(*ImageBuildSpec) imageRegistrySpecStarlarkType, isImageRegistrySpecStarlarkType := image.(*ImageRegistrySpec) if isImageBuildSpecStarlarkType { imageBuildSpec, interpretationErr := imageBuildSpecStarlarkType.ToKurtosisType(locatorOfModuleInWhichThisBuiltInIsBeingCalled, packageId, packageContentProvider, packageReplaceOptions) if interpretationErr != nil { - return "", nil, nil, interpretationErr + return "", nil, nil, nil, interpretationErr } imageName, interpretationErr := imageBuildSpecStarlarkType.GetImageName() if interpretationErr != nil { - return "", nil, nil, interpretationErr + return "", nil, nil, nil, interpretationErr } - return imageName, imageBuildSpec, nil, nil + return imageName, imageBuildSpec, nil, nil, nil } else if isImageRegistrySpecStarlarkType { imageRegistrySpec, interpretationErr := imageRegistrySpecStarlarkType.ToKurtosisType() if interpretationErr != nil { - return "", nil, nil, interpretationErr + return "", nil, nil, nil, interpretationErr } - return imageRegistrySpec.GetImageName(), nil, imageRegistrySpec, nil + return imageRegistrySpec.GetImageName(), nil, imageRegistrySpec, nil, nil } else { imageName, interpretationErr := kurtosis_types.SafeCastToString(image, ImageAttr) if interpretationErr != nil { - return "", nil, nil, interpretationErr + return "", nil, nil, nil, interpretationErr } - return imageName, nil, nil, nil + return imageName, nil, nil, nil, nil + } + + imageLoadStarlarkType, isImageLoadStarlarkType := image.(*ImageLoad) + if isImageLoadStarlarkType { + imagePathOnDisk, interpretationErr := imageLoadStarlarkType.ToKurtosisType(locatorOfModuleInWhichThisBuiltInIsBeingCalled, packageId, packageContentProvider, packageReplaceOptions) + if interpretationErr != nil { + return "", nil, nil, nil, interpretationErr + } + return "", nil, nil, imagePathOnDisk, nil + } + + imageName, interpretationErr := kurtosis_types.SafeCastToString(image, ImageAttr) + if interpretationErr != nil { + return "", nil, nil, nil, interpretationErr } + return imageName, nil, nil, nil, nil } func convertTolerations(tolerationsList *starlark.List) ([]v1.Toleration, *startosis_errors.InterpretationError) { diff --git a/core/server/api_container/server/startosis_engine/startosis_validator/images_validator.go b/core/server/api_container/server/startosis_engine/startosis_validator/images_validator.go index 8cc701b9aa..dae4bf138d 100644 --- a/core/server/api_container/server/startosis_engine/startosis_validator/images_validator.go +++ b/core/server/api_container/server/startosis_engine/startosis_validator/images_validator.go @@ -2,10 +2,13 @@ package startosis_validator import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "sync" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" + + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_load" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_download_mode" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors" @@ -58,6 +61,10 @@ func (validator *ImagesValidator) Validate( wg.Add(1) go validator.buildImageUsingBackend(ctx, wg, imageCurrentlyValidating, validator.kurtosisBackend, imageName, imageBuildSpec, imageValidationErrors, imageValidationStarted, imageValidationFinished) } + for imageName, imageLoad := range environment.imagesToLoad { + wg.Add(1) + go validator.loadImageUsingBackend(ctx, wg, imageCurrentlyValidating, validator.kurtosisBackend, imageName, imageLoad, imageValidationErrors, imageValidationStarted, imageValidationFinished) + } wg.Wait() logrus.Debug("All image validation submitted, currently in progress.") } @@ -116,3 +123,36 @@ func (validator *ImagesValidator) buildImageUsingBackend( } logrus.Debugf("Container image '%s' successfully built", imageName) } + +func (validator *ImagesValidator) loadImageUsingBackend( + ctx context.Context, + wg *sync.WaitGroup, + imageCurrentlyLoading chan bool, + backend *backend_interface.KurtosisBackend, + imageName string, + imageLoad *image_load.ImageLoad, + buildErrors chan<- error, + imageLoadStarted chan<- string, + imageLoadFinished chan<- *ValidatedImage) { + + logrus.Debugf("Requesting to load image: '%s'", imageName) + var imageArch string + imageBuiltLocally := true + imagePulledFromRemote := false + defer wg.Done() + imageCurrentlyLoading <- true + imageLoadStarted <- imageName + defer func() { + <-imageCurrentlyLoading + imageLoadFinished <- NewValidatedImage(imageName, imagePulledFromRemote, imageBuiltLocally, imageArch) + }() + + logrus.Debugf("Starting the build of image: '%s'", imageName) + err := (*backend).LoadImage(ctx, imageLoad) + if err != nil { + logrus.Warnf("Container image '%s' failed to load. Error was: '%s'", imageName, err.Error()) + buildErrors <- startosis_errors.WrapWithValidationError(err, "Failed to load the required image '%v'.", imageName) + return + } + logrus.Debugf("Container image '%s' successfully built", imageName) +} diff --git a/core/server/api_container/server/startosis_engine/startosis_validator/validator_environment.go b/core/server/api_container/server/startosis_engine/startosis_validator/validator_environment.go index bb5b05c05b..008c7065aa 100644 --- a/core/server/api_container/server/startosis_engine/startosis_validator/validator_environment.go +++ b/core/server/api_container/server/startosis_engine/startosis_validator/validator_environment.go @@ -4,6 +4,7 @@ import ( "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/compute_resources" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_build_spec" "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/image_load" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/image_registry_spec" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service_directory" @@ -15,6 +16,7 @@ import ( type ValidatorEnvironment struct { imagesToPull map[string]*image_registry_spec.ImageRegistrySpec // "set" of images that need to be downloaded imagesToBuild map[string]*image_build_spec.ImageBuildSpec + imagesToLoad map[string]*image_load.ImageLoad serviceNames map[service.ServiceName]ComponentExistence artifactNames map[string]ComponentExistence persistentKeys map[service_directory.DirectoryPersistentKey]ComponentExistence @@ -39,6 +41,7 @@ func NewValidatorEnvironment(serviceNames map[service.ServiceName]bool, artifact return &ValidatorEnvironment{ imagesToPull: map[string]*image_registry_spec.ImageRegistrySpec{}, imagesToBuild: map[string]*image_build_spec.ImageBuildSpec{}, + imagesToLoad: map[string]*image_load.ImageLoad{}, serviceNames: serviceNamesWithComponentExistence, artifactNames: artifactNamesWithComponentExistence, serviceNameToPrivatePortIDs: serviceNameToPrivatePortIds, @@ -65,8 +68,12 @@ func (environmemt *ValidatorEnvironment) AppendImageToPullWithAuth(containerImag environmemt.imagesToPull[containerImage] = registrySpec } +func (environment *ValidatorEnvironment) AppendRequiredImageLoad(containerImage string, imageBuildSpec *image_load.ImageLoad) { + environment.imagesToLoad[containerImage] = imageBuildSpec +} + func (environment *ValidatorEnvironment) GetNumberOfContainerImagesToProcess() uint32 { - return uint32(len(environment.imagesToPull) + len(environment.imagesToBuild)) + return uint32(len(environment.imagesToPull) + len(environment.imagesToBuild) + len(environment.imagesToLoad)) } func (environment *ValidatorEnvironment) AddServiceName(serviceName service.ServiceName) { diff --git a/flake.nix b/flake.nix index b35be15268..a76934973a 100644 --- a/flake.nix +++ b/flake.nix @@ -35,6 +35,7 @@ golangci-lint delve enumer + go-mockery nodejs_20 yarn protobuf