Merge pull request #5853 from claudiubelu/integration/windows-hostprocess
integration: Adds Windows HostProcess tests
This commit is contained in:
		| @@ -192,6 +192,17 @@ func PodSandboxConfigWithCleanup(t *testing.T, name, ns string, opts ...PodSandb | ||||
| 	return sb, sbConfig | ||||
| } | ||||
|  | ||||
| // Set Windows HostProcess. | ||||
| func WithWindowsHostProcess(p *runtime.PodSandboxConfig) { //nolint:unused | ||||
| 	if p.Windows == nil { | ||||
| 		p.Windows = &runtime.WindowsPodSandboxConfig{} | ||||
| 	} | ||||
| 	if p.Windows.SecurityContext == nil { | ||||
| 		p.Windows.SecurityContext = &runtime.WindowsSandboxSecurityContext{} | ||||
| 	} | ||||
| 	p.Windows.SecurityContext.HostProcess = true | ||||
| } | ||||
|  | ||||
| // ContainerOpts to set any specific attribute like labels, | ||||
| // annotations, metadata etc | ||||
| type ContainerOpts func(*runtime.ContainerConfig) | ||||
| @@ -227,6 +238,18 @@ func WithVolumeMount(hostPath, containerPath string) ContainerOpts { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func WithWindowsUsername(username string) ContainerOpts { //nolint:unused | ||||
| 	return func(c *runtime.ContainerConfig) { | ||||
| 		if c.Windows == nil { | ||||
| 			c.Windows = &runtime.WindowsContainerConfig{} | ||||
| 		} | ||||
| 		if c.Windows.SecurityContext == nil { | ||||
| 			c.Windows.SecurityContext = &runtime.WindowsContainerSecurityContext{} | ||||
| 		} | ||||
| 		c.Windows.SecurityContext.RunAsUsername = username | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Add container command. | ||||
| func WithCommand(cmd string, args ...string) ContainerOpts { | ||||
| 	return func(c *runtime.ContainerConfig) { | ||||
|   | ||||
							
								
								
									
										92
									
								
								integration/windows_hostprocess_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								integration/windows_hostprocess_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| //go:build windows | ||||
| // +build windows | ||||
|  | ||||
| /* | ||||
|    Copyright The containerd Authors. | ||||
|  | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
|  | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| */ | ||||
|  | ||||
| package integration | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	defaultCommand       = WithCommand("Powershell", "/c", "$env:CONTAINER_SANDBOX_MOUNT_POINT/pause.exe") | ||||
| 	localServiceUsername = WithWindowsUsername("NT AUTHORITY\\Local service") | ||||
| 	localSystemUsername  = WithWindowsUsername("NT AUTHORITY\\System") | ||||
| ) | ||||
|  | ||||
| // Tests to verify the Windows HostProcess | ||||
| func TestWindowsHostProcess(t *testing.T) { | ||||
| 	EnsureImageExists(t, pauseImage) | ||||
|  | ||||
| 	t.Run("run as Local Service", func(t *testing.T) { | ||||
| 		runHostProcess(t, false, pauseImage, localServiceUsername, defaultCommand) | ||||
| 	}) | ||||
| 	t.Run("run as Local System", func(t *testing.T) { | ||||
| 		runHostProcess(t, false, pauseImage, localSystemUsername, defaultCommand) | ||||
| 	}) | ||||
| 	t.Run("run as unacceptable user", func(t *testing.T) { | ||||
| 		runHostProcess(t, true, pauseImage, WithWindowsUsername("Guest"), defaultCommand) | ||||
| 	}) | ||||
| 	t.Run("run command on host", func(t *testing.T) { | ||||
| 		cmd := WithCommand("Powershell", "/c", "Get-Command containerd.exe") | ||||
| 		runHostProcess(t, false, pauseImage, localServiceUsername, cmd) | ||||
| 	}) | ||||
| 	t.Run("run withHostNetwork", func(t *testing.T) { | ||||
| 		hostname, err := os.Hostname() | ||||
| 		require.NoError(t, err) | ||||
| 		cmd := WithCommand("Powershell", "/c", fmt.Sprintf("if ($env:COMPUTERNAME -ne %s) { exit -1 }", hostname)) | ||||
| 		runHostProcess(t, false, pauseImage, localServiceUsername, cmd) | ||||
| 	}) | ||||
| 	t.Run("run with a different os.version image", func(t *testing.T) { | ||||
| 		image := "docker.io/e2eteam/busybox:1.29-windows-amd64-1909" | ||||
| 		EnsureImageExists(t, image) | ||||
| 		runHostProcess(t, false, image, localServiceUsername, defaultCommand) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func runHostProcess(t *testing.T, expectErr bool, image string, opts ...ContainerOpts) { | ||||
| 	t.Logf("Create a pod config and run sandbox container") | ||||
| 	sb, sbConfig := PodSandboxConfigWithCleanup(t, "sandbox1", "hostprocess", WithWindowsHostProcess) | ||||
|  | ||||
| 	t.Logf("Create a container config and run container in a pod") | ||||
| 	containerConfig := ContainerConfig( | ||||
| 		"container1", | ||||
| 		image, | ||||
| 		opts..., | ||||
| 	) | ||||
| 	cn, err := runtimeService.CreateContainer(sb, containerConfig, sbConfig) | ||||
| 	require.NoError(t, err) | ||||
| 	defer func() { | ||||
| 		assert.NoError(t, runtimeService.RemoveContainer(cn)) | ||||
| 	}() | ||||
| 	_, err = t, runtimeService.StartContainer(cn) | ||||
| 	if err != nil { | ||||
| 		if !expectErr { | ||||
| 			t.Fatalf("Unexpected error while starting Container: %v", err) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		assert.NoError(t, runtimeService.StopContainer(cn, 10)) | ||||
| 	}() | ||||
| } | ||||
| @@ -44,8 +44,6 @@ ${sudo} bin/cri-integration.test --test.run="${FOCUS}" --test.v \ | ||||
|   --cri-root="${CRI_ROOT}" \ | ||||
|   --runtime-handler="${RUNTIME}" \ | ||||
|   --containerd-bin="${CONTAINERD_BIN}" \ | ||||
|   --image-list="${TEST_IMAGE_LIST:-}" | ||||
|  | ||||
| test_exit_code=$? | ||||
|   --image-list="${TEST_IMAGE_LIST:-}" && test_exit_code=$? || test_exit_code=$? | ||||
|  | ||||
| exit ${test_exit_code} | ||||
|   | ||||
| @@ -96,9 +96,21 @@ test_setup() { | ||||
|   set -m | ||||
|   # Create containerd in a different process group | ||||
|   # so that we can easily clean them up. | ||||
|   keepalive "${sudo} bin/containerd ${CONTAINERD_FLAGS}" \ | ||||
|     "${RESTART_WAIT_PERIOD}" &> "${report_dir}/containerd.log" & | ||||
|   pid=$! | ||||
|   if [ $IS_WINDOWS -eq 0 ]; then | ||||
|     keepalive "${sudo} bin/containerd ${CONTAINERD_FLAGS}" \ | ||||
|       "${RESTART_WAIT_PERIOD}" &> "${report_dir}/containerd.log" & | ||||
|     pid=$! | ||||
|   else | ||||
|     # NOTE(claudiub): For Windows HostProcess containers, containerd needs to be privileged enough to | ||||
|     # start them. For this, we can register containerd as a service, so the LocalSystem will run it | ||||
|     # for us. Additionally, we don't need to worry about keeping it alive, Windows will do it for us. | ||||
|     nssm install containerd-test "$(pwd)/bin/containerd.exe" ${CONTAINERD_FLAGS} \ | ||||
|       --log-file "${report_dir}/containerd.log" | ||||
|  | ||||
|     # it might still result in SERVICE_START_PENDING, but we can ignore it. | ||||
|     nssm start containerd-test || true | ||||
|     pid="1"  # for teardown | ||||
|   fi | ||||
|   set +m | ||||
|  | ||||
|   # Wait for containerd to be running by using the containerd client ctr to check the version | ||||
| @@ -116,9 +128,8 @@ test_setup() { | ||||
| test_teardown() { | ||||
|   if [ -n "${pid}" ]; then | ||||
|     if [ $IS_WINDOWS -eq 1 ]; then | ||||
|       # NOTE(claudiub): The containerd process will have the same PGID as the keepalive process, | ||||
|       # so we can kill both of them by matching the PGID. | ||||
|       ${sudo} ps | awk "{if (\$3 == ${pid}) print \$1}" | xargs kill | ||||
|       nssm stop containerd-test | ||||
|       nssm remove containerd-test confirm | ||||
|     else | ||||
|       ${sudo} pkill -g $(ps -o pgid= -p "${pid}") | ||||
|     fi | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Estes
					Phil Estes