detached ad19cc0

Merge pull request #192 from bnema/fix/podman-restart-policy-create-time

Keep restart policy creation compatible with Podman
commit
ad19cc00ded52f755bd7bfea4834a799890298ea
author
bnema · · 2026-05-05 18:27 UTC
committer
GitHub · · 2026-05-05 18:27 UTC
merge of
3751047 + 482a736 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
2 files · +20 -82
M internal/usecase/container/service.go +17 -35
@@ -275,18 +275,19 @@ func (s *Service) buildContainerConfig(in containerConfigInput) *domain.Containe
275275 }
276276
277277 containerConfig := &domain.ContainerConfig{
278- Image: in.ImageRef,
279- Name: containerName,
280- Ports: ports,
281- Env: in.EnvVars,
282- Volumes: in.Volumes,
283- NetworkMode: in.NetworkName,
284- Hostname: in.Domain,
285- Labels: labels,
286- AutoRemove: false,
287- MemoryLimit: cfg.DefaultMemoryLimit,
288- NanoCPUs: cfg.DefaultNanoCPUs,
289- PidsLimit: cfg.DefaultPidsLimit,
278+ Image: in.ImageRef,
279+ Name: containerName,
280+ Ports: ports,
281+ Env: in.EnvVars,
282+ Volumes: in.Volumes,
283+ NetworkMode: in.NetworkName,
284+ Hostname: in.Domain,
285+ Labels: labels,
286+ AutoRemove: false,
287+ RestartPolicy: domain.RestartPolicyAlways,
288+ MemoryLimit: cfg.DefaultMemoryLimit,
289+ NanoCPUs: cfg.DefaultNanoCPUs,
290+ PidsLimit: cfg.DefaultPidsLimit,
290291 }
291292 applySecurityProfile(containerConfig, cfg)
292293 return containerConfig
@@ -654,10 +655,6 @@ func (s *Service) createStartedContainer(ctx context.Context, route domain.Route
654655 return nil, deployErr
655656 }
656657 }
657- if err := s.runtime.EnsureContainerRestartPolicy(ctx, newContainer.ID, domain.RestartPolicyAlways); err != nil {
658- s.cleanupFailedContainer(ctx, newContainer.ID)
659- return nil, log.WrapErr(err, "failed to set container restart policy")
660- }
661658
662659 inspected, err := s.runtime.InspectContainer(ctx, newContainer.ID)
663660 if err != nil {
@@ -2646,10 +2643,6 @@ func (s *Service) deployAttachedService(ctx context.Context, ownerDomain, servic
26462643 s.runtime.RemoveContainer(ctx, container.ID, true)
26472644 return fmt.Errorf("attachment %q not ready: %w", serviceName, err)
26482645 }
2649- if err := s.ensureAttachmentRestartPolicy(ctx, container.ID); err != nil {
2650- return err
2651- }
2652-
26532646 // Track attachment
26542647 s.mu.Lock()
26552648 s.attachments[ownerDomain] = append(s.attachments[ownerDomain], container.ID)
@@ -2702,26 +2695,15 @@ func (s *Service) buildAttachmentContainerConfig(ctx context.Context, ownerDomai
27022695 domain.LabelEnvHash: hashEnvironment(envVars),
27032696 domain.LabelImage: serviceImage,
27042697 },
2705- MemoryLimit: cfg.DefaultMemoryLimit,
2706- NanoCPUs: cfg.DefaultNanoCPUs,
2707- PidsLimit: cfg.DefaultPidsLimit,
2698+ MemoryLimit: cfg.DefaultMemoryLimit,
2699+ NanoCPUs: cfg.DefaultNanoCPUs,
2700+ PidsLimit: cfg.DefaultPidsLimit,
2701+ RestartPolicy: domain.RestartPolicyAlways,
27082702 }
27092703 applySecurityProfile(config, cfg)
27102704 return config, nil
27112705 }
27122706
2713-func (s *Service) ensureAttachmentRestartPolicy(ctx context.Context, containerID string) error {
2714- log := zerowrap.FromCtx(ctx)
2715- if err := s.runtime.EnsureContainerRestartPolicy(ctx, containerID, domain.RestartPolicyAlways); err != nil {
2716- if stopErr := s.runtime.StopContainer(ctx, containerID); stopErr != nil {
2717- log.Warn().Err(stopErr).Str(zerowrap.FieldEntityID, containerID).Msg("failed to stop attachment after restart policy update failure")
2718- }
2719- s.runtime.RemoveContainer(ctx, containerID, true)
2720- return log.WrapErr(err, "failed to set attachment restart policy")
2721- }
2722- return nil
2723-}
2724-
27252707 func (s *Service) attachmentExposedPorts(ctx context.Context, imageRef string) []int {
27262708 log := zerowrap.FromCtx(ctx)
27272709 exposedPorts, err := s.runtime.GetImageExposedPorts(ctx, imageRef)
@@ -275,18 +275,19 @@ func (s *Service) buildContainerConfig(in containerConfigInput) *domain.Containe
275 }275 }
276 276
277 containerConfig := &domain.ContainerConfig{277 containerConfig := &domain.ContainerConfig{
278- Image: in.ImageRef,278+ Image: in.ImageRef,
279- Name: containerName,279+ Name: containerName,
280- Ports: ports,280+ Ports: ports,
281- Env: in.EnvVars,281+ Env: in.EnvVars,
282- Volumes: in.Volumes,282+ Volumes: in.Volumes,
283- NetworkMode: in.NetworkName,283+ NetworkMode: in.NetworkName,
284- Hostname: in.Domain,284+ Hostname: in.Domain,
285- Labels: labels,285+ Labels: labels,
286- AutoRemove: false,286+ AutoRemove: false,
287- MemoryLimit: cfg.DefaultMemoryLimit,287+ RestartPolicy: domain.RestartPolicyAlways,
288- NanoCPUs: cfg.DefaultNanoCPUs,288+ MemoryLimit: cfg.DefaultMemoryLimit,
289- PidsLimit: cfg.DefaultPidsLimit,289+ NanoCPUs: cfg.DefaultNanoCPUs,
290+ PidsLimit: cfg.DefaultPidsLimit,
290 }291 }
291 applySecurityProfile(containerConfig, cfg)292 applySecurityProfile(containerConfig, cfg)
292 return containerConfig293 return containerConfig
@@ -654,10 +655,6 @@ func (s *Service) createStartedContainer(ctx context.Context, route domain.Route
654 return nil, deployErr655 return nil, deployErr
655 }656 }
656 }657 }
657- if err := s.runtime.EnsureContainerRestartPolicy(ctx, newContainer.ID, domain.RestartPolicyAlways); err != nil {
658- s.cleanupFailedContainer(ctx, newContainer.ID)
659- return nil, log.WrapErr(err, "failed to set container restart policy")
660- }
661 658
662 inspected, err := s.runtime.InspectContainer(ctx, newContainer.ID)659 inspected, err := s.runtime.InspectContainer(ctx, newContainer.ID)
663 if err != nil {660 if err != nil {
@@ -2646,10 +2643,6 @@ func (s *Service) deployAttachedService(ctx context.Context, ownerDomain, servic
2646 s.runtime.RemoveContainer(ctx, container.ID, true)2643 s.runtime.RemoveContainer(ctx, container.ID, true)
2647 return fmt.Errorf("attachment %q not ready: %w", serviceName, err)2644 return fmt.Errorf("attachment %q not ready: %w", serviceName, err)
2648 }2645 }
2649- if err := s.ensureAttachmentRestartPolicy(ctx, container.ID); err != nil {
2650- return err
2651- }
2652-
2653 // Track attachment2646 // Track attachment
2654 s.mu.Lock()2647 s.mu.Lock()
2655 s.attachments[ownerDomain] = append(s.attachments[ownerDomain], container.ID)2648 s.attachments[ownerDomain] = append(s.attachments[ownerDomain], container.ID)
@@ -2702,26 +2695,15 @@ func (s *Service) buildAttachmentContainerConfig(ctx context.Context, ownerDomai
2702 domain.LabelEnvHash: hashEnvironment(envVars),2695 domain.LabelEnvHash: hashEnvironment(envVars),
2703 domain.LabelImage: serviceImage,2696 domain.LabelImage: serviceImage,
2704 },2697 },
2705- MemoryLimit: cfg.DefaultMemoryLimit,2698+ MemoryLimit: cfg.DefaultMemoryLimit,
2706- NanoCPUs: cfg.DefaultNanoCPUs,2699+ NanoCPUs: cfg.DefaultNanoCPUs,
2707- PidsLimit: cfg.DefaultPidsLimit,2700+ PidsLimit: cfg.DefaultPidsLimit,
2701+ RestartPolicy: domain.RestartPolicyAlways,
2708 }2702 }
2709 applySecurityProfile(config, cfg)2703 applySecurityProfile(config, cfg)
2710 return config, nil2704 return config, nil
2711 }2705 }
2712 2706
2713-func (s *Service) ensureAttachmentRestartPolicy(ctx context.Context, containerID string) error {
2714- log := zerowrap.FromCtx(ctx)
2715- if err := s.runtime.EnsureContainerRestartPolicy(ctx, containerID, domain.RestartPolicyAlways); err != nil {
2716- if stopErr := s.runtime.StopContainer(ctx, containerID); stopErr != nil {
2717- log.Warn().Err(stopErr).Str(zerowrap.FieldEntityID, containerID).Msg("failed to stop attachment after restart policy update failure")
2718- }
2719- s.runtime.RemoveContainer(ctx, containerID, true)
2720- return log.WrapErr(err, "failed to set attachment restart policy")
2721- }
2722- return nil
2723-}
2724-
2725 func (s *Service) attachmentExposedPorts(ctx context.Context, imageRef string) []int {2707 func (s *Service) attachmentExposedPorts(ctx context.Context, imageRef string) []int {
2726 log := zerowrap.FromCtx(ctx)2708 log := zerowrap.FromCtx(ctx)
2727 exposedPorts, err := s.runtime.GetImageExposedPorts(ctx, imageRef)2709 exposedPorts, err := s.runtime.GetImageExposedPorts(ctx, imageRef)
M internal/usecase/container/service_test.go +3 -47
@@ -57,11 +57,6 @@ func testMinDelayConfig() Config {
5757 }
5858 }
5959
60-func allowRestartPolicyEnsure(t *testing.T, runtime *mocks.MockContainerRuntime) {
61- t.Helper()
62- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, mock.Anything, domain.RestartPolicyAlways).Return(nil).Maybe()
63-}
64-
6560 func setupMetricsTest(t *testing.T) (*telemetry.Metrics, *sdkmetric.ManualReader) {
6661 t.Helper()
6762
@@ -382,8 +377,6 @@ func TestService_Deploy_Success(t *testing.T) {
382377 // Wait for ready: IsContainerRunning (first check returns true) + verify after delay
383378 runtime.EXPECT().IsContainerRunning(mock.Anything, "container-123").Return(true, nil).Times(2)
384379
385- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, "container-123", domain.RestartPolicyAlways).Return(nil).Once()
386-
387380 // Re-inspect after start
388381 runningContainer := &domain.Container{
389382 ID: "container-123",
@@ -412,7 +405,6 @@ func TestService_Deploy_Success(t *testing.T) {
412405
413406 func TestService_Deploy_ReadinessRecoveryWindow_AllowsTransientFlap(t *testing.T) {
414407 runtime := mocks.NewMockContainerRuntime(t)
415- allowRestartPolicyEnsure(t, runtime)
416408 envLoader := mocks.NewMockEnvLoader(t)
417409 eventBus := mocks.NewMockEventPublisher(t)
418410
@@ -479,7 +471,6 @@ func TestService_Deploy_ReadinessRecoveryWindow_AllowsTransientFlap(t *testing.T
479471
480472 func TestService_Deploy_ImagePullFailure(t *testing.T) {
481473 runtime := mocks.NewMockContainerRuntime(t)
482- allowRestartPolicyEnsure(t, runtime)
483474 envLoader := mocks.NewMockEnvLoader(t)
484475 eventBus := mocks.NewMockEventPublisher(t)
485476
@@ -522,7 +513,6 @@ func TestIsPullFailure_ErrImagePullFailed(t *testing.T) {
522513
523514 func TestService_Deploy_DoesNotMisclassifyUnauthorizedEnvLoadFailure(t *testing.T) {
524515 runtime := mocks.NewMockContainerRuntime(t)
525- allowRestartPolicyEnsure(t, runtime)
526516 envLoader := mocks.NewMockEnvLoader(t)
527517 eventBus := mocks.NewMockEventPublisher(t)
528518
@@ -563,7 +553,6 @@ func TestService_CaptureRecentContainerLogs_SkipsCanceledContext(t *testing.T) {
563553
564554 func TestService_Deploy_ReadinessFailureReturnsDeployFailureWithLogs(t *testing.T) {
565555 runtime := mocks.NewMockContainerRuntime(t)
566- allowRestartPolicyEnsure(t, runtime)
567556 envLoader := mocks.NewMockEnvLoader(t)
568557 eventBus := mocks.NewMockEventPublisher(t)
569558
@@ -623,7 +612,6 @@ func TestService_Deploy_ReadinessFailureReturnsDeployFailureWithLogs(t *testing.
623612
624613 func TestService_Deploy_StrictHealthModeWithoutHealthcheckReturnsHint(t *testing.T) {
625614 runtime := mocks.NewMockContainerRuntime(t)
626- allowRestartPolicyEnsure(t, runtime)
627615 envLoader := mocks.NewMockEnvLoader(t)
628616 eventBus := mocks.NewMockEventPublisher(t)
629617
@@ -735,7 +723,6 @@ func TestService_PullImage_InternalRetriesOnConnectionRefused(t *testing.T) {
735723
736724 func TestService_Deploy_ReplacesExistingContainer(t *testing.T) {
737725 runtime := mocks.NewMockContainerRuntime(t)
738- allowRestartPolicyEnsure(t, runtime)
739726 envLoader := mocks.NewMockEnvLoader(t)
740727 eventBus := mocks.NewMockEventPublisher(t)
741728 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -819,7 +806,6 @@ func TestService_Deploy_ReplacesExistingContainer(t *testing.T) {
819806 // from killing the real active container after a Gordon restart.
820807 func TestService_Deploy_ResolvesExistingFromRuntime_WhenMemoryStale(t *testing.T) {
821808 runtime := mocks.NewMockContainerRuntime(t)
822- allowRestartPolicyEnsure(t, runtime)
823809 envLoader := mocks.NewMockEnvLoader(t)
824810 eventBus := mocks.NewMockEventPublisher(t)
825811 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -919,7 +905,6 @@ func TestService_Deploy_ResolvesExistingFromRuntime_WhenMemoryStale(t *testing.T
919905
920906 func TestService_Deploy_SkipRedundantDeploy_GetImageIDError(t *testing.T) {
921907 runtime := mocks.NewMockContainerRuntime(t)
922- allowRestartPolicyEnsure(t, runtime)
923908 envLoader := mocks.NewMockEnvLoader(t)
924909 eventBus := mocks.NewMockEventPublisher(t)
925910
@@ -982,7 +967,6 @@ func TestService_Deploy_SkipRedundantDeploy_GetImageIDError(t *testing.T) {
982967
983968 func TestService_Deploy_WithNetworkIsolation(t *testing.T) {
984969 runtime := mocks.NewMockContainerRuntime(t)
985- allowRestartPolicyEnsure(t, runtime)
986970 envLoader := mocks.NewMockEnvLoader(t)
987971 eventBus := mocks.NewMockEventPublisher(t)
988972
@@ -1041,7 +1025,6 @@ func TestService_Deploy_WithNetworkIsolation(t *testing.T) {
10411025
10421026 func TestService_Deploy_WithVolumeAutoCreate(t *testing.T) {
10431027 runtime := mocks.NewMockContainerRuntime(t)
1044- allowRestartPolicyEnsure(t, runtime)
10451028 envLoader := mocks.NewMockEnvLoader(t)
10461029 eventBus := mocks.NewMockEventPublisher(t)
10471030
@@ -2055,7 +2038,6 @@ func TestRewriteToLocalRegistry(t *testing.T) {
20552038
20562039 func TestService_Deploy_InternalDeployForcesPull(t *testing.T) {
20572040 runtime := mocks.NewMockContainerRuntime(t)
2058- allowRestartPolicyEnsure(t, runtime)
20592041 envLoader := mocks.NewMockEnvLoader(t)
20602042 eventBus := mocks.NewMockEventPublisher(t)
20612043
@@ -2136,7 +2118,6 @@ func TestService_Deploy_InternalDeployForcesPull(t *testing.T) {
21362118
21372119 func TestService_AutoStart_StartsNewContainers(t *testing.T) {
21382120 runtime := mocks.NewMockContainerRuntime(t)
2139- allowRestartPolicyEnsure(t, runtime)
21402121 envLoader := mocks.NewMockEnvLoader(t)
21412122 eventBus := mocks.NewMockEventPublisher(t)
21422123
@@ -2186,7 +2167,6 @@ func TestService_AutoStart_StartsNewContainers(t *testing.T) {
21862167
21872168 func TestService_AutoStart_SkipsExistingContainers(t *testing.T) {
21882169 runtime := mocks.NewMockContainerRuntime(t)
2189- allowRestartPolicyEnsure(t, runtime)
21902170 envLoader := mocks.NewMockEnvLoader(t)
21912171 eventBus := mocks.NewMockEventPublisher(t)
21922172
@@ -2236,7 +2216,6 @@ func TestService_AutoStart_SkipsExistingContainers(t *testing.T) {
22362216
22372217 func TestService_AutoStart_HandlesDeployErrors(t *testing.T) {
22382218 runtime := mocks.NewMockContainerRuntime(t)
2239- allowRestartPolicyEnsure(t, runtime)
22402219 envLoader := mocks.NewMockEnvLoader(t)
22412220 eventBus := mocks.NewMockEventPublisher(t)
22422221
@@ -2265,7 +2244,6 @@ func TestService_AutoStart_HandlesDeployErrors(t *testing.T) {
22652244
22662245 func TestService_AutoStart_UsesInternalDeployContext(t *testing.T) {
22672246 runtime := mocks.NewMockContainerRuntime(t)
2268- allowRestartPolicyEnsure(t, runtime)
22692247 envLoader := mocks.NewMockEnvLoader(t)
22702248 eventBus := mocks.NewMockEventPublisher(t)
22712249
@@ -2318,7 +2296,6 @@ func TestService_AutoStart_UsesInternalDeployContext(t *testing.T) {
23182296 // until the new container is ready and traffic is switched.
23192297 func TestService_Deploy_OrphanCleanupSkipsTrackedContainer(t *testing.T) {
23202298 runtime := mocks.NewMockContainerRuntime(t)
2321- allowRestartPolicyEnsure(t, runtime)
23222299 envLoader := mocks.NewMockEnvLoader(t)
23232300 eventBus := mocks.NewMockEventPublisher(t)
23242301 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2415,7 +2392,6 @@ func TestService_Deploy_OrphanCleanupSkipsTrackedContainer(t *testing.T) {
24152392 // Running canonical containers are preserved (see NeverKillsRunningCanonical test).
24162393 func TestService_Deploy_OrphanCleanupRemovesTrueOrphans(t *testing.T) {
24172394 runtime := mocks.NewMockContainerRuntime(t)
2418- allowRestartPolicyEnsure(t, runtime)
24192395 envLoader := mocks.NewMockEnvLoader(t)
24202396 eventBus := mocks.NewMockEventPublisher(t)
24212397
@@ -2496,7 +2472,6 @@ func TestService_Deploy_OrphanCleanupRemovesTrueOrphans(t *testing.T) {
24962472
24972473 func TestService_Deploy_OrphanCleanupRemovesStaleNewContainer(t *testing.T) {
24982474 runtime := mocks.NewMockContainerRuntime(t)
2499- allowRestartPolicyEnsure(t, runtime)
25002475 envLoader := mocks.NewMockEnvLoader(t)
25012476 eventBus := mocks.NewMockEventPublisher(t)
25022477 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2569,7 +2544,6 @@ func TestService_Deploy_OrphanCleanupRemovesStaleNewContainer(t *testing.T) {
25692544
25702545 func TestService_Deploy_TrackedTempContainerUsesAlternateTempName(t *testing.T) {
25712546 runtime := mocks.NewMockContainerRuntime(t)
2572- allowRestartPolicyEnsure(t, runtime)
25732547 envLoader := mocks.NewMockEnvLoader(t)
25742548 eventBus := mocks.NewMockEventPublisher(t)
25752549 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2759,7 +2733,6 @@ func TestService_Deploy_ConcurrentSameDomain(t *testing.T) {
27592733 // Verify that concurrent Deploy calls for the same domain are serialized
27602734 // and both succeed without container name conflicts.
27612735 runtime := mocks.NewMockContainerRuntime(t)
2762- allowRestartPolicyEnsure(t, runtime)
27632736 envLoader := mocks.NewMockEnvLoader(t)
27642737 eventBus := mocks.NewMockEventPublisher(t)
27652738 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2870,7 +2843,6 @@ func TestService_Deploy_ConcurrentSameDomain(t *testing.T) {
28702843 func TestService_Deploy_ContextCancellation(t *testing.T) {
28712844 // Verify that deploy lock acquisition respects context cancellation.
28722845 runtime := mocks.NewMockContainerRuntime(t)
2873- allowRestartPolicyEnsure(t, runtime)
28742846 envLoader := mocks.NewMockEnvLoader(t)
28752847 eventBus := mocks.NewMockEventPublisher(t)
28762848
@@ -2901,7 +2873,6 @@ func TestService_Deploy_ContextCancellation(t *testing.T) {
29012873 // BEFORE the old container is stopped, preventing 503 errors during deployment.
29022874 func TestService_Deploy_CacheInvalidationBeforeOldContainerStop(t *testing.T) {
29032875 runtime := mocks.NewMockContainerRuntime(t)
2904- allowRestartPolicyEnsure(t, runtime)
29052876 envLoader := mocks.NewMockEnvLoader(t)
29062877 eventBus := mocks.NewMockEventPublisher(t)
29072878 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2982,7 +2953,6 @@ func TestService_Deploy_CacheInvalidationBeforeOldContainerStop(t *testing.T) {
29822953 // when no cache invalidator is set (e.g., in tests or minimal configurations).
29832954 func TestService_Deploy_NilCacheInvalidator(t *testing.T) {
29842955 runtime := mocks.NewMockContainerRuntime(t)
2985- allowRestartPolicyEnsure(t, runtime)
29862956 envLoader := mocks.NewMockEnvLoader(t)
29872957 eventBus := mocks.NewMockEventPublisher(t)
29882958
@@ -3032,7 +3002,6 @@ func TestService_Deploy_NilCacheInvalidator(t *testing.T) {
30323002
30333003 func TestService_Deploy_SkipsRedundantDeploy(t *testing.T) {
30343004 runtime := mocks.NewMockContainerRuntime(t)
3035- allowRestartPolicyEnsure(t, runtime)
30363005 envLoader := mocks.NewMockEnvLoader(t)
30373006 eventBus := mocks.NewMockEventPublisher(t)
30383007
@@ -3093,7 +3062,6 @@ func TestService_Deploy_SkipsRedundantDeploy(t *testing.T) {
30933062
30943063 func TestService_Deploy_SkipsRedundantDeploy_WhenTrackedImageIDMissing(t *testing.T) {
30953064 runtime := mocks.NewMockContainerRuntime(t)
3096- allowRestartPolicyEnsure(t, runtime)
30973065 envLoader := mocks.NewMockEnvLoader(t)
30983066 eventBus := mocks.NewMockEventPublisher(t)
30993067
@@ -3155,7 +3123,6 @@ func TestService_Deploy_SkipsRedundantDeploy_WhenTrackedImageIDMissing(t *testin
31553123
31563124 func TestService_Deploy_DoesNotSkipWhenImageIDDiffers(t *testing.T) {
31573125 runtime := mocks.NewMockContainerRuntime(t)
3158- allowRestartPolicyEnsure(t, runtime)
31593126 envLoader := mocks.NewMockEnvLoader(t)
31603127 eventBus := mocks.NewMockEventPublisher(t)
31613128 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3258,7 +3225,6 @@ func TestSyncContainersRebuildsAttachmentMap(t *testing.T) {
32583225
32593226 func TestService_Deploy_SkipRedundantDeploy_ContainerNotRunning(t *testing.T) {
32603227 runtime := mocks.NewMockContainerRuntime(t)
3261- allowRestartPolicyEnsure(t, runtime)
32623228 envLoader := mocks.NewMockEnvLoader(t)
32633229 eventBus := mocks.NewMockEventPublisher(t)
32643230
@@ -3322,7 +3288,6 @@ func TestService_Deploy_SkipRedundantDeploy_ContainerNotRunning(t *testing.T) {
33223288
33233289 func TestService_Deploy_DoesNotSkip_WhenEnvHashDiffers(t *testing.T) {
33243290 runtime := mocks.NewMockContainerRuntime(t)
3325- allowRestartPolicyEnsure(t, runtime)
33263291 envLoader := mocks.NewMockEnvLoader(t)
33273292 eventBus := mocks.NewMockEventPublisher(t)
33283293
@@ -3381,7 +3346,6 @@ func TestService_Deploy_DoesNotSkip_WhenEnvHashDiffers(t *testing.T) {
33813346
33823347 func TestService_Deploy_DoesNotSkip_WhenEnvHashMissing(t *testing.T) {
33833348 runtime := mocks.NewMockContainerRuntime(t)
3384- allowRestartPolicyEnsure(t, runtime)
33853349 envLoader := mocks.NewMockEnvLoader(t)
33863350 eventBus := mocks.NewMockEventPublisher(t)
33873351
@@ -3508,7 +3472,6 @@ func TestService_attachmentEnvDrifted_ReturnsTrueWhenHashMissing(t *testing.T) {
35083472 // disallows creating a container with the same name as an existing running container.
35093473 func TestService_Deploy_OrphanCleanup_NeverKillsRunningCanonical(t *testing.T) {
35103474 runtime := mocks.NewMockContainerRuntime(t)
3511- allowRestartPolicyEnsure(t, runtime)
35123475 envLoader := mocks.NewMockEnvLoader(t)
35133476 eventBus := mocks.NewMockEventPublisher(t)
35143477
@@ -3605,7 +3568,6 @@ func TestService_Deploy_OrphanCleanup_NeverKillsRunningCanonical(t *testing.T) {
36053568 // and the failed new container is cleaned up.
36063569 func TestService_Deploy_RollbackOnPostSwitchCrash(t *testing.T) {
36073570 runtime := mocks.NewMockContainerRuntime(t)
3608- allowRestartPolicyEnsure(t, runtime)
36093571 envLoader := mocks.NewMockEnvLoader(t)
36103572 eventBus := mocks.NewMockEventPublisher(t)
36113573 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3700,7 +3662,6 @@ func TestService_Deploy_RollbackOnPostSwitchCrash(t *testing.T) {
37003662 // container is finalized (stopped and removed).
37013663 func TestService_Deploy_StabilizationSuccess(t *testing.T) {
37023664 runtime := mocks.NewMockContainerRuntime(t)
3703- allowRestartPolicyEnsure(t, runtime)
37043665 envLoader := mocks.NewMockEnvLoader(t)
37053666 eventBus := mocks.NewMockEventPublisher(t)
37063667 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3789,7 +3750,6 @@ func TestService_Deploy_StabilizationSuccess(t *testing.T) {
37893750 // Uses testify's NotBefore() to enforce mock call ordering.
37903751 func TestService_Deploy_ZeroDowntime_OldNeverStoppedBeforeNewReady(t *testing.T) {
37913752 runtime := mocks.NewMockContainerRuntime(t)
3792- allowRestartPolicyEnsure(t, runtime)
37933753 envLoader := mocks.NewMockEnvLoader(t)
37943754 eventBus := mocks.NewMockEventPublisher(t)
37953755 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3886,7 +3846,6 @@ func TestService_Deploy_ZeroDowntime_OldNeverStoppedBeforeNewReady(t *testing.T)
38863846 // the old container remains as the tracked container.
38873847 func TestService_Deploy_ZeroDowntime_ReadinessFailure_OldUntouched(t *testing.T) {
38883848 runtime := mocks.NewMockContainerRuntime(t)
3889- allowRestartPolicyEnsure(t, runtime)
38903849 envLoader := mocks.NewMockEnvLoader(t)
38913850 eventBus := mocks.NewMockEventPublisher(t)
38923851
@@ -3977,7 +3936,6 @@ func TestService_Deploy_ZeroDowntime_ReadinessFailure_OldUntouched(t *testing.T)
39773936 // finalize/drain logic being triggered.
39783937 func TestService_Deploy_ZeroDowntime_NoExisting_FirstDeploy(t *testing.T) {
39793938 runtime := mocks.NewMockContainerRuntime(t)
3980- allowRestartPolicyEnsure(t, runtime)
39813939 envLoader := mocks.NewMockEnvLoader(t)
39823940 eventBus := mocks.NewMockEventPublisher(t)
39833941
@@ -4054,7 +4012,6 @@ func TestService_Deploy_ZeroDowntime_NoExisting_FirstDeploy(t *testing.T) {
40544012
40554013 func TestService_Deploy_PropagatesImageLabelsToContainerConfig(t *testing.T) {
40564014 runtime := mocks.NewMockContainerRuntime(t)
4057- allowRestartPolicyEnsure(t, runtime)
40584015 envLoader := mocks.NewMockEnvLoader(t)
40594016 eventBus := mocks.NewMockEventPublisher(t)
40604017
@@ -4312,7 +4269,7 @@ func TestDeployAttachedService_SetsAliasOnContainerConfig(t *testing.T) {
43124269 assert.Equal(t, []string{"postgres"}, cfg.Aliases, "attachment container must have network aliases for DNS resolution")
43134270 assert.Equal(t, "postgres", cfg.Hostname)
43144271 assert.Equal(t, networkName, cfg.NetworkMode)
4315- assert.Empty(t, cfg.RestartPolicy)
4272+ assert.Equal(t, domain.RestartPolicyAlways, cfg.RestartPolicy)
43164273 }).
43174274 Return(&domain.Container{ID: "pg-container-1", Name: containerName}, nil)
43184275
@@ -4325,7 +4282,6 @@ func TestDeployAttachedService_SetsAliasOnContainerConfig(t *testing.T) {
43254282 runtime.EXPECT().GetContainerHealthStatus(mock.Anything, "pg-container-1").Return("", false, nil)
43264283 // TCP probe: resolve endpoint fails -> falls back to delay
43274284 runtime.EXPECT().GetContainerNetworkInfo(mock.Anything, "pg-container-1").Return("", 0, errors.New("no network"))
4328- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, "pg-container-1", domain.RestartPolicyAlways).Return(nil).Once()
43294285
43304286 err := svc.deployAttachedService(ctx, ownerDomain, serviceImage, networkName)
43314287 require.NoError(t, err)
@@ -4451,10 +4407,10 @@ func TestService_BuildContainerConfig_CompatSecurityProfileDefault(t *testing.T)
44514407 assert.Nil(t, cfg.CapAdd)
44524408 }
44534409
4454-func TestService_BuildContainerConfig_OmitsRestartPolicyBeforeReadiness(t *testing.T) {
4410+func TestService_BuildContainerConfig_SetsRestartPolicyAlways(t *testing.T) {
44554411 svc := NewService(nil, nil, nil, nil, Config{}, nil)
44564412
44574413 cfg := svc.buildContainerConfig(containerConfigInput{Domain: "app.example.com", Image: "app:latest", ImageRef: "app:latest"})
44584414
4459- assert.Empty(t, cfg.RestartPolicy)
4415+ assert.Equal(t, domain.RestartPolicyAlways, cfg.RestartPolicy)
44604416 }
@@ -57,11 +57,6 @@ func testMinDelayConfig() Config {
57 }57 }
58 }58 }
59 59
60-func allowRestartPolicyEnsure(t *testing.T, runtime *mocks.MockContainerRuntime) {
61- t.Helper()
62- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, mock.Anything, domain.RestartPolicyAlways).Return(nil).Maybe()
63-}
64-
65 func setupMetricsTest(t *testing.T) (*telemetry.Metrics, *sdkmetric.ManualReader) {60 func setupMetricsTest(t *testing.T) (*telemetry.Metrics, *sdkmetric.ManualReader) {
66 t.Helper()61 t.Helper()
67 62
@@ -382,8 +377,6 @@ func TestService_Deploy_Success(t *testing.T) {
382 // Wait for ready: IsContainerRunning (first check returns true) + verify after delay377 // Wait for ready: IsContainerRunning (first check returns true) + verify after delay
383 runtime.EXPECT().IsContainerRunning(mock.Anything, "container-123").Return(true, nil).Times(2)378 runtime.EXPECT().IsContainerRunning(mock.Anything, "container-123").Return(true, nil).Times(2)
384 379
385- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, "container-123", domain.RestartPolicyAlways).Return(nil).Once()
386-
387 // Re-inspect after start380 // Re-inspect after start
388 runningContainer := &domain.Container{381 runningContainer := &domain.Container{
389 ID: "container-123",382 ID: "container-123",
@@ -412,7 +405,6 @@ func TestService_Deploy_Success(t *testing.T) {
412 405
413 func TestService_Deploy_ReadinessRecoveryWindow_AllowsTransientFlap(t *testing.T) {406 func TestService_Deploy_ReadinessRecoveryWindow_AllowsTransientFlap(t *testing.T) {
414 runtime := mocks.NewMockContainerRuntime(t)407 runtime := mocks.NewMockContainerRuntime(t)
415- allowRestartPolicyEnsure(t, runtime)
416 envLoader := mocks.NewMockEnvLoader(t)408 envLoader := mocks.NewMockEnvLoader(t)
417 eventBus := mocks.NewMockEventPublisher(t)409 eventBus := mocks.NewMockEventPublisher(t)
418 410
@@ -479,7 +471,6 @@ func TestService_Deploy_ReadinessRecoveryWindow_AllowsTransientFlap(t *testing.T
479 471
480 func TestService_Deploy_ImagePullFailure(t *testing.T) {472 func TestService_Deploy_ImagePullFailure(t *testing.T) {
481 runtime := mocks.NewMockContainerRuntime(t)473 runtime := mocks.NewMockContainerRuntime(t)
482- allowRestartPolicyEnsure(t, runtime)
483 envLoader := mocks.NewMockEnvLoader(t)474 envLoader := mocks.NewMockEnvLoader(t)
484 eventBus := mocks.NewMockEventPublisher(t)475 eventBus := mocks.NewMockEventPublisher(t)
485 476
@@ -522,7 +513,6 @@ func TestIsPullFailure_ErrImagePullFailed(t *testing.T) {
522 513
523 func TestService_Deploy_DoesNotMisclassifyUnauthorizedEnvLoadFailure(t *testing.T) {514 func TestService_Deploy_DoesNotMisclassifyUnauthorizedEnvLoadFailure(t *testing.T) {
524 runtime := mocks.NewMockContainerRuntime(t)515 runtime := mocks.NewMockContainerRuntime(t)
525- allowRestartPolicyEnsure(t, runtime)
526 envLoader := mocks.NewMockEnvLoader(t)516 envLoader := mocks.NewMockEnvLoader(t)
527 eventBus := mocks.NewMockEventPublisher(t)517 eventBus := mocks.NewMockEventPublisher(t)
528 518
@@ -563,7 +553,6 @@ func TestService_CaptureRecentContainerLogs_SkipsCanceledContext(t *testing.T) {
563 553
564 func TestService_Deploy_ReadinessFailureReturnsDeployFailureWithLogs(t *testing.T) {554 func TestService_Deploy_ReadinessFailureReturnsDeployFailureWithLogs(t *testing.T) {
565 runtime := mocks.NewMockContainerRuntime(t)555 runtime := mocks.NewMockContainerRuntime(t)
566- allowRestartPolicyEnsure(t, runtime)
567 envLoader := mocks.NewMockEnvLoader(t)556 envLoader := mocks.NewMockEnvLoader(t)
568 eventBus := mocks.NewMockEventPublisher(t)557 eventBus := mocks.NewMockEventPublisher(t)
569 558
@@ -623,7 +612,6 @@ func TestService_Deploy_ReadinessFailureReturnsDeployFailureWithLogs(t *testing.
623 612
624 func TestService_Deploy_StrictHealthModeWithoutHealthcheckReturnsHint(t *testing.T) {613 func TestService_Deploy_StrictHealthModeWithoutHealthcheckReturnsHint(t *testing.T) {
625 runtime := mocks.NewMockContainerRuntime(t)614 runtime := mocks.NewMockContainerRuntime(t)
626- allowRestartPolicyEnsure(t, runtime)
627 envLoader := mocks.NewMockEnvLoader(t)615 envLoader := mocks.NewMockEnvLoader(t)
628 eventBus := mocks.NewMockEventPublisher(t)616 eventBus := mocks.NewMockEventPublisher(t)
629 617
@@ -735,7 +723,6 @@ func TestService_PullImage_InternalRetriesOnConnectionRefused(t *testing.T) {
735 723
736 func TestService_Deploy_ReplacesExistingContainer(t *testing.T) {724 func TestService_Deploy_ReplacesExistingContainer(t *testing.T) {
737 runtime := mocks.NewMockContainerRuntime(t)725 runtime := mocks.NewMockContainerRuntime(t)
738- allowRestartPolicyEnsure(t, runtime)
739 envLoader := mocks.NewMockEnvLoader(t)726 envLoader := mocks.NewMockEnvLoader(t)
740 eventBus := mocks.NewMockEventPublisher(t)727 eventBus := mocks.NewMockEventPublisher(t)
741 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)728 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -819,7 +806,6 @@ func TestService_Deploy_ReplacesExistingContainer(t *testing.T) {
819 // from killing the real active container after a Gordon restart.806 // from killing the real active container after a Gordon restart.
820 func TestService_Deploy_ResolvesExistingFromRuntime_WhenMemoryStale(t *testing.T) {807 func TestService_Deploy_ResolvesExistingFromRuntime_WhenMemoryStale(t *testing.T) {
821 runtime := mocks.NewMockContainerRuntime(t)808 runtime := mocks.NewMockContainerRuntime(t)
822- allowRestartPolicyEnsure(t, runtime)
823 envLoader := mocks.NewMockEnvLoader(t)809 envLoader := mocks.NewMockEnvLoader(t)
824 eventBus := mocks.NewMockEventPublisher(t)810 eventBus := mocks.NewMockEventPublisher(t)
825 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)811 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -919,7 +905,6 @@ func TestService_Deploy_ResolvesExistingFromRuntime_WhenMemoryStale(t *testing.T
919 905
920 func TestService_Deploy_SkipRedundantDeploy_GetImageIDError(t *testing.T) {906 func TestService_Deploy_SkipRedundantDeploy_GetImageIDError(t *testing.T) {
921 runtime := mocks.NewMockContainerRuntime(t)907 runtime := mocks.NewMockContainerRuntime(t)
922- allowRestartPolicyEnsure(t, runtime)
923 envLoader := mocks.NewMockEnvLoader(t)908 envLoader := mocks.NewMockEnvLoader(t)
924 eventBus := mocks.NewMockEventPublisher(t)909 eventBus := mocks.NewMockEventPublisher(t)
925 910
@@ -982,7 +967,6 @@ func TestService_Deploy_SkipRedundantDeploy_GetImageIDError(t *testing.T) {
982 967
983 func TestService_Deploy_WithNetworkIsolation(t *testing.T) {968 func TestService_Deploy_WithNetworkIsolation(t *testing.T) {
984 runtime := mocks.NewMockContainerRuntime(t)969 runtime := mocks.NewMockContainerRuntime(t)
985- allowRestartPolicyEnsure(t, runtime)
986 envLoader := mocks.NewMockEnvLoader(t)970 envLoader := mocks.NewMockEnvLoader(t)
987 eventBus := mocks.NewMockEventPublisher(t)971 eventBus := mocks.NewMockEventPublisher(t)
988 972
@@ -1041,7 +1025,6 @@ func TestService_Deploy_WithNetworkIsolation(t *testing.T) {
1041 1025
1042 func TestService_Deploy_WithVolumeAutoCreate(t *testing.T) {1026 func TestService_Deploy_WithVolumeAutoCreate(t *testing.T) {
1043 runtime := mocks.NewMockContainerRuntime(t)1027 runtime := mocks.NewMockContainerRuntime(t)
1044- allowRestartPolicyEnsure(t, runtime)
1045 envLoader := mocks.NewMockEnvLoader(t)1028 envLoader := mocks.NewMockEnvLoader(t)
1046 eventBus := mocks.NewMockEventPublisher(t)1029 eventBus := mocks.NewMockEventPublisher(t)
1047 1030
@@ -2055,7 +2038,6 @@ func TestRewriteToLocalRegistry(t *testing.T) {
2055 2038
2056 func TestService_Deploy_InternalDeployForcesPull(t *testing.T) {2039 func TestService_Deploy_InternalDeployForcesPull(t *testing.T) {
2057 runtime := mocks.NewMockContainerRuntime(t)2040 runtime := mocks.NewMockContainerRuntime(t)
2058- allowRestartPolicyEnsure(t, runtime)
2059 envLoader := mocks.NewMockEnvLoader(t)2041 envLoader := mocks.NewMockEnvLoader(t)
2060 eventBus := mocks.NewMockEventPublisher(t)2042 eventBus := mocks.NewMockEventPublisher(t)
2061 2043
@@ -2136,7 +2118,6 @@ func TestService_Deploy_InternalDeployForcesPull(t *testing.T) {
2136 2118
2137 func TestService_AutoStart_StartsNewContainers(t *testing.T) {2119 func TestService_AutoStart_StartsNewContainers(t *testing.T) {
2138 runtime := mocks.NewMockContainerRuntime(t)2120 runtime := mocks.NewMockContainerRuntime(t)
2139- allowRestartPolicyEnsure(t, runtime)
2140 envLoader := mocks.NewMockEnvLoader(t)2121 envLoader := mocks.NewMockEnvLoader(t)
2141 eventBus := mocks.NewMockEventPublisher(t)2122 eventBus := mocks.NewMockEventPublisher(t)
2142 2123
@@ -2186,7 +2167,6 @@ func TestService_AutoStart_StartsNewContainers(t *testing.T) {
2186 2167
2187 func TestService_AutoStart_SkipsExistingContainers(t *testing.T) {2168 func TestService_AutoStart_SkipsExistingContainers(t *testing.T) {
2188 runtime := mocks.NewMockContainerRuntime(t)2169 runtime := mocks.NewMockContainerRuntime(t)
2189- allowRestartPolicyEnsure(t, runtime)
2190 envLoader := mocks.NewMockEnvLoader(t)2170 envLoader := mocks.NewMockEnvLoader(t)
2191 eventBus := mocks.NewMockEventPublisher(t)2171 eventBus := mocks.NewMockEventPublisher(t)
2192 2172
@@ -2236,7 +2216,6 @@ func TestService_AutoStart_SkipsExistingContainers(t *testing.T) {
2236 2216
2237 func TestService_AutoStart_HandlesDeployErrors(t *testing.T) {2217 func TestService_AutoStart_HandlesDeployErrors(t *testing.T) {
2238 runtime := mocks.NewMockContainerRuntime(t)2218 runtime := mocks.NewMockContainerRuntime(t)
2239- allowRestartPolicyEnsure(t, runtime)
2240 envLoader := mocks.NewMockEnvLoader(t)2219 envLoader := mocks.NewMockEnvLoader(t)
2241 eventBus := mocks.NewMockEventPublisher(t)2220 eventBus := mocks.NewMockEventPublisher(t)
2242 2221
@@ -2265,7 +2244,6 @@ func TestService_AutoStart_HandlesDeployErrors(t *testing.T) {
2265 2244
2266 func TestService_AutoStart_UsesInternalDeployContext(t *testing.T) {2245 func TestService_AutoStart_UsesInternalDeployContext(t *testing.T) {
2267 runtime := mocks.NewMockContainerRuntime(t)2246 runtime := mocks.NewMockContainerRuntime(t)
2268- allowRestartPolicyEnsure(t, runtime)
2269 envLoader := mocks.NewMockEnvLoader(t)2247 envLoader := mocks.NewMockEnvLoader(t)
2270 eventBus := mocks.NewMockEventPublisher(t)2248 eventBus := mocks.NewMockEventPublisher(t)
2271 2249
@@ -2318,7 +2296,6 @@ func TestService_AutoStart_UsesInternalDeployContext(t *testing.T) {
2318 // until the new container is ready and traffic is switched.2296 // until the new container is ready and traffic is switched.
2319 func TestService_Deploy_OrphanCleanupSkipsTrackedContainer(t *testing.T) {2297 func TestService_Deploy_OrphanCleanupSkipsTrackedContainer(t *testing.T) {
2320 runtime := mocks.NewMockContainerRuntime(t)2298 runtime := mocks.NewMockContainerRuntime(t)
2321- allowRestartPolicyEnsure(t, runtime)
2322 envLoader := mocks.NewMockEnvLoader(t)2299 envLoader := mocks.NewMockEnvLoader(t)
2323 eventBus := mocks.NewMockEventPublisher(t)2300 eventBus := mocks.NewMockEventPublisher(t)
2324 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)2301 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2415,7 +2392,6 @@ func TestService_Deploy_OrphanCleanupSkipsTrackedContainer(t *testing.T) {
2415 // Running canonical containers are preserved (see NeverKillsRunningCanonical test).2392 // Running canonical containers are preserved (see NeverKillsRunningCanonical test).
2416 func TestService_Deploy_OrphanCleanupRemovesTrueOrphans(t *testing.T) {2393 func TestService_Deploy_OrphanCleanupRemovesTrueOrphans(t *testing.T) {
2417 runtime := mocks.NewMockContainerRuntime(t)2394 runtime := mocks.NewMockContainerRuntime(t)
2418- allowRestartPolicyEnsure(t, runtime)
2419 envLoader := mocks.NewMockEnvLoader(t)2395 envLoader := mocks.NewMockEnvLoader(t)
2420 eventBus := mocks.NewMockEventPublisher(t)2396 eventBus := mocks.NewMockEventPublisher(t)
2421 2397
@@ -2496,7 +2472,6 @@ func TestService_Deploy_OrphanCleanupRemovesTrueOrphans(t *testing.T) {
2496 2472
2497 func TestService_Deploy_OrphanCleanupRemovesStaleNewContainer(t *testing.T) {2473 func TestService_Deploy_OrphanCleanupRemovesStaleNewContainer(t *testing.T) {
2498 runtime := mocks.NewMockContainerRuntime(t)2474 runtime := mocks.NewMockContainerRuntime(t)
2499- allowRestartPolicyEnsure(t, runtime)
2500 envLoader := mocks.NewMockEnvLoader(t)2475 envLoader := mocks.NewMockEnvLoader(t)
2501 eventBus := mocks.NewMockEventPublisher(t)2476 eventBus := mocks.NewMockEventPublisher(t)
2502 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)2477 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2569,7 +2544,6 @@ func TestService_Deploy_OrphanCleanupRemovesStaleNewContainer(t *testing.T) {
2569 2544
2570 func TestService_Deploy_TrackedTempContainerUsesAlternateTempName(t *testing.T) {2545 func TestService_Deploy_TrackedTempContainerUsesAlternateTempName(t *testing.T) {
2571 runtime := mocks.NewMockContainerRuntime(t)2546 runtime := mocks.NewMockContainerRuntime(t)
2572- allowRestartPolicyEnsure(t, runtime)
2573 envLoader := mocks.NewMockEnvLoader(t)2547 envLoader := mocks.NewMockEnvLoader(t)
2574 eventBus := mocks.NewMockEventPublisher(t)2548 eventBus := mocks.NewMockEventPublisher(t)
2575 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)2549 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2759,7 +2733,6 @@ func TestService_Deploy_ConcurrentSameDomain(t *testing.T) {
2759 // Verify that concurrent Deploy calls for the same domain are serialized2733 // Verify that concurrent Deploy calls for the same domain are serialized
2760 // and both succeed without container name conflicts.2734 // and both succeed without container name conflicts.
2761 runtime := mocks.NewMockContainerRuntime(t)2735 runtime := mocks.NewMockContainerRuntime(t)
2762- allowRestartPolicyEnsure(t, runtime)
2763 envLoader := mocks.NewMockEnvLoader(t)2736 envLoader := mocks.NewMockEnvLoader(t)
2764 eventBus := mocks.NewMockEventPublisher(t)2737 eventBus := mocks.NewMockEventPublisher(t)
2765 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)2738 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2870,7 +2843,6 @@ func TestService_Deploy_ConcurrentSameDomain(t *testing.T) {
2870 func TestService_Deploy_ContextCancellation(t *testing.T) {2843 func TestService_Deploy_ContextCancellation(t *testing.T) {
2871 // Verify that deploy lock acquisition respects context cancellation.2844 // Verify that deploy lock acquisition respects context cancellation.
2872 runtime := mocks.NewMockContainerRuntime(t)2845 runtime := mocks.NewMockContainerRuntime(t)
2873- allowRestartPolicyEnsure(t, runtime)
2874 envLoader := mocks.NewMockEnvLoader(t)2846 envLoader := mocks.NewMockEnvLoader(t)
2875 eventBus := mocks.NewMockEventPublisher(t)2847 eventBus := mocks.NewMockEventPublisher(t)
2876 2848
@@ -2901,7 +2873,6 @@ func TestService_Deploy_ContextCancellation(t *testing.T) {
2901 // BEFORE the old container is stopped, preventing 503 errors during deployment.2873 // BEFORE the old container is stopped, preventing 503 errors during deployment.
2902 func TestService_Deploy_CacheInvalidationBeforeOldContainerStop(t *testing.T) {2874 func TestService_Deploy_CacheInvalidationBeforeOldContainerStop(t *testing.T) {
2903 runtime := mocks.NewMockContainerRuntime(t)2875 runtime := mocks.NewMockContainerRuntime(t)
2904- allowRestartPolicyEnsure(t, runtime)
2905 envLoader := mocks.NewMockEnvLoader(t)2876 envLoader := mocks.NewMockEnvLoader(t)
2906 eventBus := mocks.NewMockEventPublisher(t)2877 eventBus := mocks.NewMockEventPublisher(t)
2907 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)2878 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -2982,7 +2953,6 @@ func TestService_Deploy_CacheInvalidationBeforeOldContainerStop(t *testing.T) {
2982 // when no cache invalidator is set (e.g., in tests or minimal configurations).2953 // when no cache invalidator is set (e.g., in tests or minimal configurations).
2983 func TestService_Deploy_NilCacheInvalidator(t *testing.T) {2954 func TestService_Deploy_NilCacheInvalidator(t *testing.T) {
2984 runtime := mocks.NewMockContainerRuntime(t)2955 runtime := mocks.NewMockContainerRuntime(t)
2985- allowRestartPolicyEnsure(t, runtime)
2986 envLoader := mocks.NewMockEnvLoader(t)2956 envLoader := mocks.NewMockEnvLoader(t)
2987 eventBus := mocks.NewMockEventPublisher(t)2957 eventBus := mocks.NewMockEventPublisher(t)
2988 2958
@@ -3032,7 +3002,6 @@ func TestService_Deploy_NilCacheInvalidator(t *testing.T) {
3032 3002
3033 func TestService_Deploy_SkipsRedundantDeploy(t *testing.T) {3003 func TestService_Deploy_SkipsRedundantDeploy(t *testing.T) {
3034 runtime := mocks.NewMockContainerRuntime(t)3004 runtime := mocks.NewMockContainerRuntime(t)
3035- allowRestartPolicyEnsure(t, runtime)
3036 envLoader := mocks.NewMockEnvLoader(t)3005 envLoader := mocks.NewMockEnvLoader(t)
3037 eventBus := mocks.NewMockEventPublisher(t)3006 eventBus := mocks.NewMockEventPublisher(t)
3038 3007
@@ -3093,7 +3062,6 @@ func TestService_Deploy_SkipsRedundantDeploy(t *testing.T) {
3093 3062
3094 func TestService_Deploy_SkipsRedundantDeploy_WhenTrackedImageIDMissing(t *testing.T) {3063 func TestService_Deploy_SkipsRedundantDeploy_WhenTrackedImageIDMissing(t *testing.T) {
3095 runtime := mocks.NewMockContainerRuntime(t)3064 runtime := mocks.NewMockContainerRuntime(t)
3096- allowRestartPolicyEnsure(t, runtime)
3097 envLoader := mocks.NewMockEnvLoader(t)3065 envLoader := mocks.NewMockEnvLoader(t)
3098 eventBus := mocks.NewMockEventPublisher(t)3066 eventBus := mocks.NewMockEventPublisher(t)
3099 3067
@@ -3155,7 +3123,6 @@ func TestService_Deploy_SkipsRedundantDeploy_WhenTrackedImageIDMissing(t *testin
3155 3123
3156 func TestService_Deploy_DoesNotSkipWhenImageIDDiffers(t *testing.T) {3124 func TestService_Deploy_DoesNotSkipWhenImageIDDiffers(t *testing.T) {
3157 runtime := mocks.NewMockContainerRuntime(t)3125 runtime := mocks.NewMockContainerRuntime(t)
3158- allowRestartPolicyEnsure(t, runtime)
3159 envLoader := mocks.NewMockEnvLoader(t)3126 envLoader := mocks.NewMockEnvLoader(t)
3160 eventBus := mocks.NewMockEventPublisher(t)3127 eventBus := mocks.NewMockEventPublisher(t)
3161 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)3128 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3258,7 +3225,6 @@ func TestSyncContainersRebuildsAttachmentMap(t *testing.T) {
3258 3225
3259 func TestService_Deploy_SkipRedundantDeploy_ContainerNotRunning(t *testing.T) {3226 func TestService_Deploy_SkipRedundantDeploy_ContainerNotRunning(t *testing.T) {
3260 runtime := mocks.NewMockContainerRuntime(t)3227 runtime := mocks.NewMockContainerRuntime(t)
3261- allowRestartPolicyEnsure(t, runtime)
3262 envLoader := mocks.NewMockEnvLoader(t)3228 envLoader := mocks.NewMockEnvLoader(t)
3263 eventBus := mocks.NewMockEventPublisher(t)3229 eventBus := mocks.NewMockEventPublisher(t)
3264 3230
@@ -3322,7 +3288,6 @@ func TestService_Deploy_SkipRedundantDeploy_ContainerNotRunning(t *testing.T) {
3322 3288
3323 func TestService_Deploy_DoesNotSkip_WhenEnvHashDiffers(t *testing.T) {3289 func TestService_Deploy_DoesNotSkip_WhenEnvHashDiffers(t *testing.T) {
3324 runtime := mocks.NewMockContainerRuntime(t)3290 runtime := mocks.NewMockContainerRuntime(t)
3325- allowRestartPolicyEnsure(t, runtime)
3326 envLoader := mocks.NewMockEnvLoader(t)3291 envLoader := mocks.NewMockEnvLoader(t)
3327 eventBus := mocks.NewMockEventPublisher(t)3292 eventBus := mocks.NewMockEventPublisher(t)
3328 3293
@@ -3381,7 +3346,6 @@ func TestService_Deploy_DoesNotSkip_WhenEnvHashDiffers(t *testing.T) {
3381 3346
3382 func TestService_Deploy_DoesNotSkip_WhenEnvHashMissing(t *testing.T) {3347 func TestService_Deploy_DoesNotSkip_WhenEnvHashMissing(t *testing.T) {
3383 runtime := mocks.NewMockContainerRuntime(t)3348 runtime := mocks.NewMockContainerRuntime(t)
3384- allowRestartPolicyEnsure(t, runtime)
3385 envLoader := mocks.NewMockEnvLoader(t)3349 envLoader := mocks.NewMockEnvLoader(t)
3386 eventBus := mocks.NewMockEventPublisher(t)3350 eventBus := mocks.NewMockEventPublisher(t)
3387 3351
@@ -3508,7 +3472,6 @@ func TestService_attachmentEnvDrifted_ReturnsTrueWhenHashMissing(t *testing.T) {
3508 // disallows creating a container with the same name as an existing running container.3472 // disallows creating a container with the same name as an existing running container.
3509 func TestService_Deploy_OrphanCleanup_NeverKillsRunningCanonical(t *testing.T) {3473 func TestService_Deploy_OrphanCleanup_NeverKillsRunningCanonical(t *testing.T) {
3510 runtime := mocks.NewMockContainerRuntime(t)3474 runtime := mocks.NewMockContainerRuntime(t)
3511- allowRestartPolicyEnsure(t, runtime)
3512 envLoader := mocks.NewMockEnvLoader(t)3475 envLoader := mocks.NewMockEnvLoader(t)
3513 eventBus := mocks.NewMockEventPublisher(t)3476 eventBus := mocks.NewMockEventPublisher(t)
3514 3477
@@ -3605,7 +3568,6 @@ func TestService_Deploy_OrphanCleanup_NeverKillsRunningCanonical(t *testing.T) {
3605 // and the failed new container is cleaned up.3568 // and the failed new container is cleaned up.
3606 func TestService_Deploy_RollbackOnPostSwitchCrash(t *testing.T) {3569 func TestService_Deploy_RollbackOnPostSwitchCrash(t *testing.T) {
3607 runtime := mocks.NewMockContainerRuntime(t)3570 runtime := mocks.NewMockContainerRuntime(t)
3608- allowRestartPolicyEnsure(t, runtime)
3609 envLoader := mocks.NewMockEnvLoader(t)3571 envLoader := mocks.NewMockEnvLoader(t)
3610 eventBus := mocks.NewMockEventPublisher(t)3572 eventBus := mocks.NewMockEventPublisher(t)
3611 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)3573 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3700,7 +3662,6 @@ func TestService_Deploy_RollbackOnPostSwitchCrash(t *testing.T) {
3700 // container is finalized (stopped and removed).3662 // container is finalized (stopped and removed).
3701 func TestService_Deploy_StabilizationSuccess(t *testing.T) {3663 func TestService_Deploy_StabilizationSuccess(t *testing.T) {
3702 runtime := mocks.NewMockContainerRuntime(t)3664 runtime := mocks.NewMockContainerRuntime(t)
3703- allowRestartPolicyEnsure(t, runtime)
3704 envLoader := mocks.NewMockEnvLoader(t)3665 envLoader := mocks.NewMockEnvLoader(t)
3705 eventBus := mocks.NewMockEventPublisher(t)3666 eventBus := mocks.NewMockEventPublisher(t)
3706 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)3667 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3789,7 +3750,6 @@ func TestService_Deploy_StabilizationSuccess(t *testing.T) {
3789 // Uses testify's NotBefore() to enforce mock call ordering.3750 // Uses testify's NotBefore() to enforce mock call ordering.
3790 func TestService_Deploy_ZeroDowntime_OldNeverStoppedBeforeNewReady(t *testing.T) {3751 func TestService_Deploy_ZeroDowntime_OldNeverStoppedBeforeNewReady(t *testing.T) {
3791 runtime := mocks.NewMockContainerRuntime(t)3752 runtime := mocks.NewMockContainerRuntime(t)
3792- allowRestartPolicyEnsure(t, runtime)
3793 envLoader := mocks.NewMockEnvLoader(t)3753 envLoader := mocks.NewMockEnvLoader(t)
3794 eventBus := mocks.NewMockEventPublisher(t)3754 eventBus := mocks.NewMockEventPublisher(t)
3795 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)3755 cacheInvalidator := mocks.NewMockProxyCacheInvalidator(t)
@@ -3886,7 +3846,6 @@ func TestService_Deploy_ZeroDowntime_OldNeverStoppedBeforeNewReady(t *testing.T)
3886 // the old container remains as the tracked container.3846 // the old container remains as the tracked container.
3887 func TestService_Deploy_ZeroDowntime_ReadinessFailure_OldUntouched(t *testing.T) {3847 func TestService_Deploy_ZeroDowntime_ReadinessFailure_OldUntouched(t *testing.T) {
3888 runtime := mocks.NewMockContainerRuntime(t)3848 runtime := mocks.NewMockContainerRuntime(t)
3889- allowRestartPolicyEnsure(t, runtime)
3890 envLoader := mocks.NewMockEnvLoader(t)3849 envLoader := mocks.NewMockEnvLoader(t)
3891 eventBus := mocks.NewMockEventPublisher(t)3850 eventBus := mocks.NewMockEventPublisher(t)
3892 3851
@@ -3977,7 +3936,6 @@ func TestService_Deploy_ZeroDowntime_ReadinessFailure_OldUntouched(t *testing.T)
3977 // finalize/drain logic being triggered.3936 // finalize/drain logic being triggered.
3978 func TestService_Deploy_ZeroDowntime_NoExisting_FirstDeploy(t *testing.T) {3937 func TestService_Deploy_ZeroDowntime_NoExisting_FirstDeploy(t *testing.T) {
3979 runtime := mocks.NewMockContainerRuntime(t)3938 runtime := mocks.NewMockContainerRuntime(t)
3980- allowRestartPolicyEnsure(t, runtime)
3981 envLoader := mocks.NewMockEnvLoader(t)3939 envLoader := mocks.NewMockEnvLoader(t)
3982 eventBus := mocks.NewMockEventPublisher(t)3940 eventBus := mocks.NewMockEventPublisher(t)
3983 3941
@@ -4054,7 +4012,6 @@ func TestService_Deploy_ZeroDowntime_NoExisting_FirstDeploy(t *testing.T) {
4054 4012
4055 func TestService_Deploy_PropagatesImageLabelsToContainerConfig(t *testing.T) {4013 func TestService_Deploy_PropagatesImageLabelsToContainerConfig(t *testing.T) {
4056 runtime := mocks.NewMockContainerRuntime(t)4014 runtime := mocks.NewMockContainerRuntime(t)
4057- allowRestartPolicyEnsure(t, runtime)
4058 envLoader := mocks.NewMockEnvLoader(t)4015 envLoader := mocks.NewMockEnvLoader(t)
4059 eventBus := mocks.NewMockEventPublisher(t)4016 eventBus := mocks.NewMockEventPublisher(t)
4060 4017
@@ -4312,7 +4269,7 @@ func TestDeployAttachedService_SetsAliasOnContainerConfig(t *testing.T) {
4312 assert.Equal(t, []string{"postgres"}, cfg.Aliases, "attachment container must have network aliases for DNS resolution")4269 assert.Equal(t, []string{"postgres"}, cfg.Aliases, "attachment container must have network aliases for DNS resolution")
4313 assert.Equal(t, "postgres", cfg.Hostname)4270 assert.Equal(t, "postgres", cfg.Hostname)
4314 assert.Equal(t, networkName, cfg.NetworkMode)4271 assert.Equal(t, networkName, cfg.NetworkMode)
4315- assert.Empty(t, cfg.RestartPolicy)4272+ assert.Equal(t, domain.RestartPolicyAlways, cfg.RestartPolicy)
4316 }).4273 }).
4317 Return(&domain.Container{ID: "pg-container-1", Name: containerName}, nil)4274 Return(&domain.Container{ID: "pg-container-1", Name: containerName}, nil)
4318 4275
@@ -4325,7 +4282,6 @@ func TestDeployAttachedService_SetsAliasOnContainerConfig(t *testing.T) {
4325 runtime.EXPECT().GetContainerHealthStatus(mock.Anything, "pg-container-1").Return("", false, nil)4282 runtime.EXPECT().GetContainerHealthStatus(mock.Anything, "pg-container-1").Return("", false, nil)
4326 // TCP probe: resolve endpoint fails -> falls back to delay4283 // TCP probe: resolve endpoint fails -> falls back to delay
4327 runtime.EXPECT().GetContainerNetworkInfo(mock.Anything, "pg-container-1").Return("", 0, errors.New("no network"))4284 runtime.EXPECT().GetContainerNetworkInfo(mock.Anything, "pg-container-1").Return("", 0, errors.New("no network"))
4328- runtime.EXPECT().EnsureContainerRestartPolicy(mock.Anything, "pg-container-1", domain.RestartPolicyAlways).Return(nil).Once()
4329 4285
4330 err := svc.deployAttachedService(ctx, ownerDomain, serviceImage, networkName)4286 err := svc.deployAttachedService(ctx, ownerDomain, serviceImage, networkName)
4331 require.NoError(t, err)4287 require.NoError(t, err)
@@ -4451,10 +4407,10 @@ func TestService_BuildContainerConfig_CompatSecurityProfileDefault(t *testing.T)
4451 assert.Nil(t, cfg.CapAdd)4407 assert.Nil(t, cfg.CapAdd)
4452 }4408 }
4453 4409
4454-func TestService_BuildContainerConfig_OmitsRestartPolicyBeforeReadiness(t *testing.T) {4410+func TestService_BuildContainerConfig_SetsRestartPolicyAlways(t *testing.T) {
4455 svc := NewService(nil, nil, nil, nil, Config{}, nil)4411 svc := NewService(nil, nil, nil, nil, Config{}, nil)
4456 4412
4457 cfg := svc.buildContainerConfig(containerConfigInput{Domain: "app.example.com", Image: "app:latest", ImageRef: "app:latest"})4413 cfg := svc.buildContainerConfig(containerConfigInput{Domain: "app.example.com", Image: "app:latest", ImageRef: "app:latest"})
4458 4414
4459- assert.Empty(t, cfg.RestartPolicy)4415+ assert.Equal(t, domain.RestartPolicyAlways, cfg.RestartPolicy)
4460 }4416 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close