mirror of
https://github.com/moby/moby.git
synced 2026-01-12 19:21:41 +00:00
Compare commits
173 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3025fab86d | ||
|
|
2af1a28b19 | ||
|
|
6e95db3aa6 | ||
|
|
3a8eb7efe5 | ||
|
|
f5f15cef17 | ||
|
|
b6c3f5483b | ||
|
|
88c68b1226 | ||
|
|
faf6a54607 | ||
|
|
bdcc51c004 | ||
|
|
9c6669ca38 | ||
|
|
5205ea9f8e | ||
|
|
64a40af0ef | ||
|
|
f7c3505c82 | ||
|
|
3e0c4ba425 | ||
|
|
2a322a86ec | ||
|
|
89b3062abd | ||
|
|
e39ef953eb | ||
|
|
70ed458f9b | ||
|
|
3bda2f839e | ||
|
|
81b93d3e05 | ||
|
|
28e8a23afd | ||
|
|
d8a1415724 | ||
|
|
4d9560d6df | ||
|
|
357886087c | ||
|
|
37f2a4135a | ||
|
|
30ff73f25a | ||
|
|
30f2e54a95 | ||
|
|
f2bc077921 | ||
|
|
9b7903b291 | ||
|
|
53ecbc1e26 | ||
|
|
b61235e50a | ||
|
|
b3a92aedd5 | ||
|
|
ed9dba83fd | ||
|
|
d8674ab4d9 | ||
|
|
ef804f5954 | ||
|
|
95807d26b8 | ||
|
|
d960588787 | ||
|
|
936bfb792c | ||
|
|
590e249fb9 | ||
|
|
eaac976b86 | ||
|
|
01ba6c607d | ||
|
|
4c146e4945 | ||
|
|
5b2bd7a42c | ||
|
|
277b75e5c2 | ||
|
|
2e72912cdb | ||
|
|
8b58088b87 | ||
|
|
e462220e0e | ||
|
|
578c65d309 | ||
|
|
328131f6d9 | ||
|
|
8d9bd34f6d | ||
|
|
4dc89c2ba5 | ||
|
|
792b33ddad | ||
|
|
6ea1289acc | ||
|
|
254ff38eb1 | ||
|
|
c20fcb4d2c | ||
|
|
b097b8c18e | ||
|
|
0f69c67a27 | ||
|
|
8d5c53e1d4 | ||
|
|
9c662344a1 | ||
|
|
3fb5329499 | ||
|
|
4c81a932c0 | ||
|
|
d333ed926e | ||
|
|
c4c2efb855 | ||
|
|
ba6dcc61d2 | ||
|
|
e5b0f306c9 | ||
|
|
9e12578690 | ||
|
|
85daff009a | ||
|
|
0f4b73cd74 | ||
|
|
e581b23691 | ||
|
|
20bd79ac97 | ||
|
|
1b47203d9a | ||
|
|
237840446b | ||
|
|
eac73050d7 | ||
|
|
7a9644db86 | ||
|
|
de54a079af | ||
|
|
834ded3aee | ||
|
|
50ebafca50 | ||
|
|
c2ae605ee5 | ||
|
|
047fc79ee1 | ||
|
|
7464a5c496 | ||
|
|
d72ea00242 | ||
|
|
93b315efa5 | ||
|
|
a9ce67fb88 | ||
|
|
16c0d67f4d | ||
|
|
683a13108e | ||
|
|
74666f41d7 | ||
|
|
c363a59c2d | ||
|
|
6656e12aaa | ||
|
|
58a2b0e872 | ||
|
|
3a5a738a55 | ||
|
|
86885803ff | ||
|
|
3fe917f56a | ||
|
|
1b71859bb5 | ||
|
|
fe4cd44867 | ||
|
|
b5235a6c4a | ||
|
|
fbdfaeeedc | ||
|
|
b8835f4bba | ||
|
|
486d776e49 | ||
|
|
1b0bc01b70 | ||
|
|
f20597e377 | ||
|
|
12cdef7182 | ||
|
|
7ca5a37fbe | ||
|
|
2256402711 | ||
|
|
c7c462a7b6 | ||
|
|
d4afed04d6 | ||
|
|
0ea0289c77 | ||
|
|
77dcf9e04b | ||
|
|
5e22bc1b27 | ||
|
|
41446f1992 | ||
|
|
355f08e80f | ||
|
|
9a16ce3de0 | ||
|
|
ba83de48c9 | ||
|
|
715612aabb | ||
|
|
1be121e241 | ||
|
|
06cfa32468 | ||
|
|
13693101bf | ||
|
|
0732215719 | ||
|
|
b1754d1e1c | ||
|
|
411e817ddf | ||
|
|
9cc85eaef1 | ||
|
|
820cab90bc | ||
|
|
6bc49067a6 | ||
|
|
6fbdce4b94 | ||
|
|
f5334644ec | ||
|
|
c1d4587d76 | ||
|
|
d6428049a5 | ||
|
|
daba2462f5 | ||
|
|
de5c9cf0b9 | ||
|
|
c62dcf8ab1 | ||
|
|
17315a20ee | ||
|
|
cbd94183ab | ||
|
|
fb9f72aeb6 | ||
|
|
3115daaa91 | ||
|
|
2861734174 | ||
|
|
9c95aea306 | ||
|
|
3e09e197a7 | ||
|
|
65b679ac9c | ||
|
|
12072173df | ||
|
|
92f00d41ba | ||
|
|
a046857fbf | ||
|
|
476d9314d0 | ||
|
|
4021fa775e | ||
|
|
0fd5efe64a | ||
|
|
1017246d24 | ||
|
|
fbfa1bcc96 | ||
|
|
e12db89eef | ||
|
|
5838467405 | ||
|
|
1033f561af | ||
|
|
0fa6816991 | ||
|
|
eaad6f503d | ||
|
|
f679e1d4dc | ||
|
|
fda7b48363 | ||
|
|
258a372230 | ||
|
|
dbec963cee | ||
|
|
e35c6f5625 | ||
|
|
364e2d28ce | ||
|
|
06e19ec444 | ||
|
|
8e96db1c32 | ||
|
|
c21fe3efa3 | ||
|
|
86af4eddb3 | ||
|
|
73511cdee0 | ||
|
|
9326cda7bf | ||
|
|
76fcf9a8e0 | ||
|
|
ef1912d8b6 | ||
|
|
10739af81a | ||
|
|
ac2de55998 | ||
|
|
9a2b531127 | ||
|
|
2f5bbbe16b | ||
|
|
40618081f1 | ||
|
|
21da192ae4 | ||
|
|
2c91196921 | ||
|
|
a9a8787c93 | ||
|
|
c9689eccf5 |
9
.github/workflows/.dco.yml
vendored
9
.github/workflows/.dco.yml
vendored
@@ -7,11 +7,12 @@ on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
ALPINE_VERSION: 3.16
|
||||
ALPINE_VERSION: "3.20"
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -39,10 +40,12 @@ jobs:
|
||||
name: Validate
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "$(pwd):/workspace" \
|
||||
--quiet \
|
||||
-v ./:/workspace \
|
||||
-w /workspace \
|
||||
-e VALIDATE_REPO \
|
||||
-e VALIDATE_BRANCH \
|
||||
alpine:${{ env.ALPINE_VERSION }} sh -c 'apk add --no-cache -q bash git openssh-client && git config --system --add safe.directory /workspace && cd /workspace && hack/validate/dco'
|
||||
alpine:${{ env.ALPINE_VERSION }} sh -c 'apk add --no-cache -q bash git openssh-client && git config --system --add safe.directory /workspace && hack/validate/dco'
|
||||
env:
|
||||
VALIDATE_REPO: ${{ github.server_url }}/${{ github.repository }}.git
|
||||
VALIDATE_BRANCH: ${{ steps.base-ref.outputs.result }}
|
||||
|
||||
1
.github/workflows/.test-prepare.yml
vendored
1
.github/workflows/.test-prepare.yml
vendored
@@ -13,6 +13,7 @@ on:
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
outputs:
|
||||
matrix: ${{ steps.set.outputs.matrix }}
|
||||
steps:
|
||||
|
||||
19
.github/workflows/.test.yml
vendored
19
.github/workflows/.test.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
default: "graphdriver"
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.21.9"
|
||||
GO_VERSION: "1.22.10"
|
||||
GOTESTLIST_VERSION: v0.3.1
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
ITG_CLI_MATRIX_SIZE: 6
|
||||
@@ -23,8 +23,8 @@ env:
|
||||
jobs:
|
||||
unit:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -74,8 +74,8 @@ jobs:
|
||||
|
||||
unit-report:
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
- unit
|
||||
@@ -102,8 +102,8 @@ jobs:
|
||||
|
||||
docker-py:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -155,8 +155,8 @@ jobs:
|
||||
|
||||
integration-flaky:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@@ -183,8 +183,8 @@ jobs:
|
||||
|
||||
integration:
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -277,8 +277,8 @@ jobs:
|
||||
|
||||
integration-report:
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
- integration
|
||||
@@ -306,6 +306,7 @@ jobs:
|
||||
|
||||
integration-cli-prepare:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
outputs:
|
||||
matrix: ${{ steps.tests.outputs.matrix }}
|
||||
@@ -341,8 +342,8 @@ jobs:
|
||||
|
||||
integration-cli:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
needs:
|
||||
- integration-cli-prepare
|
||||
strategy:
|
||||
@@ -417,8 +418,8 @@ jobs:
|
||||
|
||||
integration-cli-report:
|
||||
runs-on: ubuntu-20.04
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
- integration-cli
|
||||
|
||||
16
.github/workflows/.windows.yml
vendored
16
.github/workflows/.windows.yml
vendored
@@ -19,7 +19,7 @@ on:
|
||||
default: false
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.21.9"
|
||||
GO_VERSION: "1.22.10"
|
||||
GOTESTLIST_VERSION: v0.3.1
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
WINDOWS_BASE_IMAGE: mcr.microsoft.com/windows/servercore
|
||||
@@ -33,6 +33,7 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ inputs.os }}
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
env:
|
||||
GOPATH: ${{ github.workspace }}\go
|
||||
GOBIN: ${{ github.workspace }}\go\bin
|
||||
@@ -112,7 +113,7 @@ jobs:
|
||||
|
||||
unit-test:
|
||||
runs-on: ${{ inputs.os }}
|
||||
timeout-minutes: 120
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
env:
|
||||
GOPATH: ${{ github.workspace }}\go
|
||||
GOBIN: ${{ github.workspace }}\go\bin
|
||||
@@ -193,7 +194,8 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
unit-test-report:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: always()
|
||||
needs:
|
||||
- unit-test
|
||||
@@ -219,7 +221,8 @@ jobs:
|
||||
find /tmp/artifacts -type f -name '*-go-test-report.json' -exec teststat -markdown {} \+ >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
integration-test-prepare:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
outputs:
|
||||
matrix: ${{ steps.tests.outputs.matrix }}
|
||||
steps:
|
||||
@@ -253,8 +256,8 @@ jobs:
|
||||
|
||||
integration-test:
|
||||
runs-on: ${{ inputs.os }}
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ inputs.storage == 'snapshotter' && github.event_name != 'pull_request' }}
|
||||
timeout-minutes: 120
|
||||
needs:
|
||||
- build
|
||||
- integration-test-prepare
|
||||
@@ -512,7 +515,8 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
integration-test-report:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ inputs.storage == 'snapshotter' && github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
|
||||
275
.github/workflows/arm64.yml
vendored
Normal file
275
.github/workflows/arm64.yml
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
name: arm64
|
||||
|
||||
# Default to 'contents: read', which grants actions to read commits.
|
||||
#
|
||||
# If any permission is set, any permission not included in the list is
|
||||
# implicitly set to "none".
|
||||
#
|
||||
# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- '[0-9]+.[0-9]+'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.22.10"
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
DESTDIR: ./build
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
SETUP_BUILDKIT_IMAGE: moby/buildkit:latest
|
||||
DOCKER_EXPERIMENTAL: 1
|
||||
|
||||
jobs:
|
||||
validate-dco:
|
||||
uses: ./.github/workflows/.dco.yml
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- binary
|
||||
- dynbinary
|
||||
steps:
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
-
|
||||
name: List artifacts
|
||||
run: |
|
||||
tree -nh ${{ env.DESTDIR }}
|
||||
-
|
||||
name: Check artifacts
|
||||
run: |
|
||||
find ${{ env.DESTDIR }} -type f -exec file -e ascii -- {} +
|
||||
|
||||
build-dev:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
steps:
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Build dev image
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: dev
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=dev-arm64
|
||||
*.cache-to=type=gha,scope=dev-arm64,mode=max
|
||||
*.output=type=cacheonly
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- build-dev
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up runner
|
||||
uses: ./.github/actions/setup-runner
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Build dev image
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: dev
|
||||
set: |
|
||||
dev.cache-from=type=gha,scope=dev-arm64
|
||||
-
|
||||
name: Test
|
||||
run: |
|
||||
make -o build test-unit
|
||||
-
|
||||
name: Prepare reports
|
||||
if: always()
|
||||
run: |
|
||||
mkdir -p bundles /tmp/reports
|
||||
find bundles -path '*/root/*overlay2' -prune -o -type f \( -name '*-report.json' -o -name '*.log' -o -name '*.out' -o -name '*.prof' -o -name '*-report.xml' \) -print | xargs sudo tar -czf /tmp/reports.tar.gz
|
||||
tar -xzf /tmp/reports.tar.gz -C /tmp/reports
|
||||
sudo chown -R $(id -u):$(id -g) /tmp/reports
|
||||
tree -nh /tmp/reports
|
||||
-
|
||||
name: Send to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
directory: ./bundles
|
||||
env_vars: RUNNER_OS
|
||||
flags: unit
|
||||
token: ${{ secrets.CODECOV_TOKEN }} # used to upload coverage reports: https://github.com/moby/buildkit/pull/4660#issue-2142122533
|
||||
-
|
||||
name: Upload reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-reports-unit-arm64-graphdriver
|
||||
path: /tmp/reports/*
|
||||
retention-days: 1
|
||||
|
||||
test-unit-report:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
- test-unit
|
||||
steps:
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: test-reports-unit-arm64-*
|
||||
path: /tmp/reports
|
||||
-
|
||||
name: Install teststat
|
||||
run: |
|
||||
go install github.com/vearutop/teststat@${{ env.TESTSTAT_VERSION }}
|
||||
-
|
||||
name: Create summary
|
||||
run: |
|
||||
find /tmp/reports -type f -name '*-go-test-report.json' -exec teststat -markdown {} \+ >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
needs:
|
||||
- build-dev
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up runner
|
||||
uses: ./.github/actions/setup-runner
|
||||
-
|
||||
name: Set up tracing
|
||||
uses: ./.github/actions/setup-tracing
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Build dev image
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: dev
|
||||
set: |
|
||||
dev.cache-from=type=gha,scope=dev-arm64
|
||||
-
|
||||
name: Test
|
||||
run: |
|
||||
make -o build test-integration
|
||||
env:
|
||||
TEST_SKIP_INTEGRATION_CLI: 1
|
||||
TESTCOVERAGE: 1
|
||||
-
|
||||
name: Prepare reports
|
||||
if: always()
|
||||
run: |
|
||||
reportsPath="/tmp/reports/arm64-graphdriver"
|
||||
mkdir -p bundles $reportsPath
|
||||
find bundles -path '*/root/*overlay2' -prune -o -type f \( -name '*-report.json' -o -name '*.log' -o -name '*.out' -o -name '*.prof' -o -name '*-report.xml' \) -print | xargs sudo tar -czf /tmp/reports.tar.gz
|
||||
tar -xzf /tmp/reports.tar.gz -C $reportsPath
|
||||
sudo chown -R $(id -u):$(id -g) $reportsPath
|
||||
tree -nh $reportsPath
|
||||
curl -sSLf localhost:16686/api/traces?service=integration-test-client > $reportsPath/jaeger-trace.json
|
||||
-
|
||||
name: Send to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
directory: ./bundles/test-integration
|
||||
env_vars: RUNNER_OS
|
||||
flags: integration
|
||||
token: ${{ secrets.CODECOV_TOKEN }} # used to upload coverage reports: https://github.com/moby/buildkit/pull/4660#issue-2142122533
|
||||
-
|
||||
name: Test daemon logs
|
||||
if: always()
|
||||
run: |
|
||||
cat bundles/test-integration/docker.log
|
||||
-
|
||||
name: Upload reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-reports-integration-arm64-graphdriver
|
||||
path: /tmp/reports/*
|
||||
retention-days: 1
|
||||
|
||||
test-integration-report:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
needs:
|
||||
- test-integration
|
||||
steps:
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/reports
|
||||
pattern: test-reports-integration-arm64-*
|
||||
merge-multiple: true
|
||||
-
|
||||
name: Install teststat
|
||||
run: |
|
||||
go install github.com/vearutop/teststat@${{ env.TESTSTAT_VERSION }}
|
||||
-
|
||||
name: Create summary
|
||||
run: |
|
||||
find /tmp/reports -type f -name '*-go-test-report.json' -exec teststat -markdown {} \+ >> $GITHUB_STEP_SUMMARY
|
||||
3
.github/workflows/bin-image.yml
vendored
3
.github/workflows/bin-image.yml
vendored
@@ -29,6 +29,7 @@ jobs:
|
||||
|
||||
prepare:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
outputs:
|
||||
platforms: ${{ steps.platforms.outputs.matrix }}
|
||||
steps:
|
||||
@@ -81,6 +82,7 @@ jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
- prepare
|
||||
@@ -151,6 +153,7 @@ jobs:
|
||||
|
||||
merge:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- build
|
||||
if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' && github.repository == 'moby/moby'
|
||||
|
||||
10
.github/workflows/buildkit.yml
vendored
10
.github/workflows/buildkit.yml
vendored
@@ -13,7 +13,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.21.9"
|
||||
GO_VERSION: "1.22.10"
|
||||
DESTDIR: ./build
|
||||
|
||||
jobs:
|
||||
@@ -22,6 +22,7 @@ jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
steps:
|
||||
@@ -47,7 +48,7 @@ jobs:
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- build
|
||||
env:
|
||||
@@ -87,6 +88,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: moby
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
-
|
||||
name: BuildKit ref
|
||||
run: |
|
||||
|
||||
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@@ -21,6 +21,7 @@ jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
strategy:
|
||||
@@ -53,7 +54,8 @@ jobs:
|
||||
find ${{ env.DESTDIR }} -type f -exec file -e ascii -- {} +
|
||||
|
||||
prepare-cross:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
outputs:
|
||||
@@ -75,6 +77,7 @@ jobs:
|
||||
|
||||
cross:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
- prepare-cross
|
||||
|
||||
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
@@ -13,7 +13,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.21.9"
|
||||
GO_VERSION: "1.22.10"
|
||||
GIT_PAGER: "cat"
|
||||
PAGER: "cat"
|
||||
|
||||
@@ -23,6 +23,7 @@ jobs:
|
||||
|
||||
build-dev:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
strategy:
|
||||
@@ -71,6 +72,7 @@ jobs:
|
||||
|
||||
validate-prepare:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
outputs:
|
||||
@@ -92,7 +94,7 @@ jobs:
|
||||
|
||||
validate:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120
|
||||
timeout-minutes: 30 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-prepare
|
||||
- build-dev
|
||||
@@ -126,6 +128,7 @@ jobs:
|
||||
|
||||
smoke-prepare:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- validate-dco
|
||||
outputs:
|
||||
@@ -147,6 +150,7 @@ jobs:
|
||||
|
||||
smoke:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
needs:
|
||||
- smoke-prepare
|
||||
strategy:
|
||||
|
||||
3
.github/workflows/validate-pr.yml
vendored
3
.github/workflows/validate-pr.yml
vendored
@@ -7,6 +7,7 @@ on:
|
||||
jobs:
|
||||
check-area-label:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
steps:
|
||||
- name: Missing `area/` label
|
||||
if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/')
|
||||
@@ -19,6 +20,7 @@ jobs:
|
||||
check-changelog:
|
||||
if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/')
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
env:
|
||||
PR_BODY: |
|
||||
${{ github.event.pull_request.body }}
|
||||
@@ -47,6 +49,7 @@ jobs:
|
||||
|
||||
check-pr-branch:
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
env:
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
steps:
|
||||
|
||||
@@ -38,13 +38,18 @@ linters-settings:
|
||||
alias:
|
||||
# Enforce alias to prevent it accidentally being used instead of our
|
||||
# own errdefs package (or vice-versa).
|
||||
- pkg: github.com/containerd/containerd/errdefs
|
||||
- pkg: github.com/containerd/errdefs
|
||||
alias: cerrdefs
|
||||
- pkg: github.com/opencontainers/image-spec/specs-go/v1
|
||||
alias: ocispec
|
||||
|
||||
govet:
|
||||
check-shadowing: false
|
||||
|
||||
gosec:
|
||||
excludes:
|
||||
- G115 # FIXME temporarily suppress 'G115: integer overflow conversion': it produces many hits, some of which may be false positives, and need to be looked at; see https://github.com/moby/moby/issues/48358
|
||||
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
@@ -57,6 +62,10 @@ linters-settings:
|
||||
desc: Use "gotest.tools/v3/assert" instead
|
||||
- pkg: "github.com/stretchr/testify/suite"
|
||||
desc: Do not use
|
||||
- pkg: github.com/containerd/containerd/errdefs
|
||||
desc: The errdefs package has moved to a separate module, https://github.com/containerd/errdefs
|
||||
- pkg: github.com/containerd/containerd/log
|
||||
desc: The logs package has moved to a separate module, https://github.com/containerd/log
|
||||
revive:
|
||||
rules:
|
||||
# FIXME make sure all packages have a description. Currently, there's many packages without.
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,9 +1,9 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
ARG GO_VERSION=1.21.9
|
||||
ARG GO_VERSION=1.22.10
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
|
||||
ARG XX_VERSION=1.4.0
|
||||
ARG XX_VERSION=1.6.1
|
||||
|
||||
ARG VPNKIT_VERSION=0.5.0
|
||||
|
||||
@@ -147,7 +147,7 @@ RUN git init . && git remote add origin "https://github.com/go-delve/delve.git"
|
||||
# from the https://github.com/go-delve/delve repository.
|
||||
# It can be used to run Docker with a possibility of
|
||||
# attaching debugger to it.
|
||||
ARG DELVE_VERSION=v1.21.1
|
||||
ARG DELVE_VERSION=v1.23.0
|
||||
RUN git fetch -q --depth 1 origin "${DELVE_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS delve-supported
|
||||
@@ -196,7 +196,7 @@ RUN git init . && git remote add origin "https://github.com/containerd/container
|
||||
# When updating the binary version you may also need to update the vendor
|
||||
# version to pick up bug fixes or new APIs, however, usually the Go packages
|
||||
# are built from a commit from the master branch.
|
||||
ARG CONTAINERD_VERSION=v1.7.15
|
||||
ARG CONTAINERD_VERSION=v1.7.18
|
||||
RUN git fetch -q --depth 1 origin "${CONTAINERD_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS containerd-build
|
||||
@@ -229,7 +229,7 @@ FROM binary-dummy AS containerd-windows
|
||||
FROM containerd-${TARGETOS} AS containerd
|
||||
|
||||
FROM base AS golangci_lint
|
||||
ARG GOLANGCI_LINT_VERSION=v1.55.2
|
||||
ARG GOLANGCI_LINT_VERSION=v1.60.2
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" \
|
||||
@@ -287,7 +287,7 @@ RUN git init . && git remote add origin "https://github.com/opencontainers/runc.
|
||||
# that is used. If you need to update runc, open a pull request in the containerd
|
||||
# project first, and update both after that is merged. When updating RUNC_VERSION,
|
||||
# consider updating runc in vendor.mod accordingly.
|
||||
ARG RUNC_VERSION=v1.1.12
|
||||
ARG RUNC_VERSION=v1.1.14
|
||||
RUN git fetch -q --depth 1 origin "${RUNC_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS runc-build
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# This represents the bare minimum required to build and test Docker.
|
||||
|
||||
ARG GO_VERSION=1.21.9
|
||||
ARG GO_VERSION=1.22.10
|
||||
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
|
||||
|
||||
@@ -161,10 +161,10 @@ FROM ${WINDOWS_BASE_IMAGE}:${WINDOWS_BASE_IMAGE_TAG}
|
||||
# Use PowerShell as the default shell
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
ARG GO_VERSION=1.21.9
|
||||
ARG GO_VERSION=1.22.10
|
||||
ARG GOTESTSUM_VERSION=v1.8.2
|
||||
ARG GOWINRES_VERSION=v0.3.1
|
||||
ARG CONTAINERD_VERSION=v1.7.15
|
||||
ARG CONTAINERD_VERSION=v1.7.18
|
||||
|
||||
# Environment variable notes:
|
||||
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
|
||||
|
||||
165
Jenkinsfile
vendored
165
Jenkinsfile
vendored
@@ -1,165 +0,0 @@
|
||||
#!groovy
|
||||
pipeline {
|
||||
agent none
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(daysToKeepStr: '30'))
|
||||
timeout(time: 2, unit: 'HOURS')
|
||||
timestamps()
|
||||
}
|
||||
parameters {
|
||||
booleanParam(name: 'arm64', defaultValue: true, description: 'ARM (arm64) Build/Test')
|
||||
booleanParam(name: 'dco', defaultValue: true, description: 'Run the DCO check')
|
||||
}
|
||||
environment {
|
||||
DOCKER_BUILDKIT = '1'
|
||||
DOCKER_EXPERIMENTAL = '1'
|
||||
DOCKER_GRAPHDRIVER = 'overlay2'
|
||||
CHECK_CONFIG_COMMIT = '33a3680e08d1007e72c3b3f1454f823d8e9948ee'
|
||||
TESTDEBUG = '0'
|
||||
TIMEOUT = '120m'
|
||||
}
|
||||
stages {
|
||||
stage('pr-hack') {
|
||||
when { changeRequest() }
|
||||
steps {
|
||||
script {
|
||||
echo "Workaround for PR auto-cancel feature. Borrowed from https://issues.jenkins-ci.org/browse/JENKINS-43353"
|
||||
def buildNumber = env.BUILD_NUMBER as int
|
||||
if (buildNumber > 1) milestone(buildNumber - 1)
|
||||
milestone(buildNumber)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('DCO-check') {
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { params.dco }
|
||||
}
|
||||
agent { label 'arm64 && ubuntu-2004' }
|
||||
steps {
|
||||
sh '''
|
||||
docker run --rm \
|
||||
-v "$WORKSPACE:/workspace" \
|
||||
-e VALIDATE_REPO=${GIT_URL} \
|
||||
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
|
||||
alpine sh -c 'apk add --no-cache -q bash git openssh-client && git config --system --add safe.directory /workspace && cd /workspace && hack/validate/dco'
|
||||
'''
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('arm64') {
|
||||
when {
|
||||
beforeAgent true
|
||||
expression { params.arm64 }
|
||||
}
|
||||
agent { label 'arm64 && ubuntu-2004' }
|
||||
environment {
|
||||
TEST_SKIP_INTEGRATION_CLI = '1'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Print info") {
|
||||
steps {
|
||||
sh 'docker version'
|
||||
sh 'docker info'
|
||||
sh '''
|
||||
echo "check-config.sh version: ${CHECK_CONFIG_COMMIT}"
|
||||
curl -fsSL -o ${WORKSPACE}/check-config.sh "https://raw.githubusercontent.com/moby/moby/${CHECK_CONFIG_COMMIT}/contrib/check-config.sh" \
|
||||
&& bash ${WORKSPACE}/check-config.sh || true
|
||||
'''
|
||||
}
|
||||
}
|
||||
stage("Build dev image") {
|
||||
steps {
|
||||
sh 'docker build --force-rm -t docker:${GIT_COMMIT} .'
|
||||
}
|
||||
}
|
||||
stage("Unit tests") {
|
||||
steps {
|
||||
sh '''
|
||||
sudo modprobe ip6table_filter
|
||||
'''
|
||||
sh '''
|
||||
docker run --rm -t --privileged \
|
||||
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
|
||||
--name docker-pr$BUILD_NUMBER \
|
||||
-e DOCKER_EXPERIMENTAL \
|
||||
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
|
||||
-e DOCKER_GRAPHDRIVER \
|
||||
-e VALIDATE_REPO=${GIT_URL} \
|
||||
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
|
||||
docker:${GIT_COMMIT} \
|
||||
hack/test/unit
|
||||
'''
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit testResults: 'bundles/junit-report*.xml', allowEmptyResults: true
|
||||
}
|
||||
}
|
||||
}
|
||||
stage("Integration tests") {
|
||||
environment { TEST_SKIP_INTEGRATION_CLI = '1' }
|
||||
steps {
|
||||
sh '''
|
||||
docker run --rm -t --privileged \
|
||||
-v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \
|
||||
--name docker-pr$BUILD_NUMBER \
|
||||
-e DOCKER_EXPERIMENTAL \
|
||||
-e DOCKER_GITCOMMIT=${GIT_COMMIT} \
|
||||
-e DOCKER_GRAPHDRIVER \
|
||||
-e TESTDEBUG \
|
||||
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
|
||||
-e TEST_SKIP_INTEGRATION_CLI \
|
||||
-e TIMEOUT \
|
||||
-e VALIDATE_REPO=${GIT_URL} \
|
||||
-e VALIDATE_BRANCH=${CHANGE_TARGET} \
|
||||
docker:${GIT_COMMIT} \
|
||||
hack/make.sh \
|
||||
dynbinary \
|
||||
test-integration
|
||||
'''
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
sh '''
|
||||
echo "Ensuring container killed."
|
||||
docker rm -vf docker-pr$BUILD_NUMBER || true
|
||||
'''
|
||||
|
||||
sh '''
|
||||
echo "Chowning /workspace to jenkins user"
|
||||
docker run --rm -v "$WORKSPACE:/workspace" busybox chown -R "$(id -u):$(id -g)" /workspace
|
||||
'''
|
||||
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') {
|
||||
sh '''
|
||||
bundleName=arm64-integration
|
||||
echo "Creating ${bundleName}-bundles.tar.gz"
|
||||
# exclude overlay2 directories
|
||||
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
|
||||
'''
|
||||
|
||||
archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make clean'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
"github.com/docker/docker/errdefs"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
@@ -16,7 +17,11 @@ import (
|
||||
|
||||
// WriteLogStream writes an encoded byte stream of log messages from the
|
||||
// messages channel, multiplexing them with a stdcopy.Writer if mux is true
|
||||
func WriteLogStream(_ context.Context, w io.Writer, msgs <-chan *backend.LogMessage, config *container.LogsOptions, mux bool) {
|
||||
func WriteLogStream(_ context.Context, w http.ResponseWriter, msgs <-chan *backend.LogMessage, config *container.LogsOptions, mux bool) {
|
||||
// See https://github.com/moby/moby/issues/47448
|
||||
// Trigger headers to be written immediately.
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
wf := ioutils.NewWriteFlusher(w)
|
||||
defer wf.Close()
|
||||
|
||||
|
||||
@@ -112,9 +112,18 @@ func (s *containerRouter) getContainersStats(ctx context.Context, w http.Respons
|
||||
}
|
||||
|
||||
return s.backend.ContainerStats(ctx, vars["name"], &backend.ContainerStatsConfig{
|
||||
Stream: stream,
|
||||
OneShot: oneShot,
|
||||
OutStream: w,
|
||||
Stream: stream,
|
||||
OneShot: oneShot,
|
||||
OutStream: func() io.Writer {
|
||||
// Assume that when this is called the request is OK.
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if !stream {
|
||||
return w
|
||||
}
|
||||
wf := ioutils.NewWriteFlusher(w)
|
||||
wf.Flush()
|
||||
return wf
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -788,9 +797,11 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
|
||||
if multiplexed && versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.42") {
|
||||
contentType = types.MediaTypeMultiplexedStream
|
||||
}
|
||||
fmt.Fprintf(conn, "HTTP/1.1 101 UPGRADED\r\nContent-Type: "+contentType+"\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")
|
||||
// FIXME(thaJeztah): we should not ignore errors here; see https://github.com/moby/moby/pull/48359#discussion_r1725562802
|
||||
fmt.Fprintf(conn, "HTTP/1.1 101 UPGRADED\r\nContent-Type: %v\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n", contentType)
|
||||
} else {
|
||||
fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||
// FIXME(thaJeztah): we should not ignore errors here; see https://github.com/moby/moby/pull/48359#discussion_r1725562802
|
||||
fmt.Fprint(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||
}
|
||||
|
||||
closer := func() error {
|
||||
|
||||
@@ -56,7 +56,7 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit
|
||||
if p := r.FormValue("platform"); p != "" {
|
||||
sp, err := platforms.Parse(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
platform = &sp
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit
|
||||
id, progressErr = ir.backend.ImportImage(ctx, tagRef, platform, comment, layerReader, r.Form["changes"])
|
||||
|
||||
if progressErr == nil {
|
||||
output.Write(streamformatter.FormatStatus("", id.String()))
|
||||
_, _ = output.Write(streamformatter.FormatStatus("", "%v", id.String()))
|
||||
}
|
||||
}
|
||||
if progressErr != nil {
|
||||
|
||||
@@ -224,14 +224,6 @@ func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter,
|
||||
adjustForAPIVersion(v, &service)
|
||||
}
|
||||
|
||||
version := httputils.VersionFromContext(ctx)
|
||||
if versions.LessThan(version, "1.44") {
|
||||
if service.TaskTemplate.ContainerSpec != nil && service.TaskTemplate.ContainerSpec.Healthcheck != nil {
|
||||
// StartInterval was added in API 1.44
|
||||
service.TaskTemplate.ContainerSpec.Healthcheck.StartInterval = 0
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := sr.backend.CreateService(service, encodedAuth, queryRegistry)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
|
||||
@@ -121,11 +121,17 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
||||
}
|
||||
|
||||
if versions.LessThan(cliVersion, "1.44") {
|
||||
// seccomp, apparmor, and no_new_privs were added in 1.44.
|
||||
if service.TaskTemplate.ContainerSpec != nil && service.TaskTemplate.ContainerSpec.Privileges != nil {
|
||||
service.TaskTemplate.ContainerSpec.Privileges.Seccomp = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.AppArmor = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.NoNewPrivileges = false
|
||||
if service.TaskTemplate.ContainerSpec != nil {
|
||||
// seccomp, apparmor, and no_new_privs were added in 1.44.
|
||||
if service.TaskTemplate.ContainerSpec.Privileges != nil {
|
||||
service.TaskTemplate.ContainerSpec.Privileges.Seccomp = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.AppArmor = nil
|
||||
service.TaskTemplate.ContainerSpec.Privileges.NoNewPrivileges = false
|
||||
}
|
||||
if service.TaskTemplate.ContainerSpec.Healthcheck != nil {
|
||||
// StartInterval was added in API 1.44
|
||||
service.TaskTemplate.ContainerSpec.Healthcheck.StartInterval = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +263,7 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
output := ioutils.NewWriteFlusher(w)
|
||||
defer output.Close()
|
||||
output.Flush()
|
||||
|
||||
240
api/swagger.yaml
240
api/swagger.yaml
@@ -1198,13 +1198,6 @@ definitions:
|
||||
ContainerConfig:
|
||||
description: |
|
||||
Configuration for a container that is portable between hosts.
|
||||
|
||||
When used as `ContainerConfig` field in an image, `ContainerConfig` is an
|
||||
optional field containing the configuration of the container that was last
|
||||
committed when creating the image.
|
||||
|
||||
Previous versions of Docker builder used this field to store build cache,
|
||||
and it is not in active use anymore.
|
||||
type: "object"
|
||||
properties:
|
||||
Hostname:
|
||||
@@ -1758,21 +1751,6 @@ definitions:
|
||||
format: "dateTime"
|
||||
x-nullable: true
|
||||
example: "2022-02-04T21:20:12.497794809Z"
|
||||
Container:
|
||||
description: |
|
||||
The ID of the container that was used to create the image.
|
||||
|
||||
Depending on how the image was created, this field may be empty.
|
||||
|
||||
**Deprecated**: this field is kept for backward compatibility, but
|
||||
will be removed in API v1.45.
|
||||
type: "string"
|
||||
example: "65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735"
|
||||
ContainerConfig:
|
||||
description: |
|
||||
**Deprecated**: this field is kept for backward compatibility, but
|
||||
will be removed in API v1.45.
|
||||
$ref: "#/definitions/ContainerConfig"
|
||||
DockerVersion:
|
||||
description: |
|
||||
The version of Docker that was used to build the image.
|
||||
@@ -2179,72 +2157,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2252,6 +2287,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2267,16 +2303,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2287,14 +2328,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -4942,7 +5004,7 @@ definitions:
|
||||
The version Go used to compile the daemon, and the version of the Go
|
||||
runtime in use.
|
||||
type: "string"
|
||||
example: "go1.13.14"
|
||||
example: "go1.22.7"
|
||||
Os:
|
||||
description: |
|
||||
The operating system that the daemon is running on ("linux" or "windows")
|
||||
@@ -10104,14 +10166,22 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Deprecated: CheckDuplicate is now always enabled.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -10120,55 +10190,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -89,7 +89,7 @@ type LogSelector struct {
|
||||
type ContainerStatsConfig struct {
|
||||
Stream bool
|
||||
OneShot bool
|
||||
OutStream io.Writer
|
||||
OutStream func() io.Writer
|
||||
}
|
||||
|
||||
// ExecInspect holds information about a running process started
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package container // import "github.com/docker/docker/api/types/container"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -325,12 +326,12 @@ func ValidateRestartPolicy(policy RestartPolicy) error {
|
||||
if policy.MaximumRetryCount < 0 {
|
||||
msg += " and cannot be negative"
|
||||
}
|
||||
return &errInvalidParameter{fmt.Errorf(msg)}
|
||||
return &errInvalidParameter{errors.New(msg)}
|
||||
}
|
||||
return nil
|
||||
case RestartPolicyOnFailure:
|
||||
if policy.MaximumRetryCount < 0 {
|
||||
return &errInvalidParameter{fmt.Errorf("invalid restart policy: maximum retry count cannot be negative")}
|
||||
return &errInvalidParameter{errors.New("invalid restart policy: maximum retry count cannot be negative")}
|
||||
}
|
||||
return nil
|
||||
case "":
|
||||
|
||||
@@ -457,24 +457,24 @@ type EndpointResource struct {
|
||||
type NetworkCreate struct {
|
||||
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client
|
||||
// package to older daemons.
|
||||
CheckDuplicate bool `json:",omitempty"`
|
||||
Driver string
|
||||
Scope string
|
||||
EnableIPv6 bool
|
||||
IPAM *network.IPAM
|
||||
Internal bool
|
||||
Attachable bool
|
||||
Ingress bool
|
||||
ConfigOnly bool
|
||||
ConfigFrom *network.ConfigReference
|
||||
Options map[string]string
|
||||
Labels map[string]string
|
||||
CheckDuplicate bool `json:",omitempty"`
|
||||
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
|
||||
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
|
||||
EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6.
|
||||
IPAM *network.IPAM // IPAM is the network's IP Address Management.
|
||||
Internal bool // Internal represents if the network is used internal only.
|
||||
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
|
||||
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
|
||||
ConfigOnly bool // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
|
||||
ConfigFrom *network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [NetworkCreate.ConfigOnly].
|
||||
Options map[string]string // Options specifies the network-specific options to use for when creating the network.
|
||||
Labels map[string]string // Labels holds metadata specific to the network being created.
|
||||
}
|
||||
|
||||
// NetworkCreateRequest is the request message sent to the server for network create call.
|
||||
type NetworkCreateRequest struct {
|
||||
NetworkCreate
|
||||
Name string
|
||||
Name string // Name is the requested name of the network.
|
||||
}
|
||||
|
||||
// NetworkCreateResponse is the response message sent by the server for network create call
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/gc"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
@@ -25,6 +24,7 @@ import (
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/containerd/containerd/remotes/docker/schema1" //nolint:staticcheck // Ignore SA1019: "github.com/containerd/containerd/remotes/docker/schema1" is deprecated: use images formatted in Docker Image Manifest v2, Schema 2, or OCI Image Spec v1.
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
distreference "github.com/distribution/reference"
|
||||
dimages "github.com/docker/docker/daemon/images"
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/docker/docker/builder/builder-next/exporter/overrides"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/daemon/images"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/libnetwork"
|
||||
"github.com/docker/docker/opts"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
@@ -326,7 +327,7 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.
|
||||
// TODO: remove once opt.Options.Platform is of type specs.Platform
|
||||
_, err := platforms.Parse(opt.Options.Platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.InvalidParameter(err)
|
||||
}
|
||||
frontendAttrs["platform"] = opt.Options.Platform
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ func patchImageConfig(dt []byte, dps []digest.Digest, history []ocispec.History,
|
||||
return nil, errors.Wrap(err, "failed to parse image config for patch")
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
return nil, errors.New("null image config")
|
||||
}
|
||||
|
||||
var rootFS ocispec.RootFS
|
||||
rootFS.Type = "layers"
|
||||
rootFS.DiffIDs = append(rootFS.DiffIDs, dps...)
|
||||
|
||||
42
builder/builder-next/exporter/mobyexporter/writer_test.go
Normal file
42
builder/builder-next/exporter/mobyexporter/writer_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package mobyexporter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestPatchImageConfig(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
cfgJSON string
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
cfgJSON: "{}",
|
||||
},
|
||||
{
|
||||
name: "history only",
|
||||
cfgJSON: `{"history": []}`,
|
||||
},
|
||||
{
|
||||
name: "rootfs only",
|
||||
cfgJSON: `{"rootfs": {}}`,
|
||||
},
|
||||
{
|
||||
name: "null",
|
||||
cfgJSON: "null",
|
||||
err: "null image config",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, err := patchImageConfig([]byte(tc.cfgJSON), nil, nil, nil)
|
||||
if tc.err == "" {
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ func newBuilder(ctx context.Context, options builderOptions) (*Builder, error) {
|
||||
if config.Platform != "" {
|
||||
sp, err := platforms.Parse(config.Platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.InvalidParameter(err)
|
||||
}
|
||||
b.platform = &sp
|
||||
}
|
||||
|
||||
@@ -166,17 +166,17 @@ func initializeStage(ctx context.Context, d dispatchRequest, cmd *instructions.S
|
||||
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse platform %s", v)
|
||||
return errors.Wrapf(errdefs.InvalidParameter(err), "failed to parse platform %s", v)
|
||||
}
|
||||
platform = &p
|
||||
}
|
||||
|
||||
image, err := d.getFromImage(ctx, d.shlex, cmd.BaseName, platform)
|
||||
img, err := d.getFromImage(ctx, d.shlex, cmd.BaseName, platform)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state := d.state
|
||||
if err := state.beginStage(cmd.Name, image); err != nil {
|
||||
if err := state.beginStage(cmd.Name, img); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(state.runConfig.OnBuild) > 0 {
|
||||
|
||||
@@ -27,25 +27,25 @@ func parseChownFlag(ctx context.Context, builder *Builder, state *dispatchState,
|
||||
|
||||
passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.Identity{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
|
||||
return idtools.Identity{}, errors.Wrap(err, "can't resolve /etc/passwd path in container rootfs")
|
||||
}
|
||||
groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
|
||||
if err != nil {
|
||||
return idtools.Identity{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
|
||||
return idtools.Identity{}, errors.Wrap(err, "can't resolve /etc/group path in container rootfs")
|
||||
}
|
||||
uid, err := lookupUser(userStr, passwdPath)
|
||||
if err != nil {
|
||||
return idtools.Identity{}, errors.Wrapf(err, "can't find uid for user "+userStr)
|
||||
return idtools.Identity{}, errors.Wrap(err, "can't find uid for user "+userStr)
|
||||
}
|
||||
gid, err := lookupGroup(grpStr, groupPath)
|
||||
if err != nil {
|
||||
return idtools.Identity{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
|
||||
return idtools.Identity{}, errors.Wrap(err, "can't find gid for group "+grpStr)
|
||||
}
|
||||
|
||||
// convert as necessary because of user namespaces
|
||||
chownPair, err := identityMapping.ToHost(idtools.Identity{UID: uid, GID: gid})
|
||||
if err != nil {
|
||||
return idtools.Identity{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
|
||||
return idtools.Identity{}, errors.Wrap(err, "unable to convert uid/gid to host mapping")
|
||||
}
|
||||
return chownPair, nil
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"golang.org/x/sys/windows"
|
||||
@@ -62,7 +63,7 @@ func lookupNTAccount(ctx context.Context, builder *Builder, accountName string,
|
||||
|
||||
optionsPlatform, err := platforms.Parse(builder.options.Platform)
|
||||
if err != nil {
|
||||
return idtools.Identity{}, err
|
||||
return idtools.Identity{}, errdefs.InvalidParameter(err)
|
||||
}
|
||||
|
||||
runConfig := copyRunConfig(state.runConfig,
|
||||
|
||||
@@ -44,8 +44,8 @@ func downloadRemote(remoteURL string) (string, io.ReadCloser, error) {
|
||||
// GetWithStatusError does an http.Get() and returns an error if the
|
||||
// status code is 4xx or 5xx.
|
||||
func GetWithStatusError(address string) (resp *http.Response, err error) {
|
||||
// #nosec G107
|
||||
if resp, err = http.Get(address); err != nil {
|
||||
resp, err = http.Get(address) // #nosec G107 -- ignore G107: Potential HTTP request made with variable url
|
||||
if err != nil {
|
||||
if uerr, ok := err.(*url.Error); ok {
|
||||
if derr, ok := uerr.Err.(*net.DNSError); ok && !derr.IsTimeout {
|
||||
return nil, errdefs.NotFound(err)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/spf13/pflag"
|
||||
"go.opentelemetry.io/otel"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/fs"
|
||||
@@ -284,3 +286,29 @@ func TestCDISpecDirs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestOtelMeterLeak tests for a memory leak in the OTEL meter implementation.
|
||||
// Once the fixed OTEL is vendored, this test will fail - the workaround
|
||||
// and this test should be removed then.
|
||||
func TestOtelMeterLeak(t *testing.T) {
|
||||
meter := otel.Meter("foo")
|
||||
|
||||
var before runtime.MemStats
|
||||
runtime.ReadMemStats(&before)
|
||||
|
||||
const counters = 10 * 1000 * 1000
|
||||
for i := 0; i < counters; i++ {
|
||||
_, _ = meter.Int64Counter("bar")
|
||||
}
|
||||
|
||||
var after runtime.MemStats
|
||||
runtime.ReadMemStats(&after)
|
||||
|
||||
allocs := after.Mallocs - before.Mallocs
|
||||
t.Log("Allocations:", allocs)
|
||||
|
||||
if allocs < 10 {
|
||||
// TODO: Remove Workaround OTEL memory leak in cmd/dockerd/daemon.go
|
||||
t.Fatal("Allocations count decreased. OTEL leak workaround is no longer needed!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ import (
|
||||
"github.com/moby/buildkit/util/apicaps"
|
||||
"github.com/moby/term"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/metric/noop"
|
||||
)
|
||||
|
||||
var honorXDG bool
|
||||
@@ -82,6 +85,12 @@ func main() {
|
||||
// Fixes https://github.com/docker/docker/issues/19728
|
||||
signal.Ignore(syscall.SIGPIPE)
|
||||
|
||||
// Workaround OTEL memory leak
|
||||
// See: https://github.com/open-telemetry/opentelemetry-go-contrib/issues/5190
|
||||
// The need for this workaround is checked by the TestOtelMeterLeak test
|
||||
// TODO: Remove this workaround after upgrading to v1.30.0
|
||||
otel.SetMeterProvider(noop.MeterProvider{})
|
||||
|
||||
// Set terminal emulation based on platform as required.
|
||||
_, stdout, stderr := term.StdStreams()
|
||||
onError := func(err error) {
|
||||
|
||||
@@ -14,7 +14,7 @@ func NoArgs(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if cmd.HasSubCommands() {
|
||||
return errors.Errorf("\n" + strings.TrimRight(cmd.UsageString(), "\n"))
|
||||
return errors.New("\n" + strings.TrimRight(cmd.UsageString(), "\n"))
|
||||
}
|
||||
|
||||
return errors.Errorf(
|
||||
|
||||
@@ -2,6 +2,7 @@ package stream // import "github.com/docker/docker/container/stream"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
@@ -91,24 +92,24 @@ func (c *Config) NewNopInputPipe() {
|
||||
|
||||
// CloseStreams ensures that the configured streams are properly closed.
|
||||
func (c *Config) CloseStreams() error {
|
||||
var errors []string
|
||||
var errs []string
|
||||
|
||||
if c.stdin != nil {
|
||||
if err := c.stdin.Close(); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("error close stdin: %s", err))
|
||||
errs = append(errs, fmt.Sprintf("error close stdin: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.stdout.Clean(); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("error close stdout: %s", err))
|
||||
errs = append(errs, fmt.Sprintf("error close stdout: %s", err))
|
||||
}
|
||||
|
||||
if err := c.stderr.Clean(); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("error close stderr: %s", err))
|
||||
errs = append(errs, fmt.Sprintf("error close stderr: %s", err))
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return fmt.Errorf(strings.Join(errors, "\n"))
|
||||
if len(errs) > 0 {
|
||||
return errors.New(strings.Join(errs, "\n"))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -54,6 +54,30 @@ if ! [ -d "$HOME" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mount_directory() {
|
||||
if [ -z "$_DOCKERD_ROOTLESS_CHILD" ]; then
|
||||
echo "mount_directory should be called from the child context. Otherwise data loss is at risk" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY="$1"
|
||||
if [ ! -d "$DIRECTORY" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Bind mount directory: this makes this directory visible to
|
||||
# Dockerd, even if it is originally a symlink, given Dockerd does
|
||||
# not always follow symlinks. Some directories might also be
|
||||
# "copied-up", meaning that they will also be writable on the child
|
||||
# namespace; this will be the case only if they are provided as
|
||||
# --copy-up to the rootlesskit.
|
||||
DIRECTORY_REALPATH=$(realpath "$DIRECTORY")
|
||||
MOUNT_OPTIONS="${2:---bind}"
|
||||
rm -rf "$DIRECTORY"
|
||||
mkdir -p "$DIRECTORY"
|
||||
mount $MOUNT_OPTIONS "$DIRECTORY_REALPATH" "$DIRECTORY"
|
||||
}
|
||||
|
||||
rootlesskit=""
|
||||
for f in docker-rootlesskit rootlesskit; do
|
||||
if command -v $f > /dev/null 2>&1; then
|
||||
@@ -139,6 +163,25 @@ if [ -z "$_DOCKERD_ROOTLESS_CHILD" ]; then
|
||||
"$0" "$@"
|
||||
else
|
||||
[ "$_DOCKERD_ROOTLESS_CHILD" = 1 ]
|
||||
|
||||
# The Container Device Interface (CDI) specs can be found by default
|
||||
# under {/etc,/var/run}/cdi. More information at:
|
||||
# https://github.com/cncf-tags/container-device-interface
|
||||
#
|
||||
# In order to use the Container Device Interface (CDI) integration,
|
||||
# the CDI paths need to exist before the Docker daemon is started in
|
||||
# order for it to read the CDI specification files. Otherwise, a
|
||||
# Docker daemon restart will be required for the daemon to discover
|
||||
# them.
|
||||
#
|
||||
# If another set of CDI paths (other than the default /etc/cdi and
|
||||
# /var/run/cdi) are configured through the Docker configuration file
|
||||
# (using "cdi-spec-dirs"), they need to be bind mounted in rootless
|
||||
# mode; otherwise the Docker daemon won't have access to the CDI
|
||||
# specification files.
|
||||
mount_directory /etc/cdi
|
||||
mount_directory /var/run/cdi
|
||||
|
||||
# remove the symlinks for the existing files in the parent namespace if any,
|
||||
# so that we can create our own files in our mount namespace.
|
||||
rm -f /run/docker /run/containerd /run/xtables.lock
|
||||
@@ -153,10 +196,7 @@ else
|
||||
if [ "$(stat -c %T -f /etc)" = "tmpfs" ] && [ -L "/etc/ssl" ]; then
|
||||
# Workaround for "x509: certificate signed by unknown authority" on openSUSE Tumbleweed.
|
||||
# https://github.com/rootless-containers/rootlesskit/issues/225
|
||||
realpath_etc_ssl=$(realpath /etc/ssl)
|
||||
rm -f /etc/ssl
|
||||
mkdir /etc/ssl
|
||||
mount --rbind ${realpath_etc_ssl} /etc/ssl
|
||||
mount_directory /etc/ssl "--rbind"
|
||||
fi
|
||||
|
||||
exec "$dockerd" "$@"
|
||||
|
||||
@@ -282,6 +282,19 @@ func (n *nodeRunner) handleNodeExit(node *swarmnode.Node) {
|
||||
close(n.done)
|
||||
select {
|
||||
case <-n.ready:
|
||||
// there is a case where a node can be promoted to manager while
|
||||
// another node is leaving the cluster. the node being promoted, by
|
||||
// random chance, picks the IP of the node being demoted as the one it
|
||||
// tries to connect to. in this case, the promotion will fail, and the
|
||||
// whole swarm Node object packs it in.
|
||||
//
|
||||
// when the Node object is relaunched by this code, because it has
|
||||
// joinAddr in the config, it attempts again to connect to the same
|
||||
// no-longer-manager node, and crashes again. this continues forever.
|
||||
//
|
||||
// to avoid this case, in this block, we remove JoinAddr from the
|
||||
// config.
|
||||
n.config.joinAddr = ""
|
||||
n.enableReconnectWatcher()
|
||||
default:
|
||||
if n.repeatedRun {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
||||
@@ -13,12 +13,12 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
||||
@@ -12,11 +12,11 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/diff"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/pkg/cleanup"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/image"
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/images/archive"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/labels"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
cplatforms "github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types"
|
||||
|
||||
@@ -9,11 +9,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/pkg/snapshotters"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
containerdlabels "github.com/containerd/containerd/labels"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
@@ -69,7 +69,9 @@ func (i *ImageService) TagImage(ctx context.Context, imageID image.ID, newTag re
|
||||
|
||||
// Delete the source dangling image, as it's no longer dangling.
|
||||
if err := i.images.Delete(compatcontext.WithoutCancel(ctx), danglingImageName(targetImage.Target.Digest)); err != nil {
|
||||
logger.WithError(err).Warn("unexpected error when deleting dangling image")
|
||||
if !cerrdefs.IsNotFound(err) {
|
||||
logger.WithError(err).Warn("unexpected error when deleting dangling image")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/internal/compatcontext"
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/containerd/containerd/version"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
registrytypes "github.com/docker/docker/api/types/registry"
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/container"
|
||||
|
||||
@@ -3,8 +3,8 @@ package containerd
|
||||
import (
|
||||
"context"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/compatcontext"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
containerdlabels "github.com/containerd/containerd/labels"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
@@ -918,7 +918,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||
|
||||
// ensureDefaultAppArmorProfile does nothing if apparmor is disabled
|
||||
if err := ensureDefaultAppArmorProfile(); err != nil {
|
||||
log.G(ctx).Errorf(err.Error())
|
||||
log.G(ctx).WithError(err).Error("Failed to ensure default apparmor profile is loaded")
|
||||
}
|
||||
|
||||
daemonRepo := filepath.Join(cfgStore.Root, "containers")
|
||||
|
||||
@@ -849,6 +849,10 @@ func (daemon *Daemon) initNetworkController(cfg *config.Config, activeSandboxes
|
||||
return err
|
||||
}
|
||||
|
||||
if err := daemon.netController.SetupUserChains(); err != nil {
|
||||
log.G(context.TODO()).WithError(err).Warnf("initNetworkController")
|
||||
}
|
||||
|
||||
// Set HostGatewayIP to the default bridge's IP if it is empty
|
||||
setHostGatewayIP(daemon.netController, cfg)
|
||||
return nil
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/leases"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
|
||||
@@ -33,6 +33,10 @@ const (
|
||||
// the container unstable. Defaults to none.
|
||||
defaultStartPeriod = 0 * time.Second
|
||||
|
||||
// defaultStartInterval is the default interval between health checks during
|
||||
// the start period.
|
||||
defaultStartInterval = 5 * time.Second
|
||||
|
||||
// Default number of consecutive failures of the health check
|
||||
// for the container to be considered unhealthy.
|
||||
defaultProbeRetries = 3
|
||||
@@ -251,7 +255,7 @@ func handleProbeResult(d *Daemon, c *container.Container, result *types.Healthch
|
||||
// There is never more than one monitor thread running per container at a time.
|
||||
func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) {
|
||||
probeInterval := timeoutWithDefault(c.Config.Healthcheck.Interval, defaultProbeInterval)
|
||||
startInterval := timeoutWithDefault(c.Config.Healthcheck.StartInterval, probeInterval)
|
||||
startInterval := timeoutWithDefault(c.Config.Healthcheck.StartInterval, defaultStartInterval)
|
||||
startPeriod := timeoutWithDefault(c.Config.Healthcheck.StartPeriod, defaultStartPeriod)
|
||||
|
||||
c.Lock()
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/distribution"
|
||||
"github.com/docker/docker/image"
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/content/local"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/metadata"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
@@ -825,15 +825,11 @@ func withCgroups(daemon *Daemon, daemonCfg *dconfig.Config, c *container.Contain
|
||||
|
||||
p := cgroupsPath
|
||||
if useSystemd {
|
||||
initPath, err := cgroups.GetInitCgroup("cpu")
|
||||
path, err := cgroups.GetOwnCgroup("cpu")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to init CPU RT controller")
|
||||
}
|
||||
_, err = cgroups.GetOwnCgroup("cpu")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to init CPU RT controller")
|
||||
}
|
||||
p = filepath.Join(initPath, s.Linux.CgroupsPath)
|
||||
p = filepath.Join(path, s.Linux.CgroupsPath)
|
||||
}
|
||||
|
||||
// Clean path to guard against things like ../../../BAD
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
)
|
||||
|
||||
// ContainerStats writes information about the container to the stream
|
||||
@@ -27,9 +26,11 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
|
||||
return errdefs.InvalidParameter(errors.New("cannot have stream=true and one-shot=true"))
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(config.OutStream())
|
||||
|
||||
// If the container is either not running or restarting and requires no stream, return an empty stats.
|
||||
if (!ctr.IsRunning() || ctr.IsRestarting()) && !config.Stream {
|
||||
return json.NewEncoder(config.OutStream).Encode(&types.StatsJSON{
|
||||
return enc.Encode(&types.StatsJSON{
|
||||
Name: ctr.Name,
|
||||
ID: ctr.ID,
|
||||
})
|
||||
@@ -41,15 +42,7 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.NewEncoder(config.OutStream).Encode(stats)
|
||||
}
|
||||
|
||||
outStream := config.OutStream
|
||||
if config.Stream {
|
||||
wf := ioutils.NewWriteFlusher(outStream)
|
||||
defer wf.Close()
|
||||
wf.Flush()
|
||||
outStream = wf
|
||||
return enc.Encode(stats)
|
||||
}
|
||||
|
||||
var preCPUStats types.CPUStats
|
||||
@@ -65,12 +58,11 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
|
||||
return &ss
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(outStream)
|
||||
|
||||
updates := daemon.subscribeToContainerStats(ctr)
|
||||
defer daemon.unsubscribeToContainerStats(ctr, updates)
|
||||
|
||||
noStreamFirstFrame := !config.OneShot
|
||||
|
||||
for {
|
||||
select {
|
||||
case v, ok := <-updates:
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/distribution"
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/content/local"
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
|
||||
@@ -2105,72 +2105,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2178,6 +2235,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2193,16 +2251,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2213,14 +2276,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -9536,6 +9620,7 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Check for networks with duplicate names. Since Network is
|
||||
@@ -9546,10 +9631,17 @@ paths:
|
||||
a best effort checking of any networks which has the same name
|
||||
but it is not guaranteed to catch all name collisions.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -9558,55 +9650,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -2113,72 +2113,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2186,6 +2243,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2201,16 +2259,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2221,14 +2284,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -6528,7 +6612,7 @@ paths:
|
||||
StopSignal: "SIGTERM"
|
||||
StopTimeout: 10
|
||||
Created: "2015-01-06T15:47:31.485331387Z"
|
||||
Driver: "devicemapper"
|
||||
Driver: "overlay2"
|
||||
ExecIDs:
|
||||
- "b35395de42bc8abd327f9dd65d913b9ba28c74d2f0734eeeae84fa1c616a0fca"
|
||||
- "3fc1232e5cd20c8de182ed81178503dc6437f4e7ef12b52cc5e8de020652f1c4"
|
||||
@@ -9914,6 +9998,7 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Check for networks with duplicate names. Since Network is
|
||||
@@ -9924,10 +10009,17 @@ paths:
|
||||
a best effort checking of any networks which has the same name
|
||||
but it is not guaranteed to catch all name collisions.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -9936,55 +10028,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -2144,72 +2144,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2217,6 +2274,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2232,16 +2290,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2252,14 +2315,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -6561,7 +6645,7 @@ paths:
|
||||
StopSignal: "SIGTERM"
|
||||
StopTimeout: 10
|
||||
Created: "2015-01-06T15:47:31.485331387Z"
|
||||
Driver: "devicemapper"
|
||||
Driver: "overlay2"
|
||||
ExecIDs:
|
||||
- "b35395de42bc8abd327f9dd65d913b9ba28c74d2f0734eeeae84fa1c616a0fca"
|
||||
- "3fc1232e5cd20c8de182ed81178503dc6437f4e7ef12b52cc5e8de020652f1c4"
|
||||
@@ -9932,6 +10016,7 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Check for networks with duplicate names. Since Network is
|
||||
@@ -9942,10 +10027,17 @@ paths:
|
||||
a best effort checking of any networks which has the same name
|
||||
but it is not guaranteed to catch all name collisions.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -9954,55 +10046,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -2171,72 +2171,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2244,6 +2301,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2259,16 +2317,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2279,14 +2342,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -10102,14 +10186,22 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Deprecated: CheckDuplicate is now always enabled.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -10118,55 +10210,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -1198,13 +1198,6 @@ definitions:
|
||||
ContainerConfig:
|
||||
description: |
|
||||
Configuration for a container that is portable between hosts.
|
||||
|
||||
When used as `ContainerConfig` field in an image, `ContainerConfig` is an
|
||||
optional field containing the configuration of the container that was last
|
||||
committed when creating the image.
|
||||
|
||||
Previous versions of Docker builder used this field to store build cache,
|
||||
and it is not in active use anymore.
|
||||
type: "object"
|
||||
properties:
|
||||
Hostname:
|
||||
@@ -1758,21 +1751,6 @@ definitions:
|
||||
format: "dateTime"
|
||||
x-nullable: true
|
||||
example: "2022-02-04T21:20:12.497794809Z"
|
||||
Container:
|
||||
description: |
|
||||
The ID of the container that was used to create the image.
|
||||
|
||||
Depending on how the image was created, this field may be empty.
|
||||
|
||||
**Deprecated**: this field is kept for backward compatibility, but
|
||||
will be removed in API v1.45.
|
||||
type: "string"
|
||||
example: "65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735"
|
||||
ContainerConfig:
|
||||
description: |
|
||||
**Deprecated**: this field is kept for backward compatibility, but
|
||||
will be removed in API v1.45.
|
||||
$ref: "#/definitions/ContainerConfig"
|
||||
DockerVersion:
|
||||
description: |
|
||||
The version of Docker that was used to build the image.
|
||||
@@ -2179,72 +2157,129 @@ definitions:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: |
|
||||
Name of the network.
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
Id:
|
||||
description: |
|
||||
ID that uniquely identifies a network on a single machine.
|
||||
type: "string"
|
||||
example: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created:
|
||||
description: |
|
||||
Date and time at which the network was created in
|
||||
[RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
|
||||
type: "string"
|
||||
format: "dateTime"
|
||||
example: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level)
|
||||
type: "string"
|
||||
example: "local"
|
||||
Driver:
|
||||
description: |
|
||||
The name of the driver used to create the network (e.g. `bridge`,
|
||||
`overlay`).
|
||||
type: "string"
|
||||
example: "overlay"
|
||||
EnableIPv6:
|
||||
description: |
|
||||
Whether the network was created with IPv6 enabled.
|
||||
type: "boolean"
|
||||
example: false
|
||||
IPAM:
|
||||
$ref: "#/definitions/IPAM"
|
||||
Internal:
|
||||
description: |
|
||||
Whether the network is created to only allow internal networking
|
||||
connectivity.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Attachable:
|
||||
description: |
|
||||
Wheter a global / swarm scope network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
Ingress:
|
||||
description: |
|
||||
Whether the network is providing the routing-mesh for the swarm cluster.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Whether the network is a config-only network. Config-only networks are
|
||||
placeholder networks for network configurations to be used by other
|
||||
networks. Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
Containers:
|
||||
description: |
|
||||
Contains endpoints attached to the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
$ref: "#/definitions/NetworkContainer"
|
||||
example:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
description: |
|
||||
Network-specific options uses when creating the network.
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "net01"
|
||||
Id: "7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99"
|
||||
Created: "2016-10-19T04:33:30.360899459Z"
|
||||
Scope: "local"
|
||||
Driver: "bridge"
|
||||
EnableIPv6: false
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.19.0.0/16"
|
||||
Gateway: "172.19.0.1"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: false
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Containers:
|
||||
19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:
|
||||
Name: "test"
|
||||
EndpointID: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress: "02:42:ac:13:00:02"
|
||||
IPv4Address: "172.19.0.2/16"
|
||||
IPv6Address: ""
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
Peers:
|
||||
description: |
|
||||
List of peer nodes for an overlay network. This field is only present
|
||||
for overlay networks, and omitted for other network types.
|
||||
type: "array"
|
||||
items:
|
||||
$ref: "#/definitions/PeerInfo"
|
||||
x-nullable: true
|
||||
# TODO: Add Services (only present when "verbose" is set).
|
||||
|
||||
ConfigReference:
|
||||
description: |
|
||||
The config-only network source to provide the configuration for
|
||||
this network.
|
||||
type: "object"
|
||||
properties:
|
||||
Network:
|
||||
description: |
|
||||
The name of the config-only network that provides the network's
|
||||
configuration. The specified network must be an existing config-only
|
||||
network. Only network names are allowed, not network IDs.
|
||||
type: "string"
|
||||
example: "config_only_network_01"
|
||||
|
||||
IPAM:
|
||||
type: "object"
|
||||
properties:
|
||||
@@ -2252,6 +2287,7 @@ definitions:
|
||||
description: "Name of the IPAM driver to use."
|
||||
type: "string"
|
||||
default: "default"
|
||||
example: "default"
|
||||
Config:
|
||||
description: |
|
||||
List of IPAM configuration options, specified as a map:
|
||||
@@ -2267,16 +2303,21 @@ definitions:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
foo: "bar"
|
||||
|
||||
IPAMConfig:
|
||||
type: "object"
|
||||
properties:
|
||||
Subnet:
|
||||
type: "string"
|
||||
example: "172.20.0.0/16"
|
||||
IPRange:
|
||||
type: "string"
|
||||
example: "172.20.10.0/24"
|
||||
Gateway:
|
||||
type: "string"
|
||||
example: "172.20.10.11"
|
||||
AuxiliaryAddresses:
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
@@ -2287,14 +2328,35 @@ definitions:
|
||||
properties:
|
||||
Name:
|
||||
type: "string"
|
||||
example: "container_1"
|
||||
EndpointID:
|
||||
type: "string"
|
||||
example: "628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a"
|
||||
MacAddress:
|
||||
type: "string"
|
||||
example: "02:42:ac:13:00:02"
|
||||
IPv4Address:
|
||||
type: "string"
|
||||
example: "172.19.0.2/16"
|
||||
IPv6Address:
|
||||
type: "string"
|
||||
example: ""
|
||||
|
||||
PeerInfo:
|
||||
description: |
|
||||
PeerInfo represents one peer of an overlay network.
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description:
|
||||
ID of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "6869d7c1732b"
|
||||
IP:
|
||||
description:
|
||||
IP-address of the peer-node in the Swarm cluster.
|
||||
type: "string"
|
||||
example: "10.133.77.91"
|
||||
|
||||
BuildInfo:
|
||||
type: "object"
|
||||
@@ -10104,14 +10166,22 @@ paths:
|
||||
Name:
|
||||
description: "The network's name."
|
||||
type: "string"
|
||||
example: "my_network"
|
||||
CheckDuplicate:
|
||||
description: |
|
||||
Deprecated: CheckDuplicate is now always enabled.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Driver:
|
||||
description: "Name of the network driver plugin to use."
|
||||
type: "string"
|
||||
default: "bridge"
|
||||
example: "bridge"
|
||||
Scope:
|
||||
description: |
|
||||
The level at which the network exists (e.g. `swarm` for cluster-wide
|
||||
or `local` for machine level).
|
||||
type: "string"
|
||||
Internal:
|
||||
description: "Restrict external access to the network."
|
||||
type: "boolean"
|
||||
@@ -10120,55 +10190,55 @@ paths:
|
||||
Globally scoped network is manually attachable by regular
|
||||
containers from workers in swarm mode.
|
||||
type: "boolean"
|
||||
example: true
|
||||
Ingress:
|
||||
description: |
|
||||
Ingress network is the network which provides the routing-mesh
|
||||
in swarm mode.
|
||||
type: "boolean"
|
||||
example: false
|
||||
ConfigOnly:
|
||||
description: |
|
||||
Creates a config-only network. Config-only networks are placeholder
|
||||
networks for network configurations to be used by other networks.
|
||||
Config-only networks cannot be used directly to run containers
|
||||
or services.
|
||||
type: "boolean"
|
||||
default: false
|
||||
example: false
|
||||
ConfigFrom:
|
||||
description: |
|
||||
Specifies the source which will provide the configuration for
|
||||
this network. The specified network must be an existing
|
||||
config-only network; see ConfigOnly.
|
||||
$ref: "#/definitions/ConfigReference"
|
||||
IPAM:
|
||||
description: "Optional custom IP scheme for the network."
|
||||
$ref: "#/definitions/IPAM"
|
||||
EnableIPv6:
|
||||
description: "Enable IPv6 on the network."
|
||||
type: "boolean"
|
||||
example: true
|
||||
Options:
|
||||
description: "Network specific options to be used by the drivers."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
description: "User-defined key/value metadata."
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
example:
|
||||
Name: "isolated_nw"
|
||||
CheckDuplicate: false
|
||||
Driver: "bridge"
|
||||
EnableIPv6: true
|
||||
IPAM:
|
||||
Driver: "default"
|
||||
Config:
|
||||
- Subnet: "172.20.0.0/16"
|
||||
IPRange: "172.20.10.0/24"
|
||||
Gateway: "172.20.10.11"
|
||||
- Subnet: "2001:db8:abcd::/64"
|
||||
Gateway: "2001:db8:abcd::1011"
|
||||
Options:
|
||||
foo: "bar"
|
||||
Internal: true
|
||||
Attachable: false
|
||||
Ingress: false
|
||||
Options:
|
||||
com.docker.network.bridge.default_bridge: "true"
|
||||
com.docker.network.bridge.enable_icc: "true"
|
||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
||||
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
|
||||
com.docker.network.bridge.name: "docker0"
|
||||
com.docker.network.driver.mtu: "1500"
|
||||
Labels:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
example:
|
||||
com.example.some-label: "some-value"
|
||||
com.example.some-other-label: "some-other-value"
|
||||
tags: ["Network"]
|
||||
|
||||
/networks/{id}/connect:
|
||||
|
||||
@@ -15,7 +15,7 @@ set -e
|
||||
# the binary version you may also need to update the vendor version to pick up
|
||||
# bug fixes or new APIs, however, usually the Go packages are built from a
|
||||
# commit from the master branch.
|
||||
: "${CONTAINERD_VERSION:=v1.7.15}"
|
||||
: "${CONTAINERD_VERSION:=v1.7.18}"
|
||||
|
||||
install_containerd() (
|
||||
echo "Install containerd version $CONTAINERD_VERSION"
|
||||
|
||||
@@ -9,7 +9,7 @@ set -e
|
||||
# the containerd project first, and update both after that is merged.
|
||||
#
|
||||
# When updating RUNC_VERSION, consider updating runc in vendor.mod accordingly
|
||||
: "${RUNC_VERSION:=v1.1.12}"
|
||||
: "${RUNC_VERSION:=v1.1.14}"
|
||||
|
||||
install_runc() {
|
||||
RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp"}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.21.9
|
||||
ARG GO_VERSION=1.22.10
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
ARG PROTOC_VERSION=3.11.4
|
||||
|
||||
|
||||
@@ -78,6 +78,18 @@ source "${MAKEDIR}/.go-autogen"
|
||||
GCFLAGS="all=-N -l"
|
||||
fi
|
||||
|
||||
if [ "$(go env GOARCH)" = "arm" ] && [ "$(go env GOARM)" = "5" ]; then
|
||||
# cross-compiling for arm/v5 fails on go1.22; a fix is included for this
|
||||
# in go1.23 (https://github.com/golang/go/issues/65290), but for go1.22
|
||||
# we can set the correct option manually.
|
||||
CGO_CFLAGS+=" -Wno-atomic-alignment"
|
||||
export CGO_CFLAGS
|
||||
|
||||
# Make sure libatomic is included on arm/v5, because clang does not auto-link it.
|
||||
# see https://github.com/moby/moby/pull/46982#issuecomment-2206992611
|
||||
export CGO_LDFLAGS="-latomic"
|
||||
fi
|
||||
|
||||
echo "Building $([ "$DOCKER_STATIC" = "1" ] && echo "static" || echo "dynamic") $DEST/$BINARY_FULLNAME ($PLATFORM_NAME)..."
|
||||
if [ -n "$DOCKER_DEBUG" ]; then
|
||||
set -x
|
||||
|
||||
@@ -4,7 +4,8 @@ set -e
|
||||
source hack/make/.integration-test-helpers
|
||||
|
||||
# The commit or tag to use for testing
|
||||
: "${DOCKER_PY_COMMIT:=7.0.0}"
|
||||
# TODO(thaJeztah): remove VERSION build-arg once https://github.com/docker/docker-py/pull/3267 is merged and released.
|
||||
: "${DOCKER_PY_COMMIT:=7.1.0}"
|
||||
|
||||
# custom options to pass py.test
|
||||
#
|
||||
@@ -55,8 +56,9 @@ PY_TEST_OPTIONS="$PY_TEST_OPTIONS --deselect=tests/integration/api_image_test.py
|
||||
[ -n "${TESTDEBUG}" ] && set -x
|
||||
[ -z "${TESTDEBUG}" ] && build_opts="--quiet"
|
||||
[ -f /.dockerenv ] || build_opts="${build_opts} --network=host"
|
||||
# TODO(thaJeztah): remove VERSION build-arg once https://github.com/docker/docker-py/pull/3267 is merged and released.
|
||||
# shellcheck disable=SC2086
|
||||
exec docker build ${build_opts} -t "${docker_py_image}" -f tests/Dockerfile "https://github.com/docker/docker-py.git#${DOCKER_PY_COMMIT}"
|
||||
exec docker build ${build_opts} -t "${docker_py_image}" --build-arg VERSION="${DOCKER_PY_COMMIT}" -f tests/Dockerfile "https://github.com/docker/docker-py.git#${DOCKER_PY_COMMIT}"
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -46,7 +46,7 @@ func (s *DockerBenchmarkSuite) BenchmarkConcurrentContainerActions(c *testing.B)
|
||||
args = append(args, sleepCommandForDaemonPlatform()...)
|
||||
out, _, err := dockerCmdWithError(args...)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -59,29 +59,29 @@ func (s *DockerBenchmarkSuite) BenchmarkConcurrentContainerActions(c *testing.B)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
out, _, err = dockerCmdWithError("cp", id+":/tmp", tmpDir)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
return
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("kill", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("start", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
}
|
||||
|
||||
out, _, err = dockerCmdWithError("kill", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
}
|
||||
|
||||
// don't do an rm -f here since it can potentially ignore errors from the graphdriver
|
||||
out, _, err = dockerCmdWithError("rm", id)
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -91,7 +91,7 @@ func (s *DockerBenchmarkSuite) BenchmarkConcurrentContainerActions(c *testing.B)
|
||||
for i := 0; i < numIterations; i++ {
|
||||
out, _, err := dockerCmdWithError("ps")
|
||||
if err != nil {
|
||||
chErr <- fmt.Errorf(out)
|
||||
chErr <- errors.New(out)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -116,7 +116,7 @@ func (s *DockerBenchmarkSuite) BenchmarkLogsCLIRotateFollow(c *testing.B) {
|
||||
ch <- nil
|
||||
out, _, _ := dockerCmdWithError("logs", "-f", id)
|
||||
// if this returns at all, it's an error
|
||||
ch <- fmt.Errorf(out)
|
||||
ch <- errors.New(out)
|
||||
}()
|
||||
|
||||
<-ch
|
||||
|
||||
@@ -59,16 +59,18 @@ func (s *DockerNetworkSuite) SetUpSuite(ctx context.Context, c *testing.T) {
|
||||
setupRemoteNetworkDrivers(c, mux, s.server.URL, dummyNetworkDriver, dummyIPAMDriver)
|
||||
}
|
||||
|
||||
func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ipamDrv string) {
|
||||
func setupRemoteNetworkDrivers(t *testing.T, mux *http.ServeMux, url, netDrv, ipamDrv string) {
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Implements": ["%s", "%s"]}`, driverapi.NetworkPluginEndpointType, ipamapi.PluginEndpointType)
|
||||
_, err := fmt.Fprintf(w, `{"Implements": ["%s", "%s"]}`, driverapi.NetworkPluginEndpointType, ipamapi.PluginEndpointType)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
// Network driver implementation
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.GetCapabilities", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Scope":"local"}`)
|
||||
_, err := fmt.Fprint(w, `{"Scope":"local"}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.CreateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -78,17 +80,20 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err = fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.DeleteNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.CreateEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
|
||||
_, err := fmt.Fprint(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.Join", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -98,23 +103,28 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
LinkAttrs: netlink.LinkAttrs{Name: "randomIfName", TxQLen: 0}, PeerName: "cnt0",
|
||||
}
|
||||
if err := netlink.LinkAdd(veth); err != nil {
|
||||
fmt.Fprintf(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`)
|
||||
_, err = fmt.Fprintf(w, `{"Error":"failed to add veth pair: %v"}`, err)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
|
||||
_, err = fmt.Fprint(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.Leave", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.DeleteEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
if link, err := netlink.LinkByName("cnt0"); err == nil {
|
||||
netlink.LinkDel(link)
|
||||
err = netlink.LinkDel(link)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
// IPAM Driver implementation
|
||||
@@ -123,16 +133,19 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
poolReleaseReq remoteipam.ReleasePoolRequest
|
||||
addressRequest remoteipam.RequestAddressRequest
|
||||
addressReleaseReq remoteipam.ReleaseAddressRequest
|
||||
lAS = "localAS"
|
||||
gAS = "globalAS"
|
||||
pool = "172.28.0.0/16"
|
||||
poolID = lAS + "/" + pool
|
||||
gw = "172.28.255.254/16"
|
||||
)
|
||||
const (
|
||||
lAS = "localAS"
|
||||
gAS = "globalAS"
|
||||
pool = "172.28.0.0/16"
|
||||
poolID = lAS + "/" + pool
|
||||
gw = "172.28.255.254/16"
|
||||
)
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.GetDefaultAddressSpaces", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"LocalDefaultAddressSpace":"`+lAS+`", "GlobalDefaultAddressSpace": "`+gAS+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"LocalDefaultAddressSpace":"`+lAS+`", "GlobalDefaultAddressSpace": "`+gAS+`"}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.RequestPool", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -143,11 +156,14 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
}
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
if poolRequest.AddressSpace != lAS && poolRequest.AddressSpace != gAS {
|
||||
fmt.Fprintf(w, `{"Error":"Unknown address space in pool request: `+poolRequest.AddressSpace+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Unknown address space in pool request: `+poolRequest.AddressSpace+`"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if poolRequest.Pool != "" && poolRequest.Pool != pool {
|
||||
fmt.Fprintf(w, `{"Error":"Cannot handle explicit pool requests yet"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Cannot handle explicit pool requests yet"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"PoolID":"`+poolID+`", "Pool":"`+pool+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"PoolID":"`+poolID+`", "Pool":"`+pool+`"}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -160,11 +176,14 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now querying on the expected pool id
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if addressRequest.Address != "" {
|
||||
fmt.Fprintf(w, `{"Error":"Cannot handle explicit address requests yet"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Cannot handle explicit address requests yet"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"Address":"`+gw+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"Address":"`+gw+`"}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -177,11 +196,14 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now asking to release the expected address from the expected poolid
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if addressReleaseReq.Address != gw {
|
||||
fmt.Fprintf(w, `{"Error":"unknown address"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown address"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -194,22 +216,24 @@ func setupRemoteNetworkDrivers(c *testing.T, mux *http.ServeMux, url, netDrv, ip
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now asking to release the expected poolid
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
err := os.MkdirAll("/etc/docker/plugins", 0o755)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
|
||||
fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
||||
err = os.WriteFile(fileName, []byte(url), 0o644)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
||||
err = os.WriteFile(ipamFileName, []byte(url), 0o644)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TearDownSuite(ctx context.Context, c *testing.T) {
|
||||
@@ -508,9 +532,9 @@ func (s *DockerCLINetworkSuite) TestDockerInspectNetworkWithContainerName(c *tes
|
||||
err := json.Unmarshal([]byte(out), &networkResources)
|
||||
assert.NilError(c, err)
|
||||
assert.Equal(c, len(networkResources), 1)
|
||||
container, ok := networkResources[0].Containers[containerID]
|
||||
ctr, ok := networkResources[0].Containers[containerID]
|
||||
assert.Assert(c, ok)
|
||||
assert.Equal(c, container.Name, "testNetInspect1")
|
||||
assert.Equal(c, ctr.Name, "testNetInspect1")
|
||||
|
||||
// rename container and check docker inspect output update
|
||||
newName := "HappyNewName"
|
||||
@@ -825,12 +849,12 @@ func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c *
|
||||
assert.NilError(c, err)
|
||||
assert.Equal(c, hosts, hostsPost, fmt.Sprintf("Unexpected %s change on second container creation", hostsFile))
|
||||
// but discovery is on when connecting to non default bridge network
|
||||
network := "anotherbridge"
|
||||
out, err = s.d.Cmd("network", "create", network)
|
||||
nw := "anotherbridge"
|
||||
out, err = s.d.Cmd("network", "create", nw)
|
||||
assert.NilError(c, err, out)
|
||||
defer s.d.Cmd("network", "rm", network)
|
||||
defer s.d.Cmd("network", "rm", nw)
|
||||
|
||||
out, err = s.d.Cmd("network", "connect", network, cid1)
|
||||
out, err = s.d.Cmd("network", "connect", nw, cid1)
|
||||
assert.NilError(c, err, out)
|
||||
|
||||
hosts, err = s.d.Cmd("exec", cid1, "cat", hostsFile)
|
||||
@@ -897,15 +921,15 @@ func (s *DockerNetworkSuite) TestDockerNetworkLinkOnDefaultNetworkOnly(c *testin
|
||||
// Legacy Link feature must work only on default network, and not across networks
|
||||
cnt1 := "container1"
|
||||
cnt2 := "container2"
|
||||
network := "anotherbridge"
|
||||
nw := "anotherbridge"
|
||||
|
||||
// Run first container on default network
|
||||
cli.DockerCmd(c, "run", "-d", "--name", cnt1, "busybox", "top")
|
||||
|
||||
// Create another network and run the second container on it
|
||||
cli.DockerCmd(c, "network", "create", network)
|
||||
assertNwIsAvailable(c, network)
|
||||
cli.DockerCmd(c, "run", "-d", "--net", network, "--name", cnt2, "busybox", "top")
|
||||
cli.DockerCmd(c, "network", "create", nw)
|
||||
assertNwIsAvailable(c, nw)
|
||||
cli.DockerCmd(c, "run", "-d", "--net", nw, "--name", cnt2, "busybox", "top")
|
||||
|
||||
// Try launching a container on default network, linking to the first container. Must succeed
|
||||
cli.DockerCmd(c, "run", "-d", "--link", fmt.Sprintf("%s:%s", cnt1, cnt1), "busybox", "top")
|
||||
@@ -1726,12 +1750,12 @@ func (s *DockerNetworkSuite) TestDockerNetworkValidateIP(c *testing.T) {
|
||||
// Test case for 26220
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkDisconnectFromBridge(c *testing.T) {
|
||||
out := cli.DockerCmd(c, "network", "inspect", "--format", "{{.Id}}", "bridge").Stdout()
|
||||
network := strings.TrimSpace(out)
|
||||
nw := strings.TrimSpace(out)
|
||||
|
||||
name := "test"
|
||||
cli.DockerCmd(c, "create", "--name", name, "busybox", "top")
|
||||
|
||||
_, _, err := dockerCmdWithError("network", "disconnect", network, name)
|
||||
_, _, err := dockerCmdWithError("network", "disconnect", nw, name)
|
||||
assert.NilError(c, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -251,11 +250,8 @@ func (s *DockerCLIRunSuite) TestRunAttachDetachFromConfig(c *testing.T) {
|
||||
os.Mkdir(dotDocker, 0o600)
|
||||
tmpCfg := filepath.Join(dotDocker, "config.json")
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
c.Setenv("USERPROFILE", tmpDir)
|
||||
} else {
|
||||
c.Setenv("HOME", tmpDir)
|
||||
}
|
||||
// TODO(thaJeztah): migrate this test to docker/cli, and run on Windows as well (using USERPROFILE for home-dir)
|
||||
c.Setenv("HOME", tmpDir)
|
||||
|
||||
data := `{
|
||||
"detachKeys": "ctrl-a,a"
|
||||
@@ -335,11 +331,8 @@ func (s *DockerCLIRunSuite) TestRunAttachDetachKeysOverrideConfig(c *testing.T)
|
||||
os.Mkdir(dotDocker, 0o600)
|
||||
tmpCfg := filepath.Join(dotDocker, "config.json")
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
c.Setenv("USERPROFILE", tmpDir)
|
||||
} else {
|
||||
c.Setenv("HOME", tmpDir)
|
||||
}
|
||||
// TODO(thaJeztah): migrate this test to docker/cli, and run on Windows as well (using USERPROFILE for home-dir)
|
||||
c.Setenv("HOME", tmpDir)
|
||||
|
||||
data := `{
|
||||
"detachKeys": "ctrl-e,e"
|
||||
|
||||
@@ -384,7 +384,8 @@ func (s *DockerSwarmSuite) TestSwarmContainerAttachByNetworkId(c *testing.T) {
|
||||
out, err = d.Cmd("run", "-d", "--net", networkID, "busybox", "top")
|
||||
assert.NilError(c, err, out)
|
||||
cID := strings.TrimSpace(out)
|
||||
d.WaitRun(cID)
|
||||
err = d.WaitRun(cID)
|
||||
assert.NilError(c, err)
|
||||
|
||||
out, err = d.Cmd("rm", "-f", cID)
|
||||
assert.NilError(c, err, out)
|
||||
@@ -638,16 +639,18 @@ const (
|
||||
globalIPAMPlugin = "global-ipam-plugin"
|
||||
)
|
||||
|
||||
func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDrv, ipamDrv string) {
|
||||
func setupRemoteGlobalNetworkPlugin(t *testing.T, mux *http.ServeMux, url, netDrv, ipamDrv string) {
|
||||
mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Implements": ["%s", "%s"]}`, driverapi.NetworkPluginEndpointType, ipamapi.PluginEndpointType)
|
||||
_, err := fmt.Fprintf(w, `{"Implements": ["%s", "%s"]}`, driverapi.NetworkPluginEndpointType, ipamapi.PluginEndpointType)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
// Network driver implementation
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.GetCapabilities", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Scope":"global"}`)
|
||||
_, err := fmt.Fprint(w, `{"Scope":"global"}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.AllocateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -657,12 +660,14 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err = fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.FreeNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.CreateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -672,17 +677,20 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err = fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.DeleteNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.CreateEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
|
||||
_, err := fmt.Fprint(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.Join", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -692,23 +700,28 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
LinkAttrs: netlink.LinkAttrs{Name: "randomIfName", TxQLen: 0}, PeerName: "cnt0",
|
||||
}
|
||||
if err := netlink.LinkAdd(veth); err != nil {
|
||||
fmt.Fprintf(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`)
|
||||
_, err = fmt.Fprint(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
|
||||
_, err = fmt.Fprint(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.Leave", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.DeleteEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
if link, err := netlink.LinkByName("cnt0"); err == nil {
|
||||
netlink.LinkDel(link)
|
||||
err := netlink.LinkDel(link)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
// IPAM Driver implementation
|
||||
@@ -717,16 +730,19 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
poolReleaseReq remoteipam.ReleasePoolRequest
|
||||
addressRequest remoteipam.RequestAddressRequest
|
||||
addressReleaseReq remoteipam.ReleaseAddressRequest
|
||||
lAS = "localAS"
|
||||
gAS = "globalAS"
|
||||
pool = "172.28.0.0/16"
|
||||
poolID = lAS + "/" + pool
|
||||
gw = "172.28.255.254/16"
|
||||
)
|
||||
const (
|
||||
lAS = "localAS"
|
||||
gAS = "globalAS"
|
||||
pool = "172.28.0.0/16"
|
||||
poolID = lAS + "/" + pool
|
||||
gw = "172.28.255.254/16"
|
||||
)
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.GetDefaultAddressSpaces", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
fmt.Fprintf(w, `{"LocalDefaultAddressSpace":"`+lAS+`", "GlobalDefaultAddressSpace": "`+gAS+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"LocalDefaultAddressSpace":"`+lAS+`", "GlobalDefaultAddressSpace": "`+gAS+`"}`)
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
mux.HandleFunc(fmt.Sprintf("/%s.RequestPool", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -737,11 +753,14 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
}
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
if poolRequest.AddressSpace != lAS && poolRequest.AddressSpace != gAS {
|
||||
fmt.Fprintf(w, `{"Error":"Unknown address space in pool request: `+poolRequest.AddressSpace+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Unknown address space in pool request: `+poolRequest.AddressSpace+`"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if poolRequest.Pool != "" && poolRequest.Pool != pool {
|
||||
fmt.Fprintf(w, `{"Error":"Cannot handle explicit pool requests yet"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Cannot handle explicit pool requests yet"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"PoolID":"`+poolID+`", "Pool":"`+pool+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"PoolID":"`+poolID+`", "Pool":"`+pool+`"}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -754,11 +773,14 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now querying on the expected pool id
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if addressRequest.Address != "" {
|
||||
fmt.Fprintf(w, `{"Error":"Cannot handle explicit address requests yet"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"Cannot handle explicit address requests yet"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"Address":"`+gw+`"}`)
|
||||
_, err := fmt.Fprint(w, `{"Address":"`+gw+`"}`)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -771,11 +793,14 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now asking to release the expected address from the expected poolid
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else if addressReleaseReq.Address != gw {
|
||||
fmt.Fprintf(w, `{"Error":"unknown address"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown address"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -788,22 +813,24 @@ func setupRemoteGlobalNetworkPlugin(c *testing.T, mux *http.ServeMux, url, netDr
|
||||
w.Header().Set("Content-Type", plugins.VersionMimetype)
|
||||
// make sure libnetwork is now asking to release the expected poolid
|
||||
if addressRequest.PoolID != poolID {
|
||||
fmt.Fprintf(w, `{"Error":"unknown pool id"}`)
|
||||
_, err := fmt.Fprint(w, `{"Error":"unknown pool id"}`)
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "null")
|
||||
_, err := fmt.Fprint(w, "null")
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
err := os.MkdirAll("/etc/docker/plugins", 0o755)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
|
||||
fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv)
|
||||
err = os.WriteFile(fileName, []byte(url), 0o644)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv)
|
||||
err = os.WriteFile(ipamFileName, []byte(url), 0o644)
|
||||
assert.NilError(c, err)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func (s *DockerSwarmSuite) TestSwarmNetworkPlugin(c *testing.T) {
|
||||
|
||||
@@ -439,7 +439,7 @@ func pollCheck(t *testing.T, f checkF, compare func(x interface{}) assert.BoolOr
|
||||
default:
|
||||
panic(fmt.Errorf("pollCheck: type %T not implemented", r))
|
||||
}
|
||||
return poll.Continue(comment)
|
||||
return poll.Continue("%v", comment)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/docker/docker/testutil/fakecontext"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -85,6 +86,8 @@ func TestBuildSquashParent(t *testing.T) {
|
||||
container.WithImage(name),
|
||||
container.WithCmd("/bin/sh", "-c", "cat /hello"),
|
||||
)
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, client, cid))
|
||||
reader, err := client.ContainerLogs(ctx, cid, containertypes.LogsOptions{
|
||||
ShowStdout: true,
|
||||
})
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/docker/docker/testutil/fakecontext"
|
||||
"github.com/docker/docker/testutil/fixtures/load"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -117,6 +118,8 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) {
|
||||
container.WithImage(imageTag),
|
||||
container.WithCmd("/sbin/getcap", "-n", "/bin/sleep"),
|
||||
)
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, clientNoUserRemap, cid))
|
||||
logReader, err := clientNoUserRemap.ContainerLogs(ctx, cid, containertypes.LogsOptions{
|
||||
ShowStdout: true,
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -54,6 +55,7 @@ func TestCreateWithCDIDevices(t *testing.T) {
|
||||
}
|
||||
assert.Check(t, is.DeepEqual(inspect.HostConfig.DeviceRequests, expectedRequests))
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, apiClient, id))
|
||||
reader, err := apiClient.ContainerLogs(ctx, id, containertypes.LogsOptions{
|
||||
ShowStdout: true,
|
||||
})
|
||||
|
||||
@@ -23,6 +23,7 @@ func TestDiff(t *testing.T) {
|
||||
{Kind: containertypes.ChangeAdd, Path: "/foo/bar"},
|
||||
}
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, apiClient, cID))
|
||||
items, err := apiClient.ContainerDiff(ctx, cID)
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expected, items)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -25,13 +26,25 @@ func TestNetworkNat(t *testing.T) {
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
msg := "it works"
|
||||
startServerContainer(ctx, t, msg, 8080)
|
||||
const msg = "it works"
|
||||
const port = 8080
|
||||
startServerContainer(ctx, t, msg, port)
|
||||
|
||||
endpoint := getExternalAddress(t)
|
||||
conn, err := net.Dial("tcp", net.JoinHostPort(endpoint.String(), "8080"))
|
||||
assert.NilError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
var conn net.Conn
|
||||
addr := net.JoinHostPort(endpoint.String(), strconv.Itoa(port))
|
||||
poll.WaitOn(t, func(t poll.LogT) poll.Result {
|
||||
var err error
|
||||
conn, err = net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return poll.Continue("waiting for %s to be accessible: %v", addr, err)
|
||||
}
|
||||
return poll.Success()
|
||||
})
|
||||
defer func() {
|
||||
assert.Check(t, conn.Close())
|
||||
}()
|
||||
|
||||
data, err := io.ReadAll(conn)
|
||||
assert.NilError(t, err)
|
||||
@@ -43,12 +56,23 @@ func TestNetworkLocalhostTCPNat(t *testing.T) {
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
msg := "hi yall"
|
||||
startServerContainer(ctx, t, msg, 8081)
|
||||
const msg = "hi yall"
|
||||
const port = 8081
|
||||
startServerContainer(ctx, t, msg, port)
|
||||
|
||||
conn, err := net.Dial("tcp", "localhost:8081")
|
||||
assert.NilError(t, err)
|
||||
defer conn.Close()
|
||||
var conn net.Conn
|
||||
addr := net.JoinHostPort("localhost", strconv.Itoa(port))
|
||||
poll.WaitOn(t, func(t poll.LogT) poll.Result {
|
||||
var err error
|
||||
conn, err = net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return poll.Continue("waiting for %s to be accessible: %v", addr, err)
|
||||
}
|
||||
return poll.Success()
|
||||
})
|
||||
defer func() {
|
||||
assert.Check(t, conn.Close())
|
||||
}()
|
||||
|
||||
data, err := io.ReadAll(conn)
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/containerd/errdefs"
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/docker/api/types"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
|
||||
@@ -388,6 +388,7 @@ func TestLiveRestore(t *testing.T) {
|
||||
|
||||
t.Run("volume references", testLiveRestoreVolumeReferences)
|
||||
t.Run("autoremove", testLiveRestoreAutoRemove)
|
||||
t.Run("user chains", testLiveRestoreUserChainsSetup)
|
||||
}
|
||||
|
||||
func testLiveRestoreAutoRemove(t *testing.T) {
|
||||
@@ -606,6 +607,34 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func testLiveRestoreUserChainsSetup(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRootless(), "rootless daemon uses it's own network namespace")
|
||||
|
||||
t.Parallel()
|
||||
ctx := testutil.StartSpan(baseContext, t)
|
||||
|
||||
t.Run("user chains should be inserted", func(t *testing.T) {
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t, "--live-restore")
|
||||
t.Cleanup(func() {
|
||||
d.Stop(t)
|
||||
d.Cleanup(t)
|
||||
})
|
||||
|
||||
c := d.NewClientT(t)
|
||||
|
||||
cID := container.Run(ctx, t, c, container.WithCmd("top"))
|
||||
defer c.ContainerRemove(ctx, cID, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
d.Stop(t)
|
||||
icmd.RunCommand("iptables", "--flush", "FORWARD").Assert(t, icmd.Success)
|
||||
d.Start(t, "--live-restore")
|
||||
|
||||
result := icmd.RunCommand("iptables", "-S", "FORWARD", "1")
|
||||
assert.Check(t, is.Equal(strings.TrimSpace(result.Stdout()), "-A FORWARD -j DOCKER-USER"), "the jump to DOCKER-USER should be the first rule in the FORWARD chain")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaemonDefaultBridgeWithFixedCidrButNoBip(t *testing.T) {
|
||||
skip.If(t, runtime.GOOS == "windows")
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -61,7 +62,8 @@ func TestUsernsCommit(t *testing.T) {
|
||||
clientUserRemap := dUserRemap.NewClientT(t)
|
||||
defer clientUserRemap.Close()
|
||||
|
||||
container.Run(ctx, t, clientUserRemap, container.WithName(t.Name()), container.WithImage("busybox"), container.WithCmd("sh", "-c", "echo hello world > /hello.txt && chown 1000:1000 /hello.txt"))
|
||||
cID := container.Run(ctx, t, clientUserRemap, container.WithName(t.Name()), container.WithImage("busybox"), container.WithCmd("sh", "-c", "echo hello world > /hello.txt && chown 1000:1000 /hello.txt"))
|
||||
poll.WaitOn(t, container.IsStopped(ctx, clientUserRemap, cID))
|
||||
img, err := clientUserRemap.ContainerCommit(ctx, t.Name(), containertypes.CommitOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@ import (
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
imagetypes "github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/testutil"
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -179,7 +181,8 @@ func TestImportWithCustomPlatformReject(t *testing.T) {
|
||||
reference,
|
||||
imagetypes.ImportOptions{Platform: tc.platform})
|
||||
|
||||
assert.ErrorContains(t, err, tc.expectedErr)
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter))
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedErr))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,13 @@ func WithNetworkMode(mode string) func(*TestContainerConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// WithDNS sets external DNS servers for the container
|
||||
func WithDNS(dns []string) func(*TestContainerConfig) {
|
||||
return func(c *TestContainerConfig) {
|
||||
c.HostConfig.DNS = append([]string(nil), dns...)
|
||||
}
|
||||
}
|
||||
|
||||
// WithSysctls sets sysctl options for the container
|
||||
func WithSysctls(sysctls map[string]string) func(*TestContainerConfig) {
|
||||
return func(c *TestContainerConfig) {
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"github.com/docker/docker/integration/internal/network"
|
||||
"github.com/docker/docker/testutil"
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
@@ -33,3 +35,59 @@ func TestDaemonDNSFallback(t *testing.T) {
|
||||
|
||||
poll.WaitOn(t, container.IsSuccessful(ctx, c, cid), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(10*time.Second))
|
||||
}
|
||||
|
||||
// Check that, when the internal DNS server's address is supplied as an external
|
||||
// DNS server, the daemon doesn't start talking to itself.
|
||||
func TestIntDNSAsExtDNS(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "cannot start daemon on Windows test run")
|
||||
skip.If(t, testEnv.IsRemoteDaemon, "cannot start daemon on remote test run")
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t)
|
||||
defer d.Stop(t)
|
||||
|
||||
c := d.NewClientT(t)
|
||||
defer c.Close()
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
extServers []string
|
||||
expExitCode int
|
||||
expStdout string
|
||||
}{
|
||||
{
|
||||
name: "only self",
|
||||
extServers: []string{"127.0.0.11"},
|
||||
expExitCode: 1,
|
||||
expStdout: "SERVFAIL",
|
||||
},
|
||||
{
|
||||
name: "self then ext",
|
||||
extServers: []string{"127.0.0.11", "8.8.8.8"},
|
||||
expExitCode: 0,
|
||||
expStdout: "Non-authoritative answer",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
|
||||
const netName = "testnet"
|
||||
network.CreateNoError(ctx, t, c, netName)
|
||||
defer network.RemoveNoError(ctx, t, c, netName)
|
||||
|
||||
res := container.RunAttach(ctx, t, c,
|
||||
container.WithNetworkMode(netName),
|
||||
container.WithDNS(tc.extServers),
|
||||
container.WithCmd("nslookup", "docker.com"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
assert.Check(t, is.Equal(res.ExitCode, tc.expExitCode))
|
||||
assert.Check(t, is.Contains(res.Stdout.String(), tc.expStdout))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +469,6 @@ func TestDefaultBridgeAddresses(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
||||
|
||||
ctx := setupTest(t)
|
||||
d := daemon.New(t)
|
||||
|
||||
type testStep struct {
|
||||
stepName string
|
||||
@@ -487,13 +486,13 @@ func TestDefaultBridgeAddresses(t *testing.T) {
|
||||
{
|
||||
stepName: "Set up initial UL prefix",
|
||||
fixedCIDRV6: "fd1c:f1a0:5d8d:aaaa::/64",
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:aaaa::1/64", "fe80::1/64"},
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:aaaa::1/64", "fe80::"},
|
||||
},
|
||||
{
|
||||
// Modify that prefix, the default bridge's address must be deleted and re-added.
|
||||
stepName: "Modify UL prefix - address change",
|
||||
fixedCIDRV6: "fd1c:f1a0:5d8d:bbbb::/64",
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:bbbb::1/64", "fe80::1/64"},
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:bbbb::1/64", "fe80::"},
|
||||
},
|
||||
{
|
||||
// Modify the prefix length, the default bridge's address should not change.
|
||||
@@ -501,7 +500,7 @@ func TestDefaultBridgeAddresses(t *testing.T) {
|
||||
fixedCIDRV6: "fd1c:f1a0:5d8d:bbbb::/80",
|
||||
// The prefix length displayed by 'ip a' is not updated - it's informational, and
|
||||
// can't be changed without unnecessarily deleting and re-adding the address.
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:bbbb::1/64", "fe80::1/64"},
|
||||
expAddrs: []string{"fd1c:f1a0:5d8d:bbbb::1/64", "fe80::"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -511,14 +510,14 @@ func TestDefaultBridgeAddresses(t *testing.T) {
|
||||
{
|
||||
stepName: "Standard LL subnet prefix",
|
||||
fixedCIDRV6: "fe80::/64",
|
||||
expAddrs: []string{"fe80::1/64"},
|
||||
expAddrs: []string{"fe80::"},
|
||||
},
|
||||
{
|
||||
// Modify that prefix, the default bridge's address must be deleted and re-added.
|
||||
// The bridge must still have an address in the required (standard) LL subnet.
|
||||
stepName: "Nonstandard LL prefix - address change",
|
||||
fixedCIDRV6: "fe80:1234::/32",
|
||||
expAddrs: []string{"fe80:1234::1/32", "fe80::1/64"},
|
||||
expAddrs: []string{"fe80:1234::1/32", "fe80::"},
|
||||
},
|
||||
{
|
||||
// Modify the prefix length, the addresses should not change.
|
||||
@@ -526,32 +525,48 @@ func TestDefaultBridgeAddresses(t *testing.T) {
|
||||
fixedCIDRV6: "fe80:1234::/64",
|
||||
// The prefix length displayed by 'ip a' is not updated - it's informational, and
|
||||
// can't be changed without unnecessarily deleting and re-adding the address.
|
||||
expAddrs: []string{"fe80:1234::1/", "fe80::1/64"},
|
||||
expAddrs: []string{"fe80:1234::1/", "fe80::"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
for _, step := range tc.steps {
|
||||
// Check that the daemon starts - regression test for:
|
||||
// https://github.com/moby/moby/issues/46829
|
||||
d.Start(t, "--experimental", "--ipv6", "--ip6tables", "--fixed-cidr-v6="+step.fixedCIDRV6)
|
||||
d.Stop(t)
|
||||
for _, preserveKernelLL := range []bool{false, true} {
|
||||
var dopts []daemon.Option
|
||||
if preserveKernelLL {
|
||||
dopts = append(dopts, daemon.WithEnvVars("DOCKER_BRIDGE_PRESERVE_KERNEL_LL=1"))
|
||||
}
|
||||
d := daemon.New(t, dopts...)
|
||||
c := d.NewClientT(t)
|
||||
|
||||
// Check that the expected addresses have been applied to the bridge. (Skip in
|
||||
// rootless mode, because the bridge is in a different network namespace.)
|
||||
if !testEnv.IsRootless() {
|
||||
res := testutil.RunCommand(ctx, "ip", "-6", "addr", "show", "docker0")
|
||||
assert.Equal(t, res.ExitCode, 0, step.stepName)
|
||||
stdout := res.Stdout()
|
||||
for _, expAddr := range step.expAddrs {
|
||||
assert.Check(t, is.Contains(stdout, expAddr))
|
||||
for _, tc := range testcases {
|
||||
for _, step := range tc.steps {
|
||||
tcName := fmt.Sprintf("kernel_ll_%v/%s/%s", preserveKernelLL, tc.name, step.stepName)
|
||||
t.Run(tcName, func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
// Check that the daemon starts - regression test for:
|
||||
// https://github.com/moby/moby/issues/46829
|
||||
d.StartWithBusybox(ctx, t, "--experimental", "--ipv6", "--ip6tables", "--fixed-cidr-v6="+step.fixedCIDRV6)
|
||||
|
||||
// Start a container, so that the bridge is set "up" and gets a kernel_ll address.
|
||||
cID := container.Run(ctx, t, c)
|
||||
defer c.ContainerRemove(ctx, cID, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
d.Stop(t)
|
||||
|
||||
// Check that the expected addresses have been applied to the bridge. (Skip in
|
||||
// rootless mode, because the bridge is in a different network namespace.)
|
||||
if !testEnv.IsRootless() {
|
||||
res := testutil.RunCommand(ctx, "ip", "-6", "addr", "show", "docker0")
|
||||
assert.Equal(t, res.ExitCode, 0, step.stepName)
|
||||
stdout := res.Stdout()
|
||||
for _, expAddr := range step.expAddrs {
|
||||
assert.Check(t, is.Contains(stdout, expAddr))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,3 +753,78 @@ func TestSetInterfaceSysctl(t *testing.T) {
|
||||
stdout := runRes.Stdout.String()
|
||||
assert.Check(t, is.Contains(stdout, scName))
|
||||
}
|
||||
|
||||
// With a read-only "/proc/sys/net" filesystem (simulated using env var
|
||||
// DOCKER_TEST_RO_DISABLE_IPV6), check that if IPv6 can't be disabled on a
|
||||
// container interface, container creation fails - unless the error is ignored by
|
||||
// setting env var DOCKER_ALLOW_IPV6_ON_IPV4_INTERFACE=1.
|
||||
// Regression test for https://github.com/moby/moby/issues/47751
|
||||
func TestReadOnlySlashProc(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
daemonEnv []string
|
||||
expErr string
|
||||
}{
|
||||
{
|
||||
name: "Normality",
|
||||
},
|
||||
{
|
||||
name: "Read only no workaround",
|
||||
daemonEnv: []string{
|
||||
"DOCKER_TEST_RO_DISABLE_IPV6=1",
|
||||
},
|
||||
expErr: "failed to disable IPv6 on container's interface eth0, set env var DOCKER_ALLOW_IPV6_ON_IPV4_INTERFACE=1 to ignore this error",
|
||||
},
|
||||
{
|
||||
name: "Read only with workaround",
|
||||
daemonEnv: []string{
|
||||
"DOCKER_TEST_RO_DISABLE_IPV6=1",
|
||||
"DOCKER_ALLOW_IPV6_ON_IPV4_INTERFACE=1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
|
||||
d := daemon.New(t, daemon.WithEnvVars(tc.daemonEnv...))
|
||||
d.StartWithBusybox(ctx, t)
|
||||
defer d.Stop(t)
|
||||
c := d.NewClientT(t)
|
||||
|
||||
const net4Name = "testnet4"
|
||||
network.CreateNoError(ctx, t, c, net4Name)
|
||||
defer network.RemoveNoError(ctx, t, c, net4Name)
|
||||
id4 := container.Create(ctx, t, c,
|
||||
container.WithNetworkMode(net4Name),
|
||||
container.WithCmd("ls"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, id4, containertypes.RemoveOptions{Force: true})
|
||||
err := c.ContainerStart(ctx, id4, containertypes.StartOptions{})
|
||||
if tc.expErr == "" {
|
||||
assert.Check(t, err)
|
||||
} else {
|
||||
assert.Check(t, is.ErrorContains(err, tc.expErr))
|
||||
}
|
||||
|
||||
// It should always be possible to create a container on an IPv6 network (IPv6
|
||||
// doesn't need to be disabled on the interface).
|
||||
const net6Name = "testnet6"
|
||||
network.CreateNoError(ctx, t, c, net6Name,
|
||||
network.WithIPv6(),
|
||||
network.WithIPAM("fd5c:15e3:0b62:5395::/64", "fd5c:15e3:0b62:5395::1"),
|
||||
)
|
||||
defer network.RemoveNoError(ctx, t, c, net6Name)
|
||||
id6 := container.Run(ctx, t, c,
|
||||
container.WithNetworkMode(net6Name),
|
||||
container.WithCmd("ls"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, id6, containertypes.RemoveOptions{Force: true})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ package networking
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
"github.com/docker/docker/integration/internal/network"
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
@@ -134,6 +137,59 @@ func TestInternalNetworkDNS(t *testing.T) {
|
||||
assert.Check(t, is.Contains(res.Stdout(), network.DNSRespAddr))
|
||||
}
|
||||
|
||||
// Check that '--dns' can be used to name a server inside a '--internal' network.
|
||||
// Regression test for https://github.com/moby/moby/issues/47822
|
||||
func TestInternalNetworkLocalDNS(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "No internal networks on Windows")
|
||||
skip.If(t, testEnv.IsRootless, "Can't write an accessible dnsd.conf in rootless mode")
|
||||
ctx := setupTest(t)
|
||||
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t)
|
||||
defer d.Stop(t)
|
||||
|
||||
c := d.NewClientT(t)
|
||||
defer c.Close()
|
||||
|
||||
intNetName := "intnet"
|
||||
network.CreateNoError(ctx, t, c, intNetName,
|
||||
network.WithDriver("bridge"),
|
||||
network.WithInternal(),
|
||||
)
|
||||
defer network.RemoveNoError(ctx, t, c, intNetName)
|
||||
|
||||
// Write a config file for busybox's dnsd.
|
||||
td := t.TempDir()
|
||||
fname := path.Join(td, "dnsd.conf")
|
||||
err := os.WriteFile(fname, []byte("foo.example 192.0.2.42\n"), 0644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Start a DNS server on the internal network.
|
||||
serverId := container.Run(ctx, t, c,
|
||||
container.WithNetworkMode(intNetName),
|
||||
container.WithMount(mount.Mount{
|
||||
Type: mount.TypeBind,
|
||||
Source: fname,
|
||||
Target: "/etc/dnsd.conf",
|
||||
}),
|
||||
container.WithCmd("dnsd"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, serverId, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
// Get the DNS server's address.
|
||||
inspect := container.Inspect(ctx, t, c, serverId)
|
||||
serverIP := inspect.NetworkSettings.Networks[intNetName].IPAddress
|
||||
|
||||
// Query the internal network's DNS server (via the daemon's internal DNS server).
|
||||
res := container.RunAttach(ctx, t, c,
|
||||
container.WithNetworkMode(intNetName),
|
||||
container.WithDNS([]string{serverIP}),
|
||||
container.WithCmd("nslookup", "-type=A", "foo.example"),
|
||||
)
|
||||
defer c.ContainerRemove(ctx, res.ContainerID, containertypes.RemoveOptions{Force: true})
|
||||
assert.Check(t, is.Contains(res.Stdout.String(), "192.0.2.42"))
|
||||
}
|
||||
|
||||
// TestNslookupWindows checks that nslookup gets results from external DNS.
|
||||
// Regression test for https://github.com/moby/moby/issues/46792
|
||||
func TestNslookupWindows(t *testing.T) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user