diff --git a/pkg/microservice/aslan/core/common/util/service.go b/pkg/microservice/aslan/core/common/util/service.go index 173b412dca..1a64822f09 100644 --- a/pkg/microservice/aslan/core/common/util/service.go +++ b/pkg/microservice/aslan/core/common/util/service.go @@ -111,6 +111,29 @@ func FoldManualModulesInto(autos []*commonmodels.Container, manuals []*commonmod return autos } +// OverrideContainerImagesByName updates image fields for containers already +// present in the target slice. Overrides with unknown names or unresolved +// images are ignored. +func OverrideContainerImagesByName(containers, overrides []*commonmodels.Container) { + containerByName := make(map[string]*commonmodels.Container, len(containers)) + for _, container := range containers { + if container == nil || container.Name == "" { + continue + } + containerByName[container.Name] = container + } + + for _, override := range overrides { + if override == nil || override.Image == "" || IsModuleImagePlaceholder(override.Image) { + continue + } + if container, ok := containerByName[override.Name]; ok { + container.Image = override.Image + container.ImageName = override.ImageName + } + } +} + func GetServiceDeployStrategy(serviceName string, strategyMap map[string]setting.ServiceDeployStrategy) setting.ServiceDeployStrategy { if strategyMap == nil { return setting.ServiceDeployStrategyDeploy diff --git a/pkg/microservice/aslan/core/environment/service/environment.go b/pkg/microservice/aslan/core/environment/service/environment.go index fe1edb5c0e..bf9f62a1f9 100644 --- a/pkg/microservice/aslan/core/environment/service/environment.go +++ b/pkg/microservice/aslan/core/environment/service/environment.go @@ -3076,15 +3076,12 @@ func upsertService(env *commonmodels.Product, newService *commonmodels.ProductSe if prevSvc == nil { fakeTemplateSvc := &commonmodels.Service{ServiceName: newService.ServiceName, ProductName: newService.ServiceName, KubeYamls: util.SplitYaml(parsedYaml)} commonutil.SetCurrentContainerImages(fakeTemplateSvc) - // Merge instead of overwrite. fakeTemplateSvc.Containers is the - // auto set re-parsed from the just-rendered YAML — authoritative - // for env-resolved image values on Deployment/StatefulSet/etc. - // newService.Containers came in from the caller already carrying - // manual modules (CRD/DaemonSet declarations), so blindly clobbering - // it would drop those manuals — and for ConfigMap/CRD-only services - // fakeTemplateSvc.Containers is empty, which would persist an empty - // Containers slice into ProductService and break later renders. - newService.Containers = commonutil.FoldManualModulesInto(fakeTemplateSvc.Containers, newService.Containers) + // Keep the revision's module list (service_module) authoritative: a + // container that only appears in the rendered YAML — e.g. a deleted + // component still present in the template — is intentionally not added + // back. The YAML is used only to refresh images for containers that + // already exist in the module list. + commonutil.OverrideContainerImagesByName(newService.Containers, fakeTemplateSvc.Containers) } preResourceYaml := ""