Skip to content
2 changes: 2 additions & 0 deletions cmd/nginx-ingress/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
NICVersion: version,
DynamicWeightChangesReload: *enableDynamicWeightChangesReload,
InstallationFlags: parsedFlags,
ShuttingDown: false,

Check warning on line 326 in cmd/nginx-ingress/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/nginx-ingress/main.go#L326

Added line #L326 was not covered by tests
}

lbc := k8s.NewLoadBalancerController(lbcInput)
Expand Down Expand Up @@ -816,6 +817,7 @@
nl.Fatalf(lbc.Logger, "AppProtectDosAgent command exited unexpectedly with status: %v", err)
case <-signalChan:
nl.Info(lbc.Logger, "Received SIGTERM, shutting down")
lbc.ShuttingDown = true

Check warning on line 820 in cmd/nginx-ingress/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/nginx-ingress/main.go#L820

Added line #L820 was not covered by tests
lbc.Stop()
nginxManager.Quit()
<-cpcfg.nginxDone
Expand Down
10 changes: 9 additions & 1 deletion internal/k8s/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
key := task.Key
nl.Debugf(lbc.Logger, "Syncing configmap %v", key)

if key == lbc.mgmtConfigMapName && lbc.isPodMarkedForDeletion() {
nl.Debugf(lbc.Logger, "Pod is shutting down, skipping management ConfigMap sync")
return
}

Check warning on line 88 in internal/k8s/configmap.go

View check run for this annotation

Codecov / codecov/patch

internal/k8s/configmap.go#L85-L88

Added lines #L85 - L88 were not covered by tests

switch key {
case lbc.nginxConfigMapName:
obj, configExists, err := lbc.configMapLister.GetByKey(key)
Expand Down Expand Up @@ -120,6 +125,9 @@
nl.Debugf(lbc.Logger, "Skipping ConfigMap update because batch sync is on")
return
}

if err := lbc.ctx.Err(); err != nil {
nl.Debugf(lbc.Logger, "Context canceled, skipping ConfigMap sync for %v: %v", task.Key, err)
return
}

Check warning on line 131 in internal/k8s/configmap.go

View check run for this annotation

Codecov / codecov/patch

internal/k8s/configmap.go#L128-L131

Added lines #L128 - L131 were not covered by tests
lbc.updateAllConfigs()
}
20 changes: 20 additions & 0 deletions internal/k8s/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ type LoadBalancerController struct {
weightChangesDynamicReload bool
nginxConfigMapName string
mgmtConfigMapName string
ShuttingDown bool
}

var keyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc
Expand Down Expand Up @@ -241,6 +242,7 @@ type NewLoadBalancerControllerInput struct {
NICVersion string
DynamicWeightChangesReload bool
InstallationFlags []string
ShuttingDown bool
}

// NewLoadBalancerController creates a controller
Expand Down Expand Up @@ -286,6 +288,7 @@ func NewLoadBalancerController(input NewLoadBalancerControllerInput) *LoadBalanc
weightChangesDynamicReload: input.DynamicWeightChangesReload,
nginxConfigMapName: input.ConfigMaps,
mgmtConfigMapName: input.MGMTConfigMap,
ShuttingDown: input.ShuttingDown,
}

lbc.syncQueue = newTaskQueue(lbc.Logger, lbc.sync)
Expand Down Expand Up @@ -3649,3 +3652,20 @@ func (lbc *LoadBalancerController) createCombinedDeploymentHeadlessServiceName()
combinedDeployment := fmt.Sprintf("%s-%s", name, strings.ToLower(owner.Kind))
return combinedDeployment
}

func (lbc *LoadBalancerController) isPodMarkedForDeletion() bool {
// Check if the controller is shutting down
if lbc.ShuttingDown {
nl.Debugf(lbc.Logger, "SIGTERM already received, controller is shutting down")
return true
}
podName := lbc.metadata.pod.Name
podNamespace := lbc.metadata.pod.Namespace
pod, err := lbc.client.CoreV1().Pods(podNamespace).Get(context.Background(), podName, meta_v1.GetOptions{})
if err == nil && pod.DeletionTimestamp != nil {
nl.Debugf(lbc.Logger, "Pod %s/%s is marked for deletion", podNamespace, podName)
return true
}

return false
}
83 changes: 83 additions & 0 deletions internal/k8s/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3639,3 +3639,86 @@ func TestCreateIngressExWithZoneSync(t *testing.T) {
}
}
}

func TestIsPodMarkedForDeletion(t *testing.T) {
t.Parallel()

logger := nl.LoggerFromContext(context.Background())

tests := []struct {
name string
shutdownFlag bool
envPodName string
envPodNamespace string
podExists bool
podHasTimestamp bool
expectedResult bool
}{
{
name: "controller is shutting down",
shutdownFlag: true,
expectedResult: true,
},
{
name: "pod exists with deletion timestamp",
envPodName: "test-pod",
envPodNamespace: "test-namespace",
podExists: true,
podHasTimestamp: true,
expectedResult: true,
},
{
name: "pod exists without deletion timestamp",
envPodName: "test-pod",
envPodNamespace: "test-namespace",
podExists: true,
podHasTimestamp: false,
expectedResult: false,
},
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
client := fake.NewSimpleClientset()
if test.podExists {
pod := &api_v1.Pod{
ObjectMeta: meta_v1.ObjectMeta{
Name: test.envPodName,
Namespace: test.envPodNamespace,
},
}

if test.podHasTimestamp {
now := meta_v1.Now()
pod.DeletionTimestamp = &now
}

_, err := client.CoreV1().Pods(test.envPodNamespace).Create(context.Background(), pod, meta_v1.CreateOptions{})
if err != nil {
t.Fatalf("Error creating pod: %v", err)
}
}

lbc := &LoadBalancerController{
client: client,
metadata: controllerMetadata{
pod: &api_v1.Pod{
ObjectMeta: meta_v1.ObjectMeta{
Name: test.envPodName,
Namespace: test.envPodNamespace,
},
},
},
ShuttingDown: test.shutdownFlag,
Logger: logger,
}

// Call the function and verify result
result := lbc.isPodMarkedForDeletion()
if result != test.expectedResult {
t.Errorf("Returned %v but expected %v", result, test.expectedResult)
}
})
}
}
Loading