[19.03 backport] Testing and Jenkinsfile changes [step 1]
| ... | ... |
@@ -36,7 +36,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/
|
| 36 | 36 |
FROM base AS criu |
| 37 | 37 |
ARG DEBIAN_FRONTEND |
| 38 | 38 |
# Install CRIU for checkpoint/restore support |
| 39 |
-ENV CRIU_VERSION 3.11 |
|
| 39 |
+ENV CRIU_VERSION 3.12 |
|
| 40 | 40 |
# Install dependency packages specific to criu |
| 41 | 41 |
RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 42 | 42 |
libnet-dev \ |
| ... | ... |
@@ -281,8 +281,6 @@ COPY --from=djs55/vpnkit@sha256:e508a17cfacc8fd39261d5b4e397df2b953690da577e2c98 |
| 281 | 281 |
|
| 282 | 282 |
ENV PATH=/usr/local/cli:$PATH |
| 283 | 283 |
ENV DOCKER_BUILDTAGS apparmor seccomp selinux |
| 284 |
-# Options for hack/validate/gometalinter |
|
| 285 |
-ENV GOMETALINTER_OPTS="--deadline=2m" |
|
| 286 | 284 |
WORKDIR /go/src/github.com/docker/docker |
| 287 | 285 |
VOLUME /var/lib/docker |
| 288 | 286 |
# Wrap all commands in the "docker-in-docker" script to allow nested containers |
| ... | ... |
@@ -214,7 +214,8 @@ RUN ` |
| 214 | 214 |
Download-File $location C:\gitsetup.zip; ` |
| 215 | 215 |
` |
| 216 | 216 |
Write-Host INFO: Downloading go...; ` |
| 217 |
- Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION+'.windows-amd64.zip') C:\go.zip; `
|
|
| 217 |
+ $dlGoVersion=$Env:GO_VERSION -replace '\.0$',''; ` |
|
| 218 |
+ Download-File "https://golang.org/dl/go${dlGoVersion}.windows-amd64.zip" C:\go.zip; `
|
|
| 218 | 219 |
` |
| 219 | 220 |
Write-Host INFO: Downloading compiler 1 of 3...; ` |
| 220 | 221 |
Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip C:\gcc.zip; ` |
| ... | ... |
@@ -22,15 +22,27 @@ pipeline {
|
| 22 | 22 |
DOCKER_GRAPHDRIVER = 'overlay2' |
| 23 | 23 |
APT_MIRROR = 'cdn-fastly.deb.debian.org' |
| 24 | 24 |
CHECK_CONFIG_COMMIT = '78405559cfe5987174aa2cb6463b9b2c1b917255' |
| 25 |
+ TESTDEBUG = '0' |
|
| 25 | 26 |
TIMEOUT = '120m' |
| 26 | 27 |
} |
| 27 | 28 |
stages {
|
| 29 |
+ stage('pr-hack') {
|
|
| 30 |
+ when { changeRequest() }
|
|
| 31 |
+ steps {
|
|
| 32 |
+ script {
|
|
| 33 |
+ echo "Workaround for PR auto-cancel feature. Borrowed from https://issues.jenkins-ci.org/browse/JENKINS-43353" |
|
| 34 |
+ def buildNumber = env.BUILD_NUMBER as int |
|
| 35 |
+ if (buildNumber > 1) milestone(buildNumber - 1) |
|
| 36 |
+ milestone(buildNumber) |
|
| 37 |
+ } |
|
| 38 |
+ } |
|
| 39 |
+ } |
|
| 28 | 40 |
stage('DCO-check') {
|
| 29 | 41 |
when {
|
| 30 | 42 |
beforeAgent true |
| 31 | 43 |
expression { !params.skip_dco }
|
| 32 | 44 |
} |
| 33 |
- agent { label 'linux' }
|
|
| 45 |
+ agent { label 'amd64 && ubuntu-1804 && overlay2' }
|
|
| 34 | 46 |
steps {
|
| 35 | 47 |
sh ''' |
| 36 | 48 |
docker run --rm \ |
| ... | ... |
@@ -257,13 +269,13 @@ pipeline {
|
| 257 | 257 |
run_tests() {
|
| 258 | 258 |
[ -n "$TESTDEBUG" ] && rm= || rm=--rm; |
| 259 | 259 |
docker run $rm -t --privileged \ |
| 260 |
- -v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \ |
|
| 260 |
+ -v "$WORKSPACE/bundles/${TEST_INTEGRATION_DEST}:/go/src/github.com/docker/docker/bundles" \
|
|
| 261 |
+ -v "$WORKSPACE/bundles/dynbinary-daemon:/go/src/github.com/docker/docker/bundles/dynbinary-daemon" \ |
|
| 261 | 262 |
-v "$WORKSPACE/.git:/go/src/github.com/docker/docker/.git" \ |
| 262 | 263 |
--name "$CONTAINER_NAME" \ |
| 263 | 264 |
-e KEEPBUNDLE=1 \ |
| 264 | 265 |
-e TESTDEBUG \ |
| 265 | 266 |
-e TESTFLAGS \ |
| 266 |
- -e TEST_INTEGRATION_DEST \ |
|
| 267 | 267 |
-e TEST_SKIP_INTEGRATION \ |
| 268 | 268 |
-e TEST_SKIP_INTEGRATION_CLI \ |
| 269 | 269 |
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
|
| ... | ... |
@@ -308,6 +320,11 @@ pipeline {
|
| 308 | 308 |
exit $c |
| 309 | 309 |
''' |
| 310 | 310 |
} |
| 311 |
+ post {
|
|
| 312 |
+ always {
|
|
| 313 |
+ junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true |
|
| 314 |
+ } |
|
| 315 |
+ } |
|
| 311 | 316 |
} |
| 312 | 317 |
} |
| 313 | 318 |
|
| ... | ... |
@@ -315,7 +332,8 @@ pipeline {
|
| 315 | 315 |
always {
|
| 316 | 316 |
sh ''' |
| 317 | 317 |
echo "Ensuring container killed." |
| 318 |
- docker rm -vf docker-pr$BUILD_NUMBER || true |
|
| 318 |
+ cids=$(docker ps -aq -f name=docker-pr${BUILD_NUMBER}-*)
|
|
| 319 |
+ [ -n "$cids" ] && docker rm -vf $cids || true |
|
| 319 | 320 |
''' |
| 320 | 321 |
|
| 321 | 322 |
sh ''' |
| ... | ... |
@@ -328,7 +346,7 @@ pipeline {
|
| 328 | 328 |
bundleName=amd64 |
| 329 | 329 |
echo "Creating ${bundleName}-bundles.tar.gz"
|
| 330 | 330 |
# exclude overlay2 directories |
| 331 |
- find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 331 |
+ find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 332 | 332 |
''' |
| 333 | 333 |
|
| 334 | 334 |
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true |
| ... | ... |
@@ -397,6 +415,7 @@ pipeline {
|
| 397 | 397 |
-e DOCKER_EXPERIMENTAL \ |
| 398 | 398 |
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
|
| 399 | 399 |
-e DOCKER_GRAPHDRIVER \ |
| 400 |
+ -e TESTDEBUG \ |
|
| 400 | 401 |
-e TEST_SKIP_INTEGRATION_CLI \ |
| 401 | 402 |
-e TIMEOUT \ |
| 402 | 403 |
docker:${GIT_COMMIT} \
|
| ... | ... |
@@ -405,6 +424,11 @@ pipeline {
|
| 405 | 405 |
test-integration |
| 406 | 406 |
''' |
| 407 | 407 |
} |
| 408 |
+ post {
|
|
| 409 |
+ always {
|
|
| 410 |
+ junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true |
|
| 411 |
+ } |
|
| 412 |
+ } |
|
| 408 | 413 |
} |
| 409 | 414 |
} |
| 410 | 415 |
|
| ... | ... |
@@ -425,7 +449,7 @@ pipeline {
|
| 425 | 425 |
bundleName=s390x-integration |
| 426 | 426 |
echo "Creating ${bundleName}-bundles.tar.gz"
|
| 427 | 427 |
# exclude overlay2 directories |
| 428 |
- find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 428 |
+ find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 429 | 429 |
''' |
| 430 | 430 |
|
| 431 | 431 |
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true |
| ... | ... |
@@ -483,6 +507,11 @@ pipeline {
|
| 483 | 483 |
test-integration |
| 484 | 484 |
''' |
| 485 | 485 |
} |
| 486 |
+ post {
|
|
| 487 |
+ always {
|
|
| 488 |
+ junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true |
|
| 489 |
+ } |
|
| 490 |
+ } |
|
| 486 | 491 |
} |
| 487 | 492 |
} |
| 488 | 493 |
|
| ... | ... |
@@ -503,7 +532,7 @@ pipeline {
|
| 503 | 503 |
bundleName=s390x-integration-cli |
| 504 | 504 |
echo "Creating ${bundleName}-bundles.tar.gz"
|
| 505 | 505 |
# exclude overlay2 directories |
| 506 |
- find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 506 |
+ find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 507 | 507 |
''' |
| 508 | 508 |
|
| 509 | 509 |
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true |
| ... | ... |
@@ -570,6 +599,7 @@ pipeline {
|
| 570 | 570 |
-e DOCKER_EXPERIMENTAL \ |
| 571 | 571 |
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
|
| 572 | 572 |
-e DOCKER_GRAPHDRIVER \ |
| 573 |
+ -e TESTDEBUG \ |
|
| 573 | 574 |
-e TEST_SKIP_INTEGRATION_CLI \ |
| 574 | 575 |
-e TIMEOUT \ |
| 575 | 576 |
docker:${GIT_COMMIT} \
|
| ... | ... |
@@ -578,6 +608,11 @@ pipeline {
|
| 578 | 578 |
test-integration |
| 579 | 579 |
''' |
| 580 | 580 |
} |
| 581 |
+ post {
|
|
| 582 |
+ always {
|
|
| 583 |
+ junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true |
|
| 584 |
+ } |
|
| 585 |
+ } |
|
| 581 | 586 |
} |
| 582 | 587 |
} |
| 583 | 588 |
|
| ... | ... |
@@ -598,7 +633,7 @@ pipeline {
|
| 598 | 598 |
bundleName=ppc64le-integration |
| 599 | 599 |
echo "Creating ${bundleName}-bundles.tar.gz"
|
| 600 | 600 |
# exclude overlay2 directories |
| 601 |
- find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 601 |
+ find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 602 | 602 |
''' |
| 603 | 603 |
|
| 604 | 604 |
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true |
| ... | ... |
@@ -654,6 +689,11 @@ pipeline {
|
| 654 | 654 |
test-integration |
| 655 | 655 |
''' |
| 656 | 656 |
} |
| 657 |
+ post {
|
|
| 658 |
+ always {
|
|
| 659 |
+ junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true |
|
| 660 |
+ } |
|
| 661 |
+ } |
|
| 657 | 662 |
} |
| 658 | 663 |
} |
| 659 | 664 |
|
| ... | ... |
@@ -662,8 +702,6 @@ pipeline {
|
| 662 | 662 |
sh ''' |
| 663 | 663 |
echo "Ensuring container killed." |
| 664 | 664 |
docker rm -vf docker-pr$BUILD_NUMBER || true |
| 665 |
- cids=$(docker ps -aq -f name=docker-pr${BUILD_NUMBER}-*)
|
|
| 666 |
- [ -n "$cids" ] && docker rm -vf $cids || true |
|
| 667 | 665 |
''' |
| 668 | 666 |
|
| 669 | 667 |
sh ''' |
| ... | ... |
@@ -676,7 +714,7 @@ pipeline {
|
| 676 | 676 |
bundleName=ppc64le-integration-cli |
| 677 | 677 |
echo "Creating ${bundleName}-bundles.tar.gz"
|
| 678 | 678 |
# exclude overlay2 directories |
| 679 |
- find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 679 |
+ find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz
|
|
| 680 | 680 |
''' |
| 681 | 681 |
|
| 682 | 682 |
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true |
| ... | ... |
@@ -699,11 +737,12 @@ pipeline {
|
| 699 | 699 |
} |
| 700 | 700 |
environment {
|
| 701 | 701 |
DOCKER_BUILDKIT = '0' |
| 702 |
+ DOCKER_DUT_DEBUG = '1' |
|
| 702 | 703 |
SKIP_VALIDATION_TESTS = '1' |
| 703 | 704 |
SOURCES_DRIVE = 'd' |
| 704 | 705 |
SOURCES_SUBDIR = 'gopath' |
| 705 | 706 |
TESTRUN_DRIVE = 'd' |
| 706 |
- TESTRUN_SUBDIR = "CI-$BUILD_NUMBER" |
|
| 707 |
+ TESTRUN_SUBDIR = "CI" |
|
| 707 | 708 |
WINDOWS_BASE_IMAGE = 'mcr.microsoft.com/windows/servercore' |
| 708 | 709 |
WINDOWS_BASE_IMAGE_TAG = 'ltsc2016' |
| 709 | 710 |
} |
| ... | ... |
@@ -732,6 +771,25 @@ pipeline {
|
| 732 | 732 |
} |
| 733 | 733 |
} |
| 734 | 734 |
} |
| 735 |
+ post {
|
|
| 736 |
+ always {
|
|
| 737 |
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
|
|
| 738 |
+ powershell ''' |
|
| 739 |
+ $bundleName="windowsRS1-integration" |
|
| 740 |
+ Write-Host -ForegroundColor Green "Creating ${bundleName}-bundles.zip"
|
|
| 741 |
+ |
|
| 742 |
+ # archiveArtifacts does not support env-vars to , so save the artifacts in a fixed location |
|
| 743 |
+ Compress-Archive -Path "${env:TEMP}/CIDUT.out", "${env:TEMP}/CIDUT.err" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip"
|
|
| 744 |
+ ''' |
|
| 745 |
+ |
|
| 746 |
+ archiveArtifacts artifacts: '*-bundles.zip', allowEmptyArchive: true |
|
| 747 |
+ } |
|
| 748 |
+ } |
|
| 749 |
+ cleanup {
|
|
| 750 |
+ sh 'make clean' |
|
| 751 |
+ deleteDir() |
|
| 752 |
+ } |
|
| 753 |
+ } |
|
| 735 | 754 |
} |
| 736 | 755 |
stage('win-RS5') {
|
| 737 | 756 |
when {
|
| ... | ... |
@@ -740,11 +798,12 @@ pipeline {
|
| 740 | 740 |
} |
| 741 | 741 |
environment {
|
| 742 | 742 |
DOCKER_BUILDKIT = '0' |
| 743 |
+ DOCKER_DUT_DEBUG = '1' |
|
| 743 | 744 |
SKIP_VALIDATION_TESTS = '1' |
| 744 | 745 |
SOURCES_DRIVE = 'd' |
| 745 | 746 |
SOURCES_SUBDIR = 'gopath' |
| 746 | 747 |
TESTRUN_DRIVE = 'd' |
| 747 |
- TESTRUN_SUBDIR = "CI-$BUILD_NUMBER" |
|
| 748 |
+ TESTRUN_SUBDIR = "CI" |
|
| 748 | 749 |
WINDOWS_BASE_IMAGE = 'mcr.microsoft.com/windows/servercore' |
| 749 | 750 |
WINDOWS_BASE_IMAGE_TAG = 'ltsc2019' |
| 750 | 751 |
} |
| ... | ... |
@@ -772,6 +831,25 @@ pipeline {
|
| 772 | 772 |
} |
| 773 | 773 |
} |
| 774 | 774 |
} |
| 775 |
+ post {
|
|
| 776 |
+ always {
|
|
| 777 |
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
|
|
| 778 |
+ powershell ''' |
|
| 779 |
+ $bundleName="windowsRS5-integration" |
|
| 780 |
+ Write-Host -ForegroundColor Green "Creating ${bundleName}-bundles.zip"
|
|
| 781 |
+ |
|
| 782 |
+ # archiveArtifacts does not support env-vars to , so save the artifacts in a fixed location |
|
| 783 |
+ Compress-Archive -Path "${env:TEMP}/CIDUT.out", "${env:TEMP}/CIDUT.err" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip"
|
|
| 784 |
+ ''' |
|
| 785 |
+ |
|
| 786 |
+ archiveArtifacts artifacts: '*-bundles.zip', allowEmptyArchive: true |
|
| 787 |
+ } |
|
| 788 |
+ } |
|
| 789 |
+ cleanup {
|
|
| 790 |
+ sh 'make clean' |
|
| 791 |
+ deleteDir() |
|
| 792 |
+ } |
|
| 793 |
+ } |
|
| 775 | 794 |
} |
| 776 | 795 |
} |
| 777 | 796 |
} |
| ... | ... |
@@ -111,7 +111,7 @@ |
| 111 | 111 |
# still stumble into him in our issue tracker, or on IRC. |
| 112 | 112 |
"erikh", |
| 113 | 113 |
|
| 114 |
- # Evan Hazlett is the creator of of the Shipyard and Interlock open source projects, |
|
| 114 |
+ # Evan Hazlett is the creator of the Shipyard and Interlock open source projects, |
|
| 115 | 115 |
# and the author of "Orca", which became the foundation of Docker Universal Control |
| 116 | 116 |
# Plane (UCP). As a maintainer, Evan helped integrating SwarmKit (secrets, tasks) |
| 117 | 117 |
# into the Docker engine. |
| ... | ... |
@@ -3262,7 +3262,7 @@ definitions: |
| 3262 | 3262 |
|
| 3263 | 3263 |
<p><br /></p> |
| 3264 | 3264 |
|
| 3265 |
- - "ingress" makes the target port accessible on on every node, |
|
| 3265 |
+ - "ingress" makes the target port accessible on every node, |
|
| 3266 | 3266 |
regardless of whether there is a task for the service running on |
| 3267 | 3267 |
that node or not. |
| 3268 | 3268 |
- "host" bypasses the routing mesh and publish the port directly on |
| ... | ... |
@@ -24,8 +24,11 @@ func init() {
|
| 24 | 24 |
reexec.Init() |
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 |
-func initDispatchTestCases() []dispatchTestCase {
|
|
| 28 |
- dispatchTestCases := []dispatchTestCase{
|
|
| 27 |
+func TestDispatch(t *testing.T) {
|
|
| 28 |
+ if runtime.GOOS != "windows" {
|
|
| 29 |
+ skip.If(t, os.Getuid() != 0, "skipping test that requires root") |
|
| 30 |
+ } |
|
| 31 |
+ testCases := []dispatchTestCase{
|
|
| 29 | 32 |
{
|
| 30 | 33 |
name: "ADD multiple files to file", |
| 31 | 34 |
cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
|
| ... | ... |
@@ -92,56 +95,46 @@ func initDispatchTestCases() []dispatchTestCase {
|
| 92 | 92 |
}}, |
| 93 | 93 |
expectedError: "source can't be a URL for COPY", |
| 94 | 94 |
files: nil, |
| 95 |
- }} |
|
| 96 |
- |
|
| 97 |
- return dispatchTestCases |
|
| 98 |
-} |
|
| 99 |
- |
|
| 100 |
-func TestDispatch(t *testing.T) {
|
|
| 101 |
- if runtime.GOOS != "windows" {
|
|
| 102 |
- skip.If(t, os.Getuid() != 0, "skipping test that requires root") |
|
| 95 |
+ }, |
|
| 103 | 96 |
} |
| 104 |
- testCases := initDispatchTestCases() |
|
| 105 | 97 |
|
| 106 |
- for _, testCase := range testCases {
|
|
| 107 |
- executeTestCase(t, testCase) |
|
| 108 |
- } |
|
| 109 |
-} |
|
| 98 |
+ for _, tc := range testCases {
|
|
| 99 |
+ t.Run(tc.name, func(t *testing.T) {
|
|
| 100 |
+ contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") |
|
| 101 |
+ defer cleanup() |
|
| 110 | 102 |
|
| 111 |
-func executeTestCase(t *testing.T, testCase dispatchTestCase) {
|
|
| 112 |
- contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") |
|
| 113 |
- defer cleanup() |
|
| 103 |
+ for filename, content := range tc.files {
|
|
| 104 |
+ createTestTempFile(t, contextDir, filename, content, 0777) |
|
| 105 |
+ } |
|
| 114 | 106 |
|
| 115 |
- for filename, content := range testCase.files {
|
|
| 116 |
- createTestTempFile(t, contextDir, filename, content, 0777) |
|
| 117 |
- } |
|
| 107 |
+ tarStream, err := archive.Tar(contextDir, archive.Uncompressed) |
|
| 118 | 108 |
|
| 119 |
- tarStream, err := archive.Tar(contextDir, archive.Uncompressed) |
|
| 109 |
+ if err != nil {
|
|
| 110 |
+ t.Fatalf("Error when creating tar stream: %s", err)
|
|
| 111 |
+ } |
|
| 120 | 112 |
|
| 121 |
- if err != nil {
|
|
| 122 |
- t.Fatalf("Error when creating tar stream: %s", err)
|
|
| 123 |
- } |
|
| 124 |
- |
|
| 125 |
- defer func() {
|
|
| 126 |
- if err = tarStream.Close(); err != nil {
|
|
| 127 |
- t.Fatalf("Error when closing tar stream: %s", err)
|
|
| 128 |
- } |
|
| 129 |
- }() |
|
| 113 |
+ defer func() {
|
|
| 114 |
+ if err = tarStream.Close(); err != nil {
|
|
| 115 |
+ t.Fatalf("Error when closing tar stream: %s", err)
|
|
| 116 |
+ } |
|
| 117 |
+ }() |
|
| 130 | 118 |
|
| 131 |
- context, err := remotecontext.FromArchive(tarStream) |
|
| 119 |
+ context, err := remotecontext.FromArchive(tarStream) |
|
| 132 | 120 |
|
| 133 |
- if err != nil {
|
|
| 134 |
- t.Fatalf("Error when creating tar context: %s", err)
|
|
| 135 |
- } |
|
| 121 |
+ if err != nil {
|
|
| 122 |
+ t.Fatalf("Error when creating tar context: %s", err)
|
|
| 123 |
+ } |
|
| 136 | 124 |
|
| 137 |
- defer func() {
|
|
| 138 |
- if err = context.Close(); err != nil {
|
|
| 139 |
- t.Fatalf("Error when closing tar context: %s", err)
|
|
| 140 |
- } |
|
| 141 |
- }() |
|
| 125 |
+ defer func() {
|
|
| 126 |
+ if err = context.Close(); err != nil {
|
|
| 127 |
+ t.Fatalf("Error when closing tar context: %s", err)
|
|
| 128 |
+ } |
|
| 129 |
+ }() |
|
| 142 | 130 |
|
| 143 |
- b := newBuilderWithMockBackend() |
|
| 144 |
- sb := newDispatchRequest(b, '`', context, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
|
| 145 |
- err = dispatch(sb, testCase.cmd) |
|
| 146 |
- assert.Check(t, is.ErrorContains(err, testCase.expectedError)) |
|
| 131 |
+ b := newBuilderWithMockBackend() |
|
| 132 |
+ sb := newDispatchRequest(b, '`', context, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
|
| 133 |
+ err = dispatch(sb, tc.cmd) |
|
| 134 |
+ assert.Check(t, is.ErrorContains(err, tc.expectedError)) |
|
| 135 |
+ }) |
|
| 136 |
+ } |
|
| 147 | 137 |
} |
| ... | ... |
@@ -3,8 +3,10 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"runtime" |
| 5 | 5 |
|
| 6 |
+ "github.com/docker/docker/daemon" |
|
| 6 | 7 |
"github.com/docker/docker/daemon/config" |
| 7 | 8 |
"github.com/docker/docker/opts" |
| 9 |
+ "github.com/docker/docker/plugin/executor/containerd" |
|
| 8 | 10 |
"github.com/docker/docker/registry" |
| 9 | 11 |
"github.com/spf13/pflag" |
| 10 | 12 |
) |
| ... | ... |
@@ -85,7 +87,13 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
|
| 85 | 85 |
|
| 86 | 86 |
conf.MaxConcurrentDownloads = &maxConcurrentDownloads |
| 87 | 87 |
conf.MaxConcurrentUploads = &maxConcurrentUploads |
| 88 |
- return nil |
|
| 88 |
+ |
|
| 89 |
+ flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", daemon.ContainersNamespace, "Containerd namespace to use") |
|
| 90 |
+ if err := flags.MarkHidden("containerd-namespace"); err != nil {
|
|
| 91 |
+ return err |
|
| 92 |
+ } |
|
| 93 |
+ flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", containerd.PluginNamespace, "Containerd namespace to use for plugins") |
|
| 94 |
+ return flags.MarkHidden("containerd-plugins-namespace")
|
|
| 89 | 95 |
} |
| 90 | 96 |
|
| 91 | 97 |
func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.FlagSet) {
|
| ... | ... |
@@ -235,6 +235,9 @@ type CommonConfig struct {
|
| 235 | 235 |
Features map[string]bool `json:"features,omitempty"` |
| 236 | 236 |
|
| 237 | 237 |
Builder BuilderConfig `json:"builder,omitempty"` |
| 238 |
+ |
|
| 239 |
+ ContainerdNamespace string `json:"containerd-namespace,omitempty"` |
|
| 240 |
+ ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"` |
|
| 238 | 241 |
} |
| 239 | 242 |
|
| 240 | 243 |
// IsValueSet returns true if a configuration value |
| ... | ... |
@@ -875,7 +875,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 875 | 875 |
grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), |
| 876 | 876 |
} |
| 877 | 877 |
if config.ContainerdAddr != "" {
|
| 878 |
- d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(ContainersNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) |
|
| 878 |
+ d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) |
|
| 879 | 879 |
if err != nil {
|
| 880 | 880 |
return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) |
| 881 | 881 |
} |
| ... | ... |
@@ -887,13 +887,13 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 887 | 887 |
// Windows is not currently using containerd, keep the |
| 888 | 888 |
// client as nil |
| 889 | 889 |
if config.ContainerdAddr != "" {
|
| 890 |
- pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(pluginexec.PluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) |
|
| 890 |
+ pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) |
|
| 891 | 891 |
if err != nil {
|
| 892 | 892 |
return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) |
| 893 | 893 |
} |
| 894 | 894 |
} |
| 895 | 895 |
|
| 896 |
- return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, m) |
|
| 896 |
+ return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m) |
|
| 897 | 897 |
} |
| 898 | 898 |
|
| 899 | 899 |
// Plugin system initialization should happen before restore. Do not change order. |
| ... | ... |
@@ -1041,7 +1041,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 1041 | 1041 |
|
| 1042 | 1042 |
go d.execCommandGC() |
| 1043 | 1043 |
|
| 1044 |
- d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), ContainersNamespace, d) |
|
| 1044 |
+ d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d) |
|
| 1045 | 1045 |
if err != nil {
|
| 1046 | 1046 |
return nil, err |
| 1047 | 1047 |
} |
| ... | ... |
@@ -736,6 +736,9 @@ func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error |
| 736 | 736 |
|
| 737 | 737 |
// verifyDaemonSettings performs validation of daemon config struct |
| 738 | 738 |
func verifyDaemonSettings(conf *config.Config) error {
|
| 739 |
+ if conf.ContainerdNamespace == conf.ContainerdPluginNamespace {
|
|
| 740 |
+ return errors.New("containers namespace and plugins namespace cannot be the same")
|
|
| 741 |
+ } |
|
| 739 | 742 |
// Check for mutually incompatible config options |
| 740 | 743 |
if conf.BridgeConfig.Iface != "" && conf.BridgeConfig.IP != "" {
|
| 741 | 744 |
return fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one")
|
| ... | ... |
@@ -285,6 +285,9 @@ func TestLogClosed(t *testing.T) {
|
| 285 | 285 |
} |
| 286 | 286 |
} |
| 287 | 287 |
|
| 288 |
+// TestLogBlocking tests that the Log method blocks appropriately when |
|
| 289 |
+// non-blocking behavior is not enabled. Blocking is achieved through an |
|
| 290 |
+// internal channel that must be drained for Log to return. |
|
| 288 | 291 |
func TestLogBlocking(t *testing.T) {
|
| 289 | 292 |
mockClient := newMockClient() |
| 290 | 293 |
stream := &logStream{
|
| ... | ... |
@@ -299,18 +302,20 @@ func TestLogBlocking(t *testing.T) {
|
| 299 | 299 |
err := stream.Log(&logger.Message{})
|
| 300 | 300 |
errorCh <- err |
| 301 | 301 |
}() |
| 302 |
+ // block until the goroutine above has started |
|
| 302 | 303 |
<-started |
| 303 | 304 |
select {
|
| 304 | 305 |
case err := <-errorCh: |
| 305 | 306 |
t.Fatal("Expected stream.Log to block: ", err)
|
| 306 | 307 |
default: |
| 307 |
- break |
|
| 308 | 308 |
} |
| 309 |
+ // assuming it is blocked, we can now try to drain the internal channel and |
|
| 310 |
+ // unblock it |
|
| 309 | 311 |
select {
|
| 310 |
- case <-stream.messages: |
|
| 311 |
- break |
|
| 312 |
- default: |
|
| 312 |
+ case <-time.After(10 * time.Millisecond): |
|
| 313 |
+ // if we're unable to drain the channel within 10ms, something seems broken |
|
| 313 | 314 |
t.Fatal("Expected to be able to read from stream.messages but was unable to")
|
| 315 |
+ case <-stream.messages: |
|
| 314 | 316 |
} |
| 315 | 317 |
select {
|
| 316 | 318 |
case err := <-errorCh: |
| ... | ... |
@@ -925,7 +925,12 @@ func TestFrequency(t *testing.T) {
|
| 925 | 925 |
|
| 926 | 926 |
// 1 to verify connection and 10 to verify that we have sent messages with required frequency, |
| 927 | 927 |
// but because frequency is too small (to keep test quick), instead of 11, use 9 if context switches will be slow |
| 928 |
- if hec.numOfRequests < 9 {
|
|
| 928 |
+ expectedRequests := 9 |
|
| 929 |
+ if runtime.GOOS == "windows" {
|
|
| 930 |
+ // sometimes in Windows, this test fails with number of requests showing 8. So be more conservative. |
|
| 931 |
+ expectedRequests = 7 |
|
| 932 |
+ } |
|
| 933 |
+ if hec.numOfRequests < expectedRequests {
|
|
| 929 | 934 |
t.Fatalf("Unexpected number of requests %d", hec.numOfRequests)
|
| 930 | 935 |
} |
| 931 | 936 |
|
| ... | ... |
@@ -15,6 +15,11 @@ if ($env:BUILD_TAG -match "-LoW") { $env:LCOW_MODE=1 }
|
| 15 | 15 |
if ($env:BUILD_TAG -match "-WoW") { $env:LCOW_MODE="" }
|
| 16 | 16 |
|
| 17 | 17 |
|
| 18 |
+Write-Host -ForegroundColor Red "DEBUG: print all environment variables to check how Jenkins runs this script" |
|
| 19 |
+$allArgs = [Environment]::GetCommandLineArgs() |
|
| 20 |
+Write-Host -ForegroundColor Red $allArgs |
|
| 21 |
+Write-Host -ForegroundColor Red "----------------------------------------------------------------------------" |
|
| 22 |
+ |
|
| 18 | 23 |
# ------------------------------------------------------------------------------------------- |
| 19 | 24 |
# When executed, we rely on four variables being set in the environment: |
| 20 | 25 |
# |
| ... | ... |
@@ -46,10 +51,24 @@ if ($env:BUILD_TAG -match "-WoW") { $env:LCOW_MODE="" }
|
| 46 | 46 |
# TESTRUN_DRIVE\TESTRUN_SUBDIR\CI-<CommitID> or |
| 47 | 47 |
# d:\CI\CI-<CommitID> |
| 48 | 48 |
# |
| 49 |
+# Optional environment variables help in CI: |
|
| 50 |
+# |
|
| 51 |
+# BUILD_NUMBER + BRANCH_NAME are optional variables to be added to the directory below TESTRUN_SUBDIR |
|
| 52 |
+# to have individual folder per CI build. If some files couldn't be |
|
| 53 |
+# cleaned up and we want to re-run the build in CI. |
|
| 54 |
+# Hence, the daemon under test is run under |
|
| 55 |
+# TESTRUN_DRIVE\TESTRUN_SUBDIR\PR-<PR-Number>\<BuildNumber> or |
|
| 56 |
+# d:\CI\PR-<PR-Number>\<BuildNumber> |
|
| 57 |
+# |
|
| 49 | 58 |
# In addition, the following variables can control the run configuration: |
| 50 | 59 |
# |
| 51 | 60 |
# DOCKER_DUT_DEBUG if defined starts the daemon under test in debug mode. |
| 52 | 61 |
# |
| 62 |
+# DOCKER_STORAGE_OPTS comma-separated list of optional storage driver options for the daemon under test |
|
| 63 |
+# examples: |
|
| 64 |
+# DOCKER_STORAGE_OPTS="size=40G" |
|
| 65 |
+# DOCKER_STORAGE_OPTS="lcow.globalmode=false,lcow.kernel=kernel.efi" |
|
| 66 |
+# |
|
| 53 | 67 |
# SKIP_VALIDATION_TESTS if defined skips the validation tests |
| 54 | 68 |
# |
| 55 | 69 |
# SKIP_UNIT_TESTS if defined skips the unit tests |
| ... | ... |
@@ -266,7 +285,7 @@ Try {
|
| 266 | 266 |
} |
| 267 | 267 |
} |
| 268 | 268 |
} Catch {}
|
| 269 |
- if ($defender) { Throw "ERROR: Windows Defender real time protection must be disabled for integration tests" }
|
|
| 269 |
+ if ($defender) { Write-Host -ForegroundColor Magenta "WARN: Windows Defender real time protection is enabled, which may cause some integration tests to fail" }
|
|
| 270 | 270 |
|
| 271 | 271 |
# Make sure SOURCES_DRIVE is set |
| 272 | 272 |
if ($null -eq $env:SOURCES_DRIVE) { Throw "ERROR: Environment variable SOURCES_DRIVE is not set" }
|
| ... | ... |
@@ -418,7 +437,12 @@ Try {
|
| 418 | 418 |
|
| 419 | 419 |
# Redirect to a temporary location. |
| 420 | 420 |
$TEMPORIG=$env:TEMP |
| 421 |
- $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH" |
|
| 421 |
+ if ($null -eq $env:BUILD_NUMBER) {
|
|
| 422 |
+ $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH" |
|
| 423 |
+ } else {
|
|
| 424 |
+ # individual temporary location per CI build that better matches the BUILD_URL |
|
| 425 |
+ $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\$env:BRANCH_NAME\$env:BUILD_NUMBER" |
|
| 426 |
+ } |
|
| 422 | 427 |
$env:LOCALAPPDATA="$env:TEMP\localappdata" |
| 423 | 428 |
$errorActionPreference='Stop' |
| 424 | 429 |
New-Item -ItemType Directory "$env:TEMP" -ErrorAction SilentlyContinue | Out-Null |
| ... | ... |
@@ -580,6 +604,15 @@ Try {
|
| 580 | 580 |
$dutArgs += "--exec-opt isolation=hyperv" |
| 581 | 581 |
} |
| 582 | 582 |
|
| 583 |
+ # Arguments: Allow setting optional storage-driver options |
|
| 584 |
+ # example usage: DOCKER_STORAGE_OPTS="lcow.globalmode=false,lcow.kernel=kernel.efi" |
|
| 585 |
+ if (-not ("$env:DOCKER_STORAGE_OPTS" -eq "")) {
|
|
| 586 |
+ Write-Host -ForegroundColor Green "INFO: Running the daemon under test with storage-driver options ${env:DOCKER_STORAGE_OPTS}"
|
|
| 587 |
+ $env:DOCKER_STORAGE_OPTS.Split(",") | ForEach {
|
|
| 588 |
+ $dutArgs += "--storage-opt $_" |
|
| 589 |
+ } |
|
| 590 |
+ } |
|
| 591 |
+ |
|
| 583 | 592 |
# Start the daemon under test, ensuring everything is redirected to folders under $TEMP. |
| 584 | 593 |
# Important - we launch the -$COMMITHASH version so that we can kill it without |
| 585 | 594 |
# killing the control daemon. |
| ... | ... |
@@ -608,7 +641,8 @@ Try {
|
| 608 | 608 |
|
| 609 | 609 |
# Start tailing the daemon under test if the command is installed |
| 610 | 610 |
if ($null -ne (Get-Command "tail" -ErrorAction SilentlyContinue)) {
|
| 611 |
- $tail = start-process "tail" -ArgumentList "-f $env:TEMP\dut.out" -ErrorAction SilentlyContinue |
|
| 611 |
+ Write-Host -ForegroundColor green "INFO: Start tailing logs of the daemon under tests" |
|
| 612 |
+ $tail = Start-Process "tail" -ArgumentList "-f $env:TEMP\dut.out" -PassThru -ErrorAction SilentlyContinue |
|
| 612 | 613 |
} |
| 613 | 614 |
|
| 614 | 615 |
# Verify we can get the daemon under test to respond |
| ... | ... |
@@ -717,7 +751,7 @@ Try {
|
| 717 | 717 |
|
| 718 | 718 |
# Inspect the pulled or loaded image to get the version directly |
| 719 | 719 |
$ErrorActionPreference = "SilentlyContinue" |
| 720 |
- $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}")
|
|
| 720 |
+ $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect "$($env:WINDOWS_BASE_IMAGE):$env:WINDOWS_BASE_IMAGE_TAG" --format "{{.OsVersion}}")
|
|
| 721 | 721 |
$ErrorActionPreference = "Stop" |
| 722 | 722 |
Write-Host -ForegroundColor Green $("INFO: Version of $($env:WINDOWS_BASE_IMAGE):$env:WINDOWS_BASE_IMAGE_TAG is '"+$dutimgVersion+"'")
|
| 723 | 723 |
} |
| ... | ... |
@@ -944,6 +978,12 @@ Try {
|
| 944 | 944 |
Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue |
| 945 | 945 |
} |
| 946 | 946 |
|
| 947 |
+ # Stop the tail process (if started) |
|
| 948 |
+ if ($null -ne $tail) {
|
|
| 949 |
+ Write-Host -ForegroundColor green "INFO: Stop tailing logs of the daemon under tests" |
|
| 950 |
+ Stop-Process -InputObject $tail -Force |
|
| 951 |
+ } |
|
| 952 |
+ |
|
| 947 | 953 |
Write-Host -ForegroundColor Green "INFO: executeCI.ps1 Completed successfully at $(Get-Date)." |
| 948 | 954 |
} |
| 949 | 955 |
Catch [Exception] {
|
| ... | ... |
@@ -960,6 +1000,9 @@ Catch [Exception] {
|
| 960 | 960 |
Throw $_ |
| 961 | 961 |
} |
| 962 | 962 |
Finally {
|
| 963 |
+ # Preserve the LastExitCode of the tests |
|
| 964 |
+ $tmpLastExitCode = $LastExitCode |
|
| 965 |
+ |
|
| 963 | 966 |
$ErrorActionPreference="SilentlyContinue" |
| 964 | 967 |
$global:ProgressPreference=$origProgressPreference |
| 965 | 968 |
Write-Host -ForegroundColor Green "INFO: Tidying up at end of run" |
| ... | ... |
@@ -991,6 +1034,12 @@ Finally {
|
| 991 | 991 |
|
| 992 | 992 |
Set-Location "$env:SOURCES_DRIVE\$env:SOURCES_SUBDIR" -ErrorAction SilentlyContinue |
| 993 | 993 |
Nuke-Everything |
| 994 |
+ |
|
| 995 |
+ # Restore the TEMP path |
|
| 996 |
+ if ($null -ne $TEMPORIG) { $env:TEMP="$TEMPORIG" }
|
|
| 997 |
+ |
|
| 994 | 998 |
$Dur=New-TimeSpan -Start $StartTime -End $(Get-Date) |
| 995 | 999 |
Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n" |
| 1000 |
+ |
|
| 1001 |
+ exit $tmpLastExitCode |
|
| 996 | 1002 |
} |
| ... | ... |
@@ -134,7 +134,7 @@ Function Check-InContainer() {
|
| 134 | 134 |
# outside of a container where it may be out of date with master. |
| 135 | 135 |
Function Verify-GoVersion() {
|
| 136 | 136 |
Try {
|
| 137 |
- $goVersionDockerfile=(Select-String -Path ".\Dockerfile" -Pattern "^ARG[\s]+GO_VERSION=(.*)$").Matches.groups[1].Value.TrimEnd(".0")
|
|
| 137 |
+ $goVersionDockerfile=(Select-String -Path ".\Dockerfile" -Pattern "^ARG[\s]+GO_VERSION=(.*)$").Matches.groups[1].Value -replace '\.0$','' |
|
| 138 | 138 |
$goVersionInstalled=(go version).ToString().Split(" ")[2].SubString(2)
|
| 139 | 139 |
} |
| 140 | 140 |
Catch [Exception] {
|
| ... | ... |
@@ -28,30 +28,6 @@ export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
| 28 | 28 |
export MAKEDIR="$SCRIPTDIR/make" |
| 29 | 29 |
export PKG_CONFIG=${PKG_CONFIG:-pkg-config}
|
| 30 | 30 |
|
| 31 |
-# We're a nice, sexy, little shell script, and people might try to run us; |
|
| 32 |
-# but really, they shouldn't. We want to be in a container! |
|
| 33 |
-inContainer="AssumeSoInitially" |
|
| 34 |
-if [ "$(go env GOHOSTOS)" = 'windows' ]; then |
|
| 35 |
- if [ -z "$FROM_DOCKERFILE" ]; then |
|
| 36 |
- unset inContainer |
|
| 37 |
- fi |
|
| 38 |
-else |
|
| 39 |
- if [ "$PWD" != "/go/src/$DOCKER_PKG" ]; then |
|
| 40 |
- unset inContainer |
|
| 41 |
- fi |
|
| 42 |
-fi |
|
| 43 |
- |
|
| 44 |
-if [ -z "$inContainer" ]; then |
|
| 45 |
- {
|
|
| 46 |
- echo "# WARNING! I don't seem to be running in a Docker container." |
|
| 47 |
- echo "# The result of this command might be an incorrect build, and will not be" |
|
| 48 |
- echo "# officially supported." |
|
| 49 |
- echo "#" |
|
| 50 |
- echo "# Try this instead: make all" |
|
| 51 |
- echo "#" |
|
| 52 |
- } >&2 |
|
| 53 |
-fi |
|
| 54 |
- |
|
| 55 | 31 |
echo |
| 56 | 32 |
|
| 57 | 33 |
# List of bundles to create when no argument is passed |
| ... | ... |
@@ -72,9 +72,27 @@ run_test_integration_suites() {
|
| 72 | 72 |
for dir in ${integration_api_dirs}; do
|
| 73 | 73 |
if ! ( |
| 74 | 74 |
cd "$dir" |
| 75 |
- echo "Running $PWD flags=${flags}"
|
|
| 75 |
+ # Create a useful package name based on the tests's $dir. We need to take |
|
| 76 |
+ # into account that "$dir" can be either an absolute (/go/src/github.com/docker/docker/integration/foo) |
|
| 77 |
+ # or relative (./integration/foo) path. To account for both, first we strip |
|
| 78 |
+ # the absolute path, then remove any leading periods and slashes. |
|
| 79 |
+ pkgname="${dir}"
|
|
| 80 |
+ pkgname="${pkgname#*${GOPATH}/src/${DOCKER_PKG}}"
|
|
| 81 |
+ pkgname="${pkgname#*.}"
|
|
| 82 |
+ pkgname="${pkgname#*\/}"
|
|
| 83 |
+ |
|
| 84 |
+ # Finally, we use periods as separator (instead of slashes) to be more |
|
| 85 |
+ # in line with Java package names (which is what junit.xml was designed for) |
|
| 86 |
+ pkgname="$(go env GOARCH).${pkgname//\//.}"
|
|
| 87 |
+ echo "Running $PWD (${pkgname}) flags=${flags}"
|
|
| 88 |
+ [ -n "$TESTDEBUG" ] && set -x |
|
| 76 | 89 |
# shellcheck disable=SC2086 |
| 77 |
- test_env ./test.main ${flags}
|
|
| 90 |
+ test_env gotestsum \ |
|
| 91 |
+ --format=standard-verbose \ |
|
| 92 |
+ --jsonfile="${ABS_DEST}/${pkgname//./-}-go-test-report.json" \
|
|
| 93 |
+ --junitfile="${ABS_DEST}/${pkgname//./-}-junit-report.xml" \
|
|
| 94 |
+ --raw-command \ |
|
| 95 |
+ -- go tool test2json -p "${pkgname}" -t ./test.main ${flags}
|
|
| 78 | 96 |
); then exit 1; fi |
| 79 | 97 |
done |
| 80 | 98 |
} |
| ... | ... |
@@ -15,16 +15,16 @@ copy_binaries() {
|
| 15 | 15 |
fi |
| 16 | 16 |
echo "Copying nested executables into $dir" |
| 17 | 17 |
for file in containerd containerd-shim ctr runc docker-init docker-proxy rootlesskit rootlesskit-docker-proxy dockerd-rootless.sh; do |
| 18 |
- cp -f `which "$file"` "$dir/" |
|
| 19 |
- if [ "$hash" == "hash" ]; then |
|
| 18 |
+ cp -f "$(command -v "$file")" "$dir/" |
|
| 19 |
+ if [ "$hash" = "hash" ]; then |
|
| 20 | 20 |
hash_files "$dir/$file" |
| 21 | 21 |
fi |
| 22 | 22 |
done |
| 23 | 23 |
|
| 24 | 24 |
# vpnkit is amd64 only |
| 25 |
- if which "vpnkit.$(uname -m)" 2>&1 >/dev/null; then |
|
| 26 |
- cp -f `which "vpnkit.$(uname -m)"` "$dir/vpnkit" |
|
| 27 |
- if [ "$hash" == "hash" ]; then |
|
| 25 |
+ if command -v "vpnkit.$(uname -m)" 2>&1 >/dev/null; then |
|
| 26 |
+ cp -f "$(command -v "vpnkit.$(uname -m)")" "$dir/vpnkit" |
|
| 27 |
+ if [ "$hash" = "hash" ]; then |
|
| 28 | 28 |
hash_files "$dir/vpnkit" |
| 29 | 29 |
fi |
| 30 | 30 |
fi |
| ... | ... |
@@ -13,6 +13,7 @@ source hack/make/.integration-test-helpers |
| 13 | 13 |
# TODO remove these skip once we update to a docker-py version that has https://github.com/docker/docker-py/pull/2369, https://github.com/docker/docker-py/pull/2380, https://github.com/docker/docker-py/pull/2382 |
| 14 | 14 |
: "${PY_TEST_OPTIONS:=\
|
| 15 | 15 |
--deselect=tests/integration/api_swarm_test.py::SwarmTest::test_init_swarm_data_path_addr \ |
| 16 |
+--deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream \ |
|
| 16 | 17 |
--deselect=tests/integration/api_exec_test.py::ExecTest::test_detach_with_arg \ |
| 17 | 18 |
--deselect=tests/integration/api_exec_test.py::ExecDemuxTest::test_exec_command_tty_stream_no_demux \ |
| 18 | 19 |
--deselect=tests/integration/api_build_test.py::BuildTest::test_build_invalid_platform \ |
| ... | ... |
@@ -1,12 +1,6 @@ |
| 1 | 1 |
#!/usr/bin/env bash |
| 2 | 2 |
set -e -o pipefail |
| 3 | 3 |
|
| 4 |
-if [ -n "$TEST_INTEGRATION_DEST" ]; then |
|
| 5 |
- export DEST="$ABS_DEST/$TEST_INTEGRATION_DEST" |
|
| 6 |
- export DOCKER_INTEGRATION_DAEMON_DEST="$DEST" |
|
| 7 |
- mkdir -p "$DEST" |
|
| 8 |
-fi |
|
| 9 |
- |
|
| 10 | 4 |
source hack/make/.integration-test-helpers |
| 11 | 5 |
|
| 12 | 6 |
if [ ! -z "${TEST_SKIP_INTEGRATION}" ] && [ ! -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then
|
| ... | ... |
@@ -4,10 +4,11 @@ set -e -o pipefail |
| 4 | 4 |
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
| 5 | 5 |
|
| 6 | 6 |
# CI platforms differ, so per-platform GOMETALINTER_OPTS can be set |
| 7 |
-# from a platform-specific Dockerfile, otherwise let's just set |
|
| 7 |
+# in the Jenkinsfile, otherwise let's just set a |
|
| 8 | 8 |
# (somewhat pessimistic) default of 10 minutes. |
| 9 |
-: ${GOMETALINTER_OPTS=--deadline=10m}
|
|
| 9 |
+: "${GOMETALINTER_OPTS=--deadline=10m}"
|
|
| 10 | 10 |
|
| 11 |
+# shellcheck disable=SC2086 |
|
| 11 | 12 |
gometalinter \ |
| 12 | 13 |
${GOMETALINTER_OPTS} \
|
| 13 |
- --config ${SCRIPTDIR}/gometalinter.json ./...
|
|
| 14 |
+ --config "${SCRIPTDIR}/gometalinter.json" ./...
|
| ... | ... |
@@ -28,7 +28,7 @@ func (s *DockerSuite) BenchmarkConcurrentContainerActions(c *check.C) {
|
| 28 | 28 |
go func() {
|
| 29 | 29 |
defer innerGroup.Done() |
| 30 | 30 |
for i := 0; i < numIterations; i++ {
|
| 31 |
- args := []string{"run", "-d", defaultSleepImage}
|
|
| 31 |
+ args := []string{"run", "-d", "busybox"}
|
|
| 32 | 32 |
args = append(args, sleepCommandForDaemonPlatform()...) |
| 33 | 33 |
out, _, err := dockerCmdWithError(args...) |
| 34 | 34 |
if err != nil {
|
| ... | ... |
@@ -304,8 +304,8 @@ func init() {
|
| 304 | 304 |
type DockerSwarmSuite struct {
|
| 305 | 305 |
server *httptest.Server |
| 306 | 306 |
ds *DockerSuite |
| 307 |
+ daemonsLock sync.Mutex // protect access to daemons and portIndex |
|
| 307 | 308 |
daemons []*daemon.Daemon |
| 308 |
- daemonsLock sync.Mutex // protect access to daemons |
|
| 309 | 309 |
portIndex int |
| 310 | 310 |
} |
| 311 | 311 |
|
| ... | ... |
@@ -333,11 +333,11 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemo |
| 333 | 333 |
d.StartAndSwarmInit(c) |
| 334 | 334 |
} |
| 335 | 335 |
} else {
|
| 336 |
- d.StartNode(c) |
|
| 336 |
+ d.StartNodeWithBusybox(c) |
|
| 337 | 337 |
} |
| 338 | 338 |
|
| 339 |
- s.portIndex++ |
|
| 340 | 339 |
s.daemonsLock.Lock() |
| 340 |
+ s.portIndex++ |
|
| 341 | 341 |
s.daemons = append(s.daemons, d) |
| 342 | 342 |
s.daemonsLock.Unlock() |
| 343 | 343 |
|
| ... | ... |
@@ -354,9 +354,8 @@ func (s *DockerSwarmSuite) TearDownTest(c *check.C) {
|
| 354 | 354 |
} |
| 355 | 355 |
} |
| 356 | 356 |
s.daemons = nil |
| 357 |
- s.daemonsLock.Unlock() |
|
| 358 |
- |
|
| 359 | 357 |
s.portIndex = 0 |
| 358 |
+ s.daemonsLock.Unlock() |
|
| 360 | 359 |
s.ds.TearDownTest(c) |
| 361 | 360 |
} |
| 362 | 361 |
|
| ... | ... |
@@ -189,3 +189,25 @@ func (d *Daemon) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
|
| 189 | 189 |
} |
| 190 | 190 |
return fmt.Errorf("no leader"), check.Commentf("could not find leader")
|
| 191 | 191 |
} |
| 192 |
+ |
|
| 193 |
+// CmdRetryOutOfSequence tries the specified command against the current daemon |
|
| 194 |
+// up to 10 times, retrying if it encounters an "update out of sequence" error. |
|
| 195 |
+func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) {
|
|
| 196 |
+ var ( |
|
| 197 |
+ output string |
|
| 198 |
+ err error |
|
| 199 |
+ ) |
|
| 200 |
+ |
|
| 201 |
+ for i := 0; i < 10; i++ {
|
|
| 202 |
+ output, err = d.Cmd(args...) |
|
| 203 |
+ // error, no error, whatever. if we don't have "update out of |
|
| 204 |
+ // sequence", we don't retry, we just return. |
|
| 205 |
+ if !strings.Contains(output, "update out of sequence") {
|
|
| 206 |
+ return output, err |
|
| 207 |
+ } |
|
| 208 |
+ } |
|
| 209 |
+ |
|
| 210 |
+ // otherwise, once all of our attempts have been exhausted, just return |
|
| 211 |
+ // whatever the last values were. |
|
| 212 |
+ return output, err |
|
| 213 |
+} |
| ... | ... |
@@ -62,8 +62,8 @@ func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *check.C) {
|
| 62 | 62 |
v, err := kernel.GetKernelVersion() |
| 63 | 63 |
assert.NilError(c, err) |
| 64 | 64 |
build, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0]) |
| 65 |
- if build == 16299 {
|
|
| 66 |
- c.Skip("Temporarily disabled on RS3 builds")
|
|
| 65 |
+ if build <= 16299 {
|
|
| 66 |
+ c.Skip("Temporarily disabled on RS3 and older because they are too slow. See #39909")
|
|
| 67 | 67 |
} |
| 68 | 68 |
} |
| 69 | 69 |
|
| ... | ... |
@@ -4535,17 +4535,17 @@ func (s *DockerSuite) TestBuildBuildTimeArgEnv(c *check.C) {
|
| 4535 | 4535 |
ARG FOO6 |
| 4536 | 4536 |
ARG FO10 |
| 4537 | 4537 |
RUN env |
| 4538 |
- RUN [ "$FOO1" == "fromcmd" ] |
|
| 4539 |
- RUN [ "$FOO2" == "" ] |
|
| 4540 |
- RUN [ "$FOO3" == "fromenv" ] |
|
| 4541 |
- RUN [ "$FOO4" == "fromfile" ] |
|
| 4542 |
- RUN [ "$FOO5" == "fromcmd" ] |
|
| 4538 |
+ RUN [ "$FOO1" = "fromcmd" ] |
|
| 4539 |
+ RUN [ "$FOO2" = "" ] |
|
| 4540 |
+ RUN [ "$FOO3" = "fromenv" ] |
|
| 4541 |
+ RUN [ "$FOO4" = "fromfile" ] |
|
| 4542 |
+ RUN [ "$FOO5" = "fromcmd" ] |
|
| 4543 | 4543 |
# The following should not exist at all in the env |
| 4544 |
- RUN [ "$(env | grep FOO6)" == "" ] |
|
| 4545 |
- RUN [ "$(env | grep FOO7)" == "" ] |
|
| 4546 |
- RUN [ "$(env | grep FOO8)" == "" ] |
|
| 4547 |
- RUN [ "$(env | grep FOO9)" == "" ] |
|
| 4548 |
- RUN [ "$FO10" == "" ] |
|
| 4544 |
+ RUN [ "$(env | grep FOO6)" = "" ] |
|
| 4545 |
+ RUN [ "$(env | grep FOO7)" = "" ] |
|
| 4546 |
+ RUN [ "$(env | grep FOO8)" = "" ] |
|
| 4547 |
+ RUN [ "$(env | grep FOO9)" = "" ] |
|
| 4548 |
+ RUN [ "$FO10" = "" ] |
|
| 4549 | 4549 |
` |
| 4550 | 4550 |
result := buildImage("testbuildtimeargenv",
|
| 4551 | 4551 |
cli.WithFlags( |
| ... | ... |
@@ -4615,9 +4615,9 @@ func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) {
|
| 4615 | 4615 |
ARG %s= |
| 4616 | 4616 |
ARG %s="" |
| 4617 | 4617 |
ARG %s='' |
| 4618 |
- RUN [ "$%s" == "$%s" ] |
|
| 4619 |
- RUN [ "$%s" == "$%s" ] |
|
| 4620 |
- RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2) |
|
| 4618 |
+ RUN [ "$%s" = "$%s" ] |
|
| 4619 |
+ RUN [ "$%s" = "$%s" ] |
|
| 4620 |
+ RUN [ "$%s" = "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2) |
|
| 4621 | 4621 |
buildImageSuccessfully(c, imgName, build.WithDockerfile(dockerfile)) |
| 4622 | 4622 |
} |
| 4623 | 4623 |
|
| ... | ... |
@@ -5952,7 +5952,7 @@ func (s *DockerSuite) TestBuildCopyFromWindowsIsCaseInsensitive(c *check.C) {
|
| 5952 | 5952 |
} |
| 5953 | 5953 |
|
| 5954 | 5954 |
// #33176 |
| 5955 |
-func (s *DockerSuite) TestBuildMulitStageResetScratch(c *check.C) {
|
|
| 5955 |
+func (s *DockerSuite) TestBuildMultiStageResetScratch(c *check.C) {
|
|
| 5956 | 5956 |
testRequires(c, DaemonIsLinux) |
| 5957 | 5957 |
|
| 5958 | 5958 |
dockerfile := ` |
| ... | ... |
@@ -309,7 +309,15 @@ func (s *DockerSuite) TestCreateWithWorkdir(c *check.C) {
|
| 309 | 309 |
// Windows does not create the workdir until the container is started |
| 310 | 310 |
if testEnv.OSType == "windows" {
|
| 311 | 311 |
dockerCmd(c, "start", name) |
| 312 |
+ if IsolationIsHyperv() {
|
|
| 313 |
+ // Hyper-V isolated containers do not allow file-operations on a |
|
| 314 |
+ // running container. This test currently uses `docker cp` to verify |
|
| 315 |
+ // that the WORKDIR was automatically created, which cannot be done |
|
| 316 |
+ // while the container is running. |
|
| 317 |
+ dockerCmd(c, "stop", name) |
|
| 318 |
+ } |
|
| 312 | 319 |
} |
| 320 |
+ // TODO: rewrite this test to not use `docker cp` for verifying that the WORKDIR was created |
|
| 313 | 321 |
dockerCmd(c, "cp", fmt.Sprintf("%s:%s", name, dir), prefix+slash+"tmp")
|
| 314 | 322 |
} |
| 315 | 323 |
|
| ... | ... |
@@ -121,7 +121,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) |
| 121 | 121 |
|
| 122 | 122 |
// TestDaemonShutdownWithPlugins shuts down running plugins. |
| 123 | 123 |
func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
|
| 124 |
- testRequires(c, IsAmd64, Network, testEnv.IsLocalDaemon) |
|
| 124 |
+ testRequires(c, IsAmd64, Network) |
|
| 125 | 125 |
|
| 126 | 126 |
s.d.Start(c) |
| 127 | 127 |
if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
|
| ... | ... |
@@ -159,7 +159,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
|
| 159 | 159 |
|
| 160 | 160 |
// TestDaemonKillWithPlugins leaves plugins running. |
| 161 | 161 |
func (s *DockerDaemonSuite) TestDaemonKillWithPlugins(c *check.C) {
|
| 162 |
- testRequires(c, IsAmd64, Network, testEnv.IsLocalDaemon) |
|
| 162 |
+ testRequires(c, IsAmd64, Network) |
|
| 163 | 163 |
|
| 164 | 164 |
s.d.Start(c) |
| 165 | 165 |
if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
|
| ... | ... |
@@ -232,7 +232,7 @@ func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) {
|
| 232 | 232 |
} |
| 233 | 233 |
|
| 234 | 234 |
func (s *DockerDaemonSuite) TestPluginVolumeRemoveOnRestart(c *check.C) {
|
| 235 |
- testRequires(c, DaemonIsLinux, Network, IsAmd64) |
|
| 235 |
+ testRequires(c, IsAmd64, Network) |
|
| 236 | 236 |
|
| 237 | 237 |
s.d.Start(c, "--live-restore=true") |
| 238 | 238 |
|
| ... | ... |
@@ -26,7 +26,6 @@ import ( |
| 26 | 26 |
"github.com/cloudflare/cfssl/helpers" |
| 27 | 27 |
"github.com/creack/pty" |
| 28 | 28 |
"github.com/docker/docker/api/types" |
| 29 |
- moby_daemon "github.com/docker/docker/daemon" |
|
| 30 | 29 |
"github.com/docker/docker/integration-cli/checker" |
| 31 | 30 |
"github.com/docker/docker/integration-cli/cli" |
| 32 | 31 |
"github.com/docker/docker/integration-cli/cli/build" |
| ... | ... |
@@ -826,7 +825,6 @@ func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainer |
| 826 | 826 |
} |
| 827 | 827 |
|
| 828 | 828 |
func (s *DockerDaemonSuite) TestDaemonDefaultNetworkInvalidClusterConfig(c *check.C) {
|
| 829 |
- testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon) |
|
| 830 | 829 |
|
| 831 | 830 |
// Start daemon without docker0 bridge |
| 832 | 831 |
defaultNetworkBridge := "docker0" |
| ... | ... |
@@ -967,7 +965,6 @@ func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *che |
| 967 | 967 |
} |
| 968 | 968 |
|
| 969 | 969 |
func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) {
|
| 970 |
- testRequires(c, DaemonIsLinux) |
|
| 971 | 970 |
|
| 972 | 971 |
s.d.StartWithBusybox(c, "--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024") |
| 973 | 972 |
|
| ... | ... |
@@ -1457,7 +1454,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec |
| 1457 | 1457 |
|
| 1458 | 1458 |
// kill the container |
| 1459 | 1459 |
icmd.RunCommand(ctrBinary, "--address", containerdSocket, |
| 1460 |
- "--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", id).Assert(c, icmd.Success) |
|
| 1460 |
+ "--namespace", d.ContainersNamespace(), "tasks", "kill", id).Assert(c, icmd.Success) |
|
| 1461 | 1461 |
|
| 1462 | 1462 |
// restart daemon. |
| 1463 | 1463 |
d.Restart(c) |
| ... | ... |
@@ -1977,7 +1974,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check |
| 1977 | 1977 |
|
| 1978 | 1978 |
// kill the container |
| 1979 | 1979 |
icmd.RunCommand(ctrBinary, "--address", containerdSocket, |
| 1980 |
- "--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", cid).Assert(t, icmd.Success) |
|
| 1980 |
+ "--namespace", s.d.ContainersNamespace(), "tasks", "kill", cid).Assert(t, icmd.Success) |
|
| 1981 | 1981 |
|
| 1982 | 1982 |
// Give time to containerd to process the command if we don't |
| 1983 | 1983 |
// the exit event might be received after we do the inspect |
| ... | ... |
@@ -2080,7 +2077,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *che |
| 2080 | 2080 |
result := icmd.RunCommand( |
| 2081 | 2081 |
ctrBinary, |
| 2082 | 2082 |
"--address", containerdSocket, |
| 2083 |
- "--namespace", moby_daemon.ContainersNamespace, |
|
| 2083 |
+ "--namespace", s.d.ContainersNamespace(), |
|
| 2084 | 2084 |
"tasks", "resume", cid) |
| 2085 | 2085 |
result.Assert(t, icmd.Success) |
| 2086 | 2086 |
|
| ... | ... |
@@ -388,7 +388,6 @@ func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) {
|
| 388 | 388 |
} |
| 389 | 389 |
|
| 390 | 390 |
func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
|
| 391 |
- testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) |
|
| 392 | 391 |
|
| 393 | 392 |
// daemon config file |
| 394 | 393 |
configFilePath := "test.json" |
| ... | ... |
@@ -457,7 +456,6 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
|
| 457 | 457 |
} |
| 458 | 458 |
|
| 459 | 459 |
func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
|
| 460 |
- testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) |
|
| 461 | 460 |
|
| 462 | 461 |
// daemon config file |
| 463 | 462 |
configFilePath := "test.json" |
| ... | ... |
@@ -1,5 +1,3 @@ |
| 1 |
-// +build !test_no_exec |
|
| 2 |
- |
|
| 3 | 1 |
package main |
| 4 | 2 |
|
| 5 | 3 |
import ( |
| ... | ... |
@@ -81,8 +79,7 @@ func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) {
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
func (s *DockerDaemonSuite) TestExecAfterDaemonRestart(c *check.C) {
|
| 84 |
- // TODO Windows CI: Requires a little work to get this ported. |
|
| 85 |
- testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon) |
|
| 84 |
+ // TODO Windows CI: DockerDaemonSuite doesn't run on Windows, and requires a little work to get this ported. |
|
| 86 | 85 |
s.d.StartWithBusybox(c) |
| 87 | 86 |
|
| 88 | 87 |
out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top")
|
| ... | ... |
@@ -211,7 +211,6 @@ func (s *DockerSuite) TestInsecureRegistries(c *check.C) {
|
| 211 | 211 |
} |
| 212 | 212 |
|
| 213 | 213 |
func (s *DockerDaemonSuite) TestRegistryMirrors(c *check.C) {
|
| 214 |
- testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) |
|
| 215 | 214 |
|
| 216 | 215 |
registryMirror1 := "https://192.168.1.2" |
| 217 | 216 |
registryMirror2 := "http://registry.mirror.com:5000" |
| ... | ... |
@@ -140,7 +140,7 @@ func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) {
|
| 140 | 140 |
|
| 141 | 141 |
func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) {
|
| 142 | 142 |
testRequires(c, DaemonIsLinux) |
| 143 |
- testRequires(c, testEnv.IsLocalDaemon, ExecSupport) |
|
| 143 |
+ testRequires(c, testEnv.IsLocalDaemon) |
|
| 144 | 144 |
|
| 145 | 145 |
out, _ := dockerCmd(c, "run", "-itd", "--name", "one", "busybox", "top") |
| 146 | 146 |
idOne := strings.TrimSpace(out) |
| ... | ... |
@@ -158,7 +158,7 @@ func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) {
|
| 158 | 158 |
|
| 159 | 159 |
func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) {
|
| 160 | 160 |
testRequires(c, DaemonIsLinux) |
| 161 |
- testRequires(c, testEnv.IsLocalDaemon, ExecSupport) |
|
| 161 |
+ testRequires(c, testEnv.IsLocalDaemon) |
|
| 162 | 162 |
dockerCmd(c, "run", "-d", "--name", "one", "busybox", "top") |
| 163 | 163 |
out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top") |
| 164 | 164 |
id := strings.TrimSpace(string(out)) |
| ... | ... |
@@ -805,7 +805,6 @@ func (s *DockerNetworkSuite) TestDockerPluginV2NetworkDriver(c *check.C) {
|
| 805 | 805 |
} |
| 806 | 806 |
|
| 807 | 807 |
func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c *check.C) {
|
| 808 |
- testRequires(c, ExecSupport) |
|
| 809 | 808 |
// On default bridge network built-in service discovery should not happen |
| 810 | 809 |
hostsFile := "/etc/hosts" |
| 811 | 810 |
bridgeName := "external-bridge" |
| ... | ... |
@@ -863,7 +862,7 @@ func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c * |
| 863 | 863 |
} |
| 864 | 864 |
|
| 865 | 865 |
func (s *DockerNetworkSuite) TestDockerNetworkAnonymousEndpoint(c *check.C) {
|
| 866 |
- testRequires(c, ExecSupport, NotArm) |
|
| 866 |
+ testRequires(c, NotArm) |
|
| 867 | 867 |
hostsFile := "/etc/hosts" |
| 868 | 868 |
cstmBridgeNw := "custom-bridge-nw" |
| 869 | 869 |
cstmBridgeNw1 := "custom-bridge-nw1" |
| ... | ... |
@@ -1665,7 +1664,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkCreateDeleteSpecialCharacters(c *c |
| 1665 | 1665 |
} |
| 1666 | 1666 |
|
| 1667 | 1667 |
func (s *DockerDaemonSuite) TestDaemonRestartRestoreBridgeNetwork(t *check.C) {
|
| 1668 |
- testRequires(t, DaemonIsLinux) |
|
| 1669 | 1668 |
s.d.StartWithBusybox(t, "--live-restore") |
| 1670 | 1669 |
defer s.d.Stop(t) |
| 1671 | 1670 |
oldCon := "old" |
| ... | ... |
@@ -21,7 +21,6 @@ func (s *DockerSuite) TestCLIProxyDisableProxyUnixSock(c *check.C) {
|
| 21 | 21 |
// Can't use localhost here since go has a special case to not use proxy if connecting to localhost |
| 22 | 22 |
// See https://golang.org/pkg/net/http/#ProxyFromEnvironment |
| 23 | 23 |
func (s *DockerDaemonSuite) TestCLIProxyProxyTCPSock(c *check.C) {
|
| 24 |
- testRequires(c, testEnv.IsLocalDaemon) |
|
| 25 | 24 |
// get the IP to use to connect since we can't use localhost |
| 26 | 25 |
addrs, err := net.InterfaceAddrs() |
| 27 | 26 |
assert.NilError(c, err) |
| ... | ... |
@@ -292,7 +292,7 @@ func (s *DockerSuite) TestRestartContainerwithRestartPolicy(c *check.C) {
|
| 292 | 292 |
dockerCmd(c, "start", id1) |
| 293 | 293 |
dockerCmd(c, "start", id2) |
| 294 | 294 |
|
| 295 |
- // Kill the containers, making sure the are stopped at the end of the test |
|
| 295 |
+ // Kill the containers, making sure they are stopped at the end of the test |
|
| 296 | 296 |
dockerCmd(c, "kill", id1) |
| 297 | 297 |
dockerCmd(c, "kill", id2) |
| 298 | 298 |
err = waitInspect(id1, "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTimeout)
|
| ... | ... |
@@ -1792,16 +1792,14 @@ func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) {
|
| 1792 | 1792 |
func (s *DockerSuite) TestRunInteractiveWithRestartPolicy(c *check.C) {
|
| 1793 | 1793 |
name := "test-inter-restart" |
| 1794 | 1794 |
|
| 1795 |
- result := icmd.StartCmd(icmd.Cmd{
|
|
| 1795 |
+ result := icmd.RunCmd(icmd.Cmd{
|
|
| 1796 | 1796 |
Command: []string{dockerBinary, "run", "-i", "--name", name, "--restart=always", "busybox", "sh"},
|
| 1797 | 1797 |
Stdin: bytes.NewBufferString("exit 11"),
|
| 1798 | 1798 |
}) |
| 1799 |
- assert.NilError(c, result.Error) |
|
| 1800 | 1799 |
defer func() {
|
| 1801 |
- dockerCmdWithResult("stop", name).Assert(c, icmd.Success)
|
|
| 1800 |
+ cli.Docker(cli.Args("stop", name)).Assert(c, icmd.Success)
|
|
| 1802 | 1801 |
}() |
| 1803 | 1802 |
|
| 1804 |
- result = icmd.WaitOnCmd(60*time.Second, result) |
|
| 1805 | 1803 |
result.Assert(c, icmd.Expected{ExitCode: 11})
|
| 1806 | 1804 |
} |
| 1807 | 1805 |
|
| ... | ... |
@@ -3430,7 +3428,7 @@ func (s *DockerSuite) TestRunLoopbackWhenNetworkDisabled(c *check.C) {
|
| 3430 | 3430 |
|
| 3431 | 3431 |
func (s *DockerSuite) TestRunModeNetContainerHostname(c *check.C) {
|
| 3432 | 3432 |
// Windows does not support --net=container |
| 3433 |
- testRequires(c, DaemonIsLinux, ExecSupport) |
|
| 3433 |
+ testRequires(c, DaemonIsLinux) |
|
| 3434 | 3434 |
|
| 3435 | 3435 |
dockerCmd(c, "run", "-i", "-d", "--name", "parent", "busybox", "top") |
| 3436 | 3436 |
out, _ := dockerCmd(c, "exec", "parent", "cat", "/etc/hostname") |
| ... | ... |
@@ -1442,7 +1442,7 @@ func (s *DockerSuite) TestRunUserDeviceAllowed(c *check.C) {
|
| 1442 | 1442 |
} |
| 1443 | 1443 |
|
| 1444 | 1444 |
func (s *DockerDaemonSuite) TestRunSeccompJSONNewFormat(c *check.C) {
|
| 1445 |
- testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) |
|
| 1445 |
+ testRequires(c, seccompEnabled) |
|
| 1446 | 1446 |
|
| 1447 | 1447 |
s.d.StartWithBusybox(c) |
| 1448 | 1448 |
|
| ... | ... |
@@ -1467,7 +1467,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNewFormat(c *check.C) {
|
| 1467 | 1467 |
} |
| 1468 | 1468 |
|
| 1469 | 1469 |
func (s *DockerDaemonSuite) TestRunSeccompJSONNoNameAndNames(c *check.C) {
|
| 1470 |
- testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) |
|
| 1470 |
+ testRequires(c, seccompEnabled) |
|
| 1471 | 1471 |
|
| 1472 | 1472 |
s.d.StartWithBusybox(c) |
| 1473 | 1473 |
|
| ... | ... |
@@ -1493,7 +1493,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoNameAndNames(c *check.C) {
|
| 1493 | 1493 |
} |
| 1494 | 1494 |
|
| 1495 | 1495 |
func (s *DockerDaemonSuite) TestRunSeccompJSONNoArchAndArchMap(c *check.C) {
|
| 1496 |
- testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) |
|
| 1496 |
+ testRequires(c, seccompEnabled) |
|
| 1497 | 1497 |
|
| 1498 | 1498 |
s.d.StartWithBusybox(c) |
| 1499 | 1499 |
|
| ... | ... |
@@ -1530,7 +1530,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoArchAndArchMap(c *check.C) {
|
| 1530 | 1530 |
} |
| 1531 | 1531 |
|
| 1532 | 1532 |
func (s *DockerDaemonSuite) TestRunWithDaemonDefaultSeccompProfile(c *check.C) {
|
| 1533 |
- testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) |
|
| 1533 |
+ testRequires(c, seccompEnabled) |
|
| 1534 | 1534 |
|
| 1535 | 1535 |
s.d.StartWithBusybox(c) |
| 1536 | 1536 |
|
| ... | ... |
@@ -28,7 +28,7 @@ func (s *DockerSwarmSuite) TestServiceHealthRun(c *check.C) {
|
| 28 | 28 |
result := cli.BuildCmd(c, imageName, cli.Daemon(d), |
| 29 | 29 |
build.WithDockerfile(`FROM busybox |
| 30 | 30 |
RUN touch /status |
| 31 |
- HEALTHCHECK --interval=1s --timeout=1s --retries=1\ |
|
| 31 |
+ HEALTHCHECK --interval=1s --timeout=5s --retries=1\ |
|
| 32 | 32 |
CMD cat /status`), |
| 33 | 33 |
) |
| 34 | 34 |
result.Assert(c, icmd.Success) |
| ... | ... |
@@ -14,11 +14,11 @@ func (s *DockerSwarmSuite) TestServiceScale(c *check.C) {
|
| 14 | 14 |
d := s.AddDaemon(c, true, true) |
| 15 | 15 |
|
| 16 | 16 |
service1Name := "TestService1" |
| 17 |
- service1Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service1Name, defaultSleepImage}, sleepCommandForDaemonPlatform()...)
|
|
| 17 |
+ service1Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service1Name, "busybox"}, sleepCommandForDaemonPlatform()...)
|
|
| 18 | 18 |
|
| 19 | 19 |
// global mode |
| 20 | 20 |
service2Name := "TestService2" |
| 21 |
- service2Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service2Name, "--mode=global", defaultSleepImage}, sleepCommandForDaemonPlatform()...)
|
|
| 21 |
+ service2Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service2Name, "--mode=global", "busybox"}, sleepCommandForDaemonPlatform()...)
|
|
| 22 | 22 |
|
| 23 | 23 |
// Create services |
| 24 | 24 |
_, err := d.Cmd(service1Args...) |
| ... | ... |
@@ -277,19 +277,23 @@ func (s *DockerSwarmSuite) TestSwarmPublishAdd(c *check.C) {
|
| 277 | 277 |
d := s.AddDaemon(c, true, true) |
| 278 | 278 |
|
| 279 | 279 |
name := "top" |
| 280 |
+ // this first command does not have to be retried because service creates |
|
| 281 |
+ // don't return out of sequence errors. |
|
| 280 | 282 |
out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--label", "x=y", "busybox", "top")
|
| 281 | 283 |
assert.NilError(c, err, out) |
| 282 | 284 |
assert.Assert(c, strings.TrimSpace(out) != "") |
| 283 | 285 |
|
| 284 |
- out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name)
|
|
| 286 |
+ out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name)
|
|
| 285 | 287 |
assert.NilError(c, err, out) |
| 286 | 288 |
|
| 287 |
- out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name)
|
|
| 289 |
+ out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name)
|
|
| 288 | 290 |
assert.NilError(c, err, out) |
| 289 | 291 |
|
| 290 |
- _, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name)
|
|
| 292 |
+ _, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name)
|
|
| 291 | 293 |
assert.ErrorContains(c, err, "") |
| 292 | 294 |
|
| 295 |
+ // this last command does not have to be retried because service inspect |
|
| 296 |
+ // does not return out of sequence errors. |
|
| 293 | 297 |
out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name)
|
| 294 | 298 |
assert.NilError(c, err, out) |
| 295 | 299 |
assert.Equal(c, strings.TrimSpace(out), "[{ tcp 80 80 ingress}]")
|
| ... | ... |
@@ -838,7 +842,7 @@ func (s *DockerSwarmSuite) TestSwarmServiceTTY(c *check.C) {
|
| 838 | 838 |
|
| 839 | 839 |
name := "top" |
| 840 | 840 |
|
| 841 |
- ttyCheck := "if [ -t 0 ]; then echo TTY > /status && top; else echo none > /status && top; fi" |
|
| 841 |
+ ttyCheck := "if [ -t 0 ]; then echo TTY > /status; else echo none > /status; fi; exec top" |
|
| 842 | 842 |
|
| 843 | 843 |
// Without --tty |
| 844 | 844 |
expectedOutput := "none" |
| ... | ... |
@@ -23,7 +23,7 @@ import ( |
| 23 | 23 |
// 1. validate uid/gid maps are set properly |
| 24 | 24 |
// 2. verify that files created are owned by remapped root |
| 25 | 25 |
func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
|
| 26 |
- testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, UserNamespaceInKernel) |
|
| 26 |
+ testRequires(c, UserNamespaceInKernel) |
|
| 27 | 27 |
|
| 28 | 28 |
s.d.StartWithBusybox(c, "--userns-remap", "default") |
| 29 | 29 |
|
| ... | ... |
@@ -63,7 +63,7 @@ func getContainerCount(c *check.C) int {
|
| 63 | 63 |
for _, line := range lines {
|
| 64 | 64 |
if strings.Contains(line, containers) {
|
| 65 | 65 |
output := strings.TrimSpace(line) |
| 66 |
- output = strings.TrimLeft(output, containers) |
|
| 66 |
+ output = strings.TrimPrefix(output, containers) |
|
| 67 | 67 |
output = strings.Trim(output, " ") |
| 68 | 68 |
containerCount, err := strconv.Atoi(output) |
| 69 | 69 |
assert.NilError(c, err) |
| ... | ... |
@@ -347,7 +347,7 @@ func getInspectBody(c *check.C, version, id string) []byte {
|
| 347 | 347 |
// Run a long running idle task in a background container using the |
| 348 | 348 |
// system-specific default image and command. |
| 349 | 349 |
func runSleepingContainer(c *check.C, extraArgs ...string) string {
|
| 350 |
- return runSleepingContainerInImage(c, defaultSleepImage, extraArgs...) |
|
| 350 |
+ return runSleepingContainerInImage(c, "busybox", extraArgs...) |
|
| 351 | 351 |
} |
| 352 | 352 |
|
| 353 | 353 |
// Run a long running idle task in a background container using the specified |
| ... | ... |
@@ -84,20 +84,11 @@ func bridgeNfIptables() bool {
|
| 84 | 84 |
return !SysInfo.BridgeNFCallIPTablesDisabled |
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 |
-func bridgeNfIP6tables() bool {
|
|
| 88 |
- return !SysInfo.BridgeNFCallIP6TablesDisabled |
|
| 89 |
-} |
|
| 90 |
- |
|
| 91 | 87 |
func unprivilegedUsernsClone() bool {
|
| 92 | 88 |
content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
|
| 93 | 89 |
return err != nil || !strings.Contains(string(content), "0") |
| 94 | 90 |
} |
| 95 | 91 |
|
| 96 |
-func ambientCapabilities() bool {
|
|
| 97 |
- content, err := ioutil.ReadFile("/proc/self/status")
|
|
| 98 |
- return err != nil || strings.Contains(string(content), "CapAmb:") |
|
| 99 |
-} |
|
| 100 |
- |
|
| 101 | 92 |
func overlayFSSupported() bool {
|
| 102 | 93 |
cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems") |
| 103 | 94 |
out, err := cmd.CombinedOutput() |
| ... | ... |
@@ -107,20 +98,6 @@ func overlayFSSupported() bool {
|
| 107 | 107 |
return bytes.Contains(out, []byte("overlay\n"))
|
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 |
-func overlay2Supported() bool {
|
|
| 111 |
- if !overlayFSSupported() {
|
|
| 112 |
- return false |
|
| 113 |
- } |
|
| 114 |
- |
|
| 115 |
- daemonV, err := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion) |
|
| 116 |
- if err != nil {
|
|
| 117 |
- return false |
|
| 118 |
- } |
|
| 119 |
- requiredV := kernel.VersionInfo{Kernel: 4}
|
|
| 120 |
- return kernel.CompareKernelVersion(*daemonV, requiredV) > -1 |
|
| 121 |
- |
|
| 122 |
-} |
|
| 123 |
- |
|
| 124 | 110 |
func init() {
|
| 125 | 111 |
if testEnv.IsLocalDaemon() {
|
| 126 | 112 |
SysInfo = sysinfo.New(true) |
| ... | ... |
@@ -8,8 +8,4 @@ const ( |
| 8 | 8 |
|
| 9 | 9 |
// this is the expected file permission set on windows: gh#11395 |
| 10 | 10 |
expectedFileChmod = "-rwxr-xr-x" |
| 11 |
- |
|
| 12 |
- // On Windows, the busybox image doesn't have the `top` command, so we rely |
|
| 13 |
- // on `sleep` with a high duration. |
|
| 14 |
- defaultSleepImage = "busybox" |
|
| 15 | 11 |
) |
| ... | ... |
@@ -9,8 +9,8 @@ import ( |
| 9 | 9 |
"testing" |
| 10 | 10 |
|
| 11 | 11 |
"github.com/docker/docker/api/types" |
| 12 |
+ "github.com/docker/docker/api/types/versions" |
|
| 12 | 13 |
dclient "github.com/docker/docker/client" |
| 13 |
- "github.com/docker/docker/internal/test/daemon" |
|
| 14 | 14 |
"github.com/docker/docker/internal/test/fakecontext" |
| 15 | 15 |
"github.com/docker/docker/internal/test/request" |
| 16 | 16 |
"github.com/moby/buildkit/session" |
| ... | ... |
@@ -23,18 +23,9 @@ import ( |
| 23 | 23 |
|
| 24 | 24 |
func TestBuildWithSession(t *testing.T) {
|
| 25 | 25 |
skip.If(t, testEnv.DaemonInfo.OSType == "windows") |
| 26 |
+ skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") |
|
| 26 | 27 |
|
| 27 |
- var client dclient.APIClient |
|
| 28 |
- if !testEnv.DaemonInfo.ExperimentalBuild {
|
|
| 29 |
- skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") |
|
| 30 |
- |
|
| 31 |
- d := daemon.New(t, daemon.WithExperimental) |
|
| 32 |
- d.StartWithBusybox(t) |
|
| 33 |
- defer d.Stop(t) |
|
| 34 |
- client = d.NewClientT(t) |
|
| 35 |
- } else {
|
|
| 36 |
- client = testEnv.APIClient() |
|
| 37 |
- } |
|
| 28 |
+ client := testEnv.APIClient() |
|
| 38 | 29 |
|
| 39 | 30 |
dockerfile := ` |
| 40 | 31 |
FROM busybox |
| ... | ... |
@@ -100,7 +100,7 @@ func TestBuildSquashParent(t *testing.T) {
|
| 100 | 100 |
) |
| 101 | 101 |
container.Run(ctx, t, client, |
| 102 | 102 |
container.WithImage(name), |
| 103 |
- container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`),
|
|
| 103 |
+ container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" = "world" ]`),
|
|
| 104 | 104 |
) |
| 105 | 105 |
|
| 106 | 106 |
origHistory, err := client.ImageHistory(ctx, origID) |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
// +build !windows |
| 2 | 2 |
|
| 3 |
-package ipvlan |
|
| 3 |
+package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" |
|
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 | 6 |
"context" |
| ... | ... |
@@ -22,11 +22,10 @@ import ( |
| 22 | 22 |
|
| 23 | 23 |
func TestDockerNetworkIpvlanPersistance(t *testing.T) {
|
| 24 | 24 |
// verify the driver automatically provisions the 802.1q link (di-dummy0.70) |
| 25 |
- skip.If(t, testEnv.DaemonInfo.OSType == "windows") |
|
| 26 | 25 |
skip.If(t, testEnv.IsRemoteDaemon) |
| 27 | 26 |
skip.If(t, !ipvlanKernelSupport(t), "Kernel doesn't support ipvlan") |
| 28 | 27 |
|
| 29 |
- d := daemon.New(t, daemon.WithExperimental) |
|
| 28 |
+ d := daemon.New(t) |
|
| 30 | 29 |
d.StartWithBusybox(t) |
| 31 | 30 |
defer d.Stop(t) |
| 32 | 31 |
|
| ... | ... |
@@ -50,7 +49,6 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) {
|
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 | 52 |
func TestDockerNetworkIpvlan(t *testing.T) {
|
| 53 |
- skip.If(t, testEnv.DaemonInfo.OSType == "windows") |
|
| 54 | 53 |
skip.If(t, testEnv.IsRemoteDaemon) |
| 55 | 54 |
skip.If(t, !ipvlanKernelSupport(t), "Kernel doesn't support ipvlan") |
| 56 | 55 |
|
| ... | ... |
@@ -87,7 +85,7 @@ func TestDockerNetworkIpvlan(t *testing.T) {
|
| 87 | 87 |
test: testIpvlanAddressing, |
| 88 | 88 |
}, |
| 89 | 89 |
} {
|
| 90 |
- d := daemon.New(t, daemon.WithExperimental) |
|
| 90 |
+ d := daemon.New(t) |
|
| 91 | 91 |
d.StartWithBusybox(t) |
| 92 | 92 |
c := d.NewClientT(t) |
| 93 | 93 |
|
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
// +build !windows |
| 2 | 2 |
|
| 3 |
-package macvlan |
|
| 3 |
+package macvlan // import "github.com/docker/docker/integration/network/macvlan" |
|
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 | 6 |
"context" |
| ... | ... |
@@ -20,7 +20,6 @@ import ( |
| 20 | 20 |
func TestDockerNetworkMacvlanPersistance(t *testing.T) {
|
| 21 | 21 |
// verify the driver automatically provisions the 802.1q link (dm-dummy0.60) |
| 22 | 22 |
skip.If(t, testEnv.IsRemoteDaemon) |
| 23 |
- skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") |
|
| 24 | 23 |
|
| 25 | 24 |
d := daemon.New(t) |
| 26 | 25 |
d.StartWithBusybox(t) |
| ... | ... |
@@ -43,7 +42,6 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) {
|
| 43 | 43 |
|
| 44 | 44 |
func TestDockerNetworkMacvlan(t *testing.T) {
|
| 45 | 45 |
skip.If(t, testEnv.IsRemoteDaemon) |
| 46 |
- skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") |
|
| 47 | 46 |
|
| 48 | 47 |
for _, tc := range []struct {
|
| 49 | 48 |
name string |
| ... | ... |
@@ -271,8 +269,3 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) {
|
| 271 | 271 |
assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abca::254 dev eth0")) |
| 272 | 272 |
} |
| 273 | 273 |
} |
| 274 |
- |
|
| 275 |
-// ensure Kernel version is >= v3.9 for macvlan support |
|
| 276 |
-func macvlanKernelSupport() bool {
|
|
| 277 |
- return n.CheckKernelMajorVersionGreaterOrEqualThen(3, 9) |
|
| 278 |
-} |
| ... | ... |
@@ -7,9 +7,7 @@ import ( |
| 7 | 7 |
|
| 8 | 8 |
"github.com/docker/docker/api/types" |
| 9 | 9 |
"github.com/docker/docker/api/types/container" |
| 10 |
- "github.com/docker/docker/api/types/filters" |
|
| 11 | 10 |
swarmtypes "github.com/docker/docker/api/types/swarm" |
| 12 |
- "github.com/docker/docker/client" |
|
| 13 | 11 |
"github.com/docker/docker/integration/internal/swarm" |
| 14 | 12 |
"github.com/google/go-cmp/cmp" |
| 15 | 13 |
"gotest.tools/assert" |
| ... | ... |
@@ -38,7 +36,7 @@ func TestInspect(t *testing.T) {
|
| 38 | 38 |
assert.NilError(t, err) |
| 39 | 39 |
|
| 40 | 40 |
id := resp.ID |
| 41 |
- poll.WaitOn(t, serviceContainerCount(client, id, instances)) |
|
| 41 |
+ poll.WaitOn(t, swarm.RunningTasksCount(client, id, instances)) |
|
| 42 | 42 |
|
| 43 | 43 |
service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
|
| 44 | 44 |
assert.NilError(t, err) |
| ... | ... |
@@ -134,21 +132,3 @@ func fullSwarmServiceSpec(name string, replicas uint64) swarmtypes.ServiceSpec {
|
| 134 | 134 |
}, |
| 135 | 135 |
} |
| 136 | 136 |
} |
| 137 |
- |
|
| 138 |
-func serviceContainerCount(client client.ServiceAPIClient, id string, count uint64) func(log poll.LogT) poll.Result {
|
|
| 139 |
- return func(log poll.LogT) poll.Result {
|
|
| 140 |
- filter := filters.NewArgs() |
|
| 141 |
- filter.Add("service", id)
|
|
| 142 |
- tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
|
|
| 143 |
- Filters: filter, |
|
| 144 |
- }) |
|
| 145 |
- switch {
|
|
| 146 |
- case err != nil: |
|
| 147 |
- return poll.Error(err) |
|
| 148 |
- case len(tasks) == int(count): |
|
| 149 |
- return poll.Success() |
|
| 150 |
- default: |
|
| 151 |
- return poll.Continue("task count at %d waiting for %d", len(tasks), count)
|
|
| 152 |
- } |
|
| 153 |
- } |
|
| 154 |
-} |
| ... | ... |
@@ -4,7 +4,7 @@ import ( |
| 4 | 4 |
"net/http" |
| 5 | 5 |
"testing" |
| 6 | 6 |
|
| 7 |
- "github.com/docker/docker/internal/test/daemon" |
|
| 7 |
+ "github.com/docker/docker/api/types/versions" |
|
| 8 | 8 |
req "github.com/docker/docker/internal/test/request" |
| 9 | 9 |
"gotest.tools/assert" |
| 10 | 10 |
is "gotest.tools/assert/cmp" |
| ... | ... |
@@ -13,17 +13,10 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
func TestSessionCreate(t *testing.T) {
|
| 15 | 15 |
skip.If(t, testEnv.OSType == "windows", "FIXME") |
| 16 |
+ skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") |
|
| 16 | 17 |
|
| 17 | 18 |
defer setupTest(t)() |
| 18 | 19 |
daemonHost := req.DaemonHost() |
| 19 |
- if !testEnv.DaemonInfo.ExperimentalBuild {
|
|
| 20 |
- skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") |
|
| 21 |
- |
|
| 22 |
- d := daemon.New(t, daemon.WithExperimental) |
|
| 23 |
- d.StartWithBusybox(t) |
|
| 24 |
- defer d.Stop(t) |
|
| 25 |
- daemonHost = d.Sock() |
|
| 26 |
- } |
|
| 27 | 20 |
|
| 28 | 21 |
res, body, err := req.Post("/session",
|
| 29 | 22 |
req.Host(daemonHost), |
| ... | ... |
@@ -41,17 +34,10 @@ func TestSessionCreate(t *testing.T) {
|
| 41 | 41 |
|
| 42 | 42 |
func TestSessionCreateWithBadUpgrade(t *testing.T) {
|
| 43 | 43 |
skip.If(t, testEnv.OSType == "windows", "FIXME") |
| 44 |
+ skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") |
|
| 44 | 45 |
|
| 45 | 46 |
defer setupTest(t)() |
| 46 | 47 |
daemonHost := req.DaemonHost() |
| 47 |
- if !testEnv.DaemonInfo.ExperimentalBuild {
|
|
| 48 |
- skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") |
|
| 49 |
- |
|
| 50 |
- d := daemon.New(t, daemon.WithExperimental) |
|
| 51 |
- d.StartWithBusybox(t) |
|
| 52 |
- defer d.Stop(t) |
|
| 53 |
- daemonHost = d.Sock() |
|
| 54 |
- } |
|
| 55 | 48 |
|
| 56 | 49 |
res, body, err := req.Post("/session", req.Host(daemonHost))
|
| 57 | 50 |
assert.NilError(t, err) |
| ... | ... |
@@ -147,6 +147,11 @@ func New(t testingT, ops ...func(*Daemon)) *Daemon {
|
| 147 | 147 |
return d |
| 148 | 148 |
} |
| 149 | 149 |
|
| 150 |
+// ContainersNamespace returns the containerd namespace used for containers. |
|
| 151 |
+func (d *Daemon) ContainersNamespace() string {
|
|
| 152 |
+ return d.id |
|
| 153 |
+} |
|
| 154 |
+ |
|
| 150 | 155 |
// RootDir returns the root directory of the daemon. |
| 151 | 156 |
func (d *Daemon) RootDir() string {
|
| 152 | 157 |
return d.Root |
| ... | ... |
@@ -231,12 +236,15 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
|
| 231 | 231 |
if err != nil {
|
| 232 | 232 |
return errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id) |
| 233 | 233 |
} |
| 234 |
+ |
|
| 234 | 235 |
args := append(d.GlobalFlags, |
| 235 | 236 |
"--containerd", containerdSocket, |
| 236 | 237 |
"--data-root", d.Root, |
| 237 | 238 |
"--exec-root", d.execRoot, |
| 238 | 239 |
"--pidfile", fmt.Sprintf("%s/docker.pid", d.Folder),
|
| 239 | 240 |
fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
|
| 241 |
+ "--containerd-namespace", d.id, |
|
| 242 |
+ "--containerd-plugins-namespace", d.id+"p", |
|
| 240 | 243 |
) |
| 241 | 244 |
if d.experimental {
|
| 242 | 245 |
args = append(args, "--experimental") |
| ... | ... |
@@ -313,7 +321,7 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
|
| 313 | 313 |
defer cancel() |
| 314 | 314 |
|
| 315 | 315 |
// make sure daemon is ready to receive requests |
| 316 |
- for {
|
|
| 316 |
+ for i := 0; ; i++ {
|
|
| 317 | 317 |
d.log.Logf("[%s] waiting for daemon to start", d.id)
|
| 318 | 318 |
|
| 319 | 319 |
select {
|
| ... | ... |
@@ -327,9 +335,14 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
|
| 327 | 327 |
|
| 328 | 328 |
resp, err := client.Do(req.WithContext(rctx)) |
| 329 | 329 |
if err != nil {
|
| 330 |
- d.log.Logf("[%s] error pinging daemon on start: %v", d.id, err)
|
|
| 331 |
- |
|
| 332 |
- time.Sleep(500 * time.Millisecond) |
|
| 330 |
+ if i > 2 { // don't log the first couple, this ends up just being noise
|
|
| 331 |
+ d.log.Logf("[%s] error pinging daemon on start: %v", d.id, err)
|
|
| 332 |
+ } |
|
| 333 |
+ |
|
| 334 |
+ select {
|
|
| 335 |
+ case <-ctx.Done(): |
|
| 336 |
+ case <-time.After(500 * time.Millisecond): |
|
| 337 |
+ } |
|
| 333 | 338 |
continue |
| 334 | 339 |
} |
| 335 | 340 |
|
| ... | ... |
@@ -700,8 +713,10 @@ func cleanupRaftDir(t testingT, rootPath string) {
|
| 700 | 700 |
if ht, ok := t.(test.HelperT); ok {
|
| 701 | 701 |
ht.Helper() |
| 702 | 702 |
} |
| 703 |
- walDir := filepath.Join(rootPath, "swarm/raft/wal") |
|
| 704 |
- if err := os.RemoveAll(walDir); err != nil {
|
|
| 705 |
- t.Logf("error removing %v: %v", walDir, err)
|
|
| 703 |
+ for _, p := range []string{"wal", "wal-v3-encrypted", "snap-v3-encrypted"} {
|
|
| 704 |
+ dir := filepath.Join(rootPath, "swarm/raft", p) |
|
| 705 |
+ if err := os.RemoveAll(dir); err != nil {
|
|
| 706 |
+ t.Logf("error removing %v: %v", dir, err)
|
|
| 707 |
+ } |
|
| 706 | 708 |
} |
| 707 | 709 |
} |
| ... | ... |
@@ -20,12 +20,19 @@ var ( |
| 20 | 20 |
startArgs = []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
|
| 21 | 21 |
) |
| 22 | 22 |
|
| 23 |
-// StartNode starts daemon to be used as a swarm node |
|
| 23 |
+// StartNode (re)starts the daemon |
|
| 24 | 24 |
func (d *Daemon) StartNode(t testingT) {
|
| 25 | 25 |
if ht, ok := t.(test.HelperT); ok {
|
| 26 | 26 |
ht.Helper() |
| 27 | 27 |
} |
| 28 |
- // avoid networking conflicts |
|
| 28 |
+ d.Start(t, startArgs...) |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// StartNodeWithBusybox starts daemon to be used as a swarm node, and loads the busybox image |
|
| 32 |
+func (d *Daemon) StartNodeWithBusybox(t testingT) {
|
|
| 33 |
+ if ht, ok := t.(test.HelperT); ok {
|
|
| 34 |
+ ht.Helper() |
|
| 35 |
+ } |
|
| 29 | 36 |
d.StartWithBusybox(t, startArgs...) |
| 30 | 37 |
} |
| 31 | 38 |
|
| ... | ... |
@@ -36,24 +43,28 @@ func (d *Daemon) RestartNode(t testingT) {
|
| 36 | 36 |
} |
| 37 | 37 |
// avoid networking conflicts |
| 38 | 38 |
d.Stop(t) |
| 39 |
- d.StartWithBusybox(t, startArgs...) |
|
| 39 |
+ d.Start(t, startArgs...) |
|
| 40 | 40 |
} |
| 41 | 41 |
|
| 42 | 42 |
// StartAndSwarmInit starts the daemon (with busybox) and init the swarm |
| 43 | 43 |
func (d *Daemon) StartAndSwarmInit(t testingT) {
|
| 44 |
- d.StartNode(t) |
|
| 44 |
+ d.StartNodeWithBusybox(t) |
|
| 45 | 45 |
d.SwarmInit(t, swarm.InitRequest{})
|
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 | 48 |
// StartAndSwarmJoin starts the daemon (with busybox) and join the specified swarm as worker or manager |
| 49 | 49 |
func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) {
|
| 50 |
- d.StartNode(t) |
|
| 50 |
+ if th, ok := t.(test.HelperT); ok {
|
|
| 51 |
+ th.Helper() |
|
| 52 |
+ } |
|
| 53 |
+ d.StartNodeWithBusybox(t) |
|
| 51 | 54 |
|
| 52 | 55 |
tokens := leader.JoinTokens(t) |
| 53 | 56 |
token := tokens.Worker |
| 54 | 57 |
if manager {
|
| 55 | 58 |
token = tokens.Manager |
| 56 | 59 |
} |
| 60 |
+ t.Logf("[%s] joining swarm manager [%s]@%s, swarm listen addr %s", d.id, leader.id, leader.SwarmListenAddr(), d.SwarmListenAddr())
|
|
| 57 | 61 |
d.SwarmJoin(t, swarm.JoinRequest{
|
| 58 | 62 |
RemoteAddrs: []string{leader.SwarmListenAddr()},
|
| 59 | 63 |
JoinToken: token, |
| ... | ... |
@@ -106,7 +117,7 @@ func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) {
|
| 106 | 106 |
cli := d.NewClientT(t) |
| 107 | 107 |
defer cli.Close() |
| 108 | 108 |
err := cli.SwarmJoin(context.Background(), req) |
| 109 |
- assert.NilError(t, err, "initializing swarm") |
|
| 109 |
+ assert.NilError(t, err, "[%s] joining swarm", d.id) |
|
| 110 | 110 |
d.CachedInfo = d.Info(t) |
| 111 | 111 |
} |
| 112 | 112 |
|
| ... | ... |
@@ -2,7 +2,6 @@ package term // import "github.com/docker/docker/pkg/term" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 |
- "fmt" |
|
| 6 | 5 |
"testing" |
| 7 | 6 |
|
| 8 | 7 |
"gotest.tools/assert" |
| ... | ... |
@@ -10,106 +9,143 @@ import ( |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
func TestEscapeProxyRead(t *testing.T) {
|
| 13 |
- escapeKeys, _ := ToBytes("")
|
|
| 14 |
- keys, _ := ToBytes("a")
|
|
| 15 |
- reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 16 |
- buf := make([]byte, len(keys)) |
|
| 17 |
- nr, err := reader.Read(buf) |
|
| 18 |
- assert.NilError(t, err) |
|
| 19 |
- assert.Equal(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys)))
|
|
| 20 |
- assert.DeepEqual(t, keys, buf) |
|
| 21 |
- |
|
| 22 |
- keys, _ = ToBytes("a,b,c")
|
|
| 23 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 24 |
- buf = make([]byte, len(keys)) |
|
| 25 |
- nr, err = reader.Read(buf) |
|
| 26 |
- assert.NilError(t, err) |
|
| 27 |
- assert.Equal(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys)))
|
|
| 28 |
- assert.DeepEqual(t, keys, buf) |
|
| 29 |
- |
|
| 30 |
- keys, _ = ToBytes("")
|
|
| 31 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 32 |
- buf = make([]byte, len(keys)) |
|
| 33 |
- nr, err = reader.Read(buf) |
|
| 34 |
- assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") |
|
| 35 |
- assert.Equal(t, nr, 0, "nr should be zero") |
|
| 36 |
- assert.Check(t, is.Len(keys, 0)) |
|
| 37 |
- assert.Check(t, is.Len(buf, 0)) |
|
| 38 |
- |
|
| 39 |
- escapeKeys, _ = ToBytes("DEL")
|
|
| 40 |
- keys, _ = ToBytes("a,b,c,+")
|
|
| 41 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 42 |
- buf = make([]byte, len(keys)) |
|
| 43 |
- nr, err = reader.Read(buf) |
|
| 44 |
- assert.NilError(t, err) |
|
| 45 |
- assert.Equal(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys)))
|
|
| 46 |
- assert.DeepEqual(t, keys, buf) |
|
| 47 |
- |
|
| 48 |
- keys, _ = ToBytes("")
|
|
| 49 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 50 |
- buf = make([]byte, len(keys)) |
|
| 51 |
- nr, err = reader.Read(buf) |
|
| 52 |
- assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") |
|
| 53 |
- assert.Equal(t, nr, 0, "nr should be zero") |
|
| 54 |
- assert.Check(t, is.Len(keys, 0)) |
|
| 55 |
- assert.Check(t, is.Len(buf, 0)) |
|
| 56 |
- |
|
| 57 |
- escapeKeys, _ = ToBytes("ctrl-x,ctrl-@")
|
|
| 58 |
- keys, _ = ToBytes("DEL")
|
|
| 59 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 60 |
- buf = make([]byte, len(keys)) |
|
| 61 |
- nr, err = reader.Read(buf) |
|
| 62 |
- assert.NilError(t, err) |
|
| 63 |
- assert.Equal(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr))
|
|
| 64 |
- assert.DeepEqual(t, keys, buf) |
|
| 65 |
- |
|
| 66 |
- escapeKeys, _ = ToBytes("ctrl-c")
|
|
| 67 |
- keys, _ = ToBytes("ctrl-c")
|
|
| 68 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 69 |
- buf = make([]byte, len(keys)) |
|
| 70 |
- nr, err = reader.Read(buf) |
|
| 71 |
- assert.Error(t, err, "read escape sequence") |
|
| 72 |
- assert.Equal(t, nr, 0, "nr should be equal to 0") |
|
| 73 |
- assert.DeepEqual(t, keys, buf) |
|
| 74 |
- |
|
| 75 |
- escapeKeys, _ = ToBytes("ctrl-c,ctrl-z")
|
|
| 76 |
- keys, _ = ToBytes("ctrl-c,ctrl-z")
|
|
| 77 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 78 |
- buf = make([]byte, 1) |
|
| 79 |
- nr, err = reader.Read(buf) |
|
| 80 |
- assert.NilError(t, err) |
|
| 81 |
- assert.Equal(t, nr, 0, "nr should be equal to 0") |
|
| 82 |
- assert.DeepEqual(t, keys[0:1], buf) |
|
| 83 |
- nr, err = reader.Read(buf) |
|
| 84 |
- assert.Error(t, err, "read escape sequence") |
|
| 85 |
- assert.Equal(t, nr, 0, "nr should be equal to 0") |
|
| 86 |
- assert.DeepEqual(t, keys[1:], buf) |
|
| 87 |
- |
|
| 88 |
- escapeKeys, _ = ToBytes("ctrl-c,ctrl-z")
|
|
| 89 |
- keys, _ = ToBytes("ctrl-c,DEL,+")
|
|
| 90 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 91 |
- buf = make([]byte, 1) |
|
| 92 |
- nr, err = reader.Read(buf) |
|
| 93 |
- assert.NilError(t, err) |
|
| 94 |
- assert.Equal(t, nr, 0, "nr should be equal to 0") |
|
| 95 |
- assert.DeepEqual(t, keys[0:1], buf) |
|
| 96 |
- buf = make([]byte, len(keys)) |
|
| 97 |
- nr, err = reader.Read(buf) |
|
| 98 |
- assert.NilError(t, err) |
|
| 99 |
- assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys)))
|
|
| 100 |
- assert.DeepEqual(t, keys, buf) |
|
| 101 |
- |
|
| 102 |
- escapeKeys, _ = ToBytes("ctrl-c,ctrl-z")
|
|
| 103 |
- keys, _ = ToBytes("ctrl-c,DEL")
|
|
| 104 |
- reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 105 |
- buf = make([]byte, 1) |
|
| 106 |
- nr, err = reader.Read(buf) |
|
| 107 |
- assert.NilError(t, err) |
|
| 108 |
- assert.Equal(t, nr, 0, "nr should be equal to 0") |
|
| 109 |
- assert.DeepEqual(t, keys[0:1], buf) |
|
| 110 |
- buf = make([]byte, len(keys)) |
|
| 111 |
- nr, err = reader.Read(buf) |
|
| 112 |
- assert.NilError(t, err) |
|
| 113 |
- assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys)))
|
|
| 114 |
- assert.DeepEqual(t, keys, buf) |
|
| 13 |
+ t.Run("no escape keys, keys a", func(t *testing.T) {
|
|
| 14 |
+ escapeKeys, _ := ToBytes("")
|
|
| 15 |
+ keys, _ := ToBytes("a")
|
|
| 16 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 17 |
+ |
|
| 18 |
+ buf := make([]byte, len(keys)) |
|
| 19 |
+ nr, err := reader.Read(buf) |
|
| 20 |
+ assert.NilError(t, err) |
|
| 21 |
+ assert.Equal(t, nr, len(keys)) |
|
| 22 |
+ assert.DeepEqual(t, keys, buf) |
|
| 23 |
+ }) |
|
| 24 |
+ |
|
| 25 |
+ t.Run("no escape keys, keys a,b,c", func(t *testing.T) {
|
|
| 26 |
+ escapeKeys, _ := ToBytes("")
|
|
| 27 |
+ keys, _ := ToBytes("a,b,c")
|
|
| 28 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 29 |
+ |
|
| 30 |
+ buf := make([]byte, len(keys)) |
|
| 31 |
+ nr, err := reader.Read(buf) |
|
| 32 |
+ assert.NilError(t, err) |
|
| 33 |
+ assert.Equal(t, nr, len(keys)) |
|
| 34 |
+ assert.DeepEqual(t, keys, buf) |
|
| 35 |
+ }) |
|
| 36 |
+ |
|
| 37 |
+ t.Run("no escape keys, no keys", func(t *testing.T) {
|
|
| 38 |
+ escapeKeys, _ := ToBytes("")
|
|
| 39 |
+ keys, _ := ToBytes("")
|
|
| 40 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 41 |
+ |
|
| 42 |
+ buf := make([]byte, len(keys)) |
|
| 43 |
+ nr, err := reader.Read(buf) |
|
| 44 |
+ assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") |
|
| 45 |
+ assert.Equal(t, nr, 0) |
|
| 46 |
+ assert.Check(t, is.Len(keys, 0)) |
|
| 47 |
+ assert.Check(t, is.Len(buf, 0)) |
|
| 48 |
+ }) |
|
| 49 |
+ |
|
| 50 |
+ t.Run("DEL escape key, keys a,b,c,+", func(t *testing.T) {
|
|
| 51 |
+ escapeKeys, _ := ToBytes("DEL")
|
|
| 52 |
+ keys, _ := ToBytes("a,b,c,+")
|
|
| 53 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 54 |
+ |
|
| 55 |
+ buf := make([]byte, len(keys)) |
|
| 56 |
+ nr, err := reader.Read(buf) |
|
| 57 |
+ assert.NilError(t, err) |
|
| 58 |
+ assert.Equal(t, nr, len(keys)) |
|
| 59 |
+ assert.DeepEqual(t, keys, buf) |
|
| 60 |
+ }) |
|
| 61 |
+ |
|
| 62 |
+ t.Run("DEL escape key, no keys", func(t *testing.T) {
|
|
| 63 |
+ escapeKeys, _ := ToBytes("DEL")
|
|
| 64 |
+ keys, _ := ToBytes("")
|
|
| 65 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 66 |
+ |
|
| 67 |
+ buf := make([]byte, len(keys)) |
|
| 68 |
+ nr, err := reader.Read(buf) |
|
| 69 |
+ assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") |
|
| 70 |
+ assert.Equal(t, nr, 0) |
|
| 71 |
+ assert.Check(t, is.Len(keys, 0)) |
|
| 72 |
+ assert.Check(t, is.Len(buf, 0)) |
|
| 73 |
+ }) |
|
| 74 |
+ |
|
| 75 |
+ t.Run("ctrl-x,ctrl-@ escape key, keys DEL", func(t *testing.T) {
|
|
| 76 |
+ escapeKeys, _ := ToBytes("ctrl-x,ctrl-@")
|
|
| 77 |
+ keys, _ := ToBytes("DEL")
|
|
| 78 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 79 |
+ |
|
| 80 |
+ buf := make([]byte, len(keys)) |
|
| 81 |
+ nr, err := reader.Read(buf) |
|
| 82 |
+ assert.NilError(t, err) |
|
| 83 |
+ assert.Equal(t, nr, 1) |
|
| 84 |
+ assert.DeepEqual(t, keys, buf) |
|
| 85 |
+ }) |
|
| 86 |
+ |
|
| 87 |
+ t.Run("ctrl-c escape key, keys ctrl-c", func(t *testing.T) {
|
|
| 88 |
+ escapeKeys, _ := ToBytes("ctrl-c")
|
|
| 89 |
+ keys, _ := ToBytes("ctrl-c")
|
|
| 90 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 91 |
+ |
|
| 92 |
+ buf := make([]byte, len(keys)) |
|
| 93 |
+ nr, err := reader.Read(buf) |
|
| 94 |
+ assert.Error(t, err, "read escape sequence") |
|
| 95 |
+ assert.Equal(t, nr, 0) |
|
| 96 |
+ assert.DeepEqual(t, keys, buf) |
|
| 97 |
+ }) |
|
| 98 |
+ |
|
| 99 |
+ t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,ctrl-z", func(t *testing.T) {
|
|
| 100 |
+ escapeKeys, _ := ToBytes("ctrl-c,ctrl-z")
|
|
| 101 |
+ keys, _ := ToBytes("ctrl-c,ctrl-z")
|
|
| 102 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 103 |
+ |
|
| 104 |
+ buf := make([]byte, 1) |
|
| 105 |
+ nr, err := reader.Read(buf) |
|
| 106 |
+ assert.NilError(t, err) |
|
| 107 |
+ assert.Equal(t, nr, 0) |
|
| 108 |
+ assert.DeepEqual(t, keys[0:1], buf) |
|
| 109 |
+ |
|
| 110 |
+ nr, err = reader.Read(buf) |
|
| 111 |
+ assert.Error(t, err, "read escape sequence") |
|
| 112 |
+ assert.Equal(t, nr, 0) |
|
| 113 |
+ assert.DeepEqual(t, keys[1:], buf) |
|
| 114 |
+ }) |
|
| 115 |
+ |
|
| 116 |
+ t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,DEL,+", func(t *testing.T) {
|
|
| 117 |
+ escapeKeys, _ := ToBytes("ctrl-c,ctrl-z")
|
|
| 118 |
+ keys, _ := ToBytes("ctrl-c,DEL,+")
|
|
| 119 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 120 |
+ |
|
| 121 |
+ buf := make([]byte, 1) |
|
| 122 |
+ nr, err := reader.Read(buf) |
|
| 123 |
+ assert.NilError(t, err) |
|
| 124 |
+ assert.Equal(t, nr, 0) |
|
| 125 |
+ assert.DeepEqual(t, keys[0:1], buf) |
|
| 126 |
+ |
|
| 127 |
+ buf = make([]byte, len(keys)) |
|
| 128 |
+ nr, err = reader.Read(buf) |
|
| 129 |
+ assert.NilError(t, err) |
|
| 130 |
+ assert.Equal(t, nr, len(keys)) |
|
| 131 |
+ assert.DeepEqual(t, keys, buf) |
|
| 132 |
+ }) |
|
| 133 |
+ |
|
| 134 |
+ t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,DEL", func(t *testing.T) {
|
|
| 135 |
+ escapeKeys, _ := ToBytes("ctrl-c,ctrl-z")
|
|
| 136 |
+ keys, _ := ToBytes("ctrl-c,DEL")
|
|
| 137 |
+ reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) |
|
| 138 |
+ |
|
| 139 |
+ buf := make([]byte, 1) |
|
| 140 |
+ nr, err := reader.Read(buf) |
|
| 141 |
+ assert.NilError(t, err) |
|
| 142 |
+ assert.Equal(t, nr, 0) |
|
| 143 |
+ assert.DeepEqual(t, keys[0:1], buf) |
|
| 144 |
+ |
|
| 145 |
+ buf = make([]byte, len(keys)) |
|
| 146 |
+ nr, err = reader.Read(buf) |
|
| 147 |
+ assert.NilError(t, err) |
|
| 148 |
+ assert.Equal(t, nr, len(keys)) |
|
| 149 |
+ assert.DeepEqual(t, keys, buf) |
|
| 150 |
+ }) |
|
| 151 |
+ |
|
| 115 | 152 |
} |
| ... | ... |
@@ -26,13 +26,13 @@ type ExitHandler interface {
|
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 | 28 |
// New creates a new containerd plugin executor |
| 29 |
-func New(ctx context.Context, rootDir string, cli *containerd.Client, exitHandler ExitHandler) (*Executor, error) {
|
|
| 29 |
+func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler) (*Executor, error) {
|
|
| 30 | 30 |
e := &Executor{
|
| 31 | 31 |
rootDir: rootDir, |
| 32 | 32 |
exitHandler: exitHandler, |
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 |
- client, err := libcontainerd.NewClient(ctx, cli, rootDir, PluginNamespace, e) |
|
| 35 |
+ client, err := libcontainerd.NewClient(ctx, cli, rootDir, ns, e) |
|
| 36 | 36 |
if err != nil {
|
| 37 | 37 |
return nil, errors.Wrap(err, "error creating containerd exec client") |
| 38 | 38 |
} |