k8s.io/kubernetes@v1.29.3/test/e2e_node/os_label_rename_test.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2021 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package e2enode
    21  
    22  import (
    23  	"context"
    24  	"fmt"
    25  	"runtime"
    26  	"time"
    27  
    28  	"github.com/onsi/ginkgo/v2"
    29  
    30  	v1 "k8s.io/api/core/v1"
    31  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    32  	"k8s.io/apimachinery/pkg/types"
    33  	"k8s.io/apimachinery/pkg/util/wait"
    34  	v1core "k8s.io/client-go/kubernetes/typed/core/v1"
    35  	nodeutil "k8s.io/component-helpers/node/util"
    36  	"k8s.io/kubernetes/test/e2e/framework"
    37  	e2enode "k8s.io/kubernetes/test/e2e/framework/node"
    38  	admissionapi "k8s.io/pod-security-admission/api"
    39  )
    40  
    41  var _ = SIGDescribe("OSArchLabelReconciliation", framework.WithSerial(), framework.WithSlow(), framework.WithDisruptive(), func() {
    42  	f := framework.NewDefaultFramework("node-label-reconciliation")
    43  	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
    44  	ginkgo.Context("Kubelet", func() {
    45  		ginkgo.It("should reconcile the OS and Arch labels when restarted", func(ctx context.Context) {
    46  			node := getLocalNode(ctx, f)
    47  			e2enode.ExpectNodeHasLabel(ctx, f.ClientSet, node.Name, v1.LabelOSStable, runtime.GOOS)
    48  			e2enode.ExpectNodeHasLabel(ctx, f.ClientSet, node.Name, v1.LabelArchStable, runtime.GOARCH)
    49  
    50  			ginkgo.By("killing and restarting kubelet")
    51  			// Let's kill the kubelet
    52  			startKubelet := stopKubelet()
    53  			// Update labels
    54  			newNode := node.DeepCopy()
    55  			newNode.Labels[v1.LabelOSStable] = "dummyOS"
    56  			newNode.Labels[v1.LabelArchStable] = "dummyArch"
    57  			_, _, err := nodeutil.PatchNodeStatus(f.ClientSet.CoreV1(), types.NodeName(node.Name), node, newNode)
    58  			framework.ExpectNoError(err)
    59  			// Restart kubelet
    60  			startKubelet()
    61  			framework.ExpectNoError(e2enode.WaitForAllNodesSchedulable(ctx, f.ClientSet, framework.RestartNodeReadyAgainTimeout))
    62  			// If this happens right, node should have all the labels reset properly
    63  			err = waitForNodeLabels(ctx, f.ClientSet.CoreV1(), node.Name, 5*time.Minute)
    64  			framework.ExpectNoError(err)
    65  		})
    66  		ginkgo.It("should reconcile the OS and Arch labels when running", func(ctx context.Context) {
    67  
    68  			node := getLocalNode(ctx, f)
    69  			e2enode.ExpectNodeHasLabel(ctx, f.ClientSet, node.Name, v1.LabelOSStable, runtime.GOOS)
    70  			e2enode.ExpectNodeHasLabel(ctx, f.ClientSet, node.Name, v1.LabelArchStable, runtime.GOARCH)
    71  
    72  			// Update labels
    73  			newNode := node.DeepCopy()
    74  			newNode.Labels[v1.LabelOSStable] = "dummyOS"
    75  			newNode.Labels[v1.LabelArchStable] = "dummyArch"
    76  			_, _, err := nodeutil.PatchNodeStatus(f.ClientSet.CoreV1(), types.NodeName(node.Name), node, newNode)
    77  			framework.ExpectNoError(err)
    78  			err = waitForNodeLabels(ctx, f.ClientSet.CoreV1(), node.Name, 5*time.Minute)
    79  			framework.ExpectNoError(err)
    80  		})
    81  	})
    82  })
    83  
    84  // waitForNodeLabels waits for the nodes to be have appropriate labels.
    85  func waitForNodeLabels(ctx context.Context, c v1core.CoreV1Interface, nodeName string, timeout time.Duration) error {
    86  	ginkgo.By(fmt.Sprintf("Waiting for node %v to have appropriate labels", nodeName))
    87  	// Poll until the node has desired labels
    88  	return wait.PollWithContext(ctx, framework.Poll, timeout,
    89  		func(ctx context.Context) (bool, error) {
    90  			node, err := c.Nodes().Get(ctx, nodeName, metav1.GetOptions{})
    91  			if err != nil {
    92  				return false, err
    93  			}
    94  			osLabel, ok := node.Labels[v1.LabelOSStable]
    95  			if !ok || osLabel != runtime.GOOS {
    96  				return false, nil
    97  			}
    98  			archLabel, ok := node.Labels[v1.LabelArchStable]
    99  			if !ok || archLabel != runtime.GOARCH {
   100  				return false, nil
   101  			}
   102  			return true, nil
   103  		})
   104  }