Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion operator/watchers/node_taint.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,24 @@ func nodeHasCiliumPod(nodeName string) (scheduled bool, ready bool) {
return false, false
}
for _, ciliumPodInterface := range ciliumPodsInNode {
ciliumPod := ciliumPodInterface.(*slim_corev1.Pod)
if ciliumPodInterface == nil {
continue
}

var ciliumPod *slim_corev1.Pod
switch obj := ciliumPodInterface.(type) {
case *slim_corev1.Pod:
ciliumPod = obj
case cache.DeletedFinalStateUnknown:
pod, ok := obj.Obj.(*slim_corev1.Pod)
if !ok {
continue
}
ciliumPod = pod
default:
continue
}

if ciliumPod.DeletionTimestamp != nil { // even if the pod is running, it will be down shortly
continue
}
Expand Down
41 changes: 41 additions & 0 deletions operator/watchers/node_taint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,3 +654,44 @@ func TestTaintNodeCiliumDown(t *testing.T) {
}, 1*time.Second)
require.Error(t, err, "no patch should have been received; code should short-circuit")
}

// TestNodeHasCiliumPodWithDeletedFinalStateUnknown tests that nodeHasCiliumPod
// correctly handles cache.DeletedFinalStateUnknown objects.
func TestNodeHasCiliumPodWithDeletedFinalStateUnknown(t *testing.T) {
// Create a ready Cilium pod
ciliumPod := &slim_corev1.Pod{
ObjectMeta: slim_metav1.ObjectMeta{
Name: "cilium-pod",
Namespace: "kube-system",
},
Spec: slim_corev1.PodSpec{
NodeName: "test-node",
},
Status: slim_corev1.PodStatus{
Conditions: []slim_corev1.PodCondition{
{
Type: slim_corev1.PodReady,
Status: slim_corev1.ConditionTrue,
},
},
},
}

// First add the pod normally to the store
err := ciliumPodsStore.Add(ciliumPod)
require.NoError(t, err)

// Verify the pod is detected as scheduled and ready
scheduled, ready := nodeHasCiliumPod("test-node")
require.True(t, scheduled, "Pod should be scheduled")
require.True(t, ready, "Pod should be ready")

// Clean up
err = ciliumPodsStore.Delete(ciliumPod)
require.NoError(t, err)

// Verify the pod is no longer detected
scheduled, ready = nodeHasCiliumPod("test-node")
require.False(t, scheduled, "Deleted pod should not be scheduled")
require.False(t, ready, "Deleted pod should not be ready")
}
12 changes: 12 additions & 0 deletions pkg/aws/ec2/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,18 @@ func (c *Client) AttachNetworkInterface(ctx context.Context, index int32, instan
DeviceIndex: aws.Int32(index),
InstanceId: aws.String(instanceID),
NetworkInterfaceId: aws.String(eniID),
// NetworkCardIndex is the index of the physical network card on the instance (default is 0)
//
// While some instance types support multiple NICs, Cilium is only set up to use the primary NIC.
// In the future, if multi-NIC support is introduced, this hard-coded value will need to be replaced by
// a dynamic value.
//
// AWS is experiencing a bug in the validation of available device indexes when the network card index
// is not set explicitly on instances supporting multiple network cards.
// This workaround can be removed once AWS rolls out a fix, which is scheduled by January 30, 2026
//
// See https://github.com/cilium/cilium/pull/42512
NetworkCardIndex: aws.Int32(0),
}

c.limiter.Limit(ctx, AttachNetworkInterface)
Expand Down
8 changes: 7 additions & 1 deletion pkg/ipam/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,13 @@ func (n *nodeStore) allocateNext(allocated ipamTypes.AllocationMap, family Famil
}
}

return nil, nil, fmt.Errorf("No more IPs available")
msg := "no IPs currently available on the node, allocation will be retried "
if n.conf.IPAMMode() == ipamOption.IPAMCRD {
msg += "once IPs are added to CiliumNode spec.ipam.pool"
} else {
msg += "once Cilium Operator allocates more IPs"
}
return nil, nil, errors.New(msg)
}

// totalPoolSize returns the total size of the allocation pool
Expand Down
5 changes: 5 additions & 0 deletions pkg/shell/server/shell_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package shell
import (
"bufio"
"context"
"errors"
"fmt"
"log/slog"
"net"
Expand Down Expand Up @@ -84,6 +85,10 @@ func (sh shell) listener(ctx context.Context, health cell.Health) error {
for ctx.Err() == nil {
conn, err := l.Accept()
if err != nil {
// If context is cancelled, the listener was closed gracefully
if errors.Is(ctx.Err(), context.Canceled) {
return nil
}
return fmt.Errorf("accept failed: %w", err)
}
sh.jg.Add(job.OneShot(
Expand Down
Loading