1
16
17 package windows
18
19 import (
20 "context"
21 "time"
22
23 "github.com/onsi/ginkgo/v2"
24 "github.com/onsi/gomega"
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/kubernetes/test/e2e/feature"
28 "k8s.io/kubernetes/test/e2e/framework"
29 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
30 e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
31 imageutils "k8s.io/kubernetes/test/utils/image"
32 admissionapi "k8s.io/pod-security-admission/api"
33 )
34
35 var (
36 WindowsHyperVContainerRuntimeClass = "runhcs-wcow-hypervisor"
37 )
38
39 var _ = sigDescribe(feature.WindowsHyperVContainers, "HyperV containers", skipUnlessWindows(func() {
40 ginkgo.BeforeEach(func() {
41 e2eskipper.SkipUnlessNodeOSDistroIs("windows")
42 })
43
44 f := framework.NewDefaultFramework("windows-hyperv-test")
45 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
46
47 ginkgo.It("should start a hyperv isolated container", func(ctx context.Context) {
48
49
50 skipUnlessContainerdOneSevenOrGreater(ctx, f)
51
52
53
54
55
56 _, err := f.ClientSet.NodeV1().RuntimeClasses().Get(ctx, WindowsHyperVContainerRuntimeClass, metav1.GetOptions{})
57 if err != nil {
58 framework.Logf("error getting runtime class: %v", err)
59 e2eskipper.Skipf("skipping test because runhcs-wcow-hypervisor runtime class is not present")
60 }
61
62 ginkgo.By("selecting a Windows node")
63 targetNode, err := findWindowsNode(ctx, f)
64 framework.ExpectNoError(err, "error finding Windows node")
65 framework.Logf("Using node: %v", targetNode.Name)
66
67 ginkgo.By("schedule a pod to that node")
68 image := imageutils.GetE2EImage(imageutils.BusyBox)
69 hypervPodName := "hyperv-test-pod"
70 hypervPod := &v1.Pod{
71 ObjectMeta: metav1.ObjectMeta{
72 Name: hypervPodName,
73 },
74 Spec: v1.PodSpec{
75 Containers: []v1.Container{
76 {
77 Image: image,
78 Name: "busybox-1",
79 Command: []string{"powershell.exe", "-Command", "Write-Host 'Hello'; sleep -Seconds 600"},
80 },
81 {
82 Image: image,
83 Name: "busybox-2",
84 Command: []string{"powershell.exe", "-Command", "Write-Host 'Hello'; sleep -Seconds 600"},
85 },
86 },
87 RestartPolicy: v1.RestartPolicyNever,
88 RuntimeClassName: &WindowsHyperVContainerRuntimeClass,
89 NodeName: targetNode.Name,
90 },
91 }
92
93 pc := e2epod.NewPodClient(f)
94
95 pc.Create(ctx, hypervPod)
96 ginkgo.By("waiting for the pod to be running")
97 timeout := 3 * time.Minute
98 e2epod.WaitForPodsRunningReady(ctx, f.ClientSet, f.Namespace.Name, 1, 0, timeout)
99
100 ginkgo.By("creating a host process container in another pod to verify the pod is running hyperv isolated containers")
101
102
103
104 podName := "validation-pod"
105 pod := &v1.Pod{
106 ObjectMeta: metav1.ObjectMeta{
107 Name: podName,
108 },
109 Spec: v1.PodSpec{
110 SecurityContext: &v1.PodSecurityContext{
111 WindowsOptions: &v1.WindowsSecurityContextOptions{
112 HostProcess: &trueVar,
113 RunAsUserName: &User_NTAuthoritySystem,
114 },
115 },
116 HostNetwork: true,
117 Containers: []v1.Container{
118 {
119 Image: image,
120 Name: "container",
121 Command: []string{"powershell.exe", "-Command", "$vms = Get-ComputeProcess | Where-Object { ($_.Type -EQ 'VirtualMachine') -and ($_.Owner -EQ 'containerd-shim-runhcs-v1.exe') } ; if ($vms.Length -le 0) { throw 'error' }"},
122 },
123 },
124 RestartPolicy: v1.RestartPolicyNever,
125 NodeName: targetNode.Name,
126 },
127 }
128
129 pc.Create(ctx, pod)
130 ginkgo.By("waiting for the pod to be run")
131 pc.WaitForFinish(ctx, podName, timeout)
132
133 ginkgo.By("then ensuring pod finished running successfully")
134 p, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(ctx, podName, metav1.GetOptions{})
135 framework.ExpectNoError(err, "error getting pod")
136
137 if p.Status.Phase != v1.PodSucceeded {
138 logs, err := e2epod.GetPodLogs(ctx, f.ClientSet, f.Namespace.Name, podName, "container")
139 if err != nil {
140 framework.Logf("Error pulling logs: %v", err)
141 }
142 framework.Logf("Pod phase: %v\nlogs:\n%s", p.Status.Phase, logs)
143 }
144
145 gomega.Expect(p.Status.Phase).To(gomega.Equal(v1.PodSucceeded), "pod should have succeeded")
146 })
147 }))
148
View as plain text