diff --git a/cli/cli/commands/engine/restart/restart.go b/cli/cli/commands/engine/restart/restart.go index 0dceb666d8..78d4e15042 100644 --- a/cli/cli/commands/engine/restart/restart.go +++ b/cli/cli/commands/engine/restart/restart.go @@ -20,11 +20,13 @@ import ( const ( engineVersionFlagKey = "version" + engineAuthorFlagKey = "author" logLevelFlagKey = "log-level" enclavePoolSizeFlagKey = "enclave-pool-size" githubAuthTokenOverrideFlagKey = "github-auth-token" defaultEngineVersion = "" + defaultEngineAuthor = "kurtosistech" restartEngineOnSameVersionIfAnyRunning = false defaultShouldRestartAPIContainers = "false" @@ -44,6 +46,13 @@ var RestartCmd = &lowlevel.LowlevelKurtosisCommand{ Type: flags.FlagType_String, Default: defaultEngineVersion, }, + { + Key: engineAuthorFlagKey, + Usage: "The author (Docker username) of the Kurtosis engine that should be started (blank will start the kurtosistech version)", + Shorthand: "", + Type: flags.FlagType_String, + Default: defaultEngineAuthor, + }, { Key: logLevelFlagKey, Usage: fmt.Sprintf( @@ -142,9 +151,18 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error return stacktrace.Propagate(err, "Expected a value for the '%v' flag but failed to get it", restartAPIContainersFlagKey) } + engineAuthor, err := flags.GetString(engineAuthorFlagKey) + if err != nil { + return stacktrace.Propagate(err, "Expected a value for the '%v' flag but failed to get it", engineAuthorFlagKey) + } + + if engineAuthor != defaultEngineAuthor && engineVersion == defaultEngineVersion { + return stacktrace.NewError("Expected '%v' to be set as '%v' was set. Need to enter a custom engine veresion if a custom engine author is set", engineVersionFlagKey, engineAuthorFlagKey) + } + var engineClientCloseFunc func() error var restartEngineErr error - _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, logLevel, engineVersion, restartEngineOnSameVersionIfAnyRunning, enclavePoolSize, shouldStartInDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) + _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, logLevel, engineVersion, engineAuthor, restartEngineOnSameVersionIfAnyRunning, enclavePoolSize, shouldStartInDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) if restartEngineErr != nil { return stacktrace.Propagate(restartEngineErr, "An error occurred restarting the Kurtosis engine") } diff --git a/cli/cli/commands/engine/start/start.go b/cli/cli/commands/engine/start/start.go index 29bcbdf278..bbf989f25d 100644 --- a/cli/cli/commands/engine/start/start.go +++ b/cli/cli/commands/engine/start/start.go @@ -20,11 +20,13 @@ import ( const ( engineVersionFlagKey = "version" + engineAuthorFlagKey = "author" logLevelFlagKey = "log-level" enclavePoolSizeFlagKey = "enclave-pool-size" githubAuthTokenOverrideFlagKey = "github-auth-token" defaultEngineVersion = "" + defaultEngineAuthor = "kurtosistech" kurtosisTechEngineImagePrefix = "kurtosistech/engine" imageVersionDelimiter = ":" @@ -45,6 +47,13 @@ var StartCmd = &lowlevel.LowlevelKurtosisCommand{ Type: flags.FlagType_String, Default: defaultEngineVersion, }, + { + Key: engineAuthorFlagKey, + Usage: "The author (Docker username) of the Kurtosis engine that should be started (blank will start the kurtosistech version)", + Shorthand: "", + Type: flags.FlagType_String, + Default: defaultEngineAuthor, + }, { Key: logLevelFlagKey, Usage: fmt.Sprintf( @@ -138,16 +147,30 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error return stacktrace.Propagate(err, "Expected a value for the '%v' flag but failed to get it", restartAPIContainersFlagKey) } + engineAuthor, err := flags.GetString(engineAuthorFlagKey) + if err != nil { + return stacktrace.Propagate(err, "Expected a value for the '%v' flag but failed to get it", engineAuthorFlagKey) + } + + if engineAuthor != defaultEngineAuthor && engineVersion == defaultEngineVersion { + return stacktrace.NewError("Expected '%v' to be set as '%v' was set. Need to enter a custom engine veresion if a custom engine author is set", engineVersionFlagKey, engineAuthorFlagKey) + } + + imageForLogging := kurtosisTechEngineImagePrefix + if engineAuthor != defaultEngineAuthor { + imageForLogging = strings.Replace(imageForLogging, defaultEngineAuthor, engineAuthor, 1) + } + if engineVersion == defaultEngineVersion && isDebugMode { engineDebugVersion := fmt.Sprintf("%s-%s", kurtosis_version.KurtosisVersion, defaults.DefaultKurtosisContainerDebugImageNameSuffix) - logrus.Infof("Starting Kurtosis engine in debug mode from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, engineDebugVersion) - _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineDebugVersion, logLevel, enclavePoolSize, true, githubAuthTokenOverride, shouldRestartAPIContainers) + logrus.Infof("Starting Kurtosis engine in debug mode from image '%v%v%v'...", imageForLogging, imageVersionDelimiter, engineDebugVersion) + _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineDebugVersion, engineAuthor, logLevel, enclavePoolSize, true, githubAuthTokenOverride, shouldRestartAPIContainers) } else if engineVersion == defaultEngineVersion { - logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, kurtosis_version.KurtosisVersion) + logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", imageForLogging, imageVersionDelimiter, kurtosis_version.KurtosisVersion) _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, enclavePoolSize, githubAuthTokenOverride, shouldRestartAPIContainers) } else { - logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, engineVersion) - _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineVersion, logLevel, enclavePoolSize, defaults.DefaultEnableDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) + logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", imageForLogging, imageVersionDelimiter, engineVersion) + _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineVersion, engineAuthor, logLevel, enclavePoolSize, defaults.DefaultEnableDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) } if startEngineErr != nil { return stacktrace.Propagate(startEngineErr, "An error occurred starting the Kurtosis engine") diff --git a/cli/cli/commands/github/login/login.go b/cli/cli/commands/github/login/login.go index d0e5ffb86a..fbfb1034d3 100644 --- a/cli/cli/commands/github/login/login.go +++ b/cli/cli/commands/github/login/login.go @@ -18,6 +18,7 @@ import ( const ( defaultEngineVersion = "" + defaultEngineAuthor = "kurtosistech" restartEngineOnSameVersionIfAnyRunning = true ) @@ -71,7 +72,7 @@ func RestartEngineAfterGitHubAuth(ctx context.Context) error { var engineClientCloseFunc func() error var restartEngineErr error dontRestartAPIContainers := false - _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, defaults.DefaultEngineLogLevel, defaultEngineVersion, restartEngineOnSameVersionIfAnyRunning, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultEnableDebugMode, defaults.DefaultGitHubAuthTokenOverride, dontRestartAPIContainers) + _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, defaults.DefaultEngineLogLevel, defaultEngineVersion, defaultEngineAuthor, restartEngineOnSameVersionIfAnyRunning, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultEnableDebugMode, defaults.DefaultGitHubAuthTokenOverride, dontRestartAPIContainers) if restartEngineErr != nil { return stacktrace.Propagate(restartEngineErr, "An error occurred restarting the Kurtosis engine") } diff --git a/cli/cli/helpers/engine_manager/engine_existence_guarantor.go b/cli/cli/helpers/engine_manager/engine_existence_guarantor.go index 04c6286ee4..1fb3700494 100644 --- a/cli/cli/helpers/engine_manager/engine_existence_guarantor.go +++ b/cli/cli/helpers/engine_manager/engine_existence_guarantor.go @@ -23,6 +23,7 @@ import ( const ( // If set to empty, then we'll use whichever default version the launcher provides defaultEngineImageVersionTag = "" + defaultEngineAuthor = "kurtosistech" shouldForceLogsComponentsContainersRestartWhenEngineContainerIsStopped = true shouldForceLogsComponentsContainersRestartWhenEngineContainerIsRunning = false ) @@ -84,6 +85,9 @@ type engineExistenceGuarantor struct { // To restart the current API containers after the engine has been restarted restartAPIContainers bool + + // The author of the repository where the engine is + engineAuthor string } func newEngineExistenceGuarantorWithDefaultVersion( @@ -110,6 +114,7 @@ func newEngineExistenceGuarantorWithDefaultVersion( shouldSendMetrics, engineServerKurtosisBackendConfigSupplier, defaultEngineImageVersionTag, + defaultEngineAuthor, logLevel, maybeCurrentlyRunningEngineVersionTag, kurtosisClusterType, @@ -130,6 +135,7 @@ func newEngineExistenceGuarantorWithCustomVersion( shouldSendMetrics bool, engineServerKurtosisBackendConfigSupplier engine_server_launcher.KurtosisBackendConfigSupplier, imageVersionTag string, + engineAuthor string, logLevel logrus.Level, maybeCurrentlyRunningEngineVersionTag string, kurtosisClusterType resolved_config.KurtosisClusterType, @@ -160,6 +166,7 @@ func newEngineExistenceGuarantorWithCustomVersion( shouldRunInDebugMode: shouldRunInDebugMode, githubAuthTokenOverride: githubAuthTokenOverride, restartAPIContainers: restartAPIContainers, + engineAuthor: engineAuthor, } } @@ -221,9 +228,10 @@ func (guarantor *engineExistenceGuarantor) VisitStopped() error { guarantor.restartAPIContainers, ) } else { - _, _, engineLaunchErr = guarantor.engineServerLauncher.LaunchWithCustomVersion( + _, _, engineLaunchErr = guarantor.engineServerLauncher.LaunchWithCustomImageAuthor( guarantor.ctx, guarantor.imageVersionTag, + guarantor.engineAuthor, guarantor.logLevel, kurtosis_context.DefaultGrpcEngineServerPortNum, metricsUserId, diff --git a/cli/cli/helpers/engine_manager/engine_manager.go b/cli/cli/helpers/engine_manager/engine_manager.go index 68cfcc8281..8ca8ff4610 100644 --- a/cli/cli/helpers/engine_manager/engine_manager.go +++ b/cli/cli/helpers/engine_manager/engine_manager.go @@ -219,6 +219,7 @@ func (manager *EngineManager) StartEngineIdempotentlyWithDefaultVersion( func (manager *EngineManager) StartEngineIdempotentlyWithCustomVersion( ctx context.Context, engineImageVersionTag string, + engineAuthor string, logLevel logrus.Level, poolSize uint8, shouldStartInDebugMode bool, @@ -238,6 +239,7 @@ func (manager *EngineManager) StartEngineIdempotentlyWithCustomVersion( manager.shouldSendMetrics, manager.engineServerKurtosisBackendConfigSupplier, engineImageVersionTag, + engineAuthor, logLevel, engineVersion, clusterType, @@ -343,6 +345,7 @@ func (manager *EngineManager) RestartEngineIdempotently( ctx context.Context, logLevel logrus.Level, optionalVersionToUse string, + engineAuthor string, restartEngineOnSameVersionIfAnyRunning bool, poolSize uint8, shouldStartInDebugMode bool, @@ -373,7 +376,7 @@ func (manager *EngineManager) RestartEngineIdempotently( var engineClientCloseFunc func() error var restartEngineErr error if versionOfNewEngine != defaultEngineVersion { - _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithCustomVersion(ctx, versionOfNewEngine, logLevel, poolSize, shouldStartInDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) + _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithCustomVersion(ctx, versionOfNewEngine, engineAuthor, logLevel, poolSize, shouldStartInDebugMode, githubAuthTokenOverride, shouldRestartAPIContainers) } else { _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, poolSize, githubAuthTokenOverride, shouldRestartAPIContainers) } diff --git a/core/launcher/api_container_launcher/api_container_launcher.go b/core/launcher/api_container_launcher/api_container_launcher.go index 9f49cd3943..c30e491bad 100644 --- a/core/launcher/api_container_launcher/api_container_launcher.go +++ b/core/launcher/api_container_launcher/api_container_launcher.go @@ -21,7 +21,9 @@ const ( enclaveDataVolumeDirpath = "/kurtosis-data" // TODO This should come from the same logic that builds the server image!!!!! - containerImage = "kurtosistech/core" + defaultImageAuthor = "kurtosistech" + authorImageNameSeparator = "/" + containerImage = "core" ) type ApiContainerLauncher struct { @@ -90,6 +92,45 @@ func (launcher ApiContainerLauncher) LaunchWithCustomVersion( ) ( resultApiContainer *api_container.APIContainer, resultErr error, +) { + return launcher.LaunchWithCustomImageAuthor( + ctx, + imageVersionTag, + defaultImageAuthor, + logLevel, + enclaveUuid, + grpcPortNum, + backendConfigSupplier, + enclaveEnvVars, + isProductionEnclave, + metricsUserID, + didUserAcceptSendingMetrics, + isCI, + cloudUserID, + cloudInstanceID, + shouldStartInDebugMode, + ) +} + +func (launcher ApiContainerLauncher) LaunchWithCustomImageAuthor( + ctx context.Context, + imageVersionTag string, + imageAuthor string, + logLevel logrus.Level, + enclaveUuid enclave.EnclaveUUID, + grpcPortNum uint16, + backendConfigSupplier KurtosisBackendConfigSupplier, + enclaveEnvVars string, + isProductionEnclave bool, + metricsUserID string, + didUserAcceptSendingMetrics bool, + isCI bool, + cloudUserID metrics_client.CloudUserID, + cloudInstanceID metrics_client.CloudInstanceID, + shouldStartInDebugMode bool, +) ( + resultApiContainer *api_container.APIContainer, + resultErr error, ) { kurtosisBackendType, kurtosisBackendConfig := backendConfigSupplier.getKurtosisBackendConfig() argsObj, err := args.NewAPIContainerArgs( @@ -107,6 +148,7 @@ func (launcher ApiContainerLauncher) LaunchWithCustomVersion( isCI, cloudUserID, cloudInstanceID, + imageAuthor, ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred creating the API container args") @@ -119,7 +161,7 @@ func (launcher ApiContainerLauncher) LaunchWithCustomVersion( containerImageAndTag := fmt.Sprintf( "%v:%v", - containerImage, + imageAuthor+authorImageNameSeparator+containerImage, imageVersionTag, ) diff --git a/core/launcher/args/api_container_args.go b/core/launcher/args/api_container_args.go index 37d770642a..db95a7cf0d 100644 --- a/core/launcher/args/api_container_args.go +++ b/core/launcher/args/api_container_args.go @@ -54,6 +54,10 @@ type APIContainerArgs struct { // The Cloud Instance ID of the current user if available CloudInstanceID metrics_client.CloudInstanceID `json:"cloud_instance_id"` + + // The author of the image for the APIC, Engine and Files Artifact Expander + // In case someone is using a non Kurtosis published image + ImageAuthor string `json:"image_author"` } var skipValidation = map[string]bool{ @@ -110,6 +114,7 @@ func NewAPIContainerArgs( isCI bool, cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, + imageAuthor string, ) (*APIContainerArgs, error) { result := &APIContainerArgs{ Version: version, @@ -126,6 +131,7 @@ func NewAPIContainerArgs( IsCI: isCI, CloudUserID: cloudUserID, CloudInstanceID: cloudInstanceID, + ImageAuthor: imageAuthor, } if err := result.validate(); err != nil { diff --git a/core/server/api_container/main.go b/core/server/api_container/main.go index 2d22cd0624..66d10ae6b3 100644 --- a/core/server/api_container/main.go +++ b/core/server/api_container/main.go @@ -278,6 +278,7 @@ func createServiceNetwork( ownIpAddress, args.GrpcListenPortNum, args.Version, + args.ImageAuthor, ) serviceNetwork, err := service_network.NewDefaultServiceNetwork( diff --git a/core/server/api_container/server/service_network/api_container_info.go b/core/server/api_container/server/service_network/api_container_info.go index 27c664ce85..76385647db 100644 --- a/core/server/api_container/server/service_network/api_container_info.go +++ b/core/server/api_container/server/service_network/api_container_info.go @@ -8,17 +8,21 @@ type ApiContainerInfo struct { grpcPortNum uint16 version string + + imageAuthor string } func NewApiContainerInfo( ipAddress net.IP, grpcPortNum uint16, version string, + imageAuthor string, ) *ApiContainerInfo { return &ApiContainerInfo{ ipAddress: ipAddress, grpcPortNum: grpcPortNum, version: version, + imageAuthor: imageAuthor, } } @@ -33,3 +37,7 @@ func (apic *ApiContainerInfo) GetGrpcPortNum() uint16 { func (apic *ApiContainerInfo) GetVersion() string { return apic.version } + +func (apic *ApiContainerInfo) GetImageAuthor() string { + return apic.imageAuthor +} diff --git a/core/server/api_container/server/service_network/default_service_network_test.go b/core/server/api_container/server/service_network/default_service_network_test.go index dc6bd30101..957ca21e07 100644 --- a/core/server/api_container/server/service_network/default_service_network_test.go +++ b/core/server/api_container/server/service_network/default_service_network_test.go @@ -52,6 +52,7 @@ var ( testIpFromInt(0), uint16(1234), "0.0.0", + "kurtosistech", ) unusedEnclaveDataDir *enclave_data_directory.EnclaveDataDirectory diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_backward_compatible_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_backward_compatible_test.go index 5fd85163e2..a7c0835ed5 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_backward_compatible_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_backward_compatible_test.go @@ -22,7 +22,7 @@ type serviceConfigFullTestCaseBackwardCompatible struct { func (suite *KurtosisTypeConstructorTestSuite) TestServiceConfigFullBackwardCompatible() { suite.serviceNetwork.EXPECT().GetApiContainerInfo().Times(1).Return( - service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0"), + service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0", testImageAuthor), ) suite.run(&serviceConfigFullTestCaseBackwardCompatible{ diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go index 535fcdfda8..b1eaba1e1e 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go @@ -25,7 +25,7 @@ type serviceConfigFullTestCase struct { func (suite *KurtosisTypeConstructorTestSuite) TestServiceConfigFull() { suite.serviceNetwork.EXPECT().GetApiContainerInfo().Times(1).Return( - service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0"), + service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0", testImageAuthor), ) suite.run(&serviceConfigFullTestCase{ diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_multiple_files_in_same_folder_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_multiple_files_in_same_folder_test.go index bdc28f9f4f..5995fc847a 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_multiple_files_in_same_folder_test.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_multiple_files_in_same_folder_test.go @@ -22,7 +22,7 @@ type serviceConfigMultipleFilesInSameFolderTestCase struct { func (suite *KurtosisTypeConstructorTestSuite) TestServiceConfigMultipleFilesInSameFolder() { suite.serviceNetwork.EXPECT().GetApiContainerInfo().Times(1).Return( - service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0"), + service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), 0, "0.0.0", testImageAuthor), ) suite.run(&serviceConfigMultipleFilesInSameFolderTestCase{ diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go index 45f580e662..77b376efff 100644 --- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go +++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants.go @@ -151,4 +151,6 @@ var ( testTolerationSeconds = int64(64) testFilesToBeMoved = "test.txt" + + testImageAuthor = "kurtosistech" ) 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 a083d80d4c..37ffb02faf 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 @@ -57,7 +57,7 @@ const ( filesArtifactExpansionDirsParentDirpath string = "/files-artifacts" // TODO This should be populated from the build flow that builds the files-artifacts-expander Docker image - filesArtifactsExpanderImage string = "kurtosistech/files-artifacts-expander" + filesArtifactsExpanderImage string = "files-artifacts-expander" minimumMemoryAllocationMegabytes = 6 ) @@ -623,7 +623,8 @@ func ConvertFilesArtifactsMounts(filesArtifactsMountDirpathsMap map[string][]str } expanderImageAndTag := fmt.Sprintf( - "%v:%v", + "%v/%v:%v", + apiContainerInfo.GetImageAuthor(), filesArtifactsExpanderImage, apiContainerInfo.GetVersion(), ) 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 01602da4a7..b652056026 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 @@ -32,6 +32,8 @@ const ( noInputParams = "{}" defaultNonBlockingMode = false + + testImageAuthor = "kurtosistech" ) var noPackageReplaceOptions = map[string]string{} @@ -69,7 +71,7 @@ func (suite *StartosisInterpreterIdempotentTestSuite) SetupTest() { 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"), + service_network.NewApiContainerInfo(net.IPv4(0, 0, 0, 0), uint16(1234), "0.0.0", testImageAuthor), ) serviceNetwork.EXPECT().GetEnclaveUuid().Maybe().Return(enclaveUuid) suite.interpreter = NewStartosisInterpreter(serviceNetwork, suite.packageContentProvider, runtimeValueStore, starlarkValueSerde, "", interpretationTimeValueStore) diff --git a/core/server/api_container/server/startosis_engine/startosis_interpreter_plan_yaml_test.go b/core/server/api_container/server/startosis_engine/startosis_interpreter_plan_yaml_test.go index 0efb441b75..9a4e8087ef 100644 --- a/core/server/api_container/server/startosis_engine/startosis_interpreter_plan_yaml_test.go +++ b/core/server/api_container/server/startosis_engine/startosis_interpreter_plan_yaml_test.go @@ -66,7 +66,8 @@ func (suite *StartosisIntepreterPlanYamlTestSuite) SetupTest() { apiContainerInfo := service_network.NewApiContainerInfo( net.IP{}, mockApicPortNum, - mockApicVersion) + mockApicVersion, + testImageAuthor) suite.serviceNetwork.EXPECT().GetApiContainerInfo().Return(apiContainerInfo) suite.interpreter = NewStartosisInterpreter(suite.serviceNetwork, suite.packageContentProvider, suite.runtimeValueStore, nil, "", suite.interpretationTimeValueStore) diff --git a/docs/docs/cli-reference/engine-restart.md b/docs/docs/cli-reference/engine-restart.md index 7ed0750d0f..3469e7aa88 100644 --- a/docs/docs/cli-reference/engine-restart.md +++ b/docs/docs/cli-reference/engine-restart.md @@ -13,6 +13,7 @@ kurtosis engine restart You may optionally pass in the following flags with this command: * `--log-level`: The level that the started engine should log at. Options include: `panic`, `fatal`, `error`, `warning`, `info`, `debug`, or `trace`. The engine logs at the `info` level by default. * `--version`: The version (Docker tag) of the Kurtosis engine that should be started. If not set, the engine will start up with the default version. +* `--author`: "The author (Docker username) of the Kurtosis engine that should be started (blank will start the kurtosistech version). The same author and version are used for the API Container & Files Artifact Expander. * `--enclave-pool-size`: The size of the Kurtosis engine enclave pool. The enclave pool is a component of the Kurtosis engine that allows us to create and maintain 'n' number of idle enclaves for future use. This functionality allows to improve the performance for each new creation enclave request. -CAUTION: The `--enclave-pool-size` flag is only available for Kubernetes. \ No newline at end of file +CAUTION: The `--enclave-pool-size` flag is only available for Kubernetes. The enclave pool is disabled for custom engine author for now. \ No newline at end of file diff --git a/docs/docs/cli-reference/engine-start.md b/docs/docs/cli-reference/engine-start.md index 39955dc329..6f431e54a0 100644 --- a/docs/docs/cli-reference/engine-start.md +++ b/docs/docs/cli-reference/engine-start.md @@ -14,7 +14,8 @@ This command will do nothing if the Kurtosis engine is already running. You may optionally pass in the following flags with this command: * `--log-level`: The level that the started engine should log at. Options include: `panic`, `fatal`, `error`, `warning`, `info`, `debug`, or `trace`. The engine logs at the `info` level by default. * `--version`: The version (Docker tag) of the Kurtosis engine that should be started. If not set, the engine will start up with the default version. +* `--author`: "The author (Docker username) of the Kurtosis engine that should be started (blank will start the kurtosistech version). The same author and version are used for the API Container & Files Artifact Expander. * `--enclave-pool-size`: The size of the Kurtosis engine enclave pool. The enclave pool is a component of the Kurtosis engine that allows us to create and maintain 'n' number of idle enclaves for future use. This functionality allows to improve the performance for each new creation enclave request. * `--github-auth-token`: The auth token to use for authorizing GitHub operations. If set, this will override the currently logged in GitHub user from `kurtosis github login`, if one exists. Note, this token does not persist when restarting the engine. -CAUTION: The `--enclave-pool-size` flag is only available for Kubernetes. \ No newline at end of file +CAUTION: The `--enclave-pool-size` flag is only available for Kubernetes. The enclave pool is disabled for custom engine author for now. \ No newline at end of file diff --git a/engine/launcher/args/args.go b/engine/launcher/args/args.go index 124dfdb82c..ddc52c0d0a 100644 --- a/engine/launcher/args/args.go +++ b/engine/launcher/args/args.go @@ -64,6 +64,8 @@ type EngineServerArgs struct { // To restart the current API containers after the engine has been restarted RestartAPIContainers bool `json:"restart_api_containers"` + + ImageAuthor string `json:"image_author"` } var skipValidation = map[string]bool{ @@ -108,6 +110,7 @@ func NewEngineServerArgs( grpcListenPortNum uint16, logLevelStr string, imageVersionTag string, + imageRepository string, metricsUserID string, didUserAcceptSendingMetrics bool, kurtosisBackendType KurtosisBackendType, @@ -140,6 +143,7 @@ func NewEngineServerArgs( CloudInstanceID: cloudInstanceID, AllowedCORSOrigins: allowedCORSOrigins, RestartAPIContainers: restartAPIContainers, + ImageAuthor: imageRepository, } if err := result.validate(); err != nil { return nil, stacktrace.Propagate(err, "An error occurred validating engine server args") diff --git a/engine/launcher/engine_server_launcher/engine_server_launcher.go b/engine/launcher/engine_server_launcher/engine_server_launcher.go index 9aa8a17acd..4b59f0e5e8 100644 --- a/engine/launcher/engine_server_launcher/engine_server_launcher.go +++ b/engine/launcher/engine_server_launcher/engine_server_launcher.go @@ -19,7 +19,9 @@ import ( const ( // TODO This should come from the same logic that builds the server image!!!!! - containerImage = "kurtosistech/engine" + defaultImageAuthor = "kurtosistech" + authorImageNameSeparator = "/" + engineImageName = "engine" ) type EngineServerLauncher struct { @@ -98,6 +100,52 @@ func (launcher *EngineServerLauncher) LaunchWithCustomVersion( resultPublicIpAddr net.IP, resultPublicGrpcPortSpec *port_spec.PortSpec, resultErr error, +) { + return launcher.LaunchWithCustomImageAuthor( + ctx, + imageVersionTag, + defaultImageAuthor, + logLevel, + grpcListenPortNum, + metricsUserID, + didUserAcceptSendingMetrics, + backendConfigSupplier, + onBastionHost, + poolSize, + enclaveEnvVars, + isCI, + cloudUserID, + cloudInstanceID, + allowedCORSOrigins, + shouldStartInDebugMode, + githubAuthToken, + restartAPIContainers, + ) +} + +func (launcher *EngineServerLauncher) LaunchWithCustomImageAuthor( + ctx context.Context, + imageVersionTag string, + imageAuthor string, + logLevel logrus.Level, + grpcListenPortNum uint16, // The port that the engine server will listen on AND the port that it should be bound to on the host machine + metricsUserID string, + didUserAcceptSendingMetrics bool, + backendConfigSupplier KurtosisBackendConfigSupplier, + onBastionHost bool, + poolSize uint8, + enclaveEnvVars string, + isCI bool, + cloudUserID metrics_client.CloudUserID, + cloudInstanceID metrics_client.CloudInstanceID, + allowedCORSOrigins *[]string, + shouldStartInDebugMode bool, + githubAuthToken string, + restartAPIContainers bool, +) ( + resultPublicIpAddr net.IP, + resultPublicGrpcPortSpec *port_spec.PortSpec, + resultErr error, ) { kurtosisBackendType, kurtosisBackendConfig := backendConfigSupplier.getKurtosisBackendConfig() @@ -105,6 +153,7 @@ func (launcher *EngineServerLauncher) LaunchWithCustomVersion( grpcListenPortNum, logLevel.String(), imageVersionTag, + imageAuthor, metricsUserID, didUserAcceptSendingMetrics, kurtosisBackendType, @@ -129,7 +178,7 @@ func (launcher *EngineServerLauncher) LaunchWithCustomVersion( engine, err := launcher.kurtosisBackend.CreateEngine( ctx, - containerImage, + imageAuthor+authorImageNameSeparator+engineImageName, imageVersionTag, grpcListenPortNum, envVars, diff --git a/engine/server/engine/enclave_manager/enclave_creator.go b/engine/server/engine/enclave_manager/enclave_creator.go index a736ea7883..8a51a2c5c0 100644 --- a/engine/server/engine/enclave_manager/enclave_creator.go +++ b/engine/server/engine/enclave_manager/enclave_creator.go @@ -37,6 +37,7 @@ func newEnclaveCreator( func (creator *EnclaveCreator) CreateEnclave( setupCtx context.Context, + imageAuthor string, // If blank, will use the default apiContainerImageVersionTag string, apiContainerLogLevel logrus.Level, @@ -101,6 +102,7 @@ func (creator *EnclaveCreator) CreateEnclave( } apiContainer, err := creator.LaunchApiContainer(setupCtx, + imageAuthor, apiContainerImageVersionTag, apiContainerLogLevel, enclaveUuid, @@ -187,6 +189,7 @@ func (creator *EnclaveCreator) CreateEnclave( func (creator *EnclaveCreator) LaunchApiContainer( ctx context.Context, + imageAuthor string, apiContainerImageVersionTag string, logLevel logrus.Level, enclaveUuid enclave.EnclaveUUID, @@ -207,9 +210,10 @@ func (creator *EnclaveCreator) LaunchApiContainer( creator.kurtosisBackend, ) if apiContainerImageVersionTag != "" { - apiContainer, err := apiContainerLauncher.LaunchWithCustomVersion( + apiContainer, err := apiContainerLauncher.LaunchWithCustomImageAuthor( ctx, apiContainerImageVersionTag, + imageAuthor, logLevel, enclaveUuid, grpcListenPort, diff --git a/engine/server/engine/enclave_manager/enclave_manager.go b/engine/server/engine/enclave_manager/enclave_manager.go index fbb64957bd..5fc36a6b46 100644 --- a/engine/server/engine/enclave_manager/enclave_manager.go +++ b/engine/server/engine/enclave_manager/enclave_manager.go @@ -35,6 +35,8 @@ const ( errorDelimiter = ", " enclaveNameNotFound = "Name Not Found" + + defaultImageAuthor = "kurtosistech" ) // TODO Move this to the KurtosisBackend to calculate!! @@ -132,6 +134,7 @@ func (manager *EnclaveManager) CreateEnclave( setupCtx context.Context, // If blank, will use the default engineVersion string, + imageAuthor string, apiContainerImageVersionTag string, apiContainerLogLevel logrus.Level, //If blank, will use a random one @@ -167,7 +170,9 @@ func (manager *EnclaveManager) CreateEnclave( } // TODO(victor.colombo): Extend enclave pool to have warm production enclaves - if !isProduction && manager.enclavePool != nil { + // if the image author is default only then we use the pooling + // TODO(gm) fix t his + if (imageAuthor == defaultImageAuthor) && !isProduction && manager.enclavePool != nil { enclaveInfo, err = manager.enclavePool.GetEnclave( setupCtx, enclaveName, @@ -181,9 +186,16 @@ func (manager *EnclaveManager) CreateEnclave( } } + // if the api container version isn't set and the engine author isn't kurtosistech we set it to the + // engine version passed; otherwise try user passed version with custom author + if imageAuthor != defaultImageAuthor && apiContainerImageVersionTag == "" { + apiContainerImageVersionTag = engineVersion + } + if enclaveInfo == nil { enclaveInfo, err = manager.enclaveCreator.CreateEnclave( setupCtx, + imageAuthor, apiContainerImageVersionTag, apiContainerLogLevel, enclaveName, @@ -414,6 +426,7 @@ func (manager *EnclaveManager) RestartAllEnclaveAPIContainers(ctx context.Contex // this way we are going to use always the same engine's version useDefaultApiContainerVersionTag := "" + useDefaultImageAuthor := "kurtosistech" //TODO check if we can get this one from any place, just using the default for now restartAPIContainerDefaultLogLevel := logrus.DebugLevel @@ -424,6 +437,7 @@ func (manager *EnclaveManager) RestartAllEnclaveAPIContainers(ctx context.Contex _, err := manager.enclaveCreator.LaunchApiContainer( ctx, + useDefaultImageAuthor, useDefaultApiContainerVersionTag, restartAPIContainerDefaultLogLevel, enclaveUuid, diff --git a/engine/server/engine/enclave_manager/enclave_pool.go b/engine/server/engine/enclave_manager/enclave_pool.go index 5acd2d3f4f..f97b660e96 100644 --- a/engine/server/engine/enclave_manager/enclave_pool.go +++ b/engine/server/engine/enclave_manager/enclave_pool.go @@ -283,6 +283,7 @@ func (pool *EnclavePool) createNewIdleEnclave(ctx context.Context) (*types.Encla newEnclaveInfo, err := pool.enclaveCreator.CreateEnclave( ctx, + defaultImageAuthor, apiContainerVersion, defaultApiContainerLogLevel, enclaveName, diff --git a/engine/server/engine/main.go b/engine/server/engine/main.go index 262d38768f..f08af011ee 100644 --- a/engine/server/engine/main.go +++ b/engine/server/engine/main.go @@ -285,6 +285,7 @@ func runMain() error { engineConnectServer := server.NewEngineConnectServerService( serverArgs.ImageVersionTag, + serverArgs.ImageAuthor, enclaveManager, serverArgs.MetricsUserID, serverArgs.DidUserAcceptSendingMetrics, @@ -449,6 +450,7 @@ func restApiServer( EnclaveManager: enclave_manager, LogFileManager: logFileManager, MetricsClient: metricsClient, + ImageAuthor: serverArgs.ImageAuthor, } engineApi.RegisterHandlers(echoApiRouter, engineApi.NewStrictHandler(engineRuntime, nil)) diff --git a/engine/server/engine/server/engine_connect_server_service.go b/engine/server/engine/server/engine_connect_server_service.go index 3fc908e916..3b4bcee25c 100644 --- a/engine/server/engine/server/engine_connect_server_service.go +++ b/engine/server/engine/server/engine_connect_server_service.go @@ -30,6 +30,9 @@ type EngineConnectServerService struct { // The version tag of the engine server image, so it can report its own version imageVersionTag string + // The author of the image of the engine + imageAuthor string + enclaveManager *enclave_manager.EnclaveManager // The protected user ID for metrics analytics purpose @@ -48,6 +51,7 @@ type EngineConnectServerService struct { func NewEngineConnectServerService( imageVersionTag string, + imageAuthor string, enclaveManager *enclave_manager.EnclaveManager, metricsUserId string, didUserAcceptSendingMetrics bool, @@ -57,6 +61,7 @@ func NewEngineConnectServerService( ) *EngineConnectServerService { service := &EngineConnectServerService{ imageVersionTag: imageVersionTag, + imageAuthor: imageAuthor, enclaveManager: enclaveManager, metricsUserID: metricsUserId, didUserAcceptSendingMetrics: didUserAcceptSendingMetrics, @@ -183,6 +188,7 @@ func (service *EngineConnectServerService) CreateEnclave(ctx context.Context, co enclaveInfo, err := service.enclaveManager.CreateEnclave( ctx, service.imageVersionTag, + service.imageAuthor, args.GetApiContainerVersionTag(), apiContainerLogLevel, args.GetEnclaveName(), diff --git a/engine/server/engine/server/engine_rest_api_handler.go b/engine/server/engine/server/engine_rest_api_handler.go index e7f9665024..c1be66dbcc 100644 --- a/engine/server/engine/server/engine_rest_api_handler.go +++ b/engine/server/engine/server/engine_rest_api_handler.go @@ -21,6 +21,9 @@ type EngineRuntime struct { // The version tag of the engine server image, so it can report its own version ImageVersionTag string + // The Author of the image + ImageAuthor string + EnclaveManager *enclave_manager.EnclaveManager LogFileManager *log_file_manager.LogFileManager @@ -103,6 +106,7 @@ func (engine EngineRuntime) PostEnclaves(ctx context.Context, request api.PostEn enclaveInfo, err := engine.EnclaveManager.CreateEnclave( ctx, engine.ImageVersionTag, + engine.ImageAuthor, apicVersionTag, apiContainerLogLevel, enclaveName,