@@ -24,6 +24,7 @@ import (
24
24
"github.com/pkg/errors"
25
25
corev1 "k8s.io/api/core/v1"
26
26
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27
28
"k8s.io/klog/v2"
28
29
ctrl "sigs.k8s.io/controller-runtime"
29
30
"sigs.k8s.io/controller-runtime/pkg/client"
41
42
ErrNodeNotFound = errors .New ("cannot find node with matching ProviderID" )
42
43
)
43
44
44
- func (r * Reconciler ) reconcileNode (ctx context.Context , cluster * clusterv1. Cluster , machine * clusterv1. Machine ) (ctrl.Result , error ) {
45
+ func (r * Reconciler ) reconcileNode (ctx context.Context , s * scope ) (ctrl.Result , error ) {
45
46
log := ctrl .LoggerFrom (ctx )
47
+ cluster := s .cluster
48
+ machine := s .machine
49
+ infraMachine := s .infraMachine
46
50
47
51
// Create a watch on the nodes in the Cluster.
48
52
if err := r .watchClusterNodes (ctx , cluster ); err != nil {
@@ -112,10 +116,32 @@ func (r *Reconciler) reconcileNode(ctx context.Context, cluster *clusterv1.Clust
112
116
// NOTE: Once we reconcile node labels for the first time, the NodeUninitializedTaint is removed from the node.
113
117
nodeLabels := getManagedLabels (machine .Labels )
114
118
119
+ // Get interruptible instance status from the infrastructure provider and set the interruptible label on the node.
120
+ interruptible := false
121
+ found := false
122
+ if infraMachine != nil {
123
+ interruptible , found , err = unstructured .NestedBool (infraMachine .Object , "status" , "interruptible" )
124
+ if err != nil {
125
+ return ctrl.Result {}, errors .Wrapf (err , "failed to get status interruptible from infra machine %s" , klog .KObj (infraMachine ))
126
+ }
127
+ // If interruptible is set and is true add the interruptible label to the node labels.
128
+ if found && interruptible {
129
+ nodeLabels [clusterv1 .InterruptibleLabel ] = ""
130
+ }
131
+ }
132
+
133
+ _ , nodeHadInterruptibleLabel := node .Labels [clusterv1 .InterruptibleLabel ]
134
+
115
135
// Reconcile node taints
116
136
if err := r .patchNode (ctx , remoteClient , node , nodeLabels , nodeAnnotations ); err != nil {
117
137
return ctrl.Result {}, errors .Wrapf (err , "failed to reconcile Node %s" , klog .KObj (node ))
118
138
}
139
+ if ! nodeHadInterruptibleLabel && interruptible {
140
+ // If the interruptible label is added to the node then record the event.
141
+ // Nb. Only record the event if the node previously did not have the label to avoid recording
142
+ // the event during every reconcile.
143
+ r .recorder .Event (machine , corev1 .EventTypeNormal , "SuccessfulSetInterruptibleNodeLabel" , node .Name )
144
+ }
119
145
120
146
// Do the remaining node health checks, then set the node health to true if all checks pass.
121
147
status , message := summarizeNodeConditions (node )
0 commit comments