mirror of
https://github.com/docker/compose.git
synced 2026-02-13 12:09:29 +08:00
Compare commits
1 Commits
v2.33.0
...
network_ru
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa11db3a71 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +0,0 @@
|
||||
# global rules
|
||||
* @docker/compose-maintainers
|
||||
93
.github/workflows/ci.yml
vendored
93
.github/workflows/ci.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Run
|
||||
run: |
|
||||
@@ -71,45 +71,29 @@ jobs:
|
||||
matrix:
|
||||
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v6
|
||||
uses: docker/bake-action@v2
|
||||
with:
|
||||
source: .
|
||||
targets: release
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
set: |
|
||||
*.platform=${{ matrix.platform }}
|
||||
*.cache-from=type=gha,scope=binary-${{ env.PLATFORM_PAIR }}
|
||||
*.cache-to=type=gha,scope=binary-${{ env.PLATFORM_PAIR }},mode=max
|
||||
-
|
||||
name: Rename provenance and sbom
|
||||
working-directory: ./bin/release
|
||||
run: |
|
||||
binname=$(find . -name 'docker-compose-*')
|
||||
filename=$(basename "$binname" | sed -E 's/\.exe$//')
|
||||
mv "provenance.json" "${filename}.provenance.json"
|
||||
mv "sbom-binary.spdx.json" "${filename}.sbom.json"
|
||||
find . -name 'sbom*.json' -exec rm {} \;
|
||||
-
|
||||
name: List artifacts
|
||||
run: |
|
||||
tree -nh ./bin/release
|
||||
-
|
||||
name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -121,12 +105,15 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Test
|
||||
uses: docker/bake-action@v6
|
||||
uses: docker/bake-action@v2
|
||||
with:
|
||||
targets: test
|
||||
set: |
|
||||
@@ -154,19 +141,19 @@ jobs:
|
||||
- plugin
|
||||
- standalone
|
||||
engine:
|
||||
- 26
|
||||
- 27
|
||||
- 28
|
||||
- 24.0.9
|
||||
- 25.0.5
|
||||
- 26.1.4
|
||||
- 27.4.0
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
mode=${{ matrix.mode }}
|
||||
engine=${{ matrix.engine }}
|
||||
echo "MODE_ENGINE_PAIR=${mode}-${engine}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Docker ${{ matrix.engine }}
|
||||
run: |
|
||||
sudo systemctl stop docker.service
|
||||
@@ -174,24 +161,22 @@ jobs:
|
||||
sudo apt-get install curl
|
||||
curl -fsSL https://test.docker.com -o get-docker.sh
|
||||
sudo sh ./get-docker.sh --version ${{ matrix.engine }}
|
||||
|
||||
- name: Check Docker Version
|
||||
run: docker --version
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Set up Go
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
check-latest: true
|
||||
cache: true
|
||||
|
||||
- name: Build
|
||||
uses: docker/bake-action@v6
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v2
|
||||
with:
|
||||
source: .
|
||||
targets: binary-with-coverage
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=binary-linux-amd64
|
||||
@@ -199,37 +184,37 @@ jobs:
|
||||
*.cache-to=type=gha,scope=binary-e2e-${{ matrix.mode }},mode=max
|
||||
env:
|
||||
BUILD_TAGS: e2e
|
||||
|
||||
- name: Setup tmate session
|
||||
-
|
||||
name: Setup tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
uses: mxschmitt/action-tmate@8b4e4ac71822ed7e0ad5fb3d1c33483e9e8fb270 # v3.11
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Test plugin mode
|
||||
-
|
||||
name: Test plugin mode
|
||||
if: ${{ matrix.mode == 'plugin' }}
|
||||
run: |
|
||||
rm -rf ./bin/coverage/e2e
|
||||
mkdir -p ./bin/coverage/e2e
|
||||
make e2e-compose GOCOVERDIR=bin/coverage/e2e TEST_FLAGS="-v"
|
||||
|
||||
- name: Gather coverage data
|
||||
-
|
||||
name: Gather coverage data
|
||||
if: ${{ matrix.mode == 'plugin' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-data-e2e-${{ env.MODE_ENGINE_PAIR }}
|
||||
path: bin/coverage/e2e/
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Test standalone mode
|
||||
-
|
||||
name: Test standalone mode
|
||||
if: ${{ matrix.mode == 'standalone' }}
|
||||
run: |
|
||||
rm -f /usr/local/bin/docker-compose
|
||||
cp bin/build/docker-compose /usr/local/bin
|
||||
make e2e-compose-standalone
|
||||
|
||||
- name: e2e Test Summary
|
||||
-
|
||||
name: e2e Test Summary
|
||||
uses: test-summary/action@v2
|
||||
with:
|
||||
paths: /tmp/report/report.xml
|
||||
@@ -299,11 +284,7 @@ jobs:
|
||||
find . -type f -print0 | sort -z | xargs -r0 shasum -a 256 -b | sed 's# \*\./# *#' > $RUNNER_TEMP/checksums.txt
|
||||
shasum -a 256 -U -c $RUNNER_TEMP/checksums.txt
|
||||
mv $RUNNER_TEMP/checksums.txt .
|
||||
cat checksums.txt | while read sum file; do
|
||||
if [[ "${file#\*}" == docker-compose-* && "${file#\*}" != *.provenance.json && "${file#\*}" != *.sbom.json ]]; then
|
||||
echo "$sum $file" > ${file#\*}.sha256
|
||||
fi
|
||||
done
|
||||
cat checksums.txt | while read sum file; do echo "$sum $file" > ${file#\*}.sha256; done
|
||||
-
|
||||
name: License
|
||||
run: cp packaging/* ./bin/release/
|
||||
|
||||
2
.github/workflows/docs-upstream.yml
vendored
2
.github/workflows/docs-upstream.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
validate:
|
||||
uses: docker/docs/.github/workflows/validate-upstream.yml@main
|
||||
uses: docker/docs/.github/workflows/validate-upstream.yml@919a9b9104a34a40b30d116529bcce589a544d1c # pin for artifact v4 support: https://github.com/docker/docs/pull/19220
|
||||
needs:
|
||||
- docs-yaml
|
||||
with:
|
||||
|
||||
39
.github/workflows/merge.yml
vendored
39
.github/workflows/merge.yml
vendored
@@ -82,23 +82,16 @@ jobs:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
${{ env.REPO_SLUG }}
|
||||
@@ -106,22 +99,28 @@ jobs:
|
||||
type=ref,event=tag
|
||||
type=edge
|
||||
bake-target: meta-helper
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Build and push image
|
||||
uses: docker/bake-action@v6
|
||||
uses: docker/bake-action@v2
|
||||
id: bake
|
||||
with:
|
||||
source: .
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file }}
|
||||
targets: image-cross
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
sbom: true
|
||||
provenance: mode=max
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=bin-image
|
||||
*.cache-to=type=gha,scope=bin-image,mode=max
|
||||
*.attest=type=sbom
|
||||
*.attest=type=provenance,mode=max,builder-id=https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}
|
||||
|
||||
desktop-edge-test:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -130,16 +129,14 @@ jobs:
|
||||
-
|
||||
name: Generate Token
|
||||
id: generate_token
|
||||
uses: actions/create-github-app-token@v1
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app-id: ${{ vars.DOCKERDESKTOP_APP_ID }}
|
||||
private-key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
|
||||
owner: docker
|
||||
repositories: |
|
||||
${{ secrets.DOCKERDESKTOP_REPO }}
|
||||
app_id: ${{ vars.DOCKERDESKTOP_APP_ID }}
|
||||
private_key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
|
||||
repository: docker/${{ secrets.DOCKERDESKTOP_REPO }}
|
||||
-
|
||||
name: Trigger Docker Desktop e2e with edge version
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
script: |
|
||||
|
||||
8
.github/workflows/scorecards.yml
vendored
8
.github/workflows/scorecards.yml
vendored
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.4.2
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0
|
||||
uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # tag=v2.0.6
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # tag=v4.5.0
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -49,6 +49,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@3096afedf9873361b2b2f65e1445b13272c83eb8 # tag=v2.20.00
|
||||
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -5,13 +5,12 @@ linters:
|
||||
enable-all: false
|
||||
disable-all: true
|
||||
enable:
|
||||
- copyloopvar
|
||||
- depguard
|
||||
- errcheck
|
||||
- errorlint
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofumpt
|
||||
- gofmt
|
||||
- goimports
|
||||
- gomodguard
|
||||
- revive
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
### Prerequisites
|
||||
|
||||
* Windows:
|
||||
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
|
||||
* [Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-windows)
|
||||
* make
|
||||
* macOS:
|
||||
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/mac-install/)
|
||||
* [Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-mac)
|
||||
* make
|
||||
* Linux:
|
||||
* [Docker 20.10 or later](https://docs.docker.com/engine/install/)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Want to hack on Docker? Awesome! We have a contributor's guide that explains
|
||||
[setting up a Docker development environment and the contribution
|
||||
process](https://docs.docker.com/contribute/).
|
||||
process](https://docs.docker.com/contribute/overview/).
|
||||
|
||||
This page contains information about reporting issues as well as some tips and
|
||||
guidelines useful to experienced open source contributors. Finally, make sure
|
||||
@@ -95,7 +95,7 @@ don't get discouraged!
|
||||
<tr>
|
||||
<td>Community Slack</td>
|
||||
<td>
|
||||
The Docker Community has a dedicated Slack chat to discuss features and issues. You can sign-up <a href="https://www.docker.com/community/" target="_blank">with this link</a>.
|
||||
The Docker Community has a dedicated Slack chat to discuss features and issues. You can sign-up <a href="https://www.docker.com/docker-community" target="_blank">with this link</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -118,7 +118,7 @@ don't get discouraged!
|
||||
<td>Stack Overflow</td>
|
||||
<td>
|
||||
Stack Overflow has over 17000 Docker questions listed. We regularly
|
||||
monitor <a href="https://stackoverflow.com/questions/tagged/docker" target="_blank">Docker questions</a>
|
||||
monitor <a href="https://stackoverflow.com/search?tab=newest&q=docker" target="_blank">Docker questions</a>
|
||||
and so do many other knowledgeable Docker users.
|
||||
</td>
|
||||
</tr>
|
||||
@@ -200,7 +200,7 @@ For more details, see the [MAINTAINERS](MAINTAINERS) page.
|
||||
The sign-off is a simple line at the end of the explanation for the patch. Your
|
||||
signature certifies that you wrote the patch or otherwise have the right to pass
|
||||
it on as an open-source patch. The rules are pretty simple: if you can certify
|
||||
the below (from [developercertificate.org](https://developercertificate.org/)):
|
||||
the below (from [developercertificate.org](http://developercertificate.org/)):
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
@@ -252,7 +252,7 @@ commit automatically with `git commit -s`.
|
||||
### How can I become a maintainer?
|
||||
|
||||
The procedures for adding new maintainers are explained in the global
|
||||
[MAINTAINERS](https://github.com/docker/opensource/blob/main/MAINTAINERS)
|
||||
[MAINTAINERS](https://github.com/docker/opensource/blob/master/MAINTAINERS)
|
||||
file in the
|
||||
[https://github.com/docker/opensource/](https://github.com/docker/opensource/)
|
||||
repository.
|
||||
@@ -311,8 +311,8 @@ The rules:
|
||||
2. All code should pass the default levels of
|
||||
[`golint`](https://github.com/golang/lint).
|
||||
3. All code should follow the guidelines covered in [Effective
|
||||
Go](https://go.dev/doc/effective_go) and [Go Code Review
|
||||
Comments](https://go.dev/wiki/CodeReviewComments).
|
||||
Go](http://golang.org/doc/effective_go.html) and [Go Code Review
|
||||
Comments](https://github.com/golang/go/wiki/CodeReviewComments).
|
||||
4. Include code comments. Tell us the why, the history and the context.
|
||||
5. Document _all_ declarations and methods, even private ones. Declare
|
||||
expectations, caveats and anything else that may be important. If a type
|
||||
@@ -334,6 +334,6 @@ The rules:
|
||||
guidelines. Since you've read all the rules, you now know that.
|
||||
|
||||
If you are having trouble getting into the mood of idiomatic Go, we recommend
|
||||
reading through [Effective Go](https://go.dev/doc/effective_go). The
|
||||
[Go Blog](https://go.dev/blog/) is also a great resource. Drinking the
|
||||
reading through [Effective Go](https://golang.org/doc/effective_go.html). The
|
||||
[Go Blog](https://blog.golang.org) is also a great resource. Drinking the
|
||||
kool-aid is a lot easier than going thirsty.
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARG GO_VERSION=1.22.10
|
||||
ARG XX_VERSION=1.6.1
|
||||
ARG GOLANGCI_LINT_VERSION=v1.63.4
|
||||
ARG GO_VERSION=1.22.8
|
||||
ARG XX_VERSION=1.2.1
|
||||
ARG GOLANGCI_LINT_VERSION=v1.60.2
|
||||
ARG ADDLICENSE_VERSION=v1.0.0
|
||||
|
||||
ARG BUILD_TAGS="e2e"
|
||||
|
||||
5
Makefile
5
Makefile
@@ -116,11 +116,6 @@ cache-clear: ## Clear the builder cache
|
||||
lint: ## run linter(s)
|
||||
$(BUILDX_CMD) bake lint
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
gofumpt --version >/dev/null 2>&1 || go install mvdan.cc/gofumpt@latest
|
||||
gofumpt -w .
|
||||
|
||||
.PHONY: docs
|
||||
docs: ## generate documentation
|
||||
$(eval $@_TMP_OUT := $(shell mktemp -d -t compose-output.XXXXXXXXXX))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- [Legacy](#legacy)
|
||||
# Docker Compose v2
|
||||
|
||||
[](https://github.com/docker/compose/releases/latest)
|
||||
[](https://github.com/docker/compose/releases/latest)
|
||||
[](https://pkg.go.dev/github.com/docker/compose/v2)
|
||||
[](https://github.com/docker/compose/actions?query=workflow%3Aci)
|
||||
[](https://goreportcard.com/report/github.com/docker/compose/v2)
|
||||
@@ -28,7 +28,7 @@ single command: `docker compose up`.
|
||||
### Windows and macOS
|
||||
|
||||
Docker Compose is included in
|
||||
[Docker Desktop](https://www.docker.com/products/docker-desktop/)
|
||||
[Docker Desktop](https://www.docker.com/products/docker-desktop)
|
||||
for Windows and macOS.
|
||||
|
||||
### Linux
|
||||
|
||||
@@ -55,6 +55,7 @@ func Setup(cmd *cobra.Command, dockerCli command.Cli, args []string) error {
|
||||
ctx,
|
||||
"cli/"+strings.Join(commandName(cmd), "-"),
|
||||
)
|
||||
cmdSpan.SetAttributes(attribute.StringSlice("cli.args", args))
|
||||
cmdSpan.SetAttributes(attribute.StringSlice("cli.flags", getFlags(cmd.Flags())))
|
||||
|
||||
cmd.SetContext(ctx)
|
||||
|
||||
@@ -60,4 +60,5 @@ func TestGetFlags(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
package compatibility
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
@@ -27,10 +24,9 @@ import (
|
||||
|
||||
func Test_convert(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
want []string
|
||||
wantErr bool
|
||||
name string
|
||||
args []string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "compose only",
|
||||
@@ -97,36 +93,11 @@ func Test_convert(t *testing.T) {
|
||||
args: []string{"--project-name", "compose", "down", "--remove-orphans"},
|
||||
want: []string{"compose", "--project-name", "compose", "down", "--remove-orphans"},
|
||||
},
|
||||
{
|
||||
name: "completion command",
|
||||
args: []string{"__complete", "up"},
|
||||
want: []string{"__complete", "compose", "up"},
|
||||
},
|
||||
{
|
||||
name: "string flag without argument",
|
||||
args: []string{"--log-level"},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantErr {
|
||||
if os.Getenv("BE_CRASHER") == "1" {
|
||||
Convert(tt.args)
|
||||
return
|
||||
}
|
||||
cmd := exec.Command(os.Args[0], "-test.run=^"+t.Name()+"$")
|
||||
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
|
||||
err := cmd.Run()
|
||||
var e *exec.ExitError
|
||||
if errors.As(err, &e) && !e.Success() {
|
||||
return
|
||||
}
|
||||
t.Fatalf("process ran with err %v, want exit status 1", err)
|
||||
} else {
|
||||
got := Convert(tt.args)
|
||||
assert.DeepEqual(t, tt.want, got)
|
||||
}
|
||||
got := Convert(tt.args)
|
||||
assert.DeepEqual(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import (
|
||||
"github.com/docker/compose/v2/internal/experimental"
|
||||
"github.com/docker/compose/v2/internal/tracing"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/compose"
|
||||
ui "github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/remote"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
@@ -120,9 +121,17 @@ func AdaptCmd(fn CobraCommand) func(cmd *cobra.Command, args []string) error {
|
||||
}()
|
||||
|
||||
err := fn(ctx, cmd, args)
|
||||
var composeErr compose.Error
|
||||
if api.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {
|
||||
err = dockercli.StatusError{
|
||||
StatusCode: 130,
|
||||
Status: compose.CanceledStatus,
|
||||
}
|
||||
}
|
||||
if errors.As(err, &composeErr) {
|
||||
err = dockercli.StatusError{
|
||||
StatusCode: composeErr.GetMetricsFailureCategory().ExitCode,
|
||||
Status: err.Error(),
|
||||
}
|
||||
}
|
||||
if ui.Mode == ui.ModeJSON {
|
||||
@@ -298,7 +307,7 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
|
||||
|
||||
options, err := o.toProjectOptions(po...)
|
||||
if err != nil {
|
||||
return nil, metrics, err
|
||||
return nil, metrics, compose.WrapComposeError(err)
|
||||
}
|
||||
|
||||
options.WithListeners(func(event string, metadata map[string]any) {
|
||||
@@ -330,7 +339,7 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
|
||||
|
||||
project, err := options.LoadProject(ctx)
|
||||
if err != nil {
|
||||
return nil, metrics, err
|
||||
return nil, metrics, compose.WrapComposeError(err)
|
||||
}
|
||||
|
||||
if project.Name == "" {
|
||||
@@ -444,7 +453,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
|
||||
}
|
||||
_ = cmd.Help()
|
||||
return dockercli.StatusError{
|
||||
StatusCode: 1,
|
||||
StatusCode: compose.CommandSyntaxFailure.ExitCode,
|
||||
Status: fmt.Sprintf("unknown docker command: %q", "compose "+args[0]),
|
||||
}
|
||||
},
|
||||
|
||||
@@ -348,6 +348,7 @@ func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) err
|
||||
}
|
||||
|
||||
hash, err := compose.ServiceHash(s)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ type createOptions struct {
|
||||
timeout int
|
||||
quietPull bool
|
||||
scale []string
|
||||
AssumeYes bool
|
||||
}
|
||||
|
||||
func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
|
||||
@@ -81,7 +80,6 @@ func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
|
||||
flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
|
||||
flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
|
||||
flags.StringArrayVar(&opts.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
|
||||
flags.BoolVarP(&opts.AssumeYes, "y", "y", false, `Assume "yes" as answer to all prompts and run non-interactively`)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -109,7 +107,6 @@ func runCreate(ctx context.Context, _ command.Cli, backend api.Service, createOp
|
||||
Inherit: !createOpts.noInherit,
|
||||
Timeout: createOpts.GetTimeout(),
|
||||
QuietPull: createOpts.quietPull,
|
||||
AssumeYes: createOpts.AssumeYes,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -198,9 +195,7 @@ func applyScaleOpts(project *types.Project, opts []string) error {
|
||||
}
|
||||
|
||||
func (opts createOptions) isPullPolicyValid() bool {
|
||||
pullPolicies := []string{
|
||||
types.PullPolicyAlways, types.PullPolicyNever, types.PullPolicyBuild,
|
||||
types.PullPolicyMissing, types.PullPolicyIfNotPresent,
|
||||
}
|
||||
pullPolicies := []string{types.PullPolicyAlways, types.PullPolicyNever, types.PullPolicyBuild,
|
||||
types.PullPolicyMissing, types.PullPolicyIfNotPresent}
|
||||
return slices.Contains(pullPolicies, opts.Pull)
|
||||
}
|
||||
|
||||
@@ -40,9 +40,7 @@ func TestRunCreate(t *testing.T) {
|
||||
)
|
||||
|
||||
createOpts := createOptions{}
|
||||
buildOpts := buildOptions{
|
||||
ProjectOptions: &ProjectOptions{},
|
||||
}
|
||||
buildOpts := buildOptions{}
|
||||
project := sampleProject()
|
||||
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
|
||||
require.NoError(t, err)
|
||||
@@ -60,9 +58,7 @@ func TestRunCreate_Build(t *testing.T) {
|
||||
createOpts := createOptions{
|
||||
Build: true,
|
||||
}
|
||||
buildOpts := buildOptions{
|
||||
ProjectOptions: &ProjectOptions{},
|
||||
}
|
||||
buildOpts := buildOptions{}
|
||||
project := sampleProject()
|
||||
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -50,7 +50,7 @@ func listCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {
|
||||
ValidArgsFunction: noCompletion(),
|
||||
}
|
||||
lsCmd.Flags().StringVar(&lsOpts.Format, "format", "table", "Format the output. Values: [table | json]")
|
||||
lsCmd.Flags().BoolVarP(&lsOpts.Quiet, "quiet", "q", false, "Only display project names")
|
||||
lsCmd.Flags().BoolVarP(&lsOpts.Quiet, "quiet", "q", false, "Only display IDs")
|
||||
lsCmd.Flags().Var(&lsOpts.Filter, "filter", "Filter output based on conditions provided")
|
||||
lsCmd.Flags().BoolVarP(&lsOpts.All, "all", "a", false, "Show all stopped Compose projects")
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ type publishOptions struct {
|
||||
*ProjectOptions
|
||||
resolveImageDigests bool
|
||||
ociVersion string
|
||||
withEnvironment bool
|
||||
assumeYes bool
|
||||
}
|
||||
|
||||
func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
|
||||
@@ -47,10 +45,7 @@ func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
|
||||
}
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests")
|
||||
flags.StringVar(&opts.ociVersion, "oci-version", "", "OCI image/artifact specification version (automatically determined by default)")
|
||||
flags.BoolVar(&opts.withEnvironment, "with-env", false, "Include environment variables in the published OCI artifact")
|
||||
flags.BoolVarP(&opts.assumeYes, "y", "y", false, `Assume "yes" as answer to all prompts`)
|
||||
|
||||
flags.StringVar(&opts.ociVersion, "oci-version", "", "OCI Image/Artifact specification version (automatically determined by default)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -63,7 +58,5 @@ func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Service,
|
||||
return backend.Publish(ctx, project, repository, api.PublishOptions{
|
||||
ResolveImageDigests: opts.resolveImageDigests,
|
||||
OCIVersion: api.OCIVersion(opts.ociVersion),
|
||||
WithEnvironment: opts.withEnvironment,
|
||||
AssumeYes: opts.assumeYes,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -154,7 +154,6 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
|
||||
options.noTty = !options.tty
|
||||
}
|
||||
}
|
||||
createOpts.pullChanged = cmd.Flags().Changed("pull")
|
||||
return nil
|
||||
}),
|
||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||
@@ -189,7 +188,6 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
|
||||
flags.StringArrayVarP(&options.publish, "publish", "p", []string{}, "Publish a container's port(s) to the host")
|
||||
flags.BoolVar(&options.useAliases, "use-aliases", false, "Use the service's network useAliases in the network(s) the container connects to")
|
||||
flags.BoolVarP(&options.servicePorts, "service-ports", "P", false, "Run command with all service's ports enabled and mapped to the host")
|
||||
flags.StringVar(&createOpts.Pull, "pull", "policy", `Pull image before running ("always"|"missing"|"never")`)
|
||||
flags.BoolVar(&options.quietPull, "quiet-pull", false, "Pull without printing progress information")
|
||||
flags.BoolVar(&createOpts.Build, "build", false, "Build image before starting container")
|
||||
flags.BoolVar(&options.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
|
||||
|
||||
@@ -92,6 +92,7 @@ func parseServicesReplicasArgs(args []string) (map[string]int, error) {
|
||||
return nil, fmt.Errorf("invalid scale specifier: %s", arg)
|
||||
}
|
||||
intValue, err := strconv.Atoi(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid scale specifier: can't parse replica value as int: %v", arg)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func statsCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
|
||||
'table TEMPLATE': Print output in table format using the given Go template
|
||||
'json': Print in JSON format
|
||||
'TEMPLATE': Print output using the given Go template.
|
||||
Refer to https://docs.docker.com/engine/cli/formatting/ for more information about formatting output with templates`)
|
||||
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates`)
|
||||
flags.BoolVar(&opts.noStream, "no-stream", false, "Disable streaming stats and only pull the first result")
|
||||
flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate output")
|
||||
return cmd
|
||||
|
||||
@@ -145,7 +145,6 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *c
|
||||
flags := upCmd.Flags()
|
||||
flags.BoolVarP(&up.Detach, "detach", "d", false, "Detached mode: Run containers in the background")
|
||||
flags.BoolVar(&create.Build, "build", false, "Build images before starting containers")
|
||||
flags.BoolVarP(&create.AssumeYes, "y", "y", false, `Assume "yes" as answer to all prompts and run non-interactively`)
|
||||
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's policy")
|
||||
flags.StringVar(&create.Pull, "pull", "policy", `Pull image before running ("always"|"missing"|"never")`)
|
||||
flags.BoolVar(&create.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
|
||||
@@ -256,7 +255,6 @@ func runUp(
|
||||
Inherit: !createOptions.noInherit,
|
||||
Timeout: createOptions.GetTimeout(),
|
||||
QuietPull: createOptions.quietPull,
|
||||
AssumeYes: createOptions.AssumeYes,
|
||||
}
|
||||
|
||||
if upOptions.noStart {
|
||||
|
||||
@@ -47,4 +47,5 @@ func TestApplyScaleOpt(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, *bar.Scale, 3)
|
||||
assert.Equal(t, *bar.Deploy.Replicas, 3)
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
|
||||
}
|
||||
|
||||
func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, watchOpts watchOptions, buildOpts buildOptions, services []string) error {
|
||||
project, _, err := watchOpts.ToProject(ctx, dockerCli, services)
|
||||
project, _, err := watchOpts.ToProject(ctx, dockerCli, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -27,49 +27,42 @@ var disableAnsi bool
|
||||
func ansi(code string) string {
|
||||
return fmt.Sprintf("\033%s", code)
|
||||
}
|
||||
|
||||
func SaveCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("7"))
|
||||
}
|
||||
|
||||
func RestoreCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("8"))
|
||||
}
|
||||
|
||||
func HideCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("[?25l"))
|
||||
}
|
||||
|
||||
func ShowCursor() {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi("[?25h"))
|
||||
}
|
||||
|
||||
func MoveCursor(y, x int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi(fmt.Sprintf("[%d;%dH", y, x)))
|
||||
}
|
||||
|
||||
func MoveCursorX(pos int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
}
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dG", pos)))
|
||||
}
|
||||
|
||||
func ClearLine() {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -77,7 +70,6 @@ func ClearLine() {
|
||||
// Does not move cursor from its current position
|
||||
fmt.Print(ansi("[2K"))
|
||||
}
|
||||
|
||||
func MoveCursorUp(lines int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -85,7 +77,6 @@ func MoveCursorUp(lines int) {
|
||||
// Does not add new lines
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dA", lines)))
|
||||
}
|
||||
|
||||
func MoveCursorDown(lines int) {
|
||||
if disableAnsi {
|
||||
return
|
||||
@@ -93,12 +84,10 @@ func MoveCursorDown(lines int) {
|
||||
// Does not add new lines
|
||||
fmt.Print(ansi(fmt.Sprintf("[%dB", lines)))
|
||||
}
|
||||
|
||||
func NewLine() {
|
||||
// Like \n
|
||||
fmt.Print("\012")
|
||||
}
|
||||
|
||||
func lenAnsi(s string) int {
|
||||
// len has into consideration ansi codes, if we want
|
||||
// the len of the actual len(string) we need to strip
|
||||
|
||||
@@ -104,12 +104,10 @@ func makeColorFunc(code string) colorFunc {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
nextColor = rainbowColor
|
||||
rainbow []colorFunc
|
||||
currentIndex = 0
|
||||
mutex sync.Mutex
|
||||
)
|
||||
var nextColor = rainbowColor
|
||||
var rainbow []colorFunc
|
||||
var currentIndex = 0
|
||||
var mutex sync.Mutex
|
||||
|
||||
func rainbowColor() colorFunc {
|
||||
mutex.Lock()
|
||||
|
||||
@@ -110,10 +110,8 @@ type LogKeyboard struct {
|
||||
signalChannel chan<- os.Signal
|
||||
}
|
||||
|
||||
var (
|
||||
KeyboardManager *LogKeyboard
|
||||
eg multierror.Group
|
||||
)
|
||||
var KeyboardManager *LogKeyboard
|
||||
var eg multierror.Group
|
||||
|
||||
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured bool,
|
||||
sc chan<- os.Signal,
|
||||
@@ -208,7 +206,7 @@ func (lk *LogKeyboard) navigationMenu() string {
|
||||
if openDDInfo != "" || openDDUI != "" {
|
||||
watchInfo = navColor(" ")
|
||||
}
|
||||
isEnabled := " Enable"
|
||||
var isEnabled = " Enable"
|
||||
if lk.Watch.Watching {
|
||||
isEnabled = " Disable"
|
||||
}
|
||||
@@ -262,7 +260,6 @@ func (lk *LogKeyboard) openDDComposeUI(ctx context.Context, project *types.Proje
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func (lk *LogKeyboard) openDDWatchDocs(ctx context.Context, project *types.Project) {
|
||||
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/watch", tracing.SpanOptions{},
|
||||
func(ctx context.Context) error {
|
||||
@@ -307,15 +304,10 @@ func (lk *LogKeyboard) StartWatch(ctx context.Context, doneCh chan bool, project
|
||||
lk.Watch.newContext(ctx)
|
||||
buildOpts := *options.Create.Build
|
||||
buildOpts.Quiet = true
|
||||
err := lk.Watch.WatchFn(lk.Watch.Ctx, doneCh, project, options.Start.Services, api.WatchOptions{
|
||||
return lk.Watch.WatchFn(lk.Watch.Ctx, doneCh, project, options.Start.Services, api.WatchOptions{
|
||||
Build: &buildOpts,
|
||||
LogTo: options.Start.Attach,
|
||||
})
|
||||
if err != nil {
|
||||
lk.Watch.switchWatching()
|
||||
options.Start.Attach.Err(api.WatchLogger, err.Error())
|
||||
}
|
||||
return err
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func pluginMain() {
|
||||
|
||||
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
|
||||
return dockercli.StatusError{
|
||||
StatusCode: 1,
|
||||
StatusCode: compose.CommandSyntaxFailure.ExitCode,
|
||||
Status: err.Error(),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -8,10 +8,8 @@ Publish compose application
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:---------|:--------|:-------------------------------------------------------------------------------|
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--oci-version` | `string` | | OCI image/artifact specification version (automatically determined by default) |
|
||||
| `--oci-version` | `string` | | OCI Image/Artifact specification version (automatically determined by default) |
|
||||
| `--resolve-image-digests` | `bool` | | Pin image tags to digests |
|
||||
| `--with-env` | `bool` | | Include environment variables in the published OCI artifact |
|
||||
| `-y`, `--y` | `bool` | | Assume "yes" as answer to all prompts |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
Services are built once and then tagged, by default as `project-service`.
|
||||
|
||||
If the Compose file specifies an
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/main/spec.md#image) name,
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/master/spec.md#image) name,
|
||||
the image is tagged with that name, substituting any variables beforehand. See
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/spec.md#interpolation).
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/master/spec.md#interpolation).
|
||||
|
||||
If you change a service's `Dockerfile` or the contents of its build directory,
|
||||
run `docker compose build` to rebuild it.
|
||||
@@ -34,9 +34,9 @@ run `docker compose build` to rebuild it.
|
||||
Services are built once and then tagged, by default as `project-service`.
|
||||
|
||||
If the Compose file specifies an
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/main/spec.md#image) name,
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/master/spec.md#image) name,
|
||||
the image is tagged with that name, substituting any variables beforehand. See
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/spec.md#interpolation).
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/master/spec.md#interpolation).
|
||||
|
||||
If you change a service's `Dockerfile` or the contents of its build directory,
|
||||
run `docker compose build` to rebuild it.
|
||||
|
||||
@@ -16,7 +16,6 @@ Creates containers for a service
|
||||
| `--quiet-pull` | `bool` | | Pull without printing progress information |
|
||||
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
|
||||
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
|
||||
| `-y`, `--y` | `bool` | | Assume "yes" as answer to all prompts and run non-interactively |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -11,7 +11,7 @@ Lists running Compose projects
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--filter` | `filter` | | Filter output based on conditions provided |
|
||||
| `--format` | `string` | `table` | Format the output. Values: [table \| json] |
|
||||
| `-q`, `--quiet` | `bool` | | Only display project names |
|
||||
| `-q`, `--quiet` | `bool` | | Only display IDs |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -9,8 +9,8 @@ after a container is built, but before the container's command is executed) are
|
||||
after restarting.
|
||||
|
||||
If you are looking to configure a service's restart policy, refer to
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/main/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/main/deploy.md#restart_policy).
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/master/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
|
||||
|
||||
### Options
|
||||
|
||||
@@ -33,5 +33,5 @@ after a container is built, but before the container's command is executed) are
|
||||
after restarting.
|
||||
|
||||
If you are looking to configure a service's restart policy, refer to
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/main/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/main/deploy.md#restart_policy).
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/master/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
|
||||
|
||||
@@ -57,30 +57,29 @@ specified in the service configuration.
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------|:--------------|:---------|:---------------------------------------------------------------------------------|
|
||||
| `--build` | `bool` | | Build image before starting container |
|
||||
| `--cap-add` | `list` | | Add Linux capabilities |
|
||||
| `--cap-drop` | `list` | | Drop Linux capabilities |
|
||||
| `-d`, `--detach` | `bool` | | Run container in background and print container ID |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
||||
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
||||
| `--name` | `string` | | Assign a name to the container |
|
||||
| `-T`, `--no-TTY` | `bool` | `true` | Disable pseudo-TTY allocation (default: auto-detected) |
|
||||
| `--no-deps` | `bool` | | Don't start linked services |
|
||||
| `-p`, `--publish` | `stringArray` | | Publish a container's port(s) to the host |
|
||||
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") |
|
||||
| `--quiet-pull` | `bool` | | Pull without printing progress information |
|
||||
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
|
||||
| `--rm` | `bool` | | Automatically remove the container when it exits |
|
||||
| `-P`, `--service-ports` | `bool` | | Run command with all service's ports enabled and mapped to the host |
|
||||
| `--use-aliases` | `bool` | | Use the service's network useAliases in the network(s) the container connects to |
|
||||
| `-u`, `--user` | `string` | | Run as specified username or uid |
|
||||
| `-v`, `--volume` | `stringArray` | | Bind mount a volume |
|
||||
| `-w`, `--workdir` | `string` | | Working directory inside the container |
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------|:--------------|:--------|:---------------------------------------------------------------------------------|
|
||||
| `--build` | `bool` | | Build image before starting container |
|
||||
| `--cap-add` | `list` | | Add Linux capabilities |
|
||||
| `--cap-drop` | `list` | | Drop Linux capabilities |
|
||||
| `-d`, `--detach` | `bool` | | Run container in background and print container ID |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
||||
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
||||
| `--name` | `string` | | Assign a name to the container |
|
||||
| `-T`, `--no-TTY` | `bool` | `true` | Disable pseudo-TTY allocation (default: auto-detected) |
|
||||
| `--no-deps` | `bool` | | Don't start linked services |
|
||||
| `-p`, `--publish` | `stringArray` | | Publish a container's port(s) to the host |
|
||||
| `--quiet-pull` | `bool` | | Pull without printing progress information |
|
||||
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
|
||||
| `--rm` | `bool` | | Automatically remove the container when it exits |
|
||||
| `-P`, `--service-ports` | `bool` | | Run command with all service's ports enabled and mapped to the host |
|
||||
| `--use-aliases` | `bool` | | Use the service's network useAliases in the network(s) the container connects to |
|
||||
| `-u`, `--user` | `string` | | Run as specified username or uid |
|
||||
| `-v`, `--volume` | `stringArray` | | Bind mount a volume |
|
||||
| `-w`, `--workdir` | `string` | | Working directory inside the container |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -5,13 +5,13 @@ Display a live stream of container(s) resource usage statistics
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------|:---------|:--------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `-a`, `--all` | `bool` | | Show all containers (default shows just running) |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--format` | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/engine/cli/formatting/ for more information about formatting output with templates |
|
||||
| `--no-stream` | `bool` | | Disable streaming stats and only pull the first result |
|
||||
| `--no-trunc` | `bool` | | Do not truncate output |
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `-a`, `--all` | `bool` | | Show all containers (default shows just running) |
|
||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||
| `--format` | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
||||
| `--no-stream` | `bool` | | Disable streaming stats and only pull the first result |
|
||||
| `--no-trunc` | `bool` | | Do not truncate output |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -53,7 +53,6 @@ If the process is interrupted using `SIGINT` (ctrl + C) or `SIGTERM`, the contai
|
||||
| `--wait` | `bool` | | Wait for services to be running\|healthy. Implies detached mode. |
|
||||
| `--wait-timeout` | `int` | `0` | Maximum duration in seconds to wait for the project to be running\|healthy |
|
||||
| `-w`, `--watch` | `bool` | | Watch source code and rebuild/refresh containers when files are updated. |
|
||||
| `-y`, `--y` | `bool` | | Assume "yes" as answer to all prompts and run non-interactively |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
||||
@@ -8,7 +8,7 @@ options:
|
||||
- option: oci-version
|
||||
value_type: string
|
||||
description: |
|
||||
OCI image/artifact specification version (automatically determined by default)
|
||||
OCI Image/Artifact specification version (automatically determined by default)
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
@@ -25,27 +25,6 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: with-env
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Include environment variables in the published OCI artifact
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: "y"
|
||||
shorthand: "y"
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Assume "yes" as answer to all prompts
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
|
||||
@@ -4,9 +4,9 @@ long: |-
|
||||
Services are built once and then tagged, by default as `project-service`.
|
||||
|
||||
If the Compose file specifies an
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/main/spec.md#image) name,
|
||||
[image](https://github.com/compose-spec/compose-spec/blob/master/spec.md#image) name,
|
||||
the image is tagged with that name, substituting any variables beforehand. See
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/spec.md#interpolation).
|
||||
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/master/spec.md#interpolation).
|
||||
|
||||
If you change a service's `Dockerfile` or the contents of its build directory,
|
||||
run `docker compose build` to rebuild it.
|
||||
|
||||
@@ -88,17 +88,6 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: "y"
|
||||
shorthand: "y"
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Assume "yes" as answer to all prompts and run non-interactively
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
|
||||
@@ -39,7 +39,7 @@ options:
|
||||
shorthand: q
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Only display project names
|
||||
description: Only display IDs
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
|
||||
@@ -9,8 +9,8 @@ long: |-
|
||||
after restarting.
|
||||
|
||||
If you are looking to configure a service's restart policy, refer to
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/main/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/main/deploy.md#restart_policy).
|
||||
[restart](https://github.com/compose-spec/compose-spec/blob/master/spec.md#restart)
|
||||
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
|
||||
usage: docker compose restart [OPTIONS] [SERVICE...]
|
||||
pname: docker compose
|
||||
plink: docker_compose.yaml
|
||||
|
||||
@@ -180,16 +180,6 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: pull
|
||||
value_type: string
|
||||
default_value: policy
|
||||
description: Pull image before running ("always"|"missing"|"never")
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: quiet-pull
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
|
||||
@@ -24,7 +24,7 @@ options:
|
||||
'table TEMPLATE': Print output in table format using the given Go template
|
||||
'json': Print in JSON format
|
||||
'TEMPLATE': Print output using the given Go template.
|
||||
Refer to https://docs.docker.com/engine/cli/formatting/ for more information about formatting output with templates
|
||||
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
|
||||
@@ -309,17 +309,6 @@ options:
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
- option: "y"
|
||||
shorthand: "y"
|
||||
value_type: bool
|
||||
default_value: "false"
|
||||
description: Assume "yes" as answer to all prompts and run non-interactively
|
||||
deprecated: false
|
||||
hidden: false
|
||||
experimental: false
|
||||
experimentalcli: false
|
||||
kubernetes: false
|
||||
swarm: false
|
||||
inherited_options:
|
||||
- option: dry-run
|
||||
value_type: bool
|
||||
|
||||
166
go.mod
166
go.mod
@@ -1,21 +1,21 @@
|
||||
module github.com/docker/compose/v2
|
||||
|
||||
go 1.22.10
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/Microsoft/go-winio v0.6.2
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/buger/goterm v1.0.4
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8
|
||||
github.com/containerd/containerd/v2 v2.0.2
|
||||
github.com/containerd/platforms v1.0.0-rc.1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/compose-spec/compose-go/v2 v2.4.5-0.20241111154218-9d02caaf8465
|
||||
github.com/containerd/containerd v1.7.23
|
||||
github.com/containerd/platforms v0.2.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/buildx v0.20.1
|
||||
github.com/docker/cli v27.5.1+incompatible
|
||||
github.com/docker/cli-docs-tool v0.9.0
|
||||
github.com/docker/docker v27.5.1+incompatible
|
||||
github.com/docker/buildx v0.18.0
|
||||
github.com/docker/cli v27.4.0-rc.2+incompatible
|
||||
github.com/docker/cli-docs-tool v0.8.0
|
||||
github.com/docker/docker v27.4.0-rc.2+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
|
||||
@@ -23,74 +23,72 @@ require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-version v1.7.0
|
||||
github.com/jonboulle/clockwork v0.5.0
|
||||
github.com/jonboulle/clockwork v0.4.0
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/mitchellh/go-ps v1.0.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/buildkit v0.19.0
|
||||
github.com/moby/buildkit v0.17.1
|
||||
github.com/moby/patternmatcher v0.6.0
|
||||
github.com/moby/term v0.5.2
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/morikuni/aec v1.0.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0
|
||||
github.com/otiai10/copy v1.14.1
|
||||
github.com/otiai10/copy v1.14.0
|
||||
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/theupdateframework/notary v0.7.0
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0
|
||||
go.opentelemetry.io/otel v1.31.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0
|
||||
go.opentelemetry.io/otel/metric v1.31.0
|
||||
go.opentelemetry.io/otel/sdk v1.31.0
|
||||
go.opentelemetry.io/otel/trace v1.31.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1
|
||||
go.opentelemetry.io/otel v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
|
||||
go.opentelemetry.io/otel/metric v1.21.0
|
||||
go.opentelemetry.io/otel/sdk v1.21.0
|
||||
go.opentelemetry.io/otel/trace v1.21.0
|
||||
go.uber.org/goleak v1.3.0
|
||||
go.uber.org/mock v0.5.0
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
|
||||
golang.org/x/sync v0.11.0
|
||||
golang.org/x/sys v0.30.0
|
||||
google.golang.org/grpc v1.68.1
|
||||
golang.org/x/sync v0.9.0
|
||||
golang.org/x/sys v0.27.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools/v3 v3.5.2
|
||||
gotest.tools/v3 v3.5.1
|
||||
tags.cncf.io/container-device-interface v0.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect
|
||||
github.com/aws/smithy-go v1.20.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
|
||||
github.com/aws/smithy-go v1.19.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/console v1.0.4 // indirect
|
||||
github.com/containerd/containerd/api v1.8.0 // indirect
|
||||
github.com/containerd/continuity v0.4.5 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/containerd/api v1.7.19 // indirect
|
||||
github.com/containerd/continuity v0.4.4 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/containerd/ttrpc v1.2.5 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
@@ -98,12 +96,11 @@ require (
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
@@ -114,7 +111,7 @@ require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
@@ -128,31 +125,31 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.4.0 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/capability v0.4.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.1 // indirect
|
||||
github.com/moby/sys/symlink v0.3.0 // indirect
|
||||
github.com/moby/sys/symlink v0.2.0 // indirect
|
||||
github.com/moby/sys/user v0.3.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/otiai10/mint v1.6.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.17.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
@@ -160,41 +157,40 @@ require (
|
||||
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250113203817-b14e27f4135a // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c // indirect
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 // indirect
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect
|
||||
github.com/x448/float16 v0.8.4 // 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
|
||||
github.com/zclconf/go-cty v1.16.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/term v0.24.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/api v0.31.2 // indirect
|
||||
k8s.io/apimachinery v0.31.2 // indirect
|
||||
k8s.io/client-go v0.31.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
k8s.io/api v0.29.2 // indirect
|
||||
k8s.io/apimachinery v0.29.2 // indirect
|
||||
k8s.io/client-go v0.29.2 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
408
go.sum
408
go.sum
@@ -1,21 +1,25 @@
|
||||
cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM=
|
||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
||||
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2 h1:dIScnXFlF784X79oi7MzVT6GWqr/W1uUt0pB5CsDs9M=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2/go.mod h1:gCLVsLfv1egrcZu+GoJATN5ts75F2s62ih/457eWzOw=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
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/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
|
||||
github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
|
||||
github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
@@ -27,36 +31,34 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
|
||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ=
|
||||
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
|
||||
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
|
||||
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
|
||||
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
|
||||
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
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=
|
||||
@@ -73,72 +75,70 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
|
||||
github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8 h1:7Myl8wDRl/4mRz77S+eyDJymGGEHu0diQdGSSeyq90A=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.5-0.20241111154218-9d02caaf8465 h1:1PRX/3a/n4W2DrMJu4CV9OS8Z2eauOBLe0zOuSlrWDY=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.5-0.20241111154218-9d02caaf8465/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
|
||||
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
|
||||
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
|
||||
github.com/containerd/containerd/v2 v2.0.2 h1:GmH/tRBlTvrXOLwSpWE2vNAm8+MqI6nmxKpKBNKY8Wc=
|
||||
github.com/containerd/containerd/v2 v2.0.2/go.mod h1:wIqEvQ/6cyPFUGJ5yMFanspPabMLor+bF865OHvNTTI=
|
||||
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
|
||||
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
|
||||
github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
|
||||
github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
|
||||
github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig=
|
||||
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
|
||||
github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
|
||||
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/nydus-snapshotter v0.15.0 h1:RqZRs1GPeM6T3wmuxJV9u+2Rg4YETVMwTmiDeX+iWC8=
|
||||
github.com/containerd/nydus-snapshotter v0.15.0/go.mod h1:biq0ijpeZe0I5yZFSJyHzFSjjRZQ7P7y/OuHyd7hYOw=
|
||||
github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E=
|
||||
github.com/containerd/platforms v1.0.0-rc.1/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
|
||||
github.com/containerd/plugin v1.0.0 h1:c8Kf1TNl6+e2TtMHZt+39yAPDbouRH9WAToRjex483Y=
|
||||
github.com/containerd/plugin v1.0.0/go.mod h1:hQfJe5nmWfImiqT1q8Si3jLv3ynMUIBB47bQ+KexvO8=
|
||||
github.com/containerd/stargz-snapshotter v0.16.3 h1:zbQMm8dRuPHEOD4OqAYGajJJUwCeUzt4j7w9Iaw58u4=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
|
||||
github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ=
|
||||
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/containerd/nydus-snapshotter v0.14.0 h1:6/eAi6d7MjaeLLuMO8Udfe5GVsDudmrDNO4SGETMBco=
|
||||
github.com/containerd/nydus-snapshotter v0.14.0/go.mod h1:TT4jv2SnIDxEBu4H2YOvWQHPOap031ydTaHTuvc5VQk=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
||||
github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU=
|
||||
github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso=
|
||||
github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
|
||||
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
|
||||
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/buildx v0.20.1 h1:q88EfoYwrWEKVqNb9stOFq8fUlFp/OPlDcFE+QUYZBM=
|
||||
github.com/docker/buildx v0.20.1/go.mod h1:VVi4Nvo4jd/IkRvwyExbIyW7u82fivK61MRx5I0oKic=
|
||||
github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY=
|
||||
github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.9.0 h1:CVwQbE+ZziwlPqrJ7LRyUF6GvCA+6gj7MTCsayaK9t0=
|
||||
github.com/docker/cli-docs-tool v0.9.0/go.mod h1:ClrwlNW+UioiRyH9GiAOe1o3J/TsY3Tr1ipoypjAUtc=
|
||||
github.com/docker/buildx v0.18.0 h1:rSauXHeJt90NvtXrLK5J992Eb0UPJZs2vV3u1zTf1nE=
|
||||
github.com/docker/buildx v0.18.0/go.mod h1:JGNSshOhHs5FhG3u51jXUf4lLOeD2QBIlJ2vaRB67p4=
|
||||
github.com/docker/cli v27.4.0-rc.2+incompatible h1:A0GZwegDlt2wdt3tpmrUzkVOZmbhvd7i05wPSf7Oo74=
|
||||
github.com/docker/cli v27.4.0-rc.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU=
|
||||
github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8=
|
||||
github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v27.4.0-rc.2+incompatible h1:9OJjVGtelk/zGC3TyKweJ29b9Axzh0s/0vtU4mneumE=
|
||||
github.com/docker/docker v27.4.0-rc.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
@@ -146,6 +146,8 @@ github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
@@ -158,38 +160,36 @@ github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJ
|
||||
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c=
|
||||
github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-sql-driver/mysql v1.3.0 h1:pgwjLi/dvffoP9aabwkT3AKpXQM93QARkjFhDDqC1UE=
|
||||
github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
|
||||
@@ -199,6 +199,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY=
|
||||
github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -218,8 +220,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -227,10 +229,11 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -257,8 +260,8 @@ github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8c
|
||||
github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc=
|
||||
github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
|
||||
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||
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/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@@ -284,8 +287,6 @@ 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=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.5.3 h1:C8fxWnhYyME3n0klPOhVM7PtYUB3eV1W3DeFmN3j53Y=
|
||||
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -304,6 +305,8 @@ github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebG
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
@@ -316,16 +319,16 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
|
||||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
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.19.0 h1:w9G1p7sArvCGNkpWstAqJfRQTXBKukMyMK1bsah1HNo=
|
||||
github.com/moby/buildkit v0.19.0/go.mod h1:WiHBFTgWV8eB1AmPxIWsAlKjUACAwm3X/14xOV4VWew=
|
||||
github.com/moby/buildkit v0.17.1 h1:VWj6eIdk7u6acHPn2CiA+tdq0/mQoBEk9ckweRzWmPw=
|
||||
github.com/moby/buildkit v0.17.1/go.mod h1:ru8NFyDHD8HbuKaLXJIjK9nr3x6FZR+IWjtF07S+wdM=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/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.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8=
|
||||
github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
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/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
|
||||
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
@@ -334,14 +337,14 @@ github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7z
|
||||
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
|
||||
github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0=
|
||||
github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8=
|
||||
github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU=
|
||||
github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0=
|
||||
github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc=
|
||||
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs=
|
||||
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
|
||||
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
|
||||
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
|
||||
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=
|
||||
@@ -360,12 +363,12 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
@@ -374,16 +377,14 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||
github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
|
||||
github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
|
||||
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
|
||||
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
|
||||
github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||
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/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -392,25 +393,24 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
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.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
|
||||
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
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.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
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.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
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=
|
||||
@@ -421,8 +421,8 @@ github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc h1:zAsgcP8MhzAbhMnB1QQ2
|
||||
github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
|
||||
@@ -448,9 +448,8 @@ github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3k
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 h1:XTHrT015sxHyJ5FnQ0AeemSspZWaDq7DoTRW0EVsDCE=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c h1:2EejZtjFjKJGk71ANb+wtFK5EjUzUkEM3R0xnp559xg=
|
||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -469,26 +468,22 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
||||
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA=
|
||||
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g=
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 h1:eUk79E1w8yMtXeHSzjKorxuC8qJOnyXQnLaJehxpJaI=
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250113203817-b14e27f4135a h1:EfGw4G0x/8qXWgtcZ6KVaPS+wpWOQMaypczzP8ojkMY=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20250113203817-b14e27f4135a/go.mod h1:Dl/9oEjK7IqnjAm21Okx/XIxUCFJzvh+XdVHUlBwXTw=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c h1:bQLsfX+uEPZUjyR2qmoJs5F8Z57bPVmF3IsUf22Xo9Y=
|
||||
github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c/go.mod h1:Dl/9oEjK7IqnjAm21Okx/XIxUCFJzvh+XdVHUlBwXTw=
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 h1:7I5c2Ig/5FgqkYOh/N87NzoyI9U15qUPXhDD8uCupv8=
|
||||
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
|
||||
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-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw=
|
||||
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc=
|
||||
github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs=
|
||||
github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
|
||||
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
|
||||
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=
|
||||
@@ -499,38 +494,36 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zclconf/go-cty v1.16.0 h1:xPKEhst+BW5D0wxebMZkxgapvOE/dw7bFTlgSc9nD6w=
|
||||
github.com/zclconf/go-cty v1.16.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 h1:yMkBS9yViCc7U7yeLzJPM2XizlfdVvBRSmsQDWu6qc0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0/go.mod h1:n8MR6/liuGB5EmTETUBeU5ZgqMOlqKRxUaqPQBOANZ8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 h1:4BZHA+B1wXEQoGNHxW8mURaLhcdGwvRnmhGbm+odRbc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0/go.mod h1:3qi2EEwMgB4xnKgPLqsDP3j9qxnHDZeHsnAxfjQqTko=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0 h1:FZ6ei8GFW7kyPYdxJaV2rgI6M+4tvZzhYsQ2wgyVC08=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.31.0/go.mod h1:MdEu/mC6j3D+tTEfvI15b5Ci2Fn7NneJ71YMoiS3tpI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 h1:ZsXq73BERAiNuuFXYqP4MR5hBrjXfMGSO+Cx7qoOZiM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0/go.mod h1:hg1zaDMpyZJuUzjFxFsRYBoccE86tM9Uf4IqNMUxvrY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 h1:gbhw/u49SS3gkPWiYweQNJGm/uJN5GkI/FrosxSHT7A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1/go.mod h1:GnOaBaFQ2we3b9AGWJpsBa7v1S5RlQzlC3O7dRMxZhM=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 h1:bflGWrfYyuulcdxf14V6n9+CoQcu5SAAdHmDPAJnlps=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0/go.mod h1:qcTO4xHAxZLaLxPd60TdE88rxtItPHgHWqOhOGRr0as=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
|
||||
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
|
||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
@@ -543,8 +536,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -562,10 +555,10 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
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=
|
||||
@@ -573,8 +566,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -589,25 +582,26 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -621,15 +615,17 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
|
||||
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
|
||||
@@ -656,27 +652,25 @@ 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=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
|
||||
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
|
||||
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
|
||||
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
|
||||
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A=
|
||||
k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0=
|
||||
k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8=
|
||||
k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
|
||||
k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg=
|
||||
k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc=
|
||||
tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws=
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
pusherrors "github.com/containerd/containerd/v2/core/remotes/errors"
|
||||
pusherrors "github.com/containerd/containerd/remotes/errors"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/buildx/util/imagetools"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
@@ -54,8 +54,6 @@ const (
|
||||
// > an artifactType field, and tooling to work with artifacts should
|
||||
// > fallback to the config.mediaType value.
|
||||
ComposeEmptyConfigMediaType = "application/vnd.docker.compose.config.empty.v1+json"
|
||||
// ComposeEnvFileMediaType is the media type for each Env File layer in the image manifest.
|
||||
ComposeEnvFileMediaType = "application/vnd.docker.compose.envfile"
|
||||
)
|
||||
|
||||
// clientAuthStatusCodes are client (4xx) errors that are authentication
|
||||
@@ -83,18 +81,6 @@ func DescriptorForComposeFile(path string, content []byte) v1.Descriptor {
|
||||
}
|
||||
}
|
||||
|
||||
func DescriptorForEnvFile(path string, content []byte) v1.Descriptor {
|
||||
return v1.Descriptor{
|
||||
MediaType: ComposeEnvFileMediaType,
|
||||
Digest: digest.FromString(string(content)),
|
||||
Size: int64(len(content)),
|
||||
Annotations: map[string]string{
|
||||
"com.docker.compose.version": api.ComposeVersion,
|
||||
"com.docker.compose.envfile": filepath.Base(path),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func PushManifest(
|
||||
ctx context.Context,
|
||||
resolver *imagetools.Resolver,
|
||||
|
||||
@@ -16,6 +16,8 @@ package sync
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
)
|
||||
|
||||
// PathMapping contains the Compose service and modified host system path.
|
||||
@@ -36,5 +38,5 @@ type PathMapping struct {
|
||||
}
|
||||
|
||||
type Syncer interface {
|
||||
Sync(ctx context.Context, service string, paths []*PathMapping) error
|
||||
Sync(ctx context.Context, service types.ServiceConfig, paths []PathMapping) error
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
moby "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
@@ -64,8 +65,8 @@ func NewTar(projectName string, client LowLevelClient) *Tar {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) error {
|
||||
containers, err := t.client.ContainersForService(ctx, t.projectName, service)
|
||||
func (t *Tar) Sync(ctx context.Context, service types.ServiceConfig, paths []PathMapping) error {
|
||||
containers, err := t.client.ContainersForService(ctx, t.projectName, service.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -76,7 +77,7 @@ func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) er
|
||||
if _, err := os.Stat(p.HostPath); err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||
pathsToDelete = append(pathsToDelete, p.ContainerPath)
|
||||
} else {
|
||||
pathsToCopy = append(pathsToCopy, *p)
|
||||
pathsToCopy = append(pathsToCopy, p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,5 +16,7 @@
|
||||
|
||||
package internal
|
||||
|
||||
// Version is the version of the CLI injected in compilation time
|
||||
var Version = "dev"
|
||||
var (
|
||||
// Version is the version of the CLI injected in compilation time
|
||||
Version = "dev"
|
||||
)
|
||||
|
||||
@@ -207,8 +207,6 @@ type CreateOptions struct {
|
||||
Timeout *time.Duration
|
||||
// QuietPull makes the pulling process quiet
|
||||
QuietPull bool
|
||||
// AssumeYes assume "yes" as answer to all prompts and run non-interactively
|
||||
AssumeYes bool
|
||||
}
|
||||
|
||||
// StartOptions group options of the Start API
|
||||
@@ -420,8 +418,6 @@ const (
|
||||
// PublishOptions group options of the Publish API
|
||||
type PublishOptions struct {
|
||||
ResolveImageDigests bool
|
||||
WithEnvironment bool
|
||||
AssumeYes bool
|
||||
|
||||
OCIVersion OCIVersion
|
||||
}
|
||||
@@ -433,6 +429,7 @@ func (e Event) String() string {
|
||||
attr = append(attr, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
return fmt.Sprintf("%s container %s %s (%s)\n", t, e.Status, e.Container, strings.Join(attr, ", "))
|
||||
|
||||
}
|
||||
|
||||
// ListOptions group options of the ls API
|
||||
|
||||
@@ -101,8 +101,7 @@ func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, op
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig,
|
||||
networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string,
|
||||
) (containerType.CreateResponse, error) {
|
||||
networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (containerType.CreateResponse, error) {
|
||||
d.containers = append(d.containers, moby.Container{
|
||||
ID: containerName,
|
||||
Names: []string{containerName},
|
||||
@@ -230,6 +229,7 @@ func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string
|
||||
default:
|
||||
return d.apiClient.ImageInspectWithRaw(ctx, imageName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) {
|
||||
|
||||
@@ -21,8 +21,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/containerd/platforms"
|
||||
@@ -33,7 +31,6 @@ import (
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
xprogress "github.com/docker/buildx/util/progress"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/hints"
|
||||
cliopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/compose/v2/internal/tracing"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
@@ -65,10 +62,6 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
||||
}, s.stdinfo(), "Building")
|
||||
}
|
||||
|
||||
const bakeSuggest = "Compose now can delegate build to bake for better performances\nJust set COMPOSE_BAKE=true"
|
||||
|
||||
var suggest sync.Once
|
||||
|
||||
//nolint:gocyclo
|
||||
func (s *composeService) build(ctx context.Context, project *types.Project, options api.BuildOptions, localImages map[string]string) (map[string]string, error) {
|
||||
imageIDs := map[string]string{}
|
||||
@@ -78,33 +71,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
if options.Deps {
|
||||
policy = types.IncludeDependencies
|
||||
}
|
||||
|
||||
serviceDeps := false
|
||||
project, err := project.WithServicesTransform(func(serviceName string, service types.ServiceConfig) (types.ServiceConfig, error) {
|
||||
if service.Build != nil {
|
||||
for _, c := range service.Build.AdditionalContexts {
|
||||
if t, found := strings.CutPrefix(c, types.ServicePrefix); found {
|
||||
serviceDeps = true
|
||||
if service.DependsOn == nil {
|
||||
service.DependsOn = map[string]types.ServiceDependency{}
|
||||
}
|
||||
service.DependsOn[t] = types.ServiceDependency{
|
||||
Condition: "build", // non-canonical, but will force dependency graph ordering
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return service, nil
|
||||
})
|
||||
if err != nil {
|
||||
return imageIDs, err
|
||||
}
|
||||
|
||||
if serviceDeps {
|
||||
logrus.Infof(`additional_context with "service:"" is better supported when delegating build go bake. Set COMPOSE_BAKE=true`)
|
||||
}
|
||||
|
||||
err = project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
|
||||
err := project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
|
||||
if service.Build == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -139,11 +106,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
w *xprogress.Printer
|
||||
)
|
||||
if buildkitEnabled {
|
||||
if hints.Enabled() {
|
||||
suggest.Do(func() {
|
||||
fmt.Fprintln(s.dockerCli.Out(), bakeSuggest) //nolint:errcheck
|
||||
})
|
||||
}
|
||||
builderName := options.Builder
|
||||
if builderName == "" {
|
||||
builderName = os.Getenv("BUILDX_BUILDER")
|
||||
@@ -167,14 +129,12 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
if options.Quiet {
|
||||
options.Progress = progress.ModeQuiet
|
||||
}
|
||||
if options.Progress == "" {
|
||||
options.Progress = os.Getenv("BUILDKIT_PROGRESS")
|
||||
}
|
||||
w, err = xprogress.NewPrinter(progressCtx, os.Stdout, progressui.DisplayMode(options.Progress),
|
||||
xprogress.WithDesc(
|
||||
fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver),
|
||||
fmt.Sprintf("%s:%s", b.Driver, b.Name),
|
||||
))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -191,13 +151,12 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
cw := progress.ContextWriter(ctx)
|
||||
err = InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
|
||||
service, ok := serviceToBuild[name]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cw := progress.ContextWriter(ctx)
|
||||
serviceName := fmt.Sprintf("Service %s", name)
|
||||
|
||||
if !buildkitEnabled {
|
||||
@@ -224,10 +183,12 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
return err
|
||||
}
|
||||
|
||||
cw.Event(progress.BuildingEvent(serviceName))
|
||||
digest, err := s.doBuildBuildkit(ctx, name, buildOptions, w, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cw.Event(progress.BuiltEvent(serviceName))
|
||||
builtDigests[getServiceIndex(name)] = digest
|
||||
|
||||
return nil
|
||||
@@ -251,7 +212,6 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
service := project.Services[names[i]]
|
||||
imageRef := api.GetImageNameOrDefault(service, project.Name)
|
||||
imageIDs[imageRef] = imageDigest
|
||||
cw.Event(progress.BuiltEvent(names[i]))
|
||||
}
|
||||
}
|
||||
return imageIDs, err
|
||||
@@ -468,8 +428,8 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
|
||||
DockerfilePath: dockerFilePath(service.Build.Context, service.Build.Dockerfile),
|
||||
NamedContexts: toBuildContexts(service.Build.AdditionalContexts),
|
||||
},
|
||||
CacheFrom: pb.CreateCaches(cacheFrom.ToPB()),
|
||||
CacheTo: pb.CreateCaches(cacheTo.ToPB()),
|
||||
CacheFrom: pb.CreateCaches(cacheFrom),
|
||||
CacheTo: pb.CreateCaches(cacheTo),
|
||||
NoCache: service.Build.NoCache,
|
||||
Pull: service.Build.Pull,
|
||||
BuildArgs: flatten(resolveAndMergeBuildArgs(s.dockerCli, project, service, options)),
|
||||
@@ -574,11 +534,6 @@ func getImageBuildLabels(project *types.Project, service types.ServiceConfig) ty
|
||||
func toBuildContexts(additionalContexts types.Mapping) map[string]build.NamedContext {
|
||||
namedContexts := map[string]build.NamedContext{}
|
||||
for name, contextPath := range additionalContexts {
|
||||
if _, found := strings.CutPrefix(contextPath, types.ServicePrefix); found {
|
||||
// image we depend on has been build previously, as we run in dependency order.
|
||||
// this assumes use of docker engine builder, so that build can access local images
|
||||
continue
|
||||
}
|
||||
namedContexts[name] = build.NamedContext{Path: contextPath}
|
||||
}
|
||||
return namedContexts
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
package compose
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -36,10 +35,8 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/builder/remotecontext/urlutil"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/util/gitutil"
|
||||
"github.com/moby/buildkit/util/progress/progressui"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -96,28 +93,19 @@ type bakeGroup struct {
|
||||
}
|
||||
|
||||
type bakeTarget struct {
|
||||
Context string `json:"context,omitempty"`
|
||||
Contexts map[string]string `json:"contexts,omitempty"`
|
||||
Dockerfile string `json:"dockerfile,omitempty"`
|
||||
DockerfileInline string `json:"dockerfile-inline,omitempty"`
|
||||
Args map[string]string `json:"args,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
CacheFrom []string `json:"cache-from,omitempty"`
|
||||
CacheTo []string `json:"cache-to,omitempty"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Secrets []string `json:"secret,omitempty"`
|
||||
SSH []string `json:"ssh,omitempty"`
|
||||
Platforms []string `json:"platforms,omitempty"`
|
||||
Pull bool `json:"pull,omitempty"`
|
||||
NoCache bool `json:"no-cache,omitempty"`
|
||||
NetworkMode string `json:"network,omitempty"`
|
||||
NoCacheFilter []string `json:"no-cache-filter,omitempty"`
|
||||
ShmSize types.UnitBytes `json:"shm-size,omitempty"`
|
||||
Ulimits []string `json:"ulimits,omitempty"`
|
||||
Call string `json:"call,omitempty"`
|
||||
Entitlements []string `json:"entitlements,omitempty"`
|
||||
Outputs []string `json:"output,omitempty"`
|
||||
Context string `json:"context,omitempty"`
|
||||
Dockerfile string `json:"dockerfile,omitempty"`
|
||||
Args map[string]string `json:"args,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
CacheFrom []string `json:"cache-from,omitempty"`
|
||||
CacheTo []string `json:"cache-to,omitempty"`
|
||||
Secrets []string `json:"secret,omitempty"`
|
||||
SSH []string `json:"ssh,omitempty"`
|
||||
Platforms []string `json:"platforms,omitempty"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Pull bool `json:"pull,omitempty"`
|
||||
NoCache bool `json:"no-cache,omitempty"`
|
||||
}
|
||||
|
||||
type bakeMetadata map[string]buildStatus
|
||||
@@ -127,6 +115,11 @@ type buildStatus struct {
|
||||
}
|
||||
|
||||
func (s *composeService) doBuildBake(ctx context.Context, project *types.Project, serviceToBeBuild types.Services, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo
|
||||
cw := progress.ContextWriter(ctx)
|
||||
for name := range serviceToBeBuild {
|
||||
cw.Event(progress.BuildingEvent(name))
|
||||
}
|
||||
|
||||
eg := errgroup.Group{}
|
||||
ch := make(chan *client.SolveStatus)
|
||||
display, err := progressui.NewDisplay(os.Stdout, progressui.DisplayMode(options.Progress))
|
||||
@@ -143,10 +136,8 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
Targets: map[string]bakeTarget{},
|
||||
}
|
||||
var group bakeGroup
|
||||
var privileged bool
|
||||
var read []string
|
||||
|
||||
for serviceName, service := range serviceToBeBuild {
|
||||
for name, service := range serviceToBeBuild {
|
||||
if service.Build == nil {
|
||||
continue
|
||||
}
|
||||
@@ -160,67 +151,32 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
args[k] = *v
|
||||
}
|
||||
|
||||
image := api.GetImageNameOrDefault(service, project.Name)
|
||||
|
||||
entitlements := build.Entitlements
|
||||
if slices.Contains(build.Entitlements, "security.insecure") {
|
||||
privileged = true
|
||||
}
|
||||
if build.Privileged {
|
||||
entitlements = append(entitlements, "security.insecure")
|
||||
privileged = true
|
||||
}
|
||||
|
||||
var output string
|
||||
push := options.Push && service.Image != ""
|
||||
if len(service.Build.Platforms) > 1 {
|
||||
output = fmt.Sprintf("type=image,push=%t", push)
|
||||
} else {
|
||||
output = fmt.Sprintf("type=docker,load=true,push=%t", push)
|
||||
}
|
||||
|
||||
read = append(read, build.Context)
|
||||
for _, path := range build.AdditionalContexts {
|
||||
_, err := gitutil.ParseGitRef(path)
|
||||
if !strings.Contains(path, "://") && err != nil {
|
||||
read = append(read, path)
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Targets[serviceName] = bakeTarget{
|
||||
Context: build.Context,
|
||||
Contexts: additionalContexts(build.AdditionalContexts),
|
||||
Dockerfile: dockerFilePath(build.Context, build.Dockerfile),
|
||||
DockerfileInline: build.DockerfileInline,
|
||||
Args: args,
|
||||
Labels: build.Labels,
|
||||
Tags: append(build.Tags, image),
|
||||
cfg.Targets[name] = bakeTarget{
|
||||
Context: build.Context,
|
||||
Dockerfile: dockerFilePath(build.Context, build.Dockerfile),
|
||||
Args: args,
|
||||
Labels: build.Labels,
|
||||
Tags: build.Tags,
|
||||
|
||||
CacheFrom: build.CacheFrom,
|
||||
// CacheTo: TODO
|
||||
Platforms: build.Platforms,
|
||||
Target: build.Target,
|
||||
Secrets: toBakeSecrets(project, build.Secrets),
|
||||
SSH: toBakeSSH(append(build.SSH, options.SSHs...)),
|
||||
Pull: options.Pull,
|
||||
NoCache: options.NoCache,
|
||||
ShmSize: build.ShmSize,
|
||||
Ulimits: toBakeUlimits(build.Ulimits),
|
||||
Entitlements: entitlements,
|
||||
Outputs: []string{output},
|
||||
Platforms: build.Platforms,
|
||||
Target: build.Target,
|
||||
Secrets: toBakeSecrets(project, build.Secrets),
|
||||
SSH: toBakeSSH(build.SSH),
|
||||
Pull: options.Pull,
|
||||
NoCache: options.NoCache,
|
||||
}
|
||||
group.Targets = append(group.Targets, serviceName)
|
||||
group.Targets = append(group.Targets, name)
|
||||
}
|
||||
|
||||
cfg.Groups["default"] = group
|
||||
|
||||
b, err := json.MarshalIndent(cfg, "", " ")
|
||||
b, err := json.Marshal(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logrus.Debugf("bake build config:\n%s", string(b))
|
||||
|
||||
metadata, err := os.CreateTemp(os.TempDir(), "compose")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -230,26 +186,7 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args := []string{"bake", "--file", "-", "--progress", "rawjson", "--metadata-file", metadata.Name()}
|
||||
mustAllow := buildx.Version != "" && versions.GreaterThanOrEqualTo(buildx.Version[1:], "0.17.0")
|
||||
if mustAllow {
|
||||
// FIXME we should prompt user about this, but this is a breaking change in UX
|
||||
for _, path := range read {
|
||||
args = append(args, "--allow", "fs.read="+path)
|
||||
}
|
||||
if privileged {
|
||||
args = append(args, "--allow", "security.insecure")
|
||||
}
|
||||
}
|
||||
|
||||
if options.Builder != "" {
|
||||
args = append(args, "--builder", options.Builder)
|
||||
}
|
||||
|
||||
logrus.Debugf("Executing bake with args: %v", args)
|
||||
|
||||
cmd := exec.CommandContext(ctx, buildx.Path, args...)
|
||||
cmd := exec.CommandContext(ctx, buildx.Path, "bake", "--file", "-", "--progress", "rawjson", "--metadata-file", metadata.Name())
|
||||
// Remove DOCKER_CLI_PLUGIN... variable so buildx can detect it run standalone
|
||||
cmd.Env = filter(os.Environ(), manager.ReexecEnvvar)
|
||||
|
||||
@@ -275,36 +212,29 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var errMessage string
|
||||
scanner := bufio.NewScanner(pipe)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eg.Go(cmd.Wait)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
decoder := json.NewDecoder(strings.NewReader(line))
|
||||
var status client.SolveStatus
|
||||
err := decoder.Decode(&status)
|
||||
for {
|
||||
decoder := json.NewDecoder(pipe)
|
||||
var s client.SolveStatus
|
||||
err := decoder.Decode(&s)
|
||||
if err != nil {
|
||||
if strings.HasPrefix(line, "ERROR: ") {
|
||||
errMessage = line[7:]
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
// bake displays build details at the end of a build, which isn't a json SolveStatus
|
||||
continue
|
||||
}
|
||||
ch <- &status
|
||||
ch <- &s
|
||||
}
|
||||
close(ch) // stop build progress UI
|
||||
|
||||
err = eg.Wait()
|
||||
if err != nil {
|
||||
if errMessage != "" {
|
||||
return nil, errors.New(errMessage)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to execute bake: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err = os.ReadFile(metadata.Name())
|
||||
@@ -318,7 +248,6 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cw := progress.ContextWriter(ctx)
|
||||
results := map[string]string{}
|
||||
for name, m := range md {
|
||||
results[name] = m.Digest
|
||||
@@ -327,29 +256,6 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func additionalContexts(contexts types.Mapping) map[string]string {
|
||||
ac := map[string]string{}
|
||||
for k, v := range contexts {
|
||||
if target, found := strings.CutPrefix(v, types.ServicePrefix); found {
|
||||
v = "target:" + target
|
||||
}
|
||||
ac[k] = v
|
||||
}
|
||||
return ac
|
||||
}
|
||||
|
||||
func toBakeUlimits(ulimits map[string]*types.UlimitsConfig) []string {
|
||||
s := []string{}
|
||||
for u, l := range ulimits {
|
||||
if l.Single > 0 {
|
||||
s = append(s, fmt.Sprintf("%s=%d", u, l.Single))
|
||||
} else {
|
||||
s = append(s, fmt.Sprintf("%s=%d:%d", u, l.Soft, l.Hard))
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func toBakeSSH(ssh types.SSHConfig) []string {
|
||||
var s []string
|
||||
for _, key := range ssh {
|
||||
@@ -362,15 +268,11 @@ func toBakeSecrets(project *types.Project, secrets []types.ServiceSecretConfig)
|
||||
var s []string
|
||||
for _, ref := range secrets {
|
||||
def := project.Secrets[ref.Source]
|
||||
target := ref.Target
|
||||
if target == "" {
|
||||
target = ref.Source
|
||||
}
|
||||
switch {
|
||||
case def.Environment != "":
|
||||
s = append(s, fmt.Sprintf("id=%s,type=env,env=%s", target, def.Environment))
|
||||
s = append(s, fmt.Sprintf("id=%s,type=env,env=%s", ref.Source, def.Environment))
|
||||
case def.File != "":
|
||||
s = append(s, fmt.Sprintf("id=%s,type=file,src=%s", target, def.File))
|
||||
s = append(s, fmt.Sprintf("id=%s,type=file,src=%s", ref.Source, def.File))
|
||||
}
|
||||
}
|
||||
return s
|
||||
|
||||
@@ -48,7 +48,7 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, service string, op
|
||||
confutil.NewConfig(s.dockerCli),
|
||||
buildx.WithPrefix(p, service, true))
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", WrapCategorisedComposeError(err, BuildFailure)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
|
||||
Image: c.Image,
|
||||
Labels: c.Labels,
|
||||
}
|
||||
|
||||
}
|
||||
service.Scale = increment(service.Scale)
|
||||
set[serviceLabel] = service
|
||||
@@ -320,6 +321,7 @@ func (s *composeService) RuntimeVersion(ctx context.Context) (string, error) {
|
||||
runtimeVersion.val = version.APIVersion
|
||||
})
|
||||
return runtimeVersion.val, runtimeVersion.err
|
||||
|
||||
}
|
||||
|
||||
func (s *composeService) isDesktopIntegrationActive() bool {
|
||||
|
||||
@@ -114,15 +114,6 @@ func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName
|
||||
// containerPredicate define a predicate we want container to satisfy for filtering operations
|
||||
type containerPredicate func(c moby.Container) bool
|
||||
|
||||
func matches(c moby.Container, predicates ...containerPredicate) bool {
|
||||
for _, predicate := range predicates {
|
||||
if !predicate(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[api.ServiceLabel]
|
||||
@@ -157,10 +148,10 @@ func isNotOneOff(c moby.Container) bool {
|
||||
}
|
||||
|
||||
// filter return Containers with elements to match predicate
|
||||
func (containers Containers) filter(predicates ...containerPredicate) Containers {
|
||||
func (containers Containers) filter(predicate containerPredicate) Containers {
|
||||
var filtered Containers
|
||||
for _, c := range containers {
|
||||
if matches(c, predicates...) {
|
||||
if predicate(c) {
|
||||
filtered = append(filtered, c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
"github.com/docker/compose/v2/internal/tracing"
|
||||
moby "github.com/docker/docker/api/types"
|
||||
containerType "github.com/docker/docker/api/types/container"
|
||||
mmount "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -61,7 +60,6 @@ type convergence struct {
|
||||
service *composeService
|
||||
services map[string]Containers
|
||||
networks map[string]string
|
||||
volumes map[string]string
|
||||
stateMutex sync.Mutex
|
||||
}
|
||||
|
||||
@@ -77,7 +75,7 @@ func (c *convergence) setObservedState(serviceName string, containers Containers
|
||||
c.services[serviceName] = containers
|
||||
}
|
||||
|
||||
func newConvergence(services []string, state Containers, networks map[string]string, volumes map[string]string, s *composeService) *convergence {
|
||||
func newConvergence(services []string, state Containers, networks map[string]string, s *composeService) *convergence {
|
||||
observedState := map[string]Containers{}
|
||||
for _, s := range services {
|
||||
observedState[s] = Containers{}
|
||||
@@ -90,7 +88,6 @@ func newConvergence(services []string, state Containers, networks map[string]str
|
||||
service: s,
|
||||
services: observedState,
|
||||
networks: networks,
|
||||
volumes: volumes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +202,7 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
// Scale UP
|
||||
number := next + i
|
||||
name := getContainerName(project.Name, service, number)
|
||||
i := i
|
||||
eventOpts := tracing.SpanOptions{trace.WithAttributes(attribute.String("container.name", name))}
|
||||
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "service/scale/up", eventOpts, func(ctx context.Context) error {
|
||||
opts := createOptions{
|
||||
@@ -228,9 +226,6 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||
func (c *convergence) stopDependentContainers(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
|
||||
// Stop dependent containers, so they will be restarted after service is re-created
|
||||
dependents := project.GetDependentsForService(service)
|
||||
if len(dependents) == 0 {
|
||||
return nil
|
||||
}
|
||||
err := c.service.stop(ctx, project.Name, api.StopOptions{
|
||||
Services: dependents,
|
||||
Project: project,
|
||||
@@ -343,71 +338,30 @@ func (c *convergence) mustRecreate(expected types.ServiceConfig, actual moby.Con
|
||||
}
|
||||
|
||||
if c.networks != nil && actual.State == "running" {
|
||||
if checkExpectedNetworks(expected, actual, c.networks) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
if c.volumes != nil {
|
||||
if checkExpectedVolumes(expected, actual, c.volumes) {
|
||||
return true, nil
|
||||
// check the networks container is connected to are the expected ones
|
||||
for net := range expected.Networks {
|
||||
id := c.networks[net]
|
||||
if id == "swarm" {
|
||||
// corner-case : swarm overlay network isn't visible until a container is attached
|
||||
continue
|
||||
}
|
||||
found := false
|
||||
for _, settings := range actual.NetworkSettings.Networks {
|
||||
if settings.NetworkID == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// config is up-to-date but container is not connected to network - maybe recreated ?
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func checkExpectedNetworks(expected types.ServiceConfig, actual moby.Container, networks map[string]string) bool {
|
||||
// check the networks container is connected to are the expected ones
|
||||
for net := range expected.Networks {
|
||||
id := networks[net]
|
||||
if id == "swarm" {
|
||||
// corner-case : swarm overlay network isn't visible until a container is attached
|
||||
continue
|
||||
}
|
||||
found := false
|
||||
for _, settings := range actual.NetworkSettings.Networks {
|
||||
if settings.NetworkID == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// config is up-to-date but container is not connected to network
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkExpectedVolumes(expected types.ServiceConfig, actual moby.Container, volumes map[string]string) bool {
|
||||
// check container's volume mounts and search for the expected ones
|
||||
for _, vol := range expected.Volumes {
|
||||
if vol.Type != string(mmount.TypeVolume) {
|
||||
continue
|
||||
}
|
||||
if vol.Source == "" {
|
||||
continue
|
||||
}
|
||||
id := volumes[vol.Source]
|
||||
found := false
|
||||
for _, mount := range actual.Mounts {
|
||||
if mount.Type != mmount.TypeVolume {
|
||||
continue
|
||||
}
|
||||
if mount.Name == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// config is up-to-date but container doesn't have volume mounted
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getContainerName(projectName string, service types.ServiceConfig, number int) string {
|
||||
name := getDefaultContainerName(projectName, service.Name, strconv.Itoa(number))
|
||||
if service.ContainerName != "" {
|
||||
@@ -459,7 +413,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
||||
continue
|
||||
}
|
||||
|
||||
waitingFor := containers.filter(isService(dep), isNotOneOff)
|
||||
waitingFor := containers.filter(isService(dep))
|
||||
w.Events(containerEvents(waitingFor, progress.Waiting))
|
||||
if len(waitingFor) == 0 {
|
||||
if config.Required {
|
||||
@@ -469,6 +423,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
||||
continue
|
||||
}
|
||||
|
||||
dep, config := dep, config
|
||||
eg.Go(func() error {
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
@@ -582,11 +537,11 @@ func nextContainerNumber(containers []moby.Container) int {
|
||||
}
|
||||
}
|
||||
return maxNumber + 1
|
||||
|
||||
}
|
||||
|
||||
func (s *composeService) createContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
name string, number int, opts createOptions,
|
||||
) (container moby.Container, err error) {
|
||||
name string, number int, opts createOptions) (container moby.Container, err error) {
|
||||
w := progress.ContextWriter(ctx)
|
||||
eventName := "Container " + name
|
||||
w.Event(progress.CreatingEvent(eventName))
|
||||
@@ -599,8 +554,7 @@ func (s *composeService) createContainer(ctx context.Context, project *types.Pro
|
||||
}
|
||||
|
||||
func (s *composeService) recreateContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
|
||||
replaced moby.Container, inherit bool, timeout *time.Duration,
|
||||
) (moby.Container, error) {
|
||||
replaced moby.Container, inherit bool, timeout *time.Duration) (moby.Container, error) {
|
||||
var created moby.Container
|
||||
w := progress.ContextWriter(ctx)
|
||||
w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Working, "Recreate"))
|
||||
@@ -669,6 +623,7 @@ func (s *composeService) createMobyContainer(ctx context.Context,
|
||||
) (moby.Container, error) {
|
||||
var created moby.Container
|
||||
cfgs, err := s.getCreateConfigs(ctx, project, service, number, inherit, opts)
|
||||
|
||||
if err != nil {
|
||||
return created, err
|
||||
}
|
||||
@@ -851,8 +806,7 @@ func (s *composeService) isServiceCompleted(ctx context.Context, containers Cont
|
||||
func (s *composeService) startService(ctx context.Context,
|
||||
project *types.Project, service types.ServiceConfig,
|
||||
containers Containers, listener api.ContainerEventListener,
|
||||
timeout time.Duration,
|
||||
) error {
|
||||
timeout time.Duration) error {
|
||||
if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -432,4 +432,5 @@ func TestCreateMobyContainer(t *testing.T) {
|
||||
}, progress.ContextWriter(context.TODO()))
|
||||
assert.NilError(t, err)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ func (s *composeService) listContainersTargetedForCopy(ctx context.Context, proj
|
||||
}
|
||||
if direction == fromService {
|
||||
return containers[:1], err
|
||||
|
||||
}
|
||||
return containers, err
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
pathutil "github.com/docker/compose/v2/internal/paths"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/prompt"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
moby "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/blkiodev"
|
||||
@@ -93,8 +92,7 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
|
||||
return err
|
||||
}
|
||||
|
||||
volumes, err := s.ensureProjectVolumes(ctx, project, options.AssumeYes)
|
||||
if err != nil {
|
||||
if err := s.ensureProjectVolumes(ctx, project); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -117,7 +115,7 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
|
||||
"--remove-orphans flag to clean it up.", orphans.names())
|
||||
}
|
||||
}
|
||||
return newConvergence(options.Services, observedState, networks, volumes, s).apply(ctx, project, options)
|
||||
return newConvergence(options.Services, observedState, networks, s).apply(ctx, project, options)
|
||||
}
|
||||
|
||||
func prepareNetworks(project *types.Project) {
|
||||
@@ -143,17 +141,15 @@ func (s *composeService) ensureNetworks(ctx context.Context, project *types.Proj
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (s *composeService) ensureProjectVolumes(ctx context.Context, project *types.Project, assumeYes bool) (map[string]string, error) {
|
||||
ids := map[string]string{}
|
||||
func (s *composeService) ensureProjectVolumes(ctx context.Context, project *types.Project) error {
|
||||
for k, volume := range project.Volumes {
|
||||
volume.CustomLabels = volume.CustomLabels.Add(api.VolumeLabel, k)
|
||||
volume.CustomLabels = volume.CustomLabels.Add(api.ProjectLabel, project.Name)
|
||||
volume.CustomLabels = volume.CustomLabels.Add(api.VersionLabel, api.ComposeVersion)
|
||||
id, err := s.ensureVolume(ctx, k, volume, project, assumeYes)
|
||||
volume.Labels = volume.Labels.Add(api.VolumeLabel, k)
|
||||
volume.Labels = volume.Labels.Add(api.ProjectLabel, project.Name)
|
||||
volume.Labels = volume.Labels.Add(api.VersionLabel, api.ComposeVersion)
|
||||
err := s.ensureVolume(ctx, volume, project.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
ids[k] = id
|
||||
}
|
||||
|
||||
err := func() error {
|
||||
@@ -205,10 +201,11 @@ func (s *composeService) ensureProjectVolumes(ctx context.Context, project *type
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
progress.ContextWriter(ctx).TailMsgf("Failed to prepare Synchronized file shares: %v", err)
|
||||
}
|
||||
return ids, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *composeService) getCreateConfigs(ctx context.Context,
|
||||
@@ -258,7 +255,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
|
||||
if err != nil {
|
||||
return createConfigs{}, err
|
||||
}
|
||||
containerConfig := container.Config{
|
||||
var containerConfig = container.Config{
|
||||
Hostname: service.Hostname,
|
||||
Domainname: service.DomainName,
|
||||
User: service.User,
|
||||
@@ -416,7 +413,7 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
|
||||
return "", fmt.Errorf("a MAC address is specified for multiple networks (%s), but this feature requires Docker Engine 1.44 or later (currently: %s)", strings.Join(withMacAddress, ", "), version)
|
||||
}
|
||||
|
||||
if mainNw != nil && mainNw.MacAddress != "" {
|
||||
if mainNw != nil {
|
||||
macAddress = mainNw.MacAddress
|
||||
}
|
||||
}
|
||||
@@ -424,11 +421,11 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
|
||||
return macAddress, nil
|
||||
}
|
||||
|
||||
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, cfg *types.ServiceNetworkConfig, useNetworkAliases bool) []string {
|
||||
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, networkKey string, useNetworkAliases bool) []string {
|
||||
aliases := []string{getContainerName(project.Name, service, serviceIndex)}
|
||||
if useNetworkAliases {
|
||||
aliases = append(aliases, service.Name)
|
||||
if cfg != nil {
|
||||
if cfg := service.Networks[networkKey]; cfg != nil {
|
||||
aliases = append(aliases, cfg.Aliases...)
|
||||
}
|
||||
}
|
||||
@@ -456,7 +453,7 @@ func createEndpointSettings(p *types.Project, service types.ServiceConfig, servi
|
||||
driverOpts = config.DriverOpts
|
||||
}
|
||||
return &network.EndpointSettings{
|
||||
Aliases: getAliases(p, service, serviceIndex, config, useNetworkAliases),
|
||||
Aliases: getAliases(p, service, serviceIndex, networkKey, useNetworkAliases),
|
||||
Links: links,
|
||||
IPAddress: ipv4Address,
|
||||
IPv6Gateway: ipv6Address,
|
||||
@@ -486,7 +483,7 @@ func parseSecurityOpts(p *types.Project, securityOpts []string) ([]string, bool,
|
||||
return securityOpts, false, fmt.Errorf("Invalid security-opt: %q", opt)
|
||||
}
|
||||
}
|
||||
if con[0] == "seccomp" && con[1] != "unconfined" && con[1] != "builtin" {
|
||||
if con[0] == "seccomp" && con[1] != "unconfined" {
|
||||
f, err := os.ReadFile(p.RelativePath(con[1]))
|
||||
if err != nil {
|
||||
return securityOpts, false, fmt.Errorf("opening seccomp profile (%s) failed: %w", con[1], err)
|
||||
@@ -548,28 +545,23 @@ func defaultNetworkSettings(
|
||||
primaryNetworkKey = "default"
|
||||
}
|
||||
primaryNetworkMobyNetworkName := project.Networks[primaryNetworkKey].Name
|
||||
primaryNetworkEndpoint := createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases)
|
||||
endpointsConfig := map[string]*network.EndpointSettings{}
|
||||
endpointsConfig := map[string]*network.EndpointSettings{
|
||||
primaryNetworkMobyNetworkName: createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases),
|
||||
}
|
||||
|
||||
// Starting from API version 1.44, the Engine will take several EndpointsConfigs
|
||||
// so we can pass all the extra networks we want the container to be connected to
|
||||
// in the network configuration instead of connecting the container to each extra
|
||||
// network individually after creation.
|
||||
if versions.GreaterThanOrEqualTo(version, "1.44") {
|
||||
if len(service.Networks) > 1 {
|
||||
serviceNetworks := service.NetworksByPriority()
|
||||
for _, networkKey := range serviceNetworks[1:] {
|
||||
mobyNetworkName := project.Networks[networkKey].Name
|
||||
epSettings := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
|
||||
endpointsConfig[mobyNetworkName] = epSettings
|
||||
}
|
||||
}
|
||||
if primaryNetworkEndpoint.MacAddress == "" {
|
||||
primaryNetworkEndpoint.MacAddress = service.MacAddress
|
||||
if versions.GreaterThanOrEqualTo(version, "1.44") && len(service.Networks) > 1 {
|
||||
serviceNetworks := service.NetworksByPriority()
|
||||
for _, networkKey := range serviceNetworks[1:] {
|
||||
mobyNetworkName := project.Networks[networkKey].Name
|
||||
epSettings := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
|
||||
endpointsConfig[mobyNetworkName] = epSettings
|
||||
}
|
||||
}
|
||||
|
||||
endpointsConfig[primaryNetworkMobyNetworkName] = primaryNetworkEndpoint
|
||||
networkConfig := &network.NetworkingConfig{
|
||||
EndpointsConfig: endpointsConfig,
|
||||
}
|
||||
@@ -891,7 +883,7 @@ func requireMountAPI(bind *types.ServiceVolumeBind) bool {
|
||||
}
|
||||
|
||||
func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) {
|
||||
mounts := map[string]mount.Mount{}
|
||||
var mounts = map[string]mount.Mount{}
|
||||
if inherit != nil {
|
||||
for _, m := range inherit.Mounts {
|
||||
if m.Type == "tmpfs" {
|
||||
@@ -977,7 +969,7 @@ func fillBindMounts(p types.Project, s types.ServiceConfig, m map[string]mount.M
|
||||
}
|
||||
|
||||
func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
|
||||
mounts := map[string]mount.Mount{}
|
||||
var mounts = map[string]mount.Mount{}
|
||||
|
||||
configsBaseDir := "/"
|
||||
for _, config := range s.Configs {
|
||||
@@ -1027,7 +1019,7 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount
|
||||
}
|
||||
|
||||
func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
|
||||
mounts := map[string]mount.Mount{}
|
||||
var mounts = map[string]mount.Mount{}
|
||||
|
||||
secretsDir := "/run/secrets/"
|
||||
for _, secret := range s.Secrets {
|
||||
@@ -1220,7 +1212,7 @@ func (s *composeService) ensureNetwork(ctx context.Context, project *types.Proje
|
||||
if errdefs.IsConflict(err) {
|
||||
// Maybe another execution of `docker compose up|run` created same network
|
||||
// let's retry once
|
||||
return s.resolveOrCreateNetwork(ctx, project, name, n)
|
||||
return s.resolveOrCreateNetwork(ctx, project, "", n)
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
@@ -1391,6 +1383,7 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
|
||||
networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("name", n.Name)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1433,21 +1426,21 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
|
||||
}
|
||||
}
|
||||
|
||||
func (s *composeService) ensureVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project, assumeYes bool) (string, error) {
|
||||
func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeConfig, project string) error {
|
||||
inspected, err := s.apiClient().VolumeInspect(ctx, volume.Name)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
if volume.External {
|
||||
return "", fmt.Errorf("external volume %q not found", volume.Name)
|
||||
return fmt.Errorf("external volume %q not found", volume.Name)
|
||||
}
|
||||
err = s.createVolume(ctx, volume)
|
||||
return volume.Name, err
|
||||
err := s.createVolume(ctx, volume)
|
||||
return err
|
||||
}
|
||||
|
||||
if volume.External {
|
||||
return volume.Name, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Volume exists with name, but let's double-check this is the expected one
|
||||
@@ -1455,86 +1448,18 @@ func (s *composeService) ensureVolume(ctx context.Context, name string, volume t
|
||||
if !ok {
|
||||
logrus.Warnf("volume %q already exists but was not created by Docker Compose. Use `external: true` to use an existing volume", volume.Name)
|
||||
}
|
||||
if ok && p != project.Name {
|
||||
logrus.Warnf("volume %q already exists but was created for project %q (expected %q). Use `external: true` to use an existing volume", volume.Name, p, project.Name)
|
||||
if ok && p != project {
|
||||
logrus.Warnf("volume %q already exists but was created for project %q (expected %q). Use `external: true` to use an existing volume", volume.Name, p, project)
|
||||
}
|
||||
|
||||
expected, err := VolumeHash(volume)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
actual, ok := inspected.Labels[api.ConfigHashLabel]
|
||||
if ok && actual != expected {
|
||||
confirm := assumeYes
|
||||
if !assumeYes {
|
||||
msg := fmt.Sprintf("Volume %q exists but doesn't match configuration in compose file. Recreate (data will be lost)?", volume.Name)
|
||||
confirm, err = prompt.NewPrompt(s.stdin(), s.stdout()).Confirm(msg, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if confirm {
|
||||
err = s.removeDivergedVolume(ctx, name, volume, project)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return volume.Name, s.createVolume(ctx, volume)
|
||||
}
|
||||
}
|
||||
return inspected.Name, nil
|
||||
}
|
||||
|
||||
func (s *composeService) removeDivergedVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project) error {
|
||||
// Remove services mounting divergent volume
|
||||
var services []string
|
||||
for _, service := range project.Services.Filter(func(config types.ServiceConfig) bool {
|
||||
for _, cfg := range config.Volumes {
|
||||
if cfg.Source == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}) {
|
||||
services = append(services, service.Name)
|
||||
}
|
||||
|
||||
err := s.stop(ctx, project.Name, api.StopOptions{
|
||||
Services: services,
|
||||
Project: project,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, services...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// FIXME (ndeloof) we have to remove container so we can recreate volume
|
||||
// but doing so we can't inherit anonymous volumes from previous instance
|
||||
err = s.remove(ctx, containers, api.RemoveOptions{
|
||||
Services: services,
|
||||
Project: project,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.apiClient().VolumeRemove(ctx, volume.Name, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *composeService) createVolume(ctx context.Context, volume types.VolumeConfig) error {
|
||||
eventName := fmt.Sprintf("Volume %q", volume.Name)
|
||||
w := progress.ContextWriter(ctx)
|
||||
w.Event(progress.CreatingEvent(eventName))
|
||||
hash, err := VolumeHash(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
volume.CustomLabels.Add(api.ConfigHashLabel, hash)
|
||||
_, err = s.apiClient().VolumeCreate(ctx, volumetypes.CreateOptions{
|
||||
Labels: mergeLabels(volume.Labels, volume.CustomLabels),
|
||||
_, err := s.apiClient().VolumeCreate(ctx, volumetypes.CreateOptions{
|
||||
Labels: volume.Labels,
|
||||
Name: volume.Name,
|
||||
Driver: volume.Driver,
|
||||
DriverOpts: volume.DriverOpts,
|
||||
|
||||
@@ -278,26 +278,33 @@ func TestDefaultNetworkSettings(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateEndpointSettings(t *testing.T) {
|
||||
eps := createEndpointSettings(&composetypes.Project{
|
||||
Name: "projName",
|
||||
}, composetypes.ServiceConfig{
|
||||
Name: "serviceName",
|
||||
ContainerName: "containerName",
|
||||
Networks: map[string]*composetypes.ServiceNetworkConfig{
|
||||
"netName": {
|
||||
Priority: 100,
|
||||
Aliases: []string{"alias1", "alias2"},
|
||||
Ipv4Address: "10.16.17.18",
|
||||
Ipv6Address: "fdb4:7a7f:373a:3f0c::42",
|
||||
LinkLocalIPs: []string{"169.254.10.20"},
|
||||
MacAddress: "10:00:00:00:01",
|
||||
DriverOpts: composetypes.Options{
|
||||
"driverOpt1": "optval1",
|
||||
"driverOpt2": "optval2",
|
||||
eps := createEndpointSettings(
|
||||
&composetypes.Project{
|
||||
Name: "projName",
|
||||
},
|
||||
composetypes.ServiceConfig{
|
||||
Name: "serviceName",
|
||||
ContainerName: "containerName",
|
||||
Networks: map[string]*composetypes.ServiceNetworkConfig{
|
||||
"netName": {
|
||||
Priority: 100,
|
||||
Aliases: []string{"alias1", "alias2"},
|
||||
Ipv4Address: "10.16.17.18",
|
||||
Ipv6Address: "fdb4:7a7f:373a:3f0c::42",
|
||||
LinkLocalIPs: []string{"169.254.10.20"},
|
||||
MacAddress: "10:00:00:00:01",
|
||||
DriverOpts: composetypes.Options{
|
||||
"driverOpt1": "optval1",
|
||||
"driverOpt2": "optval2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, 0, "netName", []string{"link1", "link2"}, true)
|
||||
0, // serviceIndex
|
||||
"netName", // networkKey
|
||||
[]string{"link1", "link2"}, // links
|
||||
true, // useNetworkAliases
|
||||
)
|
||||
assert.Check(t, cmp.DeepEqual(eps, &network.EndpointSettings{
|
||||
IPAMConfig: &network.EndpointIPAMConfig{
|
||||
IPv4Address: "10.16.17.18",
|
||||
|
||||
@@ -172,6 +172,7 @@ func (t *graphTraversal) run(ctx context.Context, graph *Graph, eg *errgroup.Gro
|
||||
continue
|
||||
}
|
||||
|
||||
node := node
|
||||
if !t.consume(node.Key) {
|
||||
// another worker already visited this node
|
||||
continue
|
||||
@@ -437,6 +438,7 @@ func (g *Graph) HasCycles() (bool, error) {
|
||||
if !utils.StringContains(discovered, vertex.Key) && !utils.StringContains(finished, vertex.Key) {
|
||||
var err error
|
||||
discovered, finished, err = g.visit(vertex.Key, path, discovered, finished)
|
||||
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
@@ -322,9 +322,10 @@ func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, s
|
||||
|
||||
func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, serv *types.ServiceConfig, containers []moby.Container, timeout *time.Duration) error {
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, ctr := range containers {
|
||||
for _, container := range containers {
|
||||
container := container
|
||||
eg.Go(func() error {
|
||||
return s.stopContainer(ctx, w, serv, ctr, timeout)
|
||||
return s.stopContainer(ctx, w, serv, container, timeout)
|
||||
})
|
||||
}
|
||||
return eg.Wait()
|
||||
@@ -332,9 +333,10 @@ func (s *composeService) stopContainers(ctx context.Context, w progress.Writer,
|
||||
|
||||
func (s *composeService) removeContainers(ctx context.Context, containers []moby.Container, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error {
|
||||
eg, _ := errgroup.WithContext(ctx)
|
||||
for _, ctr := range containers {
|
||||
for _, container := range containers {
|
||||
container := container
|
||||
eg.Go(func() error {
|
||||
return s.stopAndRemoveContainer(ctx, ctr, service, timeout, volumes)
|
||||
return s.stopAndRemoveContainer(ctx, container, service, timeout, volumes)
|
||||
})
|
||||
}
|
||||
return eg.Wait()
|
||||
|
||||
@@ -211,8 +211,7 @@ func TestDownRemoveOrphans(t *testing.T) {
|
||||
{
|
||||
Name: "myProject_default",
|
||||
Labels: map[string]string{compose.NetworkLabel: "default"},
|
||||
},
|
||||
}, nil)
|
||||
}}, nil)
|
||||
|
||||
stopOptions := containerType.StopOptions{}
|
||||
api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
|
||||
|
||||
@@ -21,8 +21,10 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
|
||||
var isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
|
||||
var (
|
||||
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
|
||||
isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
|
||||
)
|
||||
|
||||
// envResolver returns resolver for environment variables suitable for the current platform.
|
||||
// Expected to be used with `MappingWithEquals.Resolve`.
|
||||
|
||||
71
pkg/compose/errors.go
Normal file
71
pkg/compose/errors.go
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/errdefs"
|
||||
)
|
||||
|
||||
// Error error to categorize failures and extract metrics info
|
||||
type Error struct {
|
||||
Err error
|
||||
Category *FailureCategory
|
||||
}
|
||||
|
||||
// WrapComposeError wraps the error if not nil, otherwise returns nil
|
||||
func WrapComposeError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return Error{
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// WrapCategorisedComposeError wraps the error if not nil, otherwise returns nil
|
||||
func WrapCategorisedComposeError(err error, failure FailureCategory) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return Error{
|
||||
Err: err,
|
||||
Category: &failure,
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap get underlying error
|
||||
func (e Error) Unwrap() error { return e.Err }
|
||||
|
||||
func (e Error) Error() string { return e.Err.Error() }
|
||||
|
||||
// GetMetricsFailureCategory get metrics status and error code corresponding to this error
|
||||
func (e Error) GetMetricsFailureCategory() FailureCategory {
|
||||
if e.Category != nil {
|
||||
return *e.Category
|
||||
}
|
||||
var pathError *fs.PathError
|
||||
if errors.As(e.Err, &pathError) {
|
||||
return FileNotFoundFailure
|
||||
}
|
||||
if errdefs.IsNotFoundError(e.Err) {
|
||||
return FileNotFoundFailure
|
||||
}
|
||||
return ComposeParseFailure
|
||||
}
|
||||
@@ -92,6 +92,7 @@ func (s *composeService) createProjectFromContainers(containers []moby.Container
|
||||
Image: c.Image,
|
||||
Labels: c.Labels,
|
||||
}
|
||||
|
||||
}
|
||||
service.Scale = increment(service.Scale)
|
||||
|
||||
@@ -171,8 +172,7 @@ func (s *composeService) toComposeHealthCheck(healthConfig *containerType.Health
|
||||
}
|
||||
|
||||
func (s *composeService) toComposeVolumes(volumes []moby.MountPoint) (map[string]types.VolumeConfig,
|
||||
[]types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig,
|
||||
) {
|
||||
[]types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig) {
|
||||
volumeConfigs := make(map[string]types.VolumeConfig)
|
||||
secretConfigs := make(map[string]types.SecretConfig)
|
||||
var serviceVolumeConfigs []types.ServiceVolumeConfig
|
||||
@@ -227,6 +227,7 @@ func (s *composeService) toComposeNetwork(networks map[string]*network.EndpointS
|
||||
networkConfigs[name] = types.NetworkConfig{
|
||||
Internal: inspect.Internal,
|
||||
}
|
||||
|
||||
}
|
||||
serviceNetworkConfigs[name] = &types.ServiceNetworkConfig{
|
||||
Aliases: net.Aliases,
|
||||
|
||||
@@ -42,7 +42,6 @@ func ServiceHash(o types.ServiceConfig) (string, error) {
|
||||
return digest.SHA256.FromBytes(bytes).Encoded(), nil
|
||||
}
|
||||
|
||||
// NetworkHash computes the configuration hash for a network.
|
||||
func NetworkHash(o *types.NetworkConfig) (string, error) {
|
||||
bytes, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
@@ -50,15 +49,3 @@ func NetworkHash(o *types.NetworkConfig) (string, error) {
|
||||
}
|
||||
return digest.SHA256.FromBytes(bytes).Encoded(), nil
|
||||
}
|
||||
|
||||
// VolumeHash computes the configuration hash for a volume.
|
||||
func VolumeHash(o types.VolumeConfig) (string, error) {
|
||||
if o.Driver == "" { // (TODO: jhrotko) This probably should be fixed in compose-go
|
||||
o.Driver = "local"
|
||||
}
|
||||
bytes, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return digest.SHA256.FromBytes(bytes).Encoded(), nil
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ func (p *ImagePruner) filterImagesByExistence(ctx context.Context, imageNames []
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, img := range imageNames {
|
||||
img := img
|
||||
eg.Go(func() error {
|
||||
_, _, err := p.client.ImageInspectWithRaw(ctx, img)
|
||||
if errdefs.IsNotFound(err) {
|
||||
|
||||
@@ -48,6 +48,7 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
|
||||
for _, c := range allContainers {
|
||||
if utils.StringContains(options.Services, c.Labels[api.ServiceLabel]) {
|
||||
containers = append(containers, c)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -82,6 +83,7 @@ func (s *composeService) getImageSummaries(ctx context.Context, repoTags []strin
|
||||
l := sync.Mutex{}
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, repoTag := range repoTags {
|
||||
repoTag := repoTag
|
||||
eg.Go(func() error {
|
||||
inspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, repoTag)
|
||||
if err != nil {
|
||||
@@ -93,12 +95,12 @@ func (s *composeService) getImageSummaries(ctx context.Context, repoTags []strin
|
||||
tag := ""
|
||||
repository := ""
|
||||
ref, err := reference.ParseDockerRef(repoTag)
|
||||
if err == nil {
|
||||
// ParseDockerRef will reject a local image ID
|
||||
repository = reference.FamiliarName(ref)
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repository = reference.FamiliarName(ref)
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
l.Lock()
|
||||
summary[repoTag] = api.ImageSummary{
|
||||
|
||||
@@ -123,8 +123,7 @@ func containerLabels(service string, oneOff bool) map[string]string {
|
||||
compose.ServiceLabel: service,
|
||||
compose.ConfigFilesLabel: composefile,
|
||||
compose.WorkingDirLabel: workingdir,
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
}
|
||||
compose.ProjectLabel: strings.ToLower(testProject)}
|
||||
if oneOff {
|
||||
labels[compose.OneoffLabel] = "True"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ func (s *composeService) Logs(
|
||||
consumer api.LogConsumer,
|
||||
options api.LogOptions,
|
||||
) error {
|
||||
|
||||
var containers Containers
|
||||
var err error
|
||||
|
||||
@@ -62,12 +63,13 @@ func (s *composeService) Logs(
|
||||
}
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, ctr := range containers {
|
||||
for _, c := range containers {
|
||||
c := c
|
||||
eg.Go(func() error {
|
||||
err := s.logContainers(ctx, consumer, ctr, options)
|
||||
err := s.logContainers(ctx, consumer, c, options)
|
||||
var notImplErr errdefs.ErrNotImplemented
|
||||
if errors.As(err, ¬ImplErr) {
|
||||
logrus.Warnf("Can't retrieve logs for %q: %s", getCanonicalContainerName(ctr), err.Error())
|
||||
logrus.Warnf("Can't retrieve logs for %q: %s", getCanonicalContainerName(c), err.Error())
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -134,6 +134,7 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) {
|
||||
)
|
||||
|
||||
for _, id := range []string{"c1", "c2", "c4"} {
|
||||
id := id
|
||||
api.EXPECT().
|
||||
ContainerInspect(anyCancellableContext(), id).
|
||||
Return(
|
||||
|
||||
79
pkg/compose/metrics.go
Normal file
79
pkg/compose/metrics.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
|
||||
// FailureCategory struct regrouping metrics failure status and specific exit code
|
||||
type FailureCategory struct {
|
||||
MetricsStatus string
|
||||
ExitCode int
|
||||
}
|
||||
|
||||
const (
|
||||
// APISource is sent for API metrics
|
||||
APISource = "api"
|
||||
// SuccessStatus command success
|
||||
SuccessStatus = "success"
|
||||
// FailureStatus command failure
|
||||
FailureStatus = "failure"
|
||||
// ComposeParseFailureStatus failure while parsing compose file
|
||||
ComposeParseFailureStatus = "failure-compose-parse"
|
||||
// FileNotFoundFailureStatus failure getting compose file
|
||||
FileNotFoundFailureStatus = "failure-file-not-found"
|
||||
// CommandSyntaxFailureStatus failure reading command
|
||||
CommandSyntaxFailureStatus = "failure-cmd-syntax"
|
||||
// BuildFailureStatus failure building image
|
||||
BuildFailureStatus = "failure-build"
|
||||
// PullFailureStatus failure pulling image
|
||||
PullFailureStatus = "failure-pull"
|
||||
// CanceledStatus command canceled
|
||||
CanceledStatus = "canceled"
|
||||
)
|
||||
|
||||
var (
|
||||
// FileNotFoundFailure failure for compose file not found
|
||||
FileNotFoundFailure = FailureCategory{MetricsStatus: FileNotFoundFailureStatus, ExitCode: 14}
|
||||
// ComposeParseFailure failure for composefile parse error
|
||||
ComposeParseFailure = FailureCategory{MetricsStatus: ComposeParseFailureStatus, ExitCode: 15}
|
||||
// CommandSyntaxFailure failure for command line syntax
|
||||
CommandSyntaxFailure = FailureCategory{MetricsStatus: CommandSyntaxFailureStatus, ExitCode: 16}
|
||||
// BuildFailure failure while building images.
|
||||
BuildFailure = FailureCategory{MetricsStatus: BuildFailureStatus, ExitCode: 17}
|
||||
// PullFailure failure while pulling image
|
||||
PullFailure = FailureCategory{MetricsStatus: PullFailureStatus, ExitCode: 18}
|
||||
)
|
||||
|
||||
// ByExitCode retrieve FailureCategory based on command exit code
|
||||
func ByExitCode(exitCode int) FailureCategory {
|
||||
switch exitCode {
|
||||
case 0:
|
||||
return FailureCategory{MetricsStatus: SuccessStatus, ExitCode: 0}
|
||||
case 14:
|
||||
return FileNotFoundFailure
|
||||
case 15:
|
||||
return ComposeParseFailure
|
||||
case 16:
|
||||
return CommandSyntaxFailure
|
||||
case 17:
|
||||
return BuildFailure
|
||||
case 18:
|
||||
return PullFailure
|
||||
case 130:
|
||||
return FailureCategory{MetricsStatus: CanceledStatus, ExitCode: exitCode}
|
||||
default:
|
||||
return FailureCategory{MetricsStatus: FailureStatus, ExitCode: exitCode}
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ func (s *composeService) pause(ctx context.Context, projectName string, options
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
})
|
||||
return eg.Wait()
|
||||
}
|
||||
@@ -85,6 +86,7 @@ func (s *composeService) unPause(ctx context.Context, projectName string, option
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
})
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
|
||||
summary := make([]api.ContainerSummary, len(containers))
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for i, container := range containers {
|
||||
i, container := i, container
|
||||
eg.Go(func() error {
|
||||
publishers := make([]api.PortPublisher, len(container.Ports))
|
||||
sort.Slice(container.Ports, func(i, j int) bool {
|
||||
|
||||
@@ -55,8 +55,7 @@ func TestPs(t *testing.T) {
|
||||
containers, err := tested.Ps(ctx, strings.ToLower(testProject), compose.PsOptions{})
|
||||
|
||||
expected := []compose.ContainerSummary{
|
||||
{
|
||||
ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
{ID: "123", Name: "123", Names: []string{"/123"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
State: "running", Health: "healthy", Publishers: []compose.PortPublisher{},
|
||||
Labels: map[string]string{
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
@@ -65,8 +64,7 @@ func TestPs(t *testing.T) {
|
||||
compose.ServiceLabel: "service1",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
{ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
|
||||
State: "running", Health: "",
|
||||
Publishers: []compose.PortPublisher{{URL: "localhost", TargetPort: 90, PublishedPort: 80}},
|
||||
Labels: map[string]string{
|
||||
@@ -76,8 +74,7 @@ func TestPs(t *testing.T) {
|
||||
compose.ServiceLabel: "service1",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2",
|
||||
{ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2",
|
||||
State: "exited", Health: "", ExitCode: 130, Publishers: []compose.PortPublisher{},
|
||||
Labels: map[string]string{
|
||||
compose.ProjectLabel: strings.ToLower(testProject),
|
||||
|
||||
@@ -18,17 +18,14 @@ package compose
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/buildx/util/imagetools"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/compose/v2/internal/ocipush"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/prompt"
|
||||
)
|
||||
|
||||
func (s *composeService) Publish(ctx context.Context, project *types.Project, repository string, options api.PublishOptions) error {
|
||||
@@ -38,14 +35,7 @@ func (s *composeService) Publish(ctx context.Context, project *types.Project, re
|
||||
}
|
||||
|
||||
func (s *composeService) publish(ctx context.Context, project *types.Project, repository string, options api.PublishOptions) error {
|
||||
accept, err := s.preChecks(project, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !accept {
|
||||
return nil
|
||||
}
|
||||
err = s.Push(ctx, project, api.PushOptions{IgnoreFailures: true, ImageMandatory: true})
|
||||
err := s.Push(ctx, project, api.PushOptions{IgnoreFailures: true, ImageMandatory: true})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -73,10 +63,6 @@ func (s *composeService) publish(ctx context.Context, project *types.Project, re
|
||||
})
|
||||
}
|
||||
|
||||
if options.WithEnvironment {
|
||||
layers = append(layers, envFileLayers(project)...)
|
||||
}
|
||||
|
||||
if options.ResolveImageDigests {
|
||||
yaml, err := s.generateImageDigestsOverride(ctx, project)
|
||||
if err != nil {
|
||||
@@ -134,83 +120,3 @@ func (s *composeService) generateImageDigestsOverride(ctx context.Context, proje
|
||||
}
|
||||
return override.MarshalYAML()
|
||||
}
|
||||
|
||||
func (s *composeService) preChecks(project *types.Project, options api.PublishOptions) (bool, error) {
|
||||
envVariables, err := s.checkEnvironmentVariables(project, options)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !options.AssumeYes && len(envVariables) > 0 {
|
||||
fmt.Println("you are about to publish environment variables within your OCI artifact.\n" +
|
||||
"please double check that you are not leaking sensitive data")
|
||||
for key, val := range envVariables {
|
||||
_, _ = fmt.Fprintln(s.dockerCli.Out(), "Service/Config ", key)
|
||||
for k, v := range val {
|
||||
_, _ = fmt.Fprintf(s.dockerCli.Out(), "%s=%v\n", k, *v)
|
||||
}
|
||||
}
|
||||
return acceptPublishEnvVariables(s.dockerCli)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *composeService) checkEnvironmentVariables(project *types.Project, options api.PublishOptions) (map[string]types.MappingWithEquals, error) {
|
||||
envVarList := map[string]types.MappingWithEquals{}
|
||||
errorList := map[string][]string{}
|
||||
|
||||
for _, service := range project.Services {
|
||||
if len(service.EnvFiles) > 0 {
|
||||
errorList[service.Name] = append(errorList[service.Name], fmt.Sprintf("service %q has env_file declared.", service.Name))
|
||||
}
|
||||
if len(service.Environment) > 0 {
|
||||
errorList[service.Name] = append(errorList[service.Name], fmt.Sprintf("service %q has environment variable(s) declared.", service.Name))
|
||||
envVarList[service.Name] = service.Environment
|
||||
}
|
||||
}
|
||||
|
||||
for _, config := range project.Configs {
|
||||
if config.Environment != "" {
|
||||
errorList[config.Name] = append(errorList[config.Name], fmt.Sprintf("config %q is declare as an environment variable.", config.Name))
|
||||
envVarList[config.Name] = types.NewMappingWithEquals([]string{fmt.Sprintf("%s=%s", config.Name, config.Environment)})
|
||||
}
|
||||
}
|
||||
|
||||
if !options.WithEnvironment && len(errorList) > 0 {
|
||||
errorMsgSuffix := "To avoid leaking sensitive data, you must either explicitly allow the sending of environment variables by using the --with-env flag,\n" +
|
||||
"or remove sensitive data from your Compose configuration"
|
||||
errorMsg := ""
|
||||
for _, errors := range errorList {
|
||||
for _, err := range errors {
|
||||
errorMsg += fmt.Sprintf("%s\n", err)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("%s%s", errorMsg, errorMsgSuffix)
|
||||
|
||||
}
|
||||
return envVarList, nil
|
||||
}
|
||||
|
||||
func acceptPublishEnvVariables(cli command.Cli) (bool, error) {
|
||||
msg := "Are you ok to publish these environment variables? [y/N]: "
|
||||
confirm, err := prompt.NewPrompt(cli.In(), cli.Out()).Confirm(msg, false)
|
||||
return confirm, err
|
||||
}
|
||||
|
||||
func envFileLayers(project *types.Project) []ocipush.Pushable {
|
||||
var layers []ocipush.Pushable
|
||||
for _, service := range project.Services {
|
||||
for _, envFile := range service.EnvFiles {
|
||||
f, err := os.ReadFile(envFile.Path)
|
||||
if err != nil {
|
||||
// if we can't read the file, skip to the next one
|
||||
continue
|
||||
}
|
||||
layerDescriptor := ocipush.DescriptorForEnvFile(envFile.Path, f)
|
||||
layers = append(layers, ocipush.Pushable{
|
||||
Descriptor: layerDescriptor,
|
||||
Data: f,
|
||||
})
|
||||
}
|
||||
}
|
||||
return layers
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ import (
|
||||
)
|
||||
|
||||
func (s *composeService) Pull(ctx context.Context, project *types.Project, options api.PullOptions) error {
|
||||
if options.Quiet {
|
||||
return s.pull(ctx, project, options)
|
||||
}
|
||||
return progress.RunWithTitle(ctx, func(ctx context.Context) error {
|
||||
return s.pull(ctx, project, options)
|
||||
}, s.stdinfo(), "Pulling")
|
||||
@@ -113,9 +116,9 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
||||
|
||||
imagesBeingPulled[service.Image] = service.Name
|
||||
|
||||
idx := i
|
||||
idx, name, service := i, name, service
|
||||
eg.Go(func() error {
|
||||
_, err := s.pullServiceImage(ctx, service, s.configFile(), w, opts.Quiet, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
_, err := s.pullServiceImage(ctx, service, s.configFile(), w, false, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
if err != nil {
|
||||
pullErrors[idx] = err
|
||||
if service.Build != nil {
|
||||
@@ -175,8 +178,7 @@ func getUnwrappedErrorMessage(err error) string {
|
||||
}
|
||||
|
||||
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig,
|
||||
configFile driver.Auth, w progress.Writer, quietPull bool, defaultPlatform string,
|
||||
) (string, error) {
|
||||
configFile driver.Auth, w progress.Writer, quietPull bool, defaultPlatform string) (string, error) {
|
||||
w.Event(progress.Event{
|
||||
ID: service.Name,
|
||||
Status: progress.Working,
|
||||
@@ -211,7 +213,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
||||
Text: "Warning",
|
||||
StatusText: getUnwrappedErrorMessage(err),
|
||||
})
|
||||
return "", err
|
||||
return "", WrapCategorisedComposeError(err, PullFailure)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -221,7 +223,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
||||
Text: "Error",
|
||||
StatusText: getUnwrappedErrorMessage(err),
|
||||
})
|
||||
return "", err
|
||||
return "", WrapCategorisedComposeError(err, PullFailure)
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(stream)
|
||||
@@ -231,10 +233,10 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
return "", err
|
||||
return "", WrapCategorisedComposeError(err, PullFailure)
|
||||
}
|
||||
if jm.Error != nil {
|
||||
return "", errors.New(jm.Error.Message)
|
||||
return "", WrapCategorisedComposeError(errors.New(jm.Error.Message), PullFailure)
|
||||
}
|
||||
if !quietPull {
|
||||
toPullProgressEvent(service.Name, jm, w)
|
||||
@@ -316,6 +318,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types.
|
||||
eg.SetLimit(s.maxConcurrency)
|
||||
pulledImages := make([]string, len(needPull))
|
||||
for i, service := range needPull {
|
||||
i, service := i, service
|
||||
eg.Go(func() error {
|
||||
id, err := s.pullServiceImage(ctx, service, s.configFile(), w, quietPull, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
pulledImages[i] = id
|
||||
|
||||
@@ -72,12 +72,14 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
||||
})
|
||||
continue
|
||||
}
|
||||
service := service
|
||||
tags := []string{service.Image}
|
||||
if service.Build != nil {
|
||||
tags = append(tags, service.Build.Tags...)
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
tag := tag
|
||||
eg.Go(func() error {
|
||||
err := s.pushServiceImage(ctx, tag, info, s.configFile(), w, options.Quiet)
|
||||
if err != nil {
|
||||
|
||||
@@ -102,11 +102,12 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options
|
||||
func (s *composeService) remove(ctx context.Context, containers Containers, options api.RemoveOptions) error {
|
||||
w := progress.ContextWriter(ctx)
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, ctr := range containers {
|
||||
for _, container := range containers {
|
||||
container := container
|
||||
eg.Go(func() error {
|
||||
eventName := getContainerProgressName(ctr)
|
||||
eventName := getContainerProgressName(container)
|
||||
w.Event(progress.RemovingEvent(eventName))
|
||||
err := s.apiClient().ContainerRemove(ctx, ctr.ID, containerType.RemoveOptions{
|
||||
err := s.apiClient().ContainerRemove(ctx, container.ID, containerType.RemoveOptions{
|
||||
RemoveVolumes: options.Volumes,
|
||||
Force: options.Force,
|
||||
})
|
||||
|
||||
@@ -78,17 +78,17 @@ func (s *composeService) restart(ctx context.Context, projectName string, option
|
||||
w := progress.ContextWriter(ctx)
|
||||
return InDependencyOrder(ctx, project, func(c context.Context, service string) error {
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, ctr := range containers.filter(isService(service)) {
|
||||
for _, container := range containers.filter(isService(service)) {
|
||||
container := container
|
||||
eg.Go(func() error {
|
||||
eventName := getContainerProgressName(ctr)
|
||||
eventName := getContainerProgressName(container)
|
||||
w.Event(progress.RestartingEvent(eventName))
|
||||
timeout := utils.DurationSecondToInt(options.Timeout)
|
||||
err := s.apiClient().ContainerRestart(ctx, ctr.ID, containerType.StopOptions{Timeout: timeout})
|
||||
if err != nil {
|
||||
return err
|
||||
err := s.apiClient().ContainerRestart(ctx, container.ID, containerType.StopOptions{Timeout: timeout})
|
||||
if err == nil {
|
||||
w.Event(progress.StartedEvent(eventName))
|
||||
}
|
||||
w.Event(progress.StartedEvent(eventName))
|
||||
return nil
|
||||
return err
|
||||
})
|
||||
}
|
||||
return eg.Wait()
|
||||
|
||||
@@ -104,7 +104,7 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project,
|
||||
Labels: mergeLabels(service.Labels, service.CustomLabels),
|
||||
}
|
||||
|
||||
err = newConvergence(project.ServiceNames(), observedState, nil, nil, s).resolveServiceReferences(&service)
|
||||
err = newConvergence(project.ServiceNames(), observedState, nil, s).resolveServiceReferences(&service)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -31,5 +31,6 @@ func (s *composeService) Scale(ctx context.Context, project *types.Project, opti
|
||||
return err
|
||||
}
|
||||
return s.start(ctx, project.Name, api.StartOptions{Project: project, Services: options.Services}, nil)
|
||||
|
||||
}), s.stdinfo())
|
||||
}
|
||||
|
||||
@@ -180,8 +180,7 @@ type containerWatchFn func(container moby.Container, t time.Time) error
|
||||
// watchContainers uses engine events to capture container start/die and notify ContainerEventListener
|
||||
func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo
|
||||
projectName string, services, required []string,
|
||||
listener api.ContainerEventListener, containers Containers, onStart, onRecreate containerWatchFn,
|
||||
) error {
|
||||
listener api.ContainerEventListener, containers Containers, onStart, onRecreate containerWatchFn) error {
|
||||
if len(containers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -36,15 +36,16 @@ func (s *composeService) Top(ctx context.Context, projectName string, services [
|
||||
}
|
||||
summary := make([]api.ContainerProcSummary, len(containers))
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for i, ctr := range containers {
|
||||
for i, container := range containers {
|
||||
i, container := i, container
|
||||
eg.Go(func() error {
|
||||
topContent, err := s.apiClient().ContainerTop(ctx, ctr.ID, []string{})
|
||||
topContent, err := s.apiClient().ContainerTop(ctx, container.ID, []string{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
summary[i] = api.ContainerProcSummary{
|
||||
ID: ctr.ID,
|
||||
Name: getCanonicalContainerName(ctr),
|
||||
ID: container.ID,
|
||||
Name: getCanonicalContainerName(container),
|
||||
Processes: topContent.Processes,
|
||||
Titles: topContent.Titles,
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ type vizGraph map[*types.ServiceConfig][]*types.ServiceConfig
|
||||
func (s *composeService) Viz(_ context.Context, project *types.Project, opts api.VizOptions) (string, error) {
|
||||
graph := make(vizGraph)
|
||||
for _, service := range project.Services {
|
||||
service := service
|
||||
graph[&service] = make([]*types.ServiceConfig, 0, len(service.DependsOn))
|
||||
for dependencyName := range service.DependsOn {
|
||||
// no error should be returned since dependencyName should exist
|
||||
|
||||
@@ -35,14 +35,15 @@ func (s *composeService) Wait(ctx context.Context, projectName string, options a
|
||||
|
||||
eg, waitCtx := errgroup.WithContext(ctx)
|
||||
var statusCode int64
|
||||
for _, ctr := range containers {
|
||||
for _, c := range containers {
|
||||
c := c
|
||||
eg.Go(func() error {
|
||||
var err error
|
||||
resultC, errC := s.dockerCli.Client().ContainerWait(waitCtx, ctr.ID, "")
|
||||
resultC, errC := s.dockerCli.Client().ContainerWait(waitCtx, c.ID, "")
|
||||
|
||||
select {
|
||||
case result := <-resultC:
|
||||
_, _ = fmt.Fprintf(s.dockerCli.Out(), "container %q exited with status code %d\n", ctr.ID, result.StatusCode)
|
||||
_, _ = fmt.Fprintf(s.dockerCli.Out(), "container %q exited with status code %d\n", c.ID, result.StatusCode)
|
||||
statusCode = result.StatusCode
|
||||
case err = <-errC:
|
||||
}
|
||||
|
||||
@@ -23,14 +23,12 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/compose-spec/compose-go/v2/utils"
|
||||
ccli "github.com/docker/cli/cli/command/container"
|
||||
pathutil "github.com/docker/compose/v2/internal/paths"
|
||||
"github.com/docker/compose/v2/internal/sync"
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
@@ -39,11 +37,20 @@ import (
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/jonboulle/clockwork"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const quietPeriod = 500 * time.Millisecond
|
||||
|
||||
// fileEvent contains the Compose service and modified host system path.
|
||||
type fileEvent struct {
|
||||
sync.PathMapping
|
||||
Action types.WatchAction
|
||||
}
|
||||
|
||||
// getSyncImplementation returns an appropriate sync implementation for the
|
||||
// project.
|
||||
//
|
||||
@@ -62,7 +69,6 @@ func (s *composeService) getSyncImplementation(project *types.Project) (sync.Syn
|
||||
|
||||
return sync.NewTar(project.Name, tarDockerClient{s: s}), nil
|
||||
}
|
||||
|
||||
func (s *composeService) shouldWatch(project *types.Project) bool {
|
||||
var shouldWatch bool
|
||||
for i := range project.Services {
|
||||
@@ -78,45 +84,6 @@ func (s *composeService) shouldWatch(project *types.Project) bool {
|
||||
func (s *composeService) Watch(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error {
|
||||
return s.watch(ctx, nil, project, services, options)
|
||||
}
|
||||
|
||||
type watchRule struct {
|
||||
types.Trigger
|
||||
ignore watch.PathMatcher
|
||||
service string
|
||||
}
|
||||
|
||||
func (r watchRule) Matches(event watch.FileEvent) *sync.PathMapping {
|
||||
hostPath := string(event)
|
||||
if !pathutil.IsChild(r.Path, hostPath) {
|
||||
return nil
|
||||
}
|
||||
isIgnored, err := r.ignore.Matches(hostPath)
|
||||
if err != nil {
|
||||
logrus.Warnf("error ignore matching %q: %v", hostPath, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if isIgnored {
|
||||
logrus.Debugf("%s is matching ignore pattern", hostPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
var containerPath string
|
||||
if r.Target != "" {
|
||||
rel, err := filepath.Rel(r.Path, hostPath)
|
||||
if err != nil {
|
||||
logrus.Warnf("error making %s relative to %s: %v", hostPath, r.Path, err)
|
||||
return nil
|
||||
}
|
||||
// always use Unix-style paths for inside the container
|
||||
containerPath = path.Join(r.Target, filepath.ToSlash(rel))
|
||||
}
|
||||
return &sync.PathMapping{
|
||||
HostPath: hostPath,
|
||||
ContainerPath: containerPath,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *composeService) watch(ctx context.Context, syncChannel chan bool, project *types.Project, services []string, options api.WatchOptions) error { //nolint: gocyclo
|
||||
var err error
|
||||
if project, err = project.WithSelectedServices(services); err != nil {
|
||||
@@ -127,13 +94,10 @@ func (s *composeService) watch(ctx context.Context, syncChannel chan bool, proje
|
||||
return err
|
||||
}
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
watching := false
|
||||
options.LogTo.Register(api.WatchLogger)
|
||||
|
||||
var (
|
||||
rules []watchRule
|
||||
paths []string
|
||||
)
|
||||
for serviceName, service := range project.Services {
|
||||
for i := range project.Services {
|
||||
service := project.Services[i]
|
||||
config, err := loadDevelopmentConfig(service, project)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -155,60 +119,87 @@ func (s *composeService) watch(ctx context.Context, syncChannel chan bool, proje
|
||||
if options.Build == nil {
|
||||
return fmt.Errorf("--no-build is incompatible with watch action %s in service %s", types.WatchActionRebuild, service.Name)
|
||||
}
|
||||
// set the service to always be built - watch triggers `Up()` when it receives a rebuild event
|
||||
service.PullPolicy = types.PullPolicyBuild
|
||||
project.Services[serviceName] = service
|
||||
}
|
||||
}
|
||||
|
||||
if len(services) > 0 && service.Build == nil {
|
||||
// service explicitly selected for watch has no build section
|
||||
return fmt.Errorf("can't watch service %q without a build context", service.Name)
|
||||
}
|
||||
|
||||
if len(services) == 0 && service.Build == nil {
|
||||
logrus.Debugf("service %q has no build context, skipping watch", service.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// set the service to always be built - watch triggers `Up()` when it receives a rebuild event
|
||||
service.PullPolicy = types.PullPolicyBuild
|
||||
project.Services[i] = service
|
||||
|
||||
dockerIgnores, err := watch.LoadDockerIgnore(service.Build)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add a hardcoded set of ignores on top of what came from .dockerignore
|
||||
// some of this should likely be configurable (e.g. there could be cases
|
||||
// where you want `.git` to be synced) but this is suitable for now
|
||||
dotGitIgnore, err := watch.NewDockerPatternMatcher("/", []string{".git/"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ignore := watch.NewCompositeMatcher(
|
||||
dockerIgnores,
|
||||
watch.EphemeralPathMatcher(),
|
||||
dotGitIgnore,
|
||||
)
|
||||
|
||||
var paths, pathLogs []string
|
||||
for _, trigger := range config.Watch {
|
||||
if isSync(trigger) && checkIfPathAlreadyBindMounted(trigger.Path, service.Volumes) {
|
||||
if trigger.Action != types.WatchActionRebuild && checkIfPathAlreadyBindMounted(trigger.Path, service.Volumes) {
|
||||
logrus.Warnf("path '%s' also declared by a bind mount volume, this path won't be monitored!\n", trigger.Path)
|
||||
continue
|
||||
} else {
|
||||
var initialSync bool
|
||||
success, err := trigger.Extensions.Get("x-initialSync", &initialSync)
|
||||
if err == nil && success && initialSync && isSync(trigger) {
|
||||
if err == nil && success && initialSync && (trigger.Action == types.WatchActionSync || trigger.Action == types.WatchActionSyncRestart) {
|
||||
// Need to check initial files are in container that are meant to be synched from watch action
|
||||
err := s.initialSync(ctx, project, service, trigger, syncer)
|
||||
err := s.initialSync(ctx, project, service, trigger, ignore, syncer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
paths = append(paths, trigger.Path)
|
||||
pathLogs = append(pathLogs, fmt.Sprintf("Action %s for path %q", trigger.Action, trigger.Path))
|
||||
}
|
||||
|
||||
serviceWatchRules, err := getWatchRules(config, service)
|
||||
watcher, err := watch.NewWatcher(paths, ignore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rules = append(rules, serviceWatchRules...)
|
||||
}
|
||||
|
||||
if len(paths) == 0 {
|
||||
logrus.Debugf("Watch configuration for service %q:%s\n",
|
||||
service.Name,
|
||||
strings.Join(append([]string{""}, pathLogs...), "\n - "),
|
||||
)
|
||||
err = watcher.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
watching = true
|
||||
eg.Go(func() error {
|
||||
defer func() {
|
||||
if err := watcher.Close(); err != nil {
|
||||
logrus.Debugf("Error closing watcher for service %s: %v", service.Name, err)
|
||||
}
|
||||
}()
|
||||
return s.watchEvents(ctx, project, service.Name, options, watcher, syncer, config.Watch)
|
||||
})
|
||||
}
|
||||
if !watching {
|
||||
return fmt.Errorf("none of the selected services is configured for watch, consider setting an 'develop' section")
|
||||
}
|
||||
|
||||
watcher, err := watch.NewWatcher(paths)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = watcher.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := watcher.Close(); err != nil {
|
||||
logrus.Debugf("Error closing watcher: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
eg.Go(func() error {
|
||||
return s.watchEvents(ctx, project, options, watcher, syncer, rules)
|
||||
})
|
||||
options.LogTo.Log(api.WatchLogger, "Watch enabled")
|
||||
|
||||
for {
|
||||
@@ -222,73 +213,99 @@ func (s *composeService) watch(ctx context.Context, syncChannel chan bool, proje
|
||||
}
|
||||
}
|
||||
|
||||
func getWatchRules(config *types.DevelopConfig, service types.ServiceConfig) ([]watchRule, error) {
|
||||
var rules []watchRule
|
||||
|
||||
dockerIgnores, err := watch.LoadDockerIgnore(service.Build)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// add a hardcoded set of ignores on top of what came from .dockerignore
|
||||
// some of this should likely be configurable (e.g. there could be cases
|
||||
// where you want `.git` to be synced) but this is suitable for now
|
||||
dotGitIgnore, err := watch.NewDockerPatternMatcher("/", []string{".git/"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, trigger := range config.Watch {
|
||||
ignore, err := watch.NewDockerPatternMatcher(trigger.Path, trigger.Ignore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rules = append(rules, watchRule{
|
||||
Trigger: trigger,
|
||||
ignore: watch.NewCompositeMatcher(
|
||||
dockerIgnores,
|
||||
watch.EphemeralPathMatcher(),
|
||||
dotGitIgnore,
|
||||
ignore,
|
||||
),
|
||||
service: service.Name,
|
||||
})
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func isSync(trigger types.Trigger) bool {
|
||||
return trigger.Action == types.WatchActionSync || trigger.Action == types.WatchActionSyncRestart
|
||||
}
|
||||
|
||||
func (s *composeService) watchEvents(ctx context.Context, project *types.Project, options api.WatchOptions, watcher watch.Notify, syncer sync.Syncer, rules []watchRule) error {
|
||||
func (s *composeService) watchEvents(ctx context.Context, project *types.Project, name string, options api.WatchOptions, watcher watch.Notify, syncer sync.Syncer, triggers []types.Trigger) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// debounce and group filesystem events so that we capture IDE saving many files as one "batch" event
|
||||
batchEvents := watch.BatchDebounceEvents(ctx, s.clock, watcher.Events())
|
||||
ignores := make([]watch.PathMatcher, len(triggers))
|
||||
for i, trigger := range triggers {
|
||||
ignore, err := watch.NewDockerPatternMatcher(trigger.Path, trigger.Ignore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ignores[i] = ignore
|
||||
}
|
||||
|
||||
events := make(chan fileEvent)
|
||||
batchEvents := batchDebounceEvents(ctx, s.clock, quietPeriod, events)
|
||||
quit := make(chan bool)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
quit <- true
|
||||
return
|
||||
case batch := <-batchEvents:
|
||||
start := time.Now()
|
||||
logrus.Debugf("batch start: service[%s] count[%d]", name, len(batch))
|
||||
if err := s.handleWatchBatch(ctx, project, name, options, batch, syncer); err != nil {
|
||||
logrus.Warnf("Error handling changed files for service %s: %v", name, err)
|
||||
}
|
||||
logrus.Debugf("batch complete: service[%s] duration[%s] count[%d]",
|
||||
name, time.Since(start), len(batch))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-quit:
|
||||
options.LogTo.Log(api.WatchLogger, "Watch disabled")
|
||||
return nil
|
||||
case err := <-watcher.Errors():
|
||||
options.LogTo.Err(api.WatchLogger, "Watch disabled with errors")
|
||||
return err
|
||||
case batch := <-batchEvents:
|
||||
start := time.Now()
|
||||
logrus.Debugf("batch start: count[%d]", len(batch))
|
||||
err := s.handleWatchBatch(ctx, project, options, batch, rules, syncer)
|
||||
if err != nil {
|
||||
logrus.Warnf("Error handling changed files: %v", err)
|
||||
case event := <-watcher.Events():
|
||||
hostPath := event.Path()
|
||||
for i, trigger := range triggers {
|
||||
logrus.Debugf("change for %s - comparing with %s", hostPath, trigger.Path)
|
||||
if fileEvent := maybeFileEvent(trigger, hostPath, ignores[i]); fileEvent != nil {
|
||||
events <- *fileEvent
|
||||
}
|
||||
}
|
||||
logrus.Debugf("batch complete: duration[%s] count[%d]", time.Since(start), len(batch))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybeFileEvent returns a file event object if hostPath is valid for the provided trigger and ignore
|
||||
// rules.
|
||||
//
|
||||
// Any errors are logged as warnings and nil (no file event) is returned.
|
||||
func maybeFileEvent(trigger types.Trigger, hostPath string, ignore watch.PathMatcher) *fileEvent {
|
||||
if !pathutil.IsChild(trigger.Path, hostPath) {
|
||||
return nil
|
||||
}
|
||||
isIgnored, err := ignore.Matches(hostPath)
|
||||
if err != nil {
|
||||
logrus.Warnf("error ignore matching %q: %v", hostPath, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if isIgnored {
|
||||
logrus.Debugf("%s is matching ignore pattern", hostPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
var containerPath string
|
||||
if trigger.Target != "" {
|
||||
rel, err := filepath.Rel(trigger.Path, hostPath)
|
||||
if err != nil {
|
||||
logrus.Warnf("error making %s relative to %s: %v", hostPath, trigger.Path, err)
|
||||
return nil
|
||||
}
|
||||
// always use Unix-style paths for inside the container
|
||||
containerPath = path.Join(trigger.Target, filepath.ToSlash(rel))
|
||||
}
|
||||
|
||||
return &fileEvent{
|
||||
Action: trigger.Action,
|
||||
PathMapping: sync.PathMapping{
|
||||
HostPath: hostPath,
|
||||
ContainerPath: containerPath,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func loadDevelopmentConfig(service types.ServiceConfig, project *types.Project) (*types.DevelopConfig, error) {
|
||||
var config types.DevelopConfig
|
||||
y, ok := service.Extensions["x-develop"]
|
||||
@@ -319,10 +336,7 @@ func loadDevelopmentConfig(service types.ServiceConfig, project *types.Project)
|
||||
}
|
||||
|
||||
if trigger.Action == types.WatchActionRebuild && service.Build == nil {
|
||||
return nil, fmt.Errorf("service %s doesn't have a build section, can't apply %s on watch", types.WatchActionRebuild, service.Name)
|
||||
}
|
||||
if trigger.Action == types.WatchActionSyncExec && len(trigger.Exec.Command) == 0 {
|
||||
return nil, fmt.Errorf("can't watch with action %q on service %s wihtout a command", types.WatchActionSyncExec, service.Name)
|
||||
return nil, fmt.Errorf("service %s doesn't have a build section, can't apply 'rebuild' on watch", service.Name)
|
||||
}
|
||||
|
||||
config.Watch[i] = trigger
|
||||
@@ -330,6 +344,56 @@ func loadDevelopmentConfig(service types.ServiceConfig, project *types.Project)
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// batchDebounceEvents groups identical file events within a sliding time window and writes the results to the returned
|
||||
// channel.
|
||||
//
|
||||
// The returned channel is closed when the debouncer is stopped via context cancellation or by closing the input channel.
|
||||
func batchDebounceEvents(ctx context.Context, clock clockwork.Clock, delay time.Duration, input <-chan fileEvent) <-chan []fileEvent {
|
||||
out := make(chan []fileEvent)
|
||||
go func() {
|
||||
defer close(out)
|
||||
seen := make(map[fileEvent]time.Time)
|
||||
flushEvents := func() {
|
||||
if len(seen) == 0 {
|
||||
return
|
||||
}
|
||||
events := make([]fileEvent, 0, len(seen))
|
||||
for e := range seen {
|
||||
events = append(events, e)
|
||||
}
|
||||
// sort batch by oldest -> newest
|
||||
// (if an event is seen > 1 per batch, it gets the latest timestamp)
|
||||
sort.SliceStable(events, func(i, j int) bool {
|
||||
x := events[i]
|
||||
y := events[j]
|
||||
return seen[x].Before(seen[y])
|
||||
})
|
||||
out <- events
|
||||
seen = make(map[fileEvent]time.Time)
|
||||
}
|
||||
|
||||
t := clock.NewTicker(delay)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-t.Chan():
|
||||
flushEvents()
|
||||
case e, ok := <-input:
|
||||
if !ok {
|
||||
// input channel was closed
|
||||
flushEvents()
|
||||
return
|
||||
}
|
||||
seen[e] = time.Now()
|
||||
t.Reset(delay)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return out
|
||||
}
|
||||
|
||||
func checkIfPathAlreadyBindMounted(watchPath string, volumes []types.ServiceVolumeConfig) bool {
|
||||
for _, volume := range volumes {
|
||||
if volume.Bind != nil && strings.HasPrefix(watchPath, volume.Source) {
|
||||
@@ -417,60 +481,70 @@ func (t tarDockerClient) Untar(ctx context.Context, id string, archive io.ReadCl
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, options api.WatchOptions, batch []watch.FileEvent, rules []watchRule, syncer sync.Syncer) error {
|
||||
var (
|
||||
restart = map[string]bool{}
|
||||
syncfiles = map[string][]*sync.PathMapping{}
|
||||
exec = map[string][]int{}
|
||||
rebuild = map[string]bool{}
|
||||
)
|
||||
for _, event := range batch {
|
||||
for i, rule := range rules {
|
||||
mapping := rule.Matches(event)
|
||||
if mapping == nil {
|
||||
continue
|
||||
func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, serviceName string, options api.WatchOptions, batch []fileEvent, syncer sync.Syncer) error {
|
||||
pathMappings := make([]sync.PathMapping, len(batch))
|
||||
restartService := false
|
||||
for i := range batch {
|
||||
if batch[i].Action == types.WatchActionRebuild {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Rebuilding service %q after changes were detected...", serviceName))
|
||||
// restrict the build to ONLY this service, not any of its dependencies
|
||||
options.Build.Services = []string{serviceName}
|
||||
imageNameToIdMap, err := s.build(ctx, project, *options.Build, nil)
|
||||
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Build failed. Error: %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
switch rule.Action {
|
||||
case types.WatchActionRebuild:
|
||||
rebuild[rule.service] = true
|
||||
case types.WatchActionSync:
|
||||
syncfiles[rule.service] = append(syncfiles[rule.service], mapping)
|
||||
case types.WatchActionRestart:
|
||||
restart[rule.service] = true
|
||||
case types.WatchActionSyncRestart:
|
||||
syncfiles[rule.service] = append(syncfiles[rule.service], mapping)
|
||||
restart[rule.service] = true
|
||||
case types.WatchActionSyncExec:
|
||||
syncfiles[rule.service] = append(syncfiles[rule.service], mapping)
|
||||
// We want to run exec hooks only once after syncfiles if multiple file events match
|
||||
// as we can't compare ServiceHook to sort and compact a slice, collect rule indexes
|
||||
exec[rule.service] = append(exec[rule.service], i)
|
||||
if options.Prune {
|
||||
s.pruneDanglingImagesOnRebuild(ctx, project.Name, imageNameToIdMap)
|
||||
}
|
||||
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("service %q successfully built", serviceName))
|
||||
|
||||
err = s.create(ctx, project, api.CreateOptions{
|
||||
Services: []string{serviceName},
|
||||
Inherit: true,
|
||||
Recreate: api.RecreateForce,
|
||||
})
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Failed to recreate service after update. Error: %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
services := []string{serviceName}
|
||||
p, err := project.WithSelectedServices(services)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = s.start(ctx, project.Name, api.StartOptions{
|
||||
Project: p,
|
||||
Services: services,
|
||||
AttachTo: services,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Application failed to start after update. Error: %v", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if batch[i].Action == types.WatchActionSyncRestart {
|
||||
restartService = true
|
||||
}
|
||||
pathMappings[i] = batch[i].PathMapping
|
||||
}
|
||||
|
||||
logrus.Debugf("watch actions: rebuild %d sync %d restart %d", len(rebuild), len(syncfiles), len(restart))
|
||||
writeWatchSyncMessage(options.LogTo, serviceName, pathMappings, restartService)
|
||||
|
||||
if len(rebuild) > 0 {
|
||||
err := s.rebuild(ctx, project, utils.MapKeys(rebuild), options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
service, err := project.GetService(serviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for serviceName, pathMappings := range syncfiles {
|
||||
writeWatchSyncMessage(options.LogTo, serviceName, pathMappings)
|
||||
err := syncer.Sync(ctx, serviceName, pathMappings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := syncer.Sync(ctx, service, pathMappings); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(restart) > 0 {
|
||||
services := utils.MapKeys(restart)
|
||||
err := s.restart(ctx, project.Name, api.RestartOptions{
|
||||
Services: services,
|
||||
if restartService {
|
||||
err = s.restart(ctx, project.Name, api.RestartOptions{
|
||||
Services: []string{serviceName},
|
||||
Project: project,
|
||||
NoDeps: false,
|
||||
})
|
||||
@@ -479,89 +553,18 @@ func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Pr
|
||||
}
|
||||
options.LogTo.Log(
|
||||
api.WatchLogger,
|
||||
fmt.Sprintf("service(s) %q restarted", services))
|
||||
}
|
||||
fmt.Sprintf("service %q restarted", serviceName))
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for service, rulesToExec := range exec {
|
||||
slices.Sort(rulesToExec)
|
||||
for _, i := range slices.Compact(rulesToExec) {
|
||||
err := s.exec(ctx, project, service, rules[i].Exec, eg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
func (s *composeService) exec(ctx context.Context, project *types.Project, serviceName string, x types.ServiceHook, eg *errgroup.Group) error {
|
||||
containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, serviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range containers {
|
||||
eg.Go(func() error {
|
||||
exec := ccli.NewExecOptions()
|
||||
exec.User = x.User
|
||||
exec.Privileged = x.Privileged
|
||||
exec.Command = x.Command
|
||||
exec.Workdir = x.WorkingDir
|
||||
for _, v := range x.Environment.ToMapping().Values() {
|
||||
err := exec.Env.Set(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return ccli.RunExec(ctx, s.dockerCli, c.ID, exec)
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *composeService) rebuild(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Rebuilding service(s) %q after changes were detected...", services))
|
||||
// restrict the build to ONLY this service, not any of its dependencies
|
||||
options.Build.Services = services
|
||||
imageNameToIdMap, err := s.build(ctx, project, *options.Build, nil)
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Build failed. Error: %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
if options.Prune {
|
||||
s.pruneDanglingImagesOnRebuild(ctx, project.Name, imageNameToIdMap)
|
||||
}
|
||||
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("service(s) %q successfully built", services))
|
||||
|
||||
err = s.create(ctx, project, api.CreateOptions{
|
||||
Services: services,
|
||||
Inherit: true,
|
||||
Recreate: api.RecreateForce,
|
||||
})
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Failed to recreate services after update. Error: %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := project.WithSelectedServices(services)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = s.start(ctx, project.Name, api.StartOptions{
|
||||
Project: p,
|
||||
Services: services,
|
||||
AttachTo: services,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Application failed to start after update. Error: %v", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeWatchSyncMessage prints out a message about the sync for the changed paths.
|
||||
func writeWatchSyncMessage(log api.LogConsumer, serviceName string, pathMappings []*sync.PathMapping) {
|
||||
func writeWatchSyncMessage(log api.LogConsumer, serviceName string, pathMappings []sync.PathMapping, restart bool) {
|
||||
action := "Syncing"
|
||||
if restart {
|
||||
action = "Syncing and restarting"
|
||||
}
|
||||
if logrus.IsLevelEnabled(logrus.DebugLevel) {
|
||||
hostPathsToSync := make([]string, len(pathMappings))
|
||||
for i := range pathMappings {
|
||||
@@ -570,7 +573,8 @@ func writeWatchSyncMessage(log api.LogConsumer, serviceName string, pathMappings
|
||||
log.Log(
|
||||
api.WatchLogger,
|
||||
fmt.Sprintf(
|
||||
"Syncing service %q after changes were detected: %s",
|
||||
"%s service %q after changes were detected: %s",
|
||||
action,
|
||||
serviceName,
|
||||
strings.Join(hostPathsToSync, ", "),
|
||||
),
|
||||
@@ -578,7 +582,7 @@ func writeWatchSyncMessage(log api.LogConsumer, serviceName string, pathMappings
|
||||
} else {
|
||||
log.Log(
|
||||
api.WatchLogger,
|
||||
fmt.Sprintf("Syncing service %q after %d changes were detected", serviceName, len(pathMappings)),
|
||||
fmt.Sprintf("%s service %q after %d changes were detected", action, serviceName, len(pathMappings)),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -590,6 +594,7 @@ func (s *composeService) pruneDanglingImagesOnRebuild(ctx context.Context, proje
|
||||
filters.Arg("label", api.ProjectLabel+"="+projectName),
|
||||
),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logrus.Debugf("Failed to list images: %v", err)
|
||||
return
|
||||
@@ -607,40 +612,29 @@ func (s *composeService) pruneDanglingImagesOnRebuild(ctx context.Context, proje
|
||||
|
||||
// Walks develop.watch.path and checks which files should be copied inside the container
|
||||
// ignores develop.watch.ignore, Dockerfile, compose files, bind mounted paths and .git
|
||||
func (s *composeService) initialSync(ctx context.Context, project *types.Project, service types.ServiceConfig, trigger types.Trigger, syncer sync.Syncer) error {
|
||||
dockerIgnores, err := watch.LoadDockerIgnore(service.Build)
|
||||
func (s *composeService) initialSync(ctx context.Context, project *types.Project, service types.ServiceConfig, trigger types.Trigger, ignore watch.PathMatcher, syncer sync.Syncer) error {
|
||||
dockerFileIgnore, err := watch.NewDockerPatternMatcher("/", []string{"Dockerfile", "*compose*.y*ml"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dotGitIgnore, err := watch.NewDockerPatternMatcher("/", []string{".git/"})
|
||||
triggerIgnore, err := watch.NewDockerPatternMatcher("/", trigger.Ignore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
triggerIgnore, err := watch.NewDockerPatternMatcher(trigger.Path, trigger.Ignore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// FIXME .dockerignore
|
||||
ignoreInitialSync := watch.NewCompositeMatcher(
|
||||
dockerIgnores,
|
||||
watch.EphemeralPathMatcher(),
|
||||
dotGitIgnore,
|
||||
triggerIgnore)
|
||||
ignoreInitialSync := watch.NewCompositeMatcher(ignore, dockerFileIgnore, triggerIgnore)
|
||||
|
||||
pathsToCopy, err := s.initialSyncFiles(ctx, project, service, trigger, ignoreInitialSync)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return syncer.Sync(ctx, service.Name, pathsToCopy)
|
||||
return syncer.Sync(ctx, service, pathsToCopy)
|
||||
}
|
||||
|
||||
// Syncs files from develop.watch.path if thy have been modified after the image has been created
|
||||
//
|
||||
//nolint:gocyclo
|
||||
func (s *composeService) initialSyncFiles(ctx context.Context, project *types.Project, service types.ServiceConfig, trigger types.Trigger, ignore watch.PathMatcher) ([]*sync.PathMapping, error) {
|
||||
func (s *composeService) initialSyncFiles(ctx context.Context, project *types.Project, service types.ServiceConfig, trigger types.Trigger, ignore watch.PathMatcher) ([]sync.PathMapping, error) {
|
||||
fi, err := os.Stat(trigger.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -649,7 +643,7 @@ func (s *composeService) initialSyncFiles(ctx context.Context, project *types.Pr
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pathsToCopy []*sync.PathMapping
|
||||
var pathsToCopy []sync.PathMapping
|
||||
switch mode := fi.Mode(); {
|
||||
case mode.IsDir():
|
||||
// process directory
|
||||
@@ -684,7 +678,7 @@ func (s *composeService) initialSyncFiles(ctx context.Context, project *types.Pr
|
||||
return err
|
||||
}
|
||||
// only copy files (and not full directories)
|
||||
pathsToCopy = append(pathsToCopy, &sync.PathMapping{
|
||||
pathsToCopy = append(pathsToCopy, sync.PathMapping{
|
||||
HostPath: path,
|
||||
ContainerPath: filepath.Join(trigger.Target, rel),
|
||||
})
|
||||
@@ -694,7 +688,7 @@ func (s *composeService) initialSyncFiles(ctx context.Context, project *types.Pr
|
||||
case mode.IsRegular():
|
||||
// process file
|
||||
if fi.ModTime().After(timeImageCreated) && !shouldIgnore(filepath.Base(trigger.Path), ignore) && !checkIfPathAlreadyBindMounted(trigger.Path, service.Volumes) {
|
||||
pathsToCopy = append(pathsToCopy, &sync.PathMapping{
|
||||
pathsToCopy = append(pathsToCopy, sync.PathMapping{
|
||||
HostPath: trigger.Path,
|
||||
ContainerPath: trigger.Target,
|
||||
})
|
||||
|
||||
@@ -36,6 +36,44 @@ import (
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestDebounceBatching(t *testing.T) {
|
||||
ch := make(chan fileEvent)
|
||||
clock := clockwork.NewFakeClock()
|
||||
ctx, stop := context.WithCancel(context.Background())
|
||||
t.Cleanup(stop)
|
||||
|
||||
eventBatchCh := batchDebounceEvents(ctx, clock, quietPeriod, ch)
|
||||
for i := 0; i < 100; i++ {
|
||||
var action types.WatchAction = "a"
|
||||
if i%2 == 0 {
|
||||
action = "b"
|
||||
}
|
||||
ch <- fileEvent{Action: action}
|
||||
}
|
||||
// we sent 100 events + the debouncer
|
||||
clock.BlockUntil(101)
|
||||
clock.Advance(quietPeriod)
|
||||
select {
|
||||
case batch := <-eventBatchCh:
|
||||
require.ElementsMatch(t, batch, []fileEvent{
|
||||
{Action: "a"},
|
||||
{Action: "b"},
|
||||
})
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
t.Fatal("timed out waiting for events")
|
||||
}
|
||||
clock.BlockUntil(1)
|
||||
clock.Advance(quietPeriod)
|
||||
|
||||
// there should only be a single batch
|
||||
select {
|
||||
case batch := <-eventBatchCh:
|
||||
t.Fatalf("unexpected events: %v", batch)
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
// channel is empty
|
||||
}
|
||||
}
|
||||
|
||||
type testWatcher struct {
|
||||
events chan watch.FileEvent
|
||||
errors chan error
|
||||
@@ -72,6 +110,7 @@ func (s stdLogger) Status(container, msg string) {
|
||||
}
|
||||
|
||||
func (s stdLogger) Register(container string) {
|
||||
|
||||
}
|
||||
|
||||
func TestWatch_Sync(t *testing.T) {
|
||||
@@ -121,38 +160,32 @@ func TestWatch_Sync(t *testing.T) {
|
||||
dockerCli: cli,
|
||||
clock: clock,
|
||||
}
|
||||
rules, err := getWatchRules(&types.DevelopConfig{
|
||||
Watch: []types.Trigger{
|
||||
{
|
||||
Path: "/sync",
|
||||
Action: "sync",
|
||||
Target: "/work",
|
||||
Ignore: []string{"ignore"},
|
||||
},
|
||||
{
|
||||
Path: "/rebuild",
|
||||
Action: "rebuild",
|
||||
},
|
||||
},
|
||||
}, types.ServiceConfig{Name: "test"})
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = service.watchEvents(ctx, &proj, api.WatchOptions{
|
||||
err := service.watchEvents(ctx, &proj, "test", api.WatchOptions{
|
||||
Build: &api.BuildOptions{},
|
||||
LogTo: stdLogger{},
|
||||
Prune: true,
|
||||
}, watcher, syncer, rules)
|
||||
}, watcher, syncer, []types.Trigger{
|
||||
{
|
||||
Path: "/sync",
|
||||
Action: "sync",
|
||||
Target: "/work",
|
||||
Ignore: []string{"ignore"},
|
||||
},
|
||||
{
|
||||
Path: "/rebuild",
|
||||
Action: "rebuild",
|
||||
},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
}()
|
||||
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/changed")
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/changed/sub")
|
||||
err := clock.BlockUntilContext(ctx, 3)
|
||||
assert.NilError(t, err)
|
||||
clock.Advance(watch.QuietPeriod)
|
||||
clock.BlockUntil(3)
|
||||
clock.Advance(quietPeriod)
|
||||
select {
|
||||
case actual := <-syncer.synced:
|
||||
require.ElementsMatch(t, []*sync.PathMapping{
|
||||
require.ElementsMatch(t, []sync.PathMapping{
|
||||
{HostPath: "/sync/changed", ContainerPath: "/work/changed"},
|
||||
{HostPath: "/sync/changed/sub", ContainerPath: "/work/changed/sub"},
|
||||
}, actual)
|
||||
@@ -160,11 +193,24 @@ func TestWatch_Sync(t *testing.T) {
|
||||
t.Error("timeout")
|
||||
}
|
||||
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/ignore")
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/ignore/sub")
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/changed")
|
||||
clock.BlockUntil(4)
|
||||
clock.Advance(quietPeriod)
|
||||
select {
|
||||
case actual := <-syncer.synced:
|
||||
require.ElementsMatch(t, []sync.PathMapping{
|
||||
{HostPath: "/sync/changed", ContainerPath: "/work/changed"},
|
||||
}, actual)
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Error("timed out waiting for events")
|
||||
}
|
||||
|
||||
watcher.Events() <- watch.NewFileEvent("/rebuild")
|
||||
watcher.Events() <- watch.NewFileEvent("/sync/changed")
|
||||
err = clock.BlockUntilContext(ctx, 4)
|
||||
assert.NilError(t, err)
|
||||
clock.Advance(watch.QuietPeriod)
|
||||
clock.BlockUntil(4)
|
||||
clock.Advance(quietPeriod)
|
||||
select {
|
||||
case batch := <-syncer.synced:
|
||||
t.Fatalf("received unexpected events: %v", batch)
|
||||
@@ -175,16 +221,16 @@ func TestWatch_Sync(t *testing.T) {
|
||||
}
|
||||
|
||||
type fakeSyncer struct {
|
||||
synced chan []*sync.PathMapping
|
||||
synced chan []sync.PathMapping
|
||||
}
|
||||
|
||||
func newFakeSyncer() *fakeSyncer {
|
||||
return &fakeSyncer{
|
||||
synced: make(chan []*sync.PathMapping),
|
||||
synced: make(chan []sync.PathMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeSyncer) Sync(ctx context.Context, service string, paths []*sync.PathMapping) error {
|
||||
func (f *fakeSyncer) Sync(_ context.Context, _ types.ServiceConfig, paths []sync.PathMapping) error {
|
||||
f.synced <- paths
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
)
|
||||
|
||||
func TestLocalComposeBuild(t *testing.T) {
|
||||
|
||||
for _, env := range []string{"DOCKER_BUILDKIT=0", "DOCKER_BUILDKIT=1", "DOCKER_BUILDKIT=1,COMPOSE-BAKE=1"} {
|
||||
c := NewCLI(t, WithEnv(strings.Split(env, ",")...))
|
||||
|
||||
@@ -134,6 +135,7 @@ func TestLocalComposeBuild(t *testing.T) {
|
||||
c.RunDockerOrExitError(t, "rmi", "-f", "custom-nginx")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBuildSSH(t *testing.T) {
|
||||
@@ -148,6 +150,7 @@ func TestBuildSSH(t *testing.T) {
|
||||
ExitCode: 1,
|
||||
Err: "invalid empty ssh agent socket: make sure SSH_AUTH_SOCK is set",
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
t.Run("build succeed with ssh from Compose file", func(t *testing.T) {
|
||||
@@ -165,20 +168,17 @@ func TestBuildSSH(t *testing.T) {
|
||||
c.RunDockerCmd(t, "image", "inspect", "build-test-ssh")
|
||||
})
|
||||
|
||||
/*
|
||||
FIXME disabled waiting for https://github.com/moby/buildkit/issues/5558
|
||||
t.Run("build failed with wrong ssh key id from CLI", func(t *testing.T) {
|
||||
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
|
||||
t.Run("build failed with wrong ssh key id from CLI", func(t *testing.T) {
|
||||
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
|
||||
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "-f", "fixtures/build-test/ssh/compose-without-ssh.yaml",
|
||||
"--project-directory", "fixtures/build-test/ssh", "build", "--no-cache", "--ssh",
|
||||
"wrong-ssh=./fixtures/build-test/ssh/fake_rsa")
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 1,
|
||||
Err: "unset ssh forward key fake-ssh",
|
||||
})
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "-f", "fixtures/build-test/ssh/compose-without-ssh.yaml",
|
||||
"--project-directory", "fixtures/build-test/ssh", "build", "--no-cache", "--ssh",
|
||||
"wrong-ssh=./fixtures/build-test/ssh/fake_rsa")
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 17,
|
||||
Err: "unset ssh forward key fake-ssh",
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
||||
t.Run("build succeed as part of up with ssh from Compose file", func(t *testing.T) {
|
||||
c.RunDockerOrExitError(t, "rmi", "build-test-ssh")
|
||||
@@ -215,6 +215,7 @@ func TestBuildTags(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
|
||||
t.Run("build with tags", func(t *testing.T) {
|
||||
|
||||
// ensure local test run does not reuse previously build image
|
||||
c.RunDockerOrExitError(t, "rmi", "build-test-tags")
|
||||
|
||||
@@ -271,30 +272,14 @@ func TestBuildImageDependencies(t *testing.T) {
|
||||
t.Run("ClassicBuilder", func(t *testing.T) {
|
||||
cli := NewCLI(t, WithEnv(
|
||||
"DOCKER_BUILDKIT=0",
|
||||
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
|
||||
))
|
||||
doTest(t, cli)
|
||||
})
|
||||
|
||||
t.Run("BuildKit by dependency order", func(t *testing.T) {
|
||||
cli := NewCLI(t, WithEnv(
|
||||
"DOCKER_BUILDKIT=1",
|
||||
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
|
||||
))
|
||||
doTest(t, cli)
|
||||
})
|
||||
|
||||
t.Run("BuildKit by additional contexts", func(t *testing.T) {
|
||||
cli := NewCLI(t, WithEnv(
|
||||
"DOCKER_BUILDKIT=1",
|
||||
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
|
||||
))
|
||||
doTest(t, cli)
|
||||
})
|
||||
|
||||
t.Run("Bake by additional contexts", func(t *testing.T) {
|
||||
t.Run("BuildKit", func(t *testing.T) {
|
||||
cli := NewCLI(t, WithEnv(
|
||||
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
|
||||
"DOCKER_BUILDKIT=1",
|
||||
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
|
||||
))
|
||||
doTest(t, cli)
|
||||
@@ -320,8 +305,8 @@ func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms",
|
||||
"-f", "fixtures/build-test/platforms/compose-unsupported-platform.yml", "build")
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 1,
|
||||
Err: "no match for platform",
|
||||
ExitCode: 17,
|
||||
Err: "no match for platform in",
|
||||
})
|
||||
})
|
||||
|
||||
@@ -330,6 +315,7 @@ func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
|
||||
assert.NilError(t, res.Error, res.Stderr())
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/arm64"})
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/amd64"})
|
||||
|
||||
})
|
||||
|
||||
t.Run("multi-arch multi service builds ok", func(t *testing.T) {
|
||||
@@ -366,6 +352,7 @@ func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) {
|
||||
assert.NilError(t, res.Error, res.Stderr())
|
||||
res.Assert(t, icmd.Expected{Out: "I am building for linux/386"})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildPrivileged(t *testing.T) {
|
||||
@@ -418,8 +405,9 @@ func TestBuildPlatformsStandardErrors(t *testing.T) {
|
||||
t.Run("builder does not support multi-arch", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms", "build")
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 1,
|
||||
Err: "Multi-platform build is not supported for the docker driver.",
|
||||
ExitCode: 17,
|
||||
Err: `Multi-platform build is not supported for the docker driver.
|
||||
Switch to a different driver, or turn on the containerd image store, and try again.`,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -427,7 +415,7 @@ func TestBuildPlatformsStandardErrors(t *testing.T) {
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms",
|
||||
"-f", "fixtures/build-test/platforms/compose-service-platform-not-in-build-platforms.yaml", "build")
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 1,
|
||||
ExitCode: 15,
|
||||
Err: `service.build.platforms MUST include service.platform "linux/riscv64"`,
|
||||
})
|
||||
})
|
||||
@@ -454,6 +442,7 @@ func TestBuildPlatformsStandardErrors(t *testing.T) {
|
||||
Err: "the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit",
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildBuilder(t *testing.T) {
|
||||
@@ -480,6 +469,7 @@ func TestBuildBuilder(t *testing.T) {
|
||||
Err: fmt.Sprintf(`no builder %q found`, "unknown-builder"),
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestBuildEntitlements(t *testing.T) {
|
||||
|
||||
@@ -70,13 +70,18 @@ func TestLocalComposeExecOneOff(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
|
||||
const projectName = "compose-e2e-exec-one-off"
|
||||
defer c.cleanupWithDown(t, projectName)
|
||||
cmdArgs := func(cmd string, args ...string) []string {
|
||||
ret := []string{"--project-directory", "fixtures/simple-composefile", "--project-name", projectName, cmd}
|
||||
ret = append(ret, args...)
|
||||
return ret
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
c.RunDockerComposeCmd(t, cmdArgs("down", "--timeout=0")...)
|
||||
}
|
||||
cleanup()
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
c.RunDockerComposeCmd(t, cmdArgs("run", "-d", "simple")...)
|
||||
|
||||
t.Run("exec in one-off container", func(t *testing.T) {
|
||||
@@ -88,7 +93,4 @@ func TestLocalComposeExecOneOff(t *testing.T) {
|
||||
res := c.RunDockerComposeCmdNoCheck(t, cmdArgs("exec", "--index", "1", "-e", "FOO", "simple", "/usr/bin/env")...)
|
||||
res.Assert(t, icmd.Expected{ExitCode: 1, Err: "service \"simple\" is not running container #1"})
|
||||
})
|
||||
cmdResult := c.RunDockerCmd(t, "ps", "-q", "--filter", "label=com.docker.compose.project=compose-e2e-exec-one-off").Stdout()
|
||||
containerIDs := strings.Split(cmdResult, "\n")
|
||||
_ = c.RunDockerOrExitError(t, append([]string{"stop"}, containerIDs...)...)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
|
||||
func TestLocalComposeRun(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
defer c.cleanupWithDown(t, "run-test")
|
||||
|
||||
t.Run("compose run", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "back")
|
||||
@@ -162,20 +161,11 @@ func TestLocalComposeRun(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("--quiet-pull", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/quiet-pull.yaml", "down", "--remove-orphans", "--rmi", "all")
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/quiet-pull.yaml", "down", "--rmi", "all")
|
||||
res.Assert(t, icmd.Success)
|
||||
|
||||
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/quiet-pull.yaml", "run", "--quiet-pull", "backend")
|
||||
assert.Assert(t, !strings.Contains(res.Combined(), "Pull complete"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "Pulled"), res.Combined())
|
||||
})
|
||||
|
||||
t.Run("--pull", func(t *testing.T) {
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/pull.yaml", "down", "--remove-orphans", "--rmi", "all")
|
||||
res.Assert(t, icmd.Success)
|
||||
|
||||
res = c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/pull.yaml", "run", "--pull", "always", "backend")
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulling"), res.Combined())
|
||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulled"), res.Combined())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ func TestLocalComposeUp(t *testing.T) {
|
||||
t.Run("check user labels", func(t *testing.T) {
|
||||
res := c.RunDockerCmd(t, "inspect", projectName+"-web-1")
|
||||
res.Assert(t, icmd.Expected{Out: `"my-label": "test"`})
|
||||
|
||||
})
|
||||
|
||||
t.Run("check healthcheck output", func(t *testing.T) {
|
||||
@@ -319,7 +320,6 @@ func TestRemoveOrphaned(t *testing.T) {
|
||||
|
||||
func TestComposeFileSetByDotEnv(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
defer c.cleanupWithDown(t, "dotenv")
|
||||
|
||||
cmd := c.NewDockerComposeCmd(t, "config")
|
||||
cmd.Dir = filepath.Join(".", "fixtures", "dotenv")
|
||||
@@ -335,7 +335,6 @@ func TestComposeFileSetByDotEnv(t *testing.T) {
|
||||
|
||||
func TestComposeFileSetByProjectDirectory(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
defer c.cleanupWithDown(t, "dotenv")
|
||||
|
||||
dir := filepath.Join(".", "fixtures", "dotenv", "development")
|
||||
cmd := c.NewDockerComposeCmd(t, "--project-directory", dir, "config")
|
||||
@@ -348,7 +347,6 @@ func TestComposeFileSetByProjectDirectory(t *testing.T) {
|
||||
|
||||
func TestComposeFileSetByEnvFile(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
defer c.cleanupWithDown(t, "dotenv")
|
||||
|
||||
dotEnv, err := os.CreateTemp(t.TempDir(), ".env")
|
||||
assert.NilError(t, err)
|
||||
@@ -372,7 +370,6 @@ COMPOSE_PROFILES=test
|
||||
|
||||
func TestNestedDotEnv(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
defer c.cleanupWithDown(t, "nested")
|
||||
|
||||
cmd := c.NewDockerComposeCmd(t, "run", "echo")
|
||||
cmd.Dir = filepath.Join(".", "fixtures", "nested")
|
||||
@@ -384,18 +381,20 @@ func TestNestedDotEnv(t *testing.T) {
|
||||
|
||||
cmd = c.NewDockerComposeCmd(t, "run", "echo")
|
||||
cmd.Dir = filepath.Join(".", "fixtures", "nested", "sub")
|
||||
defer c.cleanupWithDown(t, "nested")
|
||||
res = icmd.RunCmd(cmd)
|
||||
res.Assert(t, icmd.Expected{
|
||||
ExitCode: 0,
|
||||
Out: "root sub win=sub",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestUnnecessaryResources(t *testing.T) {
|
||||
const projectName = "compose-e2e-unnecessary-resources"
|
||||
c := NewParallelCLI(t)
|
||||
defer c.cleanupWithDown(t, projectName)
|
||||
t.Cleanup(func() {
|
||||
c.RunDockerComposeCmd(t, "-p", projectName, "down", "-t=0")
|
||||
})
|
||||
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "-f", "./fixtures/external/compose.yaml", "-p", projectName, "up", "-d")
|
||||
res.Assert(t, icmd.Expected{
|
||||
|
||||
@@ -94,7 +94,6 @@ func TestStdoutStderr(t *testing.T) {
|
||||
func TestLoggingDriver(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
const projectName = "e2e-logging-driver"
|
||||
defer c.cleanupWithDown(t, projectName)
|
||||
|
||||
host := "HOST=127.0.0.1"
|
||||
res := c.RunDockerCmd(t, "info", "-f", "{{.OperatingSystem}}")
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
|
||||
func TestConfigFromEnv(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
defer c.cleanupWithDown(t, "configs")
|
||||
|
||||
t.Run("config from file", func(t *testing.T) {
|
||||
res := icmd.RunCmd(c.NewDockerComposeCmd(t, "-f", "./fixtures/configs/compose.yaml", "run", "from_file"))
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
|
||||
func TestRawEnvFile(t *testing.T) {
|
||||
c := NewParallelCLI(t)
|
||||
defer c.cleanupWithDown(t, "dotenv")
|
||||
|
||||
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/dotenv/raw.yaml", "run", "test")
|
||||
assert.Equal(t, strings.TrimSpace(res.Stdout()), "'{\"key\": \"value\"}'")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user