mirror of
https://github.com/moby/moby.git
synced 2026-01-13 11:42:02 +00:00
Compare commits
227 Commits
copilot/fi
...
28.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e04130911 | ||
|
|
f5cacc257a | ||
|
|
89c5e8fd66 | ||
|
|
9b93878308 | ||
|
|
6178456763 | ||
|
|
0cae4e5c8f | ||
|
|
33cc06f616 | ||
|
|
d525277410 | ||
|
|
2fbc51b4f8 | ||
|
|
bd98008c07 | ||
|
|
19675151a3 | ||
|
|
44896604b8 | ||
|
|
d24eab928b | ||
|
|
b651c094e2 | ||
|
|
df58dd519b | ||
|
|
f822c9f39c | ||
|
|
f8215cc266 | ||
|
|
40a856a593 | ||
|
|
5d1c3119f2 | ||
|
|
90506c1144 | ||
|
|
17db0cd834 | ||
|
|
f7c40ea344 | ||
|
|
dccf7c889c | ||
|
|
0f040aa194 | ||
|
|
5b1a039e6f | ||
|
|
8fa4bd5e0d | ||
|
|
e59129b9cc | ||
|
|
28d9ed5878 | ||
|
|
adcea7bdc9 | ||
|
|
bab04642ff | ||
|
|
7841b1c65b | ||
|
|
1dcce6800f | ||
|
|
b67c30f946 | ||
|
|
3388108f9a | ||
|
|
5c2c3c2ae1 | ||
|
|
e468481ff0 | ||
|
|
cd048300a4 | ||
|
|
e29d6be7a5 | ||
|
|
9b4369035b | ||
|
|
4f3572596b | ||
|
|
79f310d4bc | ||
|
|
deb4bbbfe0 | ||
|
|
423a7fd6af | ||
|
|
fbf2fe8b7d | ||
|
|
252a1ebe7e | ||
|
|
2c15eb6617 | ||
|
|
f984f7218f | ||
|
|
fd10938136 | ||
|
|
73f8d82c4b | ||
|
|
1096e39142 | ||
|
|
dc504e1e68 | ||
|
|
9fa8529070 | ||
|
|
d21856f25d | ||
|
|
b7496d9ec0 | ||
|
|
3aa032e1e8 | ||
|
|
80ac399595 | ||
|
|
22e0cb2d64 | ||
|
|
1b0ba3b217 | ||
|
|
6d311b44e4 | ||
|
|
608fdeb216 | ||
|
|
46dcd7f33e | ||
|
|
81da1cfdb2 | ||
|
|
249d679a6b | ||
|
|
d664cfe139 | ||
|
|
b384cd2a45 | ||
|
|
c1ce88e7f8 | ||
|
|
4a34e8e9f6 | ||
|
|
cfa70d073e | ||
|
|
d70382e442 | ||
|
|
687b206c6b | ||
|
|
e4224f86c0 | ||
|
|
5d5332b00c | ||
|
|
87622a0ee5 | ||
|
|
ffb621aade | ||
|
|
ac93e0ffb9 | ||
|
|
1c7c645702 | ||
|
|
43a614bec0 | ||
|
|
a8914649d8 | ||
|
|
18e4a056bb | ||
|
|
b6427d938e | ||
|
|
ee159311c4 | ||
|
|
660b67be5e | ||
|
|
eb7be20774 | ||
|
|
01b27f6056 | ||
|
|
65a1687e3d | ||
|
|
0e5ff488de | ||
|
|
02b4a1a3de | ||
|
|
a36d9d6276 | ||
|
|
8fd7525658 | ||
|
|
b13b91c54b | ||
|
|
314a8f8f0b | ||
|
|
31f405932a | ||
|
|
4c8a437c78 | ||
|
|
1ab19b12f5 | ||
|
|
5d385475ee | ||
|
|
74e4ea4ccc | ||
|
|
ffe9175177 | ||
|
|
7ea634f7e0 | ||
|
|
c2dca55d7d | ||
|
|
ebbaaf1a17 | ||
|
|
ad4646255d | ||
|
|
2fa44c2485 | ||
|
|
fdf63a4471 | ||
|
|
2ca61b29d8 | ||
|
|
78470bcd4d | ||
|
|
8ae706833d | ||
|
|
cc6af47b61 | ||
|
|
80947b5724 | ||
|
|
13f2be7b1a | ||
|
|
553c3b8c9f | ||
|
|
7d7edf46a6 | ||
|
|
993eae423e | ||
|
|
2c93d2f909 | ||
|
|
6305a44e58 | ||
|
|
03a4cd8d9a | ||
|
|
687cd8ebae | ||
|
|
95c3340e75 | ||
|
|
436c33fcf3 | ||
|
|
e364b6c466 | ||
|
|
9396c31e13 | ||
|
|
caed16fa09 | ||
|
|
bcbccc6eec | ||
|
|
a8682c5d39 | ||
|
|
fc31d47bee | ||
|
|
5a0d62cab0 | ||
|
|
30efb73008 | ||
|
|
8a89fe5c19 | ||
|
|
e53cd07fcc | ||
|
|
1404cd6aa1 | ||
|
|
cf0958f89b | ||
|
|
fd89baef7e | ||
|
|
b3af0c840b | ||
|
|
3fc876cd7b | ||
|
|
b61a1f7b30 | ||
|
|
3e7b60c12d | ||
|
|
51d00bc794 | ||
|
|
f8f6a7e108 | ||
|
|
96fb6e6a66 | ||
|
|
cc86659203 | ||
|
|
85aaa37c08 | ||
|
|
16c7a35584 | ||
|
|
61443a72c2 | ||
|
|
492b3c94cb | ||
|
|
d5b47b8fdf | ||
|
|
30663d3e86 | ||
|
|
40ba2f33d1 | ||
|
|
3a15e3ed23 | ||
|
|
ad243becbe | ||
|
|
501f2eab7a | ||
|
|
648c74d243 | ||
|
|
f4595bc7b7 | ||
|
|
eadee3e5b9 | ||
|
|
c9c7964b7e | ||
|
|
60e84e7350 | ||
|
|
fd06f0f345 | ||
|
|
643fcf4465 | ||
|
|
7d6a75b342 | ||
|
|
596404f3aa | ||
|
|
9fd8eaa95d | ||
|
|
bea959c7b7 | ||
|
|
b2f03f45ea | ||
|
|
3e9ff78b94 | ||
|
|
29ed80aa86 | ||
|
|
da489a11d4 | ||
|
|
f173e45ae9 | ||
|
|
e4b1f89996 | ||
|
|
0c9e14dcce | ||
|
|
bf6d688157 | ||
|
|
4205776b85 | ||
|
|
e77ff99ede | ||
|
|
6e3cf7f12b | ||
|
|
38c0abffce | ||
|
|
3b7d703484 | ||
|
|
d14a60fe24 | ||
|
|
da65c869b5 | ||
|
|
76fbfe9953 | ||
|
|
bfade89ec2 | ||
|
|
a818cfd87b | ||
|
|
653777a522 | ||
|
|
1ad3df4768 | ||
|
|
6323db8e78 | ||
|
|
a3c8f7fa8c | ||
|
|
dfbba63a34 | ||
|
|
5beb93de84 | ||
|
|
e17e96e3c5 | ||
|
|
e0183475e0 | ||
|
|
a2af8bdebd | ||
|
|
265f709647 | ||
|
|
b2a9318a1e | ||
|
|
b3e2e22b2a | ||
|
|
c571cd8513 | ||
|
|
8c713c1af4 | ||
|
|
539c115023 | ||
|
|
8e7ea470cf | ||
|
|
222baf4ccb | ||
|
|
1627e828d7 | ||
|
|
4070ebda88 | ||
|
|
b613ac489e | ||
|
|
0e0ca09ddc | ||
|
|
e62b0e2234 | ||
|
|
06ab9cd1ed | ||
|
|
97aa4e8550 | ||
|
|
e18a9c95b8 | ||
|
|
b959bebdfc | ||
|
|
02ade1a34c | ||
|
|
106c4b0af6 | ||
|
|
54d2eee6d6 | ||
|
|
09fef2b26e | ||
|
|
44c8cd2e8f | ||
|
|
78b6204f9e | ||
|
|
cf98237186 | ||
|
|
fd96b01b0e | ||
|
|
6a1fb46d48 | ||
|
|
7acb079403 | ||
|
|
0df31cf585 | ||
|
|
83b2fc245d | ||
|
|
e079583ab4 | ||
|
|
cfd5e5e4d4 | ||
|
|
576cf73add | ||
|
|
2297ae3e64 | ||
|
|
cc60ec8d3c | ||
|
|
b5b349dbd6 | ||
|
|
35916f0869 | ||
|
|
3eb59ba5a2 | ||
|
|
5d6ae34753 | ||
|
|
ea818a7f6f | ||
|
|
78ccc20545 |
@@ -2,5 +2,5 @@
|
||||
|
||||
# build artifacts
|
||||
/bundles/
|
||||
/cmd/dockerd/winresources/winres.json
|
||||
/cmd/dockerd/*.syso
|
||||
/cli/winresources/dockerd/winres.json
|
||||
/cli/winresources/dockerd/*.syso
|
||||
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1 +1,3 @@
|
||||
Dockerfile* linguist-language=Dockerfile
|
||||
vendor.mod linguist-language=Go-Module
|
||||
vendor.sum linguist-language=Go-Checksums
|
||||
|
||||
224
.github/copilot-instructions.md
vendored
224
.github/copilot-instructions.md
vendored
@@ -1,224 +0,0 @@
|
||||
# Moby Project Development Guide
|
||||
|
||||
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
|
||||
|
||||
## Critical Build and Test Environment Constraints
|
||||
|
||||
**IMPORTANT LIMITATIONS**: The development environment has significant constraints that prevent full Docker-based development container usage:
|
||||
- Docker container builds fail due to SSL certificate verification issues when downloading external dependencies
|
||||
- Integration tests require Docker daemon access which may not be available
|
||||
- Some validation tools (shfmt, gotestsum, golangci-lint) are not installed in the base environment
|
||||
- Privileged operations (chown, mount, network namespaces) are restricted
|
||||
|
||||
**DO NOT attempt the following**:
|
||||
- `make build` or `make shell` (Docker container build will fail)
|
||||
- Full integration test suites without Docker daemon access
|
||||
- Commands requiring privileged operations or Docker-in-Docker
|
||||
|
||||
## Working Effectively
|
||||
|
||||
### Bootstrap and Basic Build (WORKING METHODS)
|
||||
```bash
|
||||
# Navigate to repository
|
||||
cd /path/to/moby
|
||||
|
||||
# Download Go dependencies - takes 5-10 seconds
|
||||
go mod download
|
||||
|
||||
# Build main binaries directly with Go (RECOMMENDED)
|
||||
time go build ./cmd/dockerd # ~6-7 seconds, produces dockerd binary
|
||||
time go build ./cmd/docker-proxy # ~0.3 seconds, produces docker-proxy binary
|
||||
|
||||
# Verify binaries work
|
||||
./dockerd --version # Should show version info
|
||||
```
|
||||
|
||||
### Unit Testing
|
||||
```bash
|
||||
# Run unit tests for specific packages (FASTEST - ~1 second)
|
||||
time go test -short ./pkg/...
|
||||
|
||||
# Run with specific test directory
|
||||
TESTDIRS='./pkg/...' go test -short $TESTDIRS
|
||||
|
||||
# Run specific tests with timeout
|
||||
go test -short -timeout=5m ./pkg/authorization
|
||||
|
||||
# NEVER CANCEL: Full unit test suite can take 4+ minutes
|
||||
# Note: Many tests fail due to environment constraints (expected)
|
||||
time go test -short ./... # Takes ~4 minutes, set timeout to 10+ minutes
|
||||
```
|
||||
|
||||
### Validation and Linting
|
||||
```bash
|
||||
# Format checking (takes ~2 seconds, mostly clean except vendor/)
|
||||
gofmt -l .
|
||||
|
||||
# Go vet validation (takes ~1 second per package)
|
||||
go vet ./cmd/dockerd
|
||||
go vet ./pkg/...
|
||||
|
||||
# YAML linting (works but shows many style violations - takes ~40 seconds)
|
||||
yamllint . # NEVER CANCEL: Set timeout to 60+ minutes
|
||||
|
||||
# Check imports and basic structure
|
||||
go list -f '{{ join .Deps "\n" }}' ./cmd/dockerd | head -10
|
||||
```
|
||||
|
||||
## Manual Validation Scenarios
|
||||
|
||||
**ALWAYS test these scenarios after making changes**:
|
||||
|
||||
1. **Binary Build Validation**:
|
||||
```bash
|
||||
# Clean previous builds
|
||||
rm -f dockerd docker-proxy
|
||||
|
||||
# Build and verify
|
||||
go build ./cmd/dockerd && ./dockerd --version
|
||||
go build ./cmd/docker-proxy
|
||||
```
|
||||
|
||||
2. **Unit Test Validation** (for code in pkg/):
|
||||
```bash
|
||||
# Test specific package you modified
|
||||
go test -v ./pkg/[modified-package]
|
||||
|
||||
# Test all pkg packages (limited but fast)
|
||||
go test -short ./pkg/...
|
||||
```
|
||||
|
||||
3. **Code Quality Validation**:
|
||||
```bash
|
||||
# Check formatting
|
||||
gofmt -l . | grep -v vendor | head -5
|
||||
|
||||
# Verify imports work
|
||||
go list ./cmd/dockerd
|
||||
go list ./pkg/...
|
||||
```
|
||||
|
||||
## Repository Structure and Navigation
|
||||
|
||||
### Key Directories
|
||||
- `cmd/dockerd/` - Main Docker daemon binary
|
||||
- `cmd/docker-proxy/` - Docker proxy binary
|
||||
- `daemon/` - Core daemon implementation
|
||||
- `api/` - API definitions and client code
|
||||
- `client/` - Docker client library
|
||||
- `pkg/` - Shared packages (safest for testing)
|
||||
- `integration/` - Integration tests (require Docker daemon)
|
||||
- `hack/` - Build scripts and validation tools
|
||||
- `.github/workflows/` - CI/CD pipeline definitions
|
||||
|
||||
### Build System
|
||||
- `Makefile` - Main build interface (Docker-based, mostly non-functional in this environment)
|
||||
- `hack/make.sh` - Build script (requires Docker container)
|
||||
- `hack/test/unit` - Unit test script (requires gotestsum)
|
||||
- `hack/validate/` - Validation scripts (many require special tools)
|
||||
|
||||
### Go Modules
|
||||
```bash
|
||||
# Main module
|
||||
cat go.mod # Shows github.com/moby/moby/v2
|
||||
|
||||
# Submodules
|
||||
ls */go.mod # api/go.mod, client/go.mod, man/go.mod
|
||||
```
|
||||
|
||||
## Common Validation Tasks
|
||||
|
||||
### Pre-commit Validation (USE THESE)
|
||||
```bash
|
||||
# Quick validation workflow (~10 seconds total)
|
||||
gofmt -l . | grep -v vendor | head -5 # Check formatting
|
||||
go vet ./cmd/dockerd # Vet main package
|
||||
go build ./cmd/dockerd # Ensure it builds
|
||||
go test -short ./pkg/... # Test shared packages
|
||||
|
||||
# Extended validation (~4 minutes total)
|
||||
go test -short ./... # NEVER CANCEL: Set timeout to 10+ minutes
|
||||
```
|
||||
|
||||
### Code Changes Validation
|
||||
```bash
|
||||
# After modifying daemon code
|
||||
go build ./cmd/dockerd && ./dockerd --version
|
||||
|
||||
# After modifying pkg code
|
||||
go test -v ./pkg/[modified-package]
|
||||
|
||||
# After modifying client code
|
||||
cd client && go test ./...
|
||||
cd ..
|
||||
|
||||
# After modifying API definitions
|
||||
cd api && go test ./...
|
||||
cd ..
|
||||
```
|
||||
|
||||
## Timing Expectations and Timeouts
|
||||
|
||||
**CRITICAL**: Always set appropriate timeouts and NEVER CANCEL these operations:
|
||||
|
||||
- `go mod download`: 5-10 seconds (rarely needed, cached)
|
||||
- `go build ./cmd/dockerd`: 6-7 seconds (NEVER CANCEL - set 2+ minute timeout)
|
||||
- `go build ./cmd/docker-proxy`: 0.3 seconds
|
||||
- `go test -short ./pkg/...`: 1 second (cached), 5-10 seconds (first run)
|
||||
- `go test -short ./...`: 4+ minutes (NEVER CANCEL - set 10+ minute timeout)
|
||||
- `gofmt -l .`: 2 seconds
|
||||
- `yamllint .`: 40+ seconds (NEVER CANCEL - set 60+ minute timeout)
|
||||
|
||||
**WARNING**: Do not attempt these operations (they will fail):
|
||||
- `make build`: Fails due to Docker build issues (~15+ minutes timeout, will fail)
|
||||
- `make test`: Requires Docker container
|
||||
- Integration tests: Require Docker daemon access
|
||||
|
||||
## Architectural Overview
|
||||
|
||||
Moby is a container platform written in Go with these key components:
|
||||
|
||||
- **dockerd**: Main daemon process managing containers, images, networks
|
||||
- **docker-proxy**: Network proxy for container port mapping
|
||||
- **containerd**: Container runtime (external dependency)
|
||||
- **runc**: Low-level container runtime (external dependency)
|
||||
|
||||
### API Structure
|
||||
- REST API defined in `api/` directory
|
||||
- Client library in `client/` directory
|
||||
- Daemon implementation in `daemon/` directory
|
||||
- Shared utilities in `pkg/` directory
|
||||
|
||||
### Testing Strategy
|
||||
- Unit tests: Test individual packages and functions
|
||||
- Integration tests: Test API interactions (require Docker daemon)
|
||||
- End-to-end tests: Test complete workflows (require full environment)
|
||||
|
||||
## Environment Setup Notes
|
||||
|
||||
This repository uses:
|
||||
- **Go 1.24.6** (verified working)
|
||||
- **Docker 28.0.4** (CLI available, daemon access limited)
|
||||
- **Module system**: Multiple Go modules (main, api, client, man)
|
||||
- **Build tags**: Uses netgo, osusergo, static_build tags
|
||||
- **Cross-compilation**: Supports multiple platforms
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Issues
|
||||
- If `go build` fails: Check Go version, run `go mod download`
|
||||
- If tests fail with permission errors: Expected in restricted environment
|
||||
- If Docker commands fail: Use Go build commands instead
|
||||
|
||||
### Test Issues
|
||||
- Network-related test failures: Expected (namespace restrictions)
|
||||
- Permission errors: Expected (privilege restrictions)
|
||||
- Docker API errors: Expected (daemon not accessible)
|
||||
|
||||
### Working Around Limitations
|
||||
- Use `go test -short` to skip long-running tests
|
||||
- Focus on `./pkg/...` tests which have fewer dependencies
|
||||
- Use `go build` directly instead of Make targets
|
||||
- Validate formatting with `gofmt` instead of full validation suite
|
||||
|
||||
Always validate your changes work with the core Go commands before submitting.
|
||||
2
.github/workflows/.dco.yml
vendored
2
.github/workflows/.dco.yml
vendored
@@ -16,7 +16,7 @@ on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
ALPINE_VERSION: "3.22"
|
||||
ALPINE_VERSION: "3.21"
|
||||
|
||||
jobs:
|
||||
run:
|
||||
|
||||
45
.github/workflows/.test-prepare.yml
vendored
Normal file
45
.github/workflows/.test-prepare.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# reusable workflow
|
||||
name: .test-prepare
|
||||
|
||||
# TODO: hide reusable workflow from the UI. Tracked in https://github.com/community/community/discussions/12025
|
||||
|
||||
# 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
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
matrix:
|
||||
description: Test matrix
|
||||
value: ${{ jobs.run.outputs.matrix }}
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
outputs:
|
||||
matrix: ${{ steps.set.outputs.matrix }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Create matrix
|
||||
id: set
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
let matrix = ['graphdriver'];
|
||||
if ("${{ contains(github.event.pull_request.labels.*.name, 'containerd-integration') || github.event_name != 'pull_request' }}" == "true") {
|
||||
matrix.push('snapshotter');
|
||||
}
|
||||
await core.group(`Set matrix`, async () => {
|
||||
core.info(`matrix: ${JSON.stringify(matrix)}`);
|
||||
core.setOutput('matrix', JSON.stringify(matrix));
|
||||
});
|
||||
4
.github/workflows/.test-unit.yml
vendored
4
.github/workflows/.test-unit.yml
vendored
@@ -16,7 +16,7 @@ on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
GOTESTLIST_VERSION: v0.3.1
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
@@ -106,7 +106,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
56
.github/workflows/.test.yml
vendored
56
.github/workflows/.test.yml
vendored
@@ -21,13 +21,13 @@ on:
|
||||
default: "graphdriver"
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
GOTESTLIST_VERSION: v0.3.1
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
ITG_CLI_MATRIX_SIZE: 6
|
||||
DOCKER_EXPERIMENTAL: 1
|
||||
DOCKER_GRAPHDRIVER: ${{ inputs.storage == 'snapshotter' && 'overlayfs' || 'overlay2' }}
|
||||
TEST_INTEGRATION_USE_GRAPHDRIVER: ${{ inputs.storage == 'graphdriver' && '1' || '' }}
|
||||
TEST_INTEGRATION_USE_SNAPSHOTTER: ${{ inputs.storage == 'snapshotter' && '1' || '' }}
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
SETUP_BUILDKIT_IMAGE: moby/buildkit:latest
|
||||
|
||||
@@ -144,9 +144,7 @@ jobs:
|
||||
// { os: 'ubuntu-24.04', mode: 'rootless-systemd' }, // FIXME: https://github.com/moby/moby/issues/44084
|
||||
];
|
||||
if ("${{ inputs.storage }}" == "snapshotter") {
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'iptables+firewalld' });
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'nftables' });
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'nftables+firewalld' });
|
||||
includes.push({ os: 'ubuntu-24.04', mode: 'firewalld' });
|
||||
}
|
||||
await core.group(`Set matrix`, async () => {
|
||||
core.info(`matrix: ${JSON.stringify(includes)}`);
|
||||
@@ -192,9 +190,6 @@ jobs:
|
||||
echo "FIREWALLD=true" >> $GITHUB_ENV
|
||||
CACHE_DEV_SCOPE="${CACHE_DEV_SCOPE}firewalld"
|
||||
fi
|
||||
if [[ "${{ matrix.mode }}" == *"nftables"* ]]; then
|
||||
echo "DOCKER_FIREWALL_BACKEND=nftables" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "CACHE_DEV_SCOPE=${CACHE_DEV_SCOPE}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
@@ -270,7 +265,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -302,7 +297,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Install gotestlist
|
||||
run:
|
||||
@@ -333,43 +328,19 @@ jobs:
|
||||
// 'include' with other matrix variables that aren't part of the
|
||||
// include items.
|
||||
// Moreover, since the goal is to run only relevant tests with
|
||||
// firewalld/nftables enabled to minimize the number of CI jobs, we
|
||||
// firewalld enabled to minimize the number of CI jobs, we
|
||||
// statically define the list of test suites that we want to run.
|
||||
if ("${{ inputs.storage }}" == "snapshotter") {
|
||||
matrix.include.push({
|
||||
'mode': 'iptables+firewalld',
|
||||
'mode': 'firewalld',
|
||||
'test': 'DockerCLINetworkSuite|DockerCLIPortSuite|DockerDaemonSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'iptables+firewalld',
|
||||
'mode': 'firewalld',
|
||||
'test': 'DockerSwarmSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'iptables+firewalld',
|
||||
'test': 'DockerNetworkSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerCLINetworkSuite|DockerCLIPortSuite|DockerDaemonSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerSwarmSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables',
|
||||
'test': 'DockerNetworkSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables+firewalld',
|
||||
'test': 'DockerCLINetworkSuite|DockerCLIPortSuite|DockerDaemonSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables+firewalld',
|
||||
'test': 'DockerSwarmSuite'
|
||||
});
|
||||
matrix.include.push({
|
||||
'mode': 'nftables+firewalld',
|
||||
'mode': 'firewalld',
|
||||
'test': 'DockerNetworkSuite'
|
||||
});
|
||||
}
|
||||
@@ -409,9 +380,6 @@ jobs:
|
||||
echo "FIREWALLD=true" >> $GITHUB_ENV
|
||||
CACHE_DEV_SCOPE="${CACHE_DEV_SCOPE}firewalld"
|
||||
fi
|
||||
if [[ "${{ matrix.mode }}" == *"nftables"* ]]; then
|
||||
echo "DOCKER_FIREWALL_BACKEND=nftables" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "CACHE_DEV_SCOPE=${CACHE_DEV_SCOPE}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
@@ -469,7 +437,7 @@ jobs:
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-${{ env.TESTREPORTS_NAME }}
|
||||
name: test-reports-integration-cli-${{ inputs.storage }}-${{ env.TESTREPORTS_NAME }}
|
||||
path: /tmp/reports/*
|
||||
retention-days: 1
|
||||
|
||||
@@ -486,13 +454,13 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/reports
|
||||
pattern: test-reports-integration-cli-${{ inputs.storage }}-${{ matrix.mode }}-*
|
||||
pattern: test-reports-integration-cli-${{ inputs.storage }}-*
|
||||
merge-multiple: true
|
||||
-
|
||||
name: Install teststat
|
||||
|
||||
56
.github/workflows/.windows.yml
vendored
56
.github/workflows/.windows.yml
vendored
@@ -28,7 +28,7 @@ on:
|
||||
default: false
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
GOTESTLIST_VERSION: v0.3.1
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
WINDOWS_BASE_IMAGE: mcr.microsoft.com/windows/servercore
|
||||
@@ -70,18 +70,6 @@ jobs:
|
||||
} ElseIf ("${{ inputs.os }}" -eq "windows-2022") {
|
||||
echo "WINDOWS_BASE_IMAGE_TAG=${{ env.WINDOWS_BASE_TAG_2022 }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
|
||||
}
|
||||
-
|
||||
name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~\AppData\Local\go-build
|
||||
~\go\pkg\mod
|
||||
${{ github.workspace }}\go-build
|
||||
${{ env.GOPATH }}\pkg\mod
|
||||
key: ${{ inputs.os }}-${{ github.job }}-${{ hashFiles('**/vendor.sum') }}
|
||||
restore-keys: |
|
||||
${{ inputs.os }}-${{ github.job }}-
|
||||
-
|
||||
name: Docker info
|
||||
run: |
|
||||
@@ -98,8 +86,6 @@ jobs:
|
||||
name: Build binaries
|
||||
run: |
|
||||
& docker run --name ${{ env.TEST_CTN_NAME }} -e "DOCKER_GITCOMMIT=${{ github.sha }}" `
|
||||
-v "${{ github.workspace }}\go-build:C:\Users\ContainerAdministrator\AppData\Local\go-build" `
|
||||
-v "${{ github.workspace }}\go\pkg\mod:C:\gopath\pkg\mod" `
|
||||
${{ env.TEST_IMAGE_NAME }} hack\make.ps1 -Daemon -Client
|
||||
-
|
||||
name: Copy artifacts
|
||||
@@ -149,18 +135,6 @@ jobs:
|
||||
} ElseIf ("${{ inputs.os }}" -eq "windows-2022") {
|
||||
echo "WINDOWS_BASE_IMAGE_TAG=${{ env.WINDOWS_BASE_TAG_2022 }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
|
||||
}
|
||||
-
|
||||
name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~\AppData\Local\go-build
|
||||
~\go\pkg\mod
|
||||
${{ github.workspace }}\go-build
|
||||
${{ env.GOPATH }}\pkg\mod
|
||||
key: ${{ inputs.os }}-${{ github.job }}-${{ hashFiles('**/vendor.sum') }}
|
||||
restore-keys: |
|
||||
${{ inputs.os }}-${{ github.job }}-
|
||||
-
|
||||
name: Docker info
|
||||
run: |
|
||||
@@ -177,8 +151,6 @@ jobs:
|
||||
name: Test
|
||||
run: |
|
||||
& docker run --name ${{ env.TEST_CTN_NAME }} -e "DOCKER_GITCOMMIT=${{ github.sha }}" `
|
||||
-v "${{ github.workspace }}\go-build:C:\Users\ContainerAdministrator\AppData\Local\go-build" `
|
||||
-v "${{ github.workspace }}\go\pkg\mod:C:\gopath\pkg\mod" `
|
||||
-v "${{ env.GOPATH }}\src\github.com\docker\docker\bundles:C:\gopath\src\github.com\docker\docker\bundles" `
|
||||
${{ env.TEST_IMAGE_NAME }} hack\make.ps1 -TestUnit
|
||||
-
|
||||
@@ -212,7 +184,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -242,7 +214,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Install gotestlist
|
||||
run:
|
||||
@@ -295,6 +267,12 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: ${{ env.GOPATH }}/src/github.com/docker/docker
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache: false
|
||||
-
|
||||
name: Set up Jaeger
|
||||
run: |
|
||||
@@ -364,10 +342,10 @@ jobs:
|
||||
"--exec-root=$env:TEMP\moby-exec", `
|
||||
"--pidfile=$env:TEMP\docker.pid", `
|
||||
"--register-service"
|
||||
If ("${{ inputs.storage }}" -eq "graphdriver") {
|
||||
If ("${{ inputs.storage }}" -eq "snapshotter") {
|
||||
# Make the env-var visible to the service-managed dockerd, as there's no CLI flag for this option.
|
||||
& reg add "HKLM\SYSTEM\CurrentControlSet\Services\docker" /v Environment /t REG_MULTI_SZ /s '@' /d TEST_INTEGRATION_USE_GRAPHDRIVER=1
|
||||
echo "TEST_INTEGRATION_USE_GRAPHDRIVER=1" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
|
||||
& reg add "HKLM\SYSTEM\CurrentControlSet\Services\docker" /v Environment /t REG_MULTI_SZ /s '@' /d TEST_INTEGRATION_USE_SNAPSHOTTER=1
|
||||
echo "TEST_INTEGRATION_USE_SNAPSHOTTER=1" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
|
||||
}
|
||||
Write-Host "Starting service"
|
||||
Start-Service -Name docker
|
||||
@@ -426,12 +404,6 @@ jobs:
|
||||
& "${{ env.BIN_OUT }}\docker" images
|
||||
env:
|
||||
DOCKER_HOST: npipe:////./pipe/docker_engine
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
-
|
||||
name: Test integration
|
||||
if: matrix.test == './...'
|
||||
@@ -439,6 +411,7 @@ jobs:
|
||||
.\hack\make.ps1 -TestIntegration
|
||||
env:
|
||||
DOCKER_HOST: npipe:////./pipe/docker_engine
|
||||
GO111MODULE: "off"
|
||||
TEST_CLIENT_BINARY: ${{ env.BIN_OUT }}\docker
|
||||
-
|
||||
name: Test integration-cli
|
||||
@@ -447,6 +420,7 @@ jobs:
|
||||
.\hack\make.ps1 -TestIntegrationCli
|
||||
env:
|
||||
DOCKER_HOST: npipe:////./pipe/docker_engine
|
||||
GO111MODULE: "off"
|
||||
TEST_CLIENT_BINARY: ${{ env.BIN_OUT }}\docker
|
||||
INTEGRATION_TESTRUN: ${{ matrix.test }}
|
||||
-
|
||||
@@ -523,7 +497,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
22
.github/workflows/arm64.yml
vendored
22
.github/workflows/arm64.yml
vendored
@@ -23,7 +23,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
TESTSTAT_VERSION: v0.1.25
|
||||
DESTDIR: ./build
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
@@ -37,6 +37,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
strategy:
|
||||
@@ -70,6 +71,7 @@ jobs:
|
||||
build-dev:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
steps:
|
||||
@@ -87,12 +89,13 @@ jobs:
|
||||
targets: dev
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=dev-arm64
|
||||
*.cache-to=type=gha,scope=dev-arm64,mode=max
|
||||
*.cache-to=type=gha,scope=dev-arm64
|
||||
*.output=type=cacheonly
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-dev
|
||||
steps:
|
||||
@@ -109,6 +112,9 @@ jobs:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
-
|
||||
name: Build dev image
|
||||
uses: docker/bake-action@v6
|
||||
@@ -150,7 +156,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
if: always() && (github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only'))
|
||||
needs:
|
||||
- test-unit
|
||||
steps:
|
||||
@@ -159,7 +165,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -179,6 +185,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-dev
|
||||
steps:
|
||||
@@ -198,6 +205,9 @@ jobs:
|
||||
version: ${{ env.SETUP_BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.SETUP_BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
-
|
||||
name: Build dev image
|
||||
uses: docker/bake-action@v6
|
||||
@@ -249,7 +259,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ github.event_name != 'pull_request' }}
|
||||
if: always()
|
||||
if: always() && (github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only'))
|
||||
needs:
|
||||
- test-integration
|
||||
steps:
|
||||
@@ -258,7 +268,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: Download reports
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
11
.github/workflows/bin-image.yml
vendored
11
.github/workflows/bin-image.yml
vendored
@@ -42,6 +42,7 @@ jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
outputs:
|
||||
platforms: ${{ steps.platforms.outputs.matrix }}
|
||||
steps:
|
||||
@@ -58,15 +59,13 @@ jobs:
|
||||
### versioning strategy
|
||||
## push semver tag v23.0.0
|
||||
# moby/moby-bin:23.0.0
|
||||
# moby/moby-bin:23.0
|
||||
# moby/moby-bin:23
|
||||
# moby/moby-bin:latest
|
||||
## push semver prerelease tag v23.0.0-beta.1
|
||||
# moby/moby-bin:23.0.0-beta.1
|
||||
## push on master
|
||||
# moby/moby-bin:master
|
||||
## push on 28.x branch
|
||||
# moby/moby-bin:28.x
|
||||
## push on 23.0 branch
|
||||
# moby/moby-bin:23.0
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=ref,event=branch
|
||||
@@ -96,10 +95,10 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && (github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only')) }}
|
||||
needs:
|
||||
- validate-dco
|
||||
- prepare
|
||||
if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -172,9 +171,9 @@ jobs:
|
||||
merge:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 40 # guardrails timeout for the whole job
|
||||
if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' && github.repository == 'moby/moby' }}
|
||||
needs:
|
||||
- build
|
||||
if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.event_name != 'pull_request' && github.repository == 'moby/moby'
|
||||
steps:
|
||||
-
|
||||
name: Download meta bake definition
|
||||
|
||||
30
.github/workflows/buildkit.yml
vendored
30
.github/workflows/buildkit.yml
vendored
@@ -23,7 +23,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
DESTDIR: ./build
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
SETUP_BUILDKIT_IMAGE: moby/buildkit:latest
|
||||
@@ -35,6 +35,7 @@ jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
steps:
|
||||
@@ -62,6 +63,7 @@ jobs:
|
||||
test-linux:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-linux
|
||||
env:
|
||||
@@ -106,7 +108,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
-
|
||||
name: BuildKit ref
|
||||
run: |
|
||||
@@ -166,6 +168,7 @@ jobs:
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 120
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
env:
|
||||
@@ -188,6 +191,7 @@ jobs:
|
||||
- name: Env
|
||||
run: |
|
||||
Get-ChildItem Env: | Out-String
|
||||
|
||||
- name: Moby - Init
|
||||
run: |
|
||||
New-Item -ItemType "directory" -Path "${{ github.workspace }}\go-build"
|
||||
@@ -198,18 +202,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~\AppData\Local\go-build
|
||||
~\go\pkg\mod
|
||||
${{ github.workspace }}\go-build
|
||||
${{ env.GOPATH }}\pkg\mod
|
||||
key: ${{ inputs.os }}-${{ github.job }}-${{ hashFiles('**/vendor.sum') }}
|
||||
restore-keys: |
|
||||
${{ inputs.os }}-${{ github.job }}-
|
||||
cache: false
|
||||
|
||||
- name: Docker info
|
||||
run: |
|
||||
@@ -265,6 +258,7 @@ jobs:
|
||||
test-windows:
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-windows
|
||||
env:
|
||||
@@ -308,22 +302,27 @@ jobs:
|
||||
disabledFeatures="${disabledFeatures},merge_diff"
|
||||
fi
|
||||
echo "BUILDKIT_TEST_DISABLE_FEATURES=${disabledFeatures}" >> $GITHUB_ENV
|
||||
|
||||
- name: Expose GitHub Runtime
|
||||
uses: crazy-max/ghaction-github-runtime@v3
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: moby
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache-dependency-path: vendor.sum
|
||||
cache: false
|
||||
|
||||
- name: BuildKit ref
|
||||
shell: bash
|
||||
run: |
|
||||
echo "$(./hack/buildkit-ref)" >> $GITHUB_ENV
|
||||
working-directory: moby
|
||||
|
||||
- name: Checkout BuildKit ${{ env.BUILDKIT_REF }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -358,6 +357,7 @@ jobs:
|
||||
testFlags="${testFlags} --run=TestIntegration/$testSliceOffset.*/worker=${{ matrix.worker }}"
|
||||
fi
|
||||
echo "TESTFLAGS=${testFlags}" >> $GITHUB_ENV
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -67,6 +67,7 @@ jobs:
|
||||
prepare-cross:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
outputs:
|
||||
@@ -89,6 +90,7 @@ jobs:
|
||||
cross:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
- prepare-cross
|
||||
@@ -128,6 +130,7 @@ jobs:
|
||||
govulncheck:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
# Always run security checks, even with 'ci/validate-only' label
|
||||
permissions:
|
||||
# required to write sarif report
|
||||
security-events: write
|
||||
@@ -157,6 +160,7 @@ jobs:
|
||||
|
||||
build-dind:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
steps:
|
||||
|
||||
17
.github/workflows/codeql.yml
vendored
17
.github/workflows/codeql.yml
vendored
@@ -32,6 +32,9 @@ on:
|
||||
# * * * * *
|
||||
- cron: '0 9 * * 4'
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.9"
|
||||
|
||||
jobs:
|
||||
codeql:
|
||||
runs-on: ubuntu-24.04
|
||||
@@ -46,10 +49,20 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- name: Update Go
|
||||
# CodeQL 2.16.4's auto-build added support for multi-module repositories,
|
||||
# and is trying to be smart by searching for modules in every directory,
|
||||
# including vendor directories. If no module is found, it's creating one
|
||||
# which is ... not what we want, so let's give it a "go.mod".
|
||||
# see: https://github.com/docker/cli/pull/4944#issuecomment-2002034698
|
||||
- name: Create go.mod
|
||||
run: |
|
||||
ln -s vendor.mod go.mod
|
||||
ln -s vendor.sum go.sum
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24.6"
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
cache: false
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
|
||||
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@@ -23,7 +23,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24.6"
|
||||
GO_VERSION: "1.24.9"
|
||||
GIT_PAGER: "cat"
|
||||
PAGER: "cat"
|
||||
SETUP_BUILDX_VERSION: edge
|
||||
@@ -44,6 +44,7 @@ jobs:
|
||||
mode:
|
||||
- ""
|
||||
- systemd
|
||||
- firewalld
|
||||
steps:
|
||||
-
|
||||
name: Prepare
|
||||
@@ -65,10 +66,11 @@ jobs:
|
||||
targets: dev
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=dev${{ matrix.mode }}
|
||||
*.cache-to=type=gha,scope=dev${{ matrix.mode }},mode=max
|
||||
*.cache-to=type=gha,scope=dev${{ matrix.mode }}
|
||||
*.output=type=cacheonly
|
||||
|
||||
test:
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-dev
|
||||
- validate-dco
|
||||
@@ -84,6 +86,7 @@ jobs:
|
||||
storage: ${{ matrix.storage }}
|
||||
|
||||
test-unit:
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- build-dev
|
||||
- validate-dco
|
||||
@@ -153,6 +156,7 @@ jobs:
|
||||
smoke-prepare:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- validate-dco
|
||||
outputs:
|
||||
@@ -175,6 +179,7 @@ jobs:
|
||||
smoke:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20 # guardrails timeout for the whole job
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- smoke-prepare
|
||||
strategy:
|
||||
|
||||
9
.github/workflows/validate-pr.yml
vendored
9
.github/workflows/validate-pr.yml
vendored
@@ -14,20 +14,15 @@ on:
|
||||
types: [opened, edited, labeled, unlabeled, synchronize]
|
||||
|
||||
jobs:
|
||||
check-labels:
|
||||
check-area-label:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 120 # guardrails timeout for the whole job
|
||||
steps:
|
||||
- name: Missing `area/` label
|
||||
if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/')
|
||||
if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/')
|
||||
run: |
|
||||
echo "::error::Every PR with an 'impact/*' label should also have an 'area/*' label"
|
||||
exit 1
|
||||
- name: Missing `kind/` label
|
||||
if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'kind/')
|
||||
run: |
|
||||
echo "::error::Every PR with an 'impact/*' label should also have a 'kind/*' label"
|
||||
exit 1
|
||||
- name: OK
|
||||
run: exit 0
|
||||
|
||||
|
||||
12
.github/workflows/windows-2022.yml
vendored
12
.github/workflows/windows-2022.yml
vendored
@@ -22,15 +22,21 @@ jobs:
|
||||
validate-dco:
|
||||
uses: ./.github/workflows/.dco.yml
|
||||
|
||||
test-prepare:
|
||||
uses: ./.github/workflows/.test-prepare.yml
|
||||
needs:
|
||||
- validate-dco
|
||||
|
||||
run:
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- test-prepare
|
||||
uses: ./.github/workflows/.windows.yml
|
||||
secrets: inherit
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
storage:
|
||||
- graphdriver
|
||||
- snapshotter
|
||||
storage: ${{ fromJson(needs.test-prepare.outputs.matrix) }}
|
||||
with:
|
||||
os: windows-2022
|
||||
storage: ${{ matrix.storage }}
|
||||
|
||||
12
.github/workflows/windows-2025.yml
vendored
12
.github/workflows/windows-2025.yml
vendored
@@ -26,15 +26,21 @@ jobs:
|
||||
validate-dco:
|
||||
uses: ./.github/workflows/.dco.yml
|
||||
|
||||
test-prepare:
|
||||
uses: ./.github/workflows/.test-prepare.yml
|
||||
needs:
|
||||
- validate-dco
|
||||
|
||||
run:
|
||||
if: ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'ci/validate-only') }}
|
||||
needs:
|
||||
- test-prepare
|
||||
uses: ./.github/workflows/.windows.yml
|
||||
secrets: inherit
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
storage:
|
||||
- graphdriver
|
||||
- snapshotter
|
||||
storage: ${{ fromJson(needs.test-prepare.outputs.matrix) }}
|
||||
with:
|
||||
os: windows-2025
|
||||
storage: ${{ matrix.storage }}
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -15,8 +15,8 @@ thumbs.db
|
||||
|
||||
# build artifacts
|
||||
/bundles/
|
||||
/cmd/dockerd/winresources/winres.json
|
||||
/cmd/dockerd/*.syso
|
||||
/cli/winresources/dockerd/*.syso
|
||||
/cli/winresources/dockerd/winres.json
|
||||
|
||||
# ci artifacts
|
||||
*.exe
|
||||
|
||||
@@ -3,7 +3,7 @@ version: "2"
|
||||
run:
|
||||
# prevent golangci-lint from deducting the go version to lint for through go.mod,
|
||||
# which causes it to fallback to go1.17 semantics.
|
||||
go: "1.24.6"
|
||||
go: "1.24.9"
|
||||
concurrency: 2
|
||||
# Only supported with go modules enabled (build flag -mod=vendor only valid when using modules)
|
||||
# modules-download-mode: vendor
|
||||
@@ -69,8 +69,6 @@ linters:
|
||||
desc: Use github.com/moby/sys/userns instead.
|
||||
- pkg: "github.com/tonistiigi/fsutil"
|
||||
desc: The fsutil module does not have a stable API, so we should not have a direct dependency unless necessary.
|
||||
- pkg: "github.com/hashicorp/go-multierror"
|
||||
desc: "Use errors.Join instead"
|
||||
|
||||
dupword:
|
||||
ignore:
|
||||
@@ -105,11 +103,11 @@ linters:
|
||||
msg: Go 1.19 atomic types should be used instead.
|
||||
- pkg: ^regexp$
|
||||
pattern: ^regexp\.MustCompile
|
||||
msg: Use daemon/internal/lazyregexp.New instead.
|
||||
msg: Use internal/lazyregexp.New instead.
|
||||
- pkg: github.com/vishvananda/netlink$
|
||||
pattern: ^netlink\.(Handle\.)?(AddrList|BridgeVlanList|ChainList|ClassList|ConntrackTableList|ConntrackDeleteFilter$|ConntrackDeleteFilters|DevLinkGetDeviceList|DevLinkGetAllPortList|DevlinkGetDeviceParams|FilterList|FouList|GenlFamilyList|GTPPDPList|LinkByName|LinkByAlias|LinkList|LinkSubscribeWithOptions|NeighList$|NeighProxyList|NeighListExecute|NeighSubscribeWithOptions|LinkGetProtinfo|QdiscList|RdmaLinkList|RdmaLinkByName|RdmaLinkDel|RouteList|RouteListFilteredIter|RuleListFiltered$|RouteSubscribeWithOptions|RuleList$|RuleListFiltered|SocketGet|SocketDiagTCPInfo|SocketDiagTCP|SocketDiagUDPInfo|SocketDiagUDP|UnixSocketDiagInfo|UnixSocketDiag|VDPAGetDevConfigList|VDPAGetDevList|VDPAGetMGMTDevList|XfrmPolicyList|XfrmStateList)
|
||||
msg: Use internal nlwrap package for EINTR handling.
|
||||
- pkg: github.com/moby/moby/v2/internal/nlwrap$
|
||||
- pkg: github.com/docker/docker/internal/nlwrap$
|
||||
pattern: ^nlwrap.Handle.(BridgeVlanList|ChainList|ClassList|ConntrackDeleteFilter$|DevLinkGetDeviceList|DevLinkGetAllPortList|DevlinkGetDeviceParams|FilterList|FouList|GenlFamilyList|GTPPDPList|LinkByAlias|LinkSubscribeWithOptions|NeighList$|NeighProxyList|NeighListExecute|NeighSubscribeWithOptions|LinkGetProtinfo|QdiscList|RdmaLinkList|RdmaLinkByName|RdmaLinkDel|RouteListFilteredIter|RuleListFiltered$|RouteSubscribeWithOptions|RuleList$|RuleListFiltered|SocketGet|SocketDiagTCPInfo|SocketDiagTCP|SocketDiagUDPInfo|SocketDiagUDP|UnixSocketDiagInfo|UnixSocketDiag|VDPAGetDevConfigList|VDPAGetDevList|VDPAGetMGMTDevList)
|
||||
msg: Add a wrapper to nlwrap.Handle for EINTR handling and update the list in .golangci.yml.
|
||||
analyze-types: true
|
||||
@@ -206,20 +204,10 @@ linters:
|
||||
max-func-lines: 0
|
||||
|
||||
revive:
|
||||
# Only listed rules are applied
|
||||
# https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md
|
||||
rules:
|
||||
- name: increment-decrement
|
||||
# FIXME make sure all packages have a description. Currently, there's many packages without.
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
- name: redefines-builtin-id
|
||||
- name: superfluous-else
|
||||
arguments:
|
||||
- preserve-scope
|
||||
- name: use-any
|
||||
- name: use-errors-new
|
||||
- name: var-declaration
|
||||
|
||||
staticcheck:
|
||||
checks:
|
||||
@@ -267,6 +255,9 @@ linters:
|
||||
http-status-code: true
|
||||
|
||||
exclusions:
|
||||
paths:
|
||||
- volume/drivers/proxy.go # TODO: this is a generated file but with an invalid header, see https://github.com/moby/moby/pull/46274
|
||||
|
||||
rules:
|
||||
# We prefer to use an "linters.exclusions.rules" so that new "default" exclusions are not
|
||||
# automatically inherited. We can decide whether or not to follow upstream
|
||||
@@ -312,6 +303,11 @@ linters:
|
||||
linters:
|
||||
- staticcheck
|
||||
|
||||
# FIXME(thaJeztah): ignoring these transitional utilities until BuildKit is vendored with https://github.com/moby/moby/pull/49743
|
||||
- text: "SA1019: idtools\\.(ToUserIdentityMapping|FromUserIdentityMapping|IdentityMapping) is deprecated"
|
||||
linters:
|
||||
- staticcheck
|
||||
|
||||
# Ignore "nested context in function literal (fatcontext)" as we intentionally set up tracing on a base-context for tests.
|
||||
# FIXME(thaJeztah): see if there's a more iodiomatic way to do this.
|
||||
- text: 'nested context in function literal'
|
||||
@@ -331,21 +327,18 @@ linters:
|
||||
linters:
|
||||
- forbidigo
|
||||
- text: 'use of `regexp.MustCompile` forbidden'
|
||||
path: "daemon/internal/lazyregexp"
|
||||
linters:
|
||||
- forbidigo
|
||||
- text: 'use of `regexp.MustCompile` forbidden'
|
||||
path: "internal/testutils"
|
||||
path: "internal/lazyregexp"
|
||||
linters:
|
||||
- forbidigo
|
||||
- text: 'use of `regexp.MustCompile` forbidden'
|
||||
path: "libnetwork/cmd/networkdb-test/dbclient"
|
||||
linters:
|
||||
- forbidigo
|
||||
- text: 'use of `regexp.MustCompile` forbidden'
|
||||
path: "registry/"
|
||||
|
||||
# Ignore deprecated disk usage type warnings which will be moved internal to the daemon backend in the next major release.
|
||||
- text: "SA1019: ((buildtypes|build).CacheDiskUsage|(container|containertypes|image|volume|volumetypes).DiskUsage) is deprecated"
|
||||
linters:
|
||||
- forbidigo
|
||||
- staticcheck
|
||||
|
||||
# Log a warning if an exclusion rule is unused.
|
||||
# Default: false
|
||||
|
||||
63
Dockerfile
63
Dockerfile
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.24.6
|
||||
ARG GO_VERSION=1.24.9
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
|
||||
ARG XX_VERSION=1.6.1
|
||||
@@ -10,7 +10,7 @@ ARG XX_VERSION=1.6.1
|
||||
ARG VPNKIT_VERSION=0.6.0
|
||||
|
||||
# DOCKERCLI_VERSION is the version of the CLI to install in the dev-container.
|
||||
ARG DOCKERCLI_VERSION=v28.3.2
|
||||
ARG DOCKERCLI_VERSION=v28.2.2
|
||||
ARG DOCKERCLI_REPOSITORY="https://github.com/docker/cli.git"
|
||||
|
||||
# cli version used for integration-cli tests
|
||||
@@ -18,10 +18,10 @@ ARG DOCKERCLI_INTEGRATION_REPOSITORY="https://github.com/docker/cli.git"
|
||||
ARG DOCKERCLI_INTEGRATION_VERSION=v18.06.3-ce
|
||||
|
||||
# BUILDX_VERSION is the version of buildx to install in the dev container.
|
||||
ARG BUILDX_VERSION=0.25.0
|
||||
ARG BUILDX_VERSION=0.24.0
|
||||
|
||||
# COMPOSE_VERSION is the version of compose to install in the dev container.
|
||||
ARG COMPOSE_VERSION=v2.38.2
|
||||
ARG COMPOSE_VERSION=v2.36.2
|
||||
|
||||
ARG SYSTEMD="false"
|
||||
ARG FIREWALLD="false"
|
||||
@@ -34,8 +34,8 @@ ARG DOCKER_STATIC=1
|
||||
ARG REGISTRY_VERSION=3.0.0
|
||||
|
||||
# delve is currently only supported on linux/amd64 and linux/arm64;
|
||||
# https://github.com/go-delve/delve/blob/v1.25.0/pkg/proc/native/support_sentinel.go#L1
|
||||
# https://github.com/go-delve/delve/blob/v1.25.0/pkg/proc/native/support_sentinel_linux.go#L1
|
||||
# https://github.com/go-delve/delve/blob/v1.24.1/pkg/proc/native/support_sentinel.go#L1
|
||||
# https://github.com/go-delve/delve/blob/v1.24.1/pkg/proc/native/support_sentinel_linux.go#L1
|
||||
#
|
||||
# ppc64le support was added in v1.21.1, but is still experimental, and requires
|
||||
# the "-tags exp.linuxppc64le" build-tag to be set:
|
||||
@@ -64,6 +64,7 @@ COPY --from=xx / /
|
||||
RUN go telemetry off && [ "$(go telemetry)" = "off" ] || { echo "Failed to disable Go telemetry"; exit 1; }
|
||||
RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y file
|
||||
ENV GO111MODULE=off
|
||||
ENV GOTOOLCHAIN=local
|
||||
|
||||
FROM base AS criu
|
||||
@@ -81,18 +82,25 @@ FROM distribution/distribution:$REGISTRY_VERSION AS registry
|
||||
RUN mkdir /build && mv /bin/registry /build/registry
|
||||
|
||||
# go-swagger
|
||||
FROM base AS swagger-src
|
||||
WORKDIR /usr/src/swagger
|
||||
# Currently uses a fork from https://github.com/kolyshkin/go-swagger/tree/golang-1.13-fix
|
||||
# TODO: move to under moby/ or fix upstream go-swagger to work for us.
|
||||
RUN git init . && git remote add origin "https://github.com/kolyshkin/go-swagger.git"
|
||||
# GO_SWAGGER_COMMIT specifies the version of the go-swagger binary to build and
|
||||
# install. Go-swagger is used in CI for validating swagger.yaml in hack/validate/swagger-gen
|
||||
ARG GO_SWAGGER_COMMIT=c56166c036004ba7a3a321e5951ba472b9ae298c
|
||||
RUN git fetch -q --depth 1 origin "${GO_SWAGGER_COMMIT}" && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS swagger
|
||||
WORKDIR /go/src/github.com/go-swagger/go-swagger
|
||||
ARG TARGETPLATFORM
|
||||
# GO_SWAGGER_VERSION specifies the version of the go-swagger binary to install.
|
||||
# Go-swagger is used in CI for generating types from swagger.yaml in
|
||||
# hack/validate/swagger-gen
|
||||
ARG GO_SWAGGER_VERSION=v0.32.3
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build,id=swagger-build-$TARGETPLATFORM \
|
||||
RUN --mount=from=swagger-src,src=/usr/src/swagger,rw \
|
||||
--mount=type=cache,target=/root/.cache/go-build,id=swagger-build-$TARGETPLATFORM \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=tmpfs,target=/go/src/ <<EOT
|
||||
set -e
|
||||
GOBIN=/build xx-go install "github.com/go-swagger/go-swagger/cmd/swagger@${GO_SWAGGER_VERSION}"
|
||||
xx-go build -o /build/swagger ./cmd/swagger
|
||||
xx-verify /build/swagger
|
||||
EOT
|
||||
|
||||
@@ -127,7 +135,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.25.0
|
||||
ARG DELVE_VERSION=v1.24.1
|
||||
RUN git fetch -q --depth 1 origin "${DELVE_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS delve-supported
|
||||
@@ -137,7 +145,7 @@ RUN --mount=from=delve-src,src=/usr/src/delve,rw \
|
||||
--mount=type=cache,target=/root/.cache/go-build,id=delve-build-$TARGETPLATFORM \
|
||||
--mount=type=cache,target=/go/pkg/mod <<EOT
|
||||
set -e
|
||||
xx-go build -o /build/dlv ./cmd/dlv
|
||||
GO111MODULE=on xx-go build -o /build/dlv ./cmd/dlv
|
||||
xx-verify /build/dlv
|
||||
EOT
|
||||
|
||||
@@ -149,7 +157,7 @@ FROM base AS gowinres
|
||||
ARG GOWINRES_VERSION=v0.3.1
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ go install "github.com/tc-hib/go-winres@${GOWINRES_VERSION}" \
|
||||
GOBIN=/build/ GO111MODULE=on go install "github.com/tc-hib/go-winres@${GOWINRES_VERSION}" \
|
||||
&& /build/go-winres --help
|
||||
|
||||
# containerd
|
||||
@@ -159,8 +167,11 @@ RUN git init . && git remote add origin "https://github.com/containerd/container
|
||||
# CONTAINERD_VERSION is used to build containerd binaries, and used for the
|
||||
# integration tests. The distributed docker .deb and .rpm packages depend on a
|
||||
# separate (containerd.io) package, which may be a different version as is
|
||||
# specified here.
|
||||
ARG CONTAINERD_VERSION=v1.7.28
|
||||
# specified here. The containerd golang package is also pinned in vendor.mod.
|
||||
# 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.29
|
||||
RUN git fetch -q --depth 1 origin "${CONTAINERD_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS containerd-build
|
||||
@@ -194,7 +205,7 @@ FROM base AS golangci_lint
|
||||
ARG GOLANGCI_LINT_VERSION=v2.1.5
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" \
|
||||
GOBIN=/build/ GO111MODULE=on go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" \
|
||||
&& /build/golangci-lint --version
|
||||
|
||||
FROM base AS gotestsum
|
||||
@@ -202,20 +213,20 @@ FROM base AS gotestsum
|
||||
ARG GOTESTSUM_VERSION=v1.12.3
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ go install "gotest.tools/gotestsum@${GOTESTSUM_VERSION}" \
|
||||
GOBIN=/build/ GO111MODULE=on go install "gotest.tools/gotestsum@${GOTESTSUM_VERSION}" \
|
||||
&& /build/gotestsum --version
|
||||
|
||||
FROM base AS shfmt
|
||||
ARG SHFMT_VERSION=v3.8.0
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ go install "mvdan.cc/sh/v3/cmd/shfmt@${SHFMT_VERSION}" \
|
||||
GOBIN=/build/ GO111MODULE=on go install "mvdan.cc/sh/v3/cmd/shfmt@${SHFMT_VERSION}" \
|
||||
&& /build/shfmt --version
|
||||
|
||||
FROM base AS gopls
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
GOBIN=/build/ go install "golang.org/x/tools/gopls@latest" \
|
||||
GOBIN=/build/ GO111MODULE=on go install "golang.org/x/tools/gopls@latest" \
|
||||
&& /build/gopls version
|
||||
|
||||
FROM base AS dockercli
|
||||
@@ -250,7 +261,7 @@ RUN git init . && git remote add origin "https://github.com/opencontainers/runc.
|
||||
# RUNC_VERSION should match the version that is used by the containerd version
|
||||
# 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.
|
||||
ARG RUNC_VERSION=v1.3.0
|
||||
ARG RUNC_VERSION=v1.3.3
|
||||
RUN git fetch -q --depth 1 origin "${RUNC_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
FROM base AS runc-build
|
||||
@@ -317,7 +328,7 @@ FROM tini-${TARGETOS} AS tini
|
||||
FROM base AS rootlesskit-src
|
||||
WORKDIR /usr/src/rootlesskit
|
||||
RUN git init . && git remote add origin "https://github.com/rootless-containers/rootlesskit.git"
|
||||
# When updating, also update go.mod and hack/dockerfile/install/rootlesskit.installer accordingly.
|
||||
# When updating, also update vendor.mod and hack/dockerfile/install/rootlesskit.installer accordingly.
|
||||
ARG ROOTLESSKIT_VERSION=v2.3.4
|
||||
RUN git fetch -q --depth 1 origin "${ROOTLESSKIT_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
|
||||
|
||||
@@ -330,6 +341,7 @@ RUN --mount=type=cache,sharing=locked,id=moby-rootlesskit-aptlib,target=/var/lib
|
||||
gcc \
|
||||
libc6-dev \
|
||||
pkg-config
|
||||
ENV GO111MODULE=on
|
||||
ARG DOCKER_STATIC
|
||||
RUN --mount=from=rootlesskit-src,src=/usr/src/rootlesskit,rw \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
@@ -530,14 +542,14 @@ COPY --link --from=dockercli-integration /build/ /usr/local/cli-integration
|
||||
FROM base AS build
|
||||
COPY --from=gowinres /build/ /usr/local/bin/
|
||||
WORKDIR /go/src/github.com/docker/docker
|
||||
ENV GO111MODULE=off
|
||||
ENV CGO_ENABLED=1
|
||||
RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \
|
||||
--mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \
|
||||
apt-get update && apt-get install --no-install-recommends -y \
|
||||
clang \
|
||||
lld \
|
||||
llvm \
|
||||
icoutils
|
||||
llvm
|
||||
ARG TARGETPLATFORM
|
||||
RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \
|
||||
--mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \
|
||||
@@ -567,6 +579,7 @@ RUN <<EOT
|
||||
fi
|
||||
EOT
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=tmpfs,target=cli/winresources/dockerd \
|
||||
--mount=type=cache,target=/root/.cache/go-build,id=moby-build-$TARGETPLATFORM <<EOT
|
||||
set -e
|
||||
target=$([ "$DOCKER_STATIC" = "1" ] && echo "binary" || echo "dynbinary")
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
|
||||
# This represents the bare minimum required to build and test Docker.
|
||||
|
||||
ARG GO_VERSION=1.24.6
|
||||
ARG GO_VERSION=1.24.9
|
||||
|
||||
ARG BASE_DEBIAN_DISTRO="bookworm"
|
||||
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
|
||||
|
||||
FROM ${GOLANG_IMAGE}
|
||||
ENV GO111MODULE=off
|
||||
ENV GOTOOLCHAIN=local
|
||||
|
||||
# Compile and runtime deps
|
||||
# https://github.com/moby/moby/blob/master/project/PACKAGERS.md#build-dependencies
|
||||
# https://github.com/moby/moby/blob/master/project/PACKAGERS.md#runtime-dependencies
|
||||
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#build-dependencies
|
||||
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
curl \
|
||||
|
||||
@@ -161,14 +161,14 @@ 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.24.6
|
||||
ARG GO_VERSION=1.24.9
|
||||
|
||||
# GOTESTSUM_VERSION is the version of gotest.tools/gotestsum to install.
|
||||
ARG GOTESTSUM_VERSION=v1.12.3
|
||||
|
||||
# GOWINRES_VERSION is the version of go-winres to install.
|
||||
ARG GOWINRES_VERSION=v0.3.3
|
||||
ARG CONTAINERD_VERSION=v1.7.28
|
||||
ARG CONTAINERD_VERSION=v1.7.29
|
||||
|
||||
# Environment variable notes:
|
||||
# - GO_VERSION must be consistent with 'Dockerfile' used by Linux.
|
||||
@@ -178,6 +178,7 @@ ENV GO_VERSION=${GO_VERSION} `
|
||||
CONTAINERD_VERSION=${CONTAINERD_VERSION} `
|
||||
GIT_VERSION=2.11.1 `
|
||||
GOPATH=C:\gopath `
|
||||
GO111MODULE=off `
|
||||
GOTOOLCHAIN=local `
|
||||
FROM_DOCKERFILE=1 `
|
||||
GOTESTSUM_VERSION=${GOTESTSUM_VERSION} `
|
||||
@@ -258,14 +259,11 @@ RUN `
|
||||
Remove-Item C:\gitsetup.zip; `
|
||||
`
|
||||
Write-Host INFO: Downloading containerd; `
|
||||
Install-Package -Force 7Zip4PowerShell; `
|
||||
$location='https://github.com/containerd/containerd/releases/download/'+$Env:CONTAINERD_VERSION+'/containerd-'+$Env:CONTAINERD_VERSION.TrimStart('v')+'-windows-amd64.tar.gz'; `
|
||||
Download-File $location C:\containerd.tar.gz; `
|
||||
New-Item -Path C:\containerd -ItemType Directory; `
|
||||
Expand-7Zip C:\containerd.tar.gz C:\; `
|
||||
Expand-7Zip C:\containerd.tar C:\containerd; `
|
||||
tar -xzf C:\containerd.tar.gz -C C:\containerd; `
|
||||
Remove-Item C:\containerd.tar.gz; `
|
||||
Remove-Item C:\containerd.tar; `
|
||||
`
|
||||
# Ensure all directories exist that we will require below....
|
||||
$srcDir = """$Env:GOPATH`\src\github.com\docker\docker\bundles"""; `
|
||||
@@ -277,11 +275,13 @@ RUN `
|
||||
|
||||
RUN `
|
||||
Function Install-GoTestSum() { `
|
||||
$Env:GO111MODULE = 'on'; `
|
||||
$tmpGobin = "${Env:GOBIN_TMP}"; `
|
||||
$Env:GOBIN = """${Env:GOPATH}`\bin"""; `
|
||||
Write-Host "INFO: Installing gotestsum version $Env:GOTESTSUM_VERSION in $Env:GOBIN"; `
|
||||
&go install "gotest.tools/gotestsum@${Env:GOTESTSUM_VERSION}"; `
|
||||
$Env:GOBIN = "${tmpGobin}"; `
|
||||
$Env:GO111MODULE = 'off'; `
|
||||
if ($LASTEXITCODE -ne 0) { `
|
||||
Throw '"gotestsum install failed..."'; `
|
||||
} `
|
||||
@@ -291,11 +291,13 @@ RUN `
|
||||
|
||||
RUN `
|
||||
Function Install-GoWinres() { `
|
||||
$Env:GO111MODULE = 'on'; `
|
||||
$tmpGobin = "${Env:GOBIN_TMP}"; `
|
||||
$Env:GOBIN = """${Env:GOPATH}`\bin"""; `
|
||||
Write-Host "INFO: Installing go-winres version $Env:GOWINRES_VERSION in $Env:GOBIN"; `
|
||||
&go install "github.com/tc-hib/go-winres@${Env:GOWINRES_VERSION}"; `
|
||||
$Env:GOBIN = "${tmpGobin}"; `
|
||||
$Env:GO111MODULE = 'off'; `
|
||||
if ($LASTEXITCODE -ne 0) { `
|
||||
Throw '"go-winres install failed..."'; `
|
||||
} `
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# GitHub ID, Name, Email address, GPG fingerprint
|
||||
"akerouanton","Albin Kerouanton","albinker@gmail.com"
|
||||
"AkihiroSuda","Akihiro Suda","akihiro.suda.cz@hco.ntt.co.jp"
|
||||
"austinvazquez","Austin Vazquez","austin.vazquez.dev@gmail.com"
|
||||
"austinvazquez","Austin Vazquez","macedonv@amazon.com"
|
||||
"corhere","Cory Snider","csnider@mirantis.com"
|
||||
"cpuguy83","Brian Goff","cpuguy83@gmail.com"
|
||||
"robmry","Rob Murray","rob.murray@docker.com"
|
||||
|
||||
3
Makefile
3
Makefile
@@ -38,7 +38,6 @@ DOCKER_ENVS := \
|
||||
-e DOCKERCLI_INTEGRATION_REPOSITORY \
|
||||
-e DOCKER_DEBUG \
|
||||
-e DOCKER_EXPERIMENTAL \
|
||||
-e DOCKER_FIREWALL_BACKEND \
|
||||
-e DOCKER_GITCOMMIT \
|
||||
-e DOCKER_GRAPHDRIVER \
|
||||
-e DOCKER_LDFLAGS \
|
||||
@@ -54,7 +53,7 @@ DOCKER_ENVS := \
|
||||
-e GITHUB_ACTIONS \
|
||||
-e TEST_FORCE_VALIDATE \
|
||||
-e TEST_INTEGRATION_DIR \
|
||||
-e TEST_INTEGRATION_USE_GRAPHDRIVER \
|
||||
-e TEST_INTEGRATION_USE_SNAPSHOTTER \
|
||||
-e TEST_INTEGRATION_FAIL_FAST \
|
||||
-e TEST_SKIP_INTEGRATION \
|
||||
-e TEST_SKIP_INTEGRATION_CLI \
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
The Moby Project
|
||||
================
|
||||
|
||||
[](https://pkg.go.dev/github.com/moby/moby/v2)
|
||||

|
||||
[](https://goreportcard.com/report/github.com/moby/moby/v2)
|
||||
[](https://pkg.go.dev/github.com/docker/docker)
|
||||
[](https://goreportcard.com/report/github.com/docker/docker)
|
||||
[](https://scorecard.dev/viewer/?uri=github.com/moby/moby)
|
||||
[](https://www.bestpractices.dev/projects/10989)
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -113,5 +113,5 @@ We see gRPC as the natural communication layer between decoupled components.
|
||||
|
||||
In addition to pushing out large components into other projects, much of the
|
||||
internal code structure, and in particular the
|
||||
["Daemon"](https://pkg.go.dev/github.com/moby/moby/v2/daemon#Daemon) object,
|
||||
["Daemon"](https://godoc.org/github.com/docker/docker/daemon#Daemon) object,
|
||||
should be split into smaller, more manageable, and more testable components.
|
||||
|
||||
33
TESTING.md
33
TESTING.md
@@ -8,11 +8,11 @@ questions you may have as an aspiring Moby contributor.
|
||||
Moby has two test suites (and one legacy test suite):
|
||||
|
||||
* Unit tests - use standard `go test` and
|
||||
[gotest.tools/v3/assert](https://pkg.go.dev/gotest.tools/v3/assert) assertions. They are located in
|
||||
[gotest.tools/assert](https://godoc.org/gotest.tools/assert) assertions. They are located in
|
||||
the package they test. Unit tests should be fast and test only their own
|
||||
package.
|
||||
* API integration tests - use standard `go test` and
|
||||
[gotest.tools/v3/assert](https://pkg.go.dev/gotest.tools/v3/assert) assertions. They are located in
|
||||
[gotest.tools/assert](https://godoc.org/gotest.tools/assert) assertions. They are located in
|
||||
`./integration/<component>` directories, where `component` is: container,
|
||||
image, volume, etc. These tests perform HTTP requests to an API endpoint and
|
||||
check the HTTP response and daemon state after the call.
|
||||
@@ -57,28 +57,17 @@ Instead, implement new tests under `integration/`.
|
||||
### Integration tests environment considerations
|
||||
|
||||
When adding new tests or modifying existing tests under `integration/`, testing
|
||||
environment should be properly considered. [`skip.If`](https://pkg.go.dev/gotest.tools/v3/skip#If) from
|
||||
[gotest.tools/v3/skip](https://pkg.go.dev/gotest.tools/v3/skip) can be used to make the
|
||||
environment should be properly considered. `skip.If` from
|
||||
[gotest.tools/skip](https://godoc.org/gotest.tools/skip) can be used to make the
|
||||
test run conditionally. Full testing environment conditions can be found at
|
||||
[environment.go](https://github.com/moby/moby/blob/311b2c87e125c6d4198014369e313135cf928a8a/testutil/environment/environment.go)
|
||||
[environment.go](https://github.com/moby/moby/blob/6b6eeed03b963a27085ea670f40cd5ff8a61f32e/testutil/environment/environment.go)
|
||||
|
||||
Here is a quick example. If the test needs to interact with a docker daemon on
|
||||
the same host, the following condition should be checked within the test code
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon(), "test requires a local daemon")
|
||||
|
||||
// your integration test code
|
||||
}
|
||||
skip.If(t, testEnv.IsRemoteDaemon())
|
||||
// your integration test code
|
||||
```
|
||||
|
||||
If a remote daemon is detected, the test will be skipped.
|
||||
@@ -89,11 +78,11 @@ If a remote daemon is detected, the test will be skipped.
|
||||
|
||||
To run the unit test suite:
|
||||
|
||||
```bash
|
||||
```
|
||||
make test-unit
|
||||
```
|
||||
|
||||
or `hack/test/unit` from inside a `make shell` container or properly
|
||||
or `hack/test/unit` from inside a `BINDDIR=. make shell` container or properly
|
||||
configured environment.
|
||||
|
||||
The following environment variables may be used to run a subset of tests:
|
||||
@@ -106,7 +95,7 @@ The following environment variables may be used to run a subset of tests:
|
||||
|
||||
To run the integration test suite:
|
||||
|
||||
```bash
|
||||
```
|
||||
make test-integration
|
||||
```
|
||||
|
||||
@@ -133,5 +122,5 @@ You can change a version of golang used for building stuff that is being tested
|
||||
by setting `GO_VERSION` variable, for example:
|
||||
|
||||
```bash
|
||||
make GO_VERSION=1.24.6 test
|
||||
make GO_VERSION=1.24.8 test
|
||||
```
|
||||
|
||||
46
VENDORING.md
Normal file
46
VENDORING.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Vendoring policies
|
||||
|
||||
This document outlines recommended Vendoring policies for Docker repositories.
|
||||
(Example, libnetwork is a Docker repo and logrus is not.)
|
||||
|
||||
## Vendoring using tags
|
||||
|
||||
Commit ID based vendoring provides little/no information about the updates
|
||||
vendored. To fix this, vendors will now require that repositories use annotated
|
||||
tags along with commit ids to snapshot commits. Annotated tags by themselves
|
||||
are not sufficient, since the same tag can be force updated to reference
|
||||
different commits.
|
||||
|
||||
Each tag should:
|
||||
- Follow Semantic Versioning rules (refer to section on "Semantic Versioning")
|
||||
- Have a corresponding entry in the change tracking document.
|
||||
|
||||
Each repo should:
|
||||
- Have a change tracking document between tags/releases. Ex: CHANGELOG.md,
|
||||
github releases file.
|
||||
|
||||
The goal here is for consuming repos to be able to use the tag version and
|
||||
changelog updates to determine whether the vendoring will cause any breaking or
|
||||
backward incompatible changes. This also means that repos can specify having
|
||||
dependency on a package of a specific version or greater up to the next major
|
||||
release, without encountering breaking changes.
|
||||
|
||||
## Semantic Versioning
|
||||
Annotated version tags should follow [Semantic Versioning](http://semver.org) policies:
|
||||
|
||||
"Given a version number MAJOR.MINOR.PATCH, increment the:
|
||||
|
||||
1. MAJOR version when you make incompatible API changes,
|
||||
2. MINOR version when you add functionality in a backwards-compatible manner, and
|
||||
3. PATCH version when you make backwards-compatible bug fixes.
|
||||
|
||||
Additional labels for pre-release and build metadata are available as extensions
|
||||
to the MAJOR.MINOR.PATCH format."
|
||||
|
||||
## Vendoring cadence
|
||||
In order to avoid huge vendoring changes, it is recommended to have a regular
|
||||
cadence for vendoring updates. e.g. monthly.
|
||||
|
||||
## Pre-merge vendoring tests
|
||||
All related repos will be vendored into docker/docker.
|
||||
CI on docker/docker should catch any breaking changes involving multiple repos.
|
||||
@@ -1,18 +1,12 @@
|
||||
# Engine API
|
||||
|
||||
[](https://pkg.go.dev/github.com/moby/moby/api)
|
||||

|
||||
[](https://goreportcard.com/report/github.com/moby/moby/api)
|
||||
[](https://scorecard.dev/viewer/?uri=github.com/moby/moby)
|
||||
[](https://www.bestpractices.dev/projects/10989)
|
||||
|
||||
# Working on the Engine API
|
||||
|
||||
The Engine API is an HTTP API used by the command-line client to communicate with the daemon. It can also be used by third-party software to control the daemon.
|
||||
|
||||
It consists of various components in this repository:
|
||||
|
||||
- `api/swagger.yaml` A Swagger definition of the API.
|
||||
- `api/types/` Types shared by both the client and server, representing various objects, options, responses, etc. Most are written manually, but some are automatically generated from the Swagger definition. See [#27919](https://github.com/moby/moby/issues/27919) for progress on this.
|
||||
- `api/types/` Types shared by both the client and server, representing various objects, options, responses, etc. Most are written manually, but some are automatically generated from the Swagger definition. See [#27919](https://github.com/docker/docker/issues/27919) for progress on this.
|
||||
- `cli/` The command-line client.
|
||||
- `client/` The Go client used by the command-line client. It can also be used by third-party Go programs.
|
||||
- `daemon/` The daemon, which serves the API.
|
||||
|
||||
@@ -27,7 +21,6 @@ The API is defined by the [Swagger](http://swagger.io/specification/) definition
|
||||
## Updating the API documentation
|
||||
|
||||
The API documentation is generated entirely from `api/swagger.yaml`. If you make updates to the API, edit this file to represent the change in the documentation.
|
||||
Documentation for each API version can be found in the [docs directory](docs/README.md), which also provides a [CHANGELOG.md](docs/CHANGELOG.md).
|
||||
|
||||
The file is split into two main sections:
|
||||
|
||||
@@ -36,7 +29,7 @@ The file is split into two main sections:
|
||||
|
||||
To make an edit, first look for the endpoint you want to edit under `paths`, then make the required edits. Endpoints may reference reusable objects with `$ref`, which can be found in the `definitions` section.
|
||||
|
||||
There is hopefully enough example material in the file for you to copy a similar pattern from elsewhere in the file (e.g. adding new fields or endpoints), but for the full reference, see the [Swagger specification](https://github.com/moby/moby/issues/27919).
|
||||
There is hopefully enough example material in the file for you to copy a similar pattern from elsewhere in the file (e.g. adding new fields or endpoints), but for the full reference, see the [Swagger specification](https://github.com/docker/docker/issues/27919).
|
||||
|
||||
`swagger.yaml` is validated by `hack/validate/swagger` to ensure it is a valid Swagger definition. This is useful when making edits to ensure you are doing the right thing.
|
||||
|
||||
@@ -46,4 +39,4 @@ When you make edits to `swagger.yaml`, you may want to check the generated API d
|
||||
|
||||
Run `make swagger-docs` and a preview will be running at `http://localhost:9000`. Some of the styling may be incorrect, but you'll be able to ensure that it is generating the correct documentation.
|
||||
|
||||
The production documentation is generated by vendoring `swagger.yaml` into [docker/docs](https://github.com/docker/docs).
|
||||
The production documentation is generated by vendoring `swagger.yaml` into [docker/docker.github.io](https://github.com/docker/docker.github.io).
|
||||
|
||||
@@ -3,14 +3,18 @@ package api
|
||||
// Common constants for daemon and client.
|
||||
const (
|
||||
// DefaultVersion of the current REST API.
|
||||
DefaultVersion = "1.52"
|
||||
DefaultVersion = "1.51"
|
||||
|
||||
// MinSupportedAPIVersion is the minimum API version that can be supported
|
||||
// by the API server, specified as "major.minor". Note that the daemon
|
||||
// may be configured with a different minimum API version, as returned
|
||||
// in [github.com/moby/moby/api/types.Version.MinAPIVersion].
|
||||
// in [github.com/docker/docker/api/types.Version.MinAPIVersion].
|
||||
//
|
||||
// API requests for API versions lower than the configured version produce
|
||||
// an error.
|
||||
MinSupportedAPIVersion = "1.24"
|
||||
|
||||
// NoBaseImageSpecifier is the symbol used by the FROM
|
||||
// command to specify that no base image is to be used.
|
||||
NoBaseImageSpecifier = "scratch"
|
||||
)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# API Documentation
|
||||
|
||||
This directory contains versioned documents for each version of the API
|
||||
specification supported by this module. While this module provides support
|
||||
for older API versions, support should be considered "best-effort", especially
|
||||
for very old versions. Users are recommended to use the latest API versions,
|
||||
and only rely on older API versions for compatibility with older clients.
|
||||
|
||||
Newer API versions tend to be backward-compatible with older versions,
|
||||
with some exceptions where features were deprecated. For an overview
|
||||
of changes for each version, refer to [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
The latest version of the API specification can be found [at the root directory
|
||||
of this module](../swagger.yaml) which may contain unreleased changes.
|
||||
|
||||
For API version v1.24, documentation is only available in markdown
|
||||
format, for later versions [Swagger (OpenAPI) v2.0](https://swagger.io/specification/v2/)
|
||||
specifications can be found in this directory. The Moby project itself
|
||||
primarily uses these swagger files to produce the API documentation;
|
||||
while we attempt to make these files match the actual implementation,
|
||||
the OpenAPI 2.0 specification has limitations that prevent us from
|
||||
expressing all options provided. There may be discrepancies (for which
|
||||
we welcome contributions). If you find bugs, or discrepancies, please
|
||||
open a ticket (or pull request).
|
||||
|
||||
|
||||
13428
api/docs/v1.52.yaml
13428
api/docs/v1.52.yaml
File diff suppressed because it is too large
Load Diff
15
api/go.mod
15
api/go.mod
@@ -1,15 +0,0 @@
|
||||
module github.com/moby/moby/api
|
||||
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/docker/go-connections v0.6.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/moby/docker-image-spec v1.3.1
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.1
|
||||
golang.org/x/time v0.11.0
|
||||
gotest.tools/v3 v3.5.2
|
||||
pgregory.net/rapid v1.2.0
|
||||
)
|
||||
18
api/go.sum
18
api/go.sum
@@ -1,18 +0,0 @@
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
|
||||
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
|
||||
@@ -1,213 +0,0 @@
|
||||
package stdcopy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// StdType is the type of standard stream
|
||||
// a writer can multiplex to.
|
||||
type StdType byte
|
||||
|
||||
const (
|
||||
Stdin StdType = 0 // Stdin represents standard input stream. It is present for completeness and should NOT be used. When reading the stream with [StdCopy] it is output on [Stdout].
|
||||
Stdout StdType = 1 // Stdout represents standard output stream.
|
||||
Stderr StdType = 2 // Stderr represents standard error steam.
|
||||
Systemerr StdType = 3 // Systemerr represents errors originating from the system. When reading the stream with [StdCopy] it is returned as an error.
|
||||
)
|
||||
|
||||
const (
|
||||
stdWriterPrefixLen = 8
|
||||
stdWriterFdIndex = 0
|
||||
stdWriterSizeIndex = 4
|
||||
|
||||
startingBufLen = 32*1024 + stdWriterPrefixLen + 1
|
||||
)
|
||||
|
||||
var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }}
|
||||
|
||||
// stdWriter is wrapper of io.Writer with extra customized info.
|
||||
type stdWriter struct {
|
||||
io.Writer
|
||||
prefix byte
|
||||
}
|
||||
|
||||
// Write sends the buffer to the underlying writer.
|
||||
// It inserts the prefix header before the buffer,
|
||||
// so [StdCopy] knows where to multiplex the output.
|
||||
//
|
||||
// It implements [io.Writer].
|
||||
func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
if w == nil || w.Writer == nil {
|
||||
return 0, errors.New("writer not instantiated")
|
||||
}
|
||||
if p == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
header := [stdWriterPrefixLen]byte{stdWriterFdIndex: w.prefix}
|
||||
binary.BigEndian.PutUint32(header[stdWriterSizeIndex:], uint32(len(p)))
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
buf.Write(header[:])
|
||||
buf.Write(p)
|
||||
|
||||
n, err := w.Writer.Write(buf.Bytes())
|
||||
n -= stdWriterPrefixLen
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
bufPool.Put(buf)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// NewStdWriter instantiates a new writer using a custom format to multiplex
|
||||
// multiple streams to a single writer. All messages written using this writer
|
||||
// are encapsulated using a custom format, and written to the underlying
|
||||
// stream "w".
|
||||
//
|
||||
// Writers created through NewStdWriter allow for multiple write streams
|
||||
// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// single connection. "streamType" indicates the type of stream to encapsulate,
|
||||
// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to
|
||||
// include server-side errors in the stream. Information on this stream
|
||||
// is returned as an error by [StdCopy] and terminates processing the
|
||||
// stream.
|
||||
//
|
||||
// The [Stdin] stream is present for completeness and should generally
|
||||
// NOT be used. It is output on [Stdout] when reading the stream with
|
||||
// [StdCopy].
|
||||
//
|
||||
// All streams must share the same underlying [io.Writer] to ensure proper
|
||||
// multiplexing. Each call to NewStdWriter wraps that shared writer with
|
||||
// a header indicating the target stream.
|
||||
func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
return &stdWriter{
|
||||
Writer: w,
|
||||
prefix: byte(streamType),
|
||||
}
|
||||
}
|
||||
|
||||
// StdCopy is a modified version of [io.Copy] to de-multiplex messages
|
||||
// from "multiplexedSource" and copy them to destination streams
|
||||
// "destOut" and "destErr".
|
||||
//
|
||||
// StdCopy demultiplexes "multiplexedSource", assuming that it contains
|
||||
// two streams, previously multiplexed using a writer created with
|
||||
// [NewStdWriter].
|
||||
//
|
||||
// As it reads from "multiplexedSource", StdCopy writes [Stdout] messages
|
||||
// to "destOut", and [Stderr] message to "destErr]. For backward-compatibility,
|
||||
// [Stdin] messages are output to "destOut". The [Systemerr] stream provides
|
||||
// errors produced by the daemon. It is returned as an error, and terminates
|
||||
// processing the stream.
|
||||
//
|
||||
// StdCopy it reads until it hits [io.EOF] on "multiplexedSource", after
|
||||
// which it returns a nil error. In other words: any error returned indicates
|
||||
// a real underlying error, which may be when an unknown [StdType] stream
|
||||
// is received.
|
||||
//
|
||||
// The "written" return holds the total number of bytes written to "destOut"
|
||||
// and "destErr" combined.
|
||||
func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written int64, _ error) {
|
||||
var (
|
||||
buf = make([]byte, startingBufLen)
|
||||
bufLen = len(buf)
|
||||
nr, nw int
|
||||
err error
|
||||
out io.Writer
|
||||
frameSize int
|
||||
)
|
||||
|
||||
for {
|
||||
// Make sure we have at least a full header
|
||||
for nr < stdWriterPrefixLen {
|
||||
var nr2 int
|
||||
nr2, err = multiplexedSource.Read(buf[nr:])
|
||||
nr += nr2
|
||||
if errors.Is(err, io.EOF) {
|
||||
if nr < stdWriterPrefixLen {
|
||||
return written, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check the first byte to know where to write
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
switch stream {
|
||||
case Stdin:
|
||||
fallthrough
|
||||
case Stdout:
|
||||
// Write on stdout
|
||||
out = destOut
|
||||
case Stderr:
|
||||
// Write on stderr
|
||||
out = destErr
|
||||
case Systemerr:
|
||||
// If we're on Systemerr, we won't write anywhere.
|
||||
// NB: if this code changes later, make sure you don't try to write
|
||||
// to outstream if Systemerr is the stream
|
||||
out = nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unrecognized stream: %d", stream)
|
||||
}
|
||||
|
||||
// Retrieve the size of the frame
|
||||
frameSize = int(binary.BigEndian.Uint32(buf[stdWriterSizeIndex : stdWriterSizeIndex+4]))
|
||||
|
||||
// Check if the buffer is big enough to read the frame.
|
||||
// Extend it if necessary.
|
||||
if frameSize+stdWriterPrefixLen > bufLen {
|
||||
buf = append(buf, make([]byte, frameSize+stdWriterPrefixLen-bufLen+1)...)
|
||||
bufLen = len(buf)
|
||||
}
|
||||
|
||||
// While the amount of bytes read is less than the size of the frame + header, we keep reading
|
||||
for nr < frameSize+stdWriterPrefixLen {
|
||||
var nr2 int
|
||||
nr2, err = multiplexedSource.Read(buf[nr:])
|
||||
nr += nr2
|
||||
if errors.Is(err, io.EOF) {
|
||||
if nr < frameSize+stdWriterPrefixLen {
|
||||
return written, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// we might have an error from the source mixed up in our multiplexed
|
||||
// stream. if we do, return it.
|
||||
if stream == Systemerr {
|
||||
return written, fmt.Errorf("error from daemon in stream: %s", string(buf[stdWriterPrefixLen:frameSize+stdWriterPrefixLen]))
|
||||
}
|
||||
|
||||
// Write the retrieved frame (without header)
|
||||
nw, err = out.Write(buf[stdWriterPrefixLen : frameSize+stdWriterPrefixLen])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// If the frame has not been fully written: error
|
||||
if nw != frameSize {
|
||||
return 0, io.ErrShortWrite
|
||||
}
|
||||
written += int64(nw)
|
||||
|
||||
// Move the rest of the buffer to the beginning
|
||||
copy(buf, buf[frameSize+stdWriterPrefixLen:])
|
||||
// Move the index
|
||||
nr -= frameSize + stdWriterPrefixLen
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package stdcopy_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/pkg/stdcopy"
|
||||
)
|
||||
|
||||
func ExampleNewStdWriter() {
|
||||
muxReader, muxStream := io.Pipe()
|
||||
defer func() { _ = muxStream.Close() }()
|
||||
|
||||
// Start demuxing before the daemon starts writing.
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
// using os.Stdout for both, otherwise output doesn't show up in the example.
|
||||
osStdout := os.Stdout
|
||||
osStderr := os.Stdout
|
||||
_, err := stdcopy.StdCopy(osStdout, osStderr, muxReader)
|
||||
done <- err
|
||||
}()
|
||||
|
||||
// daemon writing to stdout, stderr, and systemErr.
|
||||
stdout := stdcopy.NewStdWriter(muxStream, stdcopy.Stdout)
|
||||
stderr := stdcopy.NewStdWriter(muxStream, stdcopy.Stderr)
|
||||
systemErr := stdcopy.NewStdWriter(muxStream, stdcopy.Systemerr)
|
||||
|
||||
for range 10 {
|
||||
_, _ = fmt.Fprintln(stdout, "hello from stdout")
|
||||
_, _ = fmt.Fprintln(stderr, "hello from stderr")
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
_, _ = fmt.Fprintln(systemErr, errors.New("something went wrong"))
|
||||
|
||||
// Wait for the demuxer to finish.
|
||||
if err := <-done; err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// error from daemon in stream: something went wrong
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
// Package streamformatter provides helper functions to format a stream.
|
||||
package streamformatter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/pkg/progress"
|
||||
"github.com/moby/moby/api/types/jsonstream"
|
||||
)
|
||||
|
||||
// jsonMessage defines a message struct. It describes
|
||||
// the created time, where it from, status, ID of the
|
||||
// message. It's used for docker events.
|
||||
//
|
||||
// It is a reduced set of [jsonmessage.JSONMessage].
|
||||
type jsonMessage struct {
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Progress *jsonstream.Progress `json:"progressDetail,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Error *jsonstream.Error `json:"errorDetail,omitempty"`
|
||||
Aux *json.RawMessage `json:"aux,omitempty"` // Aux contains out-of-band data, such as digests for push signing and image id after building.
|
||||
|
||||
// ErrorMessage contains errors encountered during the operation.
|
||||
//
|
||||
// Deprecated: this field is deprecated since docker v0.6.0 / API v1.4. Use [Error.Message] instead. This field will be omitted in a future release.
|
||||
ErrorMessage string `json:"error,omitempty"` // deprecated
|
||||
}
|
||||
|
||||
const streamNewline = "\r\n"
|
||||
|
||||
type jsonProgressFormatter struct{}
|
||||
|
||||
func appendNewline(source []byte) []byte {
|
||||
return append(source, []byte(streamNewline)...)
|
||||
}
|
||||
|
||||
// FormatStatus formats the specified objects according to the specified format (and id).
|
||||
func FormatStatus(id, format string, a ...any) []byte {
|
||||
str := fmt.Sprintf(format, a...)
|
||||
b, err := json.Marshal(&jsonMessage{ID: id, Status: str})
|
||||
if err != nil {
|
||||
return FormatError(err)
|
||||
}
|
||||
return appendNewline(b)
|
||||
}
|
||||
|
||||
// FormatError formats the error as a JSON object
|
||||
func FormatError(err error) []byte {
|
||||
jsonError, ok := err.(*jsonstream.Error)
|
||||
if !ok {
|
||||
jsonError = &jsonstream.Error{Message: err.Error()}
|
||||
}
|
||||
if b, err := json.Marshal(&jsonMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
|
||||
return appendNewline(b)
|
||||
}
|
||||
return []byte(`{"error":"format error"}` + streamNewline)
|
||||
}
|
||||
|
||||
func (sf *jsonProgressFormatter) formatStatus(id, format string, a ...any) []byte {
|
||||
return FormatStatus(id, format, a...)
|
||||
}
|
||||
|
||||
// formatProgress formats the progress information for a specified action.
|
||||
func (sf *jsonProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte {
|
||||
if progress == nil {
|
||||
progress = &jsonstream.Progress{}
|
||||
}
|
||||
var auxJSON *json.RawMessage
|
||||
if aux != nil {
|
||||
auxJSONBytes, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
auxJSON = new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
}
|
||||
b, err := json.Marshal(&jsonMessage{
|
||||
Status: action,
|
||||
Progress: progress,
|
||||
ID: id,
|
||||
Aux: auxJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return appendNewline(b)
|
||||
}
|
||||
|
||||
type rawProgressFormatter struct{}
|
||||
|
||||
func (sf *rawProgressFormatter) formatStatus(id, format string, a ...any) []byte {
|
||||
return []byte(fmt.Sprintf(format, a...) + streamNewline)
|
||||
}
|
||||
|
||||
func rawProgressString(p *jsonstream.Progress) string {
|
||||
if p == nil || (p.Current <= 0 && p.Total <= 0) {
|
||||
return ""
|
||||
}
|
||||
if p.Total <= 0 {
|
||||
switch p.Units {
|
||||
case "":
|
||||
return fmt.Sprintf("%8v", units.HumanSize(float64(p.Current)))
|
||||
default:
|
||||
return fmt.Sprintf("%d %s", p.Current, p.Units)
|
||||
}
|
||||
}
|
||||
|
||||
percentage := int(float64(p.Current)/float64(p.Total)*100) / 2
|
||||
if percentage > 50 {
|
||||
percentage = 50
|
||||
}
|
||||
|
||||
numSpaces := 0
|
||||
if 50-percentage > 0 {
|
||||
numSpaces = 50 - percentage
|
||||
}
|
||||
pbBox := fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", numSpaces))
|
||||
|
||||
var numbersBox string
|
||||
switch {
|
||||
case p.HideCounts:
|
||||
case p.Units == "": // no units, use bytes
|
||||
current := units.HumanSize(float64(p.Current))
|
||||
total := units.HumanSize(float64(p.Total))
|
||||
|
||||
numbersBox = fmt.Sprintf("%8v/%v", current, total)
|
||||
|
||||
if p.Current > p.Total {
|
||||
// remove total display if the reported current is wonky.
|
||||
numbersBox = fmt.Sprintf("%8v", current)
|
||||
}
|
||||
default:
|
||||
numbersBox = fmt.Sprintf("%d/%d %s", p.Current, p.Total, p.Units)
|
||||
|
||||
if p.Current > p.Total {
|
||||
// remove total display if the reported current is wonky.
|
||||
numbersBox = fmt.Sprintf("%d %s", p.Current, p.Units)
|
||||
}
|
||||
}
|
||||
|
||||
var timeLeftBox string
|
||||
if p.Current > 0 && p.Start > 0 && percentage < 50 {
|
||||
fromStart := time.Since(time.Unix(p.Start, 0))
|
||||
perEntry := fromStart / time.Duration(p.Current)
|
||||
left := time.Duration(p.Total-p.Current) * perEntry
|
||||
timeLeftBox = " " + left.Round(time.Second).String()
|
||||
}
|
||||
return pbBox + numbersBox + timeLeftBox
|
||||
}
|
||||
|
||||
func (sf *rawProgressFormatter) formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte {
|
||||
if progress == nil {
|
||||
progress = &jsonstream.Progress{}
|
||||
}
|
||||
endl := "\r"
|
||||
out := rawProgressString(progress)
|
||||
if out == "" {
|
||||
endl += "\n"
|
||||
}
|
||||
return []byte(action + " " + out + endl)
|
||||
}
|
||||
|
||||
// NewProgressOutput returns a progress.Output object that can be passed to
|
||||
// progress.NewProgressReader.
|
||||
func NewProgressOutput(out io.Writer) progress.Output {
|
||||
return &progressOutput{sf: &rawProgressFormatter{}, out: out, newLines: true}
|
||||
}
|
||||
|
||||
// NewJSONProgressOutput returns a progress.Output that formats output
|
||||
// using JSON objects
|
||||
func NewJSONProgressOutput(out io.Writer, newLines bool) progress.Output {
|
||||
return &progressOutput{sf: &jsonProgressFormatter{}, out: out, newLines: newLines}
|
||||
}
|
||||
|
||||
type formatProgress interface {
|
||||
formatStatus(id, format string, a ...any) []byte
|
||||
formatProgress(id, action string, progress *jsonstream.Progress, aux any) []byte
|
||||
}
|
||||
|
||||
type progressOutput struct {
|
||||
sf formatProgress
|
||||
out io.Writer
|
||||
newLines bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// WriteProgress formats progress information from a ProgressReader.
|
||||
func (out *progressOutput) WriteProgress(prog progress.Progress) error {
|
||||
var formatted []byte
|
||||
if prog.Message != "" {
|
||||
formatted = out.sf.formatStatus(prog.ID, prog.Message)
|
||||
} else {
|
||||
jsonProgress := jsonstream.Progress{
|
||||
Current: prog.Current,
|
||||
Total: prog.Total,
|
||||
HideCounts: prog.HideCounts,
|
||||
Units: prog.Units,
|
||||
}
|
||||
formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux)
|
||||
}
|
||||
|
||||
out.mu.Lock()
|
||||
defer out.mu.Unlock()
|
||||
_, err := out.out.Write(formatted)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if out.newLines && prog.LastUpdate {
|
||||
_, err = out.out.Write(out.sf.formatStatus("", ""))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AuxFormatter is a streamFormatter that writes aux progress messages
|
||||
type AuxFormatter struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// Emit emits the given interface as an aux progress message
|
||||
func (sf *AuxFormatter) Emit(id string, aux any) error {
|
||||
auxJSONBytes, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
auxJSON := new(json.RawMessage)
|
||||
*auxJSON = auxJSONBytes
|
||||
msgJSON, err := json.Marshal(&jsonMessage{ID: id, Aux: auxJSON})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msgJSON = appendNewline(msgJSON)
|
||||
n, err := sf.Writer.Write(msgJSON)
|
||||
if n != len(msgJSON) {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
# commit to be tagged for new release
|
||||
commit = "HEAD"
|
||||
|
||||
project_name = "moby"
|
||||
github_repo = "moby/moby"
|
||||
sub_path = "api"
|
||||
ignore_deps = [ "github.com/moby/moby" ]
|
||||
|
||||
# previous release
|
||||
previous = "v28.2.2"
|
||||
|
||||
pre_release = true
|
||||
|
||||
preface = """\
|
||||
The first dedicated release for the Moby API. This release continues the 1.x
|
||||
line of API compatibility with the 52nd minor release of the 1.x API.
|
||||
"""
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/events"
|
||||
"github.com/moby/moby/v2/daemon/builder"
|
||||
daemonevents "github.com/moby/moby/v2/daemon/events"
|
||||
buildkit "github.com/moby/moby/v2/daemon/internal/builder-next"
|
||||
"github.com/moby/moby/v2/daemon/internal/image"
|
||||
"github.com/moby/moby/v2/daemon/internal/stringid"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/builder"
|
||||
buildkit "github.com/docker/docker/builder/builder-next"
|
||||
daemonevents "github.com/docker/docker/daemon/events"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/v2/daemon/internal/image"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
15
api/server/httputils/decoder.go
Normal file
15
api/server/httputils/decoder.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package httputils
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
)
|
||||
|
||||
// ContainerDecoder specifies how
|
||||
// to translate an io.Reader into
|
||||
// container configuration.
|
||||
type ContainerDecoder interface {
|
||||
DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -91,7 +91,7 @@ func RepoTagReference(repo, tag string) (reference.NamedTagged, error) {
|
||||
}
|
||||
|
||||
if _, isDigested := ref.(reference.Digested); isDigested {
|
||||
return nil, errors.New("cannot import digest reference")
|
||||
return nil, fmt.Errorf("cannot import digest reference")
|
||||
}
|
||||
|
||||
if tag != "" {
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@ func HijackConnection(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
|
||||
}
|
||||
|
||||
// CloseStreams ensures that a list for http streams are properly closed.
|
||||
func CloseStreams(streams ...any) {
|
||||
func CloseStreams(streams ...interface{}) {
|
||||
for _, stream := range streams {
|
||||
if tcpc, ok := stream.(interface {
|
||||
CloseWrite() error
|
||||
@@ -59,7 +59,7 @@ func CheckForJSON(r *http.Request) error {
|
||||
|
||||
// ReadJSON validates the request to have the correct content-type, and decodes
|
||||
// the request's Body into out.
|
||||
func ReadJSON(r *http.Request, out any) error {
|
||||
func ReadJSON(r *http.Request, out interface{}) error {
|
||||
err := CheckForJSON(r)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -87,7 +87,7 @@ func ReadJSON(r *http.Request, out any) error {
|
||||
}
|
||||
|
||||
// WriteJSON writes the value v to the http response stream as json with standard json encoding.
|
||||
func WriteJSON(w http.ResponseWriter, code int, v any) error {
|
||||
func WriteJSON(w http.ResponseWriter, code int, v interface{}) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(code)
|
||||
enc := json.NewEncoder(w)
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"github.com/moby/moby/api/pkg/stdcopy"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
)
|
||||
|
||||
// rfc3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
|
||||
@@ -2,8 +2,8 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/daemon/server/middleware"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/server/middleware"
|
||||
)
|
||||
|
||||
// handlerWithGlobalMiddlewares wraps the handler function for a request with
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/v2/daemon/server/httpstatus"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api/server/httpstatus"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -61,7 +61,7 @@ func DebugRequestMiddleware(handler func(ctx context.Context, w http.ResponseWri
|
||||
return handleWithLogs(ctx, w, r, vars)
|
||||
}
|
||||
|
||||
var postForm map[string]any
|
||||
var postForm map[string]interface{}
|
||||
if err := json.Unmarshal(b, &postForm); err == nil {
|
||||
maskSecretKeys(postForm)
|
||||
// TODO(thaJeztah): is there a better way to detect if we're using JSON-formatted logs?
|
||||
@@ -80,15 +80,15 @@ func DebugRequestMiddleware(handler func(ctx context.Context, w http.ResponseWri
|
||||
}
|
||||
}
|
||||
|
||||
func maskSecretKeys(inp any) {
|
||||
if arr, ok := inp.([]any); ok {
|
||||
func maskSecretKeys(inp interface{}) {
|
||||
if arr, ok := inp.([]interface{}); ok {
|
||||
for _, f := range arr {
|
||||
maskSecretKeys(f)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if form, ok := inp.(map[string]any); ok {
|
||||
if form, ok := inp.(map[string]interface{}); ok {
|
||||
scrub := []string{
|
||||
// Note: The Data field contains the base64-encoded secret in 'secret'
|
||||
// and 'config' create and update requests. Currently, no other POST
|
||||
@@ -10,23 +10,23 @@ import (
|
||||
func TestMaskSecretKeys(t *testing.T) {
|
||||
tests := []struct {
|
||||
doc string
|
||||
input map[string]any
|
||||
expected map[string]any
|
||||
input map[string]interface{}
|
||||
expected map[string]interface{}
|
||||
}{
|
||||
{
|
||||
doc: "secret/config create and update requests",
|
||||
input: map[string]any{"Data": "foo", "Name": "name", "Labels": map[string]any{}},
|
||||
expected: map[string]any{"Data": "*****", "Name": "name", "Labels": map[string]any{}},
|
||||
input: map[string]interface{}{"Data": "foo", "Name": "name", "Labels": map[string]interface{}{}},
|
||||
expected: map[string]interface{}{"Data": "*****", "Name": "name", "Labels": map[string]interface{}{}},
|
||||
},
|
||||
{
|
||||
doc: "masking other fields (recursively)",
|
||||
input: map[string]any{
|
||||
input: map[string]interface{}{
|
||||
"password": "pass",
|
||||
"secret": "secret",
|
||||
"jointoken": "jointoken",
|
||||
"unlockkey": "unlockkey",
|
||||
"signingcakey": "signingcakey",
|
||||
"other": map[string]any{
|
||||
"other": map[string]interface{}{
|
||||
"password": "pass",
|
||||
"secret": "secret",
|
||||
"jointoken": "jointoken",
|
||||
@@ -34,13 +34,13 @@ func TestMaskSecretKeys(t *testing.T) {
|
||||
"signingcakey": "signingcakey",
|
||||
},
|
||||
},
|
||||
expected: map[string]any{
|
||||
expected: map[string]interface{}{
|
||||
"password": "*****",
|
||||
"secret": "*****",
|
||||
"jointoken": "*****",
|
||||
"unlockkey": "*****",
|
||||
"signingcakey": "*****",
|
||||
"other": map[string]any{
|
||||
"other": map[string]interface{}{
|
||||
"password": "*****",
|
||||
"secret": "*****",
|
||||
"jointoken": "*****",
|
||||
@@ -51,15 +51,15 @@ func TestMaskSecretKeys(t *testing.T) {
|
||||
},
|
||||
{
|
||||
doc: "case insensitive field matching",
|
||||
input: map[string]any{
|
||||
input: map[string]interface{}{
|
||||
"PASSWORD": "pass",
|
||||
"other": map[string]any{
|
||||
"other": map[string]interface{}{
|
||||
"PASSWORD": "pass",
|
||||
},
|
||||
},
|
||||
expected: map[string]any{
|
||||
expected: map[string]interface{}{
|
||||
"PASSWORD": "*****",
|
||||
"other": map[string]any{
|
||||
"other": map[string]interface{}{
|
||||
"PASSWORD": "*****",
|
||||
},
|
||||
},
|
||||
@@ -6,10 +6,9 @@ import (
|
||||
"net/http"
|
||||
"runtime"
|
||||
|
||||
"github.com/moby/moby/api"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/config"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
)
|
||||
|
||||
// VersionMiddleware is a middleware that
|
||||
@@ -19,7 +18,7 @@ type VersionMiddleware struct {
|
||||
|
||||
// defaultAPIVersion is the default API version provided by the API server,
|
||||
// specified as "major.minor". It is usually configured to the latest API
|
||||
// version [config.DefaultAPIVersion] supported by the daemon.
|
||||
// version [github.com/docker/docker/api.DefaultVersion].
|
||||
//
|
||||
// API requests for API versions greater than this version are rejected by
|
||||
// the server and produce a [versionUnsupportedError].
|
||||
@@ -35,11 +34,11 @@ type VersionMiddleware struct {
|
||||
|
||||
// NewVersionMiddleware creates a VersionMiddleware with the given versions.
|
||||
func NewVersionMiddleware(serverVersion, defaultAPIVersion, minAPIVersion string) (*VersionMiddleware, error) {
|
||||
if versions.LessThan(defaultAPIVersion, api.MinSupportedAPIVersion) || versions.GreaterThan(defaultAPIVersion, config.DefaultAPIVersion) {
|
||||
return nil, fmt.Errorf("invalid default API version (%s): must be between %s and %s", defaultAPIVersion, api.MinSupportedAPIVersion, config.DefaultAPIVersion)
|
||||
if versions.LessThan(defaultAPIVersion, api.MinSupportedAPIVersion) || versions.GreaterThan(defaultAPIVersion, api.DefaultVersion) {
|
||||
return nil, fmt.Errorf("invalid default API version (%s): must be between %s and %s", defaultAPIVersion, api.MinSupportedAPIVersion, api.DefaultVersion)
|
||||
}
|
||||
if versions.LessThan(minAPIVersion, api.MinSupportedAPIVersion) || versions.GreaterThan(minAPIVersion, config.DefaultAPIVersion) {
|
||||
return nil, fmt.Errorf("invalid minimum API version (%s): must be between %s and %s", minAPIVersion, api.MinSupportedAPIVersion, config.DefaultAPIVersion)
|
||||
if versions.LessThan(minAPIVersion, api.MinSupportedAPIVersion) || versions.GreaterThan(minAPIVersion, api.DefaultVersion) {
|
||||
return nil, fmt.Errorf("invalid minimum API version (%s): must be between %s and %s", minAPIVersion, api.MinSupportedAPIVersion, api.DefaultVersion)
|
||||
}
|
||||
if versions.GreaterThan(minAPIVersion, defaultAPIVersion) {
|
||||
return nil, fmt.Errorf("invalid API version: the minimum API version (%s) is higher than the default version (%s)", minAPIVersion, defaultAPIVersion)
|
||||
@@ -8,9 +8,8 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api"
|
||||
"github.com/moby/moby/v2/daemon/config"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@@ -21,38 +20,38 @@ func TestNewVersionMiddlewareValidation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
doc: "defaults",
|
||||
defaultVersion: config.DefaultAPIVersion,
|
||||
defaultVersion: api.DefaultVersion,
|
||||
minVersion: api.MinSupportedAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "invalid default lower than min",
|
||||
defaultVersion: api.MinSupportedAPIVersion,
|
||||
minVersion: config.DefaultAPIVersion,
|
||||
expectedErr: fmt.Sprintf("invalid API version: the minimum API version (%s) is higher than the default version (%s)", config.DefaultAPIVersion, api.MinSupportedAPIVersion),
|
||||
minVersion: api.DefaultVersion,
|
||||
expectedErr: fmt.Sprintf("invalid API version: the minimum API version (%s) is higher than the default version (%s)", api.DefaultVersion, api.MinSupportedAPIVersion),
|
||||
},
|
||||
{
|
||||
doc: "invalid default too low",
|
||||
defaultVersion: "0.1",
|
||||
minVersion: api.MinSupportedAPIVersion,
|
||||
expectedErr: fmt.Sprintf("invalid default API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, config.DefaultAPIVersion),
|
||||
expectedErr: fmt.Sprintf("invalid default API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
|
||||
},
|
||||
{
|
||||
doc: "invalid default too high",
|
||||
defaultVersion: "9999.9999",
|
||||
minVersion: config.DefaultAPIVersion,
|
||||
expectedErr: fmt.Sprintf("invalid default API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, config.DefaultAPIVersion),
|
||||
minVersion: api.DefaultVersion,
|
||||
expectedErr: fmt.Sprintf("invalid default API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
|
||||
},
|
||||
{
|
||||
doc: "invalid minimum too low",
|
||||
defaultVersion: api.MinSupportedAPIVersion,
|
||||
minVersion: "0.1",
|
||||
expectedErr: fmt.Sprintf("invalid minimum API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, config.DefaultAPIVersion),
|
||||
expectedErr: fmt.Sprintf("invalid minimum API version (0.1): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
|
||||
},
|
||||
{
|
||||
doc: "invalid minimum too high",
|
||||
defaultVersion: config.DefaultAPIVersion,
|
||||
defaultVersion: api.DefaultVersion,
|
||||
minVersion: "9999.9999",
|
||||
expectedErr: fmt.Sprintf("invalid minimum API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, config.DefaultAPIVersion),
|
||||
expectedErr: fmt.Sprintf("invalid minimum API version (9999.9999): must be between %s and %s", api.MinSupportedAPIVersion, api.DefaultVersion),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ func TestVersionMiddlewareVersion(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
m, err := NewVersionMiddleware("1.2.3", config.DefaultAPIVersion, api.MinSupportedAPIVersion)
|
||||
m, err := NewVersionMiddleware("1.2.3", api.DefaultVersion, api.MinSupportedAPIVersion)
|
||||
assert.NilError(t, err)
|
||||
h := m.WrapHandler(handler)
|
||||
|
||||
@@ -90,7 +89,7 @@ func TestVersionMiddlewareVersion(t *testing.T) {
|
||||
errString string
|
||||
}{
|
||||
{
|
||||
expectedVersion: config.DefaultAPIVersion,
|
||||
expectedVersion: api.DefaultVersion,
|
||||
},
|
||||
{
|
||||
reqVersion: api.MinSupportedAPIVersion,
|
||||
@@ -102,7 +101,7 @@ func TestVersionMiddlewareVersion(t *testing.T) {
|
||||
},
|
||||
{
|
||||
reqVersion: "9999.9999",
|
||||
errString: fmt.Sprintf("client version 9999.9999 is too new. Maximum supported API version is %s", config.DefaultAPIVersion),
|
||||
errString: fmt.Sprintf("client version 9999.9999 is too new. Maximum supported API version is %s", api.DefaultVersion),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -126,7 +125,7 @@ func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
m, err := NewVersionMiddleware("1.2.3", config.DefaultAPIVersion, api.MinSupportedAPIVersion)
|
||||
m, err := NewVersionMiddleware("1.2.3", api.DefaultVersion, api.MinSupportedAPIVersion)
|
||||
assert.NilError(t, err)
|
||||
h := m.WrapHandler(handler)
|
||||
|
||||
@@ -141,6 +140,6 @@ func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
|
||||
hdr := resp.Result().Header
|
||||
assert.Check(t, is.Contains(hdr.Get("Server"), "Docker/1.2.3"))
|
||||
assert.Check(t, is.Contains(hdr.Get("Server"), runtime.GOOS))
|
||||
assert.Check(t, is.Equal(hdr.Get("Api-Version"), config.DefaultAPIVersion))
|
||||
assert.Check(t, is.Equal(hdr.Get("Api-Version"), api.DefaultVersion))
|
||||
assert.Check(t, is.Equal(hdr.Get("Ostype"), runtime.GOOS))
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package build
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
)
|
||||
|
||||
// Backend abstracts an image builder whose only purpose is to build an image referenced by an imageID.
|
||||
@@ -3,8 +3,8 @@ package build
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
)
|
||||
|
||||
// buildRouter is a router to talk with the build controller
|
||||
@@ -16,16 +16,16 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/api/pkg/progress"
|
||||
"github.com/moby/moby/api/pkg/streamformatter"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package checkpoint
|
||||
|
||||
import "github.com/moby/moby/api/types/checkpoint"
|
||||
import "github.com/docker/docker/api/types/checkpoint"
|
||||
|
||||
// Backend for Checkpoint
|
||||
type Backend interface {
|
||||
@@ -1,19 +1,22 @@
|
||||
package checkpoint
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
)
|
||||
|
||||
// checkpointRouter is a router to talk with the checkpoint controller
|
||||
type checkpointRouter struct {
|
||||
backend Backend
|
||||
decoder httputils.ContainerDecoder
|
||||
routes []router.Route
|
||||
}
|
||||
|
||||
// NewRouter initializes a new checkpoint router
|
||||
func NewRouter(b Backend) router.Router {
|
||||
func NewRouter(b Backend, decoder httputils.ContainerDecoder) router.Router {
|
||||
r := &checkpointRouter{
|
||||
backend: b,
|
||||
decoder: decoder,
|
||||
}
|
||||
r.initRoutes()
|
||||
return r
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/api/types/checkpoint"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/checkpoint"
|
||||
)
|
||||
|
||||
func (cr *checkpointRouter) postContainerCheckpoint(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
@@ -38,6 +38,9 @@ func (cr *checkpointRouter) getContainerCheckpoints(ctx context.Context, w http.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if checkpoints == nil {
|
||||
checkpoints = []checkpoint.Summary{}
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, checkpoints)
|
||||
}
|
||||
@@ -4,12 +4,10 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/moby/go-archive"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
containerpkg "github.com/moby/moby/v2/daemon/container"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/pkg/sysinfo"
|
||||
)
|
||||
|
||||
// execBackend includes functions to implement to provide exec functionality.
|
||||
@@ -25,7 +23,7 @@ type execBackend interface {
|
||||
type copyBackend interface {
|
||||
ContainerArchivePath(name string, path string) (content io.ReadCloser, stat *container.PathStat, err error)
|
||||
ContainerExport(ctx context.Context, name string, out io.Writer) error
|
||||
ContainerExtractToDir(name, path string, copyUIDGID, allowOverwriteDirWithFile bool, content io.Reader) error
|
||||
ContainerExtractToDir(name, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) error
|
||||
ContainerStatPath(name string, path string) (stat *container.PathStat, err error)
|
||||
}
|
||||
|
||||
@@ -42,7 +40,7 @@ type stateBackend interface {
|
||||
ContainerStop(ctx context.Context, name string, options container.StopOptions) error
|
||||
ContainerUnpause(name string) error
|
||||
ContainerUpdate(name string, hostConfig *container.HostConfig) (container.UpdateResponse, error)
|
||||
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan containerpkg.StateStatus, error)
|
||||
ContainerWait(ctx context.Context, name string, condition container.WaitCondition) (<-chan container.StateStatus, error)
|
||||
}
|
||||
|
||||
// monitorBackend includes functions to implement to provide containers monitoring functionality.
|
||||
@@ -69,10 +67,6 @@ type commitBackend interface {
|
||||
CreateImageFromContainer(ctx context.Context, name string, config *backend.CreateImageConfig) (imageID string, err error)
|
||||
}
|
||||
|
||||
type sysInfoProvider interface {
|
||||
RawSysInfo() *sysinfo.SysInfo
|
||||
}
|
||||
|
||||
// Backend is all the methods that need to be implemented to provide container specific functionality.
|
||||
type Backend interface {
|
||||
commitBackend
|
||||
@@ -82,5 +76,4 @@ type Backend interface {
|
||||
monitorBackend
|
||||
attachBackend
|
||||
systemBackend
|
||||
sysInfoProvider
|
||||
}
|
||||
@@ -1,17 +1,24 @@
|
||||
package container
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/router"
|
||||
import (
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
)
|
||||
|
||||
// containerRouter is a router to talk with the container controller
|
||||
type containerRouter struct {
|
||||
backend Backend
|
||||
decoder httputils.ContainerDecoder
|
||||
routes []router.Route
|
||||
cgroup2 bool
|
||||
}
|
||||
|
||||
// NewRouter initializes a new container router
|
||||
func NewRouter(b Backend) router.Router {
|
||||
func NewRouter(b Backend, decoder httputils.ContainerDecoder, cgroup2 bool) router.Router {
|
||||
r := &containerRouter{
|
||||
backend: b,
|
||||
decoder: decoder,
|
||||
cgroup2: cgroup2,
|
||||
}
|
||||
r.initRoutes()
|
||||
return r
|
||||
@@ -12,56 +12,44 @@ import (
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/internal/runconfig"
|
||||
"github.com/moby/moby/v2/daemon/libnetwork/netlabel"
|
||||
networkSettings "github.com/moby/moby/v2/daemon/network"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httpstatus"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api/server/httpstatus"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
networkSettings "github.com/docker/docker/daemon/network"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/libnetwork/netlabel"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/runconfig"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/otel"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
// commitRequest may contain an optional [container.Config].
|
||||
type commitRequest struct {
|
||||
*container.Config
|
||||
}
|
||||
|
||||
// decodeCommitRequest decodes the request body and returns a [container.Config]
|
||||
// if present, or nil otherwise. It returns an error when failing to decode
|
||||
// due to invalid JSON, or if the request contains multiple JSON documents.
|
||||
//
|
||||
// The client posts a bare [*container.Config] (see [Client.ContainerCommit]
|
||||
// and [container.CommitOptions]), but it may be empty / nil, in which case
|
||||
// it must be ignored, and no overrides to be applied.
|
||||
//
|
||||
// [Client.ContainerCommit]: https://github.com/moby/moby/blob/c4afa7715715a1020e50b19ad60728c4479fb0a5/client/container_commit.go#L52
|
||||
// [container.CommitOptions]: https://github.com/moby/moby/blob/c4afa7715715a1020e50b19ad60728c4479fb0a5/api/types/container/options.go#L30
|
||||
func decodeCommitRequest(r *http.Request) (*container.Config, error) {
|
||||
var w commitRequest
|
||||
if err := httputils.ReadJSON(r, &w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return w.Config, nil
|
||||
}
|
||||
|
||||
func (c *containerRouter) postCommit(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
if err := httputils.ParseForm(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := decodeCommitRequest(r)
|
||||
if err != nil {
|
||||
if err := httputils.CheckForJSON(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// FIXME(thaJeztah): change this to unmarshal just [container.Config]:
|
||||
// The commit endpoint accepts a [container.Config], but the decoder uses a
|
||||
// [container.CreateRequest], which is a superset, and also contains
|
||||
// [container.HostConfig] and [network.NetworkConfig]. Those structs
|
||||
// are discarded here, but decoder.DecodeConfig also performs validation,
|
||||
// so a request containing those additional fields would result in a
|
||||
// validation error.
|
||||
config, _, _, err := c.decoder.DecodeConfig(r.Body)
|
||||
if err != nil && !errors.Is(err, io.EOF) { // Do not fail if body is empty.
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,12 +119,6 @@ func (c *containerRouter) getContainersJSON(ctx context.Context, w http.Response
|
||||
}
|
||||
}
|
||||
|
||||
if versions.LessThan(version, "1.52") {
|
||||
for _, c := range containers {
|
||||
c.Health = nil
|
||||
}
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, containers)
|
||||
}
|
||||
|
||||
@@ -497,14 +479,26 @@ func (c *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
||||
|
||||
name := r.Form.Get("name")
|
||||
|
||||
// TODO(thaJeztah): do we prefer [backend.ContainerCreateConfig] here?
|
||||
req, err := runconfig.DecodeCreateRequest(r.Body, c.backend.RawSysInfo())
|
||||
config, hostConfig, networkingConfig, err := c.decoder.DecodeConfig(r.Body)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return errdefs.InvalidParameter(errors.New("invalid JSON: got EOF while reading request body"))
|
||||
}
|
||||
return err
|
||||
}
|
||||
// TODO(thaJeztah): update code below to take [container.CreateRequest] or [backend.ContainerCreateConfig] directly.
|
||||
config, hostConfig, networkingConfig := req.Config, req.HostConfig, req.NetworkingConfig
|
||||
|
||||
if config == nil {
|
||||
return errdefs.InvalidParameter(runconfig.ErrEmptyConfig)
|
||||
}
|
||||
if hostConfig == nil {
|
||||
hostConfig = &container.HostConfig{}
|
||||
}
|
||||
if networkingConfig == nil {
|
||||
networkingConfig = &network.NetworkingConfig{}
|
||||
}
|
||||
if networkingConfig.EndpointsConfig == nil {
|
||||
networkingConfig.EndpointsConfig = make(map[string]*network.EndpointSettings)
|
||||
}
|
||||
// The NetworkMode "default" is used as a way to express a container should
|
||||
// be attached to the OS-dependant default network, in an OS-independent
|
||||
// way. Doing this conversion as soon as possible ensures we have less
|
||||
@@ -537,7 +531,7 @@ func (c *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
||||
}
|
||||
|
||||
// Ignore KernelMemoryTCP because it was added in API 1.40.
|
||||
hostConfig.KernelMemoryTCP = 0
|
||||
hostConfig.KernelMemoryTCP = 0 //nolint:staticcheck // ignore SA1019 This field is still used for legacy support.
|
||||
|
||||
// Older clients (API < 1.40) expects the default to be shareable, make them happy
|
||||
if hostConfig.IpcMode.IsEmpty() {
|
||||
@@ -547,7 +541,7 @@ func (c *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
||||
|
||||
if versions.LessThan(version, "1.41") {
|
||||
// Older clients expect the default to be "host" on cgroup v1 hosts
|
||||
if hostConfig.CgroupnsMode.IsEmpty() && !c.backend.RawSysInfo().CgroupUnified {
|
||||
if !c.cgroup2 && hostConfig.CgroupnsMode.IsEmpty() {
|
||||
hostConfig.CgroupnsMode = container.CgroupnsModeHost
|
||||
}
|
||||
}
|
||||
@@ -751,7 +745,7 @@ func handleMACAddressBC(config *container.Config, hostConfig *container.HostConf
|
||||
return "", nil
|
||||
}
|
||||
if !hostConfig.NetworkMode.IsBridge() && !hostConfig.NetworkMode.IsUserDefined() {
|
||||
return "", errdefs.InvalidParameter(errors.New("conflicting options: mac-address and the network mode"))
|
||||
return "", runconfig.ErrConflictContainerNetworkAndMac
|
||||
}
|
||||
|
||||
epConfig, err := epConfigForNetMode(version, hostConfig.NetworkMode, networkingConfig)
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/v2/daemon/libnetwork/netlabel"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/libnetwork/netlabel"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@@ -9,9 +9,9 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
gddohttputil "github.com/golang/gddo/httputil"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
)
|
||||
|
||||
// setContainerPathStatHeader encodes the stat to JSON, base64 encode, and place in a header.
|
||||
@@ -92,10 +92,8 @@ func (c *containerRouter) putContainersArchive(ctx context.Context, w http.Respo
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO(thaJeztah): reverse the default: deprecate noOverwriteDirNonDir and add "allowOverwriteDirWithFile" (or similar) argument to opt-in.
|
||||
allowOverwriteDirWithFile := !r.Form.Has("noOverwriteDirNonDir") || !httputils.BoolValue(r, "noOverwriteDirNonDir")
|
||||
|
||||
noOverwriteDirNonDir := httputils.BoolValue(r, "noOverwriteDirNonDir")
|
||||
copyUIDGID := httputils.BoolValue(r, "copyUIDGID")
|
||||
|
||||
return c.backend.ContainerExtractToDir(v.Name, v.Path, copyUIDGID, allowOverwriteDirWithFile, r.Body)
|
||||
return c.backend.ContainerExtractToDir(v.Name, v.Path, copyUIDGID, noOverwriteDirNonDir, r.Body)
|
||||
}
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/api/pkg/stdcopy"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/internal/sliceutil"
|
||||
"github.com/moby/moby/v2/daemon/internal/stringid"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/internal/sliceutil"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
)
|
||||
|
||||
// getContainersByName inspects container's configuration and serializes it as json.
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/v2/daemon/internal/unix_noeintr"
|
||||
"github.com/docker/docker/internal/unix_noeintr"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
)
|
||||
|
||||
// NewRouter creates a new debug router
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/distribution"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
)
|
||||
|
||||
// Backend is all the methods that need to be implemented
|
||||
@@ -1,6 +1,6 @@
|
||||
package distribution
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/router"
|
||||
import "github.com/docker/docker/api/server/router"
|
||||
|
||||
// distributionRouter is a router to talk with the registry
|
||||
type distributionRouter struct {
|
||||
@@ -8,11 +8,12 @@ import (
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
distributionpkg "github.com/moby/moby/v2/daemon/internal/distribution"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
distributionpkg "github.com/docker/docker/distribution"
|
||||
"github.com/docker/docker/errdefs"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -64,7 +65,7 @@ func (dr *distributionRouter) getDistributionInfo(ctx context.Context, w http.Re
|
||||
// - https://github.com/moby/moby/blob/12c7411b6b7314bef130cd59f1c7384a7db06d0b/distribution/pull.go#L76-L152
|
||||
var lastErr error
|
||||
for _, repo := range repos {
|
||||
distributionInspect, err := fetchManifest(ctx, repo, namedRef)
|
||||
distributionInspect, err := dr.fetchManifest(ctx, repo, namedRef)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
@@ -74,7 +75,7 @@ func (dr *distributionRouter) getDistributionInfo(ctx context.Context, w http.Re
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func fetchManifest(ctx context.Context, distrepo distribution.Repository, namedRef reference.Named) (registry.DistributionInspect, error) {
|
||||
func (dr *distributionRouter) fetchManifest(ctx context.Context, distrepo distribution.Repository, namedRef reference.Named) (registry.DistributionInspect, error) {
|
||||
var distributionInspect registry.DistributionInspect
|
||||
if canonicalRef, ok := namedRef.(reference.Canonical); !ok {
|
||||
namedRef = reference.TagNameOnly(namedRef)
|
||||
@@ -124,11 +125,6 @@ func fetchManifest(ctx context.Context, distrepo distribution.Repository, namedR
|
||||
if err != nil {
|
||||
return registry.DistributionInspect{}, err
|
||||
}
|
||||
switch mediaType {
|
||||
case distributionpkg.MediaTypeDockerSchema1Manifest, distributionpkg.MediaTypeDockerSchema1SignedManifest:
|
||||
return registry.DistributionInspect{}, distributionpkg.DeprecatedSchema1ImageError(namedRef)
|
||||
}
|
||||
|
||||
// update MediaType because registry might return something incorrect
|
||||
distributionInspect.Descriptor.MediaType = mediaType
|
||||
if distributionInspect.Descriptor.Size == 0 {
|
||||
@@ -157,6 +153,10 @@ func fetchManifest(ctx context.Context, distrepo distribution.Repository, namedR
|
||||
distributionInspect.Platforms = append(distributionInspect.Platforms, platform)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(thaJeztah); we only use this to produce a nice error, but as a result, we can't remove libtrust as dependency - see if we can reduce the dependencies, but still able to detect it's a deprecated manifest
|
||||
case *schema1.SignedManifest:
|
||||
return registry.DistributionInspect{}, distributionpkg.DeprecatedSchema1ImageError(namedRef)
|
||||
}
|
||||
return distributionInspect, nil
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
)
|
||||
|
||||
// ExperimentalRoute defines an experimental API route that can be enabled or disabled.
|
||||
@@ -1,3 +1,6 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
|
||||
package grpc
|
||||
|
||||
import (
|
||||
@@ -8,11 +11,11 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/v2/defaults"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
"github.com/docker/docker/internal/otelutil"
|
||||
"github.com/moby/buildkit/util/grpcerrors"
|
||||
"github.com/moby/buildkit/util/stack"
|
||||
"github.com/moby/buildkit/util/tracing"
|
||||
"github.com/moby/moby/v2/daemon/internal/otelutil"
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"golang.org/x/net/http2"
|
||||
"google.golang.org/grpc"
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
dockerimage "github.com/moby/moby/v2/daemon/internal/image"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
dockerimage "github.com/docker/docker/image"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@@ -32,9 +32,9 @@ type imageBackend interface {
|
||||
}
|
||||
|
||||
type importExportBackend interface {
|
||||
LoadImage(ctx context.Context, inTar io.ReadCloser, platformList []ocispec.Platform, outStream io.Writer, quiet bool) error
|
||||
LoadImage(ctx context.Context, inTar io.ReadCloser, platform *ocispec.Platform, outStream io.Writer, quiet bool) error
|
||||
ImportImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, msg string, layerReader io.Reader, changes []string) (dockerimage.ID, error)
|
||||
ExportImage(ctx context.Context, names []string, platformList []ocispec.Platform, outStream io.Writer) error
|
||||
ExportImage(ctx context.Context, names []string, platform *ocispec.Platform, outStream io.Writer) error
|
||||
}
|
||||
|
||||
type registryBackend interface {
|
||||
@@ -1,7 +1,7 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
)
|
||||
|
||||
// imageRouter is a router to talk with the image controller
|
||||
@@ -12,19 +12,20 @@ import (
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/pkg/progress"
|
||||
"github.com/moby/moby/api/pkg/streamformatter"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
imagetypes "github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/builder/remotecontext"
|
||||
"github.com/moby/moby/v2/daemon/internal/image"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/dockerversion"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
imagetypes "github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/builder/remotecontext"
|
||||
"github.com/docker/docker/dockerversion"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
@@ -166,14 +167,11 @@ func (ir *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter
|
||||
return err
|
||||
}
|
||||
|
||||
var authConfig *registry.AuthConfig
|
||||
if authEncoded := r.Header.Get(registry.AuthHeader); authEncoded != "" {
|
||||
// Handle the authConfig as a header, but ignore invalid AuthConfig
|
||||
// to increase compatibility with the existing API.
|
||||
//
|
||||
// TODO(thaJeztah): accept empty values but return an error when failing to decode.
|
||||
authConfig, _ = registry.DecodeAuthConfig(authEncoded)
|
||||
}
|
||||
// Handle the authConfig as a header, but ignore invalid AuthConfig
|
||||
// to increase compatibility with the existing API.
|
||||
//
|
||||
// TODO(thaJeztah): accept empty values but return an error when failing to decode.
|
||||
authConfig, _ := registry.DecodeAuthConfig(r.Header.Get(registry.AuthHeader))
|
||||
|
||||
output := ioutils.NewWriteFlusher(w)
|
||||
defer output.Close()
|
||||
@@ -235,7 +233,6 @@ func (ir *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter,
|
||||
|
||||
output := ioutils.NewWriteFlusher(w)
|
||||
defer output.Close()
|
||||
|
||||
var names []string
|
||||
if name, ok := vars["name"]; ok {
|
||||
names = []string{name}
|
||||
@@ -243,28 +240,27 @@ func (ir *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter,
|
||||
names = r.Form["names"]
|
||||
}
|
||||
|
||||
var platformList []ocispec.Platform
|
||||
// platform param was introduced in API version 1.48
|
||||
var platform *ocispec.Platform
|
||||
if versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.48") {
|
||||
var err error
|
||||
formPlatforms := r.Form["platform"]
|
||||
// multi-platform params were introduced in API version 1.52
|
||||
if versions.LessThan(httputils.VersionFromContext(ctx), "1.52") && len(formPlatforms) > 1 {
|
||||
return errdefs.InvalidParameter(errors.New("multiple platform parameters are not supported in this API version; use API version 1.52 or later"))
|
||||
if formPlatforms := r.Form["platform"]; len(formPlatforms) > 1 {
|
||||
// TODO(thaJeztah): remove once we support multiple platforms: see https://github.com/moby/moby/issues/48759
|
||||
return errdefs.InvalidParameter(errors.New("multiple platform parameters not supported"))
|
||||
}
|
||||
platformList, err = httputils.DecodePlatforms(formPlatforms)
|
||||
if err != nil {
|
||||
return err
|
||||
if formPlatform := r.Form.Get("platform"); formPlatform != "" {
|
||||
p, err := httputils.DecodePlatform(formPlatform)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
platform = p
|
||||
}
|
||||
}
|
||||
|
||||
if err := ir.backend.ExportImage(ctx, names, platformList, output); err != nil {
|
||||
if err := ir.backend.ExportImage(ctx, names, platform, output); err != nil {
|
||||
if !output.Flushed() {
|
||||
return err
|
||||
}
|
||||
_, _ = output.Write(streamformatter.FormatError(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -273,18 +269,18 @@ func (ir *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter
|
||||
return err
|
||||
}
|
||||
|
||||
var platformList []ocispec.Platform
|
||||
// platform param was introduced in API version 1.48
|
||||
var platform *ocispec.Platform
|
||||
if versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.48") {
|
||||
var err error
|
||||
formPlatforms := r.Form["platform"]
|
||||
// multi-platform params were introduced in API version 1.52
|
||||
if versions.LessThan(httputils.VersionFromContext(ctx), "1.52") && len(formPlatforms) > 1 {
|
||||
return errdefs.InvalidParameter(errors.New("multiple platform parameters are not supported in this API version; use API version 1.52 or later"))
|
||||
if formPlatforms := r.Form["platform"]; len(formPlatforms) > 1 {
|
||||
// TODO(thaJeztah): remove once we support multiple platforms: see https://github.com/moby/moby/issues/48759
|
||||
return errdefs.InvalidParameter(errors.New("multiple platform parameters not supported"))
|
||||
}
|
||||
platformList, err = httputils.DecodePlatforms(formPlatforms)
|
||||
if err != nil {
|
||||
return err
|
||||
if formPlatform := r.Form.Get("platform"); formPlatform != "" {
|
||||
p, err := httputils.DecodePlatform(formPlatform)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
platform = p
|
||||
}
|
||||
}
|
||||
quiet := httputils.BoolValueOrDefault(r, "quiet", true)
|
||||
@@ -293,8 +289,7 @@ func (ir *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter
|
||||
|
||||
output := ioutils.NewWriteFlusher(w)
|
||||
defer output.Close()
|
||||
|
||||
if err := ir.backend.LoadImage(ctx, r.Body, platformList, output, quiet); err != nil {
|
||||
if err := ir.backend.LoadImage(ctx, r.Body, platform, output, quiet); err != nil {
|
||||
_, _ = output.Write(streamformatter.FormatError(err))
|
||||
}
|
||||
return nil
|
||||
@@ -322,19 +317,19 @@ func (ir *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter,
|
||||
force := httputils.BoolValue(r, "force")
|
||||
prune := !httputils.BoolValue(r, "noprune")
|
||||
|
||||
var p []ocispec.Platform
|
||||
var platforms []ocispec.Platform
|
||||
if versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.50") {
|
||||
val, err := httputils.DecodePlatforms(r.Form["platforms"])
|
||||
p, err := httputils.DecodePlatforms(r.Form["platforms"])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p = val
|
||||
platforms = p
|
||||
}
|
||||
|
||||
list, err := ir.backend.ImageDelete(ctx, name, imagetypes.RemoveOptions{
|
||||
Force: force,
|
||||
PruneChildren: prune,
|
||||
Platforms: p,
|
||||
Platforms: platforms,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -591,14 +586,10 @@ func (ir *imageRouter) postImagesPrune(ctx context.Context, w http.ResponseWrite
|
||||
return httputils.WriteJSON(w, http.StatusOK, pruneReport)
|
||||
}
|
||||
|
||||
// noBaseImageSpecifier is the symbol used by the FROM
|
||||
// command to specify that no base image is to be used.
|
||||
const noBaseImageSpecifier = "scratch"
|
||||
|
||||
// validateRepoName validates the name of a repository.
|
||||
func validateRepoName(name reference.Named) error {
|
||||
familiarName := reference.FamiliarName(name)
|
||||
if familiarName == noBaseImageSpecifier {
|
||||
if familiarName == api.NoBaseImageSpecifier {
|
||||
return fmt.Errorf("'%s' is a reserved name", familiarName)
|
||||
}
|
||||
return nil
|
||||
@@ -1,10 +1,13 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"maps"
|
||||
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
)
|
||||
|
||||
// legacyConfigFields defines legacy image-config fields to include in
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/image"
|
||||
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@@ -3,7 +3,7 @@ package router
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
)
|
||||
|
||||
// RouteWrapper wraps a route with extra functionality.
|
||||
@@ -3,9 +3,9 @@ package network
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
)
|
||||
|
||||
// Backend is all the methods that need to be implemented
|
||||
@@ -1,7 +1,7 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/v2/daemon/server/router"
|
||||
"github.com/docker/docker/api/server/router"
|
||||
)
|
||||
|
||||
// networkRouter is a router to talk with the network controller
|
||||
@@ -6,14 +6,14 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/libnetwork"
|
||||
"github.com/moby/moby/v2/daemon/libnetwork/scope"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/libnetwork"
|
||||
"github.com/docker/docker/libnetwork/scope"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -6,24 +6,24 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
plugintypes "github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/v2/daemon/pkg/plugin"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/plugin"
|
||||
)
|
||||
|
||||
// Backend for Plugin
|
||||
type Backend interface {
|
||||
Disable(name string, config *backend.PluginDisableConfig) error
|
||||
Enable(name string, config *backend.PluginEnableConfig) error
|
||||
List(filters.Args) ([]plugintypes.Plugin, error)
|
||||
Inspect(name string) (*plugintypes.Plugin, error)
|
||||
List(filters.Args) ([]types.Plugin, error)
|
||||
Inspect(name string) (*types.Plugin, error)
|
||||
Remove(name string, config *backend.PluginRmConfig) error
|
||||
Set(name string, args []string) error
|
||||
Privileges(ctx context.Context, ref reference.Named, metaHeaders http.Header, authConfig *registry.AuthConfig) (plugintypes.Privileges, error)
|
||||
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges plugintypes.Privileges, outStream io.Writer, opts ...plugin.CreateOpt) error
|
||||
Privileges(ctx context.Context, ref reference.Named, metaHeaders http.Header, authConfig *registry.AuthConfig) (types.PluginPrivileges, error)
|
||||
Pull(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer, opts ...plugin.CreateOpt) error
|
||||
Push(ctx context.Context, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, outStream io.Writer) error
|
||||
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges plugintypes.Privileges, outStream io.Writer) error
|
||||
CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, options *backend.PluginCreateConfig) error
|
||||
Upgrade(ctx context.Context, ref reference.Named, name string, metaHeaders http.Header, authConfig *registry.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) error
|
||||
CreateFromContext(ctx context.Context, tarCtx io.ReadCloser, options *types.PluginCreateOptions) error
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package plugin
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/router"
|
||||
import "github.com/docker/docker/api/server/router"
|
||||
|
||||
// pluginRouter is a router to talk with the plugin controller
|
||||
type pluginRouter struct {
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/pkg/streamformatter"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/pkg/ioutils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -84,7 +84,7 @@ func (pr *pluginRouter) upgradePlugin(ctx context.Context, w http.ResponseWriter
|
||||
return errors.Wrap(err, "failed to parse form")
|
||||
}
|
||||
|
||||
var privileges plugin.Privileges
|
||||
var privileges types.PluginPrivileges
|
||||
if err := httputils.ReadJSON(r, &privileges); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func (pr *pluginRouter) pullPlugin(ctx context.Context, w http.ResponseWriter, r
|
||||
return errors.Wrap(err, "failed to parse form")
|
||||
}
|
||||
|
||||
var privileges plugin.Privileges
|
||||
var privileges types.PluginPrivileges
|
||||
if err := httputils.ReadJSON(r, &privileges); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -186,10 +186,11 @@ func (pr *pluginRouter) createPlugin(ctx context.Context, w http.ResponseWriter,
|
||||
return err
|
||||
}
|
||||
|
||||
err := pr.backend.CreateFromContext(ctx, r.Body, &backend.PluginCreateConfig{
|
||||
options := &types.PluginCreateOptions{
|
||||
RepoName: r.FormValue("name"),
|
||||
})
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
if err := pr.backend.CreateFromContext(ctx, r.Body, options); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: send progress bar
|
||||
@@ -202,13 +203,14 @@ func (pr *pluginRouter) enablePlugin(ctx context.Context, w http.ResponseWriter,
|
||||
return err
|
||||
}
|
||||
|
||||
name := vars["name"]
|
||||
timeout, err := strconv.Atoi(r.Form.Get("timeout"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := &backend.PluginEnableConfig{Timeout: timeout}
|
||||
|
||||
name := vars["name"]
|
||||
return pr.backend.Enable(name, &backend.PluginEnableConfig{Timeout: timeout})
|
||||
return pr.backend.Enable(name, config)
|
||||
}
|
||||
|
||||
func (pr *pluginRouter) disablePlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
@@ -216,9 +218,12 @@ func (pr *pluginRouter) disablePlugin(ctx context.Context, w http.ResponseWriter
|
||||
return err
|
||||
}
|
||||
|
||||
return pr.backend.Disable(vars["name"], &backend.PluginDisableConfig{
|
||||
name := vars["name"]
|
||||
config := &backend.PluginDisableConfig{
|
||||
ForceDisable: httputils.BoolValue(r, "force"),
|
||||
})
|
||||
}
|
||||
|
||||
return pr.backend.Disable(name, config)
|
||||
}
|
||||
|
||||
func (pr *pluginRouter) removePlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
@@ -227,9 +232,10 @@ func (pr *pluginRouter) removePlugin(ctx context.Context, w http.ResponseWriter,
|
||||
}
|
||||
|
||||
name := vars["name"]
|
||||
return pr.backend.Remove(name, &backend.PluginRmConfig{
|
||||
config := &backend.PluginRmConfig{
|
||||
ForceRemove: httputils.BoolValue(r, "force"),
|
||||
})
|
||||
}
|
||||
return pr.backend.Remove(name, config)
|
||||
}
|
||||
|
||||
func (pr *pluginRouter) pushPlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
@@ -1,6 +1,6 @@
|
||||
package router
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/httputils"
|
||||
import "github.com/docker/docker/api/server/httputils"
|
||||
|
||||
// Router defines an interface to specify a group of routes to add to the docker server.
|
||||
type Router interface {
|
||||
@@ -1,6 +1,6 @@
|
||||
package session
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/router"
|
||||
import "github.com/docker/docker/api/server/router"
|
||||
|
||||
// sessionRouter is a router to talk with the session controller
|
||||
type sessionRouter struct {
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/errdefs"
|
||||
)
|
||||
|
||||
func (sr *sessionRouter) startSession(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
@@ -3,9 +3,9 @@ package swarm
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
)
|
||||
|
||||
// Backend abstracts a swarm manager.
|
||||
@@ -1,6 +1,6 @@
|
||||
package swarm
|
||||
|
||||
import "github.com/moby/moby/v2/daemon/server/router"
|
||||
import "github.com/docker/docker/api/server/router"
|
||||
|
||||
// swarmRouter is a router to talk with the build controller
|
||||
type swarmRouter struct {
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
types "github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/moby/moby/v2/errdefs"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
types "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -470,7 +470,7 @@ func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter,
|
||||
rawVersion := r.URL.Query().Get("version")
|
||||
version, err := strconv.ParseUint(rawVersion, 10, 64)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(errors.New("invalid secret version"))
|
||||
return errdefs.InvalidParameter(fmt.Errorf("invalid secret version"))
|
||||
}
|
||||
|
||||
id := vars["id"]
|
||||
@@ -542,7 +542,7 @@ func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter,
|
||||
rawVersion := r.URL.Query().Get("version")
|
||||
version, err := strconv.ParseUint(rawVersion, 10, 64)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(errors.New("invalid config version"))
|
||||
return errdefs.InvalidParameter(fmt.Errorf("invalid config version"))
|
||||
}
|
||||
|
||||
id := vars["id"]
|
||||
@@ -2,15 +2,15 @@ package swarm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
basictypes "github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/moby/moby/v2/daemon/server/httputils"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
basictypes "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
)
|
||||
|
||||
// swarmLogs takes an http response, request, and selector, and writes the logs
|
||||
@@ -23,7 +23,7 @@ func (sr *swarmRouter) swarmLogs(ctx context.Context, w http.ResponseWriter, r *
|
||||
// with the appropriate status code.
|
||||
stdout, stderr := httputils.BoolValue(r, "stdout"), httputils.BoolValue(r, "stderr")
|
||||
if !stdout && !stderr {
|
||||
return errors.New("Bad parameters: you must choose at least one stream")
|
||||
return fmt.Errorf("Bad parameters: you must choose at least one stream")
|
||||
}
|
||||
|
||||
// there is probably a neater way to manufacture the LogsOptions
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
)
|
||||
|
||||
func TestAdjustForAPIVersion(t *testing.T) {
|
||||
@@ -4,14 +4,14 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/events"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"github.com/moby/moby/v2/daemon/server/backend"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
)
|
||||
|
||||
// Backend is the methods that need to be implemented to provide
|
||||
@@ -20,9 +20,9 @@ type Backend interface {
|
||||
SystemInfo(context.Context) (*system.Info, error)
|
||||
SystemVersion(context.Context) (types.Version, error)
|
||||
SystemDiskUsage(ctx context.Context, opts backend.DiskUsageOptions) (*backend.DiskUsage, error)
|
||||
SubscribeToEvents(since, until time.Time, ef filters.Args) ([]events.Message, chan any)
|
||||
UnsubscribeFromEvents(chan any)
|
||||
AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, error)
|
||||
SubscribeToEvents(since, until time.Time, ef filters.Args) ([]events.Message, chan interface{})
|
||||
UnsubscribeFromEvents(chan interface{})
|
||||
AuthenticateToRegistry(ctx context.Context, authConfig *registry.AuthConfig) (string, string, error)
|
||||
}
|
||||
|
||||
// ClusterBackend is all the methods that need to be implemented
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user