Compare commits

..

186 Commits

Author SHA1 Message Date
Sebastiaan van Stijn
036da47950 go.mod: remove toolchain directive
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-12 08:19:25 +01:00
Nicolas De Loof
33172d5e4d let user know bake is now supported
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-02-12 08:18:20 +01:00
dependabot[bot]
3f1a6b72a5 build(deps): bump gotest.tools/v3 from 3.5.1 to 3.5.2
Bumps [gotest.tools/v3](https://github.com/gotestyourself/gotest.tools) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/gotestyourself/gotest.tools/releases)
- [Commits](https://github.com/gotestyourself/gotest.tools/compare/v3.5.1...v3.5.2)

---
updated-dependencies:
- dependency-name: gotest.tools/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-11 10:53:38 +01:00
dependabot[bot]
f9a6e6c414 build(deps): bump golang.org/x/sync from 0.10.0 to 0.11.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-11 10:53:02 +01:00
dependabot[bot]
18ef6e592b build(deps): bump github.com/spf13/pflag from 1.0.5 to 1.0.6
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-11 10:50:47 +01:00
Max Proske
2884d6df0d Fix ls --quiet help description
Signed-off-by: Max Proske <max@mproske.com>
2025-02-10 17:30:39 +01:00
Sebastiaan van Stijn
4459012a4f Dockerfile: update golangci-lint to v1.63.4
make sure it's compatible with go1.23

full diff: https://github.com/golangci/golangci-lint/compare/v1.60.2...v1.63.4
Changelog: https://golangci-lint.run/product/changelog/#v1634

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-10 17:03:36 +01:00
Sebastiaan van Stijn
6f1f76c0e6 pkg/e2e: fix contains: use assert.Contains (testifylint)
pkg/e2e/ps_test.go:50:5: contains: use assert.Contains (testifylint)
                    assert.True(t, strings.Contains(line, "127.0.0.1:8001->8000/tcp"))
                    ^
    pkg/e2e/ps_test.go:54:5: contains: use assert.Contains (testifylint)
                    assert.True(t, strings.Contains(line, "80/tcp, 443/tcp, 8080/tcp"))
                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-10 17:03:36 +01:00
Nicolas De Loof
ed72c21871 use BlockUntilContext
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-02-10 15:24:46 +01:00
dependabot[bot]
fa4cfb652e build(deps): bump github.com/jonboulle/clockwork from 0.4.0 to 0.5.0
Bumps [github.com/jonboulle/clockwork](https://github.com/jonboulle/clockwork) from 0.4.0 to 0.5.0.
- [Release notes](https://github.com/jonboulle/clockwork/releases)
- [Commits](https://github.com/jonboulle/clockwork/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: github.com/jonboulle/clockwork
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 15:24:46 +01:00
dependabot[bot]
200638b024 build(deps): bump github.com/otiai10/copy from 1.14.0 to 1.14.1
Bumps [github.com/otiai10/copy](https://github.com/otiai10/copy) from 1.14.0 to 1.14.1.
- [Release notes](https://github.com/otiai10/copy/releases)
- [Commits](https://github.com/otiai10/copy/compare/v1.14.0...v1.14.1)

---
updated-dependencies:
- dependency-name: github.com/otiai10/copy
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 15:04:10 +01:00
dependabot[bot]
a0320f12ef build(deps): bump golang.org/x/sys from 0.28.0 to 0.30.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.28.0 to 0.30.0.
- [Commits](https://github.com/golang/sys/compare/v0.28.0...v0.30.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 15:03:31 +01:00
Nicolas De Loof
f8a912ab9a bump compose-go v2.4.8
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-02-10 15:02:01 +01:00
Sebastiaan van Stijn
c23a7e7281 golangci-lint: enable copyloopvar linter
capturing loop variables is no longer needed in go1.22 and higher;
https://go.dev/blog/loopvar-preview

This path enables the copyloopvar linter, which finds places where capturing
is no longer needed, and removes locations where they could be removed.

Also made some minor changes, and renamed some vars in places where
we could use a shorter name that's less likely to conflict with imports.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-10 13:46:41 +01:00
Sebastiaan van Stijn
49575ef499 gha: add docker engine v28.x to the test-matrix
currently v28.0.0-rc.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-09 17:38:01 +01:00
Sebastiaan van Stijn
faa46d374d go.mod: github.com/moby/term v0.5.2
- update github.com/Azure/go-ansiterm to v0.0.0-20250102033503-faa5f7b0171c
  to fix OSC string terminator parsing.
- add security policy
- update github actions and test against go1.22, go1.23

full diff: https://github.com/moby/term/compare/v0.5.0...v0.5.2

update github.com/Azure/go-ansiterm faa5f7b0171c

- fix OSC string terminator parsing

diff: d185dfc1b5...faa5f7b017

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-09 17:37:45 +01:00
Max Proske
6ecb8d40ae Full test coverage for convert compatibility cmd
Signed-off-by: Max Proske <max@mproske.com>
2025-02-05 18:08:54 +01:00
Nicolas De Loof
a6a39422e4 remove cli.args opentelemetry attribute
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-02-05 16:29:45 +01:00
Max Proske
40cd08f318 Update link in stats --help output
Signed-off-by: Max Proske <max@mproske.com>
2025-02-04 18:12:17 +01:00
Nicolas De Loof
5e2abb6c26 support additional_context reference to another service
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-02-03 17:23:35 +01:00
Nicolas De Loof
4db5fcd569 fix bake uses selected builder
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-31 17:05:11 +01:00
Nicolas De Loof
f14c15fa57 capture error message reported by bake and forward to compose
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-31 17:05:11 +01:00
Nicolas De Loof
8d68ef587f fix exporter to only load image for default platform
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-31 17:05:11 +01:00
Nicolas De Loof
cde9ae5952 pass --allow for filesystem read access
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-31 17:05:11 +01:00
Guillaume Lours
806ac91cf6 add warning when trying to publish env variables with OCI artifact
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-30 17:37:07 +01:00
Nicolas De Loof
1c073c0a04 watch should ony build selected services
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-30 13:47:21 +01:00
Guillaume Lours
840288895e add --with-env flag to publish command
this flag allow publishing env variables in the Compose OCI artifact

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-29 15:45:00 +01:00
Nicolas De Loof
4b70ff0ccd fix support for ssh key from CLI flags
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-29 11:28:41 +01:00
Nicolas De Loof
23351ece81 remove exit code per error type used by legacy metrics system
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-28 10:26:41 +01:00
Nicolas De Loof
7c7407672a bump docker to v27.5.1
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-23 15:31:01 +01:00
Nicolas De Loof
25cfa66a91 bump buildx v0.20.1 and docker v27.5.0
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-23 09:13:37 +01:00
CrazyMax
f160333e9e ci: use main branch for docs upstream validation workflow
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-01-22 19:27:02 +01:00
Nicolas De Loof
d04b3f48e4 e2e test covering multi-service rebuild with common resources
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-22 12:05:58 +01:00
Nicolas De Loof
ed10804e0f manage watch applied to mulitple services
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-22 12:05:58 +01:00
Rafael Buchbinder
52578c0998 Properly handle "builtin" seccomp profile
Like in CLI [1] the "builtin" seccomp profile should be handled the same
as "unconfined".

[1] f4a68da195/cli/command/container/opts.go (L929)

Signed-off-by: Rafael Buchbinder <rafi@rbk.io>
2025-01-20 15:06:09 +01:00
Guillaume Lours
bd2b49a1cf add codeowners file
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-20 14:09:53 +01:00
CrazyMax
433a60e122 ci: fix provenance for binaries and generate sbom
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-01-20 09:46:05 +01:00
Nicolas De Loof
489fe9cf02 add support for BUILDKIT_PROGRESS
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-16 12:06:09 +01:00
Guillaume Lours
ef1931c8de add missing tag for build during merge workflow
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-15 18:26:03 +01:00
Guillaume Lours
9be7a3c9a1 ci: re-use local source to build binary images
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-15 18:02:23 +01:00
CrazyMax
666996bee2 ci: use local source for binary builds
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-01-15 16:50:20 +01:00
CrazyMax
083f676214 ci: update bake-action to v6
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-01-13 12:41:14 +01:00
Nicolas De Loof
e81de103db simplification
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-10 12:21:13 +01:00
Nicolas De Loof
fa39503469 image can be set to a local ID, that isn't a valid docker ref
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-09 09:55:30 +01:00
Nicolas De Loof
a351585024 can't render progress concurrently with buildkit
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-08 16:12:54 +01:00
Nicolas De Loof
b6db1380ec exclude one-off container running convergence
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-08 10:57:46 +01:00
Florian Apolloner
2ebb475433 Only override service mac if set on the main network.
Signed-off-by: Florian Apolloner <florian@apolloner.eu>
2025-01-07 16:16:33 +01:00
Guillaume Lours
d474515d45 remove engine v25 from e2e test matrix
The 1st version available for Ubuntu 24.x is Docker Engine v26

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-07 14:59:47 +01:00
Nicolas De Loof
2b21c5df93 fix relative path in compose file
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-07 14:59:47 +01:00
Guillaume Lours
1f3c10eb4b bump compose-go to v2.4.7
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-07 14:59:47 +01:00
Guillaume Lours
68ad165a59 replace tibdex/github-app-token by official GitHub create-github-app-token
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-07 12:12:22 +01:00
Guillaume Lours
3060ed2795 bump golang.org/x/net to v0.33.0 to fix potential security issue
https://github.com/golang/go/issues/70906

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-01-07 12:11:44 +01:00
Nicolas De Loof
be09b2e8ce checkExpectedVolumes must ignore anonymous volumes
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-01-06 09:40:02 +01:00
Guillaume Tardif
571a1af013 When retrying to resolveOrCreateNetwork, retry with a valid network name
Signed-off-by: Guillaume Tardif <guillaume.tardif@gmail.com>
2025-01-06 08:28:05 +01:00
Nicolas De Loof
8f644eea73 only check bind mount conflict if sync action is involved
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-19 11:23:50 +01:00
Guillaume Lours
56e92e34b6 use the 3 latest major versions of the engine to run e2e step
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-18 16:29:41 +01:00
Guillaume Lours
a42a04dfe8 bump Golang version to v1.22.10 and update CI actions
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-18 16:09:48 +01:00
Guillaume Lours
34bcd03a76 add --pull to run command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-18 12:20:02 +01:00
Nicolas De Loof
ed61e42f93 CI to validate fmt
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-17 16:50:14 +01:00
Nicolas De Loof
65696bb1cb make fmt so any contributor can enforce formatting
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-17 16:50:14 +01:00
Sebastiaan van Stijn
446e00520c format code with gofumpt
Format the code  with gofumpt to prevent my IDE from reformatting
every time I open a file. gofumpt provides a superset of gofmt,
so should not impact users that are not using gofumpt.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-12-17 16:50:14 +01:00
Nicolas De Loof
c01c9c29f4 e2e test to prevent future regression
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-16 15:46:47 +01:00
Nicolas De Loof
038c81f34e only check volume mounts for updated config
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-16 10:26:24 +01:00
Nicolas De Loof
a20b69ac5b e2e test for recreate volume
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-13 09:52:22 +01:00
dependabot[bot]
977530c22a build(deps): bump google.golang.org/grpc from 1.68.0 to 1.68.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.68.0 to 1.68.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.68.0...v1.68.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-12 19:25:02 +01:00
dependabot[bot]
d4db8b6b12 build(deps): bump golang.org/x/crypto from 0.27.0 to 0.31.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.31.0.
- [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-12 19:12:27 +01:00
dependabot[bot]
f8ce0f04e6 build(deps): bump golang.org/x/sys from 0.27.0 to 0.28.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.27.0 to 0.28.0.
- [Commits](https://github.com/golang/sys/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-12 19:11:45 +01:00
Nicolas De Loof
8e0520e71e prompt user to confirm volume recreation
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-12 19:11:00 +01:00
Joana Hrotko
332311358e Recreate container on volume configuration change
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-12 19:11:00 +01:00
Nicolas De Loof
df9e420ddd introduce watch restart action
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-12 09:56:23 +01:00
Guillaume Lours
142f5dba84 bump otel dependencies to v1.28.0 and v0.53.0 to align with buildx, buildkit and engine versions
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-11 15:57:53 +01:00
Nicolas De Loof
700c586bcf bump docker/buildx to latest release
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-11 15:33:58 +01:00
Nicolas De Loof
fc566509d5 fix support for service.mac_address
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-10 15:59:26 +01:00
Sebastiaan van Stijn
e73c2303fb update xx to v1.6.1 for compatibility with alpine 3.21 and file 5.46+
This fixes compatibility with alpine 3.21 and file 5.46+

- Fix additional possible `xx-cc`/`xx-cargo` compatibility issue with Alpine 3.21
- Support for Alpine 3.21
- Fix `xx-verify` with `file` 5.46+
- Fix possible error taking lock in `xx-apk` in latest Alpine without `coreutils`

full diff: https://github.com/tonistiigi/xx/compare/v1.2.1...v1.6.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-12-10 15:09:02 +01:00
dependabot[bot]
624303233a build(deps): bump golang.org/x/sync from 0.9.0 to 0.10.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/sync/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 12:05:24 +01:00
Nicolas De loof
a1729c52de Update pkg/e2e/watch_test.go
Co-authored-by: Guillaume Lours <705411+glours@users.noreply.github.com>
Signed-off-by: Nicolas De loof <nicolas.deloof@gmail.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:46:42 +01:00
Nicolas De Loof
254224c182 first watch action for a file event wins
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:46:42 +01:00
Nicolas De Loof
0861e68450 fix
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:46:42 +01:00
Nicolas De Loof
af5b748500 revisit TestDebounceBatching
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:46:42 +01:00
Nicolas De Loof
32a22c1f4f introduce sync+exec watch action
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:46:42 +01:00
Nicolas De Loof
e6ea8fb962 log configuration error as a watch log event
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:30:14 +01:00
Nicolas De Loof
043465448f do not require a build section but for rebuild action
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 16:12:05 +01:00
Nicolas De Loof
1d08390864 pull --quiet should not drop status message, only progress
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-06 12:24:29 +01:00
Nicolas De Loof
69a83d1303 use latest engine tags
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-05 14:53:24 +01:00
Nicolas De Loof
781b9f1cd5 Bump buildx to 0.19.1
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-05 14:53:24 +01:00
Guillaume Lours
cbff0e5559 be sure everything has been cleanup at the end of each tests
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-04 15:28:16 +01:00
Guillaume Lours
e4222bff53 add local config.json to test configuration dir if exists
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-12-04 15:28:16 +01:00
Nicolas De Loof
25197fe6dd disable failing TestBuildSSH test
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-04 15:14:56 +01:00
Nicolas De Loof
85cdaf9ddf fix build with bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-12-03 12:05:40 +01:00
Guillaume Lours
a8469db83f bump containerd to v1.7,24
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-27 15:23:27 +01:00
Guillaume Lours
08488dae59 bump google.golang.org/grpc to v1.68.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-27 15:23:27 +01:00
dependabot[bot]
cc3a216f2f build(deps): bump github.com/moby/buildkit from 0.17.1 to 0.17.2
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.17.1 to 0.17.2.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.17.1...v0.17.2)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-27 14:37:20 +01:00
dependabot[bot]
6e818b9ae0 build(deps): bump github.com/compose-spec/compose-go/v2
Bumps [github.com/compose-spec/compose-go/v2](https://github.com/compose-spec/compose-go) from 2.4.5-0.20241111154218-9d02caaf8465 to 2.4.5.
- [Release notes](https://github.com/compose-spec/compose-go/releases)
- [Commits](https://github.com/compose-spec/compose-go/commits/v2.4.5)

---
updated-dependencies:
- dependency-name: github.com/compose-spec/compose-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-27 14:21:24 +01:00
Nicolas De Loof
6b3e57503e only stop dependent containers ... if there's some
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-27 09:58:38 +01:00
Nicolas De Loof
8e497a1289 disable TestNetworkConfigChanged which is unstable on CI
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-27 09:51:07 +01:00
Nicolas De Loof
5aed704379 only check attached networks on running containers
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-27 09:51:07 +01:00
MohammadHasan Akbari
1ff9b758d2 fix: commit tests
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-11-27 07:39:46 +01:00
MohammadHasan Akbari
9eaba55973 feat: add commit command
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-11-27 07:39:46 +01:00
Nicolas De Loof
a85f8a40a9 run build tests against bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-26 15:20:50 +01:00
Nicolas De Loof
095f65cb42 delegate build to buildx bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-26 08:51:34 +01:00
dependabot[bot]
208e57ded8 build(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-26 08:44:16 +01:00
Nicolas De Loof
2d148faedf use service.stop to stop dependent containers
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-25 11:56:22 +01:00
Trevor Foster
43ac1e31c6 Update wait-timeout flag usage to include the unit
Signed-off-by: Trevor Foster <trevorfoster19@gmail.com>
2024-11-25 11:22:18 +01:00
Sebastiaan van Stijn
5561a778c9 go.mod: github.com/docker/cli v27.4.0-rc.2
full diff: https://github.com/docker/cli/compare/8d1bacae3e49...v27.4.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-20 09:55:29 +01:00
Sebastiaan van Stijn
ae48f488d1 go.mod: github.com/docker/docker v27.4.0-rc.2
full diff: https://github.com/docker/docker/compare/v27.4.0-rc.1...v27.4.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-20 09:55:29 +01:00
Sebastiaan van Stijn
5e3a095380 go.mod: github.com/docker/cli 8d1bacae3e49 (v27.4.0-rc.2-dev)
full diff: https://github.com/docker/cli/compare/v27.4.0-rc.1...8d1bacae3e49ed1d096eede8eef4ae851d7f2eae

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 16:30:26 +01:00
Sebastiaan van Stijn
a2a3eb72e2 go.mod: github.com/docker/cli v27.4.0-rc.1
- full diff: https://github.com/docker/cli/compare/cb3048fbebb1...v27.4.0-rc.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 16:30:26 +01:00
Sebastiaan van Stijn
3513b42423 go.mod: github.com/docker/docker v27.4.0-rc.1
- full diff: https://github.com/docker/docker/compare/v27.3.1...v27.4.0-rc.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 16:30:26 +01:00
Nicolas De loof
d4fa63fdcb Update pkg/compose/convergence.go
Co-authored-by: Guillaume Lours <705411+glours@users.noreply.github.com>
Signed-off-by: Nicolas De loof <nicolas.deloof@gmail.com>
2024-11-15 15:35:49 +01:00
Nicolas De Loof
c21d4cfb40 detect network config changes and recreate if needed
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-15 15:35:49 +01:00
Sebastiaan van Stijn
61f1d4f69b go.mod: github.com/docker/buildx v0.18.0
full diff: https://github.com/docker/buildx/compare/v0.17.1..v0.18.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 11:57:00 +01:00
Sebastiaan van Stijn
f7cce281de go.mod: github.com/moby/buildkit v0.17.1
full diff: https://github.com/moby/buildkit/compare/v0.16.0..v0.17.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 11:57:00 +01:00
Sebastiaan van Stijn
bcaacc7f23 gha: test against docker engine v27.4.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-11-15 11:48:29 +01:00
Guillaume Lours
3f5898f8d0 push empty descriptor layer when using OCI version 1.1 for Compose artifact
it fixes a repository creation issue when pushing the 1st time a Compose OCI artifact on the Hub

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-13 13:36:31 +01:00
Guillaume Lours
2bb67f2700 remove ddev e2e tests
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-13 12:52:48 +01:00
Nicolas De Loof
bf521fe3ab implement remove-orphans on run
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-12 14:28:26 +01:00
Matthieu MOREL
11e9621da5 ci: enable testifylint linter
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2024-11-12 11:12:32 +01:00
Felix Fontein
a9de9abcfb Emit events for building images
Signed-off-by: Felix Fontein <felix@fontein.de>
2024-11-12 10:59:41 +01:00
koooge
799ab842a0 Fix compose images that reutn a different image with the same ID
Signed-off-by: koooge <koooooge@gmail.com>
2024-11-12 09:51:33 +01:00
Nicolas De Loof
2f65ace2aa remove obsolete containers first on scale down
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-12 09:47:36 +01:00
Guillaume Lours
aa0a4189ee pass stal bot inactivity limit from 6 to 3 months
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-12 09:37:21 +01:00
Suleiman Dibirov
eba3ff8f37 fix(config): Print service names with --no-interpolate
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-11-11 16:42:55 +01:00
dependabot[bot]
6313365ba4 build(deps): bump golang.org/x/sys from 0.26.0 to 0.27.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.26.0 to 0.27.0.
- [Commits](https://github.com/golang/sys/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-08 11:20:24 +01:00
dependabot[bot]
dbd51745c4 build(deps): bump golang.org/x/sync from 0.8.0 to 0.9.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.8.0 to 0.9.0.
- [Commits](https://github.com/golang/sync/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-08 10:49:59 +01:00
Guillaume Lours
a8bfbc147a bump compose-go v2.4.4
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-07 14:19:53 +01:00
Joana Hrotko
fbbd6f83d7 Avoid starting all services on rebuild
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-11-05 14:51:12 +00:00
Guillaume Lours
a000978980 remove ArtifactType from Config in OCI v1.1 definition of the artifact
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-11-05 15:10:56 +01:00
dependabot[bot]
361c0893a9 build(deps): bump github.com/compose-spec/compose-go/v2
Bumps [github.com/compose-spec/compose-go/v2](https://github.com/compose-spec/compose-go) from 2.4.2 to 2.4.3.
- [Release notes](https://github.com/compose-spec/compose-go/releases)
- [Commits](https://github.com/compose-spec/compose-go/compare/v2.4.2...v2.4.3)

---
updated-dependencies:
- dependency-name: github.com/compose-spec/compose-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-05 10:50:25 +01:00
Nicolas De Loof
513b6128c2 Service being declared in a profile must not trigger re-creation
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-11-05 10:49:08 +01:00
Joana Hrotko
eececb9add Add profile e2e test case to document in compose
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-10-30 16:00:41 +01:00
Laura Brehm
501b5acde6 Update MAINTAINERS file
Add `jhrotko` to Core Maintainers.

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2024-10-30 13:33:46 +01:00
Guillaume Lours
f51bc4cd00 bump compose-go to version v2.4.2
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-30 11:30:53 +01:00
Guillaume Lours
517f87a372 bump google.golang.org/grpc to v1.67.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-29 12:07:34 +01:00
Guillaume Lours
718049cbd7 bump go.uber.org/mock to v0.5.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-29 12:07:34 +01:00
Guillaume Lours
02371f3127 bump golang minimal version to 1.22 in go.mod
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-29 11:45:02 +01:00
dependabot[bot]
a7c9de82b2 build(deps): bump github.com/containerd/containerd from 1.7.22 to 1.7.23
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.22 to 1.7.23.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.22...v1.7.23)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-29 09:47:38 +01:00
Guillaume Lours
51ebeb5441 introduce generate command as alpha command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-28 17:00:59 +01:00
Guillaume Lours
fafaa9c5b8 bump compose-go to version v2.4.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-28 14:24:07 +01:00
Suleiman Dibirov
fc9c3cde06 Add license header to dockerignore_test.go
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-10-28 12:26:45 +01:00
Suleiman Dibirov
73bfbab54b fix
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-10-28 12:26:45 +01:00
Suleiman Dibirov
2ac081b4c4 fix(dockerignore): Add wildcard support to dockerignore.go
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-10-28 12:26:45 +01:00
Chris Crone
eeea049f17 push: Fix error message typo
Signed-off-by: Chris Crone <christopher.crone@docker.com>
2024-10-28 10:08:44 +01:00
Guillaume Lours
26064d4b60 allow usage of -f flag with oci Compose artifact
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-25 17:36:04 +02:00
Nicolas De Loof
7c46beb8af resurrect --all flag for cp to target oneoff container
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-25 16:59:19 +02:00
Nicolas De Loof
aa1ec4524c connect to external networks by name
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-25 16:42:28 +02:00
Nicolas De Loof
a4ee6ca7a5 don't warn about uid/gid not being supported while ... they are
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-25 12:48:00 +02:00
Guillaume Lours
5617eff0c2 bump compose-go to v2.4.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-24 14:37:42 +02:00
Nicolas De Loof
fa24ab8e25 one-off container are not indexed, and must be ignored by exec --index command
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-22 15:29:12 +02:00
Nicolas De Loof
0aad9595a5 don't use progress to render restart, which hides logs
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-22 15:28:55 +02:00
Nicolas De Loof
813900180e compose-go clean volume target to avoid ambiguous comparisons
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-22 11:40:35 +02:00
Nicolas De Loof
82417bd5bc add support for bind.recursive
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-16 22:19:58 +02:00
divinity76
0cbb73c024 Improve error message to include expected network label
Updated the error message when a network is found with an incorrect label to also display the expected label value. This provides more context for debugging.

Signed-off-by: divinity76 <hans@loltek.net>
2024-10-15 15:33:16 +02:00
David Scott
38e3d670a9 desktop: allow this client to be identified via user-agent
Previously the HTTP requests were sent with a generic Go-http-client
user-agent which made it hard to determine where the requests are
coming from. It's important that we can find clients so that they
can be updated if APIs change in future.

Signed-off-by: David Scott <dave@recoil.org>
2024-10-15 13:59:49 +02:00
Guillaume Lours
24c78728e0 bump compose-go to v2.3.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-10-10 11:18:25 +02:00
Nicolas De Loof
9eeb2d3154 convert gpus to DeviceRequests with implicit "gpu" capability
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-09 15:18:49 +02:00
Sebastiaan van Stijn
8da82c98ef gha: set default permissions to "contents: read"
make the OpenSSF scorecard slightly happier;
https://securityscorecards.dev/viewer/?uri=github.com/docker/compose

    Warn: jobLevel 'contents' permission set to 'write': .github/workflows/ci.yml:256: update your workflow using https://app.stepsecurity.io/secureworkflow/docker/compose/ci.yml/main?enable=permissions
    Warn: no topLevel permission defined: .github/workflows/docs-upstream.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/docker/compose/docs-upstream.yml/main?enable=permissions

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-09 15:02:57 +02:00
Sebastiaan van Stijn
1a8c855489 Add security policy
Add a security policy to inform users where to report security issues,
and to make the OpenSSF scorecard slightly happier;
https://securityscorecards.dev/viewer/?uri=github.com/docker/compose

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-10-09 11:05:29 +02:00
Nicolas De Loof
15bd0b0c5f add support for raw env_file format
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-08 18:33:54 +02:00
dependabot[bot]
39d0f6477e build(deps): bump golang.org/x/sys from 0.25.0 to 0.26.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.25.0 to 0.26.0.
- [Commits](https://github.com/golang/sys/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-08 10:42:02 +01:00
Nicolas De Loof
3a95a0872d add support for CDI device request using devices
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-08 11:27:22 +02:00
Nicolas De Loof
f794c79eb3 Support Dockerfile-specific ignore-file with watch
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-08 11:19:02 +02:00
Joana Hrotko
407d825705 Remove feature flag integration with Docker Desktop for ComposeUI and ComposeNav
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-10-07 20:08:12 +02:00
Nicolas De Loof
82b41b9ebd introduce service hooks
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-07 16:06:41 +02:00
Nicolas De Loof
6c06170eb0 pass device.options to engine
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-04 14:55:53 +02:00
MohammadHasan Akbari
60c1311f67 chore: remove errors depricated pkg
Signed-off-by: MohammadHasan Akbari <116190942+jarqvi@users.noreply.github.com>
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-10-02 21:15:59 +02:00
MohammadHasan Akbari
17add87e4e fix: validate-go-mod
Signed-off-by: MohammadHasan Akbari <116190942+jarqvi@users.noreply.github.com>
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-10-02 21:15:59 +02:00
MohammadHasan Akbari
bf0418bac1 fix: lint
Signed-off-by: MohammadHasan Akbari <116190942+jarqvi@users.noreply.github.com>
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-10-02 21:15:59 +02:00
MohammadHasan Akbari
b9d0c77cde feat: add export command
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2024-10-02 21:15:59 +02:00
Ananta Dwi Prasetya Purna Yuda
bdb8545611 fix(convergence): Serialize access to observed state
Signed-off-by: Ananta Dwi Prasetya Purna Yuda <hi@anantadwi13.com>
2024-10-02 15:04:38 +02:00
Joana Hrotko
41df35c1f4 Remove bind options when creating a volume type
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-10-02 10:00:28 +02:00
Nicolas De Loof
3ef5045a08 Bump docker v27.3.1
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-10-02 08:32:14 +02:00
Suleiman Dibirov
d9df7aab6e fix(push): Fix unexpected EOF on alpha publish
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-09-30 10:38:18 +02:00
Guillaume Lours
c9d96b449b use compose-go version fixing extra_hosts unicity issue
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-09-26 17:08:18 +01:00
Joana Hrotko
1744b45765 Show watch error message and open DD only when w is pressed
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-09-26 10:19:34 +01:00
Suleiman Dibirov
87f457e7dc add tests to down.go
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-09-26 10:36:37 +02:00
Suleiman Dibirov
abcc91e2b9 fix(down): Fix down command if specified services are not running
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
2024-09-26 10:36:37 +02:00
Joana Hrotko
8b9fe89842 After container restart register printer consumer
Signed-off-by: Joana Hrotko <joana.hrotko@docker.com>
2024-09-24 14:01:51 +02:00
Nicolas De Loof
34b18194f7 check secret source exists, as bind mount would create target as a folder otherwise
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-09-23 19:36:41 +02:00
Nicolas De Loof
ce27dba52e wait for dependent service up to delay set by --wait-timeout
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-09-23 18:25:02 +01:00
Nicolas De Loof
d2b9456137 append unix-style relative path when computing container target path
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-09-20 17:00:23 +02:00
Guillaume Lours
9c60fe67df revert commits link to mount API over bind changes
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2024-09-20 10:37:57 +02:00
Nicolas De Loof
c16df17e1f don't set propagation if target engine isn't linux
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-09-18 17:54:19 +02:00
Sebastiaan van Stijn
20404db12b build(deps): bump github.com/docker/docker v27.3.0-rc.2
full diff: https://github.com/docker/docker/compare/v27.3.0-rc.1...v27.3.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-09-18 15:32:40 +02:00
Sebastiaan van Stijn
f2ff7fd75e build(deps): bump github.com/docker/cli v27.3.0-rc.2
full diff: https://github.com/docker/cli/compare/v27.3.0-rc.1...v27.3.0-rc.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-09-18 15:32:40 +02:00
Nicolas De Loof
cb00aaad28 set propagation default
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2024-09-17 10:50:16 +02:00
temenuzhka-thede
e885bc084d Remove custom codeql workflow
Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>
2024-09-17 07:59:52 +02:00
196 changed files with 4933 additions and 1936 deletions

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
# global rules
* @docker/compose-maintainers

44
.github/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,44 @@
# Security Policy
The maintainers of Docker Compose take security seriously. If you discover
a security issue, please bring it to their attention right away!
## Reporting a Vulnerability
Please **DO NOT** file a public issue, instead send your report privately
to [security@docker.com](mailto:security@docker.com).
Reporter(s) can expect a response within 72 hours, acknowledging the issue was
received.
## Review Process
After receiving the report, an initial triage and technical analysis is
performed to confirm the report and determine its scope. We may request
additional information in this stage of the process.
Once a reviewer has confirmed the relevance of the report, a draft security
advisory will be created on GitHub. The draft advisory will be used to discuss
the issue with maintainers, the reporter(s), and where applicable, other
affected parties under embargo.
If the vulnerability is accepted, a timeline for developing a patch, public
disclosure, and patch release will be determined. If there is an embargo period
on public disclosure before the patch release, the reporter(s) are expected to
participate in the discussion of the timeline and abide by agreed upon dates
for public disclosure.
## Accreditation
Security reports are greatly appreciated and we will publicly thank you,
although we will keep your name confidential if you request it. We also like to
send gifts - if you're into swag, make sure to let us know. We do not currently
offer a paid security bounty program at this time.
## Supported Versions
This project docs not provide long-term supported versions, and only the current
release and `main` branch are actively maintained. Docker Compose v1, and the
corresponding [v1 branch](https://github.com/docker/compose/tree/v1) reached
EOL and are no longer supported.

2
.github/stale.yml vendored
View File

@@ -1,7 +1,7 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 180
daysUntilStale: 90
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.

View File

@@ -56,7 +56,7 @@ jobs:
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
-
name: Run
run: |
@@ -71,29 +71,45 @@ 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@v2
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
-
name: Build
uses: docker/bake-action@v2
uses: docker/bake-action@v6
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
@@ -105,15 +121,12 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
-
name: Test
uses: docker/bake-action@v2
uses: docker/bake-action@v6
with:
targets: test
set: |
@@ -141,19 +154,19 @@ jobs:
- plugin
- standalone
engine:
- 24.0.9
- 25.0.5
- 26.1.4
- 27.3.0
- 26
- 27
- 28
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
@@ -161,22 +174,24 @@ 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@v2
-
name: Set up Go
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- 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@v2
- name: Build
uses: docker/bake-action@v6
with:
source: .
targets: binary-with-coverage
set: |
*.cache-from=type=gha,scope=binary-linux-amd64
@@ -184,37 +199,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
@@ -284,7 +299,11 @@ 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 echo "$sum $file" > ${file#\*}.sha256; done
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
-
name: License
run: cp packaging/* ./bin/release/

View File

@@ -1,58 +0,0 @@
name: codeql
on:
push:
branches:
- 'main'
paths-ignore:
- '**/*.md'
- '**/*.txt'
- '**/*.yaml'
- '**/*_test.go'
pull_request:
branches:
- 'main'
paths-ignore:
- '**/*.md'
- '**/*.txt'
- '**/*.yaml'
- '**/*_test.go'
jobs:
analyze:
name: Analyze
runs-on: 'ubuntu-latest'
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language:
- go
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
check-latest: true
-
name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
-
name: Autobuild
uses: github/codeql-action/autobuild@v2
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@@ -2,6 +2,15 @@
# to check if yaml reference docs used in this repo are valid
name: docs-upstream
# Default to 'contents: read', which grants actions to read commits.
#
# If any permission is set, any permission not included in the list is
# implicitly set to "none".
#
# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
@@ -35,7 +44,7 @@ jobs:
retention-days: 1
validate:
uses: docker/docs/.github/workflows/validate-upstream.yml@919a9b9104a34a40b30d116529bcce589a544d1c # pin for artifact v4 support: https://github.com/docker/docs/pull/19220
uses: docker/docs/.github/workflows/validate-upstream.yml@main
needs:
- docs-yaml
with:

View File

@@ -82,16 +82,23 @@ 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@v2
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: |
${{ env.REPO_SLUG }}
@@ -99,28 +106,22 @@ 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@v2
uses: docker/bake-action@v6
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
@@ -129,14 +130,16 @@ jobs:
-
name: Generate Token
id: generate_token
uses: tibdex/github-app-token@v1
uses: actions/create-github-app-token@v1
with:
app_id: ${{ vars.DOCKERDESKTOP_APP_ID }}
private_key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
repository: docker/${{ secrets.DOCKERDESKTOP_REPO }}
app-id: ${{ vars.DOCKERDESKTOP_APP_ID }}
private-key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
owner: docker
repositories: |
${{ secrets.DOCKERDESKTOP_REPO }}
-
name: Trigger Docker Desktop e2e with edge version
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |

View File

@@ -22,12 +22,12 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.4.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # tag=v2.0.6
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0
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@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # tag=v4.5.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@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26
uses: github/codeql-action/upload-sarif@3096afedf9873361b2b2f65e1445b13272c83eb8 # tag=v2.20.00
with:
sarif_file: results.sarif

View File

@@ -1,4 +1,14 @@
name: 'Close stale issues'
# Default to 'contents: read', which grants actions to read commits.
#
# If any permission is set, any permission not included in the list is
# implicitly set to "none".
#
# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
contents: read
on:
schedule:
- cron: '0 0 * * 0,3' # at midnight UTC every Sunday and Wednesday

View File

@@ -5,12 +5,13 @@ linters:
enable-all: false
disable-all: true
enable:
- copyloopvar
- depguard
- errcheck
- errorlint
- gocritic
- gocyclo
- gofmt
- gofumpt
- goimports
- gomodguard
- revive
@@ -22,6 +23,7 @@ linters:
- nakedret
- nolintlint
- staticcheck
- testifylint
- typecheck
- unconvert
- unparam
@@ -71,3 +73,11 @@ issues:
# golangci hides some golint warnings (the warning about exported things
# without documentation for example), this will make it show them anyway.
exclude-use-default: false
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0

View File

@@ -2,10 +2,10 @@
### Prerequisites
* Windows:
* [Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-windows)
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
* make
* macOS:
* [Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-mac)
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/mac-install/)
* make
* Linux:
* [Docker 20.10 or later](https://docs.docker.com/engine/install/)

View File

@@ -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/overview/).
process](https://docs.docker.com/contribute/).
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/docker-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/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/search?tab=newest&q=docker" target="_blank">Docker questions</a>
monitor <a href="https://stackoverflow.com/questions/tagged/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](http://developercertificate.org/)):
the below (from [developercertificate.org](https://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/master/MAINTAINERS)
[MAINTAINERS](https://github.com/docker/opensource/blob/main/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](http://golang.org/doc/effective_go.html) and [Go Code Review
Comments](https://github.com/golang/go/wiki/CodeReviewComments).
Go](https://go.dev/doc/effective_go) and [Go Code Review
Comments](https://go.dev/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://golang.org/doc/effective_go.html). The
[Go Blog](https://blog.golang.org) is also a great resource. Drinking the
reading through [Effective Go](https://go.dev/doc/effective_go). The
[Go Blog](https://go.dev/blog/) is also a great resource. Drinking the
kool-aid is a lot easier than going thirsty.

View File

@@ -15,9 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GO_VERSION=1.22.7
ARG XX_VERSION=1.2.1
ARG GOLANGCI_LINT_VERSION=v1.60.2
ARG GO_VERSION=1.22.10
ARG XX_VERSION=1.6.1
ARG GOLANGCI_LINT_VERSION=v1.63.4
ARG ADDLICENSE_VERSION=v1.0.0
ARG BUILD_TAGS="e2e"

View File

@@ -23,6 +23,7 @@
people = [
"glours",
"jhrotko",
"milas",
"ndeloof",
"nicksieger",
@@ -72,6 +73,11 @@
Email = "guillaume.tardif@docker.com"
GitHub = "gtardif"
[people.jhrotko]
Name = "Joana Hrotko"
Email = "joana.hrotko@docker.com"
Github = "jhrotko"
[people.laurazard]
Name = "Laura Brehm"
Email = "laura.brehm@docker.com"

View File

@@ -116,6 +116,11 @@ 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))

View File

@@ -8,7 +8,7 @@
- [Legacy](#legacy)
# Docker Compose v2
[![GitHub release](https://img.shields.io/github/release/docker/compose.svg?style=flat-square)](https://github.com/docker/compose/releases/latest)
[![GitHub release](https://img.shields.io/github/v/release/docker/compose.svg?style=flat-square)](https://github.com/docker/compose/releases/latest)
[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?style=flat-square&logo=go&logoColor=white)](https://pkg.go.dev/github.com/docker/compose/v2)
[![Build Status](https://img.shields.io/github/actions/workflow/status/docker/compose/ci.yml?label=ci&logo=github&style=flat-square)](https://github.com/docker/compose/actions?query=workflow%3Aci)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/compose/v2?style=flat-square)](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

View File

@@ -55,7 +55,6 @@ 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)

View File

@@ -60,5 +60,4 @@ func TestGetFlags(t *testing.T) {
}
})
}
}

View File

@@ -17,6 +17,9 @@
package compatibility
import (
"errors"
"os"
"os/exec"
"testing"
"gotest.tools/v3/assert"
@@ -24,9 +27,10 @@ import (
func Test_convert(t *testing.T) {
tests := []struct {
name string
args []string
want []string
name string
args []string
want []string
wantErr bool
}{
{
name: "compose only",
@@ -93,11 +97,36 @@ 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) {
got := Convert(tt.args)
assert.DeepEqual(t, tt.want, got)
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)
}
})
}
}

View File

@@ -33,6 +33,7 @@ func alphaCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
cmd.AddCommand(
vizCommand(p, dockerCli, backend),
publishCommand(p, dockerCli, backend),
generateCommand(p, backend),
)
return cmd
}

93
cmd/compose/commit.go Normal file
View File

@@ -0,0 +1,93 @@
/*
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 (
"context"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type commitOptions struct {
*ProjectOptions
service string
reference string
pause bool
comment string
author string
changes opts.ListOpts
index int
}
func commitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
options := commitOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "commit [OPTIONS] SERVICE [REPOSITORY[:TAG]]",
Short: "Create a new image from a service container's changes",
Args: cobra.RangeArgs(1, 2),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
options.service = args[0]
if len(args) > 1 {
options.reference = args[1]
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runCommit(ctx, dockerCli, backend, options)
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.IntVar(&options.index, "index", 0, "index of the container if service has multiple replicas.")
flags.BoolVarP(&options.pause, "pause", "p", true, "Pause container during commit")
flags.StringVarP(&options.comment, "message", "m", "", "Commit message")
flags.StringVarP(&options.author, "author", "a", "", `Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")`)
options.changes = opts.NewListOpts(nil)
flags.VarP(&options.changes, "change", "c", "Apply Dockerfile instruction to the created image")
return cmd
}
func runCommit(ctx context.Context, dockerCli command.Cli, backend api.Service, options commitOptions) error {
projectName, err := options.toProjectName(ctx, dockerCli)
if err != nil {
return err
}
commitOptions := api.CommitOptions{
Service: options.service,
Reference: options.reference,
Pause: options.pause,
Comment: options.comment,
Author: options.author,
Changes: options.changes,
Index: options.index,
}
return backend.Commit(ctx, projectName, commitOptions)
}

View File

@@ -21,6 +21,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
@@ -37,12 +38,12 @@ import (
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/pkg/kvfile"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/internal/desktop"
"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"
@@ -70,6 +71,26 @@ const (
ComposeMenu = "COMPOSE_MENU"
)
// rawEnv load a dot env file using docker/cli key=value parser, without attempt to interpolate or evaluate values
func rawEnv(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error) {
lines, err := kvfile.ParseFromReader(r, lookup)
if err != nil {
return nil, fmt.Errorf("failed to parse env_file %s: %w", filename, err)
}
vars := types.Mapping{}
for _, line := range lines {
key, value, _ := strings.Cut(line, "=")
vars[key] = value
}
return vars, nil
}
func init() {
// compose evaluates env file values for interpolation
// `raw` format allows to load env_file with the same parser used by docker run --env-file
dotenv.RegisterFormat("raw", rawEnv)
}
type Backend interface {
api.Service
@@ -99,17 +120,9 @@ 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 {
@@ -285,7 +298,7 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
options, err := o.toProjectOptions(po...)
if err != nil {
return nil, metrics, compose.WrapComposeError(err)
return nil, metrics, err
}
options.WithListeners(func(event string, metadata map[string]any) {
@@ -317,7 +330,7 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
project, err := options.LoadProject(ctx)
if err != nil {
return nil, metrics, compose.WrapComposeError(err)
return nil, metrics, err
}
if project.Name == "" {
@@ -431,7 +444,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
}
_ = cmd.Help()
return dockercli.StatusError{
StatusCode: compose.CommandSyntaxFailure.ExitCode,
StatusCode: 1,
Status: fmt.Sprintf("unknown docker command: %q", "compose "+args[0]),
}
},
@@ -580,7 +593,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
}
c.AddCommand(
upCommand(&opts, dockerCli, backend, experiments),
upCommand(&opts, dockerCli, backend),
downCommand(&opts, dockerCli, backend),
startCommand(&opts, dockerCli, backend),
restartCommand(&opts, dockerCli, backend),
@@ -594,6 +607,8 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
removeCommand(&opts, dockerCli, backend),
execCommand(&opts, dockerCli, backend),
attachCommand(&opts, dockerCli, backend),
exportCommand(&opts, dockerCli, backend),
commitCommand(&opts, dockerCli, backend),
pauseCommand(&opts, dockerCli, backend),
unpauseCommand(&opts, dockerCli, backend),
topCommand(&opts, dockerCli, backend),

View File

@@ -279,6 +279,22 @@ func formatModel(model map[string]any, format string) (content []byte, err error
}
func runServices(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
if opts.noInterpolate {
// we can't use ToProject, so the model we render here is only partially resolved
data, err := opts.ToModel(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
if _, ok := data["services"]; ok {
for serviceName := range data["services"].(map[string]any) {
_, _ = fmt.Fprintln(dockerCli.Out(), serviceName)
}
}
return nil
}
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
@@ -287,6 +303,7 @@ func runServices(ctx context.Context, dockerCli command.Cli, opts configOptions)
_, _ = fmt.Fprintln(dockerCli.Out(), serviceName)
return nil
})
return err
}
@@ -331,7 +348,6 @@ func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) err
}
hash, err := compose.ServiceHash(s)
if err != nil {
return err
}

View File

@@ -66,9 +66,7 @@ func copyCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
flags := copyCmd.Flags()
flags.IntVar(&opts.index, "index", 0, "Index of the container if service has multiple replicas")
flags.BoolVar(&opts.all, "all", false, "Copy to all the containers of the service")
flags.MarkHidden("all") //nolint:errcheck
flags.MarkDeprecated("all", "By default all the containers of the service will get the source file/directory to be copied") //nolint:errcheck
flags.BoolVar(&opts.all, "all", false, "Include containers created by the run command")
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")

View File

@@ -46,6 +46,7 @@ type createOptions struct {
timeout int
quietPull bool
scale []string
AssumeYes bool
}
func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
@@ -80,6 +81,7 @@ 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
}
@@ -107,6 +109,7 @@ func runCreate(ctx context.Context, _ command.Cli, backend api.Service, createOp
Inherit: !createOpts.noInherit,
Timeout: createOpts.GetTimeout(),
QuietPull: createOpts.quietPull,
AssumeYes: createOpts.AssumeYes,
})
}
@@ -195,7 +198,9 @@ 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)
}

View File

@@ -40,7 +40,9 @@ func TestRunCreate(t *testing.T) {
)
createOpts := createOptions{}
buildOpts := buildOptions{}
buildOpts := buildOptions{
ProjectOptions: &ProjectOptions{},
}
project := sampleProject()
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
require.NoError(t, err)
@@ -58,7 +60,9 @@ func TestRunCreate_Build(t *testing.T) {
createOpts := createOptions{
Build: true,
}
buildOpts := buildOptions{}
buildOpts := buildOptions{
ProjectOptions: &ProjectOptions{},
}
project := sampleProject()
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
require.NoError(t, err)

74
cmd/compose/export.go Normal file
View File

@@ -0,0 +1,74 @@
/*
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 (
"context"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
)
type exportOptions struct {
*ProjectOptions
service string
output string
index int
}
func exportCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
options := exportOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "export [OPTIONS] SERVICE",
Short: "Export a service container's filesystem as a tar archive",
Args: cobra.MinimumNArgs(1),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
options.service = args[0]
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runExport(ctx, dockerCli, backend, options)
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.IntVar(&options.index, "index", 0, "index of the container if service has multiple replicas.")
flags.StringVarP(&options.output, "output", "o", "", "Write to a file, instead of STDOUT")
return cmd
}
func runExport(ctx context.Context, dockerCli command.Cli, backend api.Service, options exportOptions) error {
projectName, err := options.toProjectName(ctx, dockerCli)
if err != nil {
return err
}
exportOptions := api.ExportOptions{
Service: options.service,
Index: options.index,
Output: options.output,
}
return backend.Export(ctx, projectName, exportOptions)
}

82
cmd/compose/generate.go Normal file
View File

@@ -0,0 +1,82 @@
/*
Copyright 2023 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 (
"context"
"fmt"
"os"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type generateOptions struct {
*ProjectOptions
Format string
}
func generateCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
opts := generateOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "generate [OPTIONS] [CONTAINERS...]",
Short: "EXPERIMENTAL - Generate a Compose file from existing containers",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runGenerate(ctx, backend, opts, args)
}),
}
cmd.Flags().StringVar(&opts.ProjectName, "name", "", "Project name to set in the Compose file")
cmd.Flags().StringVar(&opts.ProjectDir, "project-dir", "", "Directory to use for the project")
cmd.Flags().StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")
return cmd
}
func runGenerate(ctx context.Context, backend api.Service, opts generateOptions, containers []string) error {
_, _ = fmt.Fprintln(os.Stderr, "generate command is EXPERIMENTAL")
if len(containers) == 0 {
return fmt.Errorf("at least one container must be specified")
}
project, err := backend.Generate(ctx, api.GenerateOptions{
Containers: containers,
ProjectName: opts.ProjectName,
})
if err != nil {
return err
}
var content []byte
switch opts.Format {
case "json":
content, err = project.MarshalJSON()
case "yaml":
content, err = project.MarshalYAML()
default:
return fmt.Errorf("unsupported format %q", opts.Format)
}
if err != nil {
return err
}
fmt.Println(string(content))
return nil
}

View File

@@ -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 IDs")
lsCmd.Flags().BoolVarP(&lsOpts.Quiet, "quiet", "q", false, "Only display project names")
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")

View File

@@ -27,6 +27,7 @@ import (
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
)
@@ -74,13 +75,13 @@ func TestPsTable(t *testing.T) {
cli.EXPECT().Out().Return(stdout).AnyTimes()
cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
err = runPs(ctx, cli, backend, nil, opts)
assert.NoError(t, err)
require.NoError(t, err)
_, err = f.Seek(0, 0)
assert.NoError(t, err)
require.NoError(t, err)
output, err := os.ReadFile(out)
assert.NoError(t, err)
require.NoError(t, err)
assert.Contains(t, string(output), "8080/tcp, 8443/tcp")
}

View File

@@ -29,6 +29,8 @@ type publishOptions struct {
*ProjectOptions
resolveImageDigests bool
ociVersion string
withEnvironment bool
assumeYes bool
}
func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
@@ -36,7 +38,7 @@ func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "publish [OPTIONS] [REPOSITORY]",
Use: "publish [OPTIONS] REPOSITORY[:TAG]",
Short: "Publish compose application",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPublish(ctx, dockerCli, backend, opts, args[0])
@@ -45,7 +47,10 @@ 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.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`)
return cmd
}
@@ -58,5 +63,7 @@ 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,
})
}

View File

@@ -63,6 +63,7 @@ type runOptions struct {
name string
noDeps bool
ignoreOrphans bool
removeOrphans bool
quietPull bool
}
@@ -153,6 +154,7 @@ 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 {
@@ -187,9 +189,10 @@ 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(&createOpts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
flags.BoolVar(&options.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file")
cmd.Flags().BoolVarP(&options.interactive, "interactive", "i", true, "Keep STDIN open even if not attached")
cmd.Flags().BoolVarP(&options.tty, "tty", "t", true, "Allocate a pseudo-TTY")
@@ -314,6 +317,7 @@ func startDependencies(ctx context.Context, backend api.Service, project types.P
err := backend.Create(ctx, &project, api.CreateOptions{
Build: buildOpts,
IgnoreOrphans: options.ignoreOrphans,
RemoveOrphans: options.removeOrphans,
QuietPull: options.quietPull,
})
if err != nil {

View File

@@ -92,7 +92,6 @@ 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)
}

View File

@@ -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/go/formatting/ for more information about formatting output with templates`)
Refer to https://docs.docker.com/engine/cli/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

View File

@@ -26,11 +26,10 @@ import (
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/internal/experimental"
xprogress "github.com/moby/buildkit/util/progress/progressui"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/api"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
@@ -81,13 +80,19 @@ func (opts upOptions) apply(project *types.Project, services []string) (*types.P
return project, nil
}
func (opts *upOptions) validateNavigationMenu(dockerCli command.Cli, experimentals *experimental.State) {
func (opts *upOptions) validateNavigationMenu(dockerCli command.Cli) {
if !dockerCli.Out().IsTerminal() {
opts.navigationMenu = false
return
}
// If --menu flag was not set
if !opts.navigationMenuChanged {
opts.navigationMenu = SetUnchangedOption(ComposeMenu, experimentals.NavBar())
if envVar, ok := os.LookupEnv(ComposeMenu); ok {
opts.navigationMenu = utils.StringToBool(envVar)
return
}
// ...and COMPOSE_MENU env var is not defined we want the default value to be true
opts.navigationMenu = true
}
}
@@ -102,7 +107,7 @@ func (opts upOptions) OnExit() api.Cascade {
}
}
func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service, experiments *experimental.State) *cobra.Command {
func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
up := upOptions{}
create := createOptions{}
build := buildOptions{ProjectOptions: p}
@@ -127,7 +132,7 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service, ex
return errors.New("cannot combine --attach and --attach-dependencies")
}
up.validateNavigationMenu(dockerCli, experiments)
up.validateNavigationMenu(dockerCli)
if !p.All && len(project.Services) == 0 {
return fmt.Errorf("no service selected")
@@ -140,6 +145,7 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service, ex
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")
@@ -162,7 +168,7 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service, ex
flags.StringArrayVar(&up.noAttach, "no-attach", []string{}, "Do not attach (stream logs) to the specified services")
flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Automatically attach to log output of dependent services")
flags.BoolVar(&up.wait, "wait", false, "Wait for services to be running|healthy. Implies detached mode.")
flags.IntVar(&up.waitTimeout, "wait-timeout", 0, "Maximum duration to wait for the project to be running|healthy")
flags.IntVar(&up.waitTimeout, "wait-timeout", 0, "Maximum duration in seconds to wait for the project to be running|healthy")
flags.BoolVarP(&up.watch, "watch", "w", false, "Watch source code and rebuild/refresh containers when files are updated.")
flags.BoolVar(&up.navigationMenu, "menu", false, "Enable interactive shortcuts when running attached. Incompatible with --detach. Can also be enable/disable by setting COMPOSE_MENU environment var.")
@@ -250,6 +256,7 @@ func runUp(
Inherit: !createOptions.noInherit,
Timeout: createOptions.GetTimeout(),
QuietPull: createOptions.quietPull,
AssumeYes: createOptions.AssumeYes,
}
if upOptions.noStart {

View File

@@ -47,5 +47,4 @@ func TestApplyScaleOpt(t *testing.T) {
assert.NilError(t, err)
assert.Equal(t, *bar.Scale, 3)
assert.Equal(t, *bar.Deploy.Replicas, 3)
}

View File

@@ -17,10 +17,10 @@
package compose
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPreferredIndentationStr(t *testing.T) {
@@ -83,10 +83,12 @@ func TestPreferredIndentationStr(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := preferredIndentationStr(tt.args.size, tt.args.useSpace)
if tt.wantErr && assert.NotNilf(t, err, fmt.Sprintf("preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)) {
return
if tt.wantErr {
require.Errorf(t, err, "preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)
} else {
require.NoError(t, err)
assert.Equalf(t, tt.want, got, "preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)
}
assert.Equalf(t, tt.want, got, "preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)
})
}
}

View File

@@ -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, nil)
project, _, err := watchOpts.ToProject(ctx, dockerCli, services)
if err != nil {
return err
}

View File

@@ -27,42 +27,49 @@ 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
@@ -70,6 +77,7 @@ func ClearLine() {
// Does not move cursor from its current position
fmt.Print(ansi("[2K"))
}
func MoveCursorUp(lines int) {
if disableAnsi {
return
@@ -77,6 +85,7 @@ func MoveCursorUp(lines int) {
// Does not add new lines
fmt.Print(ansi(fmt.Sprintf("[%dA", lines)))
}
func MoveCursorDown(lines int) {
if disableAnsi {
return
@@ -84,10 +93,12 @@ 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

View File

@@ -21,7 +21,7 @@ import (
"strconv"
"sync"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/cli/cli/command"
)
var names = []string{
@@ -59,7 +59,7 @@ const (
)
// SetANSIMode configure formatter for colored output on ANSI-compliant console
func SetANSIMode(streams api.Streams, ansi string) {
func SetANSIMode(streams command.Streams, ansi string) {
if !useAnsi(streams, ansi) {
nextColor = func() colorFunc {
return monochrome
@@ -68,7 +68,7 @@ func SetANSIMode(streams api.Streams, ansi string) {
}
}
func useAnsi(streams api.Streams, ansi string) bool {
func useAnsi(streams command.Streams, ansi string) bool {
switch ansi {
case Always:
return true
@@ -104,10 +104,12 @@ func makeColorFunc(code string) colorFunc {
}
}
var nextColor = rainbowColor
var rainbow []colorFunc
var currentIndex = 0
var mutex sync.Mutex
var (
nextColor = rainbowColor
rainbow []colorFunc
currentIndex = 0
mutex sync.Mutex
)
func rainbowColor() colorFunc {
mutex.Lock()

View File

@@ -61,21 +61,32 @@ func (l *logConsumer) Register(name string) {
}
func (l *logConsumer) register(name string) *presenter {
cf := monochrome
if l.color {
if name == api.WatchLogger {
cf = makeColorFunc("92")
} else {
cf = nextColor()
var p *presenter
root, _, found := strings.Cut(name, " ")
if found {
parent := l.getPresenter(root)
p = &presenter{
colors: parent.colors,
name: name,
prefix: parent.prefix,
}
} else {
cf := monochrome
if l.color {
if name == api.WatchLogger {
cf = makeColorFunc("92")
} else {
cf = nextColor()
}
}
p = &presenter{
colors: cf,
name: name,
}
}
p := &presenter{
colors: cf,
name: name,
}
l.presenters.Store(name, p)
l.computeWidth()
if l.prefix {
l.computeWidth()
l.presenters.Range(func(key, value interface{}) bool {
p := value.(*presenter)
p.setPrefix(l.width)

View File

@@ -106,15 +106,16 @@ type LogKeyboard struct {
Watch KeyboardWatch
IsDockerDesktopActive bool
IsWatchConfigured bool
IsDDComposeUIActive bool
logLevel KEYBOARD_LOG_LEVEL
signalChannel chan<- os.Signal
}
var KeyboardManager *LogKeyboard
var eg multierror.Group
var (
KeyboardManager *LogKeyboard
eg multierror.Group
)
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured, isDockerDesktopConfigActive bool,
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured bool,
sc chan<- os.Signal,
watchFn func(ctx context.Context,
doneCh chan bool,
@@ -126,7 +127,6 @@ func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfi
km := LogKeyboard{}
km.IsDockerDesktopActive = isDockerDesktopActive
km.IsWatchConfigured = isWatchConfigured
km.IsDDComposeUIActive = isDockerDesktopConfigActive
km.logLevel = INFO
km.Watch.Watching = false
@@ -200,14 +200,15 @@ func (lk *LogKeyboard) navigationMenu() string {
if openDDInfo != "" {
openDDUI = navColor(" ")
}
if lk.IsDDComposeUIActive {
if lk.IsDockerDesktopActive {
openDDUI = openDDUI + shortcutKeyColor("o") + navColor(" View Config")
}
var watchInfo string
if openDDInfo != "" || openDDUI != "" {
watchInfo = navColor(" ")
}
var isEnabled = " Enable"
isEnabled := " Enable"
if lk.Watch.Watching {
isEnabled = " Disable"
}
@@ -246,7 +247,7 @@ func (lk *LogKeyboard) openDockerDesktop(ctx context.Context, project *types.Pro
}
func (lk *LogKeyboard) openDDComposeUI(ctx context.Context, project *types.Project) {
if !lk.IsDDComposeUIActive {
if !lk.IsDockerDesktopActive {
return
}
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/composeview", tracing.SpanOptions{},
@@ -261,6 +262,7 @@ 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 {
@@ -288,19 +290,7 @@ func (lk *LogKeyboard) keyboardError(prefix string, err error) {
func (lk *LogKeyboard) StartWatch(ctx context.Context, doneCh chan bool, project *types.Project, options api.UpOptions) {
if !lk.IsWatchConfigured {
if lk.IsDDComposeUIActive {
// we try to open watch docs
lk.openDDWatchDocs(ctx, project)
}
// either way we mark menu/watch as an error
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{},
func(ctx context.Context) error {
err := fmt.Errorf("Watch is not yet configured. Learn more: %s", ansiColor(CYAN, "https://docs.docker.com/compose/file-watch/"))
lk.keyboardError("Watch", err)
return err
}))
return
}
lk.Watch.switchWatching()
if !lk.Watch.isWatching() {
@@ -317,10 +307,15 @@ func (lk *LogKeyboard) StartWatch(ctx context.Context, doneCh chan bool, project
lk.Watch.newContext(ctx)
buildOpts := *options.Create.Build
buildOpts.Quiet = true
return lk.Watch.WatchFn(lk.Watch.Ctx, doneCh, project, options.Start.Services, api.WatchOptions{
err := 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
}))
}
}
@@ -330,6 +325,20 @@ func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Cont
case 'v':
lk.openDockerDesktop(ctx, project)
case 'w':
if !lk.IsWatchConfigured {
// we try to open watch docs if DD is installed
if lk.IsDockerDesktopActive {
lk.openDDWatchDocs(ctx, project)
}
// either way we mark menu/watch as an error
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{},
func(ctx context.Context) error {
err := fmt.Errorf("watch is not yet configured. Learn more: %s", ansiColor(CYAN, "https://docs.docker.com/compose/file-watch/"))
lk.keyboardError("Watch", err)
return err
}))
return
}
lk.StartWatch(ctx, doneCh, project, options)
case 'o':
lk.openDDComposeUI(ctx, project)

View File

@@ -62,7 +62,7 @@ func pluginMain() {
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return dockercli.StatusError{
StatusCode: compose.CommandSyntaxFailure.ExitCode,
StatusCode: 1,
Status: err.Error(),
}
})

View File

@@ -13,12 +13,14 @@ Define and run multi-container applications with Docker
|:--------------------------------|:----------------------------------------------------------------------------------------|
| [`attach`](compose_attach.md) | Attach local standard input, output, and error streams to a service's running container |
| [`build`](compose_build.md) | Build or rebuild services |
| [`commit`](compose_commit.md) | Create a new image from a service container's changes |
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
| [`create`](compose_create.md) | Creates containers for a service |
| [`down`](compose_down.md) | Stop and remove containers, networks |
| [`events`](compose_events.md) | Receive real time events from containers |
| [`exec`](compose_exec.md) | Execute a command in a running container |
| [`export`](compose_export.md) | Export a service container's filesystem as a tar archive |
| [`images`](compose_images.md) | List images used by the created containers |
| [`kill`](compose_kill.md) | Force stop service containers |
| [`logs`](compose_logs.md) | View output from containers |

View File

@@ -0,0 +1,17 @@
# docker compose alpha generate
<!---MARKER_GEN_START-->
EXPERIMENTAL - Generate a Compose file from existing containers
### Options
| Name | Type | Default | Description |
|:----------------|:---------|:--------|:------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--format` | `string` | `yaml` | Format the output. Values: [yaml \| json] |
| `--name` | `string` | | Project name to set in the Compose file |
| `--project-dir` | `string` | | Directory to use for the project |
<!---MARKER_GEN_END-->

View File

@@ -8,8 +8,10 @@ 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-->

View File

@@ -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/master/spec.md#image) name,
[image](https://github.com/compose-spec/compose-spec/blob/main/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/master/spec.md#interpolation).
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/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/master/spec.md#image) name,
[image](https://github.com/compose-spec/compose-spec/blob/main/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/master/spec.md#interpolation).
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/spec.md#interpolation).
If you change a service's `Dockerfile` or the contents of its build directory,
run `docker compose build` to rebuild it.

View File

@@ -0,0 +1,19 @@
# docker compose commit
<!---MARKER_GEN_START-->
Create a new image from a service container's changes
### Options
| Name | Type | Default | Description |
|:------------------|:---------|:--------|:-----------------------------------------------------------|
| `-a`, `--author` | `string` | | Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") |
| `-c`, `--change` | `list` | | Apply Dockerfile instruction to the created image |
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--index` | `int` | `0` | index of the container if service has multiple replicas. |
| `-m`, `--message` | `string` | | Commit message |
| `-p`, `--pause` | `bool` | `true` | Pause container during commit |
<!---MARKER_GEN_END-->

View File

@@ -7,6 +7,7 @@ Copy files/folders between a service container and the local filesystem
| Name | Type | Default | Description |
|:----------------------|:-------|:--------|:--------------------------------------------------------|
| `--all` | `bool` | | Include containers created by the run command |
| `-a`, `--archive` | `bool` | | Archive mode (copy all uid/gid information) |
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `-L`, `--follow-link` | `bool` | | Always follow symbol link in SRC_PATH |

View File

@@ -16,6 +16,7 @@ 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-->

View File

@@ -0,0 +1,16 @@
# docker compose export
<!---MARKER_GEN_START-->
Export a service container's filesystem as a tar archive
### Options
| Name | Type | Default | Description |
|:-----------------|:---------|:--------|:---------------------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--index` | `int` | `0` | index of the container if service has multiple replicas. |
| `-o`, `--output` | `string` | | Write to a file, instead of STDOUT |
<!---MARKER_GEN_END-->

View File

@@ -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 IDs |
| `-q`, `--quiet` | `bool` | | Only display project names |
<!---MARKER_GEN_END-->

View File

@@ -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/master/spec.md#restart)
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
[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).
### 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/master/spec.md#restart)
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
[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).

View File

@@ -57,29 +57,30 @@ 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 |
| `--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 |
| `--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 |
<!---MARKER_GEN_END-->

View File

@@ -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/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 |
| 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 |
<!---MARKER_GEN_END-->

View File

@@ -51,8 +51,9 @@ If the process is interrupted using `SIGINT` (ctrl + C) or `SIGTERM`, the contai
| `-t`, `--timeout` | `int` | `0` | Use this timeout in seconds for container shutdown when attached or when containers are already running |
| `--timestamps` | `bool` | | Show timestamps |
| `--wait` | `bool` | | Wait for services to be running\|healthy. Implies detached mode. |
| `--wait-timeout` | `int` | `0` | Maximum duration to wait for the project to be running\|healthy |
| `--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-->

View File

@@ -7,12 +7,14 @@ plink: docker.yaml
cname:
- docker compose attach
- docker compose build
- docker compose commit
- docker compose config
- docker compose cp
- docker compose create
- docker compose down
- docker compose events
- docker compose exec
- docker compose export
- docker compose images
- docker compose kill
- docker compose logs
@@ -38,12 +40,14 @@ cname:
clink:
- docker_compose_attach.yaml
- docker_compose_build.yaml
- docker_compose_commit.yaml
- docker_compose_config.yaml
- docker_compose_cp.yaml
- docker_compose_create.yaml
- docker_compose_down.yaml
- docker_compose_events.yaml
- docker_compose_exec.yaml
- docker_compose_export.yaml
- docker_compose_images.yaml
- docker_compose_kill.yaml
- docker_compose_logs.yaml

View File

@@ -4,9 +4,11 @@ long: Experimental commands
pname: docker compose
plink: docker_compose.yaml
cname:
- docker compose alpha generate
- docker compose alpha publish
- docker compose alpha viz
clink:
- docker_compose_alpha_generate.yaml
- docker_compose_alpha_publish.yaml
- docker_compose_alpha_viz.yaml
inherited_options:

View File

@@ -0,0 +1,53 @@
command: docker compose alpha generate
short: EXPERIMENTAL - Generate a Compose file from existing containers
long: EXPERIMENTAL - Generate a Compose file from existing containers
usage: docker compose alpha generate [OPTIONS] [CONTAINERS...]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
options:
- option: format
value_type: string
default_value: yaml
description: 'Format the output. Values: [yaml | json]'
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: name
value_type: string
description: Project name to set in the Compose file
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: project-dir
value_type: string
description: Directory to use for the project
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: true
kubernetes: false
swarm: false

View File

@@ -1,14 +1,14 @@
command: docker compose alpha publish
short: Publish compose application
long: Publish compose application
usage: docker compose alpha publish [OPTIONS] [REPOSITORY]
usage: docker compose alpha publish [OPTIONS] REPOSITORY[:TAG]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
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,6 +25,27 @@ 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

View File

@@ -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/master/spec.md#image) name,
[image](https://github.com/compose-spec/compose-spec/blob/main/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/master/spec.md#interpolation).
[variable interpolation](https://github.com/compose-spec/compose-spec/blob/main/spec.md#interpolation).
If you change a service's `Dockerfile` or the contents of its build directory,
run `docker compose build` to rebuild it.

View File

@@ -0,0 +1,76 @@
command: docker compose commit
short: Create a new image from a service container's changes
long: Create a new image from a service container's changes
usage: docker compose commit [OPTIONS] SERVICE [REPOSITORY[:TAG]]
pname: docker compose
plink: docker_compose.yaml
options:
- option: author
shorthand: a
value_type: string
description: Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: change
shorthand: c
value_type: list
description: Apply Dockerfile instruction to the created image
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: index
value_type: int
default_value: "0"
description: index of the container if service has multiple replicas.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: message
shorthand: m
value_type: string
description: Commit message
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: pause
shorthand: p
value_type: bool
default_value: "true"
description: Pause container during commit
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false

View File

@@ -10,9 +10,9 @@ options:
- option: all
value_type: bool
default_value: "false"
description: Copy to all the containers of the service
deprecated: true
hidden: true
description: Include containers created by the run command
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false

View File

@@ -88,6 +88,17 @@ 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

View File

@@ -0,0 +1,45 @@
command: docker compose export
short: Export a service container's filesystem as a tar archive
long: Export a service container's filesystem as a tar archive
usage: docker compose export [OPTIONS] SERVICE
pname: docker compose
plink: docker_compose.yaml
options:
- option: index
value_type: int
default_value: "0"
description: index of the container if service has multiple replicas.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: output
shorthand: o
value_type: string
description: Write to a file, instead of STDOUT
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false

View File

@@ -39,7 +39,7 @@ options:
shorthand: q
value_type: bool
default_value: "false"
description: Only display IDs
description: Only display project names
deprecated: false
hidden: false
experimental: false

View File

@@ -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/master/spec.md#restart)
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).
[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).
usage: docker compose restart [OPTIONS] [SERVICE...]
pname: docker compose
plink: docker_compose.yaml

View File

@@ -180,6 +180,16 @@ 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"

View File

@@ -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/go/formatting/ for more information about formatting output with templates
Refer to https://docs.docker.com/engine/cli/formatting/ for more information about formatting output with templates
deprecated: false
hidden: false
experimental: false

View File

@@ -289,7 +289,8 @@ options:
- option: wait-timeout
value_type: int
default_value: "0"
description: Maximum duration to wait for the project to be running|healthy
description: |
Maximum duration in seconds to wait for the project to be running|healthy
deprecated: false
hidden: false
experimental: false
@@ -308,6 +309,17 @@ 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

180
go.mod
View File

@@ -1,21 +1,21 @@
module github.com/docker/compose/v2
go 1.21.0
go 1.22.10
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.2.0
github.com/containerd/containerd v1.7.22
github.com/containerd/platforms v0.2.1
github.com/davecgh/go-spew v1.1.1
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/distribution/reference v0.6.0
github.com/docker/buildx v0.17.1
github.com/docker/cli v27.3.0-rc.1+incompatible
github.com/docker/cli-docs-tool v0.8.0
github.com/docker/docker v27.3.0-rc.1+incompatible
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/go-connections v0.5.0
github.com/docker/go-units v0.5.0
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
@@ -23,71 +23,74 @@ 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.4.0
github.com/jonboulle/clockwork v0.5.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.16.0
github.com/moby/buildkit v0.19.0
github.com/moby/patternmatcher v0.6.0
github.com/moby/term v0.5.0
github.com/moby/term v0.5.2
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.0
github.com/otiai10/copy v1.14.1
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.5
github.com/stretchr/testify v1.9.0
github.com/spf13/pflag v1.0.6
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.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.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.uber.org/goleak v1.3.0
go.uber.org/mock v0.4.0
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948
golang.org/x/sync v0.8.0
golang.org/x/sys v0.25.0
google.golang.org/grpc v1.62.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
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.1
gotest.tools/v3 v3.5.2
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-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // 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/Masterminds/semver/v3 v3.2.1 // 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/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/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/console v1.0.4 // indirect
github.com/containerd/containerd/api v1.7.19 // indirect
github.com/containerd/continuity v0.4.3 // indirect
github.com/containerd/errdefs v0.1.0 // 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/log v0.1.0 // 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.4 // 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/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
@@ -95,14 +98,14 @@ 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/go-logr/logr v1.4.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // 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.3 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-viper/mapstructure/v2 v2.0.0 // indirect
github.com/gofrs/flock v0.12.1 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
@@ -111,7 +114,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.16.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.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
@@ -120,18 +123,18 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
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.2.0 // indirect
github.com/moby/spdystream v0.4.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
@@ -142,53 +145,56 @@ require (
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/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/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/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c // 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/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
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.26.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.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
golang.org/x/time v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/protobuf v1.33.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
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.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
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
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.3.0 // indirect
tags.cncf.io/container-device-interface v0.8.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

437
go.sum
View File

@@ -1,25 +1,21 @@
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.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
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-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/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/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-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
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/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.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ=
github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU=
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
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=
@@ -31,34 +27,36 @@ 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.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/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/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=
@@ -75,68 +73,72 @@ 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.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.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
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/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-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
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.2.0 h1:VsQosGhuO+H9wh5laiIiAe4TVd73kQ5NWwmNrdm0HRA=
github.com/compose-spec/compose-go/v2 v2.2.0/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
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/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd v1.7.22 h1:nZuNnNRA6T6jB975rx2RRNqqH2k6ELYKDZfqTHqwyy0=
github.com/containerd/containerd v1.7.22/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g=
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.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
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/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.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 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
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/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/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.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/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/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.17.1 h1:9ob2jGp4+W9PxWw68GsoNFp+eYFc7eUoRL9VljLCSM4=
github.com/docker/buildx v0.17.1/go.mod h1:kJOhOhS47LRvrLFRulFiO5SE6VJf54yYMn7DzjgO5W0=
github.com/docker/cli v27.3.0-rc.1+incompatible h1:yc++0aWWMlq4QBYrvuuzYhVHc+Y/MRrWa4T/g/0mVPQ=
github.com/docker/cli v27.3.0-rc.1+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/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/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.3.0-rc.1+incompatible h1:rqvkkh1Ukw3IYyI0DYbMuLd0r5EvIRC4bAaFg4uC8sU=
github.com/docker/docker v27.3.0-rc.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
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-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=
@@ -144,8 +146,6 @@ 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,49 +158,47 @@ 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.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
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.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/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/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 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-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-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=
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
github.com/golang/glog v1.2.0/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=
@@ -220,8 +218,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-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
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/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=
@@ -229,11 +227,10 @@ 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.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
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/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=
@@ -260,8 +257,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.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
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=
@@ -274,8 +271,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -287,6 +284,8 @@ 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=
@@ -305,8 +304,6 @@ 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=
@@ -319,16 +316,18 @@ 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.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE=
github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ=
github.com/moby/buildkit v0.19.0 h1:w9G1p7sArvCGNkpWstAqJfRQTXBKukMyMK1bsah1HNo=
github.com/moby/buildkit v0.19.0/go.mod h1:WiHBFTgWV8eB1AmPxIWsAlKjUACAwm3X/14xOV4VWew=
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.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
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/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=
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
@@ -341,8 +340,8 @@ 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.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
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/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=
@@ -361,12 +360,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.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
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/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.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
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/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=
@@ -375,38 +374,43 @@ 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/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
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/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.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/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/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=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
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/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.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
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_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.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
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/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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
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=
@@ -417,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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
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/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=
@@ -444,8 +448,9 @@ 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=
@@ -462,22 +467,28 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
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/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M=
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM=
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/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.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
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/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=
@@ -488,40 +499,42 @@ 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.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.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.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.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -530,15 +543,15 @@ 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.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
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/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=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -549,10 +562,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.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
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/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=
@@ -560,8 +573,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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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/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=
@@ -582,19 +595,19 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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/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.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
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/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=
@@ -602,23 +615,21 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU=
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
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/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
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=
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=
@@ -645,25 +656,27 @@ 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.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=
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=
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.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
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=

View File

@@ -27,11 +27,15 @@ import (
"net/http"
"strings"
"github.com/docker/compose/v2/internal"
"github.com/docker/compose/v2/internal/memnet"
"github.com/r3labs/sse"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// identify this client in the logs
var userAgent = "compose/" + internal.Version
// Client for integration with Docker Desktop features.
type Client struct {
apiEndpoint string
@@ -76,6 +80,7 @@ func (c *Client) Ping(ctx context.Context) (*PingResponse, error) {
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
@@ -105,6 +110,7 @@ func (c *Client) FeatureFlags(ctx context.Context) (FeatureFlagResponse, error)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
@@ -135,6 +141,7 @@ func (c *Client) GetFileSharesConfig(ctx context.Context) (*GetFileSharesConfigR
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
@@ -170,6 +177,7 @@ func (c *Client) CreateFileShare(ctx context.Context, r CreateFileShareRequest)
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
@@ -212,6 +220,7 @@ func (c *Client) ListFileShares(ctx context.Context) ([]FileShareSession, error)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
@@ -236,6 +245,7 @@ func (c *Client) DeleteFileShare(ctx context.Context, id string) error {
if err != nil {
return err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return err
@@ -268,6 +278,7 @@ func (c *Client) StreamFileShares(ctx context.Context) (<-chan EventMessage[[]Fi
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", userAgent)
resp, err := c.client.Do(req)
if err != nil {
return nil, err

View File

@@ -66,20 +66,3 @@ func (s *State) Load(ctx context.Context, client *desktop.Client) error {
s.desktopValues = desktopValues
return nil
}
func (s *State) NavBar() bool {
return s.determineFeatureState("ComposeNav")
}
func (s *State) ComposeUI() bool {
return s.determineFeatureState("ComposeUIView")
}
func (s *State) determineFeatureState(name string) bool {
if s == nil || !s.active || s.desktopValues == nil {
return false
}
// TODO(milas): we should add individual environment variable overrides
// per-experiment in a generic way here
return s.desktopValues[name].Enabled
}

View File

@@ -25,7 +25,7 @@ import (
"path/filepath"
"time"
pusherrors "github.com/containerd/containerd/remotes/errors"
pusherrors "github.com/containerd/containerd/v2/core/remotes/errors"
"github.com/distribution/reference"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/compose/v2/pkg/api"
@@ -54,6 +54,8 @@ 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
@@ -81,6 +83,18 @@ 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,
@@ -88,6 +102,10 @@ func PushManifest(
layers []Pushable,
ociVersion api.OCIVersion,
) error {
// Check if we need an extra empty layer for the manifest config
if ociVersion == api.OCIVersion1_1 || ociVersion == "" {
layers = append(layers, Pushable{Descriptor: v1.DescriptorEmptyJSON, Data: []byte("{}")})
}
// prepare to push the manifest by pushing the layers
layerDescriptors := make([]v1.Descriptor, len(layers))
for i := range layers {
@@ -179,7 +197,7 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]Pusha
config = v1.DescriptorEmptyJSON
artifactType = ComposeProjectArtifactType
// N.B. the descriptor has the data embedded in it
toPush = append(toPush, Pushable{Descriptor: config, Data: nil})
toPush = append(toPush, Pushable{Descriptor: config, Data: make([]byte, len(config.Data))})
default:
return nil, fmt.Errorf("unsupported OCI version: %s", ociCompat)
}

View File

@@ -16,8 +16,6 @@ package sync
import (
"context"
"github.com/compose-spec/compose-go/v2/types"
)
// PathMapping contains the Compose service and modified host system path.
@@ -38,5 +36,5 @@ type PathMapping struct {
}
type Syncer interface {
Sync(ctx context.Context, service types.ServiceConfig, paths []PathMapping) error
Sync(ctx context.Context, service string, paths []*PathMapping) error
}

View File

@@ -32,7 +32,6 @@ 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"
)
@@ -65,8 +64,8 @@ func NewTar(projectName string, client LowLevelClient) *Tar {
}
}
func (t *Tar) Sync(ctx context.Context, service types.ServiceConfig, paths []PathMapping) error {
containers, err := t.client.ContainersForService(ctx, t.projectName, service.Name)
func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) error {
containers, err := t.client.ContainersForService(ctx, t.projectName, service)
if err != nil {
return err
}
@@ -77,7 +76,7 @@ func (t *Tar) Sync(ctx context.Context, service types.ServiceConfig, paths []Pat
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)
}
}

View File

@@ -17,10 +17,8 @@
package tracing
import (
"context"
"fmt"
"os"
"time"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context/store"
@@ -63,11 +61,7 @@ func traceClientFromDockerContext(dockerCli command.Cli, otelEnv envMap) (otlptr
}
}
dialCtx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
conn, err := grpc.DialContext(
dialCtx,
cfg.Endpoint,
conn, err := grpc.NewClient(cfg.Endpoint,
grpc.WithContextDialer(memnet.DialEndpoint),
// this dial is restricted to using a local Unix socket / named pipe,
// so there is no need for TLS

View File

@@ -22,19 +22,16 @@ import (
"go.opentelemetry.io/otel/attribute"
)
func KeyboardMetrics(ctx context.Context, enabled, isDockerDesktopActive, isWatchConfigured, isDockerDesktopComposeUI bool) {
func KeyboardMetrics(ctx context.Context, enabled, isDockerDesktopActive, isWatchConfigured bool) {
commandAvailable := []string{}
if isDockerDesktopActive {
commandAvailable = append(commandAvailable, "gui")
commandAvailable = append(commandAvailable, "gui/composeview")
}
if isWatchConfigured {
commandAvailable = append(commandAvailable, "watch")
}
if isDockerDesktopComposeUI {
commandAvailable = append(commandAvailable, "gui/composeview")
}
AddAttributeToSpan(ctx,
attribute.Bool("navmenu.enabled", enabled),
attribute.StringSlice("navmenu.command_available", commandAvailable))

View File

@@ -16,7 +16,5 @@
package internal
var (
// Version is the version of the CLI injected in compilation time
Version = "dev"
)
// Version is the version of the CLI injected in compilation time
var Version = "dev"

View File

@@ -23,6 +23,7 @@ import (
"time"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/opts"
"github.com/docker/compose/v2/pkg/utils"
)
@@ -90,6 +91,12 @@ type Service interface {
Wait(ctx context.Context, projectName string, options WaitOptions) (int64, error)
// Scale manages numbers of container instances running per service
Scale(ctx context.Context, project *types.Project, options ScaleOptions) error
// Export a service container's filesystem as a tar archive
Export(ctx context.Context, projectName string, options ExportOptions) error
// Create a new image from a service container's changes
Commit(ctx context.Context, projectName string, options CommitOptions) error
// Generate generates a Compose Project from existing containers
Generate(ctx context.Context, options GenerateOptions) (*types.Project, error)
}
type ScaleOptions struct {
@@ -200,6 +207,8 @@ 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
@@ -289,6 +298,7 @@ type ConfigOptions struct {
type PushOptions struct {
Quiet bool
IgnoreFailures bool
ImageMandatory bool
}
// PullOptions group options of the Pull API
@@ -410,6 +420,8 @@ const (
// PublishOptions group options of the Publish API
type PublishOptions struct {
ResolveImageDigests bool
WithEnvironment bool
AssumeYes bool
OCIVersion OCIVersion
}
@@ -421,7 +433,6 @@ 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
@@ -553,6 +564,33 @@ type PauseOptions struct {
Project *types.Project
}
// ExportOptions group options of the Export API
type ExportOptions struct {
Service string
Index int
Output string
}
// CommitOptions group options of the Commit API
type CommitOptions struct {
Service string
Reference string
Pause bool
Comment string
Author string
Changes opts.ListOpts
Index int
}
type GenerateOptions struct {
// ProjectName to set in the Compose file
ProjectName string
// Containers passed in the command line to be used as reference for service definition
Containers []string
}
const (
// STARTING indicates that stack is being deployed
STARTING string = "Starting"
@@ -628,6 +666,8 @@ const (
ContainerEventExit
// UserCancel user cancelled compose up, we are stopping containers
UserCancel
// HookEventLog is a ContainerEvent of type log on stdout by service hook
HookEventLog
)
// Separator is used for naming components

View File

@@ -101,7 +101,8 @@ 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},
@@ -229,7 +230,6 @@ 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) {

View File

@@ -21,7 +21,8 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/compose-spec/compose-go/v2/types"
"github.com/containerd/platforms"
@@ -32,13 +33,13 @@ 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"
"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder/remotecontext/urlutil"
bclient "github.com/moby/buildkit/client"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/auth/authprovider"
@@ -64,25 +65,45 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
}, s.stdinfo(), "Building")
}
type serviceToBuild struct {
name string
service types.ServiceConfig
}
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) {
buildkitEnabled, err := s.dockerCli.BuildKitEnabled()
if err != nil {
return nil, err
}
imageIDs := map[string]string{}
serviceToBeBuild := map[string]serviceToBuild{}
serviceToBuild := types.Services{}
var policy types.DependencyOption = types.IgnoreDependencies
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 {
if service.Build == nil {
return nil
@@ -92,20 +113,37 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
if localImagePresent && service.PullPolicy != types.PullPolicyBuild {
return nil
}
serviceToBeBuild[serviceName] = serviceToBuild{name: serviceName, service: *service}
serviceToBuild[serviceName] = *service
return nil
}, policy)
if err != nil || len(serviceToBeBuild) == 0 {
if err != nil || len(serviceToBuild) == 0 {
return imageIDs, err
}
bake, err := buildWithBake(s.dockerCli)
if err != nil {
return nil, err
}
if bake {
return s.doBuildBake(ctx, project, serviceToBuild, options)
}
// Initialize buildkit nodes
buildkitEnabled, err := s.dockerCli.BuildKitEnabled()
if err != nil {
return nil, err
}
var (
b *builder.Builder
nodes []builder.Node
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")
@@ -129,12 +167,14 @@ 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
}
@@ -151,18 +191,22 @@ 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 {
serviceToBuild, ok := serviceToBeBuild[name]
service, ok := serviceToBuild[name]
if !ok {
return nil
}
service := serviceToBuild.service
serviceName := fmt.Sprintf("Service %s", name)
if !buildkitEnabled {
cw.Event(progress.BuildingEvent(serviceName))
id, err := s.doBuildClassic(ctx, project, service, options)
if err != nil {
return err
}
cw.Event(progress.BuiltEvent(serviceName))
builtDigests[getServiceIndex(name)] = id
if options.Push {
@@ -204,8 +248,10 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
for i, imageDigest := range builtDigests {
if imageDigest != "" {
imageRef := api.GetImageNameOrDefault(project.Services[names[i]], project.Name)
service := project.Services[names[i]]
imageRef := api.GetImageNameOrDefault(service, project.Name)
imageIDs[imageRef] = imageDigest
cw.Event(progress.BuiltEvent(names[i]))
}
}
return imageIDs, err
@@ -274,7 +320,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
imageNames = append(imageNames, imgName)
}
}
imgs, err := s.getImages(ctx, imageNames)
imgs, err := s.getImageSummaries(ctx, imageNames)
if err != nil {
return nil, err
}
@@ -327,12 +373,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
//
// Finally, standard proxy variables based on the Docker client configuration are added, but will not overwrite
// any values if already present.
func resolveAndMergeBuildArgs(
dockerCli command.Cli,
project *types.Project,
service types.ServiceConfig,
opts api.BuildOptions,
) types.MappingWithEquals {
func resolveAndMergeBuildArgs(dockerCli command.Cli, project *types.Project, service types.ServiceConfig, opts api.BuildOptions) types.MappingWithEquals {
result := make(types.MappingWithEquals).
OverrideBy(service.Build.Args).
OverrideBy(opts.Args).
@@ -427,8 +468,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),
CacheTo: pb.CreateCaches(cacheTo),
CacheFrom: pb.CreateCaches(cacheFrom.ToPB()),
CacheTo: pb.CreateCaches(cacheTo.ToPB()),
NoCache: service.Build.NoCache,
Pull: service.Build.Pull,
BuildArgs: flatten(resolveAndMergeBuildArgs(s.dockerCli, project, service, options)),
@@ -472,16 +513,6 @@ func flatten(in types.MappingWithEquals) types.Mapping {
return out
}
func dockerFilePath(ctxName string, dockerfile string) string {
if dockerfile == "" {
return ""
}
if urlutil.IsGitURL(ctxName) || filepath.IsAbs(dockerfile) {
return dockerfile
}
return filepath.Join(ctxName, dockerfile)
}
func sshAgentProvider(sshKeys types.SSHConfig) (session.Attachable, error) {
sshConfig := make([]sshprovider.AgentConfig, 0, len(sshKeys))
for _, sshKey := range sshKeys {
@@ -543,6 +574,11 @@ 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

403
pkg/compose/build_bake.go Normal file
View File

@@ -0,0 +1,403 @@
/*
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 (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"slices"
"strconv"
"strings"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/socket"
"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"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
"golang.org/x/sync/errgroup"
)
func buildWithBake(dockerCli command.Cli) (bool, error) {
b, ok := os.LookupEnv("COMPOSE_BAKE")
if !ok {
if dockerCli.ConfigFile().Plugins["compose"]["build"] == "bake" {
b, ok = "true", true
}
}
if !ok {
return false, nil
}
bake, err := strconv.ParseBool(b)
if err != nil {
return false, err
}
if !bake {
return false, nil
}
enabled, err := dockerCli.BuildKitEnabled()
if err != nil {
return false, err
}
if !enabled {
logrus.Warnf("Docker Compose is configured to build using Bake, but buildkit isn't enabled")
}
_, err = manager.GetPlugin("buildx", dockerCli, &cobra.Command{})
if err != nil {
if manager.IsNotFound(err) {
logrus.Warnf("Docker Compose is configured to build using Bake, but buildx isn't installed")
return false, nil
}
return false, err
}
return true, err
}
// We _could_ use bake.* types from github.com/docker/buildx but long term plan is to remove buildx as a dependency
type bakeConfig struct {
Groups map[string]bakeGroup `json:"group"`
Targets map[string]bakeTarget `json:"target"`
}
type bakeGroup struct {
Targets []string `json:"targets"`
}
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"`
}
type bakeMetadata map[string]buildStatus
type buildStatus struct {
Digest string `json:"containerimage.digest"`
}
func (s *composeService) doBuildBake(ctx context.Context, project *types.Project, serviceToBeBuild types.Services, options api.BuildOptions) (map[string]string, error) { //nolint:gocyclo
eg := errgroup.Group{}
ch := make(chan *client.SolveStatus)
display, err := progressui.NewDisplay(os.Stdout, progressui.DisplayMode(options.Progress))
if err != nil {
return nil, err
}
eg.Go(func() error {
_, err := display.UpdateFrom(ctx, ch)
return err
})
cfg := bakeConfig{
Groups: map[string]bakeGroup{},
Targets: map[string]bakeTarget{},
}
var group bakeGroup
var privileged bool
var read []string
for serviceName, service := range serviceToBeBuild {
if service.Build == nil {
continue
}
build := *service.Build
args := types.Mapping{}
for k, v := range resolveAndMergeBuildArgs(s.dockerCli, project, service, options) {
if v == nil {
continue
}
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),
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},
}
group.Targets = append(group.Targets, serviceName)
}
cfg.Groups["default"] = group
b, err := json.MarshalIndent(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
}
buildx, err := manager.GetPlugin("buildx", s.dockerCli, &cobra.Command{})
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...)
// Remove DOCKER_CLI_PLUGIN... variable so buildx can detect it run standalone
cmd.Env = filter(os.Environ(), manager.ReexecEnvvar)
// Use docker/cli mechanism to propagate termination signal to child process
server, err := socket.NewPluginServer(nil)
if err != nil {
defer server.Close() //nolint:errcheck
cmd.Cancel = server.Close
cmd.Env = replace(cmd.Env, socket.EnvKey, server.Addr().String())
}
cmd.Env = append(cmd.Env, fmt.Sprintf("DOCKER_CONTEXT=%s", s.dockerCli.CurrentContext()))
// propagate opentelemetry context to child process, see https://github.com/open-telemetry/oteps/blob/main/text/0258-env-context-baggage-carriers.md
carrier := propagation.MapCarrier{}
otel.GetTextMapPropagator().Inject(ctx, &carrier)
cmd.Env = append(cmd.Env, types.Mapping(carrier).Values()...)
cmd.Stdout = s.stdout()
cmd.Stdin = bytes.NewBuffer(b)
pipe, err := cmd.StderrPipe()
if err != nil {
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)
if err != nil {
if strings.HasPrefix(line, "ERROR: ") {
errMessage = line[7:]
}
continue
}
ch <- &status
}
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)
}
b, err = os.ReadFile(metadata.Name())
if err != nil {
return nil, err
}
var md bakeMetadata
err = json.Unmarshal(b, &md)
if err != nil {
return nil, err
}
cw := progress.ContextWriter(ctx)
results := map[string]string{}
for name, m := range md {
results[name] = m.Digest
cw.Event(progress.BuiltEvent(name))
}
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 {
s = append(s, fmt.Sprintf("%s=%s", key.ID, key.Path))
}
return s
}
func toBakeSecrets(project *types.Project, secrets []types.ServiceSecretConfig) []string {
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))
case def.File != "":
s = append(s, fmt.Sprintf("id=%s,type=file,src=%s", target, def.File))
}
}
return s
}
func filter(environ []string, variable string) []string {
prefix := variable + "="
filtered := make([]string, 0, len(environ))
for _, val := range environ {
if !strings.HasPrefix(val, prefix) {
filtered = append(filtered, val)
}
}
return filtered
}
func replace(environ []string, variable, value string) []string {
filtered := filter(environ, variable)
return append(filtered, fmt.Sprintf("%s=%s", variable, value))
}
func dockerFilePath(ctxName string, dockerfile string) string {
if dockerfile == "" {
return ""
}
if urlutil.IsGitURL(ctxName) || filepath.IsAbs(dockerfile) {
return dockerfile
}
return filepath.Join(ctxName, dockerfile)
}

View File

@@ -45,10 +45,10 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, service string, op
response, err = build.Build(ctx, nodes,
map[string]build.Options{service: opts},
dockerutil.NewClient(s.dockerCli),
confutil.ConfigDir(s.dockerCli),
confutil.NewConfig(s.dockerCli),
buildx.WithPrefix(p, service, true))
if err != nil {
return "", WrapCategorisedComposeError(err, BuildFailure)
return "", err
}
}
@@ -70,11 +70,6 @@ func (s composeService) dryRunBuildResponse(ctx context.Context, name string, op
w := progress.ContextWriter(ctx)
buildResponse := map[string]*client.SolveResponse{}
dryRunUUID := fmt.Sprintf("dryRun-%x", sha1.Sum([]byte(name)))
w.Event(progress.Event{
ID: " ",
Status: progress.Done,
Text: fmt.Sprintf("build service %s", name),
})
w.Event(progress.Event{
ID: "==>",
Status: progress.Done,

87
pkg/compose/commit.go Normal file
View File

@@ -0,0 +1,87 @@
/*
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 (
"context"
"fmt"
"strings"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
containerType "github.com/docker/docker/api/types/container"
)
func (s *composeService) Commit(ctx context.Context, projectName string, options api.CommitOptions) error {
return progress.RunWithTitle(ctx, func(ctx context.Context) error {
return s.commit(ctx, projectName, options)
}, s.stdinfo(), "Committing")
}
func (s *composeService) commit(ctx context.Context, projectName string, options api.CommitOptions) error {
projectName = strings.ToLower(projectName)
container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index)
if err != nil {
return err
}
clnt := s.dockerCli.Client()
w := progress.ContextWriter(ctx)
name := getCanonicalContainerName(container)
msg := fmt.Sprintf("Commit %s", name)
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Working,
StatusText: "Committing",
})
if s.dryRun {
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Done,
StatusText: "Committed",
})
return nil
}
response, err := clnt.ContainerCommit(ctx, container.ID, containerType.CommitOptions{
Reference: options.Reference,
Comment: options.Comment,
Author: options.Author,
Changes: options.Changes.GetAll(),
Pause: options.Pause,
})
if err != nil {
return err
}
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Done,
StatusText: fmt.Sprintf("Committed as %s", response.ID),
})
return nil
}

View File

@@ -176,7 +176,10 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
}
set := types.Services{}
for _, c := range containers {
serviceLabel := c.Labels[api.ServiceLabel]
serviceLabel, ok := c.Labels[api.ServiceLabel]
if !ok {
serviceLabel = getCanonicalContainerName(c)
}
service, ok := set[serviceLabel]
if !ok {
service = types.ServiceConfig{
@@ -184,7 +187,6 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
Image: c.Image,
Labels: c.Labels,
}
}
service.Scale = increment(service.Scale)
set[serviceLabel] = service
@@ -318,16 +320,8 @@ func (s *composeService) RuntimeVersion(ctx context.Context) (string, error) {
runtimeVersion.val = version.APIVersion
})
return runtimeVersion.val, runtimeVersion.err
}
func (s *composeService) isDesktopIntegrationActive() bool {
return s.desktopCli != nil
}
func (s *composeService) isDesktopUIEnabled() bool {
if !s.isDesktopIntegrationActive() {
return false
}
return s.experiments.ComposeUI()
}

View File

@@ -114,6 +114,15 @@ 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]
@@ -148,10 +157,10 @@ func isNotOneOff(c moby.Container) bool {
}
// filter return Containers with elements to match predicate
func (containers Containers) filter(predicate containerPredicate) Containers {
func (containers Containers) filter(predicates ...containerPredicate) Containers {
var filtered Containers
for _, c := range containers {
if predicate(c) {
if matches(c, predicates...) {
filtered = append(filtered, c)
}
}

View File

@@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"sort"
"strconv"
"strings"
@@ -34,6 +35,7 @@ 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"
@@ -56,24 +58,26 @@ const (
// Cross services dependencies are managed by creating services in expected order and updating `service:xx` reference
// when a service has converged, so dependent ones can be managed with resolved containers references.
type convergence struct {
service *composeService
observedState map[string]Containers
stateMutex sync.Mutex
service *composeService
services map[string]Containers
networks map[string]string
volumes map[string]string
stateMutex sync.Mutex
}
func (c *convergence) getObservedState(serviceName string) Containers {
c.stateMutex.Lock()
defer c.stateMutex.Unlock()
return c.observedState[serviceName]
return c.services[serviceName]
}
func (c *convergence) setObservedState(serviceName string, containers Containers) {
c.stateMutex.Lock()
defer c.stateMutex.Unlock()
c.observedState[serviceName] = containers
c.services[serviceName] = containers
}
func newConvergence(services []string, state Containers, s *composeService) *convergence {
func newConvergence(services []string, state Containers, networks map[string]string, volumes map[string]string, s *composeService) *convergence {
observedState := map[string]Containers{}
for _, s := range services {
observedState[s] = Containers{}
@@ -83,8 +87,10 @@ func newConvergence(services []string, state Containers, s *composeService) *con
observedState[service] = append(observedState[service], c)
}
return &convergence{
service: s,
observedState: observedState,
service: s,
services: observedState,
networks: networks,
volumes: volumes,
}
}
@@ -123,11 +129,11 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
sort.Slice(containers, func(i, j int) bool {
// select obsolete containers first, so they get removed as we scale down
if obsolete, _ := mustRecreate(service, containers[i], recreate); obsolete {
if obsolete, _ := c.mustRecreate(service, containers[i], recreate); obsolete {
// i is obsolete, so must be first in the list
return true
}
if obsolete, _ := mustRecreate(service, containers[j], recreate); obsolete {
if obsolete, _ := c.mustRecreate(service, containers[j], recreate); obsolete {
// j is obsolete, so must be first in the list
return false
}
@@ -136,25 +142,27 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
ni, erri := strconv.Atoi(containers[i].Labels[api.ContainerNumberLabel])
nj, errj := strconv.Atoi(containers[j].Labels[api.ContainerNumberLabel])
if erri == nil && errj == nil {
return ni < nj
return ni > nj
}
// If we don't get a container number (?) just sort by creation date
return containers[i].Created < containers[j].Created
})
slices.Reverse(containers)
for i, container := range containers {
if i >= expected {
// Scale Down
// As we sorted containers, obsolete ones and/or highest number will be removed
container := container
traceOpts := append(tracing.ServiceOptions(service), tracing.ContainerOptions(container)...)
eg.Go(tracing.SpanWrapFuncForErrGroup(ctx, "service/scale/down", traceOpts, func(ctx context.Context) error {
return c.service.stopAndRemoveContainer(ctx, container, timeout, false)
return c.service.stopAndRemoveContainer(ctx, container, &service, timeout, false)
}))
continue
}
mustRecreate, err := mustRecreate(service, container, recreate)
mustRecreate, err := c.mustRecreate(service, container, recreate)
if err != nil {
return err
}
@@ -197,7 +205,6 @@ 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{
@@ -219,20 +226,26 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
}
func (c *convergence) stopDependentContainers(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
w := progress.ContextWriter(ctx)
// 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,
})
if err != nil {
return err
}
for _, name := range dependents {
dependents := c.observedState[name]
err := c.service.stopContainers(ctx, w, dependents, nil)
if err != nil {
return err
}
dependents := c.getObservedState(name)
for i, dependent := range dependents {
dependent.State = ContainerExited
dependents[i] = dependent
}
c.observedState[name] = dependents
c.setObservedState(name, dependents)
}
return nil
}
@@ -312,7 +325,7 @@ func (c *convergence) resolveSharedNamespaces(service *types.ServiceConfig) erro
return nil
}
func mustRecreate(expected types.ServiceConfig, actual moby.Container, policy string) (bool, error) {
func (c *convergence) mustRecreate(expected types.ServiceConfig, actual moby.Container, policy string) (bool, error) {
if policy == api.RecreateNever {
return false, nil
}
@@ -325,7 +338,74 @@ func mustRecreate(expected types.ServiceConfig, actual moby.Container, policy st
}
configChanged := actual.Labels[api.ConfigHashLabel] != configHash
imageUpdated := actual.Labels[api.ImageDigestLabel] != expected.CustomLabels[api.ImageDigestLabel]
return configChanged || imageUpdated, nil
if configChanged || imageUpdated {
return true, nil
}
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
}
}
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 {
@@ -364,7 +444,12 @@ func containerReasonEvents(containers Containers, eventFunc func(string, string)
const ServiceConditionRunningOrHealthy = "running_or_healthy"
//nolint:gocyclo
func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependant string, dependencies types.DependsOnConfig, containers Containers) error {
func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependant string, dependencies types.DependsOnConfig, containers Containers, timeout time.Duration) error {
if timeout > 0 {
withTimeout, cancelFunc := context.WithTimeout(ctx, timeout)
defer cancelFunc()
ctx = withTimeout
}
eg, _ := errgroup.WithContext(ctx)
w := progress.ContextWriter(ctx)
for dep, config := range dependencies {
@@ -374,7 +459,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
continue
}
waitingFor := containers.filter(isService(dep))
waitingFor := containers.filter(isService(dep), isNotOneOff)
w.Events(containerEvents(waitingFor, progress.Waiting))
if len(waitingFor) == 0 {
if config.Required {
@@ -384,7 +469,6 @@ 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()
@@ -454,7 +538,11 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
}
})
}
return eg.Wait()
err := eg.Wait()
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("timeout waiting for dependencies")
}
return err
}
func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceDependency, project *types.Project) (bool, error) {
@@ -494,11 +582,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))
@@ -511,7 +599,8 @@ 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"))
@@ -580,7 +669,6 @@ 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
}
@@ -760,12 +848,16 @@ func (s *composeService) isServiceCompleted(ctx context.Context, containers Cont
return false, 0, nil
}
func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig, containers Containers) error {
func (s *composeService) startService(ctx context.Context,
project *types.Project, service types.ServiceConfig,
containers Containers, listener api.ContainerEventListener,
timeout time.Duration,
) error {
if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 {
return nil
}
err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, containers)
err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, containers, timeout)
if err != nil {
return err
}
@@ -784,10 +876,18 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
}
eventName := getContainerProgressName(container)
w.Event(progress.StartingEvent(eventName))
err := s.apiClient().ContainerStart(ctx, container.ID, containerType.StartOptions{})
err = s.apiClient().ContainerStart(ctx, container.ID, containerType.StartOptions{})
if err != nil {
return err
}
for _, hook := range service.PostStart {
err = s.runHook(ctx, container, service, hook, listener)
if err != nil {
return err
}
}
w.Event(progress.StartedEvent(eventName))
}
return nil

View File

@@ -28,6 +28,7 @@ import (
containerType "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"go.uber.org/mock/gomock"
"gotest.tools/v3/assert"
@@ -238,7 +239,7 @@ func TestWaitDependencies(t *testing.T) {
"db": {Condition: ServiceConditionRunningOrHealthy},
"redis": {Condition: ServiceConditionRunningOrHealthy},
}
assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil))
assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil, 0))
})
t.Run("should skip dependencies with condition service_started", func(t *testing.T) {
dbService := types.ServiceConfig{Name: "db", Scale: intPtr(1)}
@@ -251,7 +252,7 @@ func TestWaitDependencies(t *testing.T) {
"db": {Condition: types.ServiceConditionStarted, Required: true},
"redis": {Condition: types.ServiceConditionStarted, Required: true},
}
assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil))
assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil, 0))
})
}
@@ -300,10 +301,17 @@ func TestCreateMobyContainer(t *testing.T) {
},
}
apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Cond(func(x any) bool {
v := x.(*containerType.HostConfig)
return v.NetworkMode == "b-moby-name"
}), gomock.Eq(
var falseBool bool
apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
&containerType.HostConfig{
PortBindings: nat.PortMap{},
ExtraHosts: []string{},
Tmpfs: map[string]string{},
Resources: containerType.Resources{
OomKillDisable: &falseBool,
},
NetworkMode: "b-moby-name",
}), gomock.Eq(
&network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
"b-moby-name": {
@@ -382,10 +390,17 @@ func TestCreateMobyContainer(t *testing.T) {
},
}
apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Cond(func(x any) bool {
v := x.(*containerType.HostConfig)
return v.NetworkMode == "b-moby-name"
}), gomock.Eq(
var falseBool bool
apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
&containerType.HostConfig{
PortBindings: nat.PortMap{},
ExtraHosts: []string{},
Tmpfs: map[string]string{},
Resources: containerType.Resources{
OomKillDisable: &falseBool,
},
NetworkMode: "b-moby-name",
}), gomock.Eq(
&network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
"a-moby-name": {
@@ -417,5 +432,4 @@ func TestCreateMobyContainer(t *testing.T) {
}, progress.ContextWriter(context.TODO()))
assert.NilError(t, err)
})
}

View File

@@ -61,11 +61,6 @@ func (s *composeService) copy(ctx context.Context, projectName string, options a
direction |= fromService
serviceName = srcService
copyFunc = s.copyFromContainer
// copying from multiple containers of a services doesn't make sense.
if options.All {
return errors.New("cannot use the --all flag when copying from a service")
}
}
if destService != "" {
direction |= toService
@@ -80,7 +75,7 @@ func (s *composeService) copy(ctx context.Context, projectName string, options a
return errors.New("unknown copy direction")
}
containers, err := s.listContainersTargetedForCopy(ctx, projectName, options.Index, direction, serviceName)
containers, err := s.listContainersTargetedForCopy(ctx, projectName, options, direction, serviceName)
if err != nil {
return err
}
@@ -119,18 +114,22 @@ func (s *composeService) copy(ctx context.Context, projectName string, options a
return g.Wait()
}
func (s *composeService) listContainersTargetedForCopy(ctx context.Context, projectName string, index int, direction copyDirection, serviceName string) (Containers, error) {
func (s *composeService) listContainersTargetedForCopy(ctx context.Context, projectName string, options api.CopyOptions, direction copyDirection, serviceName string) (Containers, error) {
var containers Containers
var err error
switch {
case index > 0:
ctr, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, serviceName, index)
case options.Index > 0:
ctr, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, serviceName, options.Index)
if err != nil {
return nil, err
}
return append(containers, ctr), nil
default:
containers, err = s.getContainers(ctx, projectName, oneOffExclude, true, serviceName)
withOneOff := oneOffExclude
if options.All {
withOneOff = oneOffInclude
}
containers, err = s.getContainers(ctx, projectName, withOneOff, true, serviceName)
if err != nil {
return nil, err
}
@@ -140,7 +139,6 @@ func (s *composeService) listContainersTargetedForCopy(ctx context.Context, proj
}
if direction == fromService {
return containers[:1], err
}
return containers, err
}

View File

@@ -24,7 +24,6 @@ import (
"fmt"
"io/fs"
"os"
"path"
"path/filepath"
"sort"
"strconv"
@@ -35,6 +34,7 @@ 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"
@@ -48,6 +48,7 @@ import (
"github.com/docker/docker/errdefs"
"github.com/docker/go-connections/nat"
"github.com/sirupsen/logrus"
cdi "tags.cncf.io/container-device-interface/pkg/parser"
)
type createOptions struct {
@@ -80,12 +81,6 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
return err
}
var observedState Containers
observedState, err = s.getContainers(ctx, project.Name, oneOffInclude, true)
if err != nil {
return err
}
err = s.ensureImagesExists(ctx, project, options.Build, options.QuietPull)
if err != nil {
return err
@@ -93,18 +88,25 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
prepareNetworks(project)
if err := s.ensureNetworks(ctx, project.Networks); err != nil {
networks, err := s.ensureNetworks(ctx, project)
if err != nil {
return err
}
if err := s.ensureProjectVolumes(ctx, project); err != nil {
volumes, err := s.ensureProjectVolumes(ctx, project, options.AssumeYes)
if err != nil {
return err
}
var observedState Containers
observedState, err = s.getContainers(ctx, project.Name, oneOffInclude, true)
if err != nil {
return err
}
orphans := observedState.filter(isOrphaned(project))
if len(orphans) > 0 && !options.IgnoreOrphans {
if options.RemoveOrphans {
err := s.removeContainers(ctx, orphans, nil, false)
err := s.removeContainers(ctx, orphans, nil, nil, false)
if err != nil {
return err
}
@@ -115,38 +117,43 @@ 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, s).apply(ctx, project, options)
return newConvergence(options.Services, observedState, networks, volumes, s).apply(ctx, project, options)
}
func prepareNetworks(project *types.Project) {
for k, nw := range project.Networks {
nw.Labels = nw.Labels.Add(api.NetworkLabel, k)
nw.Labels = nw.Labels.Add(api.ProjectLabel, project.Name)
nw.Labels = nw.Labels.Add(api.VersionLabel, api.ComposeVersion)
nw.CustomLabels = nw.CustomLabels.
Add(api.NetworkLabel, k).
Add(api.ProjectLabel, project.Name).
Add(api.VersionLabel, api.ComposeVersion)
project.Networks[k] = nw
}
}
func (s *composeService) ensureNetworks(ctx context.Context, networks types.Networks) error {
for i, nw := range networks {
err := s.ensureNetwork(ctx, &nw)
func (s *composeService) ensureNetworks(ctx context.Context, project *types.Project) (map[string]string, error) {
networks := map[string]string{}
for name, nw := range project.Networks {
id, err := s.ensureNetwork(ctx, project, name, &nw)
if err != nil {
return err
return nil, err
}
networks[i] = nw
networks[name] = id
project.Networks[name] = nw
}
return nil
return networks, nil
}
func (s *composeService) ensureProjectVolumes(ctx context.Context, project *types.Project) error {
func (s *composeService) ensureProjectVolumes(ctx context.Context, project *types.Project, assumeYes bool) (map[string]string, error) {
ids := map[string]string{}
for k, volume := range project.Volumes {
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)
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)
if err != nil {
return err
return nil, err
}
ids[k] = id
}
err := func() error {
@@ -198,11 +205,10 @@ 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 nil
return ids, nil
}
func (s *composeService) getCreateConfigs(ctx context.Context,
@@ -252,7 +258,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
if err != nil {
return createConfigs{}, err
}
var containerConfig = container.Config{
containerConfig := container.Config{
Hostname: service.Hostname,
Domainname: service.DomainName,
User: service.User,
@@ -410,7 +416,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 {
if mainNw != nil && mainNw.MacAddress != "" {
macAddress = mainNw.MacAddress
}
}
@@ -418,11 +424,11 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
return macAddress, nil
}
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, networkKey string, useNetworkAliases bool) []string {
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, cfg *types.ServiceNetworkConfig, useNetworkAliases bool) []string {
aliases := []string{getContainerName(project.Name, service, serviceIndex)}
if useNetworkAliases {
aliases = append(aliases, service.Name)
if cfg := service.Networks[networkKey]; cfg != nil {
if cfg != nil {
aliases = append(aliases, cfg.Aliases...)
}
}
@@ -450,7 +456,7 @@ func createEndpointSettings(p *types.Project, service types.ServiceConfig, servi
driverOpts = config.DriverOpts
}
return &network.EndpointSettings{
Aliases: getAliases(p, service, serviceIndex, networkKey, useNetworkAliases),
Aliases: getAliases(p, service, serviceIndex, config, useNetworkAliases),
Links: links,
IPAddress: ipv4Address,
IPv6Gateway: ipv6Address,
@@ -480,7 +486,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" {
if con[0] == "seccomp" && con[1] != "unconfined" && con[1] != "builtin" {
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)
@@ -505,7 +511,10 @@ func (s *composeService) prepareLabels(labels types.Labels, service types.Servic
}
labels[api.ConfigHashLabel] = hash
labels[api.ContainerNumberLabel] = strconv.Itoa(number)
if number > 0 {
// One-off containers are not indexed
labels[api.ContainerNumberLabel] = strconv.Itoa(number)
}
var dependencies []string
for s, d := range service.DependsOn {
@@ -539,23 +548,28 @@ func defaultNetworkSettings(
primaryNetworkKey = "default"
}
primaryNetworkMobyNetworkName := project.Networks[primaryNetworkKey].Name
endpointsConfig := map[string]*network.EndpointSettings{
primaryNetworkMobyNetworkName: createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases),
}
primaryNetworkEndpoint := createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases)
endpointsConfig := map[string]*network.EndpointSettings{}
// 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") && 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 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
}
}
endpointsConfig[primaryNetworkMobyNetworkName] = primaryNetworkEndpoint
networkConfig := &network.NetworkingConfig{
EndpointsConfig: endpointsConfig,
}
@@ -645,7 +659,14 @@ func getDeployResources(s types.ServiceConfig) container.Resources {
setReservations(s.Deploy.Resources.Reservations, &resources)
}
var cdiDeviceNames []string
for _, device := range s.Devices {
if device.Source == device.Target && cdi.IsQualifiedName(device.Source) {
cdiDeviceNames = append(cdiDeviceNames, device.Source)
continue
}
resources.Devices = append(resources.Devices, container.DeviceMapping{
PathOnHost: device.Source,
PathInContainer: device.Target,
@@ -653,6 +674,23 @@ func getDeployResources(s types.ServiceConfig) container.Resources {
})
}
if len(cdiDeviceNames) > 0 {
resources.DeviceRequests = append(resources.DeviceRequests, container.DeviceRequest{
Driver: "cdi",
DeviceIDs: cdiDeviceNames,
})
}
for _, gpus := range s.Gpus {
resources.DeviceRequests = append(resources.DeviceRequests, container.DeviceRequest{
Driver: gpus.Driver,
Count: int(gpus.Count),
DeviceIDs: gpus.IDs,
Capabilities: [][]string{append(gpus.Capabilities, "gpu")},
Options: gpus.Options,
})
}
ulimits := toUlimits(s.Ulimits)
resources.Ulimits = ulimits
return resources
@@ -694,6 +732,7 @@ func setReservations(reservations *types.Resource, resources *container.Resource
Count: int(device.Count),
DeviceIDs: device.IDs,
Driver: device.Driver,
Options: device.Options,
})
}
}
@@ -806,23 +845,23 @@ func (s *composeService) buildContainerVolumes(
return nil, nil, err
}
version, err := s.RuntimeVersion(ctx)
if err != nil {
return nil, nil, err
}
if versions.GreaterThan(version, "1.42") {
// We can fully leverage `Mount` API as a replacement for legacy `Bind`
return nil, mountOptions, nil
}
MOUNTS:
for _, m := range mountOptions {
if m.Type == mount.TypeNamedPipe {
mounts = append(mounts, m)
continue
}
if m.Type == mount.TypeBind {
// `Mount` does not offer option to created host path if missing
// `Mount` is preferred but does not offer option to created host path if missing
// so `Bind` API is used here with raw volume string
// see https://github.com/moby/moby/issues/43483
for _, v := range service.Volumes {
if v.Target == m.Target {
if v.Bind != nil && v.Bind.CreateHostPath {
switch {
case string(m.Type) != v.Type:
v.Source = m.Source
fallthrough
case !requireMountAPI(v.Bind):
binds = append(binds, v.String())
continue MOUNTS
}
@@ -834,8 +873,25 @@ MOUNTS:
return binds, mounts, nil
}
// requireMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
// options which require use of Mount API
func requireMountAPI(bind *types.ServiceVolumeBind) bool {
switch {
case bind == nil:
return false
case !bind.CreateHostPath:
return true
case bind.Propagation != "":
return true
case bind.Recursive != "":
return true
default:
return false
}
}
func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) {
var mounts = map[string]mount.Mount{}
mounts := map[string]mount.Mount{}
if inherit != nil {
for _, m := range inherit.Mounts {
if m.Type == "tmpfs" {
@@ -845,7 +901,6 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby
if m.Type == "volume" {
src = m.Name
}
m.Destination = path.Clean(m.Destination)
if img.Config != nil {
if _, ok := img.Config.Volumes[m.Destination]; ok {
@@ -922,7 +977,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) {
var mounts = map[string]mount.Mount{}
mounts := map[string]mount.Mount{}
configsBaseDir := "/"
for _, config := range s.Configs {
@@ -933,10 +988,6 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount
target = configsBaseDir + config.Target
}
if config.UID != "" || config.GID != "" || config.Mode != nil {
logrus.Warn("config `uid`, `gid` and `mode` are not supported, they will be ignored")
}
definedConfig := p.Configs[config.Source]
if definedConfig.External {
return nil, fmt.Errorf("unsupported external config %s", definedConfig.Name)
@@ -953,6 +1004,10 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount
continue
}
if config.UID != "" || config.GID != "" || config.Mode != nil {
logrus.Warn("config `uid`, `gid` and `mode` are not supported, they will be ignored")
}
bindMount, err := buildMount(p, types.ServiceVolumeConfig{
Type: types.VolumeTypeBind,
Source: definedConfig.File,
@@ -972,7 +1027,7 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount
}
func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) {
var mounts = map[string]mount.Mount{}
mounts := map[string]mount.Mount{}
secretsDir := "/run/secrets/"
for _, secret := range s.Secrets {
@@ -983,10 +1038,6 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount
target = secretsDir + secret.Target
}
if secret.UID != "" || secret.GID != "" || secret.Mode != nil {
logrus.Warn("secrets `uid`, `gid` and `mode` are not supported, they will be ignored")
}
definedSecret := p.Secrets[secret.Source]
if definedSecret.External {
return nil, fmt.Errorf("unsupported external secret %s", definedSecret.Name)
@@ -1003,11 +1054,22 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount
continue
}
if secret.UID != "" || secret.GID != "" || secret.Mode != nil {
logrus.Warn("secrets `uid`, `gid` and `mode` are not supported, they will be ignored")
}
if _, err := os.Stat(definedSecret.File); os.IsNotExist(err) {
logrus.Warnf("secret file %s does not exist", definedSecret.Name)
}
mnt, err := buildMount(p, types.ServiceVolumeConfig{
Type: types.VolumeTypeBind,
Source: definedSecret.File,
Target: target,
ReadOnly: true,
Bind: &types.ServiceVolumeBind{
CreateHostPath: false,
},
})
if err != nil {
return nil, err
@@ -1062,8 +1124,6 @@ func buildMount(project types.Project, volume types.ServiceVolumeConfig) (mount.
bind, vol, tmpfs := buildMountOptions(volume)
volume.Target = path.Clean(volume.Target)
if bind != nil {
volume.Type = types.VolumeTypeBind
}
@@ -1114,11 +1174,19 @@ func buildBindOption(bind *types.ServiceVolumeBind) *mount.BindOptions {
if bind == nil {
return nil
}
return &mount.BindOptions{
opts := &mount.BindOptions{
Propagation: mount.Propagation(bind.Propagation),
CreateMountpoint: bind.CreateHostPath,
// NonRecursive: false, FIXME missing from model ?
}
switch bind.Recursive {
case "disabled":
opts.NonRecursive = true
case "writable":
opts.ReadOnlyNonRecursive = true
case "readonly":
opts.ReadOnlyForceRecursive = true
}
return opts
}
func buildVolumeOptions(vol *types.ServiceVolumeVolume) *mount.VolumeOptions {
@@ -1143,24 +1211,21 @@ func buildTmpfsOptions(tmpfs *types.ServiceVolumeTmpfs) *mount.TmpfsOptions {
}
}
func (s *composeService) ensureNetwork(ctx context.Context, n *types.NetworkConfig) error {
func (s *composeService) ensureNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) (string, error) {
if n.External {
return s.resolveExternalNetwork(ctx, n)
}
err := s.resolveOrCreateNetwork(ctx, n)
id, err := s.resolveOrCreateNetwork(ctx, project, name, n)
if errdefs.IsConflict(err) {
// Maybe another execution of `docker compose up|run` created same network
// let's retry once
return s.resolveOrCreateNetwork(ctx, n)
return s.resolveOrCreateNetwork(ctx, project, name, n)
}
return err
return id, err
}
func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.NetworkConfig) error { //nolint:gocyclo
expectedNetworkLabel := n.Labels[api.NetworkLabel]
expectedProjectLabel := n.Labels[api.ProjectLabel]
func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) (string, error) { //nolint:gocyclo
// First, try to find a unique network matching by name or ID
inspect, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
if err == nil {
@@ -1171,14 +1236,33 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
if !ok {
logrus.Warnf("a network with name %s exists but was not created by compose.\n"+
"Set `external: true` to use an existing network", n.Name)
} else if p != expectedProjectLabel {
} else if p != project.Name {
logrus.Warnf("a network with name %s exists but was not created for project %q.\n"+
"Set `external: true` to use an existing network", n.Name, expectedProjectLabel)
"Set `external: true` to use an existing network", n.Name, project.Name)
}
if inspect.Labels[api.NetworkLabel] != expectedNetworkLabel {
return fmt.Errorf("network %s was found but has incorrect label %s set to %q", n.Name, api.NetworkLabel, inspect.Labels[api.NetworkLabel])
if inspect.Labels[api.NetworkLabel] != name {
return "", fmt.Errorf(
"network %s was found but has incorrect label %s set to %q (expected: %q)",
n.Name,
api.NetworkLabel,
inspect.Labels[api.NetworkLabel],
name,
)
}
hash := inspect.Labels[api.ConfigHashLabel]
expected, err := NetworkHash(n)
if err != nil {
return "", err
}
if hash == "" || hash == expected {
return inspect.ID, nil
}
err = s.removeDivergedNetwork(ctx, project, name, n)
if err != nil {
return "", err
}
return nil
}
}
// ignore other errors. Typically, an ambiguous request by name results in some generic `invalidParameter` error
@@ -1188,7 +1272,7 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
Filters: filters.NewArgs(filters.Arg("name", n.Name)),
})
if err != nil {
return err
return "", err
}
// NetworkList Matches all or part of a network name, so we have to filter for a strict match
@@ -1197,9 +1281,9 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
})
for _, net := range networks {
if net.Labels[api.ProjectLabel] == expectedProjectLabel &&
net.Labels[api.NetworkLabel] == expectedNetworkLabel {
return nil
if net.Labels[api.ProjectLabel] == project.Name &&
net.Labels[api.NetworkLabel] == name {
return net.ID, nil
}
}
@@ -1209,7 +1293,7 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
if len(networks) > 0 {
logrus.Warnf("a network with name %s exists but was not created by compose.\n"+
"Set `external: true` to use an existing network", n.Name)
return nil
return networks[0].ID, nil
}
var ipam *network.IPAM
@@ -1228,8 +1312,13 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
Config: config,
}
}
hash, err := NetworkHash(n)
if err != nil {
return "", err
}
n.CustomLabels = n.CustomLabels.Add(api.ConfigHashLabel, hash)
createOpts := network.CreateOptions{
Labels: n.Labels,
Labels: mergeLabels(n.Labels, n.CustomLabels),
Driver: n.Driver,
Options: n.DriverOpts,
Internal: n.Internal,
@@ -1259,16 +1348,42 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, n *types.Ne
w := progress.ContextWriter(ctx)
w.Event(progress.CreatingEvent(networkEventName))
_, err = s.apiClient().NetworkCreate(ctx, n.Name, createOpts)
resp, err := s.apiClient().NetworkCreate(ctx, n.Name, createOpts)
if err != nil {
w.Event(progress.ErrorEvent(networkEventName))
return fmt.Errorf("failed to create network %s: %w", n.Name, err)
return "", fmt.Errorf("failed to create network %s: %w", n.Name, err)
}
w.Event(progress.CreatedEvent(networkEventName))
return nil
return resp.ID, nil
}
func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.NetworkConfig) error {
func (s *composeService) removeDivergedNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) error {
// Remove services attached to this network to force recreation
var services []string
for _, service := range project.Services.Filter(func(config types.ServiceConfig) bool {
_, ok := config.Networks[name]
return ok
}) {
services = append(services, service.Name)
}
// Stop containers so we can remove network
// They will be restarted (actually: recreated) with the updated network
err := s.stop(ctx, project.Name, api.StopOptions{
Services: services,
Project: project,
})
if err != nil {
return err
}
err = s.apiClient().NetworkRemove(ctx, n.Name)
eventName := fmt.Sprintf("Network %s", n.Name)
progress.ContextWriter(ctx).Event(progress.RemovedEvent(eventName))
return err
}
func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.NetworkConfig) (string, error) {
// NetworkInspect will match on ID prefix, so NetworkList with a name
// filter is used to look for an exact match to prevent e.g. a network
// named `db` from getting erroneously matched to a network with an ID
@@ -1276,16 +1391,15 @@ 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
return "", err
}
if len(networks) == 0 {
// in this instance, n.Name is really an ID
sn, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
if err != nil && !errdefs.IsNotFound(err) {
return err
return "", err
}
networks = append(networks, sn)
}
@@ -1300,41 +1414,40 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
switch len(networks) {
case 1:
n.Name = networks[0].ID
return nil
return networks[0].ID, nil
case 0:
enabled, err := s.isSWarmEnabled(ctx)
if err != nil {
return err
return "", err
}
if enabled {
// Swarm nodes do not register overlay networks that were
// created on a different node unless they're in use.
// So we can't preemptively check network exists, but
// networkAttach will later fail anyway if network actually doesn't exist
return nil
return "swarm", nil
}
return fmt.Errorf("network %s declared as external, but could not be found", n.Name)
return "", fmt.Errorf("network %s declared as external, but could not be found", n.Name)
default:
return fmt.Errorf("multiple networks with name %q were found. Use network ID as `name` to avoid ambiguity", n.Name)
return "", fmt.Errorf("multiple networks with name %q were found. Use network ID as `name` to avoid ambiguity", n.Name)
}
}
func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeConfig, project string) error {
func (s *composeService) ensureVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project, assumeYes bool) (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 err
err = s.createVolume(ctx, volume)
return volume.Name, err
}
if volume.External {
return nil
return volume.Name, nil
}
// Volume exists with name, but let's double-check this is the expected one
@@ -1342,18 +1455,86 @@ func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeCo
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 {
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)
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)
}
return nil
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)
}
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))
_, err := s.apiClient().VolumeCreate(ctx, volumetypes.CreateOptions{
Labels: volume.Labels,
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),
Name: volume.Name,
Driver: volume.Driver,
DriverOpts: volume.DriverOpts,

View File

@@ -92,7 +92,7 @@ func TestPrepareNetworkLabels(t *testing.T) {
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{"skynet": {}}),
}
prepareNetworks(&project)
assert.DeepEqual(t, project.Networks["skynet"].Labels, composetypes.Labels(map[string]string{
assert.DeepEqual(t, project.Networks["skynet"].CustomLabels, composetypes.Labels(map[string]string{
"com.docker.compose.network": "skynet",
"com.docker.compose.project": "myProject",
"com.docker.compose.version": api.ComposeVersion,
@@ -278,33 +278,26 @@ 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, // serviceIndex
"netName", // networkKey
[]string{"link1", "link2"}, // links
true, // useNetworkAliases
)
}, 0, "netName", []string{"link1", "link2"}, true)
assert.Check(t, cmp.DeepEqual(eps, &network.EndpointSettings{
IPAMConfig: &network.EndpointIPAMConfig{
IPv4Address: "10.16.17.18",

View File

@@ -172,7 +172,6 @@ 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
@@ -438,7 +437,6 @@ 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
}

View File

@@ -67,18 +67,26 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
}
// Check requested services exists in model
options.Services, err = checkSelectedServices(options, project)
services, err := checkSelectedServices(options, project)
if err != nil {
return err
}
if len(options.Services) > 0 && len(services) == 0 {
logrus.Infof("Any of the services %v not running in project %q", options.Services, projectName)
return nil
}
options.Services = services
if len(containers) > 0 {
resourceToRemove = true
}
err = InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
serviceContainers := containers.filter(isService(service))
err := s.removeContainers(ctx, serviceContainers, options.Timeout, options.Volumes)
serv := project.Services[service]
err := s.removeContainers(ctx, serviceContainers, &serv, options.Timeout, options.Volumes)
return err
}, WithRootNodesAndDown(options.Services))
if err != nil {
@@ -87,7 +95,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
orphans := containers.filter(isOrphaned(project))
if options.RemoveOrphans && len(orphans) > 0 {
err := s.removeContainers(ctx, orphans, options.Timeout, false)
err := s.removeContainers(ctx, orphans, nil, options.Timeout, false)
if err != nil {
return err
}
@@ -289,9 +297,19 @@ func (s *composeService) removeVolume(ctx context.Context, id string, w progress
return err
}
func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, container moby.Container, timeout *time.Duration) error {
func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, service *types.ServiceConfig, container moby.Container, timeout *time.Duration) error {
eventName := getContainerProgressName(container)
w.Event(progress.StoppingEvent(eventName))
if service != nil {
for _, hook := range service.PreStop {
err := s.runHook(ctx, container, *service, hook, nil)
if err != nil {
return err
}
}
}
timeoutInSecond := utils.DurationSecondToInt(timeout)
err := s.apiClient().ContainerStop(ctx, container.ID, containerType.StopOptions{Timeout: timeoutInSecond})
if err != nil {
@@ -302,32 +320,30 @@ func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, c
return nil
}
func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, containers []moby.Container, timeout *time.Duration) error {
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 _, container := range containers {
container := container
for _, ctr := range containers {
eg.Go(func() error {
return s.stopContainer(ctx, w, container, timeout)
return s.stopContainer(ctx, w, serv, ctr, timeout)
})
}
return eg.Wait()
}
func (s *composeService) removeContainers(ctx context.Context, containers []moby.Container, timeout *time.Duration, volumes bool) error {
func (s *composeService) removeContainers(ctx context.Context, containers []moby.Container, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error {
eg, _ := errgroup.WithContext(ctx)
for _, container := range containers {
container := container
for _, ctr := range containers {
eg.Go(func() error {
return s.stopAndRemoveContainer(ctx, container, timeout, volumes)
return s.stopAndRemoveContainer(ctx, ctr, service, timeout, volumes)
})
}
return eg.Wait()
}
func (s *composeService) stopAndRemoveContainer(ctx context.Context, container moby.Container, timeout *time.Duration, volumes bool) error {
func (s *composeService) stopAndRemoveContainer(ctx context.Context, container moby.Container, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error {
w := progress.ContextWriter(ctx)
eventName := getContainerProgressName(container)
err := s.stopContainer(ctx, w, container, timeout)
err := s.stopContainer(ctx, w, service, container, timeout)
if errdefs.IsNotFound(err) {
w.Event(progress.RemovedEvent(eventName))
return nil

View File

@@ -96,6 +96,95 @@ func TestDown(t *testing.T) {
assert.NilError(t, err)
}
func TestDownWithGivenServices(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
api, cli := prepareMocks(mockCtrl)
tested := composeService{
dockerCli: cli,
}
api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
[]moby.Container{
testContainer("service1", "123", false),
testContainer("service2", "456", false),
testContainer("service2", "789", false),
testContainer("service_orphan", "321", true),
}, nil)
api.EXPECT().VolumeList(
gomock.Any(),
volume.ListOptions{
Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
}).
Return(volume.ListResponse{}, nil)
// network names are not guaranteed to be unique, ensure Compose handles
// cleanup properly if duplicates are inadvertently created
api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
Return([]network.Summary{
{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
}, nil)
stopOptions := containerType.StopOptions{}
api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
api.EXPECT().ContainerRemove(gomock.Any(), "123", containerType.RemoveOptions{Force: true}).Return(nil)
api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{
Filters: filters.NewArgs(
projectFilter(strings.ToLower(testProject)),
networkFilter("default")),
}).Return([]network.Summary{
{ID: "abc123", Name: "myProject_default"},
}, nil)
api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(network.Inspect{ID: "abc123"}, nil)
api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil)
err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{
Services: []string{"service1", "not-running-service"},
})
assert.NilError(t, err)
}
func TestDownWithSpecifiedServiceButTheServicesAreNotRunning(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
api, cli := prepareMocks(mockCtrl)
tested := composeService{
dockerCli: cli,
}
api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
[]moby.Container{
testContainer("service1", "123", false),
testContainer("service2", "456", false),
testContainer("service2", "789", false),
testContainer("service_orphan", "321", true),
}, nil)
api.EXPECT().VolumeList(
gomock.Any(),
volume.ListOptions{
Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
}).
Return(volume.ListResponse{}, nil)
// network names are not guaranteed to be unique, ensure Compose handles
// cleanup properly if duplicates are inadvertently created
api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
Return([]network.Summary{
{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
}, nil)
err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{
Services: []string{"not-running-service1", "not-running-service2"},
})
assert.NilError(t, err)
}
func TestDownRemoveOrphans(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
@@ -122,7 +211,8 @@ 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)

View File

@@ -21,10 +21,8 @@ import (
"strings"
)
var (
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
)
// isCaseInsensitiveEnvVars is true on platforms where environment variable names are treated case-insensitively.
var isCaseInsensitiveEnvVars = (runtime.GOOS == "windows")
// envResolver returns resolver for environment variables suitable for the current platform.
// Expected to be used with `MappingWithEquals.Resolve`.

View File

@@ -1,71 +0,0 @@
/*
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
}

101
pkg/compose/export.go Normal file
View File

@@ -0,0 +1,101 @@
/*
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 (
"context"
"fmt"
"io"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
)
func (s *composeService) Export(ctx context.Context, projectName string, options api.ExportOptions) error {
return progress.RunWithTitle(ctx, func(ctx context.Context) error {
return s.export(ctx, projectName, options)
}, s.stdinfo(), "Exporting")
}
func (s *composeService) export(ctx context.Context, projectName string, options api.ExportOptions) error {
projectName = strings.ToLower(projectName)
container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index)
if err != nil {
return err
}
if options.Output == "" && s.dockerCli.Out().IsTerminal() {
return fmt.Errorf("output option is required when exporting to terminal")
}
if err := command.ValidateOutputPath(options.Output); err != nil {
return fmt.Errorf("failed to export container: %w", err)
}
clnt := s.dockerCli.Client()
w := progress.ContextWriter(ctx)
name := getCanonicalContainerName(container)
msg := fmt.Sprintf("export %s to %s", name, options.Output)
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Working,
StatusText: "Exporting",
})
responseBody, err := clnt.ContainerExport(ctx, container.ID)
if err != nil {
return err
}
defer func() {
if err := responseBody.Close(); err != nil {
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Error,
StatusText: fmt.Sprintf("Failed to close response body: %v", err),
})
}
}()
if !s.dryRun {
if options.Output == "" {
_, err := io.Copy(s.dockerCli.Out(), responseBody)
return err
}
if err := command.CopyToFile(options.Output, responseBody); err != nil {
return err
}
}
w.Event(progress.Event{
ID: name,
Text: msg,
Status: progress.Done,
StatusText: "Exported",
})
return nil
}

246
pkg/compose/generate.go Normal file
View File

@@ -0,0 +1,246 @@
/*
Copyright 2023 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 (
"context"
"fmt"
"strings"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
moby "github.com/docker/docker/api/types"
containerType "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"golang.org/x/exp/maps"
)
func (s *composeService) Generate(ctx context.Context, options api.GenerateOptions) (*types.Project, error) {
filtersListNames := filters.NewArgs()
filtersListIDs := filters.NewArgs()
for _, containerName := range options.Containers {
filtersListNames.Add("name", containerName)
filtersListIDs.Add("id", containerName)
}
containers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{
Filters: filtersListNames,
All: true,
})
if err != nil {
return nil, err
}
containersByIds, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{
Filters: filtersListIDs,
All: true,
})
if err != nil {
return nil, err
}
for _, container := range containersByIds {
if !utils.Contains(containers, container) {
containers = append(containers, container)
}
}
if len(containers) == 0 {
return nil, fmt.Errorf("no container(s) found with the following name(s): %s", strings.Join(options.Containers, ","))
}
return s.createProjectFromContainers(containers, options.ProjectName)
}
func (s *composeService) createProjectFromContainers(containers []moby.Container, projectName string) (*types.Project, error) {
project := &types.Project{}
services := types.Services{}
networks := types.Networks{}
volumes := types.Volumes{}
secrets := types.Secrets{}
if projectName != "" {
project.Name = projectName
}
for _, c := range containers {
// if the container is from a previous Compose application, use the existing service name
serviceLabel, ok := c.Labels[api.ServiceLabel]
if !ok {
serviceLabel = getCanonicalContainerName(c)
}
service, ok := services[serviceLabel]
if !ok {
service = types.ServiceConfig{
Name: serviceLabel,
Image: c.Image,
Labels: c.Labels,
}
}
service.Scale = increment(service.Scale)
inspect, err := s.apiClient().ContainerInspect(context.Background(), c.ID)
if err != nil {
services[serviceLabel] = service
continue
}
s.extractComposeConfiguration(&service, inspect, volumes, secrets, networks)
service.Labels = cleanDockerPreviousLabels(service.Labels)
services[serviceLabel] = service
}
project.Services = services
project.Networks = networks
project.Volumes = volumes
project.Secrets = secrets
return project, nil
}
func (s *composeService) extractComposeConfiguration(service *types.ServiceConfig, inspect moby.ContainerJSON, volumes types.Volumes, secrets types.Secrets, networks types.Networks) {
service.Environment = types.NewMappingWithEquals(inspect.Config.Env)
if inspect.Config.Healthcheck != nil {
healthConfig := inspect.Config.Healthcheck
service.HealthCheck = s.toComposeHealthCheck(healthConfig)
}
if len(inspect.Mounts) > 0 {
detectedVolumes, volumeConfigs, detectedSecrets, secretsConfigs := s.toComposeVolumes(inspect.Mounts)
service.Volumes = append(service.Volumes, volumeConfigs...)
service.Secrets = append(service.Secrets, secretsConfigs...)
maps.Copy(volumes, detectedVolumes)
maps.Copy(secrets, detectedSecrets)
}
if len(inspect.NetworkSettings.Networks) > 0 {
detectedNetworks, networkConfigs := s.toComposeNetwork(inspect.NetworkSettings.Networks)
service.Networks = networkConfigs
maps.Copy(networks, detectedNetworks)
}
if len(inspect.HostConfig.PortBindings) > 0 {
for key, portBindings := range inspect.HostConfig.PortBindings {
for _, portBinding := range portBindings {
service.Ports = append(service.Ports, types.ServicePortConfig{
Target: uint32(key.Int()),
Published: portBinding.HostPort,
Protocol: key.Proto(),
HostIP: portBinding.HostIP,
})
}
}
}
}
func (s *composeService) toComposeHealthCheck(healthConfig *containerType.HealthConfig) *types.HealthCheckConfig {
var healthCheck types.HealthCheckConfig
healthCheck.Test = healthConfig.Test
if healthConfig.Timeout != 0 {
timeout := types.Duration(healthConfig.Timeout)
healthCheck.Timeout = &timeout
}
if healthConfig.Interval != 0 {
interval := types.Duration(healthConfig.Interval)
healthCheck.Interval = &interval
}
if healthConfig.StartPeriod != 0 {
startPeriod := types.Duration(healthConfig.StartPeriod)
healthCheck.StartPeriod = &startPeriod
}
if healthConfig.StartInterval != 0 {
startInterval := types.Duration(healthConfig.StartInterval)
healthCheck.StartInterval = &startInterval
}
if healthConfig.Retries != 0 {
retries := uint64(healthConfig.Retries)
healthCheck.Retries = &retries
}
return &healthCheck
}
func (s *composeService) toComposeVolumes(volumes []moby.MountPoint) (map[string]types.VolumeConfig,
[]types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig,
) {
volumeConfigs := make(map[string]types.VolumeConfig)
secretConfigs := make(map[string]types.SecretConfig)
var serviceVolumeConfigs []types.ServiceVolumeConfig
var serviceSecretConfigs []types.ServiceSecretConfig
for _, volume := range volumes {
serviceVC := types.ServiceVolumeConfig{
Type: string(volume.Type),
Source: volume.Source,
Target: volume.Destination,
ReadOnly: !volume.RW,
}
switch volume.Type {
case mount.TypeVolume:
serviceVC.Source = volume.Name
vol := types.VolumeConfig{}
if volume.Driver != "local" {
vol.Driver = volume.Driver
vol.Name = volume.Name
}
volumeConfigs[volume.Name] = vol
serviceVolumeConfigs = append(serviceVolumeConfigs, serviceVC)
case mount.TypeBind:
if strings.HasPrefix(volume.Destination, "/run/secrets") {
destination := strings.Split(volume.Destination, "/")
secret := types.SecretConfig{
Name: destination[len(destination)-1],
File: strings.TrimPrefix(volume.Source, "/host_mnt"),
}
secretConfigs[secret.Name] = secret
serviceSecretConfigs = append(serviceSecretConfigs, types.ServiceSecretConfig{
Source: secret.Name,
Target: volume.Destination,
})
} else {
serviceVolumeConfigs = append(serviceVolumeConfigs, serviceVC)
}
}
}
return volumeConfigs, serviceVolumeConfigs, secretConfigs, serviceSecretConfigs
}
func (s *composeService) toComposeNetwork(networks map[string]*network.EndpointSettings) (map[string]types.NetworkConfig, map[string]*types.ServiceNetworkConfig) {
networkConfigs := make(map[string]types.NetworkConfig)
serviceNetworkConfigs := make(map[string]*types.ServiceNetworkConfig)
for name, net := range networks {
inspect, err := s.apiClient().NetworkInspect(context.Background(), name, network.InspectOptions{})
if err != nil {
networkConfigs[name] = types.NetworkConfig{}
} else {
networkConfigs[name] = types.NetworkConfig{
Internal: inspect.Internal,
}
}
serviceNetworkConfigs[name] = &types.ServiceNetworkConfig{
Aliases: net.Aliases,
}
}
return networkConfigs, serviceNetworkConfigs
}
func cleanDockerPreviousLabels(labels types.Labels) types.Labels {
cleanedLabels := types.Labels{}
for key, value := range labels {
if !strings.HasPrefix(key, "com.docker.compose.") && !strings.HasPrefix(key, "desktop.docker.io") {
cleanedLabels[key] = value
}
}
return cleanedLabels
}

Some files were not shown because too many files have changed in this diff Show More