Windows CI: Add support for testing with containerd
| ... | ... |
@@ -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") != ""
|