Browse code

Merge pull request #41479 from olljanat/ci-win-containerd-support

Windows CI: Add support for testing with containerd

Sebastiaan van Stijn authored on 2021/08/25 05:29:14
Showing 13 changed files
... ...
@@ -166,12 +166,15 @@ FROM microsoft/windowsservercore
166 166
 SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
167 167
 
168 168
 ARG GO_VERSION=1.16.7
169
+ARG CONTAINERD_VERSION=1.5.5
169 170
 ARG GOTESTSUM_COMMIT=v0.5.3
170 171
 
171 172
 # Environment variable notes:
172 173
 #  - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
174
+#  - CONTAINERD_VERSION must be consistent with 'hack/dockerfile/install/containerd.installer' used by Linux.
173 175
 #  - FROM_DOCKERFILE is used for detection of building within a container.
174 176
 ENV GO_VERSION=${GO_VERSION} `
177
+    CONTAINERD_VERSION=${CONTAINERD_VERSION} `
175 178
     GIT_VERSION=2.11.1 `
176 179
     GOPATH=C:\gopath `
177 180
     GO111MODULE=off `
... ...
@@ -211,7 +214,7 @@ RUN `
211 211
     } `
212 212
   } `
213 213
   `
214
-  setx /M PATH $('C:\git\cmd;C:\git\usr\bin;'+$Env:PATH+';C:\gcc\bin;C:\go\bin'); `
214
+  setx /M PATH $('C:\git\cmd;C:\git\usr\bin;'+$Env:PATH+';C:\gcc\bin;C:\go\bin;C:\containerd\bin'); `
215 215
   `
216 216
   Write-Host INFO: Downloading git...; `
217 217
   $location='https://www.nuget.org/api/v2/package/GitForWindows/'+$Env:GIT_VERSION; `
... ...
@@ -252,6 +255,16 @@ RUN `
252 252
   Remove-Item C:\binutils.zip; `
253 253
   Remove-Item C:\gitsetup.zip; `
254 254
   `
255
+  Write-Host INFO: Downloading containerd; `
256
+  Install-Package -Force 7Zip4PowerShell; `
257
+  $location='https://github.com/containerd/containerd/releases/download/v'+$Env:CONTAINERD_VERSION+'/containerd-'+$Env:CONTAINERD_VERSION+'-windows-amd64.tar.gz'; `
258
+  Download-File $location C:\containerd.tar.gz; `
259
+  New-Item -Path C:\containerd -ItemType Directory; `
260
+  Expand-7Zip C:\containerd.tar.gz C:\; `
261
+  Expand-7Zip C:\containerd.tar C:\containerd; `
262
+  Remove-Item C:\containerd.tar.gz; `
263
+  Remove-Item C:\containerd.tar; `
264
+  `
255 265
   # Ensure all directories exist that we will require below....
256 266
   $srcDir = """$Env:GOPATH`\src\github.com\docker\docker\bundles"""; `
257 267
   Write-Host INFO: Ensuring existence of directory $srcDir...; `
... ...
@@ -1308,7 +1308,7 @@ pipeline {
1308 1308
                                 Write-Host -ForegroundColor Green "Creating ${bundleName}-bundles.zip"
1309 1309
 
1310 1310
                                 # archiveArtifacts does not support env-vars to , so save the artifacts in a fixed location
1311
-                                Compress-Archive -Path "bundles/CIDUT.out", "bundles/CIDUT.err", "bundles/junit-report-*.xml" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip"
1311
+                                Compress-Archive -Path "bundles/CIDUT.out", "bundles/CIDUT.err", "bundles/containerd.out", "bundles/containerd.err", "bundles/junit-report-*.xml" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip"
1312 1312
                                 '''
1313 1313
 
1314 1314
                                 archiveArtifacts artifacts: '*-bundles.zip', allowEmptyArchive: true
... ...
@@ -94,6 +94,6 @@ func newCgroupParent(config *config.Config) string {
94 94
 }
95 95
 
96 96
 func (cli *DaemonCli) initContainerD(_ context.Context) (func(time.Duration) error, error) {
97
-	system.InitContainerdRuntime(cli.Config.Experimental, cli.Config.ContainerdAddr)
97
+	system.InitContainerdRuntime(cli.Config.ContainerdAddr)
98 98
 	return nil, nil
99 99
 }
... ...
@@ -8,8 +8,8 @@ import (
8 8
 
9 9
 func (daemon *Daemon) getLibcontainerdCreateOptions(_ *container.Container) (string, interface{}, error) {
10 10
 	if system.ContainerdRuntimeSupported() {
11
-		// Set the runtime options to debug regardless of current logging level.
12
-		return "", &options.Options{Debug: true}, nil
11
+		opts := &options.Options{}
12
+		return "io.containerd.runhcs.v1", opts, nil
13 13
 	}
14 14
 	return "", nil, nil
15 15
 }
... ...
@@ -179,6 +179,13 @@ Function Nuke-Everything {
179 179
             }
180 180
         }
181 181
 
182
+        # Kill any spurious containerd.
183
+        $pids=$(get-process | where-object {$_.ProcessName -like 'containerd'}).id
184
+        foreach ($p in $pids) {
185
+            Write-Host "INFO: Killing containerd with PID $p"
186
+            Stop-Process -Id $p -Force -ErrorAction SilentlyContinue
187
+        }
188
+
182 189
         Stop-Process -name "cc1" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
183 190
         Stop-Process -name "link" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
184 191
         Stop-Process -name "compile" -Force -ErrorAction SilentlyContinue 2>&1 | Out-Null
... ...
@@ -521,6 +528,15 @@ Try {
521 521
             Throw "ERROR: gotestsum.exe not found...." `
522 522
         }
523 523
 
524
+        docker cp "$COMMITHASH`:c`:\containerd\bin\containerd.exe" $env:TEMP\binary\
525
+        if (-not (Test-Path "$env:TEMP\binary\containerd.exe")) {
526
+            Throw "ERROR: containerd.exe not found...." `
527
+        }
528
+        docker cp "$COMMITHASH`:c`:\containerd\bin\containerd-shim-runhcs-v1.exe" $env:TEMP\binary\
529
+        if (-not (Test-Path "$env:TEMP\binary\containerd-shim-runhcs-v1.exe")) {
530
+            Throw "ERROR: containerd-shim-runhcs-v1.exe not found...." `
531
+        }
532
+
524 533
         $ErrorActionPreference = "Stop"
525 534
 
526 535
         # Copy the built dockerd.exe to dockerd-$COMMITHASH.exe so that easily spotted in task manager.
... ...
@@ -566,8 +582,10 @@ Try {
566 566
     $env:GOPATH="$env:SOURCES_DRIVE`:\$env:SOURCES_SUBDIR"
567 567
     Write-Host -ForegroundColor Green "INFO: GOPATH=$env:GOPATH"
568 568
 
569
-    # Set the path to have the version of go from the image at the front
570
-    $env:PATH="$env:TEMP\go\bin;$env:PATH"
569
+    # Set the path to have:
570
+    # - the version of go from the image at the front
571
+    # - the test binaries, not the host ones.
572
+    $env:PATH="$env:TEMP\go\bin;$env:TEMP\binary;$env:PATH"
571 573
 
572 574
     # Set the GOROOT to be our copy of go from the image
573 575
     $env:GOROOT="$env:TEMP\go"
... ...
@@ -594,6 +612,12 @@ Try {
594 594
         $dutArgs += "-D"
595 595
     }
596 596
 
597
+    # Arguments: Are we starting the daemon under test in containerd mode?
598
+    if (-not ("$env:DOCKER_WINDOWS_CONTAINERD_RUNTIME" -eq "")) {
599
+        Write-Host -ForegroundColor Green "INFO: Running the daemon under test in containerd mode"
600
+        $dutArgs += "--containerd \\.\pipe\containerd-containerd"
601
+    }
602
+
597 603
     # Arguments: Are we starting the daemon under test with Hyper-V containers as the default isolation?
598 604
     if (-not ("$env:DOCKER_DUT_HYPERV" -eq "")) {
599 605
         Write-Host -ForegroundColor Green "INFO: Running the daemon under test with Hyper-V containers as the default"
... ...
@@ -616,6 +640,15 @@ Try {
616 616
     Write-Host -ForegroundColor Green "INFO: Args: $dutArgs"
617 617
     New-Item -ItemType Directory $env:TEMP\daemon -ErrorAction SilentlyContinue  | Out-Null
618 618
 
619
+    # Start containerd first
620
+    if (-not ("$env:DOCKER_WINDOWS_CONTAINERD_RUNTIME" -eq "")) {
621
+        Start-Process "$env:TEMP\binary\containerd.exe" `
622
+                    -ArgumentList "--log-level debug" `
623
+                    -RedirectStandardOutput "$env:TEMP\containerd.out" `
624
+                    -RedirectStandardError "$env:TEMP\containerd.err"
625
+        Write-Host -ForegroundColor Green "INFO: Containerd started successfully."
626
+    }
627
+
619 628
     # Cannot fathom why, but always writes to stderr....
620 629
     Start-Process "$env:TEMP\binary\dockerd-$COMMITHASH" `
621 630
                   -ArgumentList $dutArgs `
... ...
@@ -840,7 +873,6 @@ Try {
840 840
                                                     "`$env`:PATH`='c`:\target;'+`$env:PATH`;  `$env:DOCKER_HOST`='tcp`://'+(ipconfig | select -last 1).Substring(39)+'`:2357'; c:\target\runIntegrationCLI.ps1" | Out-Host } )
841 841
         } else  {
842 842
             $env:DOCKER_HOST=$DASHH_CUT
843
-            $env:PATH="$env:TEMP\binary;$env:PATH;"  # Force to use the test binaries, not the host ones.
844 843
                 $env:GO111MODULE="off"
845 844
             Write-Host -ForegroundColor Green "INFO: DOCKER_HOST at $DASHH_CUT"
846 845
 
... ...
@@ -943,6 +975,15 @@ Finally {
943 943
         Copy-Item  "$env:TEMP\dut.out" "bundles\CIDUT.out" -Force -ErrorAction SilentlyContinue
944 944
         Write-Host -ForegroundColor Green "INFO: Saving daemon under test log ($env:TEMP\dut.err) to bundles\CIDUT.err"
945 945
         Copy-Item  "$env:TEMP\dut.err" "bundles\CIDUT.err" -Force -ErrorAction SilentlyContinue
946
+
947
+        Write-Host -ForegroundColor Green "INFO: Saving containerd logs to bundles"
948
+        if (Test-Path -Path "$env:TEMP\containerd.out") {
949
+            Copy-Item "$env:TEMP\containerd.out" "bundles\containerd.out" -Force -ErrorAction SilentlyContinue
950
+            Copy-Item "$env:TEMP\containerd.err" "bundles\containerd.err" -Force -ErrorAction SilentlyContinue
951
+        } else {
952
+            "" | Out-File -FilePath "bundles\containerd.out"
953
+            "" | Out-File -FilePath "bundles\containerd.err"
954
+        }
946 955
     }
947 956
 
948 957
     Set-Location "$env:SOURCES_DRIVE\$env:SOURCES_SUBDIR" -ErrorAction SilentlyContinue
... ...
@@ -18,11 +18,13 @@ import (
18 18
 	"github.com/docker/docker/client"
19 19
 	"github.com/docker/docker/testutil/request"
20 20
 	"gotest.tools/v3/assert"
21
+	"gotest.tools/v3/skip"
21 22
 )
22 23
 
23 24
 var expectedNetworkInterfaceStats = strings.Split("rx_bytes rx_dropped rx_errors rx_packets tx_bytes tx_dropped tx_errors tx_packets", " ")
24 25
 
25 26
 func (s *DockerSuite) TestAPIStatsNoStreamGetCpu(c *testing.T) {
27
+	skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
26 28
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "while true;usleep 100; do echo 'Hello'; done")
27 29
 
28 30
 	id := strings.TrimSpace(out)
... ...
@@ -98,6 +100,7 @@ func (s *DockerSuite) TestAPIStatsStoppedContainerInGoroutines(c *testing.T) {
98 98
 }
99 99
 
100 100
 func (s *DockerSuite) TestAPIStatsNetworkStats(c *testing.T) {
101
+	skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
101 102
 	testRequires(c, testEnv.IsLocalDaemon)
102 103
 
103 104
 	out := runSleepingContainer(c)
... ...
@@ -7,9 +7,11 @@ import (
7 7
 	"github.com/docker/docker/api/types/versions"
8 8
 	"github.com/docker/docker/integration-cli/cli"
9 9
 	"gotest.tools/v3/assert"
10
+	"gotest.tools/v3/skip"
10 11
 )
11 12
 
12 13
 func (s *DockerSuite) TestCommitAfterContainerIsDone(c *testing.T) {
14
+	skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
13 15
 	out := cli.DockerCmd(c, "run", "-i", "-a", "stdin", "busybox", "echo", "foo").Combined()
14 16
 
15 17
 	cleanedContainerID := strings.TrimSpace(out)
... ...
@@ -227,6 +227,7 @@ func (s *DockerSuite) TestPsListContainersFilterStatus(c *testing.T) {
227 227
 }
228 228
 
229 229
 func (s *DockerSuite) TestPsListContainersFilterHealth(c *testing.T) {
230
+	skip.If(c, RuntimeIsWindowsContainerd(), "FIXME. Hang on Windows + containerd combination")
230 231
 	existingContainers := ExistingContainerIDs(c)
231 232
 	// Test legacy no health check
232 233
 	out := runSleepingContainer(c, "--name=none_legacy")
... ...
@@ -36,6 +36,7 @@ import (
36 36
 	"github.com/moby/sys/mountinfo"
37 37
 	"gotest.tools/v3/assert"
38 38
 	"gotest.tools/v3/icmd"
39
+	"gotest.tools/v3/skip"
39 40
 )
40 41
 
41 42
 // "test123" should be printed by docker run
... ...
@@ -1983,6 +1984,7 @@ func (s *DockerSuite) TestRunCidFileCheckIDLength(c *testing.T) {
1983 1983
 }
1984 1984
 
1985 1985
 func (s *DockerSuite) TestRunSetMacAddress(c *testing.T) {
1986
+	skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
1986 1987
 	mac := "12:34:56:78:9a:bc"
1987 1988
 	var out string
1988 1989
 	if testEnv.OSType == "windows" {
... ...
@@ -181,6 +181,10 @@ func RegistryHosting() bool {
181 181
 	return err == nil
182 182
 }
183 183
 
184
+func RuntimeIsWindowsContainerd() bool {
185
+	return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
186
+}
187
+
184 188
 func SwarmInactive() bool {
185 189
 	return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive
186 190
 }
... ...
@@ -17,6 +17,7 @@ import (
17 17
 
18 18
 // TestExecWithCloseStdin adds case for moby#37870 issue.
19 19
 func TestExecWithCloseStdin(t *testing.T) {
20
+	skip.If(t, testEnv.RuntimeIsWindowsContainerd(), "FIXME. Hang on Windows + containerd combination")
20 21
 	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "broken in earlier versions")
21 22
 	defer setupTest(t)()
22 23
 
... ...
@@ -1,29 +1,18 @@
1 1
 package system // import "github.com/docker/docker/pkg/system"
2 2
 
3
-import (
4
-	"os"
5
-
6
-	"github.com/sirupsen/logrus"
7
-)
8
-
9 3
 var (
10
-	// containerdRuntimeSupported determines if ContainerD should be the runtime.
11
-	// As of March 2019, this is an experimental feature.
4
+	// containerdRuntimeSupported determines if containerd should be the runtime.
12 5
 	containerdRuntimeSupported = false
13 6
 )
14 7
 
15
-// InitContainerdRuntime sets whether to use ContainerD for runtime
16
-// on Windows. This is an experimental feature still in development, and
17
-// also requires an environment variable to be set (so as not to turn the
18
-// feature on from simply experimental which would also mean LCOW.
19
-func InitContainerdRuntime(experimental bool, cdPath string) {
20
-	if experimental && len(cdPath) > 0 && len(os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME")) > 0 {
21
-		logrus.Warnf("Using ContainerD runtime. This feature is experimental")
8
+// InitContainerdRuntime sets whether to use containerd for runtime on Windows.
9
+func InitContainerdRuntime(cdPath string) {
10
+	if len(cdPath) > 0 {
22 11
 		containerdRuntimeSupported = true
23 12
 	}
24 13
 }
25 14
 
26
-// ContainerdRuntimeSupported returns true if the use of ContainerD runtime is supported.
15
+// ContainerdRuntimeSupported returns true if the use of containerd runtime is supported.
27 16
 func ContainerdRuntimeSupported() bool {
28 17
 	return containerdRuntimeSupported
29 18
 }
... ...
@@ -162,6 +162,11 @@ func (e *Execution) IsUserNamespace() bool {
162 162
 	return root != ""
163 163
 }
164 164
 
165
+// RuntimeIsWindowsContainerd returns whether containerd runtime is used on Windows
166
+func (e *Execution) RuntimeIsWindowsContainerd() bool {
167
+	return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
168
+}
169
+
165 170
 // IsRootless returns whether the rootless mode is enabled
166 171
 func (e *Execution) IsRootless() bool {
167 172
 	return os.Getenv("DOCKER_ROOTLESS") != ""