Compare commits
272 Commits
v0.11.0-rc
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d85ad5269 | |||
|
|
008ce88567 | ||
|
|
17a7e99226 | ||
|
|
027a8c16e7 | ||
| a12bc79097 | |||
| a0b5a420e8 | |||
|
|
0151ea9a3f | ||
|
|
221d091b68 | ||
| 1760b8b586 | |||
|
|
4d142d8b45 | ||
|
|
44dd1f1f5e | ||
|
|
f35b2b7cab | ||
|
|
29ba5ecef6 | ||
|
|
87e8e4b847 | ||
|
|
a71a24c0f4 | ||
|
|
76119b0f61 | ||
|
|
7843b5f417 | ||
|
|
da6662975f | ||
|
|
de4dbb7d00 | ||
|
|
3bd4bca994 | ||
|
|
296832c90e | ||
|
|
56d55a4137 | ||
|
|
626e6f8fa3 | ||
|
|
5941bf0494 | ||
|
|
29a496cdab | ||
|
|
a43d9a67c7 | ||
|
|
c47eb3bf5a | ||
|
|
a97e1641a4 | ||
|
|
86ae8ea854 | ||
|
|
d37d483097 | ||
|
|
4e96faa201 | ||
|
|
e5419ef6d7 | ||
|
|
14747a490a | ||
|
|
e5cee892ed | ||
|
|
ef4b984df4 | ||
|
|
a8f402e28d | ||
|
|
2eba99b40b | ||
|
|
7686fa1f16 | ||
|
|
51b9bab245 | ||
|
|
6b5758f4cd | ||
|
|
bd375a14a8 | ||
|
|
b01693f63e | ||
|
|
4a059d5144 | ||
|
|
f3775c0046 | ||
|
|
50fbdd86f9 | ||
|
|
1f61de0fcc | ||
|
|
e206c585bb | ||
|
|
5e46d8057d | ||
|
|
4e7709e54c | ||
|
|
5ed8f1b7d9 | ||
|
|
1d12c1f5b3 | ||
|
|
3ef93e081c | ||
|
|
18894a8e3a | ||
|
|
13ec635988 | ||
|
|
f804b8fa4b | ||
|
|
21a55ff9a1 | ||
|
|
dd350284df | ||
|
|
c010d3de8d | ||
|
|
d11dbbf9f7 | ||
|
|
75cdceb9f1 | ||
|
|
10ff93f190 | ||
|
|
bf00185809 | ||
|
|
90f03e57c2 | ||
|
|
a59fd3ebfe | ||
|
|
3eb490153d | ||
|
|
d957d8b987 | ||
|
|
5a1f252bd9 | ||
|
|
ab4585f38c | ||
|
|
3003045c0b | ||
|
|
a6f3f290b4 | ||
|
|
27d072a099 | ||
|
|
8e3df1943c | ||
|
|
8c54de66ce | ||
|
|
06b9ac2dc4 | ||
|
|
b8739d7441 | ||
|
|
23fe02993b | ||
|
|
1d177f00d2 | ||
|
|
ceaba7011f | ||
|
|
9c06f383ba | ||
|
|
e11c5e3e96 | ||
|
|
f5719f3017 | ||
|
|
163babdca7 | ||
|
|
094d1aded8 | ||
|
|
05ef20b434 | ||
|
|
cc718b3444 | ||
|
|
e98e8f6ac9 | ||
|
|
36541ed9d5 | ||
|
|
418ea82d3a | ||
|
|
130bbda00e | ||
|
|
2666bd6996 | ||
|
|
ff2c8da803 | ||
|
|
e094296f37 | ||
|
|
7c3b77fb36 | ||
|
|
fb4c4f07ca | ||
|
|
b9e25e82cf | ||
|
|
089036da29 | ||
|
|
1123bfed10 | ||
|
|
7f2293308b | ||
|
|
a65131f9d3 | ||
|
|
8a3a646c61 | ||
|
|
4384947be1 | ||
|
|
69421182ca | ||
|
|
068382f5df | ||
|
|
c4bec05466 | ||
|
|
89e1ac0a6e | ||
|
|
b84e0e11b4 | ||
|
|
d95f5f8f3b | ||
|
|
b4c0941683 | ||
|
|
cf9798cede | ||
|
|
20d2501edc | ||
|
|
d45601fdc6 | ||
|
|
c81a9a89cf | ||
|
|
87b9f9ecfb | ||
|
|
cbc473359a | ||
|
|
2eba60db75 | ||
|
|
0dcbed3f53 | ||
|
|
ca08eb65e2 | ||
|
|
6f37d9bee7 | ||
|
|
e65f6b8c8b | ||
|
|
707dc43d55 | ||
|
|
8cbb7a9319 | ||
|
|
4f5a56aadb | ||
|
|
399beb53d9 | ||
|
|
7dec9fd6e7 | ||
|
|
120f3a8918 | ||
|
|
bd672eaf5b | ||
|
|
c2500ea2d8 | ||
|
|
a4663b4b2e | ||
|
|
57c618b83a | ||
|
|
b3a4f95110 | ||
|
|
28a1eb3527 | ||
|
|
75ecc15958 | ||
|
|
2235ebce2f | ||
|
|
7147463418 | ||
|
|
010e4c8d54 | ||
|
|
6f394a0691 | ||
|
|
efd7279118 | ||
|
|
601056f3a7 | ||
|
|
0a7f96cbfb | ||
|
|
1c530c2fe0 | ||
|
|
1e576dd7c6 | ||
|
|
7a5472153b | ||
|
|
b986ce566b | ||
|
|
daba16f4be | ||
|
|
ee36e2264e | ||
|
|
329e98d9f0 | ||
|
|
f4513f7028 | ||
|
|
b1c5449428 | ||
|
|
431732f5d1 | ||
|
|
687feca9e8 | ||
|
|
d4a2c8d0c3 | ||
|
|
bef42b2441 | ||
|
|
2de333fdd3 | ||
|
|
1138789f20 | ||
|
|
1f4ac09ffb | ||
|
|
26a8ffb393 | ||
|
|
9b7aada99b | ||
|
|
fd6207695b | ||
|
|
def96d2bf4 | ||
|
|
f5f00e68ef | ||
|
|
14aebe713e | ||
|
|
9d2388e6f5 | ||
|
|
75e2c46295 | ||
|
|
2c02db8db4 | ||
|
|
e304a05d2a | ||
|
|
14c1ea0e11 | ||
|
|
c30bcade2c | ||
|
|
62bfb19db4 | ||
|
|
47e34f2684 | ||
|
|
3d981be4ad | ||
|
|
5d94b0fcc7 | ||
|
|
569c66fb62 | ||
|
|
93f7fbdd78 | ||
|
|
ea06685c11 | ||
|
|
eaba4fa9e6 | ||
|
|
99e3882e2a | ||
|
|
0a2f35970c | ||
|
|
ab5f5e4169 | ||
|
|
696770d29c | ||
|
|
b47b4e5957 | ||
|
|
9a125afba0 | ||
|
|
d34103b0d9 | ||
|
|
c820350b5e | ||
|
|
61a7854659 | ||
|
|
e859ebc12e | ||
|
|
ef997fd6d0 | ||
|
|
76c96347ff | ||
|
|
48d7dafbd5 | ||
|
|
d03e93f6f1 | ||
|
|
fcb7810a38 | ||
|
|
459d94bdf1 | ||
|
|
7cef021a8a | ||
|
|
c6db4cf342 | ||
|
|
6c9436fbd5 | ||
|
|
a906149930 | ||
|
|
af328fe413 | ||
|
|
183a73abae | ||
|
|
b7f0b3d763 | ||
|
|
5b27d5a9f6 | ||
|
|
8f24c58f4d | ||
|
|
cd1648192e | ||
|
|
8d822fb06c | ||
|
|
0758a9b75d | ||
|
|
f8fa526678 | ||
|
|
4abff3ce12 | ||
|
|
e7034f66bc | ||
|
|
8c65e4fc1d | ||
|
|
d196ac347e | ||
|
|
9b723ece46 | ||
|
|
5e2f8bd64a | ||
|
|
5788ab33d2 | ||
|
|
f1788002e1 | ||
|
|
6c62225d1b | ||
|
|
38b4eef5c6 | ||
|
|
a4db138c5e | ||
|
|
55377b2b0f | ||
|
|
98dedd3225 | ||
|
|
74b121be66 | ||
|
|
b9cf46785b | ||
|
|
ecf8dd0a26 | ||
|
|
73c17ef4d2 | ||
|
|
e762e46b4b | ||
|
|
cafeedba79 | ||
|
|
17bdbbd3c3 | ||
|
|
2dae553d18 | ||
|
|
91c17f25fb | ||
|
|
63fc01e08a | ||
|
|
354ccc9469 | ||
|
|
68ae67720a | ||
|
|
b273db20c3 | ||
|
|
0ae88ecc4d | ||
|
|
341fb65f6f | ||
|
|
69a9c6609a | ||
|
|
1c96fdaf03 | ||
|
|
c77bd8a578 | ||
|
|
e5f701351c | ||
|
|
09798cdebd | ||
|
|
0dfc35d558 | ||
|
|
8085f57a3a | ||
|
|
d582a21acd | ||
|
|
580820a4de | ||
|
|
b7e8afc61b | ||
|
|
a8a637e19d | ||
|
|
79632a4c4c | ||
|
|
a6b0959276 | ||
|
|
6d7142b057 | ||
|
|
d0bff18cee | ||
|
|
7e39644f69 | ||
|
|
adc6349b28 | ||
|
|
f558fd8b22 | ||
|
|
432e16ef70 | ||
|
|
8c86c2242a | ||
|
|
75ad5d732b | ||
|
|
9bd0202312 | ||
|
|
367f114cc7 | ||
|
|
2959ce205e | ||
|
|
75b5c6560f | ||
|
|
4429ccbcc2 | ||
|
|
c59fc18325 | ||
|
|
4ce80856b3 | ||
|
|
af3feec4ea | ||
|
|
90c849f5ef | ||
|
|
6024212ac8 | ||
|
|
2d124e0ce9 | ||
|
|
e61a8cf637 | ||
|
|
167cd16acb | ||
|
|
1dd31fefcb | ||
|
|
5a12b25bab | ||
|
|
b702188b65 | ||
|
|
8ad30d0a35 | ||
|
|
89d99b1694 | ||
|
|
9753f63f57 |
25
.devcontainer/devcontainer.json
Normal file
25
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,25 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/go
|
||||
{
|
||||
"name": "Go",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
||||
}
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "go version",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
54
.github/CONTRIBUTING.md
vendored
54
.github/CONTRIBUTING.md
vendored
@@ -116,6 +116,60 @@ commit automatically with `git commit -s`.
|
||||
|
||||
### Run the unit- and integration-tests
|
||||
|
||||
Running tests:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
This runs all unit and integration tests, in a containerized environment.
|
||||
Locally, every package can be tested separately with standard Go tools, but
|
||||
integration tests are skipped if local user doesn't have enough permissions or
|
||||
worker binaries are not installed.
|
||||
|
||||
```bash
|
||||
# run unit tests only
|
||||
make test-unit
|
||||
|
||||
# run integration tests only
|
||||
make test-integration
|
||||
|
||||
# test a specific package
|
||||
TESTPKGS=./bake make test
|
||||
|
||||
# run all integration tests with a specific worker
|
||||
TESTFLAGS="--run=//worker=remote -v" make test-integration
|
||||
|
||||
# run a specific integration test
|
||||
TESTFLAGS="--run /TestBuild/worker=remote/ -v" make test-integration
|
||||
|
||||
# run a selection of integration tests using a regexp
|
||||
TESTFLAGS="--run /TestBuild.*/worker=remote/ -v" make test-integration
|
||||
```
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Set `TEST_KEEP_CACHE=1` for the test framework to keep external dependant
|
||||
> images in a docker volume if you are repeatedly calling `make test`. This
|
||||
> helps to avoid rate limiting on the remote registry side.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Set `TEST_DOCKERD=1` for the test framework to enable the docker workers,
|
||||
> specifically the `docker` and `docker-container` drivers.
|
||||
>
|
||||
> The docker tests cannot be run in parallel, so require passing `--parallel=1`
|
||||
> in `TESTFLAGS`.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If you are working behind a proxy, you can set some of or all
|
||||
> `HTTP_PROXY=http://ip:port`, `HTTPS_PROXY=http://ip:port`, `NO_PROXY=http://ip:port`
|
||||
> for the test framework to specify the proxy build args.
|
||||
|
||||
|
||||
### Run the helper commands
|
||||
|
||||
To enter a demo container environment and experiment, you may run:
|
||||
|
||||
```
|
||||
|
||||
111
.github/workflows/build.yml
vendored
111
.github/workflows/build.yml
vendored
@@ -23,14 +23,18 @@ env:
|
||||
BUILDKIT_IMAGE: "moby/buildkit:latest"
|
||||
REPO_SLUG: "docker/buildx-bin"
|
||||
DESTDIR: "./bin"
|
||||
TEST_CACHE_SCOPE: "test"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
prepare-test:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
@@ -39,27 +43,99 @@ jobs:
|
||||
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Test
|
||||
name: Build
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
targets: test
|
||||
targets: integration-test-base
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=test
|
||||
*.cache-to=type=gha,scope=test
|
||||
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
||||
*.cache-to=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- prepare-test
|
||||
env:
|
||||
TESTFLAGS: "-v --parallel=6 --timeout=30m"
|
||||
TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m"
|
||||
GOTESTSUM_FORMAT: "standard-verbose"
|
||||
TEST_IMAGE_BUILD: "0"
|
||||
TEST_IMAGE_ID: "buildx-tests"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
worker:
|
||||
- docker
|
||||
- docker\+containerd # same as docker, but with containerd snapshotter
|
||||
- docker-container
|
||||
- remote
|
||||
pkg:
|
||||
- ./tests
|
||||
include:
|
||||
- pkg: ./...
|
||||
skip-integration-tests: 1
|
||||
steps:
|
||||
-
|
||||
name: Upload coverage
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
version: ${{ env.BUILDX_VERSION }}
|
||||
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
|
||||
buildkitd-flags: --debug
|
||||
-
|
||||
name: Build test image
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
targets: integration-test
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
|
||||
*.output=type=docker,name=${{ env.TEST_IMAGE_ID }}
|
||||
-
|
||||
name: Test
|
||||
run: |
|
||||
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
||||
./hack/test
|
||||
env:
|
||||
TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}"
|
||||
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
||||
TESTPKGS: "${{ matrix.pkg }}"
|
||||
SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}"
|
||||
-
|
||||
name: Send to Codecov
|
||||
if: always()
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
directory: ${{ env.DESTDIR }}/coverage
|
||||
directory: ./bin/testreports
|
||||
-
|
||||
name: Generate annotations
|
||||
if: always()
|
||||
uses: crazy-max/.github/.github/actions/gotest-annotations@1a64ea6d01db9a48aa61954cb20e265782c167d9
|
||||
with:
|
||||
directory: ./bin/testreports
|
||||
-
|
||||
name: Upload test reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-reports
|
||||
path: ./bin/testreports
|
||||
|
||||
prepare:
|
||||
prepare-binaries:
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
matrix: ${{ steps.platforms.outputs.matrix }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Create matrix
|
||||
id: platforms
|
||||
@@ -73,11 +149,11 @@ jobs:
|
||||
binaries:
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- prepare
|
||||
- prepare-binaries
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||||
platform: ${{ fromJson(needs.prepare-binaries.outputs.matrix) }}
|
||||
steps:
|
||||
-
|
||||
name: Prepare
|
||||
@@ -86,7 +162,7 @@ jobs:
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@@ -115,11 +191,13 @@ jobs:
|
||||
|
||||
bin-image:
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- test
|
||||
if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@@ -166,11 +244,12 @@ jobs:
|
||||
release:
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- test
|
||||
- binaries
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Download binaries
|
||||
uses: actions/download-artifact@v3
|
||||
@@ -204,7 +283,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
4
.github/workflows/docs-release.yml
vendored
4
.github/workflows/docs-release.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout docs repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
||||
repository: docker/docs
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
git add -A .
|
||||
-
|
||||
name: Create PR on docs repo
|
||||
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666
|
||||
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38
|
||||
with:
|
||||
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
||||
push-to-fork: docker-tools-robot/docker.github.io
|
||||
|
||||
2
.github/workflows/docs-upstream.yml
vendored
2
.github/workflows/docs-upstream.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
4
.github/workflows/e2e.yml
vendored
4
.github/workflows/e2e.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
2
.github/workflows/validate.yml
vendored
2
.github/workflows/validate.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
64
Dockerfile
64
Dockerfile
@@ -1,10 +1,12 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.20
|
||||
ARG XX_VERSION=1.1.2
|
||||
ARG DOCKERD_VERSION=20.10.14
|
||||
ARG GO_VERSION=1.20.7
|
||||
ARG XX_VERSION=1.2.1
|
||||
|
||||
FROM docker:$DOCKERD_VERSION AS dockerd-release
|
||||
ARG DOCKER_VERSION=24.0.2
|
||||
ARG GOTESTSUM_VERSION=v1.9.0
|
||||
ARG REGISTRY_VERSION=2.8.0
|
||||
ARG BUILDKIT_VERSION=v0.11.6
|
||||
|
||||
# xx is a helper for cross-compilation
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
@@ -18,6 +20,33 @@ ENV GOFLAGS=-mod=vendor
|
||||
ENV CGO_ENABLED=0
|
||||
WORKDIR /src
|
||||
|
||||
FROM registry:$REGISTRY_VERSION AS registry
|
||||
|
||||
FROM moby/buildkit:$BUILDKIT_VERSION AS buildkit
|
||||
|
||||
FROM gobase AS docker
|
||||
ARG TARGETPLATFORM
|
||||
ARG DOCKER_VERSION
|
||||
WORKDIR /opt/docker
|
||||
RUN DOCKER_ARCH=$(case ${TARGETPLATFORM:-linux/amd64} in \
|
||||
"linux/amd64") echo "x86_64" ;; \
|
||||
"linux/arm/v6") echo "armel" ;; \
|
||||
"linux/arm/v7") echo "armhf" ;; \
|
||||
"linux/arm64") echo "aarch64" ;; \
|
||||
"linux/ppc64le") echo "ppc64le" ;; \
|
||||
"linux/s390x") echo "s390x" ;; \
|
||||
*) echo "" ;; esac) \
|
||||
&& echo "DOCKER_ARCH=$DOCKER_ARCH" \
|
||||
&& wget -qO- "https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz" | tar xvz --strip 1
|
||||
RUN ./dockerd --version && ./containerd --version && ./ctr --version && ./runc --version
|
||||
|
||||
FROM gobase AS gotestsum
|
||||
ARG GOTESTSUM_VERSION
|
||||
ENV GOFLAGS=
|
||||
RUN --mount=target=/root/.cache,type=cache \
|
||||
GOBIN=/out/ go install "gotest.tools/gotestsum@${GOTESTSUM_VERSION}" && \
|
||||
/out/gotestsum --version
|
||||
|
||||
FROM gobase AS buildx-version
|
||||
RUN --mount=type=bind,target=. <<EOT
|
||||
set -e
|
||||
@@ -39,6 +68,7 @@ RUN --mount=type=bind,target=. \
|
||||
EOT
|
||||
|
||||
FROM gobase AS test
|
||||
ENV SKIP_INTEGRATION_TESTS=1
|
||||
RUN --mount=type=bind,target=. \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
@@ -61,6 +91,28 @@ FROM binaries-$TARGETOS AS binaries
|
||||
# enable scanning for this stage
|
||||
ARG BUILDKIT_SBOM_SCAN_STAGE=true
|
||||
|
||||
FROM gobase AS integration-test-base
|
||||
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
|
||||
RUN apk add --no-cache \
|
||||
btrfs-progs \
|
||||
e2fsprogs \
|
||||
e2fsprogs-extra \
|
||||
ip6tables \
|
||||
iptables \
|
||||
openssl \
|
||||
shadow-uidmap \
|
||||
xfsprogs \
|
||||
xz
|
||||
COPY --link --from=gotestsum /out/gotestsum /usr/bin/
|
||||
COPY --link --from=registry /bin/registry /usr/bin/
|
||||
COPY --link --from=docker /opt/docker/* /usr/bin/
|
||||
COPY --link --from=buildkit /usr/bin/buildkitd /usr/bin/
|
||||
COPY --link --from=buildkit /usr/bin/buildctl /usr/bin/
|
||||
COPY --link --from=binaries /buildx /usr/bin/
|
||||
|
||||
FROM integration-test-base AS integration-test
|
||||
COPY . .
|
||||
|
||||
# Release
|
||||
FROM --platform=$BUILDPLATFORM alpine AS releaser
|
||||
WORKDIR /work
|
||||
@@ -69,14 +121,14 @@ RUN --mount=from=binaries \
|
||||
--mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
|
||||
set -e
|
||||
mkdir -p /out
|
||||
cp buildx* "/out/buildx-$(cat /buildx-version/version).$(echo $TARGETPLATFORM | sed 's/\//-/g')$(ls buildx* | sed -e 's/^buildx//')"
|
||||
cp buildx* "/out/buildx"
|
||||
EOT
|
||||
|
||||
FROM scratch AS release
|
||||
COPY --from=releaser /out/ /
|
||||
|
||||
# Shell
|
||||
FROM docker:$DOCKERD_VERSION AS dockerd-release
|
||||
FROM docker:$DOCKER_VERSION AS dockerd-release
|
||||
FROM alpine AS shell
|
||||
RUN apk add --no-cache iptables tmux git vim less openssh
|
||||
RUN mkdir -p /usr/local/lib/docker/cli-plugins && ln -s /usr/local/bin/buildx /usr/local/lib/docker/cli-plugins/docker-buildx
|
||||
|
||||
10
Makefile
10
Makefile
@@ -45,7 +45,15 @@ lint:
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(BUILDX_CMD) bake test
|
||||
./hack/test
|
||||
|
||||
.PHONY: test-unit
|
||||
test-unit:
|
||||
TESTPKGS=./... SKIP_INTEGRATION_TESTS=1 ./hack/test
|
||||
|
||||
.PHONY: test
|
||||
test-integration:
|
||||
TESTPKGS=./tests ./hack/test
|
||||
|
||||
.PHONY: validate-vendor
|
||||
validate-vendor:
|
||||
|
||||
@@ -71,8 +71,9 @@ for Windows and macOS.
|
||||
|
||||
## Linux packages
|
||||
|
||||
Docker Linux packages also include Docker Buildx when installed using the
|
||||
[DEB or RPM packages](https://docs.docker.com/engine/install/).
|
||||
Docker Engine package repositories contain Docker Buildx packages when installed according to the
|
||||
[Docker Engine install documentation](https://docs.docker.com/engine/install/). Install the
|
||||
`docker-buildx-plugin` package to install the Buildx plugin.
|
||||
|
||||
## Manual download
|
||||
|
||||
@@ -148,7 +149,7 @@ $ DOCKER_BUILDKIT=1 docker build --platform=local -o . "https://github.com/docke
|
||||
$ mkdir -p ~/.docker/cli-plugins
|
||||
$ mv buildx ~/.docker/cli-plugins/docker-buildx
|
||||
|
||||
# Local
|
||||
# Local
|
||||
$ git clone https://github.com/docker/buildx.git && cd buildx
|
||||
$ make install
|
||||
```
|
||||
@@ -240,7 +241,7 @@ When you invoke a build, you can set the `--platform` flag to specify the target
|
||||
platform for the build output, (for example, `linux/amd64`, `linux/arm64`, or
|
||||
`darwin/amd64`).
|
||||
|
||||
When the current builder instance is backed by the `docker-container` or
|
||||
When the current builder instance is backed by the `docker-container` or
|
||||
`kubernetes` driver, you can specify multiple platforms together. In this case,
|
||||
it builds a manifest list which contains images for all specified architectures.
|
||||
When you use this image in [`docker run`](https://docs.docker.com/engine/reference/commandline/run/)
|
||||
|
||||
42
bake/bake.go
42
bake/bake.go
@@ -55,7 +55,7 @@ func defaultFilenames() []string {
|
||||
return names
|
||||
}
|
||||
|
||||
func ReadLocalFiles(names []string) ([]File, error) {
|
||||
func ReadLocalFiles(names []string, stdin io.Reader) ([]File, error) {
|
||||
isDefault := false
|
||||
if len(names) == 0 {
|
||||
isDefault = true
|
||||
@@ -67,7 +67,7 @@ func ReadLocalFiles(names []string) ([]File, error) {
|
||||
var dt []byte
|
||||
var err error
|
||||
if n == "-" {
|
||||
dt, err = io.ReadAll(os.Stdin)
|
||||
dt, err = io.ReadAll(stdin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -587,9 +587,9 @@ type Target struct {
|
||||
Name string `json:"-" hcl:"name,label" cty:"name"`
|
||||
|
||||
// Inherits is the only field that cannot be overridden with --set
|
||||
Attest []string `json:"attest,omitempty" hcl:"attest,optional" cty:"attest"`
|
||||
Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional" cty:"inherits"`
|
||||
|
||||
Attest []string `json:"attest,omitempty" hcl:"attest,optional" cty:"attest"`
|
||||
Context *string `json:"context,omitempty" hcl:"context,optional" cty:"context"`
|
||||
Contexts map[string]string `json:"contexts,omitempty" hcl:"contexts,optional" cty:"contexts"`
|
||||
Dockerfile *string `json:"dockerfile,omitempty" hcl:"dockerfile,optional" cty:"dockerfile"`
|
||||
@@ -620,7 +620,7 @@ var _ hclparser.WithEvalContexts = &Group{}
|
||||
var _ hclparser.WithGetName = &Group{}
|
||||
|
||||
func (t *Target) normalize() {
|
||||
t.Attest = removeDupes(t.Attest)
|
||||
t.Attest = removeAttestDupes(t.Attest)
|
||||
t.Tags = removeDupes(t.Tags)
|
||||
t.Secrets = removeDupes(t.Secrets)
|
||||
t.SSH = removeDupes(t.SSH)
|
||||
@@ -682,6 +682,7 @@ func (t *Target) Merge(t2 *Target) {
|
||||
}
|
||||
if t2.Attest != nil { // merge
|
||||
t.Attest = append(t.Attest, t2.Attest...)
|
||||
t.Attest = removeAttestDupes(t.Attest)
|
||||
}
|
||||
if t2.Secrets != nil { // merge
|
||||
t.Secrets = append(t.Secrets, t2.Secrets...)
|
||||
@@ -999,6 +1000,10 @@ func checkPath(p string) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
p, err = filepath.Abs(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1007,7 +1012,8 @@ func checkPath(p string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
|
||||
parts := strings.Split(rel, string(os.PathSeparator))
|
||||
if parts[0] == ".." {
|
||||
return errors.Errorf("path %s is outside of the working directory, please set BAKE_ALLOW_REMOTE_FS_ACCESS=1", p)
|
||||
}
|
||||
return nil
|
||||
@@ -1042,12 +1048,12 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
|
||||
bi.DockerfileInline = *t.DockerfileInline
|
||||
}
|
||||
updateContext(&bi, inp)
|
||||
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !path.IsAbs(bi.DockerfilePath) {
|
||||
bi.DockerfilePath = path.Join(bi.ContextPath, bi.DockerfilePath)
|
||||
}
|
||||
if strings.HasPrefix(bi.ContextPath, "cwd://") {
|
||||
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
|
||||
}
|
||||
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !path.IsAbs(bi.DockerfilePath) {
|
||||
bi.DockerfilePath = path.Join(bi.ContextPath, bi.DockerfilePath)
|
||||
}
|
||||
for k, v := range bi.NamedContexts {
|
||||
if strings.HasPrefix(v.Path, "cwd://") {
|
||||
bi.NamedContexts[k] = build.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))}
|
||||
@@ -1193,6 +1199,26 @@ func removeDupes(s []string) []string {
|
||||
return s[:i]
|
||||
}
|
||||
|
||||
func removeAttestDupes(s []string) []string {
|
||||
res := []string{}
|
||||
m := map[string]int{}
|
||||
for _, v := range s {
|
||||
att, err := buildflags.ParseAttest(v)
|
||||
if err != nil {
|
||||
res = append(res, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if i, ok := m[att.Type]; ok {
|
||||
res[i] = v
|
||||
} else {
|
||||
m[att.Type] = len(res)
|
||||
res = append(res, v)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func parseOutputType(str string) string {
|
||||
csvReader := csv.NewReader(strings.NewReader(str))
|
||||
fields, err := csvReader.Read()
|
||||
|
||||
@@ -295,6 +295,9 @@ services:
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
m, g, err := ReadTargets(ctx, []File{fp, fp2, fp3}, []string{"default"}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -303,7 +306,7 @@ services:
|
||||
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
|
||||
require.Equal(t, ".", *m["webapp"].Context)
|
||||
require.Equal(t, cwd, *m["webapp"].Context)
|
||||
require.Equal(t, ptrstr("1"), m["webapp"].Args["buildno"])
|
||||
require.Equal(t, ptrstr("12"), m["webapp"].Args["buildno2"])
|
||||
|
||||
@@ -342,6 +345,9 @@ services:
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"web.app"}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(m))
|
||||
@@ -364,7 +370,7 @@ services:
|
||||
_, ok = m["web_app"]
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "Dockerfile.webapp", *m["web_app"].Dockerfile)
|
||||
require.Equal(t, ".", *m["web_app"].Context)
|
||||
require.Equal(t, cwd, *m["web_app"].Context)
|
||||
require.Equal(t, ptrstr("1"), m["web_app"].Args["buildno"])
|
||||
require.Equal(t, ptrstr("12"), m["web_app"].Args["buildno2"])
|
||||
|
||||
@@ -386,18 +392,19 @@ func TestHCLCwdPrefix(t *testing.T) {
|
||||
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(m))
|
||||
_, ok := m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
_, err = TargetsToBuildOpt(m, &Input{})
|
||||
bo, err := TargetsToBuildOpt(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "test", *m["app"].Dockerfile)
|
||||
require.Equal(t, "foo", *m["app"].Context)
|
||||
|
||||
require.Equal(t, 1, len(g))
|
||||
require.Equal(t, []string{"app"}, g["default"].Targets)
|
||||
|
||||
require.Equal(t, 1, len(m))
|
||||
require.Contains(t, m, "app")
|
||||
require.Equal(t, "test", *m["app"].Dockerfile)
|
||||
require.Equal(t, "foo", *m["app"].Context)
|
||||
|
||||
require.Equal(t, "foo/test", bo["app"].Inputs.DockerfilePath)
|
||||
require.Equal(t, "foo", bo["app"].Inputs.ContextPath)
|
||||
}
|
||||
|
||||
func TestOverrideMerge(t *testing.T) {
|
||||
@@ -542,6 +549,9 @@ services:
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
m, _, err := ReadTargets(ctx, []File{fp, fp2}, []string{"app1", "app2"}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -554,7 +564,7 @@ services:
|
||||
require.Equal(t, "Dockerfile", *m["app1"].Dockerfile)
|
||||
require.Equal(t, ".", *m["app1"].Context)
|
||||
require.Equal(t, "Dockerfile", *m["app2"].Dockerfile)
|
||||
require.Equal(t, ".", *m["app2"].Context)
|
||||
require.Equal(t, cwd, *m["app2"].Context)
|
||||
}
|
||||
|
||||
func TestReadContextFromTargetChain(t *testing.T) {
|
||||
@@ -1398,7 +1408,7 @@ func TestReadLocalFilesDefault(t *testing.T) {
|
||||
for _, tf := range tt.filenames {
|
||||
require.NoError(t, os.WriteFile(tf, []byte(tf), 0644))
|
||||
}
|
||||
files, err := ReadLocalFiles(nil)
|
||||
files, err := ReadLocalFiles(nil, nil)
|
||||
require.NoError(t, err)
|
||||
if len(files) == 0 {
|
||||
require.Equal(t, len(tt.expected), len(files))
|
||||
@@ -1417,3 +1427,36 @@ func TestReadLocalFilesDefault(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestDuplicates(t *testing.T) {
|
||||
fp := File{
|
||||
Name: "docker-bake.hcl",
|
||||
Data: []byte(
|
||||
`target "default" {
|
||||
attest = ["type=sbom", "type=sbom,generator=custom", "type=sbom,foo=bar", "type=provenance,mode=max"]
|
||||
}`),
|
||||
}
|
||||
ctx := context.TODO()
|
||||
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"default"}, nil, nil)
|
||||
require.Equal(t, []string{"type=sbom,foo=bar", "type=provenance,mode=max"}, m["default"].Attest)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts, err := TargetsToBuildOpt(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{
|
||||
"sbom": ptrstr("type=sbom,foo=bar"),
|
||||
"provenance": ptrstr("type=provenance,mode=max"),
|
||||
}, opts["default"].Attests)
|
||||
|
||||
m, _, err = ReadTargets(ctx, []File{fp}, []string{"default"}, []string{"*.attest=type=sbom,disabled=true"}, nil)
|
||||
require.Equal(t, []string{"type=sbom,disabled=true", "type=provenance,mode=max"}, m["default"].Attest)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts, err = TargetsToBuildOpt(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{
|
||||
"sbom": nil,
|
||||
"provenance": ptrstr("type=provenance,mode=max"),
|
||||
}, opts["default"].Attests)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ func ParseCompose(cfgs []compose.ConfigFile, envs map[string]string) (*Config, e
|
||||
}, func(options *loader.Options) {
|
||||
options.SetProjectName("bake", false)
|
||||
options.SkipNormalization = true
|
||||
options.Profiles = []string{"*"}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,7 +22,7 @@ services:
|
||||
build:
|
||||
context: ./dir
|
||||
additional_contexts:
|
||||
foo: /bar
|
||||
foo: ./bar
|
||||
dockerfile: Dockerfile-alternate
|
||||
network:
|
||||
none
|
||||
@@ -36,6 +36,8 @@ services:
|
||||
- token
|
||||
- aws
|
||||
webapp2:
|
||||
profiles:
|
||||
- test
|
||||
build:
|
||||
context: ./dir
|
||||
dockerfile_inline: |
|
||||
@@ -47,6 +49,9 @@ secrets:
|
||||
file: /root/.aws/credentials
|
||||
`)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -60,12 +65,12 @@ secrets:
|
||||
return c.Targets[i].Name < c.Targets[j].Name
|
||||
})
|
||||
require.Equal(t, "db", c.Targets[0].Name)
|
||||
require.Equal(t, "./db", *c.Targets[0].Context)
|
||||
require.Equal(t, filepath.Join(cwd, "db"), *c.Targets[0].Context)
|
||||
require.Equal(t, []string{"docker.io/tonistiigi/db"}, c.Targets[0].Tags)
|
||||
|
||||
require.Equal(t, "webapp", c.Targets[1].Name)
|
||||
require.Equal(t, "./dir", *c.Targets[1].Context)
|
||||
require.Equal(t, map[string]string{"foo": "/bar"}, c.Targets[1].Contexts)
|
||||
require.Equal(t, filepath.Join(cwd, "dir"), *c.Targets[1].Context)
|
||||
require.Equal(t, map[string]string{"foo": filepath.Join(cwd, "bar")}, c.Targets[1].Contexts)
|
||||
require.Equal(t, "Dockerfile-alternate", *c.Targets[1].Dockerfile)
|
||||
require.Equal(t, 1, len(c.Targets[1].Args))
|
||||
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
|
||||
@@ -78,7 +83,7 @@ secrets:
|
||||
}, c.Targets[1].Secrets)
|
||||
|
||||
require.Equal(t, "webapp2", c.Targets[2].Name)
|
||||
require.Equal(t, "./dir", *c.Targets[2].Context)
|
||||
require.Equal(t, filepath.Join(cwd, "dir"), *c.Targets[2].Context)
|
||||
require.Equal(t, "FROM alpine\n", *c.Targets[2].DockerfileInline)
|
||||
}
|
||||
|
||||
@@ -654,6 +659,66 @@ services:
|
||||
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, c.Targets[0].Args)
|
||||
}
|
||||
|
||||
func TestDependsOn(t *testing.T) {
|
||||
var dt = []byte(`
|
||||
services:
|
||||
foo:
|
||||
build:
|
||||
context: .
|
||||
ports:
|
||||
- 3306:3306
|
||||
depends_on:
|
||||
- bar
|
||||
bar:
|
||||
build:
|
||||
context: .
|
||||
`)
|
||||
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestInclude(t *testing.T) {
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
err := os.WriteFile(filepath.Join(tmpdir, "compose-foo.yml"), []byte(`
|
||||
services:
|
||||
foo:
|
||||
build:
|
||||
context: .
|
||||
target: buildfoo
|
||||
ports:
|
||||
- 3306:3306
|
||||
`), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
var dt = []byte(`
|
||||
include:
|
||||
- compose-foo.yml
|
||||
|
||||
services:
|
||||
bar:
|
||||
build:
|
||||
context: .
|
||||
target: buildbar
|
||||
`)
|
||||
|
||||
chdir(t, tmpdir)
|
||||
c, err := ParseComposeFiles([]File{{
|
||||
Name: "compose.yml",
|
||||
Data: dt,
|
||||
}})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 2, len(c.Targets))
|
||||
sort.Slice(c.Targets, func(i, j int) bool {
|
||||
return c.Targets[i].Name < c.Targets[j].Name
|
||||
})
|
||||
require.Equal(t, "bar", c.Targets[0].Name)
|
||||
require.Equal(t, "buildbar", *c.Targets[0].Target)
|
||||
require.Equal(t, "foo", c.Targets[1].Name)
|
||||
require.Equal(t, "buildfoo", *c.Targets[1].Target)
|
||||
}
|
||||
|
||||
// chdir changes the current working directory to the named directory,
|
||||
// and then restore the original working directory at the end of the test.
|
||||
func chdir(t *testing.T, dir string) {
|
||||
|
||||
@@ -59,7 +59,7 @@ func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, name
|
||||
|
||||
ch, done := progress.NewChannel(pw)
|
||||
defer func() { <-done }()
|
||||
_, err = c.Build(ctx, client.SolveOpt{Session: session}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||
_, err = c.Build(ctx, client.SolveOpt{Session: session, Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||
def, err := st.Marshal(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
155
build/build.go
155
build/build.go
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/docker/buildx/builder"
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/buildx/localstate"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/buildx/util/dockerutil"
|
||||
"github.com/docker/buildx/util/imagetools"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
@@ -65,7 +66,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
printFallbackImage = "docker/dockerfile-upstream:1.4-outline@sha256:627443ff4e2d0f635d429cfc1da5388bcd5a70949c38adcd3cd7c4e5df67c73c"
|
||||
printFallbackImage = "docker/dockerfile:1.5.2-labs@sha256:f2e91734a84c0922ff47aa4098ab775f1dfa932430d2888dd5cad5251fafdac4"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@@ -266,11 +267,11 @@ func resolveDriversBase(ctx context.Context, nodes []builder.Node, opt map[strin
|
||||
}
|
||||
|
||||
undetectedPlatform := false
|
||||
allPlatforms := map[string]int{}
|
||||
allPlatforms := map[string]struct{}{}
|
||||
for _, opt := range opt {
|
||||
for _, p := range opt.Platforms {
|
||||
k := platforms.Format(p)
|
||||
allPlatforms[k] = -1
|
||||
allPlatforms[k] = struct{}{}
|
||||
if _, ok := availablePlatforms[k]; !ok {
|
||||
undetectedPlatform = true
|
||||
}
|
||||
@@ -363,7 +364,7 @@ func toRepoOnly(in string) (string, error) {
|
||||
return strings.Join(out, ","), nil
|
||||
}
|
||||
|
||||
func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Options, bopts gateway.BuildOpts, configDir string, pw progress.Writer, dl dockerLoadCallback) (solveOpt *client.SolveOpt, release func(), err error) {
|
||||
func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Options, bopts gateway.BuildOpts, configDir string, pw progress.Writer, docker *dockerutil.Client) (solveOpt *client.SolveOpt, release func(), err error) {
|
||||
nodeDriver := node.Driver
|
||||
defers := make([]func(), 0, 2)
|
||||
releaseF := func() {
|
||||
@@ -389,7 +390,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
}
|
||||
|
||||
for _, e := range opt.CacheTo {
|
||||
if e.Type != "inline" && !nodeDriver.Features()[driver.CacheExport] {
|
||||
if e.Type != "inline" && !nodeDriver.Features(ctx)[driver.CacheExport] {
|
||||
return nil, nil, notSupported(nodeDriver, driver.CacheExport)
|
||||
}
|
||||
}
|
||||
@@ -453,7 +454,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
attests[k] = *v
|
||||
}
|
||||
}
|
||||
supportsAttestations := bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations"))
|
||||
supportsAttestations := bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations")) && nodeDriver.Features(ctx)[driver.MultiPlatform]
|
||||
if len(attests) > 0 {
|
||||
if !supportsAttestations {
|
||||
return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
|
||||
@@ -527,25 +528,33 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
|
||||
// set up exporters
|
||||
for i, e := range opt.Exports {
|
||||
if e.Type == "oci" && !nodeDriver.Features()[driver.OCIExporter] {
|
||||
if e.Type == "oci" && !nodeDriver.Features(ctx)[driver.OCIExporter] {
|
||||
return nil, nil, notSupported(nodeDriver, driver.OCIExporter)
|
||||
}
|
||||
if e.Type == "docker" {
|
||||
if len(opt.Platforms) > 1 || len(attests) > 0 {
|
||||
features := docker.Features(ctx, e.Attrs["context"])
|
||||
if features[dockerutil.OCIImporter] && e.Output == nil {
|
||||
// rely on oci importer if available (which supports
|
||||
// multi-platform images), otherwise fall back to docker
|
||||
opt.Exports[i].Type = "oci"
|
||||
} else if len(opt.Platforms) > 1 || len(attests) > 0 {
|
||||
if e.Output != nil {
|
||||
return nil, nil, errors.Errorf("docker exporter does not support exporting manifest lists, use the oci exporter instead")
|
||||
}
|
||||
return nil, nil, errors.Errorf("docker exporter does not currently support exporting manifest lists")
|
||||
}
|
||||
if e.Output == nil {
|
||||
if nodeDriver.IsMobyDriver() {
|
||||
e.Type = "image"
|
||||
} else {
|
||||
w, cancel, err := dl(e.Attrs["context"])
|
||||
w, cancel, err := docker.LoadImage(ctx, e.Attrs["context"], pw)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defers = append(defers, cancel)
|
||||
opt.Exports[i].Output = wrapWriteCloser(w)
|
||||
}
|
||||
} else if !nodeDriver.Features()[driver.DockerExporter] {
|
||||
} else if !nodeDriver.Features(ctx)[driver.DockerExporter] {
|
||||
return nil, nil, notSupported(nodeDriver, driver.DockerExporter)
|
||||
}
|
||||
}
|
||||
@@ -584,7 +593,10 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
}
|
||||
|
||||
if opt.Pull {
|
||||
so.FrontendAttrs["image-resolve-mode"] = "pull"
|
||||
so.FrontendAttrs["image-resolve-mode"] = pb.AttrImageResolveModeForcePull
|
||||
} else if nodeDriver.IsMobyDriver() {
|
||||
// moby driver always resolves local images by default
|
||||
so.FrontendAttrs["image-resolve-mode"] = pb.AttrImageResolveModePreferLocal
|
||||
}
|
||||
if opt.Target != "" {
|
||||
so.FrontendAttrs["target"] = opt.Target
|
||||
@@ -614,7 +626,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
for i, p := range opt.Platforms {
|
||||
pp[i] = platforms.Format(p)
|
||||
}
|
||||
if len(pp) > 1 && !nodeDriver.Features()[driver.MultiPlatform] {
|
||||
if len(pp) > 1 && !nodeDriver.Features(ctx)[driver.MultiPlatform] {
|
||||
return nil, nil, notSupported(nodeDriver, driver.MultiPlatform)
|
||||
}
|
||||
so.FrontendAttrs["platform"] = strings.Join(pp, ",")
|
||||
@@ -633,7 +645,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
||||
}
|
||||
|
||||
// setup extrahosts
|
||||
extraHosts, err := toBuildkitExtraHosts(opt.ExtraHosts, nodeDriver.IsMobyDriver())
|
||||
extraHosts, err := toBuildkitExtraHosts(ctx, opt.ExtraHosts, nodeDriver)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -667,7 +679,7 @@ func Build(ctx context.Context, nodes []builder.Node, opt map[string]Options, do
|
||||
return BuildWithResultHandler(ctx, nodes, opt, docker, configDir, w, nil)
|
||||
}
|
||||
|
||||
func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[string]Options, docker *dockerutil.Client, configDir string, w progress.Writer, resultHandleFunc func(driverIndex int, rCtx *ResultContext)) (resp map[string]*client.SolveResponse, err error) {
|
||||
func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[string]Options, docker *dockerutil.Client, configDir string, w progress.Writer, resultHandleFunc func(driverIndex int, rCtx *ResultHandle)) (resp map[string]*client.SolveResponse, err error) {
|
||||
if len(nodes) == 0 {
|
||||
return nil, errors.Errorf("driver required for build")
|
||||
}
|
||||
@@ -725,7 +737,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||
hasMobyDriver := false
|
||||
gitattrs, err := getGitAttributes(ctx, opt.Inputs.ContextPath, opt.Inputs.DockerfilePath)
|
||||
if err != nil {
|
||||
logrus.Warn(err)
|
||||
logrus.WithError(err).Warn("current commit information was not captured by the build")
|
||||
}
|
||||
for i, np := range m[k] {
|
||||
node := nodes[np.driverIndex]
|
||||
@@ -733,9 +745,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||
hasMobyDriver = true
|
||||
}
|
||||
opt.Platforms = np.platforms
|
||||
so, release, err := toSolveOpt(ctx, node, multiDriver, opt, np.bopts, configDir, w, func(name string) (io.WriteCloser, func(), error) {
|
||||
return docker.LoadImage(ctx, name, w)
|
||||
})
|
||||
so, release, err := toSolveOpt(ctx, node, multiDriver, opt, np.bopts, configDir, w, docker)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -822,6 +832,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||
|
||||
for i, dp := range dps {
|
||||
i, dp, so := i, dp, *dp.so
|
||||
node := nodes[dp.driverIndex]
|
||||
if multiDriver {
|
||||
for i, e := range so.Exports {
|
||||
switch e.Type {
|
||||
@@ -885,61 +896,71 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||
|
||||
cc := c
|
||||
var printRes map[string][]byte
|
||||
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||
var isFallback bool
|
||||
var origErr error
|
||||
for {
|
||||
if opt.PrintFunc != nil {
|
||||
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
|
||||
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
|
||||
} else {
|
||||
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
|
||||
}
|
||||
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
|
||||
if isFallback {
|
||||
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
|
||||
}
|
||||
buildFunc := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||
if opt.PrintFunc != nil {
|
||||
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
|
||||
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
|
||||
} else {
|
||||
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
|
||||
}
|
||||
res, err := c.Solve(ctx, req)
|
||||
if err != nil {
|
||||
if origErr != nil {
|
||||
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
|
||||
}
|
||||
|
||||
res, err := c.Solve(ctx, req)
|
||||
if err != nil {
|
||||
fallback := false
|
||||
var reqErr *errdefs.UnsupportedSubrequestError
|
||||
if errors.As(err, &reqErr) {
|
||||
switch reqErr.Name {
|
||||
case "frontend.outline", "frontend.targets":
|
||||
fallback = true
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
var reqErr *errdefs.UnsupportedSubrequestError
|
||||
if !isFallback {
|
||||
if errors.As(err, &reqErr) {
|
||||
switch reqErr.Name {
|
||||
case "frontend.outline", "frontend.targets":
|
||||
isFallback = true
|
||||
origErr = err
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
|
||||
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
|
||||
isFallback = true
|
||||
origErr = err
|
||||
continue
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
if opt.PrintFunc != nil {
|
||||
printRes = res.Metadata
|
||||
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
|
||||
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
|
||||
fallback = true
|
||||
}
|
||||
results.Set(resultKey(dp.driverIndex, k), res)
|
||||
if resultHandleFunc != nil {
|
||||
resultCtx, err := NewResultContext(ctx, cc, so, res)
|
||||
if err == nil {
|
||||
resultHandleFunc(dp.driverIndex, resultCtx)
|
||||
} else {
|
||||
logrus.Warnf("failed to record result: %s", err)
|
||||
|
||||
if fallback {
|
||||
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
|
||||
res2, err2 := c.Solve(ctx, req)
|
||||
if err2 != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = res2
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
}, ch)
|
||||
if opt.PrintFunc != nil {
|
||||
printRes = res.Metadata
|
||||
}
|
||||
|
||||
results.Set(resultKey(dp.driverIndex, k), res)
|
||||
return res, nil
|
||||
}
|
||||
var rr *client.SolveResponse
|
||||
if resultHandleFunc != nil {
|
||||
var resultHandle *ResultHandle
|
||||
resultHandle, rr, err = NewResultHandle(ctx, cc, so, "buildx", buildFunc, ch)
|
||||
resultHandleFunc(dp.driverIndex, resultHandle)
|
||||
} else {
|
||||
rr, err = c.Build(ctx, so, "buildx", buildFunc, ch)
|
||||
}
|
||||
if desktop.BuildBackendEnabled() && node.Driver.HistoryAPISupported(ctx) {
|
||||
buildRef := fmt.Sprintf("%s/%s/%s", node.Builder, node.Name, so.Ref)
|
||||
if err != nil {
|
||||
return &desktop.ErrorWithBuildRef{
|
||||
Ref: buildRef,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
progress.WriteBuildRef(w, k, buildRef)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1080,7 +1101,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
||||
}
|
||||
}
|
||||
|
||||
dt, desc, err := itpull.Combine(ctx, srcs)
|
||||
dt, desc, err := itpull.Combine(ctx, srcs, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1244,7 +1265,7 @@ func createTempDockerfile(r io.Reader) (string, error) {
|
||||
return dir, err
|
||||
}
|
||||
|
||||
func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Writer, target *client.SolveOpt) (func(), error) {
|
||||
func LoadInputs(ctx context.Context, d *driver.DriverHandle, inp Inputs, pw progress.Writer, target *client.SolveOpt) (func(), error) {
|
||||
if inp.ContextPath == "" {
|
||||
return nil, errors.New("please specify build context (e.g. \".\" for the current directory)")
|
||||
}
|
||||
@@ -1543,8 +1564,6 @@ func notSupported(d driver.Driver, f driver.Feature) error {
|
||||
return errors.Errorf("%s feature is currently not supported for %s driver. Please switch to a different driver (eg. \"docker buildx create --use\")", f, d.Factory().Name())
|
||||
}
|
||||
|
||||
type dockerLoadCallback func(name string) (io.WriteCloser, func(), error)
|
||||
|
||||
func noDefaultLoad() bool {
|
||||
v, ok := os.LookupEnv("BUILDX_NO_DEFAULT_LOAD")
|
||||
if !ok {
|
||||
|
||||
10
build/git.go
10
build/git.go
@@ -51,21 +51,21 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
||||
|
||||
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
|
||||
if err != nil {
|
||||
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
|
||||
return res, errors.New("buildx: git was not found in the system. Current commit information was not captured by the build")
|
||||
if st, err1 := os.Stat(path.Join(wd, ".git")); err1 == nil && st.IsDir() {
|
||||
return res, errors.Wrap(err, "git was not found in the system")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !gitc.IsInsideWorkTree() {
|
||||
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
|
||||
return res, errors.New("buildx: failed to read current commit information with git rev-parse --is-inside-work-tree")
|
||||
return res, errors.New("failed to read current commit information with git rev-parse --is-inside-work-tree")
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
if sha, err := gitc.FullCommit(); err != nil && !gitutil.IsUnknownRevision(err) {
|
||||
return res, errors.Wrapf(err, "buildx: failed to get git commit")
|
||||
return res, errors.Wrap(err, "failed to get git commit")
|
||||
} else if sha != "" {
|
||||
checkDirty := false
|
||||
if v, ok := os.LookupEnv("BUILDX_GIT_CHECK_DIRTY"); ok {
|
||||
@@ -95,7 +95,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
||||
|
||||
if setGitLabels {
|
||||
if root, err := gitc.RootDir(); err != nil {
|
||||
return res, errors.Wrapf(err, "buildx: failed to get git root dir")
|
||||
return res, errors.Wrap(err, "failed to get git root dir")
|
||||
} else if root != "" {
|
||||
if dockerfilePath == "" {
|
||||
dockerfilePath = filepath.Join(wd, "Dockerfile")
|
||||
|
||||
@@ -21,10 +21,10 @@ type Container struct {
|
||||
initStarted atomic.Bool
|
||||
container gateway.Container
|
||||
releaseCh chan struct{}
|
||||
resultCtx *ResultContext
|
||||
resultCtx *ResultHandle
|
||||
}
|
||||
|
||||
func NewContainer(ctx context.Context, resultCtx *ResultContext, cfg *controllerapi.InvokeConfig) (*Container, error) {
|
||||
func NewContainer(ctx context.Context, resultCtx *ResultHandle, cfg *controllerapi.InvokeConfig) (*Container, error) {
|
||||
mainCtx := ctx
|
||||
|
||||
ctrCh := make(chan *Container)
|
||||
@@ -112,7 +112,7 @@ func (c *Container) Exec(ctx context.Context, cfg *controllerapi.InvokeConfig, s
|
||||
return err
|
||||
}
|
||||
|
||||
func exec(ctx context.Context, resultCtx *ResultContext, cfg *controllerapi.InvokeConfig, ctr gateway.Container, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
|
||||
func exec(ctx context.Context, resultCtx *ResultHandle, cfg *controllerapi.InvokeConfig, ctr gateway.Container, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) error {
|
||||
processCfg, err := resultCtx.getProcessConfig(cfg, stdin, stdout, stderr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
354
build/result.go
354
build/result.go
@@ -6,8 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/moby/buildkit/client"
|
||||
@@ -22,14 +20,188 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func NewResultContext(ctx context.Context, c *client.Client, solveOpt client.SolveOpt, res *gateway.Result) (*ResultContext, error) {
|
||||
def, err := getDefinition(ctx, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// NewResultHandle makes a call to client.Build, additionally returning a
|
||||
// opaque ResultHandle alongside the standard response and error.
|
||||
//
|
||||
// This ResultHandle can be used to execute additional build steps in the same
|
||||
// context as the build occurred, which can allow easy debugging of build
|
||||
// failures and successes.
|
||||
//
|
||||
// If the returned ResultHandle is not nil, the caller must call Done() on it.
|
||||
func NewResultHandle(ctx context.Context, cc *client.Client, opt client.SolveOpt, product string, buildFunc gateway.BuildFunc, ch chan *client.SolveStatus) (*ResultHandle, *client.SolveResponse, error) {
|
||||
// Create a new context to wrap the original, and cancel it when the
|
||||
// caller-provided context is cancelled.
|
||||
//
|
||||
// We derive the context from the background context so that we can forbid
|
||||
// cancellation of the build request after <-done is closed (which we do
|
||||
// before returning the ResultHandle).
|
||||
baseCtx := ctx
|
||||
ctx, cancel := context.WithCancelCause(context.Background())
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
select {
|
||||
case <-baseCtx.Done():
|
||||
cancel(baseCtx.Err())
|
||||
case <-done:
|
||||
// Once done is closed, we've recorded a ResultHandle, so we
|
||||
// shouldn't allow cancelling the underlying build request anymore.
|
||||
}
|
||||
}()
|
||||
|
||||
// Create a new channel to forward status messages to the original.
|
||||
//
|
||||
// We do this so that we can discard status messages after the main portion
|
||||
// of the build is complete. This is necessary for the solve error case,
|
||||
// where the original gateway is kept open until the ResultHandle is
|
||||
// closed - we don't want progress messages from operations in that
|
||||
// ResultHandle to display after this function exits.
|
||||
//
|
||||
// Additionally, callers should wait for the progress channel to be closed.
|
||||
// If we keep the session open and never close the progress channel, the
|
||||
// caller will likely hang.
|
||||
baseCh := ch
|
||||
ch = make(chan *client.SolveStatus)
|
||||
go func() {
|
||||
for {
|
||||
s, ok := <-ch
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-baseCh:
|
||||
// base channel is closed, discard status messages
|
||||
default:
|
||||
baseCh <- s
|
||||
}
|
||||
}
|
||||
}()
|
||||
defer close(baseCh)
|
||||
|
||||
var resp *client.SolveResponse
|
||||
var respErr error
|
||||
var respHandle *ResultHandle
|
||||
|
||||
go func() {
|
||||
defer cancel(context.Canceled) // ensure no dangling processes
|
||||
|
||||
var res *gateway.Result
|
||||
var err error
|
||||
resp, err = cc.Build(ctx, opt, product, func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||
var err error
|
||||
res, err = buildFunc(ctx, c)
|
||||
|
||||
if res != nil && err == nil {
|
||||
// Force evaluation of the build result (otherwise, we likely
|
||||
// won't get a solve error)
|
||||
def, err2 := getDefinition(ctx, res)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
res, err = evalDefinition(ctx, c, def)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Scenario 1: we failed to evaluate a node somewhere in the
|
||||
// build graph.
|
||||
//
|
||||
// In this case, we construct a ResultHandle from this
|
||||
// original Build session, and return it alongside the original
|
||||
// build error. We then need to keep the gateway session open
|
||||
// until the caller explicitly closes the ResultHandle.
|
||||
|
||||
var se *errdefs.SolveError
|
||||
if errors.As(err, &se) {
|
||||
respHandle = &ResultHandle{
|
||||
done: make(chan struct{}),
|
||||
solveErr: se,
|
||||
gwClient: c,
|
||||
gwCtx: ctx,
|
||||
}
|
||||
respErr = se
|
||||
close(done)
|
||||
|
||||
// Block until the caller closes the ResultHandle.
|
||||
select {
|
||||
case <-respHandle.done:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, err
|
||||
}, ch)
|
||||
if respHandle != nil {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
// Something unexpected failed during the build, we didn't succeed,
|
||||
// but we also didn't make it far enough to create a ResultHandle.
|
||||
respErr = err
|
||||
close(done)
|
||||
return
|
||||
}
|
||||
|
||||
// Scenario 2: we successfully built the image with no errors.
|
||||
//
|
||||
// In this case, the original gateway session has now been closed
|
||||
// since the Build has been completed. So, we need to create a new
|
||||
// gateway session to populate the ResultHandle. To do this, we
|
||||
// need to re-evaluate the target result, in this new session. This
|
||||
// should be instantaneous since the result should be cached.
|
||||
|
||||
def, err := getDefinition(ctx, res)
|
||||
if err != nil {
|
||||
respErr = err
|
||||
close(done)
|
||||
return
|
||||
}
|
||||
|
||||
// NOTE: ideally this second connection should be lazily opened
|
||||
opt := opt
|
||||
opt.Ref = ""
|
||||
opt.Exports = nil
|
||||
opt.CacheExports = nil
|
||||
opt.Internal = true
|
||||
_, respErr = cc.Build(ctx, opt, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||
res, err := evalDefinition(ctx, c, def)
|
||||
if err != nil {
|
||||
// This should probably not happen, since we've previously
|
||||
// successfully evaluated the same result with no issues.
|
||||
return nil, errors.Wrap(err, "inconsistent solve result")
|
||||
}
|
||||
respHandle = &ResultHandle{
|
||||
done: make(chan struct{}),
|
||||
res: res,
|
||||
gwClient: c,
|
||||
gwCtx: ctx,
|
||||
}
|
||||
close(done)
|
||||
|
||||
// Block until the caller closes the ResultHandle.
|
||||
select {
|
||||
case <-respHandle.done:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
return nil, ctx.Err()
|
||||
}, nil)
|
||||
if respHandle != nil {
|
||||
return
|
||||
}
|
||||
close(done)
|
||||
}()
|
||||
|
||||
// Block until the other thread signals that it's completed the build.
|
||||
select {
|
||||
case <-done:
|
||||
case <-baseCtx.Done():
|
||||
if respErr == nil {
|
||||
respErr = baseCtx.Err()
|
||||
}
|
||||
}
|
||||
return getResultAt(ctx, c, solveOpt, def, nil)
|
||||
return respHandle, resp, respErr
|
||||
}
|
||||
|
||||
// getDefinition converts a gateway result into a collection of definitions for
|
||||
// each ref in the result.
|
||||
func getDefinition(ctx context.Context, res *gateway.Result) (*result.Result[*pb.Definition], error) {
|
||||
return result.ConvertResult(res, func(ref gateway.Reference) (*pb.Definition, error) {
|
||||
st, err := ref.ToState()
|
||||
@@ -44,136 +216,58 @@ func getDefinition(ctx context.Context, res *gateway.Result) (*result.Result[*pb
|
||||
})
|
||||
}
|
||||
|
||||
func getResultAt(ctx context.Context, c *client.Client, solveOpt client.SolveOpt, targets *result.Result[*pb.Definition], statusChan chan *client.SolveStatus) (*ResultContext, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// forward SolveStatus
|
||||
done := new(atomic.Bool)
|
||||
defer done.Store(true)
|
||||
ch := make(chan *client.SolveStatus)
|
||||
go func() {
|
||||
for {
|
||||
s := <-ch
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
if done.Load() {
|
||||
// Do not forward if the function returned because statusChan is possibly closed
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case statusChan <- s:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// get result
|
||||
resultCtxCh := make(chan *ResultContext)
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
solveOpt := solveOpt
|
||||
solveOpt.Ref = ""
|
||||
buildDoneCh := make(chan struct{})
|
||||
_, err := c.Build(context.Background(), solveOpt, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||
doneErr := errors.Errorf("done")
|
||||
ctx, cancel := context.WithCancelCause(ctx)
|
||||
defer cancel(doneErr)
|
||||
|
||||
// force evaluation of all targets in parallel
|
||||
results := make(map[*pb.Definition]*gateway.Result)
|
||||
resultsMu := sync.Mutex{}
|
||||
eg, egCtx := errgroup.WithContext(ctx)
|
||||
targets.EachRef(func(def *pb.Definition) error {
|
||||
eg.Go(func() error {
|
||||
res2, err := c.Solve(egCtx, gateway.SolveRequest{
|
||||
Evaluate: true,
|
||||
Definition: def,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultsMu.Lock()
|
||||
results[def] = res2
|
||||
resultsMu.Unlock()
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
// evalDefinition performs the reverse of getDefinition, converting a
|
||||
// collection of definitions into a gateway result.
|
||||
func evalDefinition(ctx context.Context, c gateway.Client, defs *result.Result[*pb.Definition]) (*gateway.Result, error) {
|
||||
// force evaluation of all targets in parallel
|
||||
results := make(map[*pb.Definition]*gateway.Result)
|
||||
resultsMu := sync.Mutex{}
|
||||
eg, egCtx := errgroup.WithContext(ctx)
|
||||
defs.EachRef(func(def *pb.Definition) error {
|
||||
eg.Go(func() error {
|
||||
res, err := c.Solve(egCtx, gateway.SolveRequest{
|
||||
Evaluate: true,
|
||||
Definition: def,
|
||||
})
|
||||
resultCtx := ResultContext{}
|
||||
if err := eg.Wait(); err != nil {
|
||||
var se *errdefs.SolveError
|
||||
if errors.As(err, &se) {
|
||||
resultCtx.solveErr = se
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res2, _ := result.ConvertResult(targets, func(def *pb.Definition) (gateway.Reference, error) {
|
||||
if res, ok := results[def]; ok {
|
||||
return res.Ref, nil
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
// Record the client and ctx as well so that containers can be created from the SolveError.
|
||||
resultCtx.res = res2
|
||||
resultCtx.gwClient = c
|
||||
resultCtx.gwCtx = ctx
|
||||
resultCtx.gwDone = func() {
|
||||
cancel(doneErr)
|
||||
// wait for Build() completion(or timeout) to ensure the Build's finalizing and avoiding an error "context canceled"
|
||||
select {
|
||||
case <-buildDoneCh:
|
||||
case <-time.After(5 * time.Second):
|
||||
}
|
||||
}
|
||||
select {
|
||||
case resultCtxCh <- &resultCtx:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
|
||||
// wait for cleanup or cancel
|
||||
<-ctx.Done()
|
||||
if context.Cause(ctx) != doneErr { // doneErr is not an error.
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
return nil, nil
|
||||
}, ch)
|
||||
close(buildDoneCh)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case resultCtx := <-resultCtxCh:
|
||||
return resultCtx, nil
|
||||
case err := <-errCh:
|
||||
resultsMu.Lock()
|
||||
results[def] = res
|
||||
resultsMu.Unlock()
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
return nil, err
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
res, _ := result.ConvertResult(defs, func(def *pb.Definition) (gateway.Reference, error) {
|
||||
if res, ok := results[def]; ok {
|
||||
return res.Ref, nil
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ResultContext is a build result with the client that built it.
|
||||
type ResultContext struct {
|
||||
// ResultHandle is a build result with the client that built it.
|
||||
type ResultHandle struct {
|
||||
res *gateway.Result
|
||||
solveErr *errdefs.SolveError
|
||||
|
||||
gwClient gateway.Client
|
||||
gwCtx context.Context
|
||||
gwDone func()
|
||||
gwDoneOnce sync.Once
|
||||
done chan struct{}
|
||||
doneOnce sync.Once
|
||||
|
||||
gwClient gateway.Client
|
||||
gwCtx context.Context
|
||||
|
||||
cleanups []func()
|
||||
cleanupsMu sync.Mutex
|
||||
}
|
||||
|
||||
func (r *ResultContext) Done() {
|
||||
r.gwDoneOnce.Do(func() {
|
||||
func (r *ResultHandle) Done() {
|
||||
r.doneOnce.Do(func() {
|
||||
r.cleanupsMu.Lock()
|
||||
cleanups := r.cleanups
|
||||
r.cleanups = nil
|
||||
@@ -181,22 +275,24 @@ func (r *ResultContext) Done() {
|
||||
for _, f := range cleanups {
|
||||
f()
|
||||
}
|
||||
r.gwDone()
|
||||
|
||||
close(r.done)
|
||||
<-r.gwCtx.Done()
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ResultContext) registerCleanup(f func()) {
|
||||
func (r *ResultHandle) registerCleanup(f func()) {
|
||||
r.cleanupsMu.Lock()
|
||||
r.cleanups = append(r.cleanups, f)
|
||||
r.cleanupsMu.Unlock()
|
||||
}
|
||||
|
||||
func (r *ResultContext) build(buildFunc gateway.BuildFunc) (err error) {
|
||||
func (r *ResultHandle) build(buildFunc gateway.BuildFunc) (err error) {
|
||||
_, err = buildFunc(r.gwCtx, r.gwClient)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ResultContext) getContainerConfig(ctx context.Context, c gateway.Client, cfg *controllerapi.InvokeConfig) (containerCfg gateway.NewContainerRequest, _ error) {
|
||||
func (r *ResultHandle) getContainerConfig(ctx context.Context, c gateway.Client, cfg *controllerapi.InvokeConfig) (containerCfg gateway.NewContainerRequest, _ error) {
|
||||
if r.res != nil && r.solveErr == nil {
|
||||
logrus.Debugf("creating container from successful build")
|
||||
ccfg, err := containerConfigFromResult(ctx, r.res, c, *cfg)
|
||||
@@ -215,7 +311,7 @@ func (r *ResultContext) getContainerConfig(ctx context.Context, c gateway.Client
|
||||
return containerCfg, nil
|
||||
}
|
||||
|
||||
func (r *ResultContext) getProcessConfig(cfg *controllerapi.InvokeConfig, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) (_ gateway.StartRequest, err error) {
|
||||
func (r *ResultHandle) getProcessConfig(cfg *controllerapi.InvokeConfig, stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser) (_ gateway.StartRequest, err error) {
|
||||
processCfg := newStartRequest(stdin, stdout, stderr)
|
||||
if r.res != nil && r.solveErr == nil {
|
||||
logrus.Debugf("creating container from successful build")
|
||||
@@ -292,7 +388,7 @@ func populateProcessConfigFromResult(req *gateway.StartRequest, res *gateway.Res
|
||||
} else if img != nil {
|
||||
args = append(args, img.Config.Entrypoint...)
|
||||
}
|
||||
if cfg.Cmd != nil {
|
||||
if !cfg.NoCmd {
|
||||
args = append(args, cfg.Cmd...)
|
||||
} else if img != nil {
|
||||
args = append(args, img.Config.Cmd...)
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func createTempDockerfileFromURL(ctx context.Context, d driver.Driver, url string, pw progress.Writer) (string, error) {
|
||||
func createTempDockerfileFromURL(ctx context.Context, d *driver.DriverHandle, url string, pw progress.Writer) (string, error) {
|
||||
c, err := driver.Boot(ctx, ctx, d, pw)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -21,7 +21,7 @@ func createTempDockerfileFromURL(ctx context.Context, d driver.Driver, url strin
|
||||
var out string
|
||||
ch, done := progress.NewChannel(pw)
|
||||
defer func() { <-done }()
|
||||
_, err = c.Build(ctx, client.SolveOpt{}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||
_, err = c.Build(ctx, client.SolveOpt{Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||
def, err := llb.HTTP(url, llb.Filename("Dockerfile"), llb.WithCustomNamef("[internal] load %s", url)).Marshal(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -3,10 +3,12 @@ package build
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/builder/remotecontext/urlutil"
|
||||
"github.com/moby/buildkit/util/gitutil"
|
||||
@@ -57,7 +59,7 @@ func isArchive(header []byte) bool {
|
||||
}
|
||||
|
||||
// toBuildkitExtraHosts converts hosts from docker key:value format to buildkit's csv format
|
||||
func toBuildkitExtraHosts(inp []string, mobyDriver bool) (string, error) {
|
||||
func toBuildkitExtraHosts(ctx context.Context, inp []string, nodeDriver *driver.DriverHandle) (string, error) {
|
||||
if len(inp) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
@@ -67,11 +69,16 @@ func toBuildkitExtraHosts(inp []string, mobyDriver bool) (string, error) {
|
||||
if !ok || host == "" || ip == "" {
|
||||
return "", errors.Errorf("invalid host %s", h)
|
||||
}
|
||||
// Skip IP address validation for "host-gateway" string with moby driver
|
||||
if !mobyDriver || ip != mobyHostGatewayName {
|
||||
if net.ParseIP(ip) == nil {
|
||||
return "", errors.Errorf("invalid host %s", h)
|
||||
// If the IP Address is a "host-gateway", replace this value with the
|
||||
// IP address provided by the worker's label.
|
||||
if ip == mobyHostGatewayName {
|
||||
hgip, err := nodeDriver.HostGatewayIP(ctx)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "unable to derive the IP value for host-gateway")
|
||||
}
|
||||
ip = hgip.String()
|
||||
} else if net.ParseIP(ip) == nil {
|
||||
return "", errors.Errorf("invalid host %s", h)
|
||||
}
|
||||
hosts = append(hosts, host+"="+ip)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/docker/buildx/util/dockerutil"
|
||||
"github.com/docker/buildx/util/imagetools"
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/util/grpcerrors"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
@@ -21,9 +22,11 @@ import (
|
||||
type Node struct {
|
||||
store.Node
|
||||
Builder string
|
||||
Driver driver.Driver
|
||||
Driver *driver.DriverHandle
|
||||
DriverInfo *driver.Info
|
||||
Platforms []ocispecs.Platform
|
||||
GCPolicy []client.PruneInfo
|
||||
Labels map[string]string
|
||||
ImageOpt imagetools.Opt
|
||||
ProxyConfig map[string]string
|
||||
Version string
|
||||
@@ -79,12 +82,12 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
|
||||
contextStore := b.opts.dockerCli.ContextStore()
|
||||
|
||||
var kcc driver.KubeClientConfig
|
||||
kcc, err = ctxkube.ConfigFromContext(n.Endpoint, contextStore)
|
||||
kcc, err = ctxkube.ConfigFromEndpoint(n.Endpoint, contextStore)
|
||||
if err != nil {
|
||||
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
|
||||
// try again with name="default".
|
||||
// FIXME(@AkihiroSuda): n should retain real context name.
|
||||
kcc, err = ctxkube.ConfigFromContext("default", contextStore)
|
||||
kcc, err = ctxkube.ConfigFromEndpoint("default", contextStore)
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
}
|
||||
@@ -106,7 +109,7 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
|
||||
}
|
||||
}
|
||||
|
||||
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, factory, n.Endpoint, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.Platforms, b.opts.contextPathHash)
|
||||
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, factory, n.Endpoint, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.SecurityOpts, n.Platforms, b.opts.contextPathHash)
|
||||
if err != nil {
|
||||
node.Err = err
|
||||
return nil
|
||||
@@ -184,8 +187,12 @@ func (n *Node) loadData(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "listing workers")
|
||||
}
|
||||
for _, w := range workers {
|
||||
for idx, w := range workers {
|
||||
n.Platforms = append(n.Platforms, w.Platforms...)
|
||||
if idx == 0 {
|
||||
n.GCPolicy = w.GCPolicy
|
||||
n.Labels = w.Labels
|
||||
}
|
||||
}
|
||||
n.Platforms = platformutil.Dedupe(n.Platforms)
|
||||
inf, err := driverClient.Info(ctx)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/buildx/commands"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/buildx/version"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli-plugins/manager"
|
||||
@@ -18,10 +19,7 @@ import (
|
||||
//nolint:staticcheck // vendored dependencies may still use this
|
||||
"github.com/containerd/containerd/pkg/seed"
|
||||
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
|
||||
|
||||
_ "github.com/docker/buildx/driver/docker"
|
||||
_ "github.com/docker/buildx/driver/docker-container"
|
||||
@@ -89,6 +87,9 @@ func main() {
|
||||
} else {
|
||||
fmt.Fprintf(cmd.Err(), "ERROR: %v\n", err)
|
||||
}
|
||||
if ebr, ok := err.(*desktop.ErrorWithBuildRef); ok {
|
||||
ebr.Print(cmd.Err())
|
||||
}
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/console"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/buildx/bake"
|
||||
"github.com/docker/buildx/build"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/docker/buildx/util/cobrautil/completion"
|
||||
"github.com/docker/buildx/util/confutil"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/buildx/util/dockerutil"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/docker/buildx/util/tracing"
|
||||
@@ -117,6 +119,11 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com
|
||||
progressTextDesc = fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver)
|
||||
}
|
||||
|
||||
var term bool
|
||||
if _, err := console.ConsoleFromFile(os.Stderr); err == nil {
|
||||
term = true
|
||||
}
|
||||
|
||||
printer, err := progress.NewPrinter(ctx2, os.Stderr, os.Stderr, cFlags.progress,
|
||||
progress.WithDesc(progressTextDesc, progressConsoleDesc),
|
||||
)
|
||||
@@ -130,13 +137,16 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
if err == nil && cFlags.progress != progress.PrinterModeQuiet {
|
||||
desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if url != "" {
|
||||
files, inp, err = bake.ReadRemoteFiles(ctx, nodes, url, in.files, printer)
|
||||
} else {
|
||||
files, err = bake.ReadLocalFiles(in.files)
|
||||
files, err = bake.ReadLocalFiles(in.files, dockerCli.In())
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/docker/buildx/store"
|
||||
"github.com/docker/buildx/store/storeutil"
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/buildx/util/ioset"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/docker/buildx/util/tracing"
|
||||
@@ -233,6 +234,15 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.LoadNodes(ctx, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var term bool
|
||||
if _, err := console.ConsoleFromFile(os.Stderr); err == nil {
|
||||
term = true
|
||||
}
|
||||
|
||||
ctx2, cancel := context.WithCancel(context.TODO())
|
||||
defer cancel()
|
||||
@@ -269,15 +279,15 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) {
|
||||
return retErr
|
||||
}
|
||||
|
||||
if options.quiet {
|
||||
fmt.Println(resp.ExporterResponse[exptypes.ExporterImageDigestKey])
|
||||
if progressMode != progress.PrinterModeQuiet {
|
||||
desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term)
|
||||
} else {
|
||||
fmt.Println(getImageID(resp.ExporterResponse))
|
||||
}
|
||||
if options.imageIDFile != "" {
|
||||
dgst := resp.ExporterResponse[exptypes.ExporterImageDigestKey]
|
||||
if v, ok := resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; ok {
|
||||
dgst = v
|
||||
if err := os.WriteFile(options.imageIDFile, []byte(getImageID(resp.ExporterResponse)), 0644); err != nil {
|
||||
return errors.Wrap(err, "writing image ID file")
|
||||
}
|
||||
return os.WriteFile(options.imageIDFile, []byte(dgst), 0644)
|
||||
}
|
||||
if options.metadataFile != "" {
|
||||
if err := writeMetadataFile(options.metadataFile, decodeExporterResponse(resp.ExporterResponse)); err != nil {
|
||||
@@ -292,8 +302,20 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// getImageID returns the image ID - the digest of the image config
|
||||
func getImageID(resp map[string]string) string {
|
||||
dgst := resp[exptypes.ExporterImageDigestKey]
|
||||
if v, ok := resp[exptypes.ExporterImageConfigDigestKey]; ok {
|
||||
dgst = v
|
||||
}
|
||||
return dgst
|
||||
}
|
||||
|
||||
func runBasicBuild(ctx context.Context, dockerCli command.Cli, opts *controllerapi.BuildOptions, options buildOptions, printer *progress.Printer) (*client.SolveResponse, error) {
|
||||
resp, _, err := cbuild.RunBuild(ctx, dockerCli, *opts, os.Stdin, printer, false)
|
||||
resp, res, err := cbuild.RunBuild(ctx, dockerCli, *opts, dockerCli.In(), printer, false)
|
||||
if res != nil {
|
||||
res.Done()
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -324,7 +346,7 @@ func runControllerBuild(ctx context.Context, dockerCli command.Cli, opts *contro
|
||||
var retErr error
|
||||
var resp *client.SolveResponse
|
||||
f := ioset.NewSingleForwarder()
|
||||
f.SetReader(os.Stdin)
|
||||
f.SetReader(dockerCli.In())
|
||||
if !options.noBuild {
|
||||
pr, pw := io.Pipe()
|
||||
f.SetWriter(pw, func() io.WriteCloser {
|
||||
@@ -442,7 +464,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
|
||||
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
|
||||
|
||||
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
|
||||
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", `Set the parent cgroup for the "RUN" instructions during build`)
|
||||
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
|
||||
|
||||
flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
|
||||
@@ -465,7 +487,8 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
|
||||
|
||||
if isExperimental() {
|
||||
flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]")
|
||||
flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets)")
|
||||
flags.SetAnnotation("print", "experimentalCLI", nil)
|
||||
}
|
||||
|
||||
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--output=type=registry"`)
|
||||
@@ -489,13 +512,17 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
|
||||
flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)
|
||||
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--attest=type=sbom"`)
|
||||
flags.StringVar(&options.provenance, "provenance", "", `Shortand for "--attest=type=provenance"`)
|
||||
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--attest=type=provenance"`)
|
||||
|
||||
if isExperimental() {
|
||||
flags.StringVar(&invokeFlag, "invoke", "", "Invoke a command after the build [experimental]")
|
||||
flags.StringVar(&options.Root, "root", "", "Specify root directory of server to connect [experimental]")
|
||||
flags.BoolVar(&options.Detach, "detach", false, "Detach buildx server (supported only on linux) [experimental]")
|
||||
flags.StringVar(&options.ServerConfig, "server-config", "", "Specify buildx server config file (used only when launching new server) [experimental]")
|
||||
flags.StringVar(&invokeFlag, "invoke", "", "Invoke a command after the build")
|
||||
flags.SetAnnotation("invoke", "experimentalCLI", nil)
|
||||
flags.StringVar(&options.Root, "root", "", "Specify root directory of server to connect")
|
||||
flags.SetAnnotation("root", "experimentalCLI", nil)
|
||||
flags.BoolVar(&options.Detach, "detach", false, "Detach buildx server (supported only on linux)")
|
||||
flags.SetAnnotation("detach", "experimentalCLI", nil)
|
||||
flags.StringVar(&options.ServerConfig, "server-config", "", "Specify buildx server config file (used only when launching new server)")
|
||||
flags.SetAnnotation("server-config", "experimentalCLI", nil)
|
||||
}
|
||||
|
||||
// hidden flags
|
||||
@@ -518,6 +545,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
flags.BoolVar(&ignoreBool, "squash", false, "Squash newly built layers into a single new layer")
|
||||
flags.MarkHidden("squash")
|
||||
flags.SetAnnotation("squash", "flag-warn", []string{"experimental flag squash is removed with BuildKit. You should squash inside build using a multi-stage Dockerfile for efficiency."})
|
||||
flags.SetAnnotation("squash", "experimentalCLI", nil)
|
||||
|
||||
flags.StringVarP(&ignore, "memory", "m", "", "Memory limit")
|
||||
flags.MarkHidden("memory")
|
||||
@@ -670,6 +698,7 @@ func (cfg *invokeConfig) needsMonitor(retErr error) bool {
|
||||
func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
||||
cfg.invokeFlag = invoke
|
||||
cfg.Tty = true
|
||||
cfg.NoCmd = true
|
||||
switch invoke {
|
||||
case "default", "debug-shell":
|
||||
return cfg, nil
|
||||
@@ -678,16 +707,19 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
||||
// TODO: make this configurable via flags or restorable from LLB.
|
||||
// Discussion: https://github.com/docker/buildx/pull/1640#discussion_r1113295900
|
||||
cfg.Cmd = []string{"/bin/sh"}
|
||||
cfg.NoCmd = false
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
csvReader := csv.NewReader(strings.NewReader(invoke))
|
||||
csvReader.LazyQuotes = true
|
||||
fields, err := csvReader.Read()
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
if len(fields) == 1 && !strings.Contains(fields[0], "=") {
|
||||
cfg.Cmd = []string{fields[0]}
|
||||
cfg.NoCmd = false
|
||||
return cfg, nil
|
||||
}
|
||||
cfg.NoUser = true
|
||||
@@ -701,11 +733,16 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
||||
value := parts[1]
|
||||
switch key {
|
||||
case "args":
|
||||
cfg.Cmd = append(cfg.Cmd, value) // TODO: support JSON
|
||||
cfg.Cmd = append(cfg.Cmd, maybeJSONArray(value)...)
|
||||
cfg.NoCmd = false
|
||||
case "entrypoint":
|
||||
cfg.Entrypoint = append(cfg.Entrypoint, value) // TODO: support JSON
|
||||
cfg.Entrypoint = append(cfg.Entrypoint, maybeJSONArray(value)...)
|
||||
if cfg.Cmd == nil {
|
||||
cfg.Cmd = []string{}
|
||||
cfg.NoCmd = false
|
||||
}
|
||||
case "env":
|
||||
cfg.Env = append(cfg.Env, value)
|
||||
cfg.Env = append(cfg.Env, maybeJSONArray(value)...)
|
||||
case "user":
|
||||
cfg.User = value
|
||||
cfg.NoUser = false
|
||||
@@ -724,6 +761,14 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func maybeJSONArray(v string) []string {
|
||||
var list []string
|
||||
if err := json.Unmarshal([]byte(v), &list); err == nil {
|
||||
return list
|
||||
}
|
||||
return []string{v}
|
||||
}
|
||||
|
||||
func listToMap(values []string, defaultEnv bool) map[string]string {
|
||||
result := make(map[string]string, len(values))
|
||||
for _, value := range values {
|
||||
|
||||
@@ -42,6 +42,7 @@ type createOptions struct {
|
||||
flags string
|
||||
configFile string
|
||||
driverOpts []string
|
||||
securityOpts []string
|
||||
bootstrap bool
|
||||
// upgrade bool // perform upgrade of the driver
|
||||
}
|
||||
@@ -239,6 +240,11 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := csvToMap(in.securityOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if in.configFile == "" {
|
||||
// if buildkit config is not provided, check if the default one is
|
||||
// available and use it
|
||||
@@ -248,7 +254,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := ng.Update(in.nodeName, ep, in.platform, setEp, in.actionAppend, flags, in.configFile, m); err != nil {
|
||||
if err := ng.Update(in.nodeName, ep, in.platform, setEp, in.actionAppend, flags, in.configFile, m, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -340,6 +346,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVar(&options.configFile, "config", "", "BuildKit config file")
|
||||
flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node")
|
||||
flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver")
|
||||
flags.StringArrayVar(&options.securityOpts, "security-opt", []string{}, "Options for the security profile of driver")
|
||||
flags.BoolVar(&options.bootstrap, "bootstrap", false, "Boot builder after creation")
|
||||
|
||||
flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
|
||||
|
||||
@@ -24,6 +24,9 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "debug-shell",
|
||||
Short: "Start a monitor",
|
||||
Annotations: map[string]string{
|
||||
"experimentalCLI": "",
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
printer, err := progress.NewPrinter(context.TODO(), os.Stderr, os.Stderr, progressMode)
|
||||
if err != nil {
|
||||
@@ -47,7 +50,7 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
err = monitor.RunMonitor(ctx, "", nil, controllerapi.InvokeConfig{
|
||||
Tty: true,
|
||||
}, c, os.Stdin, os.Stdout, os.Stderr, printer)
|
||||
}, c, dockerCli.In(), os.Stdout, os.Stderr, printer)
|
||||
con.Reset()
|
||||
return err
|
||||
},
|
||||
@@ -55,9 +58,15 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.StringVar(&options.Root, "root", "", "Specify root directory of server to connect [experimental]")
|
||||
flags.BoolVar(&options.Detach, "detach", runtime.GOOS == "linux", "Detach buildx server (supported only on linux) [experimental]")
|
||||
flags.StringVar(&options.ServerConfig, "server-config", "", "Specify buildx server config file (used only when launching new server) [experimental]")
|
||||
flags.StringVar(&options.Root, "root", "", "Specify root directory of server to connect")
|
||||
flags.SetAnnotation("root", "experimentalCLI", nil)
|
||||
|
||||
flags.BoolVar(&options.Detach, "detach", runtime.GOOS == "linux", "Detach buildx server (supported only on linux)")
|
||||
flags.SetAnnotation("detach", "experimentalCLI", nil)
|
||||
|
||||
flags.StringVar(&options.ServerConfig, "server-config", "", "Specify buildx server config file (used only when launching new server)")
|
||||
flags.SetAnnotation("server-config", "experimentalCLI", nil)
|
||||
|
||||
flags.StringVar(&progressMode, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -25,6 +25,7 @@ type createOptions struct {
|
||||
builder string
|
||||
files []string
|
||||
tags []string
|
||||
annotations []string
|
||||
dryrun bool
|
||||
actionAppend bool
|
||||
progress string
|
||||
@@ -82,6 +83,11 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
||||
return errors.Errorf("no repositories specified, please set a reference in tag or source")
|
||||
}
|
||||
|
||||
ann, err := parseAnnotations(in.annotations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var defaultRepo *string
|
||||
if len(repos) == 1 {
|
||||
for repo := range repos {
|
||||
@@ -154,7 +160,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
dt, desc, err := r.Combine(ctx, srcs)
|
||||
dt, desc, err := r.Combine(ctx, srcs, ann)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -264,6 +270,18 @@ func parseSource(in string) (*imagetools.Source, error) {
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
func parseAnnotations(in []string) (map[string]string, error) {
|
||||
out := make(map[string]string)
|
||||
for _, i := range in {
|
||||
kv := strings.SplitN(i, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
return nil, errors.Errorf("invalid annotation %q, expected key=value", in)
|
||||
}
|
||||
out[kv[0]] = kv[1]
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
||||
var options createOptions
|
||||
|
||||
@@ -283,6 +301,7 @@ func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
||||
flags.BoolVar(&options.dryrun, "dry-run", false, "Show final image instead of pushing")
|
||||
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
|
||||
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
||||
flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -4,15 +4,19 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/docker/buildx/builder"
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/buildx/util/cobrautil/completion"
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/debug"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -78,6 +82,13 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
||||
if len(driverOpts) > 0 {
|
||||
fmt.Fprintf(w, "Driver Options:\t%s\n", strings.Join(driverOpts, " "))
|
||||
}
|
||||
var securityOpts []string
|
||||
for k, v := range n.SecurityOpts {
|
||||
securityOpts = append(securityOpts, fmt.Sprintf("%s=%q", k, v))
|
||||
}
|
||||
if len(securityOpts) > 0 {
|
||||
fmt.Fprintf(w, "Security Options:\t%s\n", strings.Join(driverOpts, " "))
|
||||
}
|
||||
|
||||
if err := n.Err; err != nil {
|
||||
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
||||
@@ -90,6 +101,38 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
||||
fmt.Fprintf(w, "Buildkit:\t%s\n", nodes[i].Version)
|
||||
}
|
||||
fmt.Fprintf(w, "Platforms:\t%s\n", strings.Join(platformutil.FormatInGroups(n.Node.Platforms, n.Platforms), ", "))
|
||||
if debug.IsEnabled() {
|
||||
fmt.Fprintf(w, "Features:\n")
|
||||
features := nodes[i].Driver.Features(ctx)
|
||||
featKeys := make([]string, 0, len(features))
|
||||
for k := range features {
|
||||
featKeys = append(featKeys, string(k))
|
||||
}
|
||||
sort.Strings(featKeys)
|
||||
for _, k := range featKeys {
|
||||
fmt.Fprintf(w, "\t%s:\t%t\n", k, features[driver.Feature(k)])
|
||||
}
|
||||
}
|
||||
if len(nodes[i].Labels) > 0 {
|
||||
fmt.Fprintf(w, "Labels:\n")
|
||||
for _, k := range sortedKeys(nodes[i].Labels) {
|
||||
v := nodes[i].Labels[k]
|
||||
fmt.Fprintf(w, "\t%s:\t%s\n", k, v)
|
||||
}
|
||||
}
|
||||
for ri, rule := range nodes[i].GCPolicy {
|
||||
fmt.Fprintf(w, "GC Policy rule#%d:\n", ri)
|
||||
fmt.Fprintf(w, "\tAll:\t%v\n", rule.All)
|
||||
if len(rule.Filter) > 0 {
|
||||
fmt.Fprintf(w, "\tFilters:\t%s\n", strings.Join(rule.Filter, " "))
|
||||
}
|
||||
if rule.KeepDuration > 0 {
|
||||
fmt.Fprintf(w, "\tKeep Duration:\t%v\n", rule.KeepDuration.String())
|
||||
}
|
||||
if rule.KeepBytes > 0 {
|
||||
fmt.Fprintf(w, "\tKeep Bytes:\t%s\n", units.BytesSize(float64(rule.KeepBytes)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,3 +164,14 @@ func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func sortedKeys(m map[string]string) []string {
|
||||
s := make([]string, len(m))
|
||||
i := 0
|
||||
for k := range m {
|
||||
s[i] = k
|
||||
i++
|
||||
}
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli-plugins/plugin"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/debug"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@@ -40,6 +41,11 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman
|
||||
cmd.TraverseChildren = true
|
||||
cmd.DisableFlagsInUseLine = true
|
||||
cli.DisableFlagsInUseLine(cmd)
|
||||
|
||||
// DEBUG=1 should perform the same as --debug at the docker root level
|
||||
if debug.IsEnabled() {
|
||||
debug.Enable()
|
||||
}
|
||||
}
|
||||
|
||||
logrus.SetFormatter(&logutil.Formatter{})
|
||||
@@ -52,17 +58,6 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman
|
||||
"using default config store",
|
||||
))
|
||||
|
||||
// filter out useless commandConn.CloseWrite warning message that can occur
|
||||
// when listing builder instances with "buildx ls" for those that are
|
||||
// unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
|
||||
// https://github.com/docker/cli/blob/3fb4fb83dfb5db0c0753a8316f21aea54dab32c5/cli/connhelper/commandconn/commandconn.go#L203-L214
|
||||
logrus.AddHook(logutil.NewFilter([]logrus.Level{
|
||||
logrus.WarnLevel,
|
||||
},
|
||||
"commandConn.CloseWrite:",
|
||||
"commandConn.CloseRead:",
|
||||
))
|
||||
|
||||
addCommands(cmd, dockerCli)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ const defaultTargetName = "default"
|
||||
|
||||
// RunBuild runs the specified build and returns the result.
|
||||
//
|
||||
// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext,
|
||||
// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultHandle,
|
||||
// this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can
|
||||
// inspect the result and debug the cause of that error.
|
||||
func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progress progress.Writer, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) {
|
||||
func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.BuildOptions, inStream io.Reader, progress progress.Writer, generateResult bool) (*client.SolveResponse, *build.ResultHandle, error) {
|
||||
if in.NoCache && len(in.NoCacheFilter) > 0 {
|
||||
return nil, nil, errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together")
|
||||
}
|
||||
@@ -54,6 +54,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
|
||||
NamedContexts: contexts,
|
||||
},
|
||||
BuildArgs: in.BuildArgs,
|
||||
CgroupParent: in.CgroupParent,
|
||||
ExtraHosts: in.ExtraHosts,
|
||||
Labels: in.Labels,
|
||||
NetworkMode: in.NetworkMode,
|
||||
@@ -176,7 +177,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
|
||||
resp, res, err := buildTargets(ctx, dockerCli, b.NodeGroup, nodes, map[string]build.Options{defaultTargetName: opts}, progress, generateResult)
|
||||
err = wrapBuildError(err, false)
|
||||
if err != nil {
|
||||
// NOTE: buildTargets can return *build.ResultContext even on error.
|
||||
// NOTE: buildTargets can return *build.ResultHandle even on error.
|
||||
return nil, res, err
|
||||
}
|
||||
return resp, res, nil
|
||||
@@ -184,17 +185,17 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in controllerapi.Build
|
||||
|
||||
// buildTargets runs the specified build and returns the result.
|
||||
//
|
||||
// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultContext,
|
||||
// NOTE: When an error happens during the build and this function acquires the debuggable *build.ResultHandle,
|
||||
// this function returns it in addition to the error (i.e. it does "return nil, res, err"). The caller can
|
||||
// inspect the result and debug the cause of that error.
|
||||
func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, generateResult bool) (*client.SolveResponse, *build.ResultContext, error) {
|
||||
var res *build.ResultContext
|
||||
func buildTargets(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, nodes []builder.Node, opts map[string]build.Options, progress progress.Writer, generateResult bool) (*client.SolveResponse, *build.ResultHandle, error) {
|
||||
var res *build.ResultHandle
|
||||
var resp map[string]*client.SolveResponse
|
||||
var err error
|
||||
if generateResult {
|
||||
var mu sync.Mutex
|
||||
var idx int
|
||||
resp, err = build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress, func(driverIndex int, gotRes *build.ResultContext) {
|
||||
resp, err = build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), progress, func(driverIndex int, gotRes *build.ResultHandle) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if res == nil || driverIndex < idx {
|
||||
|
||||
@@ -29,7 +29,7 @@ func NewLocalBuildxController(ctx context.Context, dockerCli command.Cli, logger
|
||||
type buildConfig struct {
|
||||
// TODO: these two structs should be merged
|
||||
// Discussion: https://github.com/docker/buildx/pull/1640#discussion_r1113279719
|
||||
resultCtx *build.ResultContext
|
||||
resultCtx *build.ResultHandle
|
||||
buildOptions *controllerapi.BuildOptions
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func (b *localController) Build(ctx context.Context, options controllerapi.Build
|
||||
defer b.buildOnGoing.Store(false)
|
||||
|
||||
resp, res, buildErr := cbuild.RunBuild(ctx, b.dockerCli, options, in, progress, true)
|
||||
// NOTE: RunBuild can return *build.ResultContext even on error.
|
||||
// NOTE: RunBuild can return *build.ResultHandle even on error.
|
||||
if res != nil {
|
||||
b.buildConfig = buildConfig{
|
||||
resultCtx: res,
|
||||
|
||||
@@ -1527,6 +1527,7 @@ func (m *InitMessage) GetInvokeConfig() *InvokeConfig {
|
||||
type InvokeConfig struct {
|
||||
Entrypoint []string `protobuf:"bytes,1,rep,name=Entrypoint,proto3" json:"Entrypoint,omitempty"`
|
||||
Cmd []string `protobuf:"bytes,2,rep,name=Cmd,proto3" json:"Cmd,omitempty"`
|
||||
NoCmd bool `protobuf:"varint,11,opt,name=NoCmd,proto3" json:"NoCmd,omitempty"`
|
||||
Env []string `protobuf:"bytes,3,rep,name=Env,proto3" json:"Env,omitempty"`
|
||||
User string `protobuf:"bytes,4,opt,name=User,proto3" json:"User,omitempty"`
|
||||
NoUser bool `protobuf:"varint,5,opt,name=NoUser,proto3" json:"NoUser,omitempty"`
|
||||
@@ -1578,6 +1579,13 @@ func (m *InvokeConfig) GetCmd() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *InvokeConfig) GetNoCmd() bool {
|
||||
if m != nil {
|
||||
return m.NoCmd
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *InvokeConfig) GetEnv() []string {
|
||||
if m != nil {
|
||||
return m.Env
|
||||
@@ -2046,125 +2054,126 @@ func init() {
|
||||
func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
|
||||
|
||||
var fileDescriptor_ed7f10298fa1d90f = []byte{
|
||||
// 1881 bytes of a gzipped FileDescriptorProto
|
||||
// 1890 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x6f, 0xdb, 0xc8,
|
||||
0x11, 0x2f, 0x25, 0x59, 0x7f, 0x46, 0x96, 0xe3, 0x6c, 0x9d, 0x74, 0xc3, 0xa4, 0x17, 0x87, 0x49,
|
||||
0xae, 0x42, 0x53, 0x48, 0x77, 0xbe, 0xa6, 0xbe, 0x5c, 0xee, 0x80, 0xda, 0xb2, 0x05, 0xfb, 0x90,
|
||||
0xd8, 0xc6, 0xca, 0xc9, 0xa1, 0x2d, 0xd0, 0x80, 0x92, 0xd6, 0x32, 0x21, 0x8a, 0xab, 0x72, 0x57,
|
||||
0xb6, 0xd5, 0xa7, 0xbe, 0xf4, 0xad, 0xe8, 0xf7, 0x28, 0xfa, 0x11, 0xfa, 0xd2, 0x7e, 0xa1, 0xa2,
|
||||
0x1f, 0xa1, 0xd8, 0x3f, 0xa4, 0x48, 0x4b, 0x94, 0xed, 0xf6, 0x49, 0x3b, 0xc3, 0xdf, 0x6f, 0x76,
|
||||
0x67, 0x38, 0x3b, 0x33, 0x14, 0xac, 0xf7, 0x58, 0x20, 0x42, 0xe6, 0xfb, 0x34, 0x6c, 0x8c, 0x43,
|
||||
0x26, 0x18, 0xda, 0xe8, 0x4e, 0x3c, 0xbf, 0x7f, 0xd5, 0x48, 0x3c, 0xb8, 0xf8, 0xd2, 0x7e, 0x3b,
|
||||
0xf0, 0xc4, 0xf9, 0xa4, 0xdb, 0xe8, 0xb1, 0x51, 0x73, 0xc4, 0xba, 0xd3, 0xa6, 0x42, 0x0d, 0x3d,
|
||||
0xd1, 0x74, 0xc7, 0x5e, 0x93, 0xd3, 0xf0, 0xc2, 0xeb, 0x51, 0xde, 0x34, 0xa4, 0xe8, 0x57, 0x9b,
|
||||
0xb4, 0x5f, 0x67, 0x92, 0x39, 0x9b, 0x84, 0x3d, 0x3a, 0x66, 0xbe, 0xd7, 0x9b, 0x36, 0xc7, 0xdd,
|
||||
0xa6, 0x5e, 0x69, 0x9a, 0x53, 0x87, 0x8d, 0x77, 0x1e, 0x17, 0x27, 0x21, 0xeb, 0x51, 0xce, 0x29,
|
||||
0x27, 0xf4, 0x0f, 0x13, 0xca, 0x05, 0x5a, 0x87, 0x3c, 0xa1, 0x67, 0xd8, 0xda, 0xb4, 0xea, 0x15,
|
||||
0x22, 0x97, 0xce, 0x09, 0x3c, 0xb8, 0x86, 0xe4, 0x63, 0x16, 0x70, 0x8a, 0xb6, 0x61, 0xe5, 0x30,
|
||||
0x38, 0x63, 0x1c, 0x5b, 0x9b, 0xf9, 0x7a, 0x75, 0xeb, 0x59, 0x63, 0x91, 0x73, 0x0d, 0xc3, 0x93,
|
||||
0x48, 0xa2, 0xf1, 0x0e, 0x87, 0x6a, 0x42, 0x8b, 0x9e, 0x40, 0x25, 0x12, 0xf7, 0xcc, 0xc6, 0x33,
|
||||
0x05, 0x6a, 0xc3, 0xea, 0x61, 0x70, 0xc1, 0x86, 0xb4, 0xc5, 0x82, 0x33, 0x6f, 0x80, 0x73, 0x9b,
|
||||
0x56, 0xbd, 0xba, 0xe5, 0x2c, 0xde, 0x2c, 0x89, 0x24, 0x29, 0x9e, 0xf3, 0x3d, 0xe0, 0x3d, 0x8f,
|
||||
0xf7, 0x58, 0x10, 0xd0, 0x5e, 0xe4, 0x4c, 0xa6, 0xd3, 0xe9, 0x33, 0xe5, 0xae, 0x9d, 0xc9, 0x79,
|
||||
0x0c, 0x8f, 0x16, 0xd8, 0xd2, 0x61, 0x71, 0x7e, 0x0f, 0xab, 0xbb, 0xf2, 0x6c, 0xd9, 0xc6, 0xbf,
|
||||
0x85, 0xd2, 0xf1, 0x58, 0x78, 0x2c, 0xe0, 0xcb, 0xbd, 0x51, 0x66, 0x0c, 0x92, 0x44, 0x14, 0xe7,
|
||||
0x9f, 0x55, 0xb3, 0x81, 0x51, 0xa0, 0x4d, 0xa8, 0xb6, 0x58, 0x20, 0xe8, 0x95, 0x38, 0x71, 0xc5,
|
||||
0xb9, 0xd9, 0x28, 0xa9, 0x42, 0x9f, 0xc3, 0xda, 0x1e, 0xeb, 0x0d, 0x69, 0x78, 0xe6, 0xf9, 0xf4,
|
||||
0xc8, 0x1d, 0x51, 0xe3, 0xd2, 0x35, 0x2d, 0xfa, 0x4e, 0x7a, 0xed, 0x05, 0xa2, 0x3d, 0x09, 0x7a,
|
||||
0x38, 0xaf, 0x8e, 0xf6, 0x34, 0xeb, 0xad, 0x1a, 0x18, 0x99, 0x31, 0xd0, 0xef, 0xa0, 0x26, 0xcd,
|
||||
0xf4, 0xcd, 0xd6, 0x1c, 0x17, 0x54, 0x62, 0xbc, 0xbe, 0xd9, 0xbb, 0x46, 0x8a, 0xb7, 0x1f, 0x88,
|
||||
0x70, 0x4a, 0xd2, 0xb6, 0xd0, 0x06, 0xac, 0xec, 0xf8, 0x3e, 0xbb, 0xc4, 0x2b, 0x9b, 0xf9, 0x7a,
|
||||
0x85, 0x68, 0x01, 0xfd, 0x0a, 0x4a, 0x3b, 0x42, 0x50, 0x2e, 0x38, 0x2e, 0xaa, 0xcd, 0x9e, 0x2c,
|
||||
0xde, 0x4c, 0x83, 0x48, 0x04, 0x46, 0xc7, 0x50, 0x51, 0xfb, 0xef, 0x84, 0x03, 0x8e, 0x4b, 0x8a,
|
||||
0xf9, 0xe5, 0x2d, 0x8e, 0x19, 0x73, 0xf4, 0x11, 0x67, 0x36, 0xd0, 0x3e, 0x54, 0x5a, 0x6e, 0xef,
|
||||
0x9c, 0xb6, 0x43, 0x36, 0xc2, 0x65, 0x65, 0xf0, 0x67, 0x8b, 0x0d, 0x2a, 0x98, 0x31, 0x68, 0xcc,
|
||||
0xc4, 0x4c, 0xb4, 0x03, 0x25, 0x25, 0x9c, 0x32, 0x5c, 0xb9, 0x9b, 0x91, 0x88, 0x87, 0x1c, 0x58,
|
||||
0x6d, 0x0d, 0x42, 0x36, 0x19, 0x9f, 0xb8, 0x21, 0x0d, 0x04, 0x06, 0xf5, 0xaa, 0x53, 0x3a, 0xf4,
|
||||
0x16, 0x4a, 0xfb, 0x57, 0x63, 0x16, 0x0a, 0x8e, 0xab, 0xcb, 0x2e, 0xaf, 0x06, 0x99, 0x0d, 0x0c,
|
||||
0x03, 0x7d, 0x06, 0xb0, 0x7f, 0x25, 0x42, 0xf7, 0x80, 0xc9, 0xb0, 0xaf, 0xaa, 0xd7, 0x91, 0xd0,
|
||||
0xa0, 0x36, 0x14, 0xdf, 0xb9, 0x5d, 0xea, 0x73, 0x5c, 0x53, 0xb6, 0x1b, 0xb7, 0x08, 0xac, 0x26,
|
||||
0xe8, 0x8d, 0x0c, 0x5b, 0xe6, 0xf5, 0x11, 0x15, 0x97, 0x2c, 0x1c, 0xbe, 0x67, 0x7d, 0x8a, 0xd7,
|
||||
0x74, 0x5e, 0x27, 0x54, 0xe8, 0x05, 0xd4, 0x8e, 0x98, 0x0e, 0x9e, 0xe7, 0x0b, 0x1a, 0xe2, 0x7b,
|
||||
0xea, 0x30, 0x69, 0xa5, 0xba, 0xcb, 0xbe, 0x2b, 0xce, 0x58, 0x38, 0xe2, 0x78, 0x5d, 0x21, 0x66,
|
||||
0x0a, 0x99, 0x41, 0x1d, 0xda, 0x0b, 0xa9, 0xe0, 0xf8, 0xfe, 0xb2, 0x0c, 0xd2, 0x20, 0x12, 0x81,
|
||||
0x11, 0x86, 0x52, 0xe7, 0x7c, 0xd4, 0xf1, 0xfe, 0x48, 0x31, 0xda, 0xb4, 0xea, 0x79, 0x12, 0x89,
|
||||
0xe8, 0x15, 0xe4, 0x3b, 0x9d, 0x03, 0xfc, 0x63, 0x65, 0xed, 0x51, 0x86, 0xb5, 0xce, 0x01, 0x91,
|
||||
0x28, 0x84, 0xa0, 0x70, 0xea, 0x0e, 0x38, 0xde, 0x50, 0xe7, 0x52, 0x6b, 0xf4, 0x10, 0x8a, 0xa7,
|
||||
0x6e, 0x38, 0xa0, 0x02, 0x3f, 0x50, 0x3e, 0x1b, 0x09, 0xbd, 0x81, 0xd2, 0x07, 0xdf, 0x1b, 0x79,
|
||||
0x82, 0xe3, 0x87, 0xcb, 0x2e, 0xa7, 0x06, 0x1d, 0x8f, 0x05, 0x89, 0xf0, 0xf2, 0xb4, 0x2a, 0xde,
|
||||
0x34, 0xc4, 0x3f, 0x51, 0x36, 0x23, 0x51, 0x3e, 0x31, 0xe1, 0xc2, 0x78, 0xd3, 0xaa, 0x97, 0x49,
|
||||
0x24, 0xca, 0xa3, 0x9d, 0x4c, 0x7c, 0x1f, 0x3f, 0x52, 0x6a, 0xb5, 0xd6, 0xef, 0x5e, 0xa6, 0xc1,
|
||||
0xc9, 0x84, 0x9f, 0x63, 0x5b, 0x3d, 0x49, 0x68, 0x66, 0xcf, 0xdf, 0x31, 0xb7, 0x8f, 0x1f, 0x27,
|
||||
0x9f, 0x4b, 0x0d, 0x3a, 0x84, 0xd5, 0x8e, 0x6a, 0x4b, 0x27, 0xaa, 0x19, 0xe1, 0x27, 0xca, 0x8f,
|
||||
0x97, 0x0d, 0xd9, 0xb9, 0x1a, 0x51, 0xe7, 0x92, 0x3e, 0x24, 0x9b, 0x57, 0x43, 0x83, 0x49, 0x8a,
|
||||
0x6a, 0xff, 0x1a, 0xd0, 0x7c, 0xd5, 0x90, 0xd5, 0x76, 0x48, 0xa7, 0x51, 0xb5, 0x1d, 0xd2, 0xa9,
|
||||
0x2c, 0x1c, 0x17, 0xae, 0x3f, 0x89, 0x6a, 0x9e, 0x16, 0xbe, 0xc9, 0x7d, 0x6d, 0xd9, 0xdf, 0xc2,
|
||||
0x5a, 0xfa, 0x42, 0xdf, 0x89, 0xfd, 0x06, 0xaa, 0x89, 0xac, 0xbd, 0x0b, 0xd5, 0xf9, 0x97, 0x05,
|
||||
0xd5, 0xc4, 0xd5, 0x52, 0x49, 0x30, 0x1d, 0x53, 0x43, 0x56, 0x6b, 0xb4, 0x0b, 0x2b, 0x3b, 0x42,
|
||||
0x84, 0xb2, 0x45, 0xc8, 0x3c, 0xfa, 0xc5, 0x8d, 0x17, 0xb4, 0xa1, 0xe0, 0xfa, 0x0a, 0x69, 0xaa,
|
||||
0xbc, 0x41, 0x7b, 0x94, 0x0b, 0x2f, 0x70, 0xe5, 0x2d, 0x53, 0x15, 0xbd, 0x42, 0x92, 0x2a, 0xfb,
|
||||
0x6b, 0x80, 0x19, 0xed, 0x4e, 0x3e, 0xfc, 0xdd, 0x82, 0xfb, 0x73, 0x55, 0x68, 0xa1, 0x27, 0x07,
|
||||
0x69, 0x4f, 0xb6, 0x6e, 0x59, 0xd1, 0xe6, 0xfd, 0xf9, 0x3f, 0x4e, 0x7b, 0x04, 0x45, 0x5d, 0xfa,
|
||||
0x17, 0x9e, 0xd0, 0x86, 0xf2, 0x9e, 0xc7, 0xdd, 0xae, 0x4f, 0xfb, 0x8a, 0x5a, 0x26, 0xb1, 0xac,
|
||||
0xfa, 0x8e, 0x3a, 0xbd, 0x8e, 0x9e, 0x16, 0x1c, 0x7d, 0xc7, 0xd1, 0x1a, 0xe4, 0xe2, 0x99, 0x25,
|
||||
0x77, 0xb8, 0x27, 0xc1, 0xb2, 0xe1, 0x6a, 0x57, 0x2b, 0x44, 0x0b, 0x4e, 0x1b, 0x8a, 0xba, 0x6a,
|
||||
0xcc, 0xe1, 0x6d, 0x28, 0xb7, 0x3d, 0x9f, 0xaa, 0xbe, 0xad, 0xcf, 0x1c, 0xcb, 0xd2, 0xbd, 0xfd,
|
||||
0xe0, 0xc2, 0x6c, 0x2b, 0x97, 0xce, 0x76, 0xa2, 0x3d, 0x4b, 0x3f, 0x54, 0x27, 0x37, 0x7e, 0xa8,
|
||||
0xfe, 0xfd, 0x10, 0x8a, 0x6d, 0x16, 0x8e, 0x5c, 0x61, 0x8c, 0x19, 0xc9, 0x71, 0x60, 0xed, 0x30,
|
||||
0xe0, 0x63, 0xda, 0x13, 0xd9, 0x63, 0xde, 0x31, 0xdc, 0x8b, 0x31, 0x66, 0xc0, 0x4b, 0xcc, 0x29,
|
||||
0xd6, 0xdd, 0xe7, 0x94, 0xbf, 0x59, 0x50, 0x89, 0x2b, 0x11, 0x6a, 0x41, 0x51, 0xbd, 0x8d, 0x68,
|
||||
0x5a, 0x7c, 0x75, 0x43, 0xe9, 0x6a, 0x7c, 0x54, 0x68, 0xd3, 0x11, 0x34, 0xd5, 0xfe, 0x01, 0xaa,
|
||||
0x09, 0xf5, 0x82, 0x04, 0xd8, 0x4a, 0x26, 0x40, 0x66, 0x29, 0xd7, 0x9b, 0x24, 0xd3, 0x63, 0x0f,
|
||||
0x8a, 0x5a, 0xb9, 0x30, 0xac, 0x08, 0x0a, 0x07, 0x6e, 0xa8, 0x53, 0x23, 0x4f, 0xd4, 0x5a, 0xea,
|
||||
0x3a, 0xec, 0x4c, 0xa8, 0xd7, 0x93, 0x27, 0x6a, 0xed, 0xfc, 0xc3, 0x82, 0x9a, 0x19, 0xfd, 0x4c,
|
||||
0x04, 0x29, 0xac, 0xeb, 0x1b, 0x4a, 0xc3, 0x48, 0x67, 0xfc, 0x7f, 0xb3, 0x24, 0x94, 0x11, 0xb4,
|
||||
0x71, 0x9d, 0xab, 0xa3, 0x31, 0x67, 0xd2, 0x6e, 0xc1, 0x83, 0x85, 0xd0, 0x3b, 0x5d, 0x91, 0x97,
|
||||
0x70, 0x7f, 0x36, 0xd4, 0x66, 0xe7, 0xc9, 0x06, 0xa0, 0x24, 0xcc, 0x0c, 0xbd, 0x4f, 0xa1, 0x2a,
|
||||
0x3f, 0x12, 0xb2, 0x69, 0x0e, 0xac, 0x6a, 0x80, 0x89, 0x0c, 0x82, 0xc2, 0x90, 0x4e, 0x75, 0x36,
|
||||
0x54, 0x88, 0x5a, 0x3b, 0x7f, 0xb5, 0xe4, 0xac, 0x3f, 0x9e, 0x88, 0xf7, 0x94, 0x73, 0x77, 0x20,
|
||||
0x13, 0xb0, 0x70, 0x18, 0x78, 0xc2, 0x64, 0xdf, 0xe7, 0x59, 0x33, 0xff, 0x78, 0x22, 0x24, 0xcc,
|
||||
0xb0, 0x0e, 0x7e, 0x44, 0x14, 0x0b, 0x6d, 0x43, 0x61, 0xcf, 0x15, 0xae, 0xc9, 0x85, 0x8c, 0x09,
|
||||
0x47, 0x22, 0x12, 0x44, 0x29, 0xee, 0x96, 0xe4, 0x87, 0xcd, 0x78, 0x22, 0x9c, 0x17, 0xb0, 0x7e,
|
||||
0xdd, 0xfa, 0x02, 0xd7, 0xbe, 0x82, 0x6a, 0xc2, 0x8a, 0xba, 0xb7, 0xc7, 0x6d, 0x05, 0x28, 0x13,
|
||||
0xb9, 0x94, 0xbe, 0xc6, 0x07, 0x59, 0xd5, 0x7b, 0x38, 0xf7, 0xa0, 0xa6, 0x4c, 0xc7, 0x11, 0xfc,
|
||||
0x53, 0x0e, 0x4a, 0x91, 0x89, 0xed, 0x94, 0xdf, 0xcf, 0xb2, 0xfc, 0x9e, 0x77, 0xf9, 0x35, 0x14,
|
||||
0x64, 0xfd, 0x30, 0x2e, 0x67, 0x8c, 0x07, 0xed, 0x7e, 0x82, 0x26, 0xe1, 0xe8, 0x3b, 0x28, 0x12,
|
||||
0xca, 0xe5, 0x28, 0xa3, 0x87, 0xfe, 0xe7, 0x8b, 0x89, 0x1a, 0x33, 0x23, 0x1b, 0x92, 0xa4, 0x77,
|
||||
0xbc, 0x41, 0xe0, 0xfa, 0xb8, 0xb0, 0x8c, 0xae, 0x31, 0x09, 0xba, 0x56, 0xcc, 0xc2, 0xfd, 0x67,
|
||||
0x0b, 0xaa, 0x4b, 0x43, 0xbd, 0xfc, 0xb3, 0x6c, 0xee, 0x53, 0x31, 0xff, 0x3f, 0x7e, 0x2a, 0xfe,
|
||||
0xdb, 0x4a, 0x1b, 0x52, 0x53, 0x8d, 0xbc, 0x4f, 0x63, 0xe6, 0x05, 0xc2, 0xa4, 0x6c, 0x42, 0x23,
|
||||
0x0f, 0xda, 0x1a, 0xf5, 0x4d, 0xd1, 0x97, 0xcb, 0x59, 0xf1, 0xce, 0x9b, 0xe2, 0x2d, 0x93, 0xe0,
|
||||
0x03, 0xa7, 0xa1, 0x0a, 0x51, 0x85, 0xa8, 0xb5, 0xac, 0xd7, 0x47, 0x4c, 0x69, 0x57, 0x54, 0xb6,
|
||||
0x18, 0x49, 0xd9, 0xbb, 0xec, 0xe3, 0xa2, 0x76, 0xbc, 0x75, 0xa9, 0xba, 0xd0, 0x11, 0x93, 0xba,
|
||||
0x92, 0x02, 0x6a, 0x41, 0xe2, 0x4e, 0xc5, 0x14, 0x97, 0x75, 0xaa, 0x9d, 0x8a, 0xa9, 0x6c, 0x28,
|
||||
0x84, 0xf9, 0x7e, 0xd7, 0xed, 0x0d, 0x71, 0x45, 0x77, 0xb2, 0x48, 0x96, 0x93, 0x9e, 0x8c, 0xae,
|
||||
0xe7, 0xfa, 0xea, 0x9b, 0xa0, 0x4c, 0x22, 0xd1, 0xd9, 0x81, 0x4a, 0x9c, 0x14, 0xb2, 0x47, 0xb5,
|
||||
0xfb, 0x2a, 0xe8, 0x35, 0x92, 0x6b, 0xf7, 0xa3, 0x7c, 0xce, 0xcd, 0xe7, 0x73, 0x3e, 0x91, 0xcf,
|
||||
0xdb, 0x50, 0x4b, 0xa5, 0x87, 0x04, 0x11, 0x76, 0xc9, 0x8d, 0x21, 0xb5, 0x96, 0xba, 0x16, 0xf3,
|
||||
0xf5, 0x57, 0x6f, 0x8d, 0xa8, 0xb5, 0xf3, 0x1c, 0x6a, 0xa9, 0xc4, 0x58, 0x54, 0x81, 0x9d, 0x67,
|
||||
0x50, 0xeb, 0x08, 0x57, 0x4c, 0x96, 0xfc, 0x4d, 0xf1, 0x1f, 0x0b, 0xd6, 0x22, 0x8c, 0xa9, 0x31,
|
||||
0xbf, 0x84, 0xf2, 0x05, 0x0d, 0x05, 0xbd, 0x8a, 0xbb, 0x0e, 0x9e, 0x1f, 0x34, 0x3f, 0x2a, 0x04,
|
||||
0x89, 0x91, 0xe8, 0x1b, 0x28, 0x73, 0x65, 0x87, 0x46, 0x13, 0xcb, 0x67, 0x59, 0x2c, 0xb3, 0x5f,
|
||||
0x8c, 0x47, 0x4d, 0x28, 0xf8, 0x6c, 0xc0, 0xd5, 0x7b, 0xaf, 0x6e, 0x3d, 0xce, 0xe2, 0xbd, 0x63,
|
||||
0x03, 0xa2, 0x80, 0xe8, 0x2d, 0x94, 0x2f, 0xdd, 0x30, 0xf0, 0x82, 0x41, 0xf4, 0xb5, 0xfc, 0x34,
|
||||
0x8b, 0xf4, 0x83, 0xc6, 0x91, 0x98, 0xe0, 0xd4, 0xe4, 0x75, 0x39, 0x63, 0x26, 0x26, 0xce, 0x6f,
|
||||
0x64, 0xd6, 0x4a, 0xd1, 0xb8, 0x7f, 0x08, 0x35, 0x9d, 0xf9, 0x1f, 0x69, 0xc8, 0xe5, 0xfc, 0x67,
|
||||
0x2d, 0xbb, 0x9d, 0xbb, 0x49, 0x28, 0x49, 0x33, 0x9d, 0x4f, 0xa6, 0xb1, 0x45, 0x0a, 0x99, 0x4b,
|
||||
0x63, 0xb7, 0x37, 0x74, 0x07, 0xd1, 0x7b, 0x8a, 0x44, 0xf9, 0xe4, 0xc2, 0xec, 0xa7, 0x2f, 0x68,
|
||||
0x24, 0xca, 0xdc, 0x0c, 0xe9, 0x85, 0xc7, 0x67, 0xa3, 0x68, 0x2c, 0x6f, 0xfd, 0xa5, 0x04, 0xd0,
|
||||
0x8a, 0xcf, 0x83, 0x4e, 0x60, 0x45, 0xed, 0x87, 0x9c, 0xa5, 0x6d, 0x52, 0xf9, 0x6d, 0x3f, 0xbf,
|
||||
0x45, 0x2b, 0x45, 0x1f, 0x65, 0xf2, 0xab, 0xf1, 0x06, 0xbd, 0xc8, 0x2a, 0x08, 0xc9, 0x09, 0xc9,
|
||||
0x7e, 0x79, 0x03, 0xca, 0xd8, 0xfd, 0x00, 0x45, 0x9d, 0x05, 0x28, 0xab, 0xea, 0x25, 0xf3, 0xd6,
|
||||
0x7e, 0xb1, 0x1c, 0xa4, 0x8d, 0x7e, 0x61, 0x21, 0x62, 0x6a, 0x22, 0x72, 0x96, 0x34, 0x3d, 0x73,
|
||||
0x63, 0xb2, 0x02, 0x90, 0xea, 0x2f, 0x75, 0x0b, 0x7d, 0x0f, 0x45, 0x5d, 0xd5, 0xd0, 0x4f, 0x17,
|
||||
0x13, 0x22, 0x7b, 0xcb, 0x1f, 0xd7, 0xad, 0x2f, 0x2c, 0xf4, 0x1e, 0x0a, 0xb2, 0x9d, 0xa3, 0x8c,
|
||||
0xde, 0x94, 0x98, 0x05, 0x6c, 0x67, 0x19, 0xc4, 0x44, 0xf1, 0x13, 0xc0, 0x6c, 0xa8, 0x40, 0x19,
|
||||
0xff, 0x79, 0xcc, 0x4d, 0x27, 0x76, 0xfd, 0x66, 0xa0, 0xd9, 0xe0, 0xbd, 0xec, 0xa8, 0x67, 0x0c,
|
||||
0x65, 0xf6, 0xd2, 0xf8, 0x1a, 0xd9, 0xce, 0x32, 0x88, 0x31, 0x77, 0x0e, 0xb5, 0xd4, 0x7f, 0xa2,
|
||||
0xe8, 0xe7, 0xd9, 0x4e, 0x5e, 0xff, 0x8b, 0xd5, 0x7e, 0x75, 0x2b, 0xac, 0xd9, 0x49, 0x24, 0xa7,
|
||||
0x32, 0xf3, 0x18, 0x35, 0x6e, 0xf2, 0x3b, 0xfd, 0xff, 0xa6, 0xdd, 0xbc, 0x35, 0x5e, 0xef, 0xba,
|
||||
0x5b, 0xf8, 0x6d, 0x6e, 0xdc, 0xed, 0x16, 0xd5, 0x5f, 0xc5, 0x5f, 0xfd, 0x37, 0x00, 0x00, 0xff,
|
||||
0xff, 0xc1, 0x4b, 0x2d, 0x65, 0xc8, 0x16, 0x00, 0x00,
|
||||
0xb6, 0xd5, 0xa7, 0x3e, 0xb4, 0x6f, 0x45, 0xbf, 0x47, 0xd1, 0x8f, 0xd0, 0x97, 0xf6, 0x1b, 0xf5,
|
||||
0x23, 0x14, 0xfb, 0x87, 0x14, 0x69, 0x89, 0xb2, 0xdd, 0x3e, 0x69, 0x67, 0xf8, 0xfb, 0xcd, 0xec,
|
||||
0x2c, 0x67, 0x67, 0x86, 0x82, 0xf5, 0x1e, 0x0b, 0x44, 0xc8, 0x7c, 0x9f, 0x86, 0x8d, 0x71, 0xc8,
|
||||
0x04, 0x43, 0x1b, 0xdd, 0x89, 0xe7, 0xf7, 0xaf, 0x1a, 0x89, 0x07, 0x17, 0x5f, 0xda, 0x6f, 0x07,
|
||||
0x9e, 0x38, 0x9f, 0x74, 0x1b, 0x3d, 0x36, 0x6a, 0x8e, 0x58, 0x77, 0xda, 0x54, 0xa8, 0xa1, 0x27,
|
||||
0x9a, 0xee, 0xd8, 0x6b, 0x72, 0x1a, 0x5e, 0x78, 0x3d, 0xca, 0x9b, 0x86, 0x14, 0xfd, 0x6a, 0x93,
|
||||
0xf6, 0xeb, 0x4c, 0x32, 0x67, 0x93, 0xb0, 0x47, 0xc7, 0xcc, 0xf7, 0x7a, 0xd3, 0xe6, 0xb8, 0xdb,
|
||||
0xd4, 0x2b, 0x4d, 0x73, 0xea, 0xb0, 0xf1, 0xce, 0xe3, 0xe2, 0x24, 0x64, 0x3d, 0xca, 0x39, 0xe5,
|
||||
0x84, 0xfe, 0x61, 0x42, 0xb9, 0x40, 0xeb, 0x90, 0x27, 0xf4, 0x0c, 0x5b, 0x9b, 0x56, 0xbd, 0x42,
|
||||
0xe4, 0xd2, 0x39, 0x81, 0x07, 0xd7, 0x90, 0x7c, 0xcc, 0x02, 0x4e, 0xd1, 0x36, 0xac, 0x1c, 0x06,
|
||||
0x67, 0x8c, 0x63, 0x6b, 0x33, 0x5f, 0xaf, 0x6e, 0x3d, 0x6b, 0x2c, 0x0a, 0xae, 0x61, 0x78, 0x12,
|
||||
0x49, 0x34, 0xde, 0xe1, 0x50, 0x4d, 0x68, 0xd1, 0x13, 0xa8, 0x44, 0xe2, 0x9e, 0x71, 0x3c, 0x53,
|
||||
0xa0, 0x36, 0xac, 0x1e, 0x06, 0x17, 0x6c, 0x48, 0x5b, 0x2c, 0x38, 0xf3, 0x06, 0x38, 0xb7, 0x69,
|
||||
0xd5, 0xab, 0x5b, 0xce, 0x62, 0x67, 0x49, 0x24, 0x49, 0xf1, 0x9c, 0xef, 0x01, 0xef, 0x79, 0xbc,
|
||||
0xc7, 0x82, 0x80, 0xf6, 0xa2, 0x60, 0x32, 0x83, 0x4e, 0xef, 0x29, 0x77, 0x6d, 0x4f, 0xce, 0x63,
|
||||
0x78, 0xb4, 0xc0, 0x96, 0x3e, 0x16, 0xe7, 0xf7, 0xb0, 0xba, 0x2b, 0xf7, 0x96, 0x6d, 0xfc, 0x5b,
|
||||
0x28, 0x1d, 0x8f, 0x85, 0xc7, 0x02, 0xbe, 0x3c, 0x1a, 0x65, 0xc6, 0x20, 0x49, 0x44, 0x71, 0xfe,
|
||||
0x55, 0x35, 0x0e, 0x8c, 0x02, 0x6d, 0x42, 0xb5, 0xc5, 0x02, 0x41, 0xaf, 0xc4, 0x89, 0x2b, 0xce,
|
||||
0x8d, 0xa3, 0xa4, 0x0a, 0x7d, 0x0e, 0x6b, 0x7b, 0xac, 0x37, 0xa4, 0xe1, 0x99, 0xe7, 0xd3, 0x23,
|
||||
0x77, 0x44, 0x4d, 0x48, 0xd7, 0xb4, 0xe8, 0x3b, 0x19, 0xb5, 0x17, 0x88, 0xf6, 0x24, 0xe8, 0xe1,
|
||||
0xbc, 0xda, 0xda, 0xd3, 0xac, 0xb7, 0x6a, 0x60, 0x64, 0xc6, 0x40, 0xbf, 0x83, 0x9a, 0x34, 0xd3,
|
||||
0x37, 0xae, 0x39, 0x2e, 0xa8, 0xc4, 0x78, 0x7d, 0x73, 0x74, 0x8d, 0x14, 0x6f, 0x3f, 0x10, 0xe1,
|
||||
0x94, 0xa4, 0x6d, 0xa1, 0x0d, 0x58, 0xd9, 0xf1, 0x7d, 0x76, 0x89, 0x57, 0x36, 0xf3, 0xf5, 0x0a,
|
||||
0xd1, 0x02, 0xfa, 0x15, 0x94, 0x76, 0x84, 0xa0, 0x5c, 0x70, 0x5c, 0x54, 0xce, 0x9e, 0x2c, 0x76,
|
||||
0xa6, 0x41, 0x24, 0x02, 0xa3, 0x63, 0xa8, 0x28, 0xff, 0x3b, 0xe1, 0x80, 0xe3, 0x92, 0x62, 0x7e,
|
||||
0x79, 0x8b, 0x6d, 0xc6, 0x1c, 0xbd, 0xc5, 0x99, 0x0d, 0xb4, 0x0f, 0x95, 0x96, 0xdb, 0x3b, 0xa7,
|
||||
0xed, 0x90, 0x8d, 0x70, 0x59, 0x19, 0xfc, 0xd9, 0x62, 0x83, 0x0a, 0x66, 0x0c, 0x1a, 0x33, 0x31,
|
||||
0x13, 0xed, 0x40, 0x49, 0x09, 0xa7, 0x0c, 0x57, 0xee, 0x66, 0x24, 0xe2, 0x21, 0x07, 0x56, 0x5b,
|
||||
0x83, 0x90, 0x4d, 0xc6, 0x27, 0x6e, 0x48, 0x03, 0x81, 0x41, 0xbd, 0xea, 0x94, 0x0e, 0xbd, 0x85,
|
||||
0xd2, 0xfe, 0xd5, 0x98, 0x85, 0x82, 0xe3, 0xea, 0xb2, 0xcb, 0xab, 0x41, 0xc6, 0x81, 0x61, 0xa0,
|
||||
0xcf, 0x00, 0xf6, 0xaf, 0x44, 0xe8, 0x1e, 0x30, 0x79, 0xec, 0xab, 0xea, 0x75, 0x24, 0x34, 0xa8,
|
||||
0x0d, 0xc5, 0x77, 0x6e, 0x97, 0xfa, 0x1c, 0xd7, 0x94, 0xed, 0xc6, 0x2d, 0x0e, 0x56, 0x13, 0xb4,
|
||||
0x23, 0xc3, 0x96, 0x79, 0x7d, 0x44, 0xc5, 0x25, 0x0b, 0x87, 0xef, 0x59, 0x9f, 0xe2, 0x35, 0x9d,
|
||||
0xd7, 0x09, 0x15, 0x7a, 0x01, 0xb5, 0x23, 0xa6, 0x0f, 0xcf, 0xf3, 0x05, 0x0d, 0xf1, 0x3d, 0xb5,
|
||||
0x99, 0xb4, 0x52, 0xdd, 0x65, 0xdf, 0x15, 0x67, 0x2c, 0x1c, 0x71, 0xbc, 0xae, 0x10, 0x33, 0x85,
|
||||
0xcc, 0xa0, 0x0e, 0xed, 0x85, 0x54, 0x70, 0x7c, 0x7f, 0x59, 0x06, 0x69, 0x10, 0x89, 0xc0, 0x08,
|
||||
0x43, 0xa9, 0x73, 0x3e, 0xea, 0x78, 0x7f, 0xa4, 0x18, 0x6d, 0x5a, 0xf5, 0x3c, 0x89, 0x44, 0xf4,
|
||||
0x0a, 0xf2, 0x9d, 0xce, 0x01, 0xfe, 0xb1, 0xb2, 0xf6, 0x28, 0xc3, 0x5a, 0xe7, 0x80, 0x48, 0x14,
|
||||
0x42, 0x50, 0x38, 0x75, 0x07, 0x1c, 0x6f, 0xa8, 0x7d, 0xa9, 0x35, 0x7a, 0x08, 0xc5, 0x53, 0x37,
|
||||
0x1c, 0x50, 0x81, 0x1f, 0xa8, 0x98, 0x8d, 0x84, 0xde, 0x40, 0xe9, 0x83, 0xef, 0x8d, 0x3c, 0xc1,
|
||||
0xf1, 0xc3, 0x65, 0x97, 0x53, 0x83, 0x8e, 0xc7, 0x82, 0x44, 0x78, 0xb9, 0x5b, 0x75, 0xde, 0x34,
|
||||
0xc4, 0x3f, 0x51, 0x36, 0x23, 0x51, 0x3e, 0x31, 0xc7, 0x85, 0xf1, 0xa6, 0x55, 0x2f, 0x93, 0x48,
|
||||
0x94, 0x5b, 0x3b, 0x99, 0xf8, 0x3e, 0x7e, 0xa4, 0xd4, 0x6a, 0xad, 0xdf, 0xbd, 0x4c, 0x83, 0x93,
|
||||
0x09, 0x3f, 0xc7, 0xb6, 0x7a, 0x92, 0xd0, 0xcc, 0x9e, 0xbf, 0x63, 0x6e, 0x1f, 0x3f, 0x4e, 0x3e,
|
||||
0x97, 0x1a, 0x74, 0x08, 0xab, 0x1d, 0xd5, 0x96, 0x4e, 0x54, 0x33, 0xc2, 0x4f, 0x54, 0x1c, 0x2f,
|
||||
0x1b, 0xb2, 0x73, 0x35, 0xa2, 0xce, 0x25, 0x63, 0x48, 0x36, 0xaf, 0x86, 0x06, 0x93, 0x14, 0xd5,
|
||||
0xfe, 0x35, 0xa0, 0xf9, 0xaa, 0x21, 0xab, 0xed, 0x90, 0x4e, 0xa3, 0x6a, 0x3b, 0xa4, 0x53, 0x59,
|
||||
0x38, 0x2e, 0x5c, 0x7f, 0x12, 0xd5, 0x3c, 0x2d, 0x7c, 0x93, 0xfb, 0xda, 0xb2, 0xbf, 0x85, 0xb5,
|
||||
0xf4, 0x85, 0xbe, 0x13, 0xfb, 0x0d, 0x54, 0x13, 0x59, 0x7b, 0x17, 0xaa, 0xf3, 0x6f, 0x0b, 0xaa,
|
||||
0x89, 0xab, 0xa5, 0x92, 0x60, 0x3a, 0xa6, 0x86, 0xac, 0xd6, 0x68, 0x17, 0x56, 0x76, 0x84, 0x08,
|
||||
0x65, 0x8b, 0x90, 0x79, 0xf4, 0x8b, 0x1b, 0x2f, 0x68, 0x43, 0xc1, 0xf5, 0x15, 0xd2, 0x54, 0x79,
|
||||
0x83, 0xf6, 0x28, 0x17, 0x5e, 0xe0, 0xca, 0x5b, 0xa6, 0x2a, 0x7a, 0x85, 0x24, 0x55, 0xf6, 0xd7,
|
||||
0x00, 0x33, 0xda, 0x9d, 0x62, 0xf8, 0x87, 0x05, 0xf7, 0xe7, 0xaa, 0xd0, 0xc2, 0x48, 0x0e, 0xd2,
|
||||
0x91, 0x6c, 0xdd, 0xb2, 0xa2, 0xcd, 0xc7, 0xf3, 0x7f, 0xec, 0xf6, 0x08, 0x8a, 0xba, 0xf4, 0x2f,
|
||||
0xdc, 0xa1, 0x0d, 0xe5, 0x3d, 0x8f, 0xbb, 0x5d, 0x9f, 0xf6, 0x15, 0xb5, 0x4c, 0x62, 0x59, 0xf5,
|
||||
0x1d, 0xb5, 0x7b, 0x7d, 0x7a, 0x5a, 0x70, 0xf4, 0x1d, 0x47, 0x6b, 0x90, 0x8b, 0x67, 0x96, 0xdc,
|
||||
0xe1, 0x9e, 0x04, 0xcb, 0x86, 0xab, 0x43, 0xad, 0x10, 0x2d, 0x38, 0x6d, 0x28, 0xea, 0xaa, 0x31,
|
||||
0x87, 0xb7, 0xa1, 0xdc, 0xf6, 0x7c, 0xaa, 0xfa, 0xb6, 0xde, 0x73, 0x2c, 0xcb, 0xf0, 0xf6, 0x83,
|
||||
0x0b, 0xe3, 0x56, 0x2e, 0x9d, 0xed, 0x44, 0x7b, 0x96, 0x71, 0xa8, 0x4e, 0x6e, 0xe2, 0x50, 0xfd,
|
||||
0xfb, 0x21, 0x14, 0xdb, 0x2c, 0x1c, 0xb9, 0xc2, 0x18, 0x33, 0x92, 0xe3, 0xc0, 0xda, 0x61, 0xc0,
|
||||
0xc7, 0xb4, 0x27, 0xb2, 0xc7, 0xbc, 0x63, 0xb8, 0x17, 0x63, 0xcc, 0x80, 0x97, 0x98, 0x53, 0xac,
|
||||
0xbb, 0xcf, 0x29, 0x7f, 0xb7, 0xa0, 0x12, 0x57, 0x22, 0xd4, 0x82, 0xa2, 0x7a, 0x1b, 0xd1, 0xb4,
|
||||
0xf8, 0xea, 0x86, 0xd2, 0xd5, 0xf8, 0xa8, 0xd0, 0xa6, 0x23, 0x68, 0xaa, 0xfd, 0x03, 0x54, 0x13,
|
||||
0xea, 0x05, 0x09, 0xb0, 0x95, 0x4c, 0x80, 0xcc, 0x52, 0xae, 0x9d, 0x24, 0xd3, 0x63, 0x0f, 0x8a,
|
||||
0x5a, 0xb9, 0xf0, 0x58, 0x11, 0x14, 0x0e, 0xdc, 0x50, 0xa7, 0x46, 0x9e, 0xa8, 0xb5, 0xd4, 0x75,
|
||||
0xd8, 0x99, 0x50, 0xaf, 0x27, 0x4f, 0xd4, 0xda, 0xf9, 0xa7, 0x05, 0x35, 0x33, 0xfa, 0x99, 0x13,
|
||||
0xa4, 0xb0, 0xae, 0x6f, 0x28, 0x0d, 0x23, 0x9d, 0x89, 0xff, 0xcd, 0x92, 0xa3, 0x8c, 0xa0, 0x8d,
|
||||
0xeb, 0x5c, 0x7d, 0x1a, 0x73, 0x26, 0xed, 0x16, 0x3c, 0x58, 0x08, 0xbd, 0xd3, 0x15, 0x79, 0x09,
|
||||
0xf7, 0x67, 0x43, 0x6d, 0x76, 0x9e, 0x6c, 0x00, 0x4a, 0xc2, 0xcc, 0xd0, 0xfb, 0x14, 0xaa, 0xf2,
|
||||
0x23, 0x21, 0x9b, 0xe6, 0xc0, 0xaa, 0x06, 0x98, 0x93, 0x41, 0x50, 0x18, 0xd2, 0xa9, 0xce, 0x86,
|
||||
0x0a, 0x51, 0x6b, 0xe7, 0x6f, 0x96, 0x9c, 0xf5, 0xc7, 0x13, 0xf1, 0x9e, 0x72, 0xee, 0x0e, 0x64,
|
||||
0x02, 0x16, 0x0e, 0x03, 0x4f, 0x98, 0xec, 0xfb, 0x3c, 0x6b, 0xe6, 0x1f, 0x4f, 0x84, 0x84, 0x19,
|
||||
0xd6, 0xc1, 0x8f, 0x88, 0x62, 0xa1, 0x6d, 0x28, 0xec, 0xb9, 0xc2, 0x35, 0xb9, 0x90, 0x31, 0xe1,
|
||||
0x48, 0x44, 0x82, 0x28, 0xc5, 0xdd, 0x92, 0xfc, 0xb0, 0x19, 0x4f, 0x84, 0xf3, 0x02, 0xd6, 0xaf,
|
||||
0x5b, 0x5f, 0x10, 0xda, 0x57, 0x50, 0x4d, 0x58, 0x51, 0xf7, 0xf6, 0xb8, 0xad, 0x00, 0x65, 0x22,
|
||||
0x97, 0x32, 0xd6, 0x78, 0x23, 0xab, 0xda, 0x87, 0x73, 0x0f, 0x6a, 0xca, 0x74, 0x7c, 0x82, 0x7f,
|
||||
0xca, 0x41, 0x29, 0x32, 0xb1, 0x9d, 0x8a, 0xfb, 0x59, 0x56, 0xdc, 0xf3, 0x21, 0xbf, 0x86, 0x82,
|
||||
0xac, 0x1f, 0x26, 0xe4, 0x8c, 0xf1, 0xa0, 0xdd, 0x4f, 0xd0, 0x24, 0x1c, 0x7d, 0x07, 0x45, 0x42,
|
||||
0xb9, 0x1c, 0x65, 0xf4, 0xd0, 0xff, 0x7c, 0x31, 0x51, 0x63, 0x66, 0x64, 0x43, 0x92, 0xf4, 0x8e,
|
||||
0x37, 0x08, 0x5c, 0x1f, 0x17, 0x96, 0xd1, 0x35, 0x26, 0x41, 0xd7, 0x8a, 0xd9, 0x71, 0xff, 0xc5,
|
||||
0x82, 0xea, 0xd2, 0xa3, 0x5e, 0xfe, 0x59, 0x36, 0xf7, 0xa9, 0x98, 0xff, 0x1f, 0x3f, 0x15, 0xff,
|
||||
0x9c, 0x4b, 0x1b, 0x52, 0x53, 0x8d, 0xbc, 0x4f, 0x63, 0xe6, 0x05, 0xc2, 0xa4, 0x6c, 0x42, 0x23,
|
||||
0x37, 0xda, 0x1a, 0xf5, 0x4d, 0xd1, 0x97, 0x4b, 0x79, 0xcd, 0x8e, 0x98, 0xd4, 0x55, 0x55, 0x1a,
|
||||
0x68, 0x61, 0x56, 0xd2, 0xf3, 0xa6, 0xa4, 0xcb, 0xd4, 0xf8, 0xc0, 0x69, 0xa8, 0x0e, 0xae, 0x42,
|
||||
0xd4, 0x5a, 0x56, 0xf1, 0x23, 0xa6, 0xb4, 0x2b, 0x8a, 0x6c, 0x24, 0xe5, 0xe5, 0xb2, 0x8f, 0x8b,
|
||||
0xfa, 0x38, 0x5a, 0x97, 0x91, 0x97, 0xcb, 0x3e, 0x2e, 0xc5, 0x5e, 0x2e, 0x95, 0x97, 0x53, 0x31,
|
||||
0xc5, 0x65, 0x9d, 0x80, 0xa7, 0x62, 0x2a, 0xdb, 0x0c, 0x61, 0xbe, 0xdf, 0x75, 0x7b, 0x43, 0x5c,
|
||||
0xd1, 0xfd, 0x2d, 0x92, 0xe5, 0xfc, 0x27, 0xcf, 0xdc, 0x73, 0x7d, 0xf5, 0xa5, 0x50, 0x26, 0x91,
|
||||
0xe8, 0xec, 0x40, 0x25, 0x4e, 0x15, 0xd9, 0xb9, 0xda, 0x7d, 0xf5, 0x2a, 0x6a, 0x24, 0xd7, 0xee,
|
||||
0x47, 0x59, 0x9e, 0x9b, 0xcf, 0xf2, 0x7c, 0x22, 0xcb, 0xb7, 0xa1, 0x96, 0x4a, 0x1a, 0x09, 0x22,
|
||||
0xec, 0x92, 0x1b, 0x43, 0x6a, 0x2d, 0x75, 0x2d, 0xe6, 0xeb, 0x6f, 0xe1, 0x1a, 0x51, 0x6b, 0xe7,
|
||||
0x39, 0xd4, 0x52, 0xe9, 0xb2, 0xa8, 0x2e, 0x3b, 0xcf, 0xa0, 0xd6, 0x11, 0xae, 0x98, 0x2c, 0xf9,
|
||||
0xf3, 0xe2, 0x3f, 0x16, 0xac, 0x45, 0x18, 0x53, 0x79, 0x7e, 0x09, 0xe5, 0x0b, 0x1a, 0x0a, 0x7a,
|
||||
0x15, 0xf7, 0x22, 0x3c, 0x3f, 0x7e, 0x7e, 0x54, 0x08, 0x12, 0x23, 0xd1, 0x37, 0x50, 0xe6, 0xca,
|
||||
0x0e, 0x8d, 0xe6, 0x98, 0xcf, 0xb2, 0x58, 0xc6, 0x5f, 0x8c, 0x47, 0x4d, 0x28, 0xf8, 0x6c, 0xc0,
|
||||
0xd5, 0x7b, 0xaf, 0x6e, 0x3d, 0xce, 0xe2, 0xbd, 0x63, 0x03, 0xa2, 0x80, 0xe8, 0x2d, 0x94, 0x2f,
|
||||
0xdd, 0x30, 0xf0, 0x82, 0x41, 0xf4, 0x0d, 0xfd, 0x34, 0x8b, 0xf4, 0x83, 0xc6, 0x91, 0x98, 0xe0,
|
||||
0xd4, 0xe4, 0x25, 0x3a, 0x63, 0xe6, 0x4c, 0x9c, 0xdf, 0xc8, 0x5c, 0x96, 0xa2, 0x09, 0xff, 0x10,
|
||||
0x6a, 0xfa, 0x3e, 0x7c, 0xa4, 0x21, 0x97, 0x53, 0xa1, 0xb5, 0xec, 0xce, 0xee, 0x26, 0xa1, 0x24,
|
||||
0xcd, 0x74, 0x3e, 0x99, 0x76, 0x17, 0x29, 0x64, 0x2e, 0x8d, 0xdd, 0xde, 0xd0, 0x1d, 0x44, 0xef,
|
||||
0x29, 0x12, 0xe5, 0x93, 0x0b, 0xe3, 0x4f, 0x5f, 0xdb, 0x48, 0x94, 0xb9, 0x19, 0xd2, 0x0b, 0x8f,
|
||||
0xcf, 0x06, 0xd4, 0x58, 0xde, 0xfa, 0x6b, 0x09, 0xa0, 0x15, 0xef, 0x07, 0x9d, 0xc0, 0x8a, 0xf2,
|
||||
0x87, 0x9c, 0xa5, 0xcd, 0x53, 0xc5, 0x6d, 0x3f, 0xbf, 0x45, 0x83, 0x45, 0x1f, 0x65, 0xf2, 0xab,
|
||||
0xa1, 0x07, 0xbd, 0xc8, 0x2a, 0x13, 0xc9, 0xb9, 0xc9, 0x7e, 0x79, 0x03, 0xca, 0xd8, 0xfd, 0x00,
|
||||
0x45, 0x9d, 0x05, 0x28, 0xab, 0x16, 0x26, 0xf3, 0xd6, 0x7e, 0xb1, 0x1c, 0xa4, 0x8d, 0x7e, 0x61,
|
||||
0x21, 0x62, 0x2a, 0x25, 0x72, 0x96, 0xb4, 0x42, 0x73, 0x63, 0xb2, 0x0e, 0x20, 0xd5, 0x75, 0xea,
|
||||
0x16, 0xfa, 0x1e, 0x8a, 0xba, 0xd6, 0xa1, 0x9f, 0x2e, 0x26, 0x44, 0xf6, 0x96, 0x3f, 0xae, 0x5b,
|
||||
0x5f, 0x58, 0xe8, 0x3d, 0x14, 0x64, 0x93, 0x47, 0x19, 0x1d, 0x2b, 0x31, 0x21, 0xd8, 0xce, 0x32,
|
||||
0x88, 0x39, 0xc5, 0x4f, 0x00, 0xb3, 0x51, 0x03, 0x65, 0xfc, 0x13, 0x32, 0x37, 0xb3, 0xd8, 0xf5,
|
||||
0x9b, 0x81, 0xc6, 0xc1, 0x7b, 0xd9, 0x67, 0xcf, 0x18, 0xca, 0xec, 0xb0, 0xf1, 0x35, 0xb2, 0x9d,
|
||||
0x65, 0x10, 0x63, 0xee, 0x1c, 0x6a, 0xa9, 0x7f, 0x4a, 0xd1, 0xcf, 0xb3, 0x83, 0xbc, 0xfe, 0xc7,
|
||||
0xab, 0xfd, 0xea, 0x56, 0x58, 0xe3, 0x49, 0x24, 0x67, 0x35, 0xf3, 0x18, 0x35, 0x6e, 0x8a, 0x3b,
|
||||
0xfd, 0xaf, 0xa7, 0xdd, 0xbc, 0x35, 0x5e, 0x7b, 0xdd, 0x2d, 0xfc, 0x36, 0x37, 0xee, 0x76, 0x8b,
|
||||
0xea, 0x0f, 0xe4, 0xaf, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x18, 0x4b, 0xe5, 0x8f, 0xde, 0x16,
|
||||
0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
||||
@@ -192,6 +192,7 @@ message InitMessage {
|
||||
message InvokeConfig {
|
||||
repeated string Entrypoint = 1;
|
||||
repeated string Cmd = 2;
|
||||
bool NoCmd = 11; // Do not set cmd but use the image's default
|
||||
repeated string Env = 3;
|
||||
string User = 4;
|
||||
bool NoUser = 5; // Do not set user but use the image's default
|
||||
|
||||
@@ -19,6 +19,10 @@ func (w *writer) Write(status *client.SolveStatus) {
|
||||
w.ch <- ToControlStatus(status)
|
||||
}
|
||||
|
||||
func (w *writer) WriteBuildRef(target string, ref string) {
|
||||
return
|
||||
}
|
||||
|
||||
func (w *writer) ValidateLogSource(digest.Digest, interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func (m *Manager) DeleteProcess(id string) error {
|
||||
// When a container isn't available (i.e. first time invoking or the container has exited) or cfg.Rollback is set,
|
||||
// this method will start a new container and run the process in it. Otherwise, this method starts a new process in the
|
||||
// existing container.
|
||||
func (m *Manager) StartProcess(pid string, resultCtx *build.ResultContext, cfg *pb.InvokeConfig) (*Process, error) {
|
||||
func (m *Manager) StartProcess(pid string, resultCtx *build.ResultHandle, cfg *pb.InvokeConfig) (*Process, error) {
|
||||
// Get the target result to invoke a container from
|
||||
var ctr *build.Container
|
||||
if a := m.container.Load(); a != nil {
|
||||
|
||||
@@ -148,7 +148,7 @@ func serveCmd(dockerCli command.Cli) *cobra.Command {
|
||||
}()
|
||||
|
||||
// prepare server
|
||||
b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, progress progress.Writer) (*client.SolveResponse, *build.ResultContext, error) {
|
||||
b := NewServer(func(ctx context.Context, options *controllerapi.BuildOptions, stdin io.Reader, progress progress.Writer) (*client.SolveResponse, *build.ResultHandle, error) {
|
||||
return cbuild.RunBuild(ctx, dockerCli, *options, stdin, progress, true)
|
||||
})
|
||||
defer b.Close()
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, progress progress.Writer) (resp *client.SolveResponse, res *build.ResultContext, err error)
|
||||
type BuildFunc func(ctx context.Context, options *pb.BuildOptions, stdin io.Reader, progress progress.Writer) (resp *client.SolveResponse, res *build.ResultHandle, err error)
|
||||
|
||||
func NewServer(buildFunc BuildFunc) *Server {
|
||||
return &Server{
|
||||
@@ -40,7 +40,7 @@ type session struct {
|
||||
buildOptions *pb.BuildOptions
|
||||
inputPipe *io.PipeWriter
|
||||
|
||||
result *build.ResultContext
|
||||
result *build.ResultHandle
|
||||
|
||||
processes *processes.Manager
|
||||
}
|
||||
@@ -57,9 +57,7 @@ func (m *Server) ListProcesses(ctx context.Context, req *pb.ListProcessesRequest
|
||||
return nil, errors.Errorf("unknown ref %q", req.Ref)
|
||||
}
|
||||
res = new(pb.ListProcessesResponse)
|
||||
for _, p := range s.processes.ListProcesses() {
|
||||
res.Infos = append(res.Infos, p)
|
||||
}
|
||||
res.Infos = append(res.Infos, s.processes.ListProcesses()...)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -205,7 +203,7 @@ func (m *Server) Build(ctx context.Context, req *pb.BuildRequest) (*pb.BuildResp
|
||||
resp, res, buildErr := m.buildFunc(ctx, req.Options, inR, pw)
|
||||
m.sessionMu.Lock()
|
||||
if s, ok := m.session[ref]; ok {
|
||||
// NOTE: buildFunc can return *build.ResultContext even on error (e.g. when it's implemented using (github.com/docker/buildx/controller/build).RunBuild).
|
||||
// NOTE: buildFunc can return *build.ResultHandle even on error (e.g. when it's implemented using (github.com/docker/buildx/controller/build).RunBuild).
|
||||
if res != nil {
|
||||
s.result = res
|
||||
s.cancelBuild = cancel
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
variable "GO_VERSION" {
|
||||
default = "1.20"
|
||||
default = null
|
||||
}
|
||||
variable "DOCS_FORMATS" {
|
||||
default = "md"
|
||||
@@ -156,3 +156,29 @@ target "image-local" {
|
||||
inherits = ["image"]
|
||||
output = ["type=docker"]
|
||||
}
|
||||
|
||||
variable "HTTP_PROXY" {
|
||||
default = ""
|
||||
}
|
||||
variable "HTTPS_PROXY" {
|
||||
default = ""
|
||||
}
|
||||
variable "NO_PROXY" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
target "integration-test-base" {
|
||||
inherits = ["_common"]
|
||||
args = {
|
||||
HTTP_PROXY = HTTP_PROXY
|
||||
HTTPS_PROXY = HTTPS_PROXY
|
||||
NO_PROXY = NO_PROXY
|
||||
}
|
||||
target = "integration-test-base"
|
||||
output = ["type=cacheonly"]
|
||||
}
|
||||
|
||||
target "integration-test" {
|
||||
inherits = ["integration-test-base"]
|
||||
target = "integration-test"
|
||||
}
|
||||
|
||||
@@ -69,16 +69,16 @@ The following example shows the same Bake file in the HCL format:
|
||||
|
||||
```hcl
|
||||
variable "TAG" {
|
||||
"default" = "latest"
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
group "default" {
|
||||
"targets" = ["latest"]
|
||||
targets = ["webapp"]
|
||||
}
|
||||
|
||||
target "webapp" {
|
||||
"dockerfile" = "Dockerfile"
|
||||
"tags" = ["docker.io/username/webapp:${TAG}"]
|
||||
dockerfile = "Dockerfile"
|
||||
tags = ["docker.io/username/webapp:${TAG}"]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ build command to specify a command to launch in the resulting image.
|
||||
|
||||
```console
|
||||
$ docker buildx build --invoke /bin/sh .
|
||||
+] Building 4.2s (19/19) FINISHED
|
||||
[+] Building 4.2s (19/19) FINISHED
|
||||
=> [internal] connecting to local controller 0.0s
|
||||
=> [internal] load build definition from Dockerfile 0.0s
|
||||
=> => transferring dockerfile: 32B 0.0s
|
||||
@@ -49,6 +49,57 @@ bin etc lib mnt proc run srv tmp var
|
||||
dev home media opt root sbin sys usr work
|
||||
```
|
||||
|
||||
Optional long form allows you specifying detailed configurations of the process.
|
||||
It must be CSV-styled comma-separated key-value pairs.
|
||||
Supported keys are `args` (can be JSON array format), `entrypoint` (can be JSON array format), `env` (can be JSON array format), `user`, `cwd` and `tty` (bool).
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
$ docker buildx build --invoke 'entrypoint=["sh"],"args=[""-c"", ""env | grep -e FOO -e AAA""]","env=[""FOO=bar"", ""AAA=bbb""]"' .
|
||||
```
|
||||
|
||||
#### `on-error`
|
||||
|
||||
If you want to start a debug session when a build fails, you can use
|
||||
`--invoke=on-error` to start a debug session when the build fails.
|
||||
|
||||
```console
|
||||
$ docker buildx build --invoke on-error .
|
||||
[+] Building 4.2s (19/19) FINISHED
|
||||
=> [internal] connecting to local controller 0.0s
|
||||
=> [internal] load build definition from Dockerfile 0.0s
|
||||
=> => transferring dockerfile: 32B 0.0s
|
||||
=> [internal] load .dockerignore 0.0s
|
||||
=> => transferring context: 34B 0.0s
|
||||
...
|
||||
=> ERROR [shell 10/10] RUN bad-command
|
||||
------
|
||||
> [shell 10/10] RUN bad-command:
|
||||
#0 0.049 /bin/sh: bad-command: not found
|
||||
------
|
||||
Launching interactive container. Press Ctrl-a-c to switch to monitor console
|
||||
Interactive container was restarted with process "edmzor60nrag7rh1mbi4o9lm8". Press Ctrl-a-c to switch to the new container
|
||||
/ #
|
||||
```
|
||||
|
||||
This allows you to explore the state of the image when the build failed.
|
||||
|
||||
#### `debug-shell`
|
||||
|
||||
If you want to drop into a debug session without first starting the build, you
|
||||
can use `--invoke=debug-shell` to start a debug session.
|
||||
|
||||
```
|
||||
$ docker buildx build --invoke debug-shell .
|
||||
[+] Building 4.2s (19/19) FINISHED
|
||||
=> [internal] connecting to local controller 0.0s
|
||||
(buildx)
|
||||
```
|
||||
|
||||
You can then use the commands available in [monitor mode](#monitor-mode) to
|
||||
start and observe the build.
|
||||
|
||||
## Monitor mode
|
||||
|
||||
By default, when debugging, you'll be dropped into a shell in the final stage.
|
||||
@@ -65,12 +116,12 @@ Available commands are:
|
||||
disconnect disconnect a client from a buildx server. Specific session ID can be specified an arg
|
||||
exec execute a process in the interactive container
|
||||
exit exits monitor
|
||||
help shows this message
|
||||
help shows this message. Optionally pass a command name as an argument to print the detailed usage.
|
||||
kill kill buildx server
|
||||
list list buildx sessions
|
||||
ps list processes invoked by "exec". Use "attach" to attach IO to that process
|
||||
reload reloads the context and build it
|
||||
rollback re-runs the interactive container with initial rootfs contents
|
||||
rollback re-runs the interactive container with the step's rootfs contents
|
||||
```
|
||||
|
||||
## Build controllers
|
||||
@@ -93,7 +144,7 @@ immediately enter the monitor mode.
|
||||
|
||||
```console
|
||||
$ docker buildx debug-shell
|
||||
+] Building 0.0s (1/1) FINISHED
|
||||
[+] Building 0.0s (1/1) FINISHED
|
||||
=> [internal] connecting to remote controller
|
||||
(buildx) list
|
||||
ID CURRENT_SESSION
|
||||
@@ -110,4 +161,4 @@ Attached to process "3ug8iqaufiwwnukimhqqt06jz". Press Ctrl-a-c to switch to the
|
||||
bin etc lib mnt proc run srv tmp var
|
||||
dev home media opt root sbin sys usr work
|
||||
/ #
|
||||
```
|
||||
```
|
||||
|
||||
@@ -9,24 +9,21 @@ Extended build capabilities with BuildKit
|
||||
|
||||
### Subcommands
|
||||
|
||||
| Name | Description |
|
||||
|:-----------------------------------------------|:-------------------------------------------|
|
||||
| [`_INTERNAL_SERVE`](buildx__INTERNAL_SERVE.md) | |
|
||||
| [`bake`](buildx_bake.md) | Build from a file |
|
||||
| [`build`](buildx_build.md) | Start a build |
|
||||
| [`create`](buildx_create.md) | Create a new builder instance |
|
||||
| [`debug-shell`](buildx_debug-shell.md) | Start a monitor |
|
||||
| [`du`](buildx_du.md) | Disk usage |
|
||||
| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry |
|
||||
| [`inspect`](buildx_inspect.md) | Inspect current builder instance |
|
||||
| [`install`](buildx_install.md) | Install buildx as a 'docker builder' alias |
|
||||
| [`ls`](buildx_ls.md) | List builder instances |
|
||||
| [`prune`](buildx_prune.md) | Remove build cache |
|
||||
| [`rm`](buildx_rm.md) | Remove a builder instance |
|
||||
| [`stop`](buildx_stop.md) | Stop builder instance |
|
||||
| [`uninstall`](buildx_uninstall.md) | Uninstall the 'docker builder' alias |
|
||||
| [`use`](buildx_use.md) | Set the current builder instance |
|
||||
| [`version`](buildx_version.md) | Show buildx version information |
|
||||
| Name | Description |
|
||||
|:---------------------------------------|:---------------------------------------|
|
||||
| [`bake`](buildx_bake.md) | Build from a file |
|
||||
| [`build`](buildx_build.md) | Start a build |
|
||||
| [`create`](buildx_create.md) | Create a new builder instance |
|
||||
| [`debug-shell`](buildx_debug-shell.md) | Start a monitor |
|
||||
| [`du`](buildx_du.md) | Disk usage |
|
||||
| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry |
|
||||
| [`inspect`](buildx_inspect.md) | Inspect current builder instance |
|
||||
| [`ls`](buildx_ls.md) | List builder instances |
|
||||
| [`prune`](buildx_prune.md) | Remove build cache |
|
||||
| [`rm`](buildx_rm.md) | Remove a builder instance |
|
||||
| [`stop`](buildx_stop.md) | Stop builder instance |
|
||||
| [`use`](buildx_use.md) | Set the current builder instance |
|
||||
| [`version`](buildx_version.md) | Show buildx version information |
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
@@ -23,11 +23,11 @@ Start a build
|
||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
|
||||
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
|
||||
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Optional parent cgroup for the container |
|
||||
| `--detach` | | | Detach buildx server (supported only on linux) [experimental] |
|
||||
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
|
||||
| `--detach` | | | Detach buildx server (supported only on linux) |
|
||||
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
|
||||
| `--iidfile` | `string` | | Write the image ID to the file |
|
||||
| `--invoke` | `string` | | Invoke a command after the build [experimental] |
|
||||
| `--invoke` | `string` | | Invoke a command after the build |
|
||||
| `--label` | `stringArray` | | Set metadata for an image |
|
||||
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
|
||||
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
|
||||
@@ -36,16 +36,16 @@ Start a build
|
||||
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
|
||||
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
|
||||
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
|
||||
| `--print` | `string` | | Print result of information request (e.g., outline, targets) [experimental] |
|
||||
| `--print` | `string` | | Print result of information request (e.g., outline, targets) |
|
||||
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
||||
| [`--provenance`](#provenance) | `string` | | Shortand for `--attest=type=provenance` |
|
||||
| [`--provenance`](#provenance) | `string` | | Shorthand for `--attest=type=provenance` |
|
||||
| `--pull` | | | Always attempt to pull all referenced images |
|
||||
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
|
||||
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
|
||||
| `--root` | `string` | | Specify root directory of server to connect [experimental] |
|
||||
| `--root` | `string` | | Specify root directory of server to connect |
|
||||
| [`--sbom`](#sbom) | `string` | | Shorthand for `--attest=type=sbom` |
|
||||
| [`--secret`](#secret) | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
|
||||
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) [experimental] |
|
||||
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
|
||||
| [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` |
|
||||
| [`--ssh`](#ssh) | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
|
||||
| [`-t`](https://docs.docker.com/engine/reference/commandline/build/#tag), [`--tag`](https://docs.docker.com/engine/reference/commandline/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
|
||||
@@ -125,7 +125,6 @@ Same as [`docker build` command](https://docs.docker.com/engine/reference/comman
|
||||
There are also useful built-in build args like:
|
||||
|
||||
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>` trigger git context to keep the `.git` directory
|
||||
* `BUILDKIT_INLINE_BUILDINFO_ATTRS=<bool>` inline build info attributes in image config or not
|
||||
* `BUILDKIT_INLINE_CACHE=<bool>` inline cache metadata to image config or not
|
||||
* `BUILDKIT_MULTI_PLATFORM=<bool>` opt into deterministic output regardless of multi-platform output or not
|
||||
|
||||
@@ -286,26 +285,6 @@ $ cat metadata.json
|
||||
```
|
||||
```json
|
||||
{
|
||||
"containerimage.buildinfo": {
|
||||
"frontend": "dockerfile.v0",
|
||||
"attrs": {
|
||||
"context": "https://github.com/crazy-max/buildkit-buildsources-test.git#master",
|
||||
"filename": "Dockerfile",
|
||||
"source": "docker/dockerfile:master"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "docker-image",
|
||||
"ref": "docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0",
|
||||
"pin": "sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0"
|
||||
},
|
||||
{
|
||||
"type": "docker-image",
|
||||
"ref": "docker.io/library/alpine:3.13",
|
||||
"pin": "sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c"
|
||||
}
|
||||
]
|
||||
},
|
||||
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
|
||||
"containerimage.descriptor": {
|
||||
"annotations": {
|
||||
|
||||
@@ -141,7 +141,7 @@ to achieve that.
|
||||
|
||||
Passes additional driver-specific options.
|
||||
|
||||
Note: When using quoted values for example for the `nodeselector` or
|
||||
Note: When using quoted values for the `nodeselector`, `annotations`, `labels` or
|
||||
`tolerations` options, ensure that quotes are escaped correctly for your shell.
|
||||
|
||||
#### `docker` driver
|
||||
@@ -165,6 +165,8 @@ No driver options.
|
||||
- `limits.memory` - Sets the limit memory value specified in bytes or with a valid suffix. Example `limits.memory=500Mi`, `limits.memory=4G`
|
||||
- `serviceaccount` - Sets the created pod's service account. Example `serviceaccount=example-sa`
|
||||
- `"nodeselector=label1=value1,label2=value2"` - Sets the kv of `Pod` nodeSelector. No Defaults. Example `nodeselector=kubernetes.io/arch=arm64`
|
||||
- `"annotations=domain/thing1=value1,domain/thing2=value2"` - Sets additional annotations on the deployments and pods. No Defaults. Example `annotations=example.com/owner=sarah`
|
||||
- `"labels=domain/thing1=value1,domain/thing2=value2"` - Sets additional labels on the deployments and pods. No Defaults. Example `labels=example.com/team=rd`
|
||||
- `"tolerations=key=foo,value=bar;key=foo2,operator=exists;key=foo3,effect=NoSchedule"` - Sets the `Pod` tolerations. Accepts the same values as the kube manifest tolera>tions. Key-value pairs are separated by `,`, tolerations are separated by `;`. No Defaults. Example `tolerations=operator=exists`
|
||||
- `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. Needs Kubernetes 1.19 or later. [Using Ubuntu host kernel is recommended](https://github.com/moby/buildkit/blob/master/docs/rootless.md). Defaults to false.
|
||||
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"
|
||||
@@ -221,7 +223,7 @@ building for the same platform.
|
||||
|
||||
```console
|
||||
$ docker buildx create --platform linux/amd64
|
||||
$ docker buildx create --platform linux/arm64,linux/arm/v8
|
||||
$ docker buildx create --platform linux/arm64,linux/arm/v7
|
||||
```
|
||||
|
||||
### <a name="use"></a> Automatically switch to the newly created builder (--use)
|
||||
|
||||
@@ -8,10 +8,10 @@ Start a monitor
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------|:---------|:--------|:-----------------------------------------------------------------------------------------|
|
||||
| `--builder` | `string` | | Override the configured builder instance |
|
||||
| `--detach` | | | Detach buildx server (supported only on linux) [experimental] |
|
||||
| `--detach` | | | Detach buildx server (supported only on linux) |
|
||||
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
||||
| `--root` | `string` | | Specify root directory of server to connect [experimental] |
|
||||
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) [experimental] |
|
||||
| `--root` | `string` | | Specify root directory of server to connect |
|
||||
| `--server-config` | `string` | | Specify buildx server config file (used only when launching new server) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -11,6 +11,7 @@ Create a new image based on source images
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
|
||||
| `--annotation` | `stringArray` | | Add annotation to the image |
|
||||
| [`--append`](#append) | | | Append to existing manifest |
|
||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
|
||||
|
||||
@@ -49,20 +49,44 @@ The following example shows information about a builder instance named
|
||||
|
||||
```console
|
||||
$ docker buildx inspect elated_tesla
|
||||
|
||||
Name: elated_tesla
|
||||
Driver: docker-container
|
||||
Name: elated_tesla
|
||||
Driver: docker-container
|
||||
Last Activity: 2022-11-30 12:42:47 +0100 CET
|
||||
|
||||
Nodes:
|
||||
Name: elated_tesla0
|
||||
Endpoint: unix:///var/run/docker.sock
|
||||
Status: running
|
||||
Buildkit: v0.10.3
|
||||
Platforms: linux/amd64
|
||||
|
||||
Name: elated_tesla1
|
||||
Endpoint: ssh://ubuntu@1.2.3.4
|
||||
Status: running
|
||||
Buildkit: v0.10.3
|
||||
Platforms: linux/arm64*, linux/arm/v7, linux/arm/v6
|
||||
Name: elated_tesla0
|
||||
Endpoint: unix:///var/run/docker.sock
|
||||
Driver Options: env.BUILDKIT_STEP_LOG_MAX_SPEED="10485760" env.JAEGER_TRACE="localhost:6831" image="moby/buildkit:latest" network="host" env.BUILDKIT_STEP_LOG_MAX_SIZE="10485760"
|
||||
Status: running
|
||||
Flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
|
||||
BuildKit: v0.10.6
|
||||
Platforms: linux/arm64*, linux/arm/v7, linux/arm/v6
|
||||
Labels:
|
||||
org.mobyproject.buildkit.worker.executor: oci
|
||||
org.mobyproject.buildkit.worker.hostname: docker-desktop
|
||||
org.mobyproject.buildkit.worker.network: host
|
||||
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
|
||||
org.mobyproject.buildkit.worker.selinux.enabled: false
|
||||
org.mobyproject.buildkit.worker.snapshotter: overlayfs
|
||||
GC Policy rule#0:
|
||||
All: false
|
||||
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
|
||||
Keep Duration: 48h0m0s
|
||||
Keep Bytes: 488.3MiB
|
||||
GC Policy rule#1:
|
||||
All: false
|
||||
Keep Duration: 1440h0m0s
|
||||
Keep Bytes: 24.21GiB
|
||||
GC Policy rule#2:
|
||||
All: false
|
||||
Keep Bytes: 24.21GiB
|
||||
GC Policy rule#3:
|
||||
All: true
|
||||
Keep Bytes: 24.21GiB
|
||||
```
|
||||
|
||||
`debug` flag can also be used to get more information about the builder:
|
||||
|
||||
```console
|
||||
$ docker --debug buildx inspect elated_tesla
|
||||
```
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# buildx install
|
||||
|
||||
```
|
||||
docker buildx install
|
||||
```
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Install buildx as a 'docker builder' alias
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@@ -1,11 +0,0 @@
|
||||
# buildx uninstall
|
||||
|
||||
```
|
||||
docker buildx uninstall
|
||||
```
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Uninstall the 'docker builder' alias
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
dockerarchive "github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
@@ -40,6 +42,7 @@ type Driver struct {
|
||||
netMode string
|
||||
image string
|
||||
cgroupParent string
|
||||
securityOpts map[string]string
|
||||
env []string
|
||||
}
|
||||
|
||||
@@ -108,7 +111,6 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
||||
if d.InitConfig.BuildkitFlags != nil {
|
||||
cfg.Cmd = d.InitConfig.BuildkitFlags
|
||||
}
|
||||
|
||||
useInit := true // let it cleanup exited processes created by BuildKit's container API
|
||||
if err := l.Wrap("creating container "+d.Name, func() error {
|
||||
hc := &container.HostConfig{
|
||||
@@ -126,6 +128,13 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
||||
hc.NetworkMode = container.NetworkMode(d.netMode)
|
||||
}
|
||||
if info, err := d.DockerAPI.Info(ctx); err == nil {
|
||||
secOpts, err := dockertypes.DecodeSecurityOptions(info.SecurityOptions)
|
||||
l.Wrap("driverOpts"+info.CgroupDriver, func() error {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.CgroupDriver == "cgroupfs" {
|
||||
// Place all buildkit containers inside this cgroup by default so limits can be attached
|
||||
// to all build activity on the host.
|
||||
@@ -134,28 +143,39 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
||||
hc.CgroupParent = d.cgroupParent
|
||||
}
|
||||
}
|
||||
|
||||
secOpts, err := dockertypes.DecodeSecurityOptions(info.SecurityOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range secOpts {
|
||||
if f.Name == "userns" {
|
||||
hc.UsernsMode = "host"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for i, k := range d.securityOpts {
|
||||
switch {
|
||||
case i == "systempaths":
|
||||
hc.MaskedPaths = []string{}
|
||||
hc.ReadonlyPaths = []string{}
|
||||
case i == "privileged":
|
||||
val, err := strconv.ParseBool(k)
|
||||
if err != nil {
|
||||
return errors.Errorf("invalid value privleged security option, options are true/false")
|
||||
}
|
||||
hc.Privileged = val
|
||||
default:
|
||||
hc.SecurityOpt = append(hc.SecurityOpt, i+"="+k)
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := d.DockerAPI.ContainerCreate(ctx, cfg, hc, &network.NetworkingConfig{}, nil, d.Name)
|
||||
if err != nil {
|
||||
if err != nil && !errdefs.IsConflict(err) {
|
||||
return err
|
||||
}
|
||||
if err := d.copyToContainer(ctx, d.InitConfig.Files); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.start(ctx, l); err != nil {
|
||||
return err
|
||||
if err == nil {
|
||||
if err := d.copyToContainer(ctx, d.InitConfig.Files); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.start(ctx, l); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := d.wait(ctx, l); err != nil {
|
||||
return err
|
||||
@@ -387,13 +407,12 @@ func (d *Driver) Factory() driver.Factory {
|
||||
return d.factory
|
||||
}
|
||||
|
||||
func (d *Driver) Features() map[driver.Feature]bool {
|
||||
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
return map[driver.Feature]bool{
|
||||
driver.OCIExporter: true,
|
||||
driver.DockerExporter: true,
|
||||
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true,
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
||||
return nil, errors.Errorf("%s driver requires docker API access", f.Name())
|
||||
}
|
||||
d := &Driver{factory: f, InitConfig: cfg}
|
||||
d.securityOpts = make(map[string]string)
|
||||
for k, v := range cfg.DriverOpts {
|
||||
switch {
|
||||
case k == "network":
|
||||
@@ -57,11 +58,32 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
||||
return nil, errors.Errorf("invalid env option %q, expecting env.FOO=bar", k)
|
||||
}
|
||||
d.env = append(d.env, fmt.Sprintf("%s=%s", envName, v))
|
||||
case k == "seccomp":
|
||||
d.securityOpts[k] = v
|
||||
case k == "apparmor":
|
||||
d.securityOpts[k] = v
|
||||
case k == "systempaths":
|
||||
d.securityOpts[k] = v
|
||||
case k == "privileged":
|
||||
d.securityOpts[k] = v
|
||||
default:
|
||||
return nil, errors.Errorf("invalid driver option %s for docker-container driver", k)
|
||||
}
|
||||
}
|
||||
|
||||
for i, _ := range cfg.SecurityOpts {
|
||||
switch {
|
||||
case i == "seccomp":
|
||||
continue
|
||||
case i == "apparmor":
|
||||
continue
|
||||
case i == "systempaths":
|
||||
continue
|
||||
case i == "privileged":
|
||||
continue
|
||||
default:
|
||||
return nil, errors.Errorf("invalid Security option %s for docker-container driver", i)
|
||||
}
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,8 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
||||
}))
|
||||
}
|
||||
|
||||
func (d *Driver) Features() map[driver.Feature]bool {
|
||||
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
var useContainerdSnapshotter bool
|
||||
ctx := context.Background()
|
||||
c, err := d.Client(ctx)
|
||||
if err == nil {
|
||||
workers, _ := c.ListWorkers(ctx)
|
||||
|
||||
@@ -2,10 +2,12 @@ package driver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/docker/buildx/store"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
clitypes "github.com/docker/cli/cli/config/types"
|
||||
controlapi "github.com/moby/buildkit/api/services/control"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -57,12 +59,12 @@ type Driver interface {
|
||||
Stop(ctx context.Context, force bool) error
|
||||
Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error
|
||||
Client(ctx context.Context) (*client.Client, error)
|
||||
Features() map[Feature]bool
|
||||
Features(ctx context.Context) map[Feature]bool
|
||||
IsMobyDriver() bool
|
||||
Config() InitConfig
|
||||
}
|
||||
|
||||
func Boot(ctx, clientContext context.Context, d Driver, pw progress.Writer) (*client.Client, error) {
|
||||
func Boot(ctx, clientContext context.Context, d *DriverHandle, pw progress.Writer) (*client.Client, error) {
|
||||
try := 0
|
||||
for {
|
||||
info, err := d.Info(ctx)
|
||||
@@ -78,7 +80,6 @@ func Boot(ctx, clientContext context.Context, d Driver, pw progress.Writer) (*cl
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
c, err := d.Client(clientContext)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == ErrNotRunning && try <= 2 {
|
||||
@@ -89,3 +90,22 @@ func Boot(ctx, clientContext context.Context, d Driver, pw progress.Writer) (*cl
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func historyAPISupported(ctx context.Context, c *client.Client) bool {
|
||||
cl, err := c.ControlClient().ListenBuildHistory(ctx, &controlapi.BuildHistoryRequest{
|
||||
ActiveOnly: true,
|
||||
Ref: "buildx-test-history-api-feature", // dummy ref to check if the server supports the API
|
||||
EarlyExit: true,
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for {
|
||||
_, err := cl.Recv()
|
||||
if errors.Is(err, io.EOF) {
|
||||
return true
|
||||
} else if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ type Feature string
|
||||
const OCIExporter Feature = "OCI exporter"
|
||||
const DockerExporter Feature = "Docker exporter"
|
||||
|
||||
const CacheExport Feature = "cache export"
|
||||
const MultiPlatform Feature = "multiple platforms"
|
||||
const CacheExport Feature = "Cache export"
|
||||
const MultiPlatform Feature = "Multiple platforms"
|
||||
|
||||
@@ -23,6 +23,7 @@ type EndpointMeta struct {
|
||||
AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"`
|
||||
Exec *clientcmdapi.ExecConfig `json:",omitempty"`
|
||||
UsernamePassword *UsernamePassword `json:"usernamePassword,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// UsernamePassword contains username/password auth info
|
||||
@@ -77,6 +78,9 @@ func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
|
||||
authInfo.Username = c.UsernamePassword.Username
|
||||
authInfo.Password = c.UsernamePassword.Password
|
||||
}
|
||||
if c.Token != "" {
|
||||
authInfo.Token = c.Token
|
||||
}
|
||||
authInfo.AuthProvider = c.AuthProvider
|
||||
authInfo.Exec = c.Exec
|
||||
cfg.Clusters["cluster"] = cluster
|
||||
|
||||
@@ -68,6 +68,7 @@ func FromKubeConfig(kubeconfig, kubeContext, namespaceOverride string) (Endpoint
|
||||
AuthProvider: clientcfg.AuthProvider,
|
||||
Exec: clientcfg.ExecProvider,
|
||||
UsernamePassword: usernamePassword,
|
||||
Token: clientcfg.BearerToken,
|
||||
},
|
||||
TLSData: tlsData,
|
||||
}, nil
|
||||
|
||||
@@ -204,8 +204,7 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
||||
}
|
||||
containerName := pod.Spec.Containers[0].Name
|
||||
cmd := []string{"buildctl", "dial-stdio"}
|
||||
conn, err := execconn.ExecConn(restClient, restClientConfig,
|
||||
pod.Namespace, pod.Name, containerName, cmd)
|
||||
conn, err := execconn.ExecConn(ctx, restClient, restClientConfig, pod.Namespace, pod.Name, containerName, cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -229,12 +228,11 @@ func (d *Driver) Factory() driver.Factory {
|
||||
return d.factory
|
||||
}
|
||||
|
||||
func (d *Driver) Features() map[driver.Feature]bool {
|
||||
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
return map[driver.Feature]bool{
|
||||
driver.OCIExporter: true,
|
||||
driver.DockerExporter: d.DockerAPI != nil,
|
||||
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package execconn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
)
|
||||
|
||||
func ExecConn(restClient rest.Interface, restConfig *rest.Config, namespace, pod, container string, cmd []string) (net.Conn, error) {
|
||||
func ExecConn(ctx context.Context, restClient rest.Interface, restConfig *rest.Config, namespace, pod, container string, cmd []string) (net.Conn, error) {
|
||||
req := restClient.
|
||||
Post().
|
||||
Namespace(namespace).
|
||||
@@ -42,13 +43,13 @@ func ExecConn(restClient rest.Interface, restConfig *rest.Config, namespace, pod
|
||||
remoteAddr: dummyAddr{network: "dummy", s: "dummy-1"},
|
||||
}
|
||||
go func() {
|
||||
serr := exec.Stream(remotecommand.StreamOptions{
|
||||
serr := exec.StreamWithContext(ctx, remotecommand.StreamOptions{
|
||||
Stdin: stdinR,
|
||||
Stdout: stdoutW,
|
||||
Stderr: os.Stderr,
|
||||
Tty: false,
|
||||
})
|
||||
if serr != nil {
|
||||
if serr != nil && serr != context.Canceled {
|
||||
logrus.Error(serr)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -148,15 +148,20 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
||||
case "serviceaccount":
|
||||
deploymentOpt.ServiceAccountName = v
|
||||
case "nodeselector":
|
||||
kvs := strings.Split(strings.Trim(v, `"`), ",")
|
||||
s := map[string]string{}
|
||||
for i := range kvs {
|
||||
kv := strings.Split(kvs[i], "=")
|
||||
if len(kv) == 2 {
|
||||
s[kv[0]] = kv[1]
|
||||
}
|
||||
deploymentOpt.NodeSelector, err = splitMultiValues(v, ",", "=")
|
||||
if err != nil {
|
||||
return nil, "", "", errors.Wrap(err, "cannot parse node selector")
|
||||
}
|
||||
case "annotations":
|
||||
deploymentOpt.CustomAnnotations, err = splitMultiValues(v, ",", "=")
|
||||
if err != nil {
|
||||
return nil, "", "", errors.Wrap(err, "cannot parse annotations")
|
||||
}
|
||||
case "labels":
|
||||
deploymentOpt.CustomLabels, err = splitMultiValues(v, ",", "=")
|
||||
if err != nil {
|
||||
return nil, "", "", errors.Wrap(err, "cannot parse labels")
|
||||
}
|
||||
deploymentOpt.NodeSelector = s
|
||||
case "tolerations":
|
||||
ts := strings.Split(v, ";")
|
||||
deploymentOpt.Tolerations = []corev1.Toleration{}
|
||||
@@ -217,6 +222,19 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
||||
return deploymentOpt, loadbalance, namespace, nil
|
||||
}
|
||||
|
||||
func splitMultiValues(in string, itemsep string, kvsep string) (map[string]string, error) {
|
||||
kvs := strings.Split(strings.Trim(in, `"`), itemsep)
|
||||
s := map[string]string{}
|
||||
for i := range kvs {
|
||||
kv := strings.Split(kvs[i], kvsep)
|
||||
if len(kv) != 2 {
|
||||
return nil, errors.Errorf("invalid key-value pair: %s", kvs[i])
|
||||
}
|
||||
s[kv[0]] = kv[1]
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (f *factory) AllowsInstances() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -47,13 +47,13 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
"rootless": "true",
|
||||
"nodeselector": "selector1=value1,selector2=value2",
|
||||
"tolerations": "key=tolerationKey1,value=tolerationValue1,operator=Equal,effect=NoSchedule,tolerationSeconds=60;key=tolerationKey2,operator=Exists",
|
||||
"annotations": "example.com/expires-after=annotation1,example.com/other=annotation2",
|
||||
"labels": "example.com/owner=label1,example.com/other=label2",
|
||||
"loadbalance": "random",
|
||||
"qemu.install": "true",
|
||||
"qemu.image": "qemu:latest",
|
||||
}
|
||||
ns := "test"
|
||||
|
||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, ns, cfg)
|
||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
nodeSelectors := map[string]string{
|
||||
"selector1": "value1",
|
||||
@@ -75,6 +75,16 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
customAnnotations := map[string]string{
|
||||
"example.com/expires-after": "annotation1",
|
||||
"example.com/other": "annotation2",
|
||||
}
|
||||
|
||||
customLabels := map[string]string{
|
||||
"example.com/owner": "label1",
|
||||
"example.com/other": "label2",
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "test-ns", ns)
|
||||
@@ -86,6 +96,8 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
require.Equal(t, "64Mi", r.LimitsMemory)
|
||||
require.True(t, r.Rootless)
|
||||
require.Equal(t, nodeSelectors, r.NodeSelector)
|
||||
require.Equal(t, customAnnotations, r.CustomAnnotations)
|
||||
require.Equal(t, customLabels, r.CustomLabels)
|
||||
require.Equal(t, tolerations, r.Tolerations)
|
||||
require.Equal(t, LoadbalanceRandom, loadbalance)
|
||||
require.True(t, r.Qemu.Install)
|
||||
@@ -110,6 +122,8 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
require.Equal(t, "", r.LimitsMemory)
|
||||
require.False(t, r.Rootless)
|
||||
require.Empty(t, r.NodeSelector)
|
||||
require.Empty(t, r.CustomAnnotations)
|
||||
require.Empty(t, r.CustomLabels)
|
||||
require.Empty(t, r.Tolerations)
|
||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||
require.False(t, r.Qemu.Install)
|
||||
@@ -137,6 +151,8 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
require.Equal(t, "", r.LimitsMemory)
|
||||
require.True(t, r.Rootless)
|
||||
require.Empty(t, r.NodeSelector)
|
||||
require.Empty(t, r.CustomAnnotations)
|
||||
require.Empty(t, r.CustomLabels)
|
||||
require.Empty(t, r.Tolerations)
|
||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||
require.False(t, r.Qemu.Install)
|
||||
@@ -149,9 +165,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"replicas": "invalid",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -161,9 +175,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"rootless": "invalid",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -173,9 +185,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"tolerations": "key=foo,value=bar,invalid=foo2",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -185,9 +195,27 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"tolerations": "key=foo,value=bar,tolerationSeconds=invalid",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InvalidCustomAnnotation", func(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"annotations": "key,value",
|
||||
}
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
|
||||
t.Run(
|
||||
"InvalidCustomLabel", func(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"labels": "key=value=foo",
|
||||
}
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -197,9 +225,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"loadbalance": "invalid",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -209,9 +235,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"qemu.install": "invalid",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
@@ -221,9 +245,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
||||
cfg.DriverOpts = map[string]string{
|
||||
"invalid": "foo",
|
||||
}
|
||||
|
||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||
|
||||
require.Error(t, err)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@@ -31,24 +32,32 @@ type DeploymentOpt struct {
|
||||
// files mounted at /etc/buildkitd
|
||||
ConfigFiles map[string][]byte
|
||||
|
||||
Rootless bool
|
||||
NodeSelector map[string]string
|
||||
Tolerations []corev1.Toleration
|
||||
RequestsCPU string
|
||||
RequestsMemory string
|
||||
LimitsCPU string
|
||||
LimitsMemory string
|
||||
Platforms []v1.Platform
|
||||
Rootless bool
|
||||
NodeSelector map[string]string
|
||||
CustomAnnotations map[string]string
|
||||
CustomLabels map[string]string
|
||||
Tolerations []corev1.Toleration
|
||||
RequestsCPU string
|
||||
RequestsMemory string
|
||||
LimitsCPU string
|
||||
LimitsMemory string
|
||||
Platforms []v1.Platform
|
||||
}
|
||||
|
||||
const (
|
||||
containerName = "buildkitd"
|
||||
AnnotationPlatform = "buildx.docker.com/platform"
|
||||
LabelApp = "app"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrReservedAnnotationPlatform = errors.Errorf("the annotation \"%s\" is reserved and cannot be customized", AnnotationPlatform)
|
||||
ErrReservedLabelApp = errors.Errorf("the label \"%s\" is reserved and cannot be customized", LabelApp)
|
||||
)
|
||||
|
||||
func NewDeployment(opt *DeploymentOpt) (d *appsv1.Deployment, c []*corev1.ConfigMap, err error) {
|
||||
labels := map[string]string{
|
||||
"app": opt.Name,
|
||||
LabelApp: opt.Name,
|
||||
}
|
||||
annotations := map[string]string{}
|
||||
replicas := int32(opt.Replicas)
|
||||
@@ -59,6 +68,20 @@ func NewDeployment(opt *DeploymentOpt) (d *appsv1.Deployment, c []*corev1.Config
|
||||
annotations[AnnotationPlatform] = strings.Join(platformutil.Format(opt.Platforms), ",")
|
||||
}
|
||||
|
||||
for k, v := range opt.CustomAnnotations {
|
||||
if k == AnnotationPlatform {
|
||||
return nil, nil, ErrReservedAnnotationPlatform
|
||||
}
|
||||
annotations[k] = v
|
||||
}
|
||||
|
||||
for k, v := range opt.CustomLabels {
|
||||
if k == LabelApp {
|
||||
return nil, nil, ErrReservedLabelApp
|
||||
}
|
||||
labels[k] = v
|
||||
}
|
||||
|
||||
d = &appsv1.Deployment{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: appsv1.SchemeGroupVersion.String(),
|
||||
|
||||
@@ -2,17 +2,17 @@ package driver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/moby/buildkit/client"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type Factory interface {
|
||||
@@ -56,6 +56,7 @@ type InitConfig struct {
|
||||
BuildkitFlags []string
|
||||
Files map[string][]byte
|
||||
DriverOpts map[string]string
|
||||
SecurityOpts map[string]string
|
||||
Auth Auth
|
||||
Platforms []specs.Platform
|
||||
// ContextPathHash can be used for determining pods in the driver instance
|
||||
@@ -104,7 +105,7 @@ func GetFactory(name string, instanceRequired bool) (Factory, error) {
|
||||
return nil, errors.Errorf("failed to find driver %q", name)
|
||||
}
|
||||
|
||||
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, platforms []specs.Platform, contextPathHash string) (Driver, error) {
|
||||
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, so map[string]string, platforms []specs.Platform, contextPathHash string) (*DriverHandle, error) {
|
||||
ic := InitConfig{
|
||||
EndpointAddr: endpointAddr,
|
||||
DockerAPI: api,
|
||||
@@ -112,6 +113,7 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string,
|
||||
Name: name,
|
||||
BuildkitFlags: flags,
|
||||
DriverOpts: do,
|
||||
SecurityOpts: so,
|
||||
Auth: auth,
|
||||
Platforms: platforms,
|
||||
ContextPathHash: contextPathHash,
|
||||
@@ -128,7 +130,7 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cachedDriver{Driver: d}, nil
|
||||
return &DriverHandle{Driver: d}, nil
|
||||
}
|
||||
|
||||
func GetFactories(instanceRequired bool) []Factory {
|
||||
@@ -145,16 +147,72 @@ func GetFactories(instanceRequired bool) []Factory {
|
||||
return ds
|
||||
}
|
||||
|
||||
type cachedDriver struct {
|
||||
type DriverHandle struct {
|
||||
Driver
|
||||
client *client.Client
|
||||
err error
|
||||
once sync.Once
|
||||
client *client.Client
|
||||
err error
|
||||
once sync.Once
|
||||
featuresOnce sync.Once
|
||||
features map[Feature]bool
|
||||
historyAPISupportedOnce sync.Once
|
||||
historyAPISupported bool
|
||||
hostGatewayIPOnce sync.Once
|
||||
hostGatewayIP net.IP
|
||||
hostGatewayIPErr error
|
||||
}
|
||||
|
||||
func (d *cachedDriver) Client(ctx context.Context) (*client.Client, error) {
|
||||
func (d *DriverHandle) Client(ctx context.Context) (*client.Client, error) {
|
||||
d.once.Do(func() {
|
||||
d.client, d.err = d.Driver.Client(ctx)
|
||||
})
|
||||
return d.client, d.err
|
||||
}
|
||||
|
||||
func (d *DriverHandle) Features(ctx context.Context) map[Feature]bool {
|
||||
d.featuresOnce.Do(func() {
|
||||
d.features = d.Driver.Features(ctx)
|
||||
})
|
||||
return d.features
|
||||
}
|
||||
|
||||
func (d *DriverHandle) HistoryAPISupported(ctx context.Context) bool {
|
||||
d.historyAPISupportedOnce.Do(func() {
|
||||
if c, err := d.Client(ctx); err == nil {
|
||||
d.historyAPISupported = historyAPISupported(ctx, c)
|
||||
}
|
||||
})
|
||||
return d.historyAPISupported
|
||||
}
|
||||
|
||||
func (d *DriverHandle) HostGatewayIP(ctx context.Context) (net.IP, error) {
|
||||
d.hostGatewayIPOnce.Do(func() {
|
||||
if !d.Driver.IsMobyDriver() {
|
||||
d.hostGatewayIPErr = errors.New("host-gateway is only supported with the docker driver")
|
||||
return
|
||||
}
|
||||
c, err := d.Client(ctx)
|
||||
if err != nil {
|
||||
d.hostGatewayIPErr = err
|
||||
return
|
||||
}
|
||||
workers, err := c.ListWorkers(ctx)
|
||||
if err != nil {
|
||||
d.hostGatewayIPErr = errors.Wrap(err, "listing workers")
|
||||
return
|
||||
}
|
||||
for _, w := range workers {
|
||||
// should match github.com/docker/docker/builder/builder-next/worker/label.HostGatewayIP const
|
||||
if v, ok := w.Labels["org.mobyproject.buildkit.worker.moby.host-gateway-ip"]; ok && v != "" {
|
||||
ip := net.ParseIP(v)
|
||||
if ip == nil {
|
||||
d.hostGatewayIPErr = errors.Errorf("failed to parse host-gateway IP: %s", v)
|
||||
return
|
||||
}
|
||||
d.hostGatewayIP = ip
|
||||
return
|
||||
}
|
||||
}
|
||||
d.hostGatewayIPErr = errors.New("host-gateway IP not found")
|
||||
})
|
||||
return d.hostGatewayIP, d.hostGatewayIPErr
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/moby/buildkit/client"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/backoff"
|
||||
)
|
||||
|
||||
type Driver struct {
|
||||
@@ -23,25 +25,11 @@ type tlsOpts struct {
|
||||
}
|
||||
|
||||
func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
|
||||
for i := 0; ; i++ {
|
||||
info, err := d.Info(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Status != driver.Inactive {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
if i > 10 {
|
||||
i = 10
|
||||
}
|
||||
time.Sleep(time.Duration(i) * time.Second)
|
||||
}
|
||||
c, err := d.Client(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Wait(ctx)
|
||||
}
|
||||
|
||||
func (d *Driver) Info(ctx context.Context) (*driver.Info, error) {
|
||||
@@ -77,6 +65,13 @@ func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error {
|
||||
|
||||
func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
||||
opts := []client.ClientOpt{}
|
||||
|
||||
backoffConfig := backoff.DefaultConfig
|
||||
backoffConfig.MaxDelay = 1 * time.Second
|
||||
opts = append(opts, client.WithGRPCDialOption(
|
||||
grpc.WithConnectParams(grpc.ConnectParams{Backoff: backoffConfig}),
|
||||
))
|
||||
|
||||
if d.tlsOpts != nil {
|
||||
opts = append(opts, []client.ClientOpt{
|
||||
client.WithServerConfig(d.tlsOpts.serverName, d.tlsOpts.caCert),
|
||||
@@ -87,10 +82,10 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
||||
return client.New(ctx, d.InitConfig.EndpointAddr, opts...)
|
||||
}
|
||||
|
||||
func (d *Driver) Features() map[driver.Feature]bool {
|
||||
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
return map[driver.Feature]bool{
|
||||
driver.OCIExporter: true,
|
||||
driver.DockerExporter: false,
|
||||
driver.DockerExporter: true,
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true,
|
||||
}
|
||||
|
||||
127
go.mod
127
go.mod
@@ -3,77 +3,73 @@ module github.com/docker/buildx
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.2.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5
|
||||
github.com/compose-spec/compose-go v1.13.4
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.16
|
||||
github.com/compose-spec/compose-go v1.17.0
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/containerd v1.7.0
|
||||
github.com/containerd/typeurl/v2 v2.1.0
|
||||
github.com/docker/cli v23.0.6+incompatible
|
||||
github.com/docker/cli-docs-tool v0.5.1
|
||||
github.com/containerd/containerd v1.7.2
|
||||
github.com/containerd/continuity v0.4.1
|
||||
github.com/containerd/typeurl/v2 v2.1.1
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/docker/cli v24.0.5+incompatible
|
||||
github.com/docker/cli-docs-tool v0.6.0
|
||||
github.com/docker/distribution v2.8.2+incompatible
|
||||
github.com/docker/docker v23.0.6+incompatible
|
||||
github.com/docker/docker v24.0.5+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
||||
github.com/hashicorp/hcl/v2 v2.8.2
|
||||
github.com/moby/buildkit v0.11.0-rc3.0.20230411142536-333ee9158128
|
||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b
|
||||
github.com/moby/sys/mountinfo v0.6.2
|
||||
github.com/moby/sys/signal v0.7.0
|
||||
github.com/morikuni/aec v1.0.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/zclconf/go-cty v1.10.0
|
||||
go.opentelemetry.io/otel v1.14.0
|
||||
go.opentelemetry.io/otel/trace v1.14.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/term v0.5.0
|
||||
golang.org/x/mod v0.11.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/term v0.8.0
|
||||
google.golang.org/grpc v1.53.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.26.2
|
||||
k8s.io/apimachinery v0.26.2
|
||||
k8s.io/apiserver v0.26.2
|
||||
k8s.io/client-go v0.26.2
|
||||
k8s.io/api v0.26.7
|
||||
k8s.io/apimachinery v0.26.7
|
||||
k8s.io/apiserver v0.26.7
|
||||
k8s.io/client-go v0.26.7
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.18.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
|
||||
github.com/apparentlymart/go-cidr v1.0.1 // indirect
|
||||
github.com/apparentlymart/go-textseg/v12 v12.0.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 // indirect
|
||||
github.com/aws/smithy-go v1.11.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6 // indirect
|
||||
github.com/aws/smithy-go v1.13.5 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bugsnag/bugsnag-go v1.4.1 // indirect
|
||||
github.com/bugsnag/panicwrap v1.2.0 // indirect
|
||||
@@ -81,8 +77,7 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/containerd/ttrpc v1.2.1 // indirect
|
||||
github.com/containerd/ttrpc v1.2.2 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa // indirect
|
||||
@@ -102,7 +97,6 @@ require (
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/google/certificate-transparency-go v1.1.4 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
@@ -111,14 +105,16 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jinzhu/gorm v1.9.2 // indirect
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/klauspost/compress v1.16.0 // indirect
|
||||
github.com/klauspost/compress v1.16.3 // indirect
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
@@ -129,24 +125,25 @@ require (
|
||||
github.com/moby/patternmatcher v0.5.0 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/term v0.0.0-20221120202655-abb19827d345 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
github.com/opencontainers/runc v1.1.7 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/spf13/viper v1.14.0 // indirect
|
||||
github.com/theupdateframework/notary v0.6.1 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb // indirect
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
|
||||
@@ -160,17 +157,16 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.4.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.5.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.5.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
|
||||
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
||||
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
||||
@@ -183,10 +179,3 @@ require (
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
k8s.io/api => k8s.io/api v0.25.4
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.25.4
|
||||
k8s.io/apiserver => k8s.io/apiserver v0.25.4
|
||||
k8s.io/client-go => k8s.io/client-go v0.25.4
|
||||
)
|
||||
|
||||
336
go.sum
336
go.sum
@@ -13,6 +13,7 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@@ -20,9 +21,7 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
|
||||
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
@@ -40,29 +39,13 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 h1:+vTEFqeoeur6XSq06bs+roX3YiT49gUniJK7Zky7Xjg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
@@ -71,10 +54,8 @@ github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U=
|
||||
github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
|
||||
@@ -85,28 +66,30 @@ github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJE
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3 h1:0W1TSJ7O6OzwuEvIXAtJGvOeQ0SGAhcpxPN2/NK5EhM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.3/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5 h1:P+xwhr6kabhxDTXTVH9YoHkqjLJ0wVVpIUHtFNr2hjU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.15.5/go.mod h1:ZijHHh0xd/A+ZY53az0qzC5tT46kt4JVCePf2NX9Lk4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 h1:4R/NqlcRFSkR0wxOhgHi+agGpbEr5qMCjn7VqUIJY+E=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.12.0/go.mod h1:9YWk7VW+eyKsoIL6/CljkTrNVWBSK9pkqOPUuijid4A=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 h1:FP8gquGeGHHdfY6G5llaMQDF+HAf20VKc8opRwmjf04=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4/go.mod h1:u/s5/Z+ohUQOPXl00m2yJVyioWDECsbpXTQlaqSlufc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 h1:uFWgo6mGJI1n17nbcvSc6fxVuR3xLNqvXt12JCnEcT8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 h1:cnsvEKSoHN4oAN7spMMr0zhEW2MHnhAVpmqQg8E6UcM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 h1:6cZRymlLEIlDTEB0+5+An6Zj1CKt6rSE69tOmFeu1nk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11/go.mod h1:0MR+sS1b/yxsfAPvAESrw8NfwUoxMinDyw6EYR9BS2U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 h1:b16QW0XWl0jWjLABFc1A+uh145Oqv+xDcObNk0iQgUk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4/go.mod h1:uKkN7qmSIsNJVyMtxNQoCEYMvFEXbOg9fwCJPdfp2u8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 h1:Uw5wBybFQ1UeA9ts0Y07gbv0ncZnIAyw858tDW0NP2o=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4/go.mod h1:cPDwJwsP4Kff9mldCXAmddjJL6JGQqtA3Mzer2zyr88=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 h1:+xtV90n3abQmgzk1pS++FdxZTrPEDgQng6e4/56WR2A=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4/go.mod h1:lfSYenAXtavyX2A1LsViglqlG9eEFYxNryTZS5rn3QE=
|
||||
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
|
||||
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.6 h1:Y773UK7OBqhzi5VDXMi1zVGsoj+CVHs2eaC2bDsLwi0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.16 h1:4r7gsCu8Ekwl5iJGE/GmspA2UifqySCCkyyyPFeWs3w=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.16/go.mod h1:XjM6lVbq7UgELp9NjXBrb1DQY/ownlWsvDhEQksemJc=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.16 h1:GgToSxaENX/1zXIGNFfiVk4hxryYJ5Vt4Mh8XLAL7Lc=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.16/go.mod h1:KP7aFJhfwPFgx9aoVYL2nYHjya5WBD98CWaadpgmnpY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24 h1:5qyqXASrX2zy5cTnoHHa4N2c3Lc94GH7gjnBP3GwKdU=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.24/go.mod h1:neYVaeKr5eT7BzwULuG2YbLhzWZ22lpjKdCybR7AXrQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30 h1:y+8n9AGDjikyXoMBTRaHHHSaFEB8267ykmvyPodJfys=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.30/go.mod h1:LUBAO3zNXQjoONBKn/kR1y0Q4cj/D02Ts0uHYjcCQLM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24 h1:r+Kv+SEJquhAZXaJ7G4u44cIwXV3f8K+N482NNAzJZA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.24/go.mod h1:gAuCezX/gob6BSMbItsSlMb6WZGV7K2+fWOvk8xBSto=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31 h1:hf+Vhp5WtTdcSdE+yEcUz8L73sAzN0R+0jQv+Z51/mI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.31/go.mod h1:5zUjguZfG5qjhG9/wqmuyHRyUftl2B5Cp6NNxNC6kRA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24 h1:c5qGfdbCHav6viBwiyDns3OXqhqAbGjfIB4uVu2ayhk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.24/go.mod h1:HMA4FZG6fyib+NDo5bpIxX1EhYjrAOveZJY2YR0xrNE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5 h1:bdKIX6SVF3nc3xJFw6Nf0igzS6Ff/louGq8Z6VP/3Hs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.5/go.mod h1:vuWiaDB30M/QTC+lI3Wj6S/zb7tpUK2MSYgy3Guh2L0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5 h1:xLPZMyuZ4GuqRCIec/zWuIhRFPXh2UOJdLXBSi64ZWQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.5/go.mod h1:QjxpHmCwAg0ESGtPQnLIVp7SedTOBMYy+Slr3IfMKeI=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6 h1:rIFn5J3yDoeuKCE9sESXqM5POTAhOP1du3bv/qTL+tE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.18.6/go.mod h1:48WJ9l3dwP0GSHWGc5sFGGlCkuA82Mc2xnw+T6Q8aDw=
|
||||
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
|
||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -123,14 +106,11 @@ github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e h1:Qux+lbuMaRzkQyTdzgtz8MgzPtzmaPQy6DXmxpdxT3U=
|
||||
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
@@ -141,28 +121,28 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/compose-spec/compose-go v1.13.4 h1:O6xAsPqaY1s9KXteiO7wRCDTJLahv1XP/z/eUO9EfbI=
|
||||
github.com/compose-spec/compose-go v1.13.4/go.mod h1:rsiZ8uaOHJYJemDBzTe9UBpaq5ZFVEOO4TxM2G3SJxk=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||
github.com/compose-spec/compose-go v1.17.0 h1:cvje90CU94dQyTnJoHJYjx9yE4Iggse1XmGcO3Qi5ts=
|
||||
github.com/compose-spec/compose-go v1.17.0/go.mod h1:zR2tP1+kZHi5vJz7PjpW6oMoDji/Js3GHjP+hfjf70Q=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg=
|
||||
github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc=
|
||||
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
|
||||
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
|
||||
github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo=
|
||||
github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI=
|
||||
github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU=
|
||||
github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
|
||||
github.com/containerd/nydus-snapshotter v0.3.1 h1:b8WahTrPkt3XsabjG2o/leN4fw3HWZYr+qxo/Z8Mfzk=
|
||||
github.com/containerd/stargz-snapshotter v0.14.1 h1:M58AiJ+Kj50cabqYP1TpBPgUczKgn8zipmteC5FyjVs=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.1 h1:n9M2GDSWM96pyipFTA0DaU+zdtzi3Iwsnj/rIHr1yFM=
|
||||
github.com/containerd/ttrpc v1.2.1 h1:VWv/Rzx023TBLv4WQ+9WPXlBG/s3rsRjY3i9AJ2BJdE=
|
||||
github.com/containerd/ttrpc v1.2.1/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak=
|
||||
github.com/containerd/typeurl/v2 v2.1.0 h1:yNAhJvbNEANt7ck48IlEGOxP7YAp6LLpGn5jZACDNIE=
|
||||
github.com/containerd/typeurl/v2 v2.1.0/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/containerd/nydus-snapshotter v0.8.2 h1:7SOrMU2YmLzfbsr5J7liMZJlNi5WT6vtIOxLGv+iz7E=
|
||||
github.com/containerd/stargz-snapshotter v0.14.3 h1:OTUVZoPSPs8mGgmQUE1dqw3WX/3nrsmsurW7UPLWl1U=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||
github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs=
|
||||
github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak=
|
||||
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
|
||||
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -170,14 +150,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
|
||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
|
||||
github.com/docker/cli v23.0.6+incompatible h1:CScadyCJ2ZKUDpAMZta6vK8I+6/m60VIjGIV7Wg/Eu4=
|
||||
github.com/docker/cli v23.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.5.1 h1:jIk/cCZurZERhALPVKhqlNxTQGxn2kcI+56gE57PQXg=
|
||||
github.com/docker/cli-docs-tool v0.5.1/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
|
||||
github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
|
||||
github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
|
||||
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v23.0.6+incompatible h1:aBD4np894vatVX99UTx/GyOUOK4uEcROwA3+bQhEcoU=
|
||||
github.com/docker/docker v23.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
|
||||
github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
@@ -187,7 +167,6 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
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/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4 h1:k8TfKGeAcDQFFQOGCQMRN04N4a9YrPlRMMKnzAuvM9Q=
|
||||
@@ -207,7 +186,6 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
|
||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
@@ -217,12 +195,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
@@ -242,8 +216,6 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
@@ -252,10 +224,6 @@ github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6x
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||
@@ -286,8 +254,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY=
|
||||
@@ -304,7 +273,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
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/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -347,11 +316,12 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY=
|
||||
github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
|
||||
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
|
||||
@@ -360,30 +330,25 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
|
||||
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
|
||||
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -407,23 +372,22 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/buildkit v0.11.0-rc3.0.20230411142536-333ee9158128 h1:MpK1e4TlETVYELLbzaxmbvQrftq1TWYoOftFiSNk/iE=
|
||||
github.com/moby/buildkit v0.11.0-rc3.0.20230411142536-333ee9158128/go.mod h1:GwK84qTEVfkyvAhd6aET84FRzND+lrQZC0pTesljST0=
|
||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b h1:LUpEbvxcyM0NuWk54WwNjDVZ5YujyCm1CudzZpqaohE=
|
||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b/go.mod h1:bs0LeDdh7AQpYXLiPNUt+hzDjRxMg+QeLq1a1r0awFM=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
|
||||
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||
github.com/moby/term v0.0.0-20221120202655-abb19827d345 h1:J9c53/kxIH+2nTKBEfZYFMlhghtHpIHSXpm5VRGHSnU=
|
||||
github.com/moby/term v0.0.0-20221120202655-abb19827d345/go.mod h1:15ce4BGCFxt7I5NQKT+HV0yEDxmf6fSysfEDiVo3zFM=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -433,30 +397,24 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs=
|
||||
github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=
|
||||
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.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
|
||||
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
|
||||
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk=
|
||||
github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.2 h1:ucBtEms2tamYYW/SvGpvq9yUN0NEVL6oyLEwDcTSrk8=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/package-url/packageurl-go v0.1.1-0.20220428063043-89078438f170 h1:DiLBVp4DAcZlBVBEtJpNWZpZVq0AEeCY7Hqk8URVs4o=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -466,60 +424,47 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 h1:ka9QPuQg2u4LGipiZGsgkg3rJCo4iIUCy75FddM0GRQ=
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
|
||||
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spdx/tools-golang v0.3.1-0.20230104082527-d6f58551be3f h1:9B623Cfs+mclYK6dsae7gLSwuIBHvlgmEup87qpqsAQ=
|
||||
github.com/spdx/tools-golang v0.5.1 h1:fJg3SVOGG+eIva9ZUBm/hvyA7PIPVFjRxUKe6fdAgwE=
|
||||
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -529,37 +474,30 @@ github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+eg
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
|
||||
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa h1:XOFp/3aBXlqmOFAg3r6e0qQjPnK5I970LilqX+Is1W8=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa/go.mod h1:AvLEd1LEIl64G2Jpgwo7aVV5lGH0ePcKl0ygGIHNYl8=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb h1:uUe8rNyVXM8moActoBol6Xf6xX2GMr7SosR2EywMvGg=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb/go.mod h1:SxX/oNQ/ag6Vaoli547ipFK9J7BZn5JqJG0JE8lf8bA=
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 h1:Y/M5lygoNPKwVNLMPXgVfsRT40CSFKXCxuU8LoHySjs=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc=
|
||||
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
@@ -615,8 +553,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
|
||||
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -629,6 +565,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -649,8 +587,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -681,25 +619,17 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
|
||||
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -710,8 +640,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -723,16 +653,13 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -745,47 +672,35 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -828,8 +743,8 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4=
|
||||
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -924,15 +839,14 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/dancannon/gorethink.v3 v3.0.5 h1:/g7PWP7zUS6vSNmHSDbjCHQh1Rqn8Jy6zSMQxAsBSMQ=
|
||||
gopkg.in/dancannon/gorethink.v3 v3.0.5/go.mod h1:GXsi1e3N2OcKhcP6nsYABTiUejbWMFO4GY5a4pEaeEc=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
@@ -947,9 +861,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -964,14 +876,14 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs=
|
||||
k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ=
|
||||
k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc=
|
||||
k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo=
|
||||
k8s.io/apiserver v0.25.4 h1:/3TwZcgLqX7wUxq7TtXOUqXeBTwXIblVMQdhR5XZ7yo=
|
||||
k8s.io/apiserver v0.25.4/go.mod h1:rPcm567XxjOnnd7jedDUnGJGmDGAo+cT6H7QHAN+xV0=
|
||||
k8s.io/client-go v0.25.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8=
|
||||
k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw=
|
||||
k8s.io/api v0.26.7 h1:Lf4iEBEJb5OFNmawtBfSZV/UNi9riSJ0t1qdhyZqI40=
|
||||
k8s.io/api v0.26.7/go.mod h1:Vk9bMadzA49UHPmHB//lX7VRCQSXGoVwfLd3Sc1SSXI=
|
||||
k8s.io/apimachinery v0.26.7 h1:590jSBwaSHCAFCqltaEogY/zybFlhGsnLteLpuF2wig=
|
||||
k8s.io/apimachinery v0.26.7/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
||||
k8s.io/apiserver v0.26.7 h1:NX/zBZZn4R+Cq6shwyn8Pn8REd0yJJ16dbtv9WkEVEU=
|
||||
k8s.io/apiserver v0.26.7/go.mod h1:r0wDRWHI7VL/KlQLTkJJBVGZ3KeNfv+VetlyRtr86xs=
|
||||
k8s.io/client-go v0.26.7 h1:hyU9aKHlwVOykgyxzGYkrDSLCc4+mimZVyUJjPyUn1E=
|
||||
k8s.io/client-go v0.26.7/go.mod h1:okYjy0jtq6sdeztALDvCh24tg4opOQS1XNvsJlERDAo=
|
||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||
|
||||
@@ -9,8 +9,9 @@ set -e
|
||||
|
||||
: "${CGO_ENABLED=0}"
|
||||
: "${GO_PKG=github.com/docker/buildx}"
|
||||
: "${GO_EXTRA_FLAGS=}"
|
||||
: "${GO_LDFLAGS=-X ${GO_PKG}/version.Version=${VERSION} -X ${GO_PKG}/version.Revision=${REVISION} -X ${GO_PKG}/version.Package=${PACKAGE}}"
|
||||
: "${GO_EXTRA_LDFLAGS=}"
|
||||
|
||||
set -x
|
||||
CGO_ENABLED=$CGO_ENABLED go build -mod vendor -trimpath -ldflags "${GO_LDFLAGS} ${GO_EXTRA_LDFLAGS}" -o "${DESTDIR}/docker-buildx" ./cmd/buildx
|
||||
CGO_ENABLED=$CGO_ENABLED go build -mod vendor -trimpath ${GO_EXTRA_FLAGS} -ldflags "${GO_LDFLAGS} ${GO_EXTRA_LDFLAGS}" -o "${DESTDIR}/docker-buildx" ./cmd/buildx
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.20
|
||||
ARG GO_VERSION=1.20.7
|
||||
ARG FORMATS=md,yaml
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS docsgen
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
# Copyright The Buildx Authors.
|
||||
# Licensed under the Apache License, Version 2.0
|
||||
|
||||
ARG GO_VERSION="1.20"
|
||||
ARG GO_VERSION="1.20.7"
|
||||
ARG PROTOC_VERSION="3.11.4"
|
||||
|
||||
# protoc is dynamically linked to glibc so can't use alpine base
|
||||
FROM golang:${GO_VERSION}-buster AS base
|
||||
FROM golang:${GO_VERSION}-bookworm AS base
|
||||
RUN apt-get update && apt-get --no-install-recommends install -y git unzip
|
||||
ARG PROTOC_VERSION
|
||||
ARG TARGETOS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.20
|
||||
ARG GO_VERSION=1.20.7
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine
|
||||
RUN apk add --no-cache git gcc musl-dev
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.20
|
||||
ARG GO_VERSION=1.20.7
|
||||
ARG MODOUTDATED_VERSION=v0.8.0
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS base
|
||||
|
||||
34
hack/test
Executable file
34
hack/test
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
: "${BUILDX_CMD=docker buildx}"
|
||||
|
||||
: "${TEST_IMAGE_BUILD=1}"
|
||||
: "${TEST_IMAGE_ID=buildx-tests}"
|
||||
|
||||
: "${TEST_REPORT_SUFFIX=}"
|
||||
: "${TEST_KEEP_CACHE=}"
|
||||
: "${TEST_DOCKERD=}"
|
||||
: "${TEST_BUILDKIT_IMAGE=}"
|
||||
|
||||
if [ "$TEST_IMAGE_BUILD" = "1" ]; then
|
||||
${BUILDX_CMD} bake integration-test --set "*.output=type=docker,name=$TEST_IMAGE_ID"
|
||||
fi
|
||||
|
||||
testReportsDir="$(pwd)/bin/testreports"
|
||||
mkdir -p "$testReportsDir"
|
||||
testReportsVol="-v $testReportsDir:/testreports"
|
||||
gotestsumArgs="--format=standard-verbose --jsonfile=/testreports/go-test-report$TEST_REPORT_SUFFIX.json --junitfile=/testreports/junit-report$TEST_REPORT_SUFFIX.xml"
|
||||
gotestArgs="-mod=vendor -coverprofile=/testreports/coverage-report$TEST_REPORT_SUFFIX.txt -covermode=atomic"
|
||||
|
||||
cacheVolume="buildx-test-cache"
|
||||
if ! docker container inspect "$cacheVolume" >/dev/null 2>/dev/null; then
|
||||
docker create -v /root/.cache -v /root/.cache/registry -v /go/pkg/mod --name "$cacheVolume" alpine
|
||||
fi
|
||||
if [ "$TEST_KEEP_CACHE" != "1" ]; then
|
||||
trap 'docker rm -v $cacheVolume' EXIT
|
||||
fi
|
||||
|
||||
cid=$(docker create --rm -v /tmp $testReportsVol --volumes-from=$cacheVolume -e GITHUB_REF -e TEST_DOCKERD -e TEST_BUILDKIT_IMAGE -e SKIP_INTEGRATION_TESTS -e GOTESTSUM_FORMAT ${BUILDKIT_INTEGRATION_SNAPSHOTTER:+"-eBUILDKIT_INTEGRATION_SNAPSHOTTER"} -e BUILDKIT_REGISTRY_MIRROR_DIR=/root/.cache/registry --privileged $TEST_IMAGE_ID gotestsum $gotestsumArgs --packages="${TESTPKGS:-./...}" -- $gotestArgs ${TESTFLAGS:--v})
|
||||
docker start -a -i $cid
|
||||
@@ -20,7 +20,17 @@ func NewAttachCmd(m types.Monitor, stdout io.WriteCloser) types.Command {
|
||||
}
|
||||
|
||||
func (cm *AttachCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "attach to a buildx server or a process in the container"}
|
||||
return types.CommandInfo{
|
||||
Name: "attach",
|
||||
HelpMessage: "attach to a buildx server or a process in the container",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
attach ID
|
||||
|
||||
ID is for a session (visible via list command) or a process (visible via ps command).
|
||||
If you attached to a process, use Ctrl-a-c for switching the monitor to that process's STDIO.
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *AttachCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -2,6 +2,7 @@ package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/buildx/monitor/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -16,7 +17,16 @@ func NewDisconnectCmd(m types.Monitor) types.Command {
|
||||
}
|
||||
|
||||
func (cm *DisconnectCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "disconnect a client from a buildx server. Specific session ID can be specified an arg"}
|
||||
return types.CommandInfo{
|
||||
Name: "disconnect",
|
||||
HelpMessage: "disconnect a client from a buildx server. Specific session ID can be specified an arg",
|
||||
HelpMessageLong: fmt.Sprintf(`
|
||||
Usage:
|
||||
disconnect [ID]
|
||||
|
||||
ID is for a session (visible via list command). Default is %q.
|
||||
`, cm.m.AttachedSessionID()),
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *DisconnectCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -22,7 +22,16 @@ func NewExecCmd(m types.Monitor, invokeConfig controllerapi.InvokeConfig, stdout
|
||||
}
|
||||
|
||||
func (cm *ExecCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "execute a process in the interactive container"}
|
||||
return types.CommandInfo{
|
||||
Name: "exec",
|
||||
HelpMessage: "execute a process in the interactive container",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
exec COMMAND [ARG...]
|
||||
|
||||
COMMAND and ARG... will be executed in the container.
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *ExecCmd) Exec(ctx context.Context, args []string) error {
|
||||
@@ -32,6 +41,7 @@ func (cm *ExecCmd) Exec(ctx context.Context, args []string) error {
|
||||
cfg := controllerapi.InvokeConfig{
|
||||
Entrypoint: []string{args[1]},
|
||||
Cmd: args[2:],
|
||||
NoCmd: false,
|
||||
// TODO: support other options as well via flags
|
||||
Env: cm.invokeConfig.Env,
|
||||
User: cm.invokeConfig.User,
|
||||
|
||||
@@ -16,7 +16,16 @@ func NewKillCmd(m types.Monitor) types.Command {
|
||||
}
|
||||
|
||||
func (cm *KillCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "kill buildx server"}
|
||||
return types.CommandInfo{
|
||||
Name: "kill",
|
||||
HelpMessage: "kill buildx server",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
kill
|
||||
|
||||
Kills the currently connecting buildx server process.
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *KillCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -21,7 +21,14 @@ func NewListCmd(m types.Monitor, stdout io.WriteCloser) types.Command {
|
||||
}
|
||||
|
||||
func (cm *ListCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "list buildx sessions"}
|
||||
return types.CommandInfo{
|
||||
Name: "list",
|
||||
HelpMessage: "list buildx sessions",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
list
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *ListCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -20,7 +20,14 @@ func NewPsCmd(m types.Monitor, stdout io.WriteCloser) types.Command {
|
||||
}
|
||||
|
||||
func (cm *PsCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: `list processes invoked by "exec". Use "attach" to attach IO to that process`}
|
||||
return types.CommandInfo{
|
||||
Name: "ps",
|
||||
HelpMessage: `list processes invoked by "exec". Use "attach" to attach IO to that process`,
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
ps
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *PsCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -27,7 +27,14 @@ func NewReloadCmd(m types.Monitor, stdout io.WriteCloser, progress *progress.Pri
|
||||
}
|
||||
|
||||
func (cm *ReloadCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "reloads the context and build it"}
|
||||
return types.CommandInfo{
|
||||
Name: "reload",
|
||||
HelpMessage: "reloads the context and build it",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
reload
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *ReloadCmd) Exec(ctx context.Context, args []string) error {
|
||||
|
||||
@@ -21,7 +21,19 @@ func NewRollbackCmd(m types.Monitor, invokeConfig controllerapi.InvokeConfig, st
|
||||
}
|
||||
|
||||
func (cm *RollbackCmd) Info() types.CommandInfo {
|
||||
return types.CommandInfo{HelpMessage: "re-runs the interactive container with initial rootfs contents"}
|
||||
return types.CommandInfo{
|
||||
Name: "rollback",
|
||||
HelpMessage: "re-runs the interactive container with the step's rootfs contents",
|
||||
HelpMessageLong: `
|
||||
Usage:
|
||||
rollback [FLAGS] [COMMAND] [ARG...]
|
||||
|
||||
Flags:
|
||||
--init Run the container with the initial rootfs of that step.
|
||||
|
||||
COMMAND and ARG... will be executed in the container.
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *RollbackCmd) Exec(ctx context.Context, args []string) error {
|
||||
@@ -35,6 +47,7 @@ func (cm *RollbackCmd) Exec(ctx context.Context, args []string) error {
|
||||
if len(cmds) > 0 {
|
||||
cfg.Entrypoint = []string{cmds[0]}
|
||||
cfg.Cmd = cmds[1:]
|
||||
cfg.NoCmd = false
|
||||
}
|
||||
}
|
||||
id := cm.m.Rollback(ctx, cfg)
|
||||
|
||||
@@ -85,18 +85,22 @@ func RunMonitor(ctx context.Context, curRef string, options *controllerapi.Build
|
||||
id := m.Rollback(ctx, invokeConfig)
|
||||
fmt.Fprintf(stdout, "Interactive container was restarted with process %q. Press Ctrl-a-c to switch to the new container\n", id)
|
||||
|
||||
registeredCommands := map[string]types.Command{
|
||||
"reload": commands.NewReloadCmd(m, stdout, progress, options, invokeConfig),
|
||||
"rollback": commands.NewRollbackCmd(m, invokeConfig, stdout),
|
||||
"list": commands.NewListCmd(m, stdout),
|
||||
"disconnect": commands.NewDisconnectCmd(m),
|
||||
"kill": commands.NewKillCmd(m),
|
||||
"attach": commands.NewAttachCmd(m, stdout),
|
||||
"exec": commands.NewExecCmd(m, invokeConfig, stdout),
|
||||
"ps": commands.NewPsCmd(m, stdout),
|
||||
availableCommands := []types.Command{
|
||||
commands.NewReloadCmd(m, stdout, progress, options, invokeConfig),
|
||||
commands.NewRollbackCmd(m, invokeConfig, stdout),
|
||||
commands.NewListCmd(m, stdout),
|
||||
commands.NewDisconnectCmd(m),
|
||||
commands.NewKillCmd(m),
|
||||
commands.NewAttachCmd(m, stdout),
|
||||
commands.NewExecCmd(m, invokeConfig, stdout),
|
||||
commands.NewPsCmd(m, stdout),
|
||||
}
|
||||
registeredCommands := make(map[string]types.Command)
|
||||
for _, c := range availableCommands {
|
||||
registeredCommands[c.Info().Name] = c
|
||||
}
|
||||
additionalHelpMessages := map[string]string{
|
||||
"help": "shows this message",
|
||||
"help": "shows this message. Optionally pass a command name as an argument to print the detailed usage.",
|
||||
"exit": "exits monitor",
|
||||
}
|
||||
|
||||
@@ -141,6 +145,10 @@ func RunMonitor(ctx context.Context, curRef string, options *controllerapi.Build
|
||||
case "exit":
|
||||
return
|
||||
case "help":
|
||||
if len(args) >= 2 {
|
||||
printHelpMessageOfCommand(stdout, args[1], registeredCommands, additionalHelpMessages)
|
||||
continue
|
||||
}
|
||||
printHelpMessage(stdout, registeredCommands, additionalHelpMessages)
|
||||
continue
|
||||
default:
|
||||
@@ -171,6 +179,21 @@ func RunMonitor(ctx context.Context, curRef string, options *controllerapi.Build
|
||||
}
|
||||
}
|
||||
|
||||
func printHelpMessageOfCommand(out io.Writer, name string, registeredCommands map[string]types.Command, additional map[string]string) {
|
||||
var target types.Command
|
||||
if c, ok := registeredCommands[name]; ok {
|
||||
target = c
|
||||
} else {
|
||||
fmt.Fprintf(out, "monitor: no help message for %q\n", name)
|
||||
printHelpMessage(out, registeredCommands, additional)
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(out, target.Info().HelpMessage)
|
||||
if h := target.Info().HelpMessageLong; h != "" {
|
||||
fmt.Fprintln(out, h)
|
||||
}
|
||||
}
|
||||
|
||||
func printHelpMessage(out io.Writer, registeredCommands map[string]types.Command, additional map[string]string) {
|
||||
var names []string
|
||||
for name := range registeredCommands {
|
||||
@@ -259,6 +282,8 @@ func (m *monitor) startInvoke(ctx context.Context, pid string, cfg controllerapi
|
||||
}
|
||||
if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 {
|
||||
cfg.Entrypoint = []string{"sh"} // launch shell by default
|
||||
cfg.Cmd = []string{}
|
||||
cfg.NoCmd = false
|
||||
}
|
||||
go func() {
|
||||
// Start a new invoke
|
||||
|
||||
@@ -38,9 +38,14 @@ type Monitor interface {
|
||||
|
||||
// CommandInfo is information about a command.
|
||||
type CommandInfo struct {
|
||||
// Name is the name of the command.
|
||||
Name string
|
||||
|
||||
// HelpMessage is the message printed to the console when "help" command is invoked.
|
||||
// HelpMessage is one-line message printed to the console when "help" command is invoked.
|
||||
HelpMessage string
|
||||
|
||||
// HelpMessageLong is a detailed message printed to the console when "help" command prints this command's information.
|
||||
HelpMessageLong string
|
||||
}
|
||||
|
||||
// Command represents a command for debugging.
|
||||
|
||||
BIN
out/buildx
Executable file
BIN
out/buildx
Executable file
Binary file not shown.
@@ -24,11 +24,12 @@ type NodeGroup struct {
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
Name string
|
||||
Endpoint string
|
||||
Platforms []specs.Platform
|
||||
Flags []string
|
||||
DriverOpts map[string]string
|
||||
Name string
|
||||
Endpoint string
|
||||
Platforms []specs.Platform
|
||||
Flags []string
|
||||
DriverOpts map[string]string
|
||||
SecurityOpts map[string]string
|
||||
|
||||
Files map[string][]byte
|
||||
}
|
||||
@@ -48,7 +49,7 @@ func (ng *NodeGroup) Leave(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string) error {
|
||||
func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string, so map[string]string) error {
|
||||
if ng.Dynamic {
|
||||
return errors.New("dynamic node group does not support Update")
|
||||
}
|
||||
@@ -91,6 +92,10 @@ func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpoints
|
||||
n.DriverOpts = do
|
||||
needsRestart = true
|
||||
}
|
||||
if so != nil {
|
||||
n.SecurityOpts = so
|
||||
needsRestart = true
|
||||
}
|
||||
if configFile != "" {
|
||||
for k, v := range files {
|
||||
n.Files[k] = v
|
||||
@@ -118,12 +123,13 @@ func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpoints
|
||||
}
|
||||
|
||||
n := Node{
|
||||
Name: name,
|
||||
Endpoint: endpoint,
|
||||
Platforms: pp,
|
||||
Flags: flags,
|
||||
DriverOpts: do,
|
||||
Files: files,
|
||||
Name: name,
|
||||
Endpoint: endpoint,
|
||||
Platforms: pp,
|
||||
Flags: flags,
|
||||
DriverOpts: do,
|
||||
SecurityOpts: so,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
ng.Nodes = append(ng.Nodes, n)
|
||||
@@ -156,6 +162,10 @@ func (n *Node) Copy() *Node {
|
||||
for k, v := range n.DriverOpts {
|
||||
driverOpts[k] = v
|
||||
}
|
||||
securityOpts := map[string]string{}
|
||||
for k, v := range n.SecurityOpts {
|
||||
securityOpts[k] = v
|
||||
}
|
||||
files := map[string][]byte{}
|
||||
for k, v := range n.Files {
|
||||
vv := []byte{}
|
||||
@@ -163,12 +173,13 @@ func (n *Node) Copy() *Node {
|
||||
files[k] = vv
|
||||
}
|
||||
return &Node{
|
||||
Name: n.Name,
|
||||
Endpoint: n.Endpoint,
|
||||
Platforms: platforms,
|
||||
Flags: flags,
|
||||
DriverOpts: driverOpts,
|
||||
Files: files,
|
||||
Name: n.Name,
|
||||
Endpoint: n.Endpoint,
|
||||
Platforms: platforms,
|
||||
Flags: flags,
|
||||
DriverOpts: driverOpts,
|
||||
SecurityOpts: securityOpts,
|
||||
Files: files,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,3 +235,26 @@ func TestNodeManagement(t *testing.T) {
|
||||
require.NotNil(t, ng)
|
||||
require.Equal(t, "mybuild", ng.Name)
|
||||
}
|
||||
|
||||
func TestNodeInvalidName(t *testing.T) {
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
s, err := New(tmpdir)
|
||||
require.NoError(t, err)
|
||||
|
||||
txn, release, err := s.Txn()
|
||||
require.NoError(t, err)
|
||||
defer release()
|
||||
|
||||
_, err = txn.NodeGroupByName("123builder")
|
||||
require.Error(t, err)
|
||||
require.True(t, IsErrInvalidName(err))
|
||||
|
||||
err = txn.Save(&NodeGroup{
|
||||
Name: "123builder",
|
||||
Driver: "mydriver",
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, IsErrInvalidName(err))
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func GetCurrentInstance(txn *store.Txn, dockerCli command.Cli) (*store.NodeGroup
|
||||
func GetNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.NodeGroup, error) {
|
||||
ng, err := txn.NodeGroupByName(name)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(errors.Cause(err)) {
|
||||
if !os.IsNotExist(errors.Cause(err)) && !store.IsErrInvalidName(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,28 @@ import (
|
||||
|
||||
var namePattern = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9\.\-_]*$`)
|
||||
|
||||
type errInvalidName struct {
|
||||
error
|
||||
}
|
||||
|
||||
func (e *errInvalidName) Error() string {
|
||||
return e.error.Error()
|
||||
}
|
||||
|
||||
func (e *errInvalidName) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func IsErrInvalidName(err error) bool {
|
||||
_, ok := err.(*errInvalidName)
|
||||
return ok
|
||||
}
|
||||
|
||||
func ValidateName(s string) (string, error) {
|
||||
if !namePattern.MatchString(s) {
|
||||
return "", errors.Errorf("invalid name %s, name needs to start with a letter and may not contain symbols, except ._-", s)
|
||||
return "", &errInvalidName{
|
||||
errors.Errorf("invalid name %s, name needs to start with a letter and may not contain symbols, except ._-", s),
|
||||
}
|
||||
}
|
||||
return strings.ToLower(s), nil
|
||||
}
|
||||
|
||||
289
tests/bake.go
Normal file
289
tests/bake.go
Normal file
@@ -0,0 +1,289 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/docker/buildx/util/gitutil"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func bakeCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
||||
opts = append([]cmdOpt{withArgs("bake", "--progress=quiet")}, opts...)
|
||||
cmd := buildxCmd(sb, opts...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testBakeLocal,
|
||||
testBakeRemote,
|
||||
testBakeRemoteCmdContext,
|
||||
testBakeRemoteCmdContextOverride,
|
||||
testBakeRemoteContextSubdir,
|
||||
testBakeRemoteCmdContextEscapeRoot,
|
||||
testBakeRemoteCmdContextEscapeRelative,
|
||||
}
|
||||
|
||||
func testBakeLocal(t *testing.T, sb integration.Sandbox) {
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
`)
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
}
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
out, err := bakeCmd(sb, withDir(dir), withArgs("--set", "*.output=type=local,dest="+dirDest))
|
||||
require.NoError(t, err, out)
|
||||
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
|
||||
func testBakeRemote(t *testing.T, sb integration.Sandbox) {
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
dockerfile-inline = <<EOT
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
EOT
|
||||
}
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
git, err := gitutil.New(gitutil.WithWorkingDir(dir))
|
||||
require.NoError(t, err)
|
||||
|
||||
gitutil.GitInit(git, t)
|
||||
gitutil.GitAdd(git, t, "docker-bake.hcl", "foo")
|
||||
gitutil.GitCommit(git, t, "initial commit")
|
||||
addr := gitutil.GitServeHTTP(git, t)
|
||||
|
||||
out, err := bakeCmd(sb, withDir(dir), withArgs(addr, "--set", "*.output=type=local,dest="+dirDest))
|
||||
require.NoError(t, err, out)
|
||||
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
|
||||
func testBakeRemoteCmdContext(t *testing.T, sb integration.Sandbox) {
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
context = BAKE_CMD_CONTEXT
|
||||
dockerfile-inline = <<EOT
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
EOT
|
||||
}
|
||||
`)
|
||||
dirSpec := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
)
|
||||
dirSrc := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
git, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
|
||||
require.NoError(t, err)
|
||||
|
||||
gitutil.GitInit(git, t)
|
||||
gitutil.GitAdd(git, t, "docker-bake.hcl")
|
||||
gitutil.GitCommit(git, t, "initial commit")
|
||||
addr := gitutil.GitServeHTTP(git, t)
|
||||
|
||||
out, err := bakeCmd(sb, withDir(dirSrc), withArgs(addr, "--set", "*.output=type=local,dest="+dirDest))
|
||||
require.NoError(t, err, out)
|
||||
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
|
||||
func testBakeRemoteCmdContextOverride(t *testing.T, sb integration.Sandbox) {
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
context = BAKE_CMD_CONTEXT
|
||||
dockerfile-inline = <<EOT
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
EOT
|
||||
}
|
||||
`)
|
||||
dirSpec := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
)
|
||||
dirSrc := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
gitSpec, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
|
||||
require.NoError(t, err)
|
||||
gitutil.GitInit(gitSpec, t)
|
||||
gitutil.GitAdd(gitSpec, t, "docker-bake.hcl")
|
||||
gitutil.GitCommit(gitSpec, t, "initial commit")
|
||||
addrSpec := gitutil.GitServeHTTP(gitSpec, t)
|
||||
|
||||
gitSrc, err := gitutil.New(gitutil.WithWorkingDir(dirSrc))
|
||||
require.NoError(t, err)
|
||||
gitutil.GitInit(gitSrc, t)
|
||||
gitutil.GitAdd(gitSrc, t, "foo")
|
||||
gitutil.GitCommit(gitSrc, t, "initial commit")
|
||||
addrSrc := gitutil.GitServeHTTP(gitSrc, t)
|
||||
|
||||
out, err := bakeCmd(sb, withDir("/tmp"), withArgs(addrSpec, addrSrc, "--set", "*.output=type=local,dest="+dirDest))
|
||||
require.NoError(t, err, out)
|
||||
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
|
||||
// https://github.com/docker/buildx/issues/1738
|
||||
func testBakeRemoteContextSubdir(t *testing.T, sb integration.Sandbox) {
|
||||
bakefile := []byte(`
|
||||
target default {
|
||||
context = "./bar"
|
||||
}
|
||||
`)
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
COPY super-cool.txt /
|
||||
`)
|
||||
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
fstest.CreateDir("bar", 0700),
|
||||
fstest.CreateFile("bar/Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("bar/super-cool.txt", []byte("super cool"), 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
git, err := gitutil.New(gitutil.WithWorkingDir(dir))
|
||||
require.NoError(t, err)
|
||||
gitutil.GitInit(git, t)
|
||||
gitutil.GitAdd(git, t, "docker-bake.hcl", "bar")
|
||||
gitutil.GitCommit(git, t, "initial commit")
|
||||
addr := gitutil.GitServeHTTP(git, t)
|
||||
|
||||
out, err := bakeCmd(sb, withDir("/tmp"), withArgs(addr, "--set", "*.output=type=local,dest="+dirDest))
|
||||
require.NoError(t, err, out)
|
||||
|
||||
require.FileExists(t, filepath.Join(dirDest, "super-cool.txt"))
|
||||
}
|
||||
|
||||
func testBakeRemoteCmdContextEscapeRoot(t *testing.T, sb integration.Sandbox) {
|
||||
dirSrc := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
dirSrc, err := filepath.Abs(dirSrc)
|
||||
require.NoError(t, err)
|
||||
|
||||
dirCurrent := tmpdir(t)
|
||||
dirCurrent, err = filepath.Abs(dirCurrent)
|
||||
require.NoError(t, err)
|
||||
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
context = "cwd://` + dirSrc + `"
|
||||
dockerfile-inline = <<EOT
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
EOT
|
||||
}
|
||||
`)
|
||||
dirSpec := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
git, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
|
||||
require.NoError(t, err)
|
||||
|
||||
gitutil.GitInit(git, t)
|
||||
gitutil.GitAdd(git, t, "docker-bake.hcl")
|
||||
gitutil.GitCommit(git, t, "initial commit")
|
||||
addr := gitutil.GitServeHTTP(git, t)
|
||||
|
||||
out, err := bakeCmd(
|
||||
sb,
|
||||
withDir(dirCurrent),
|
||||
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
|
||||
)
|
||||
require.Error(t, err, out)
|
||||
require.Contains(t, out, "outside of the working directory, please set BAKE_ALLOW_REMOTE_FS_ACCESS")
|
||||
|
||||
out, err = bakeCmd(
|
||||
sb,
|
||||
withDir(dirCurrent),
|
||||
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
|
||||
withEnv("BAKE_ALLOW_REMOTE_FS_ACCESS=1"),
|
||||
)
|
||||
require.NoError(t, err, out)
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
|
||||
func testBakeRemoteCmdContextEscapeRelative(t *testing.T, sb integration.Sandbox) {
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
context = "cwd://../"
|
||||
dockerfile-inline = <<EOT
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
EOT
|
||||
}
|
||||
`)
|
||||
dirSpec := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
)
|
||||
dirSrc := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
fstest.CreateDir("subdir", 0700),
|
||||
)
|
||||
dirDest := t.TempDir()
|
||||
|
||||
git, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
|
||||
require.NoError(t, err)
|
||||
|
||||
gitutil.GitInit(git, t)
|
||||
gitutil.GitAdd(git, t, "docker-bake.hcl")
|
||||
gitutil.GitCommit(git, t, "initial commit")
|
||||
addr := gitutil.GitServeHTTP(git, t)
|
||||
|
||||
out, err := bakeCmd(
|
||||
sb,
|
||||
withDir(filepath.Join(dirSrc, "subdir")),
|
||||
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
|
||||
)
|
||||
require.Error(t, err, out)
|
||||
require.Contains(t, out, "outside of the working directory, please set BAKE_ALLOW_REMOTE_FS_ACCESS")
|
||||
|
||||
out, err = bakeCmd(
|
||||
sb,
|
||||
withDir(filepath.Join(dirSrc, "subdir")),
|
||||
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
|
||||
withEnv("BAKE_ALLOW_REMOTE_FS_ACCESS=1"),
|
||||
)
|
||||
require.NoError(t, err, out)
|
||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
||||
}
|
||||
315
tests/build.go
Normal file
315
tests/build.go
Normal file
@@ -0,0 +1,315 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/creack/pty"
|
||||
"github.com/moby/buildkit/util/contentutil"
|
||||
"github.com/moby/buildkit/util/testutil"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func buildCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
||||
opts = append([]cmdOpt{withArgs("build", "--progress=quiet")}, opts...)
|
||||
cmd := buildxCmd(sb, opts...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testBuild,
|
||||
testImageIDOutput,
|
||||
testBuildLocalExport,
|
||||
testBuildRegistryExport,
|
||||
testBuildRegistryExportAttestations,
|
||||
testBuildTarExport,
|
||||
testBuildMobyFromLocalImage,
|
||||
testBuildDetailsLink,
|
||||
testBuildProgress,
|
||||
}
|
||||
|
||||
func testBuild(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
out, err := buildCmd(sb, withArgs(dir))
|
||||
require.NoError(t, err, string(out))
|
||||
}
|
||||
|
||||
func testBuildLocalExport(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=local,dest=%s/result", dir), dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
dt, err := os.ReadFile(dir + "/result/bar")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "foo", string(dt))
|
||||
}
|
||||
|
||||
func testBuildTarExport(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=tar,dest=%s/result.tar", dir), dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
dt, err := os.ReadFile(fmt.Sprintf("%s/result.tar", dir))
|
||||
require.NoError(t, err)
|
||||
m, err := testutil.ReadTarToMap(dt, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, m, "bar")
|
||||
require.Equal(t, "foo", string(m["bar"].Data))
|
||||
}
|
||||
|
||||
func testBuildRegistryExport(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/registry:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=image,name=%s,push=true", target), dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
desc, provider, err := contentutil.ProviderFromRef(target)
|
||||
require.NoError(t, err)
|
||||
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk := platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
||||
img := imgs.Find(pk)
|
||||
require.NotNil(t, img)
|
||||
require.Len(t, img.Layers, 1)
|
||||
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
||||
}
|
||||
|
||||
func testBuildRegistryExportAttestations(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/registry:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=image,name=%s,push=true", target), "--provenance=true", dir))
|
||||
if sb.Name() == "docker" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, out, "attestations are not supported")
|
||||
return
|
||||
}
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
desc, provider, err := contentutil.ProviderFromRef(target)
|
||||
require.NoError(t, err)
|
||||
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
|
||||
require.NoError(t, err)
|
||||
|
||||
pk := platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
||||
img := imgs.Find(pk)
|
||||
require.NotNil(t, img)
|
||||
require.Len(t, img.Layers, 1)
|
||||
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
||||
|
||||
att := imgs.FindAttestation(pk)
|
||||
require.NotNil(t, att)
|
||||
require.Len(t, att.Layers, 1)
|
||||
}
|
||||
|
||||
func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
||||
dockerfile := []byte(`FROM busybox:latest`)
|
||||
|
||||
dir := tmpdir(t,
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
)
|
||||
targetDir := t.TempDir()
|
||||
|
||||
outFlag := "--output=type=docker"
|
||||
|
||||
if sb.DockerAddress() == "" {
|
||||
// there is no Docker atm to load the image
|
||||
outFlag += ",dest=" + targetDir + "/image.tar"
|
||||
}
|
||||
|
||||
cmd := buildxCmd(
|
||||
sb,
|
||||
withArgs("build", "-q", "--provenance", "false", outFlag, "--iidfile", filepath.Join(targetDir, "iid.txt"), "--metadata-file", filepath.Join(targetDir, "md.json"), dir),
|
||||
)
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
require.NoError(t, err)
|
||||
|
||||
dt, err := os.ReadFile(filepath.Join(targetDir, "iid.txt"))
|
||||
require.NoError(t, err)
|
||||
|
||||
imageID := string(dt)
|
||||
require.NotEmpty(t, imageID)
|
||||
|
||||
dgst, err := digest.Parse(string(dt))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, dgst.String(), strings.TrimSpace(stdout.String()))
|
||||
|
||||
dt, err = os.ReadFile(filepath.Join(targetDir, "md.json"))
|
||||
require.NoError(t, err)
|
||||
|
||||
type mdT struct {
|
||||
ConfigDigest string `json:"containerimage.config.digest"`
|
||||
}
|
||||
var md mdT
|
||||
err = json.Unmarshal(dt, &md)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotEmpty(t, md.ConfigDigest)
|
||||
require.Equal(t, dgst, digest.Digest(md.ConfigDigest))
|
||||
}
|
||||
|
||||
func testBuildMobyFromLocalImage(t *testing.T, sb integration.Sandbox) {
|
||||
if !isDockerWorker(sb) {
|
||||
t.Skip("skipping test for non-docker workers")
|
||||
}
|
||||
|
||||
// pull image
|
||||
cmd := dockerCmd(sb, withArgs("pull", "-q", "busybox:latest"))
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
require.NoError(t, cmd.Run())
|
||||
require.Equal(t, "docker.io/library/busybox:latest", strings.TrimSpace(stdout.String()))
|
||||
|
||||
// create local tag
|
||||
cmd = dockerCmd(sb, withArgs("tag", "busybox:latest", "buildx-test:busybox"))
|
||||
cmd.Stderr = os.Stderr
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
// build image
|
||||
dockerfile := []byte(`FROM buildx-test:busybox`)
|
||||
dir := tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
||||
cmd = buildxCmd(
|
||||
sb,
|
||||
withArgs("build", "-q", "--output=type=cacheonly", dir),
|
||||
)
|
||||
cmd.Stderr = os.Stderr
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
// create local tag matching a remote one
|
||||
cmd = dockerCmd(sb, withArgs("tag", "busybox:latest", "busybox:1.35"))
|
||||
cmd.Stderr = os.Stderr
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
// build image and check that it uses the local tag
|
||||
// (note: the version check should match the version of busybox in pins.go)
|
||||
dockerfile = []byte(`
|
||||
FROM busybox:1.35
|
||||
RUN busybox | head -1 | grep v1.36.1
|
||||
`)
|
||||
dir = tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
||||
cmd = buildxCmd(
|
||||
sb,
|
||||
withArgs("build", "-q", "--output=type=cacheonly", dir),
|
||||
)
|
||||
cmd.Stderr = os.Stderr
|
||||
require.NoError(t, cmd.Run())
|
||||
}
|
||||
|
||||
func testBuildDetailsLink(t *testing.T, sb integration.Sandbox) {
|
||||
buildDetailsPattern := regexp.MustCompile(`(?m)^View build details: docker-desktop://dashboard/build/[^/]+/[^/]+/[^/]+\n$`)
|
||||
|
||||
// build simple dockerfile
|
||||
dockerfile := []byte(`FROM busybox:latest
|
||||
RUN echo foo > /bar`)
|
||||
dir := tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
||||
cmd := buildxCmd(sb, withArgs("build", "--output=type=cacheonly", dir))
|
||||
out, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(out))
|
||||
require.False(t, buildDetailsPattern.MatchString(string(out)), fmt.Sprintf("build details link not expected in output, got %q", out))
|
||||
|
||||
// create desktop-build .lastaccess file
|
||||
home, err := os.UserHomeDir() // TODO: sandbox should create a temp home dir and expose it through its interface
|
||||
require.NoError(t, err)
|
||||
dbDir := path.Join(home, ".docker", "desktop-build")
|
||||
require.NoError(t, os.MkdirAll(dbDir, 0755))
|
||||
dblaFile, err := os.Create(path.Join(dbDir, ".lastaccess"))
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
dblaFile.Close()
|
||||
if err := os.Remove(dblaFile.Name()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// build again
|
||||
cmd = buildxCmd(sb, withArgs("build", "--output=type=cacheonly", dir))
|
||||
out, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(out))
|
||||
require.True(t, buildDetailsPattern.MatchString(string(out)), fmt.Sprintf("expected build details link in output, got %q", out))
|
||||
|
||||
// build erroneous dockerfile
|
||||
dockerfile = []byte(`FROM busybox:latest
|
||||
RUN exit 1`)
|
||||
dir = tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
||||
cmd = buildxCmd(sb, withArgs("build", "--output=type=cacheonly", dir))
|
||||
out, err = cmd.CombinedOutput()
|
||||
require.Error(t, err, string(out))
|
||||
require.True(t, buildDetailsPattern.MatchString(string(out)), fmt.Sprintf("expected build details link in output, got %q", out))
|
||||
}
|
||||
|
||||
func createTestProject(t *testing.T) string {
|
||||
dockerfile := []byte(`
|
||||
FROM busybox:latest AS base
|
||||
COPY foo /etc/foo
|
||||
RUN cp /etc/foo /etc/bar
|
||||
|
||||
FROM scratch
|
||||
COPY --from=base /etc/bar /bar
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
return dir
|
||||
}
|
||||
|
||||
func testBuildProgress(t *testing.T, sb integration.Sandbox) {
|
||||
dir := createTestProject(t)
|
||||
driver, _, _ := strings.Cut(sb.Name(), "+")
|
||||
name := sb.Address()
|
||||
|
||||
// progress=tty
|
||||
cmd := buildxCmd(sb, withArgs("build", "--progress=tty", "--output=type=cacheonly", dir))
|
||||
f, err := pty.Start(cmd)
|
||||
require.NoError(t, err)
|
||||
buf := bytes.NewBuffer(nil)
|
||||
io.Copy(buf, f)
|
||||
ttyOutput := buf.String()
|
||||
require.Contains(t, ttyOutput, "[+] Building")
|
||||
require.Contains(t, ttyOutput, fmt.Sprintf("%s:%s", driver, name))
|
||||
require.Contains(t, ttyOutput, "=> [internal] load build definition from Dockerfile")
|
||||
require.Contains(t, ttyOutput, "=> [base 1/3] FROM docker.io/library/busybox:latest")
|
||||
|
||||
// progress=plain
|
||||
cmd = buildxCmd(sb, withArgs("build", "--progress=plain", "--output=type=cacheonly", dir))
|
||||
plainOutput, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(plainOutput), fmt.Sprintf(`#0 building with "%s" instance using %s driver`, name, driver))
|
||||
require.Contains(t, string(plainOutput), "[internal] load build definition from Dockerfile")
|
||||
require.Contains(t, string(plainOutput), "[base 1/3] FROM docker.io/library/busybox:latest")
|
||||
}
|
||||
267
tests/imagetools.go
Normal file
267
tests/imagetools.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var imagetoolsTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testImagetoolsCopyManifest,
|
||||
testImagetoolsCopyIndex,
|
||||
testImagetoolsInspectAndFilter,
|
||||
testImagetoolsAnnotation,
|
||||
}
|
||||
|
||||
func testImagetoolsCopyManifest(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools-manifest:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var mfst ocispecs.Manifest
|
||||
err = json.Unmarshal(dt, &mfst)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst.MediaType)
|
||||
|
||||
registry2, err := sb.NewRegistry()
|
||||
require.NoError(t, err)
|
||||
target2 := registry2 + "/buildx/imtools2-manifest:latest"
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
||||
require.Equal(t, 1, len(idx2.Manifests))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2+"@"+string(idx2.Manifests[0].Digest), "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var mfst2 ocispecs.Manifest
|
||||
err = json.Unmarshal(dt, &mfst2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst2.MediaType)
|
||||
|
||||
require.Equal(t, mfst.Config.Digest, mfst2.Config.Digest)
|
||||
require.Equal(t, len(mfst.Layers), len(mfst2.Layers))
|
||||
for i := range mfst.Layers {
|
||||
require.Equal(t, mfst.Layers[i].Digest, mfst2.Layers[i].Digest)
|
||||
}
|
||||
}
|
||||
|
||||
func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx.MediaType)
|
||||
require.Equal(t, 2, len(idx.Manifests))
|
||||
|
||||
registry2, err := sb.NewRegistry()
|
||||
require.NoError(t, err)
|
||||
target2 := registry2 + "/buildx/imtools2:latest"
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
||||
|
||||
require.Equal(t, len(idx.Manifests), len(idx2.Manifests))
|
||||
for i := range idx.Manifests {
|
||||
require.Equal(t, idx.Manifests[i].Digest, idx2.Manifests[i].Digest)
|
||||
}
|
||||
}
|
||||
|
||||
func testImagetoolsInspectAndFilter(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 2, len(idx.Manifests))
|
||||
|
||||
mfst := idx.Manifests[0]
|
||||
require.Equal(t, "linux/amd64", platforms.Format(*mfst.Platform))
|
||||
|
||||
mfst = idx.Manifests[1]
|
||||
require.Equal(t, "linux/arm64", platforms.Format(*mfst.Platform))
|
||||
|
||||
// create amd64 only image
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target+"-arm64", target+"@"+string(idx.Manifests[1].Digest)))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target+"-arm64", "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx2 ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx2)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(idx2.Manifests))
|
||||
|
||||
require.Equal(t, idx.Manifests[1].Digest, idx2.Manifests[0].Digest)
|
||||
require.Equal(t, platforms.Format(*idx.Manifests[1].Platform), platforms.Format(*idx2.Manifests[0].Platform))
|
||||
}
|
||||
|
||||
func testImagetoolsAnnotation(t *testing.T, sb integration.Sandbox) {
|
||||
if sb.Name() != "docker-container" {
|
||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
||||
}
|
||||
|
||||
dir := createDockerfile(t)
|
||||
registry, err := sb.NewRegistry()
|
||||
if errors.Is(err, integration.ErrRequirements) {
|
||||
t.Skip(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
target := registry + "/buildx/imtools:latest"
|
||||
|
||||
out, err := buildCmd(sb, withArgs("--output", "type=registry,oci-mediatypes=true,name="+target, "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
||||
dt, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
var idx ocispecs.Index
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, idx.Annotations)
|
||||
|
||||
imagetoolsCmd := func(source []string) *exec.Cmd {
|
||||
args := []string{"imagetools", "create", "-t", target, "--annotation", "index:foo=bar", "--annotation", "index:bar=baz",
|
||||
"--annotation", "manifest-descriptor:foo=bar", "--annotation", "manifest-descriptor[linux/amd64]:bar=baz"}
|
||||
args = append(args, source...)
|
||||
return buildxCmd(sb, withArgs(args...))
|
||||
}
|
||||
sources := [][]string{
|
||||
{
|
||||
target,
|
||||
},
|
||||
{
|
||||
target + "@" + string(idx.Manifests[0].Digest),
|
||||
target + "@" + string(idx.Manifests[1].Digest),
|
||||
},
|
||||
}
|
||||
for _, source := range sources {
|
||||
cmd = imagetoolsCmd(source)
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
newTarget := registry + "/buildx/imtools:annotations"
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", newTarget, target))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", newTarget, "--raw"))
|
||||
dt, err = cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(dt))
|
||||
|
||||
err = json.Unmarshal(dt, &idx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, idx.Annotations, 2)
|
||||
require.Equal(t, "bar", idx.Annotations["foo"])
|
||||
require.Equal(t, "baz", idx.Annotations["bar"])
|
||||
require.Len(t, idx.Manifests, 2)
|
||||
for _, mfst := range idx.Manifests {
|
||||
require.Equal(t, "bar", mfst.Annotations["foo"])
|
||||
if platforms.Format(*mfst.Platform) == "linux/amd64" {
|
||||
require.Equal(t, "baz", mfst.Annotations["bar"])
|
||||
} else {
|
||||
require.Empty(t, mfst.Annotations["bar"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createDockerfile(t *testing.T) string {
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
ARG TARGETARCH
|
||||
COPY foo-${TARGETARCH} /foo
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo-amd64", []byte("foo-amd64"), 0600),
|
||||
fstest.CreateFile("foo-arm64", []byte("foo-arm64"), 0600),
|
||||
)
|
||||
return dir
|
||||
}
|
||||
40
tests/inspect.go
Normal file
40
tests/inspect.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func inspectCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
||||
opts = append([]cmdOpt{withArgs("inspect")}, opts...)
|
||||
cmd := buildxCmd(sb, opts...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
var inspectTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testInspect,
|
||||
}
|
||||
|
||||
func testInspect(t *testing.T, sb integration.Sandbox) {
|
||||
out, err := inspectCmd(sb)
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
var name string
|
||||
var driver string
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if v, ok := strings.CutPrefix(line, "Name:"); ok && name == "" {
|
||||
name = strings.TrimSpace(v)
|
||||
}
|
||||
if v, ok := strings.CutPrefix(line, "Driver:"); ok && driver == "" {
|
||||
driver = strings.TrimSpace(v)
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, sb.Address(), name)
|
||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
||||
require.Equal(t, sbDriver, driver)
|
||||
}
|
||||
75
tests/integration.go
Normal file
75
tests/integration.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func tmpdir(t *testing.T, appliers ...fstest.Applier) string {
|
||||
t.Helper()
|
||||
tmpdir := t.TempDir()
|
||||
err := fstest.Apply(appliers...).Apply(tmpdir)
|
||||
require.NoError(t, err)
|
||||
return tmpdir
|
||||
}
|
||||
|
||||
type cmdOpt func(*exec.Cmd)
|
||||
|
||||
func withEnv(env ...string) cmdOpt {
|
||||
return func(cmd *exec.Cmd) {
|
||||
cmd.Env = append(cmd.Env, env...)
|
||||
}
|
||||
}
|
||||
|
||||
func withArgs(args ...string) cmdOpt {
|
||||
return func(cmd *exec.Cmd) {
|
||||
cmd.Args = append(cmd.Args, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func withDir(dir string) cmdOpt {
|
||||
return func(cmd *exec.Cmd) {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
}
|
||||
|
||||
func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||
cmd := exec.Command("buildx")
|
||||
cmd.Env = append([]string{}, os.Environ()...)
|
||||
for _, opt := range opts {
|
||||
opt(cmd)
|
||||
}
|
||||
|
||||
if builder := sb.Address(); builder != "" {
|
||||
cmd.Args = append(cmd.Args, "--builder="+builder)
|
||||
cmd.Env = append(cmd.Env, "BUILDX_CONFIG=/tmp/buildx-"+builder)
|
||||
}
|
||||
if context := sb.DockerAddress(); context != "" {
|
||||
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||
cmd := exec.Command("docker")
|
||||
cmd.Env = append([]string{}, os.Environ()...)
|
||||
for _, opt := range opts {
|
||||
opt(cmd)
|
||||
}
|
||||
if context := sb.DockerAddress(); context != "" {
|
||||
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func isDockerWorker(sb integration.Sandbox) bool {
|
||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
||||
return sbDriver == "docker"
|
||||
}
|
||||
49
tests/integration_test.go
Normal file
49
tests/integration_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/tests/workers"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if bkworkers.IsTestDockerd() {
|
||||
workers.InitDockerWorker()
|
||||
workers.InitDockerContainerWorker()
|
||||
} else {
|
||||
workers.InitRemoteWorker()
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegration(t *testing.T) {
|
||||
var tests []func(t *testing.T, sb integration.Sandbox)
|
||||
tests = append(tests, buildTests...)
|
||||
tests = append(tests, bakeTests...)
|
||||
tests = append(tests, inspectTests...)
|
||||
tests = append(tests, lsTests...)
|
||||
tests = append(tests, imagetoolsTests...)
|
||||
tests = append(tests, versionTests...)
|
||||
testIntegration(t, tests...)
|
||||
}
|
||||
|
||||
func testIntegration(t *testing.T, funcs ...func(t *testing.T, sb integration.Sandbox)) {
|
||||
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
|
||||
buildkitImage := "docker.io/moby/buildkit:buildx-stable-1"
|
||||
if bkworkers.IsTestDockerd() {
|
||||
if img, ok := os.LookupEnv("TEST_BUILDKIT_IMAGE"); ok {
|
||||
ref, err := reference.ParseNormalizedNamed(img)
|
||||
if err == nil {
|
||||
buildkitImage = ref.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
mirroredImages["moby/buildkit:buildx-stable-1"] = buildkitImage
|
||||
mirrors := integration.WithMirroredImages(mirroredImages)
|
||||
|
||||
tests := integration.TestFuncs(funcs...)
|
||||
integration.Run(t, tests, mirrors)
|
||||
}
|
||||
34
tests/ls.go
Normal file
34
tests/ls.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func lsCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
||||
opts = append([]cmdOpt{withArgs("ls")}, opts...)
|
||||
cmd := buildxCmd(sb, opts...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
return string(out), err
|
||||
}
|
||||
|
||||
var lsTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testLs,
|
||||
}
|
||||
|
||||
func testLs(t *testing.T, sb integration.Sandbox) {
|
||||
out, err := lsCmd(sb)
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if strings.Contains(line, sb.Address()) {
|
||||
require.Contains(t, line, sbDriver)
|
||||
return
|
||||
}
|
||||
}
|
||||
require.Fail(t, out)
|
||||
}
|
||||
55
tests/version.go
Normal file
55
tests/version.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var versionTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testVersion,
|
||||
}
|
||||
|
||||
func testVersion(t *testing.T, sb integration.Sandbox) {
|
||||
cmd := buildxCmd(sb, withArgs("version"))
|
||||
out, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(out))
|
||||
|
||||
// There should be at least one newline and the first line
|
||||
// of output should contain the name, version, and possibly a revision.
|
||||
firstLine, _, hasNewline := strings.Cut(string(out), "\n")
|
||||
require.True(t, hasNewline, "At least one newline is required in the output")
|
||||
|
||||
// Log the output to make debugging easier.
|
||||
t.Log(firstLine)
|
||||
|
||||
// Split by spaces into at least 2 fields.
|
||||
fields := strings.Fields(firstLine)
|
||||
require.GreaterOrEqual(t, len(fields), 2, "Expected at least 2 fields in the first line")
|
||||
|
||||
// First field should be an import path.
|
||||
// This can be any valid import path for Go
|
||||
// so don't set too many restrictions here.
|
||||
// Just checking if the import path is a valid Go
|
||||
// path should be suitable enough to make sure this is ok.
|
||||
// Using CheckImportPath instead of CheckPath as it is less
|
||||
// restrictive.
|
||||
importPath := fields[0]
|
||||
require.NoError(t, module.CheckImportPath(importPath), "First field was not a valid import path: %+v", importPath)
|
||||
|
||||
// Second field should be a version.
|
||||
// This defaults to something that's still compatible
|
||||
// with semver.
|
||||
version := fields[1]
|
||||
require.True(t, semver.IsValid(version), "Second field was not valid semver: %+v", version)
|
||||
|
||||
// Revision should be empty or should look like a git hash.
|
||||
if len(fields) > 2 && len(fields[2]) > 0 {
|
||||
revision := fields[2]
|
||||
require.Regexp(t, `[0-9a-f]{40}`, revision, "Third field was not a git revision: %+v", revision)
|
||||
}
|
||||
}
|
||||
59
tests/workers/backend.go
Normal file
59
tests/workers/backend.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
)
|
||||
|
||||
type backend struct {
|
||||
builder string
|
||||
context string
|
||||
unsupportedFeatures []string
|
||||
}
|
||||
|
||||
var _ integration.Backend = &backend{}
|
||||
|
||||
func (s *backend) Address() string {
|
||||
return s.builder
|
||||
}
|
||||
|
||||
func (s *backend) DockerAddress() string {
|
||||
return s.context
|
||||
}
|
||||
|
||||
func (s *backend) ContainerdAddress() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *backend) Snapshotter() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *backend) Rootless() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s backend) Supports(feature string) bool {
|
||||
if enabledFeatures := os.Getenv("BUILDKIT_TEST_ENABLE_FEATURES"); enabledFeatures != "" {
|
||||
for _, enabledFeature := range strings.Split(enabledFeatures, ",") {
|
||||
if feature == enabledFeature {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if disabledFeatures := os.Getenv("BUILDKIT_TEST_DISABLE_FEATURES"); disabledFeatures != "" {
|
||||
for _, disabledFeature := range strings.Split(disabledFeatures, ",") {
|
||||
if feature == disabledFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, unsupportedFeature := range s.unsupportedFeatures {
|
||||
if feature == unsupportedFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
88
tests/workers/docker-container.go
Normal file
88
tests/workers/docker-container.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitDockerContainerWorker() {
|
||||
integration.Register(&containerWorker{
|
||||
id: "docker-container",
|
||||
})
|
||||
}
|
||||
|
||||
type containerWorker struct {
|
||||
id string
|
||||
|
||||
unsupported []string
|
||||
|
||||
docker integration.Backend
|
||||
dockerClose func() error
|
||||
dockerErr error
|
||||
dockerOnce sync.Once
|
||||
}
|
||||
|
||||
func (w *containerWorker) Name() string {
|
||||
return w.id
|
||||
}
|
||||
|
||||
func (w *containerWorker) Rootless() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (integration.Backend, func() error, error) {
|
||||
w.dockerOnce.Do(func() {
|
||||
w.docker, w.dockerClose, w.dockerErr = dockerWorker{id: w.id}.New(ctx, cfg)
|
||||
})
|
||||
if w.dockerErr != nil {
|
||||
return w.docker, w.dockerClose, w.dockerErr
|
||||
}
|
||||
|
||||
name := "integration-container-" + identity.NewID()
|
||||
cmd := exec.Command("buildx", "create",
|
||||
"--bootstrap",
|
||||
"--name="+name,
|
||||
"--config="+cfg.ConfigFile,
|
||||
"--driver=docker-container",
|
||||
"--driver-opt=network=host",
|
||||
)
|
||||
cmd.Env = append(
|
||||
os.Environ(),
|
||||
"BUILDX_CONFIG=/tmp/buildx-"+name,
|
||||
"DOCKER_CONTEXT="+w.docker.DockerAddress(),
|
||||
)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||
}
|
||||
|
||||
cl := func() error {
|
||||
cmd := exec.Command("buildx", "rm", "-f", name)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
return &backend{
|
||||
context: w.docker.DockerAddress(),
|
||||
builder: name,
|
||||
unsupportedFeatures: w.unsupported,
|
||||
}, cl, nil
|
||||
}
|
||||
|
||||
func (w *containerWorker) Close() error {
|
||||
if close := w.dockerClose; close != nil {
|
||||
return close()
|
||||
}
|
||||
|
||||
// reset the worker to be ready to go again
|
||||
w.docker = nil
|
||||
w.dockerClose = nil
|
||||
w.dockerErr = nil
|
||||
w.dockerOnce = sync.Once{}
|
||||
|
||||
return nil
|
||||
}
|
||||
79
tests/workers/docker.go
Normal file
79
tests/workers/docker.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitDockerWorker() {
|
||||
integration.Register(&dockerWorker{
|
||||
id: "docker",
|
||||
})
|
||||
integration.Register(&dockerWorker{
|
||||
id: "docker+containerd",
|
||||
containerdSnapshotter: true,
|
||||
})
|
||||
}
|
||||
|
||||
type dockerWorker struct {
|
||||
id string
|
||||
containerdSnapshotter bool
|
||||
unsupported []string
|
||||
}
|
||||
|
||||
func (c dockerWorker) Name() string {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func (c dockerWorker) Rootless() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||
moby := bkworkers.Moby{
|
||||
ID: c.id,
|
||||
ContainerdSnapshotter: c.containerdSnapshotter,
|
||||
}
|
||||
bk, bkclose, err := moby.New(ctx, cfg)
|
||||
if err != nil {
|
||||
return bk, cl, err
|
||||
}
|
||||
|
||||
name := "integration-" + identity.NewID()
|
||||
cmd := exec.Command("docker", "context", "create",
|
||||
name,
|
||||
"--docker", "host="+bk.DockerAddress(),
|
||||
)
|
||||
cmd.Env = append(os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return bk, cl, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||
}
|
||||
|
||||
cl = func() error {
|
||||
var err error
|
||||
if err1 := bkclose(); err == nil {
|
||||
err = err1
|
||||
}
|
||||
cmd := exec.Command("docker", "context", "rm", "-f", name)
|
||||
if err1 := cmd.Run(); err1 != nil {
|
||||
err = errors.Wrapf(err1, "failed to remove buildx instance %s", name)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return &backend{
|
||||
builder: name,
|
||||
context: name,
|
||||
unsupportedFeatures: c.unsupported,
|
||||
}, cl, nil
|
||||
}
|
||||
|
||||
func (c dockerWorker) Close() error {
|
||||
return nil
|
||||
}
|
||||
13
tests/workers/features.go
Normal file
13
tests/workers/features.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
)
|
||||
|
||||
var features = map[string]struct{}{}
|
||||
|
||||
func CheckFeatureCompat(t *testing.T, sb integration.Sandbox, reason ...string) {
|
||||
integration.CheckFeatureCompat(t, sb, features, reason...)
|
||||
}
|
||||
72
tests/workers/remote.go
Normal file
72
tests/workers/remote.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/moby/buildkit/identity"
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func InitRemoteWorker() {
|
||||
integration.Register(&remoteWorker{
|
||||
id: "remote",
|
||||
})
|
||||
}
|
||||
|
||||
type remoteWorker struct {
|
||||
id string
|
||||
unsupported []string
|
||||
}
|
||||
|
||||
func (w remoteWorker) Name() string {
|
||||
return w.id
|
||||
}
|
||||
|
||||
func (w remoteWorker) Rootless() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||
oci := bkworkers.OCI{ID: w.id}
|
||||
bk, bkclose, err := oci.New(ctx, cfg)
|
||||
if err != nil {
|
||||
return bk, cl, err
|
||||
}
|
||||
|
||||
name := "integration-remote-" + identity.NewID()
|
||||
cmd := exec.Command("buildx", "create",
|
||||
"--bootstrap",
|
||||
"--name="+name,
|
||||
"--driver=remote",
|
||||
bk.Address(),
|
||||
)
|
||||
cmd.Env = append(os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||
}
|
||||
|
||||
cl = func() error {
|
||||
var err error
|
||||
if err1 := bkclose(); err == nil {
|
||||
err = err1
|
||||
}
|
||||
cmd := exec.Command("buildx", "rm", "-f", name)
|
||||
if err1 := cmd.Run(); err == nil {
|
||||
err = err1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return &backend{
|
||||
builder: name,
|
||||
unsupportedFeatures: w.unsupported,
|
||||
}, cl, nil
|
||||
}
|
||||
|
||||
func (w remoteWorker) Close() error {
|
||||
return nil
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func ParseAttests(in []string) ([]*controllerapi.Attest, error) {
|
||||
found := map[string]struct{}{}
|
||||
for _, in := range in {
|
||||
in := in
|
||||
attest, err := parseAttest(in)
|
||||
attest, err := ParseAttest(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -40,7 +40,7 @@ func ParseAttests(in []string) ([]*controllerapi.Attest, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func parseAttest(in string) (*controllerapi.Attest, error) {
|
||||
func ParseAttest(in string) (*controllerapi.Attest, error) {
|
||||
if in == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user