Compare commits

...

261 Commits

Author SHA1 Message Date
Nicolas De Loof
6007d4c7e7 publish env_file references as opaque hash to prevent paths conflicts
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-22 19:32:16 +02:00
Guillaume Lours
69bcb962bf Enforce compose files from OCI artifact all get into the same target (cache) folder
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-22 19:32:16 +02:00
Nicolas De Loof
9b4fcce034 introduce WithPrompt to configure compose backend to use a plugable UI component for user interaction
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-22 16:14:55 +02:00
Guillaume Lours
da5c57c29d test digest or canonical reference, not only tag, when checking if an image is already present
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-10-20 18:42:24 +02:00
Nicolas De Loof
e25265dd55 remove unused code to only rely on api.Service
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-20 14:53:04 +02:00
Nicolas De Loof
e19e1278b5 fail build if minimal required version of buildx isn't installed
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-20 12:25:38 +02:00
Nicolas De Loof
585c4db4f9 Compose can't create a tar with adequate uid:gid ownership
as we can't get container UID/GID as int by ContainerInspect
revert https://github.com/docker/compose/pull/13288

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-20 09:51:58 +02:00
Guillaume Lours
be8c7e6c60 make CTRL+Z a no-op operation on Windows
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-10-17 15:07:37 +02:00
Nicolas De Loof
27f59d7f42 Detect failure to access os.TempDir
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-17 09:49:44 +02:00
Nicolas De Loof
2681ed17a7 mutualize code from injectSecrets / injectConfigs
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-16 17:43:04 +02:00
Nicolas De Loof
ee75be342b Set secret/config uid:gid to match container's USER
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-16 17:43:04 +02:00
Paul Thiele
157617480a fix race-condition bug in publish command
Signed-off-by: Paul Thiele <paul.thiele@kinexon.com>
2025-10-16 09:24:57 +02:00
Nicolas De Loof
88aae9c46e support Ctrl+Z to run compose in background
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-15 17:26:11 +02:00
Guillaume Lours
7755302348 use fixed version of compose bridge transformer images
to avoid CI issue on Compose when a new version is released and change the outputs

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-10-14 09:21:59 +02:00
Guillaume Lours
147923c44c bump golang to version 1.24.9
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-10-14 09:14:56 +02:00
Olivier Goulpeau
289faae5fa fix(publish): in publish(), select all profiles in the project to publish.
This code is moved from `generateImageDigestsOverride()` as no more
needed at that point.

Signed-off-by: Olivier Goulpeau <olivier.goulpeau@ledger.fr>
2025-10-14 08:25:26 +02:00
Olivier Goulpeau
e7aa484b78 fix(publish): in processFile(), load the compose file passing the project.Profiles to the loader.Options.
Signed-off-by: Olivier Goulpeau <olivier.goulpeau@ledger.fr>
2025-10-14 08:25:26 +02:00
Sebastiaan van Stijn
ae3309afab pkg/compose: build with bake: drop support for buildx v0.16 and lower
[buildx v0.17][1] was released a Year ago, so any version this
conditional code was accounting for would be versions before that;
the latest of which being [buildx v0.16.2][2] (July 2024).

Given that those versions are long EOL and no longer supported, we
can probably remove the conditional code.

[1]: https://github.com/docker/buildx/releases/tag/v0.17.0
[2]: https://github.com/docker/buildx/releases/tag/v0.16.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-14 08:02:58 +02:00
Sebastiaan van Stijn
0b5fb36eb5 build(deps): bump docker/buildx v0.29.1, moby/buildkit v0.25.1
full diff:

- https://github.com/docker/buildx/compare/v0.28.0...v0.29.1
- https://github.com/moby/buildkit/compare/v0.24.0...v0.25.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 21:21:01 +02:00
Sebastiaan van Stijn
63920c4cc0 pkg/compose: align classic builder implementation with docker/cli
This aligns the implementation closer to the implementation in docker/cli,
with the refactor done in [cli@260f1db]; this removes some direct uses of
the github.com/docker/docker/builder/remotecontext/urlutil package, which
won't be included in the new Moby modules.

There's still some remaining uses in the `dockerFilePath` utility (which
may need to be updated to also account for remote contexts that are not
"git"), so possibly we can remove the use in that utility as well.

[cli@260f1db]: 260f1dbebb

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-13 16:53:00 +02:00
Nicolas De Loof
a03f2562df bake only interpolates ${*}
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-13 10:40:19 +02:00
dependabot[bot]
a07f2b8ded build(deps): bump golang.org/x/sys from 0.36.0 to 0.37.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.36.0 to 0.37.0.
- [Commits](https://github.com/golang/sys/compare/v0.36.0...v0.37.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-09 11:35:31 +02:00
dependabot[bot]
f45a3ebcfd build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 28.5.0+incompatible to 28.5.1+incompatible.
- [Commits](https://github.com/docker/cli/compare/v28.5.0...v28.5.1)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.5.1+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-09 11:35:14 +02:00
dependabot[bot]
7fec70b6c7 build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.5.0+incompatible to 28.5.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.5.0...v28.5.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.5.1+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-09 11:34:52 +02:00
Kian Eliasi
ce463d50b2 Fix: set PWD only if not set
Signed-off-by: Kian Eliasi <kian.elbo@gmail.com>
2025-10-08 10:12:02 +02:00
Benedikt Radtke
fa7e85ed83 Write error to watcher error channel if Start() fails
Up's loop will notice globalCtx is done, and invoke watcher.Stop(). Stop() reads from the watcher error channel. If Start() does not write an error, Stop() will never finish.

Fixes https://github.com/docker/compose/issues/13262

Signed-off-by: Benedikt Radtke <benediktradtke@gmail.com>
2025-10-06 14:50:19 +02:00
dependabot[bot]
d9423f6872 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 28.5.0-rc.1+incompatible to 28.5.0+incompatible.
- [Commits](https://github.com/docker/cli/compare/v28.5.0-rc.1...v28.5.0)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.5.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-03 11:32:15 +02:00
dependabot[bot]
5add90240d build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.5.0-rc.1+incompatible to 28.5.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.5.0-rc.1...v28.5.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.5.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-03 11:32:08 +02:00
Nicolas De Loof
07602f2070 publish Compose application as compose.yaml + images
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-03 10:59:57 +02:00
Nicolas De Loof
cf7e31f731 escape $ in bake.json as interpolation already has been managed by compose
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-10-03 09:25:35 +02:00
Nicolas De Loof
fa08127456 use containerd client for OCI operations
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-30 12:03:46 +02:00
Nicolas De Loof
4ee52ad168 pass bake secrets by env
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-30 09:07:22 +02:00
Sebastiaan van Stijn
4a4776ec57 cmd/compose: fix minor linting issues
- inline variable that shadowed package-type
- don't use apiBuildOptions if an error was returned

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 15:25:22 +02:00
Sebastiaan van Stijn
713de5bb9e pkg/compose: explicitly map AuthConfig fields instead of a direct cast
Commit [cli@27b2797] forked the AuthConfig type from the API, and changed
existing code to do a direct cast / convert of the forked type to the API
type. This can cause issues if the API types diverges, such as the removal
of the Email field.

This patch explicitly maps each field to the corresponding API type, but
adds some TODOs, because various code-paths only included a subset of the
fields, which may be intentional for fields that were meant to be handled
on the daemon / registry-client only.

We should evaluate these conversions to make sure these fields should
be sent from the client or not (and possibly even removed from the API
type).

[cli@27b2797]: 27b2797f7d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 15:24:42 +02:00
Sebastiaan van Stijn
9ded1684cd gha: update test-matrix: remove docker 26.x
- Mirantis Container Runtime (MCR) 23.0 reached EOL, and the next LTS
  version of MCR is 25.x, but download.docker.com does not have 25.x
  packages for the latest Ubuntu release.
- Docker 26.x reached EOL and is no longer maintained

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-29 14:27:41 +02:00
Guillaume Lours
8bc8593fd0 provider services: use '--project-name=' notation
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-29 12:38:10 +02:00
Nicolas De Loof
8978c1027d use containerd registry client
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-26 18:45:07 +02:00
Sebastiaan van Stijn
032e0309ee cmd: pluginMain: use WithUserAgent option
Rewrite the custom user agent to use the new options that were added
in the cli:

- plugin.Run now accepts custom CLI options to allow customizing the CLI's
- cli/command now has a WithUserAgent option to customize the CLI's user-
  agent, allowing it to be overridden from the default.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 16:50:44 +02:00
Sebastiaan van Stijn
38ba35e165 pkg/mocks: re-generate mocks
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 16:50:44 +02:00
Sebastiaan van Stijn
56e0ba8080 build(deps): bump github.com/docker/docker, docker/cli v28.5.0-rc.1
full diff:

- https://github.com/docker/cli/compare/v28.4.0...v28.5.0-rc.1
- https://github.com/docker/docker/compare/v28.4.0...v28.5.0-rc.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 16:50:44 +02:00
Sebastiaan van Stijn
9752fa5500 pluginMain: remove uses of DockerCLI.Apply
The Apply method was added when CLI options for constructing the CLI were
rewritten into functional options in [cli@7f207f3]. There was no mention
in the pull request of this method specifically, and we want to remove or
reduce functions that mutate the CLI configuration after initialization
if possible (and likely remove the `Apply` method).

This patch removes the use of the `Apply` function as an intermediate step;
improvements will be made in the CLI itself for a more solid implementation.

[cli@7f207f3]: 7f207f3f95

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 14:09:55 +02:00
Sebastiaan van Stijn
4761fd88b0 pkg/compose: build: remove permissions warning on Windows
This warning was added in [moby@4a8b3ca] to print a warning when building
Linux images from a Windows client. Window's filesystem does not have an
"executable" bit, which mean that, for example, copying a shell script
to an image during build would lose the executable bit. So for Windows
clients, the executable bit would be set on all files, unconditionally.

Originally this was detected in the client, which had direct access to
the API response headers, but when refactoring the client to use a common
library in [moby@535c4c9], this was refactored into a `ImageBuildResponse`
wrapper, deconstructing the API response into an `io.Reader` and a string
field containing only the `OSType` header.

This was the only use and only purpose of the `OSType` field, and now that
BuildKit is the default builder for Linux images, this warning didn't get
printed unless BuildKit was explicitly disabled.

This patch removes the warning, so that we can potentially remove the
field, or the `ImageBuildResponse` type altogether.

[moby@4a8b3ca]: 4a8b3cad60
[moby@535c4c9]: 535c4c9a59

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 10:26:05 +02:00
Sebastiaan van Stijn
02c8e63545 pkg/watch: remove unused IsWindowsShortReadError
This function was added in b3615d64e2 but
appears to be unused.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 09:29:27 +02:00
Sebastiaan van Stijn
ab7a6e9322 pkg/compose: remove uses of deprecated mitchellh/mapstructure module
The github.com/mitchellh/mapstructure module was archived and is no longer
maintained. This module has moved to github.com/go-viper/mapstructure,
which updated to v2, with a minor breaking change in v2.0;

> Error is removed in favor of errors.Join (backported from Go 1.20 to
> preserve compatibility with earlier versions)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-24 09:21:40 +02:00
Nicolas De Loof
2ca7b96e33 resolve secrets based on env var before executing bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-22 14:56:15 +02:00
Ricardo Branco
a32dc3da72 test: Set stop_signal to SIGTERM
The official nginx images set STOPSIGNAL to SIGQUIT which dumps core.
Set it to SIGTERM to avoid dumping core on e2e tests.

Signed-off-by: Ricardo Branco <rbranco@suse.de>
2025-09-19 10:31:20 +02:00
Guillaume Lours
db260938c1 bump compose-go to version v2.9.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-19 10:13:08 +02:00
Guillaume Lours
5aea94794c Update comment on run command with tty & piped command
Co-authored-by: Nicolas De loof <nicolas.deloof@gmail.com>
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-19 09:51:15 +02:00
Guillaume Lours
d07c437ce8 dectect if piped run command and disable tty if so
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-19 09:51:15 +02:00
Guillaume Lours
da72230c39 remove tty attribute from run options and use dedicated variable to avoid confusion
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-19 09:51:15 +02:00
Nicolas De Loof
a429c09dfa fix support for build with bake when target docker endpoint requires TLS
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-18 11:16:47 +02:00
Guillaume Lours
df3c27c864 add deprecation warning for x-initialSync + e2e test
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-18 11:06:44 +02:00
Guillaume Lours
956891af54 add support of develop.watch.initial_sync attribute
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-18 11:06:44 +02:00
Nicolas De Loof
a473341058 volume ls command can run without a project
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-10 09:41:47 +02:00
Guillaume Lours
385b3f5c96 bump compose-go to version v2.8.2
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-08 18:07:00 +02:00
Nicolas De Loof
2d482e61ce propagate docker endpoint to bake using DOCKER_* env variables
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 17:54:55 +02:00
Nicolas De loof
c75418ee07 Apply suggestions from code review
Co-authored-by: Allie Sadler <102604716+aevesdocker@users.noreply.github.com>
Signed-off-by: Nicolas De loof <nicolas.deloof@gmail.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 15:56:55 +02:00
Nicolas De Loof
0cdc5c9bff rename --no-TTY => --no-tty for consistency
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 15:56:55 +02:00
Nicolas De Loof
b768232c0e document (hidden) --tty --interactive flags
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 15:56:55 +02:00
Nicolas De Loof
09689400e5 fix run --build support for service:* reference in additional_context
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 15:10:29 +02:00
Nicolas De Loof
cb3691154b detect container is restarted
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 15:03:18 +02:00
Nicolas De Loof
b387ba4a05 only load COMPOSE_* from $PWD/.env
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 14:40:49 +02:00
Nicolas De Loof
7cd569922e only propagate os.Env to bake, not the whole project.Environment
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 14:40:49 +02:00
Nicolas De Loof
eec2bb7ea6 only force plain mode build if progress is set to auto
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-08 14:17:04 +02:00
dependabot[bot]
2c15aef2ed build(deps): bump golang.org/x/sys from 0.35.0 to 0.36.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.35.0 to 0.36.0.
- [Commits](https://github.com/golang/sys/compare/v0.35.0...v0.36.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 13:49:29 +02:00
dependabot[bot]
290366205b build(deps): bump golang.org/x/sync from 0.16.0 to 0.17.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/sync/compare/v0.16.0...v0.17.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 13:33:10 +02:00
Guillaume Lours
a91ca95a71 bump golang to version 1.24.7
to align with moby/moby version

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-09-08 12:05:41 +02:00
Sebastiaan van Stijn
beb81a73f9 pkg/compose: remove aliases for container-state consts
These are no longer used, and have no known external consumers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 11:52:28 +02:00
Sebastiaan van Stijn
f217207876 pkg/compose: use state consts from moby API
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 11:52:28 +02:00
Nicolas De Loof
02ffe2ac6c prefer application container vs one-off running exec without index
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-07 14:41:34 +02:00
dependabot[bot]
f48131fb66 build(deps): bump github.com/spf13/pflag from 1.0.9 to 1.0.10
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.9...v1.0.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-07 14:37:04 +02:00
Nicolas De Loof
4dd369bdcb fix sigint/sigterm support in logs --follow
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-09-07 14:19:56 +02:00
dependabot[bot]
ad73766bf2 build(deps): bump github.com/docker/buildx from 0.28.0-rc2 to 0.28.0
Bumps [github.com/docker/buildx](https://github.com/docker/buildx) from 0.28.0-rc2 to 0.28.0.
- [Release notes](https://github.com/docker/buildx/releases)
- [Commits](https://github.com/docker/buildx/compare/v0.28.0-rc2...v0.28.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-05 08:38:23 +02:00
Sebastiaan van Stijn
3c1f5a1815 go.mod: bump github.com/docker/docker, docker/cli v28.4.0
full diffs:

- https://github.com/docker/docker/compare/v28.3.3...v28.4.0
- https://github.com/docker/cli/compare/v28.3.3...v28.4.0
- https://github.com/moby/buildkit/compare/v0.24.0-rc2...v0.24.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 15:23:59 +02:00
dependabot[bot]
42d1e4c333 build(deps): bump github.com/spf13/cobra from 1.9.1 to 1.10.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.9.1 to 1.10.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.9.1...v1.10.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-03 14:44:38 +02:00
dependabot[bot]
6ca8663bda build(deps): bump github.com/spf13/pflag from 1.0.7 to 1.0.9
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.7 to 1.0.9.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.7...v1.0.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-02 15:46:14 +02:00
Sebastiaan van Stijn
b33ecf65e8 go.mod: bump buildx v0.28.0-rc2, buildkit v0.24.0-rc2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-02 07:28:06 +02:00
Roberto Villarreal
04b8ac5fe4 Unquote volume names in creation events
Volumes are the only resources that are quoted, and only on creation.

Signed-off-by: Roberto Villarreal <rrjjvv@yahoo.com>
2025-08-29 11:50:42 +02:00
dependabot[bot]
d09948da41 build(deps): bump github.com/stretchr/testify from 1.10.0 to 1.11.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.10.0 to 1.11.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 08:28:51 +02:00
Sebastiaan van Stijn
f1efbb8322 use enum-consts for State and Health
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 08:18:16 +02:00
Sebastiaan van Stijn
1d52012b82 go.mod: bump buildkit v0.24.0-rc1, buildx v0.28.0-rc1
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-29 08:16:23 +02:00
Sebastiaan van Stijn
1d69f4a68c pkg/compose: composeService.Up: rewrite without go-multierror
- Use a errgroup.Group and add a appendErr utility to not fail-fast,
  but collect errors.
- replace doneCh for a global context to cancel goroutines
- Commented out attachCtx code, as it didn't appear to be functional
  (as it wouldn't be cancelled).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-27 15:25:17 +02:00
Kian Eliasi
6078b4d99d Fix: use image created time when last tag time is not present
Signed-off-by: Kian Eliasi <kian.elbo@gmail.com>
2025-08-27 09:03:58 +02:00
Kian Eliasi
73e593e69a Fix: incorrect time when last tag time is not set
Signed-off-by: Kian Eliasi <kian.elbo@gmail.com>
2025-08-27 09:03:58 +02:00
Sebastiaan van Stijn
51499f645b pkg/compose: pull: use native multi-errors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 11:22:25 +02:00
Sebastiaan van Stijn
5165b0f814 internal/tracing: replace go-multierror.Group with sync.WaitGroup
The go-multierror Group is just a shallow wrapper around sync.WaitGroup;
https://github.com/hashicorp/go-multierror/blob/v1.1.1/group.go#L5-L38

This patch replaces the go-multierror.Group for a sync.WaitGroup (we
probably don't need to limit concurrency for this one) and stdlib multi-
errors.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 11:22:25 +02:00
Sebastiaan van Stijn
93dd1a4558 internal/sync: replace go-multierror.Group with golang.org/x/sync/errgroup
The go-multierror Group is just a shallow wrapper around sync.WaitGroup;
https://github.com/hashicorp/go-multierror/blob/v1.1.1/group.go#L5-L38

It does not limit concurrency, but handles synchronisation to collect
all errors (if any) in a go-multierror.

This patch replaces the go-multierror.Group for a sync.ErrGroup (which
is slightly easier to use, and does allow for limiting concurrency if
wanted), and a basic slice with mutex to collect the errors and to produce
a stdlib multi-error through errors.Join

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 11:22:25 +02:00
Sebastiaan van Stijn
ba3f5664c0 cmd/formatter: remove unused SetMultiErrorFormat
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 11:22:25 +02:00
Guillaume Lours
c420bc44c4 check the assume yes publish flag command before the presence of bind mounts
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-08-25 10:29:52 +02:00
Max Proske
60681a824c Add e2e test to verify docker compose down works even when env file is missing
Signed-off-by: Max Proske <max@mproske.com>
2025-08-25 10:03:55 +02:00
Max Proske
19ad737ee7 Fix runtime ops with missing env file
Signed-off-by: Max Proske <max@mproske.com>
2025-08-25 10:03:55 +02:00
may
d3a260e533 add completions for the --progress flag
Signed-off-by: may <m4rch3n1ng@gmail.com>
2025-08-25 10:01:49 +02:00
dependabot[bot]
e75329dce2 build(deps): bump go.uber.org/mock from 0.5.2 to 0.6.0
Bumps [go.uber.org/mock](https://github.com/uber/mock) from 0.5.2 to 0.6.0.
- [Release notes](https://github.com/uber/mock/releases)
- [Changelog](https://github.com/uber-go/mock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uber/mock/compare/v0.5.2...v0.6.0)

---
updated-dependencies:
- dependency-name: go.uber.org/mock
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 09:50:16 +02:00
Sebastiaan van Stijn
1dc0be2c30 go.mod: github.com/docker/buildx v0.27.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-25 09:36:33 +02:00
cuiweixie
3bac9ffd08 Refactor to use maps.Copy
Signed-off-by: cuiweixie <cuiweixie@gmail.com>
2025-08-25 08:57:52 +02:00
Guillaume Lours
f266715dd0 add --provenance and --sbom flag to generated bake command line,
also add attestation per-service configuration to generated bake target

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-08-13 09:36:22 +02:00
Guillaume Lours
c2cb0aef6b only monitor attached services on up command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-08-08 17:27:08 +02:00
Austin Vazquez
fbc62d111e bump golang to 1.23.12
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
2025-08-08 16:22:30 +02:00
dependabot[bot]
0d40064ce8 build(deps): bump golang.org/x/sys from 0.34.0 to 0.35.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.34.0 to 0.35.0.
- [Commits](https://github.com/golang/sys/compare/v0.34.0...v0.35.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 14:22:18 +02:00
dependabot[bot]
91a6eafa1d build(deps): bump github.com/docker/go-connections from 0.5.0 to 0.6.0
Bumps [github.com/docker/go-connections](https://github.com/docker/go-connections) from 0.5.0 to 0.6.0.
- [Commits](https://github.com/docker/go-connections/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/docker/go-connections
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 14:08:26 +02:00
Matthew Runyon
f36ee00f71 Add go as a prerequesite in build instructions
Signed-off-by: Matthew Runyon <matthewrunyon@deephaven.io>
2025-08-06 15:27:09 +02:00
dependabot[bot]
29ede3ba7d build(deps): bump github.com/containerd/containerd/v2
Bumps [github.com/containerd/containerd/v2](https://github.com/containerd/containerd) from 2.1.3 to 2.1.4.
- [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/v2.1.3...v2.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 13:55:31 +02:00
Guillaume Lours
bf6d7bf47e define pull and no_cache from either service or flags values when building with bake
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-08-05 13:52:43 +02:00
Sebastiaan van Stijn
fc66da06db pkg/compose: simplify getting auth-config key
Rewrite to remove the `github.com/docker/docker/registry` dependency,
which will not be included in the upcoming "api" and "client" modules,
and will not be a public package in the module used for the daemon itself.

1. don't call "/info" API endpoint to get default registry

The `IndexServerAddress` in the `/info` endpoint was added as part of the
initial Windows implementation of the engine. For legal reasons, Microsoft
Windows (and thus Docker images based on Windows) were not allowed to be
distributed through non-Microsoft infrastructure. As a temporary solution,
a dedicated "registry-win-tp3.docker.io" registry was created to serve
Windows images.

Using separate registries was not an ideal solution, and a more permanent
solution was created by introducing "foreign image layers" in the distribution
spec, after which the "registry-win-tp3.docker.io" ceased to exist, and
removed from the engine through docker/docker PR 21100.

However, the `ElectAuthServer` was left in place, quoting from that PR;

> make the client check which default registry the daemon uses is still
> more correct than leaving it up to the client, even if it won't technically
> matter after this PR. There may be some backward compatibility scenarios
> where `ElectAuthServer` [sic] is still helpful.

That comment was 10 Years ago, and the CLI stopped using this information,
as the default registry is not configurable, so in practice was a static
value. (see b4ca1c7368).

2. replace `ParseRepositoryInfo` and `GetAuthConfigKey` with local impl

The `ParseRepositoryInfo` function was originally implemented for use by
the daemon itself. It returns a `RepositoryInfo` struct that holds information
about the repository and the registry the repository can be found in.

As it was written for use by the daemon, it also was designed to be used
in combination with the daemon's configuration (such as mirrors, and
insecure registries). If no daemon configuration is present, which would
be the case when used in a CLI, it uses fallback logic as used in the daemon
to detect if the registry is running on a localhost / loopback address,
because such addresses are allowed to be "insecure" by default; this includes
resolving the IP-address of the host (if it's not an IP-address).

Unfortunately, these functions (and related types) were reused in the
CLI and many other places, which resulted in those types to be deeply
ingrained in interfaces and (external) code.

For compose; it was only used to get the "auth-config key" to use for
looking up auth information from the credentials store, which still
needs special handling for the "default" (docker hub) domain, which
unlike other image references doesn't use the hostname included in
the image reference for the actual registry (and key for storing
auth).

For those that want to follow along;

First, note that `GetAuthConfig` only requires a `registry.IndexInfo`, so not
the whole `RepositoryInfo` struct;
https://github.com/moby/moby/blob/v28.3.3/registry/types.go#L8-L24

From the `registry.IndexInfo` it only uses the `IsOfficial` and `Name` fields;
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L390-L395

But to get the `IndexInfo`, `ParseRepositoryInfo` is needed, which first
takes the image reference's "domain name" (e.g. `docker.io`);
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L421

This gets "normalized" for some cases where the `info.IndexServerAddress`
was incorrectly assumed to be the canonical domain for Docker Hub registry,
and which _does_ happen to also be accessible as a "v2" registry.
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L334-L341

After normalizing, it checks if it's a docker hub address ("docker.io"
after normalizing); Docker Hub is always required to use a secure
connection, so no detection happens, and the `Official` field is set
to indicate it's Docker Hub (this code path was already simplified
as historically it would try to find daemon configuration (or otherwise
use a default) for Mirror configuration;
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L420-L443

For non-Docker Hub registries, it also sets the name, and attempts
to detect if the registry is allowed to be "insecure";
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L435-L442

Which (as mentioned) involves parsing the address and, if needed, resolving
the hostname
https://github.com/moby/moby/blob/v28.3.3/registry/config.go#L445-L481

As `Insecure` is not used for looking up the auth-config key, all of the
above can be reduced to;

- Is the hostname obtained from the image reference "docker.io" (after normalizing)?
- If so, use the special `https://index.docker.io/v1/` as auth-config key (another horrible remnant)
- Otherwise use the hostname obtained from the image reference as-is

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 10:08:23 +02:00
Sebastiaan van Stijn
909211dd61 use cli-plugins/metadata package
The metadata types and consts where moved to a separate package,
so update the code to use the new location instead of the aliases
provided.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-05 10:01:53 +02:00
dependabot[bot]
0dc9852c67 build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.3.2+incompatible to 28.3.3+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.3.2...v28.3.3)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.3+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 11:39:57 +02:00
dependabot[bot]
a478702236 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 28.3.2+incompatible to 28.3.3+incompatible.
- [Commits](https://github.com/docker/cli/compare/v28.3.2...v28.3.3)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.3.3+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 11:27:29 +02:00
Nicolas De Loof
2c12ad19db use log API for containers we didn't attached to
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-29 14:23:24 +02:00
Guillaume Lours
038ea8441a apply BUILDKIT_PROGRESS value when building with bake
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-29 11:45:33 +02:00
Guillaume Lours
9e98e6101e add missing _MODEL suffix to model variable pass to dependent services of a model
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-29 09:40:46 +02:00
keitosuwahara
52f04229c0 fixed lint error
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-28 10:07:03 +02:00
keitosuwahara
28895d0322 fix lint error
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-28 10:07:03 +02:00
keitosuwahara
a926f7d717 Elimneted magic string
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-28 10:07:03 +02:00
Nicolas De Loof
fe046915eb buildkit require os.Stdout to access the raw terminal
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-28 09:25:35 +02:00
keitosuwahara
adbd61e5d6 fixed lint error
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 19:36:40 +02:00
keitosuwahara
e37ac04329 deleted useless comment
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 19:36:40 +02:00
keitosuwahara
cab2c2a44e Refactoring of redundant condition checks
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 19:36:40 +02:00
keitosuwahara
1946de598d improved lint error
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 15:12:38 +02:00
keitosuwahara
8e29a138aa improved test
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 15:12:38 +02:00
keitosuwahara
3c8da0afee Add test of json.go
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 15:12:38 +02:00
keitosuwahara
1b12c867c5 add Streams Comment
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-27 14:57:43 +02:00
Guillaume Lours
1a4fc55fd7 bump compose-go to v2.8.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-24 18:10:41 +02:00
Guillaume Lours
efc939dcee add info about models usage to OpenTelemetry spans
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-24 16:01:28 +02:00
keitosuwahara
d6e9f79ba6 Integration of SetAttributes calls
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-24 09:05:30 +02:00
keitosuwahara
b4c44a431f Eliminate magic number in init functions
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-24 09:04:52 +02:00
keitosuwahara
fb5a8644c3 Efficiency of ansiColorCode function
Signed-off-by: keitosuwahara <keitosuwahara0816@gmail.com>
2025-07-24 09:04:02 +02:00
Guillaume Lours
95660c5e5a bump buildx to v0.26.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-23 16:01:28 +02:00
Guillaume Lours
f6ddd6ae88 use output registry when push true and load to docker store if not
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-23 15:49:19 +02:00
dependabot[bot]
4ae7066955 build(deps): bump google.golang.org/grpc from 1.73.0 to 1.74.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.73.0 to 1.74.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.73.0...v1.74.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 14:51:08 +02:00
Nicolas De Loof
fd954f266c show build progress during watch rebuild
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-23 13:57:46 +02:00
Nicolas De Loof
d62e21025c forward git command error to user
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-23 12:10:25 +02:00
Guillaume Lours
6a2d16bd10 bump compose-go to version v2.8.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-23 11:53:47 +02:00
Guillaume Lours
4d47da6dc2 do not pass user id on Windows system as engine is not able to handel it
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-22 12:07:58 +02:00
Nicolas De Loof
8f91793fb5 introduce build.provenance and sbom support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-21 17:07:41 +02:00
Sebastiaan van Stijn
1d2223fb23 pkg/compose: use local copy of pkg/system.IsAbs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 16:02:52 +02:00
Sebastiaan van Stijn
d4f6000712 remove import aliases for containerd/errdefs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 15:51:39 +02:00
Sebastiaan van Stijn
c50d16cd78 pkg/compose: remove uses of moby/errdefs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-21 15:51:39 +02:00
Nicolas De Loof
3875e13fad simpler stop UI
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-21 10:31:50 +02:00
Nicolas De Loof
c89f30170d force plain displaymode if stdout isn't a terminal
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-21 10:19:58 +02:00
Nicolas De Loof
41a9b91887 warn user COMPOSE_BAKE=false is deprecated
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-21 10:18:08 +02:00
Nicolas De Loof
5fc2b2a71c fix yaml indentation
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-18 11:59:56 +02:00
Nicolas De Loof
b1cd40c316 swarm
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-18 11:58:25 +02:00
dependabot[bot]
362ab0733f build(deps): bump github.com/spf13/pflag from 1.0.6 to 1.0.7
Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.6...v1.0.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-17 15:35:38 +02:00
Nicolas De Loof
f35d2cfb3b monitor must watch events even when context is cancelled
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-17 15:08:35 +02:00
Nicolas De Loof
17ba6c7188 abstract model-cli commands execution with a model (pseudo) API
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-16 17:34:59 +02:00
Nicolas De Loof
1c37f1abb6 use logs API with Since to collect the very first logs after restart
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-16 17:24:11 +02:00
Nicolas De Loof
485b6200ee (refactoring) introduce monitor to manage containers events and application termination
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-16 17:24:11 +02:00
Nicolas De Loof
8c17a35609 don't run navigation menu if stdin isn't a terminal
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-16 16:51:26 +02:00
Guillaume Lours
6b9667401a fix the helm bridge e2e tests after the latest update of the templates
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-16 16:04:52 +02:00
Arthur Bols
9a1e589ce8 Fix report image name in bake result
Signed-off-by: Arthur Bols <arthur@bols.dev>
2025-07-16 08:59:12 +02:00
Guillaume Lours
5e147e852e add default compose labels to images built from bake
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-16 07:35:07 +02:00
Nicolas De Loof
29308cb97e keep containers attached on stop to capture termination logs
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-15 11:26:44 +02:00
Guillaume Lours
0b0242d0ac add dry-run support to bake build
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-15 10:52:03 +02:00
Cedric Staniewski
5a704004d3 Add a space character to separate the timestamp from the log message
Signed-off-by: Cedric Staniewski <cedric@gmx.ca>
2025-07-15 10:50:43 +02:00
MohammadHasan Akbari
cb95910018 chore: print model attribute instead of model name used in compose file
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2025-07-11 11:08:08 +02:00
MohammadHasan Akbari
f42226e352 feat: add --models flag to config command
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2025-07-11 11:08:08 +02:00
Nicolas De Loof
0cc3c7a550 bump dependencies
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-11 11:04:26 +02:00
atagtm
f7ee9c8a0c feat(os): add FreeBSD support
Signed-off-by: atagtm <donisos1146@gmail.com>
2025-07-11 10:44:45 +02:00
MohammadHasan Akbari
35efa97b7d feat: add since & until flags to events command
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
Co-authored-by: Amin Ehterami <A.Ehterami@proton.me>
2025-07-09 10:08:33 +02:00
dependabot[bot]
9e17a091be build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.3.0+incompatible to 28.3.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.3.0...v28.3.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.1+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-08 11:17:18 +02:00
Guillaume Lours
4bbc6c609f add USER_AGENT variable to cmd when shellouting
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-08 11:12:40 +02:00
Nicolas De Loof
69f1430a49 resolve Dockerfile symlink but file name
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-08 10:06:34 +02:00
Nicolas De Loof
7cf7c6414f build resolves enabled service after project has been loaded
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-07 16:43:42 +02:00
MohammadHasan Akbari
0e0ed91a39 fix: lint errors
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2025-07-07 10:37:20 +02:00
MohammadHasan Akbari
66524e7728 feat: add --networks flag to config command
Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
2025-07-07 10:37:20 +02:00
Guillaume Lours
c626befee1 fix the way we're checking if the provider metadata are empty or not
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-04 12:41:37 +02:00
Nicolas De Loof
60ee6adcd2 a single place for shell-out command setup
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-04 11:17:11 +02:00
dependabot[bot]
8faf1eb808 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 28.3.0+incompatible to 28.3.1+incompatible.
- [Commits](https://github.com/docker/cli/compare/v28.3.0...v28.3.1)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.3.1+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-03 11:35:58 +02:00
dependabot[bot]
3b0601b671 build(deps): bump github.com/moby/buildkit from 0.23.1 to 0.23.2
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.23.1 to 0.23.2.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.23.1...v0.23.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 11:49:11 +02:00
Guillaume Lours
f42374bb18 add a Done event to model progress display
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-02 11:25:07 +02:00
mountdisk
b046a5ef72 chore: fix some minor issues in the comments
Signed-off-by: mountdisk <mountdisk@icloud.com>
2025-07-02 07:31:00 +02:00
Guillaume Lours
1570c6c076 bump go-viper/mapstructure to version v2.3.0
Fix https://github.com/advisories/GHSA-fv92-fjc5-jj9h

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-01 14:56:57 +02:00
Guillaume Lours
674e13fb6d bump golang to v1.23.10
Fix Vulnerability Report: GO-2025-3751

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-07-01 14:52:43 +02:00
Nicolas De Loof
6fa173124a (reactoring) avoid a global variable by introducing logConsumer decorator
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-07-01 12:29:05 +02:00
Sebastiaan van Stijn
2c69fc3d4d pkg/compose: remove redundant uses of strslice.StrSlice
The strslice.StrSlice type is a string-slice with a custom JSON Unmarshal
function to provide backward-compatibility with older API requests (see
[moby@17d6f00] and [moby@ea4a067]).

Given that the type is assigned implicitly through the fields on HostConfig,
we can just use a regular []string instead.

[moby@17d6f00]: 17d6f00ec2
[moby@ea4a067]: ea4a06740b

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-07-01 10:49:29 +02:00
Nicolas De Loof
317ebcd3b0 implement model_variable
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 21:50:39 +02:00
Guillaume Lours
5cf1f0e2a4 bump compose-go to version v2.7.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 21:22:56 +02:00
Leonardo Peregrino
6198ed5bd2 fix linting errors
Signed-off-by: Leonardo Peregrino <55335068+leoperegrino@users.noreply.github.com>
2025-06-30 19:38:27 +02:00
Leonardo Peregrino
00ccddbde8 add volumes command test cases
Signed-off-by: Leonardo Peregrino <55335068+leoperegrino@users.noreply.github.com>
2025-06-30 19:38:27 +02:00
Leonardo Peregrino
63b441401e add volumes docs/reference/
Signed-off-by: Leonardo Peregrino <55335068+leoperegrino@users.noreply.github.com>
2025-06-30 19:38:27 +02:00
Leonardo Peregrino
3a7982fe45 add service filter to volumes command
Signed-off-by: Leonardo Peregrino <55335068+leoperegrino@users.noreply.github.com>
2025-06-30 19:38:27 +02:00
Leonardo Peregrino
5430caa172 add volumes command
Signed-off-by: Leonardo Peregrino <55335068+leoperegrino@users.noreply.github.com>
2025-06-30 19:38:27 +02:00
Nicolas De Loof
ee1b1e0a93 run docker model configure
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 19:22:35 +02:00
Nicolas De Loof
26e46d7cc8 e2e tests in CI
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 19:22:35 +02:00
Nicolas De Loof
a9e76943f6 introduce support for models
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 19:22:35 +02:00
Nicolas De Loof
b6a0df8d3c e2e compose run --env
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 19:09:22 +02:00
Guillaume Lours
5a063b7510 fix provider concurrent environment map accesses
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 19:07:10 +02:00
dependabot[bot]
ae49bba9be build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 28.2.2+incompatible to 28.3.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.2.2...v28.3.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 18:49:27 +02:00
Nicolas De Loof
51acc58453 mount /var/run/docker.sock for --use-api-socket
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 18:45:39 +02:00
Guillaume Lours
7c999d7f93 improve publish bind mount warning message
Co-authored-by: Nicolas De loof <nicolas.deloof@gmail.com>
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 18:45:30 +02:00
Guillaume Lours
ad750d6143 remove publish limitation on bind mount
list all bind mounts and ask user validation before publishing

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 18:45:30 +02:00
dependabot[bot]
fe382df507 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 28.2.2+incompatible to 28.3.0+incompatible.
- [Commits](https://github.com/docker/cli/compare/v28.2.2...v28.3.0)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.3.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 18:37:19 +02:00
Nicolas De Loof
6501d59efc pass project.environment to bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-30 15:39:55 +02:00
Zhizhen He
33a782572f fix: typos
Signed-off-by: Zhizhen He <hezhizhen.yi@gmail.com>
2025-06-30 14:26:17 +02:00
Guillaume Lours
65803ea12e remove error message from exec outpout by default
Add the error as a log for verbose mode

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 12:50:03 +02:00
Guillaume Lours
f613379373 make sure the post_start hooks fails
before we were assuming the container will be close before the post_start will be executed

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-30 12:37:58 +02:00
Guillaume Lours
3553aa26a6 add a default statut messsage to exec error to avoid empty line display
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-27 20:44:49 +02:00
Nathan Scott
257ea7b75d Swap to Reader in bake to avoid hangs on output
Signed-off-by: Nathan Scott <natedscott@gmail.com>
2025-06-27 16:19:28 +02:00
Guillaume Lours
d219aa66f4 don't fail down cmd if services with pre_stop hook already stopped/removed
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-27 14:41:52 +02:00
Guillaume Lours
c9ebfad78e exclude provider services from the list of dependencies that Compose should wait for
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-26 21:26:33 +02:00
Guillaume Lours
8e57362a0f use errdefs.IsNotImplemented to check if the logging is not implemented
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-26 16:42:57 +02:00
Guillaume Lours
29630f184e check progress default value instead of empty string to use BUILDKIT_PROGRESS env variable value
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-26 16:42:57 +02:00
Nicolas De Loof
6514c680a5 only expose API socket to service asking for it
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-24 17:17:41 +02:00
Nicolas De Loof
3394bf031b propagate target docker host set by --host to Bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-24 15:51:45 +02:00
dependabot[bot]
832a08f579 build(deps): bump github.com/moby/buildkit from 0.23.0 to 0.23.1
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.23.0 to 0.23.1.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.23.0...v0.23.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 15:39:44 +02:00
Nicolas De Loof
aadce87b16 inject secrets/config just before container is started
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-24 12:26:46 +02:00
Nicolas De Loof
b3207c455d setting buildOptions.Services triggers image to be always rebuilt
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-24 11:26:52 +02:00
Guillaume Lours
769b7391ba don't create from run command during dependencies creation process
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-24 11:26:52 +02:00
Guillaume Lours
149b882ebf don't create from run command during dependencies creation process
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-24 11:26:52 +02:00
Sebastiaan van Stijn
c97e40e2b8 pkg/compose: remove uses of ExecOptions.Detach
This field was added in [moby@5130fe5d38837302e], which
added it for use as intermediate struct when parsing CLI flags (through
`runconfig.ParseExec`) in [moby@c786a8ee5e9db8f5f].

Commit [moby@9d9dff3d0d9e92adf] rewrote the CLI to use
Cobra, and as part of this introduced a separate `execOptions` type in
`api/client/container`, however the ExecOptions.Detach field was still
used as intermediate field to store the flag's value.

Given that the client doesn't use this field, let's remove its use to
prevent giving the impression that it's used anywhere.

[moby@5130fe5d38837302e]: 5130fe5d38
[moby@c786a8ee5e9db8f5f]: c786a8ee5e
[moby@9d9dff3d0d9e92adf]: 9d9dff3d0d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-23 21:05:38 +02:00
Nicolas De Loof
22e23bd4dc networkMode
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-22 20:50:35 +02:00
Nicolas De Loof
2dde5faeb8 add support for cache_to with bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-22 07:44:38 +02:00
Nicolas De Loof
f7825a56bf bump buildx to v0.25
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-20 15:16:51 +02:00
Nicolas De Loof
4cf075ea0a bump compose-go to v2.6.5
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-20 15:16:51 +02:00
Nicolas De Loof
4f491ffa98 fix panic using w shortcut on project without watch support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-16 11:15:45 +02:00
Nicolas De Loof
ea1c26d22a restore ContainerName in images --json
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-16 09:42:07 +02:00
Nicolas De Loof
9a5fa05ad6 add (temporary) support for use_api_socket
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-13 14:43:16 +02:00
Nicolas De Loof
276c229458 move run logic inside backend
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-13 14:43:16 +02:00
dependabot[bot]
eef448dc64 build(deps): bump github.com/containerd/containerd/v2
Bumps [github.com/containerd/containerd/v2](https://github.com/containerd/containerd) from 2.1.1 to 2.1.2.
- [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/v2.1.1...v2.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-13 12:07:26 +02:00
dependabot[bot]
343117233b build(deps): bump google.golang.org/grpc from 1.72.2 to 1.73.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.72.2 to 1.73.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.72.2...v1.73.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-12 10:18:57 +02:00
Nicolas De Loof
f599a8cdd2 add support for extra_hosts building with bake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-12 09:52:20 +02:00
Nicolas De Loof
63b06f5563 fix panic on failure starting plugin server
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-12 09:48:07 +02:00
Nicolas De Loof
1d34661e91 fix support for additional_contexts with service sub-dependencies
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-12 09:47:19 +02:00
Jeff Carter
0f9e6ab832 Fix the generated manifest for compose artifacts so that the empty config is not added as a layer.
Signed-off-by: Jeff Carter <jeff.carter@docker.com>
2025-06-11 16:51:51 +02:00
Nicolas De Loof
15c9651a3a restore os.Remove(metadataFile)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-11 16:12:08 +02:00
Nicolas De Loof
4893a8b9ad don't create metadatafile, just generate a random name
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-11 15:56:26 +02:00
Nicolas De Loof
97530790fa only look for required image in bake metadata
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-11 13:46:57 +02:00
Nicolas De Loof
213c03f99a produce bake targets for all services, group for services to build
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-10 09:30:22 +02:00
Nicolas De Loof
ebd7b761f2 sanitize service name so they can be used as bake targets
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-10 09:30:22 +02:00
x0rw
ea48480d80 Restore images format list format behaviour
Signed-off-by: x0rw <mahdi.svt5@gmail.com>
2025-06-07 23:07:49 +02:00
Nicolas De Loof
8151b59288 bump golang.org/x/sync v0.15.0
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-06 16:21:29 +02:00
Guillaume Lours
ec49baca56 do not forgot to remove the bake metadata file
few DD e2e tests failed on Windows due to permission issues

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-06 14:56:40 +02:00
Nicolas De Loof
7b9ad96240 fix SIGSEGV on Enable Watch
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-06 10:07:20 +02:00
Nicolas De Loof
9b67a48c33 (refactoting) Move watch logic into a dedicated Watcher type
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-05 16:48:05 +02:00
Nicolas De Loof
0d0e12cc85 use Bake by default
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-05 16:20:44 +02:00
Guillaume Lours
92fafccfb2 add validation for required parameters of provider service when metadata are available
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-05 15:12:32 +02:00
Guillaume Lours
fee8aee8f0 save provider metadata for Docker LSP
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-05 15:12:32 +02:00
Guillaume Lours
40f5786e68 add support of metadata subcommand for provider services
This command will let Compose and external tooling know about which parameters should be passed to the Compose plugin

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-06-05 15:12:32 +02:00
Nicolas De Loof
61e44da936 debug message to help diagnose platform mismatch
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-05 11:43:13 +02:00
Nicolas De Loof
0bf7d1ea25 pull does not require env_file being resolved
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-05 11:42:35 +02:00
dependabot[bot]
80ace63dfb build(deps): bump google.golang.org/grpc from 1.72.1 to 1.72.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.72.1 to 1.72.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.72.1...v1.72.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-05 11:38:21 +02:00
Nicolas De Loof
27e90a3fdf end-to-end test
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-02 18:57:07 +02:00
Andrii Telesh
3ca75bdf55 Fix the inability to restart the Compose stack after network configuration change
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-02 18:57:07 +02:00
Nicolas De Loof
eb3074bbda include platform and creation date listing image used by running compose application
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-02 16:07:24 +02:00
Nicolas De Loof
f4fc010d6b build dependent service images when required
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-02 12:28:43 +02:00
Nicolas De Loof
693b9ef078 fix support for BUILDKIT_PROGRESS
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-06-02 11:03:04 +02:00
Sebastiaan van Stijn
046879a4a2 replace uses of golang.org/x/exp/(maps|slices) for stdlib
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-02 10:43:17 +02:00
Sebastiaan van Stijn
7c79b23005 pkg/bridge: fix importShadow: shadow of imported package (gocritic)
pkg/bridge/convert.go:114:3: importShadow: shadow of imported package 'user' (gocritic)
            user, err := user.Current()
            ^
    pkg/bridge/convert.go:142:51: importShadow: shadow of imported from 'github.com/docker/cli/cli/command/container' package 'cli' (gocritic)
    func LoadAdditionalResources(ctx context.Context, cli command.Cli, project *types.Project) (*types.Project, error) {
                                                      ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-02 10:43:17 +02:00
Sebastiaan van Stijn
ad4cbee498 bump github.com/docker/docker, docker/cli v28.2.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-06-02 10:39:56 +02:00
Carlos Daniel Vilaseca
60256a875c fix typo in suggestion log
Signed-off-by: Carlos Daniel Vilaseca <carlosd.vilaseca@ai.yareytech.com>
2025-05-31 19:40:32 +02:00
Nicolas De Loof
45bd60c33a resolve symlinks while making dockerfile path absolute
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-05-28 12:12:16 +02:00
Nicolas De Loof
cf89fd1aa1 also (re)start dependent services after watch rebuilt image
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-05-27 16:14:36 +02:00
Nicolas De Loof
23fef850b9 prefer use of slices.DeleteFunc
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-05-27 15:16:50 +02:00
Nicolas De Loof
12b73bea73 remove utils.Contains to prefer slice.ContainsFunc
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2025-05-27 15:16:50 +02:00
tongjicoder
2e71440bee refactor: use slices.Contains to simplify code
Signed-off-by: tongjicoder <tongjicoder@icloud.com>
2025-05-27 11:45:26 +02:00
Guillaume Lours
d49a68ecbf bridge - run transformer container as current user
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-27 10:35:30 +02:00
Guillaume Lours
be83f63f26 add e2e tests for bridge convert and transformers ls commands
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-27 10:35:30 +02:00
Guillaume Lours
9a9227ce64 add new bridge commands documentation
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-27 10:35:30 +02:00
Guillaume Lours
024f8ebdc5 add convert subcommand to bridge command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-27 10:35:30 +02:00
Guillaume Lours
8c622da20b add bridge command and transformations subcommands
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-27 10:35:30 +02:00
Guillaume Lours
bbb2b76a14 bump cli-doc-tools to v0.10.0
and update the documentation to pass CI checks

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2025-05-26 16:37:45 +02:00
257 changed files with 7038 additions and 2696 deletions

View File

@@ -12,6 +12,12 @@ body:
Include both the current behavior (what you are seeing) as well as what you expected to happen.
validations:
required: true
- type: markdown
attributes:
value: |
[Docker Swarm](https://www.mirantis.com/software/swarm/) uses a distinct compose file parser and
as such doesn't support some of the recent features of Docker Compose. Please contact Mirantis
if you need assistance with compose file support in Docker Swarm.
- type: textarea
attributes:
label: Steps To Reproduce

View File

@@ -156,9 +156,8 @@ jobs:
- plugin
- standalone
engine:
- 26
- 27
- 28
- 27 # old stable (latest major - 1)
- 28 # current stable
steps:
- name: Prepare
run: |
@@ -183,6 +182,11 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Docker Model
run: |
sudo apt-get install docker-model-plugin
docker model version
- name: Set up Go
uses: actions/setup-go@v5
with:
@@ -190,6 +194,9 @@ jobs:
check-latest: true
cache: true
- name: Build example provider
run: make example-provider
- name: Build
uses: docker/bake-action@v6
with:

View File

@@ -30,6 +30,12 @@ linters:
deny:
- pkg: io/ioutil
desc: io/ioutil package has been deprecated
- pkg: github.com/docker/docker/errdefs
desc: use github.com/containerd/errdefs instead.
- pkg: golang.org/x/exp/maps
desc: use stdlib maps package
- pkg: golang.org/x/exp/slices
desc: use stdlib slices package
- pkg: gopkg.in/yaml.v2
desc: compose-go uses yaml.v3
gocritic:

View File

@@ -4,12 +4,15 @@
* Windows:
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/windows-install/)
* make
* go (see [go.mod](go.mod) for minimum version)
* macOS:
* [Docker Desktop](https://docs.docker.com/desktop/setup/install/mac-install/)
* make
* go (see [go.mod](go.mod) for minimum version)
* Linux:
* [Docker 20.10 or later](https://docs.docker.com/engine/install/)
* make
* go (see [go.mod](go.mod) for minimum version)
### Building the CLI

View File

@@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GO_VERSION=1.23.8
ARG GO_VERSION=1.24.9
ARG XX_VERSION=1.6.1
ARG GOLANGCI_LINT_VERSION=v2.0.2
ARG ADDLICENSE_VERSION=v1.0.0

View File

@@ -1,124 +0,0 @@
# Docker maintainers file
#
# This file describes who runs the docker/compose project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant
# parser.
#
# This file is compiled into the MAINTAINERS file in docker/opensource.
#
[Org]
[Org."Core maintainers"]
# The Core maintainers are the ghostbusters of the project: when there's a problem others
# can't solve, they show up and fix it with bizarre devices and weaponry.
# They have final say on technical implementation and coding style.
# They are ultimately responsible for quality in all its forms: usability polish,
# bugfixes, performance, stability, etc. When ownership can cleanly be passed to
# a subsystem, they are responsible for doing so and holding the
# subsystem maintainers accountable. If ownership is unclear, they are the de facto owners.
people = [
"glours",
"jhrotko",
"milas",
"ndeloof",
"nicksieger",
"StefanScherer",
"ulyssessouza"
]
[Org."Regular maintainers"]
# The Regular maintainers are people who aren't Core maintainers but are around
# to help reviewing and fixing bugs, just on a less regular basis than previously.
# Most of them were previously Core maintainers of Compose.
people = [
"aiordache",
"chris-crone",
"gtardif",
"laurazard",
"maxcleme",
"rumpl",
"thaJeztah"
]
[people]
# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
[people.aiordache]
Name = "Anca Iordache"
Email = "anca.iordache@docker.com"
GitHub = "aiordache "
[people.chris-crone]
Name = "Christopher Crone"
Email = "christopher.crone@docker.com"
GitHub = "chris-crone"
[people.glours]
Name = "Guillaume Lours"
Email = "guillaume.lours@docker.com"
GitHub = "glours"
[people.gtardif]
Name = "Guillaume Tardif"
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"
GitHub = "laurazard"
[people.maxcleme]
Name = "Maxime Clement"
Email = "maxime.clement@docker.com"
GitHub = "maxcleme"
[people.milas]
Name = "Milas Bowman"
Email = "milas.bowman@docker.com"
GitHub = "milas"
[people.nicksieger]
Name = "Nick Sieger"
Email = "nick.sieger@docker.com"
GitHub = "nicksieger"
[people.ndeloof]
Name = "Nicolas Deloof"
Email = "nicolas.deloof@docker.com"
GitHub = "ndeloof"
[people.rumpl]
Name = "Djordje Lukic"
Email = "djordje.lukic@docker.com"
GitHub = "rumpl"
[people.thaJeztah]
Name = "Sebastiaan van Stijn"
Email = "sebastiaan.vanstijn@docker.com"
GitHub = "thaJeztah "
[people.StefanScherer]
Name = "Stefan Scherer"
Email = "stefan.scherer@docker.com"
GitHub = "StefanScherer"
[people.ulyssessouza]
Name = "Ulysses Souza"
Email = "<ulysses.souza@docker.com"
Github = "ulyssessouza"

View File

@@ -74,7 +74,7 @@ install: binary
install $(or $(DESTDIR),./bin/build)/docker-compose ~/.docker/cli-plugins/docker-compose
.PHONY: e2e-compose
e2e-compose: ## Run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
e2e-compose: example-provider ## Run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
go run gotest.tools/gotestsum@latest --format testname --junitfile "/tmp/report/report.xml" -- -v $(TEST_FLAGS) -count=1 ./pkg/e2e
.PHONY: e2e-compose-standalone
@@ -87,6 +87,10 @@ build-and-e2e-compose: build e2e-compose ## Compile the compose cli-plugin and r
.PHONY: build-and-e2e-compose-standalone
build-and-e2e-compose-standalone: build e2e-compose-standalone ## Compile the compose cli-plugin and run End to end local tests in standalone mode. Set E2E_TEST=TestName to run a single test
.PHONY: example-provider
example-provider: ## build example provider for e2e tests
go build -o bin/build/example-provider docs/examples/provider.go
.PHONY: mocks
mocks:
mockgen --version >/dev/null 2>&1 || go install go.uber.org/mock/mockgen@v0.4.0

View File

@@ -23,6 +23,12 @@ your application are configured.
Once you have a Compose file, you can create and start your application with a
single command: `docker compose up`.
> **Note**: About Docker Swarm
> Docker Swarm used to rely on the legacy compose file format but did not adopted the compose specification
> so is missing some of the recent enhancements in the compose syntax. After
> [acquisition by Mirantis](https://www.mirantis.com/software/swarm/) swarm isn't maintained by Docker Inc, and
> as such some Docker Compose features aren't accessible to swarm users.
# Where to get Docker Compose
### Windows and macOS

View File

@@ -55,8 +55,10 @@ func Setup(cmd *cobra.Command, dockerCli command.Cli, args []string) error {
ctx,
"cli/"+strings.Join(commandName(cmd), "-"),
)
cmdSpan.SetAttributes(attribute.StringSlice("cli.flags", getFlags(cmd.Flags())))
cmdSpan.SetAttributes(attribute.Bool("cli.isatty", dockerCli.In().IsTerminal()))
cmdSpan.SetAttributes(
attribute.StringSlice("cli.flags", getFlags(cmd.Flags())),
attribute.Bool("cli.isatty", dockerCli.In().IsTerminal()),
)
cmd.SetContext(ctx)
wrapRunE(cmd, cmdSpan, tracingShutdown)

View File

@@ -21,7 +21,7 @@ import (
)
// alphaCommand groups all experimental subcommands
func alphaCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func alphaCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
cmd := &cobra.Command{
Short: "Experimental commands",
Use: "alpha [COMMAND]",

View File

@@ -35,7 +35,7 @@ type attachOpts struct {
proxy bool
}
func attachCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func attachCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := attachOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -63,7 +63,7 @@ func attachCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
return runCmd
}
func runAttach(ctx context.Context, dockerCli command.Cli, backend api.Service, opts attachOpts) error {
func runAttach(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts attachOpts) error {
projectName, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err

149
cmd/compose/bridge.go Normal file
View File

@@ -0,0 +1,149 @@
/*
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"
"github.com/distribution/reference"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/bridge"
)
func bridgeCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "bridge CMD [OPTIONS]",
Short: "Convert compose files into another model",
TraverseChildren: true,
}
cmd.AddCommand(
convertCommand(p, dockerCli),
transformersCommand(dockerCli),
)
return cmd
}
func convertCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
convertOpts := bridge.ConvertOptions{}
cmd := &cobra.Command{
Use: "convert",
Short: "Convert compose files to Kubernetes manifests, Helm charts, or another model",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runConvert(ctx, dockerCli, p, convertOpts)
}),
}
flags := cmd.Flags()
flags.StringVarP(&convertOpts.Output, "output", "o", "out", "The output directory for the Kubernetes resources")
flags.StringArrayVarP(&convertOpts.Transformations, "transformation", "t", nil, "Transformation to apply to compose model (default: docker/compose-bridge-kubernetes)")
flags.StringVar(&convertOpts.Templates, "templates", "", "Directory containing transformation templates")
return cmd
}
func runConvert(ctx context.Context, dockerCli command.Cli, p *ProjectOptions, opts bridge.ConvertOptions) error {
project, _, err := p.ToProject(ctx, dockerCli, nil)
if err != nil {
return err
}
return bridge.Convert(ctx, dockerCli, project, opts)
}
func transformersCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "transformations CMD [OPTIONS]",
Short: "Manage transformation images",
}
cmd.AddCommand(
listTransformersCommand(dockerCli),
createTransformerCommand(dockerCli),
)
return cmd
}
func listTransformersCommand(dockerCli command.Cli) *cobra.Command {
options := lsOptions{}
cmd := &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Short: "List available transformations",
RunE: Adapt(func(ctx context.Context, args []string) error {
transformers, err := bridge.ListTransformers(ctx, dockerCli)
if err != nil {
return err
}
return displayTransformer(dockerCli, transformers, options)
}),
}
cmd.Flags().StringVar(&options.Format, "format", "table", "Format the output. Values: [table | json]")
cmd.Flags().BoolVarP(&options.Quiet, "quiet", "q", false, "Only display transformer names")
return cmd
}
func displayTransformer(dockerCli command.Cli, transformers []image.Summary, options lsOptions) error {
if options.Quiet {
for _, t := range transformers {
if len(t.RepoTags) > 0 {
_, _ = fmt.Fprintln(dockerCli.Out(), t.RepoTags[0])
} else {
_, _ = fmt.Fprintln(dockerCli.Out(), t.ID)
}
}
return nil
}
return formatter.Print(transformers, options.Format, dockerCli.Out(),
func(w io.Writer) {
for _, img := range transformers {
id := stringid.TruncateID(img.ID)
size := units.HumanSizeWithPrecision(float64(img.Size), 3)
repo, tag := "<none>", "<none>"
if len(img.RepoTags) > 0 {
ref, err := reference.ParseDockerRef(img.RepoTags[0])
if err == nil {
// ParseDockerRef will reject a local image ID
repo = reference.FamiliarName(ref)
if tagged, ok := ref.(reference.Tagged); ok {
tag = tagged.Tag()
}
}
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", id, repo, tag, size)
}
},
"IMAGE ID", "REPO", "TAGS", "SIZE")
}
func createTransformerCommand(dockerCli command.Cli) *cobra.Command {
var opts bridge.CreateTransformerOptions
cmd := &cobra.Command{
Use: "create [OPTION] PATH",
Short: "Create a new transformation",
RunE: Adapt(func(ctx context.Context, args []string) error {
opts.Dest = args[0]
return bridge.CreateTransformer(ctx, dockerCli, opts)
}),
}
cmd.Flags().StringVarP(&opts.From, "from", "f", "", "Existing transformation to copy (default: docker/compose-bridge-kubernetes)")
return cmd
}

View File

@@ -27,7 +27,6 @@ import (
"github.com/docker/cli/cli/command"
cliopts "github.com/docker/cli/opts"
ui "github.com/docker/compose/v2/pkg/progress"
buildkit "github.com/moby/buildkit/util/progress/progressui"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -46,7 +45,8 @@ type buildOptions struct {
deps bool
print bool
check bool
provenance bool
sbom string
provenance string
}
func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions, error) {
@@ -85,11 +85,12 @@ func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions,
Check: opts.check,
SSHs: SSHKeys,
Builder: builderName,
SBOM: opts.sbom,
Provenance: opts.provenance,
}, nil
}
func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := buildOptions{
ProjectOptions: p,
}
@@ -120,12 +121,14 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
}
flags := cmd.Flags()
flags.BoolVar(&opts.push, "push", false, "Push service images")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress the build output")
flags.BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image")
flags.StringArrayVar(&opts.args, "build-arg", []string{}, "Set build-time variables for services")
flags.StringVar(&opts.ssh, "ssh", "", "Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent)")
flags.StringVar(&opts.builder, "builder", "", "Set builder to use")
flags.BoolVar(&opts.deps, "with-dependencies", false, "Also build dependencies (transitively)")
flags.StringVar(&opts.provenance, "provenance", "", `Add a provenance attestation`)
flags.StringVar(&opts.sbom, "sbom", "", `Add a SBOM attestation`)
flags.Bool("parallel", true, "Build images in parallel. DEPRECATED")
flags.MarkHidden("parallel") //nolint:errcheck
@@ -137,7 +140,7 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
flags.Bool("no-rm", false, "Do not remove intermediate containers after a successful build. DEPRECATED")
flags.MarkHidden("no-rm") //nolint:errcheck
flags.VarP(&opts.memory, "memory", "m", "Set memory limit for the build container. Not supported by BuildKit.")
flags.StringVar(&p.Progress, "progress", string(buildkit.AutoMode), fmt.Sprintf(`Set type of ui output (%s)`, strings.Join(printerModes, ", ")))
flags.StringVar(&p.Progress, "progress", "", fmt.Sprintf(`Set type of ui output (%s)`, strings.Join(printerModes, ", ")))
flags.MarkHidden("progress") //nolint:errcheck
flags.BoolVar(&opts.print, "print", false, "Print equivalent bake file")
flags.BoolVar(&opts.check, "check", false, "Check build configuration")
@@ -145,7 +148,8 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, opts buildOptions, services []string) error {
func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts buildOptions, services []string) error {
opts.All = true // do not drop resources as build may involve some dependencies by additional_contexts
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
if err != nil {
return err
@@ -156,10 +160,10 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o
}
apiBuildOptions, err := opts.toAPIBuildOptions(services)
apiBuildOptions.Provenance = true
if err != nil {
return err
}
apiBuildOptions.Attestations = true
return backend.Build(ctx, project, apiBuildOptions)
}

View File

@@ -39,7 +39,7 @@ type commitOptions struct {
index int
}
func commitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func commitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
options := commitOptions{
ProjectOptions: p,
}
@@ -73,13 +73,13 @@ func commitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
return cmd
}
func runCommit(ctx context.Context, dockerCli command.Cli, backend api.Service, options commitOptions) error {
func runCommit(ctx context.Context, dockerCli command.Cli, backend api.Compose, options commitOptions) error {
projectName, err := options.toProjectName(ctx, dockerCli)
if err != nil {
return err
}
commitOptions := api.CommitOptions{
return backend.Commit(ctx, projectName, api.CommitOptions{
Service: options.service,
Reference: options.reference,
Pause: options.pause,
@@ -87,7 +87,5 @@ func runCommit(ctx context.Context, dockerCli command.Cli, backend api.Service,
Author: options.author,
Changes: options.changes,
Index: options.index,
}
return backend.Commit(ctx, projectName, commitOptions)
})
}

View File

@@ -52,7 +52,7 @@ func completeServiceNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn
}
}
func completeProjectNames(backend api.Service) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
func completeProjectNames(backend api.Compose) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, err := backend.List(cmd.Context(), api.ListOptions{
All: true,

View File

@@ -36,18 +36,15 @@ import (
composegoutils "github.com/compose-spec/compose-go/v2/utils"
"github.com/docker/buildx/util/logutil"
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/metadata"
"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"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/remote"
"github.com/docker/compose/v2/pkg/utils"
buildkit "github.com/moby/buildkit/util/progress/progressui"
"github.com/morikuni/aec"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -92,14 +89,6 @@ func init() {
dotenv.RegisterFormat("raw", rawEnv)
}
type Backend interface {
api.Service
SetDesktopClient(cli *desktop.Client)
SetExperiments(experiments *experimental.State)
}
// Command defines a compose CLI command as a func with args
type Command func(context.Context, []string) error
@@ -230,7 +219,7 @@ func (o *ProjectOptions) addProjectFlags(f *pflag.FlagSet) {
f.StringVar(&o.ProjectDir, "project-directory", "", "Specify an alternate working directory\n(default: the path of the, first specified, Compose file)")
f.StringVar(&o.WorkDir, "workdir", "", "DEPRECATED! USE --project-directory INSTEAD.\nSpecify an alternate working directory\n(default: the path of the, first specified, Compose file)")
f.BoolVar(&o.Compatibility, "compatibility", false, "Run compose in backward compatibility mode")
f.StringVar(&o.Progress, "progress", defaultStringVar(ComposeProgress, string(buildkit.AutoMode)), fmt.Sprintf(`Set type of progress output (%s)`, strings.Join(printerModes, ", ")))
f.StringVar(&o.Progress, "progress", os.Getenv(ComposeProgress), fmt.Sprintf(`Set type of progress output (%s)`, strings.Join(printerModes, ", ")))
f.BoolVar(&o.All, "all-resources", false, "Include all resources, even those not used by services")
_ = f.MarkHidden("workdir")
}
@@ -242,19 +231,11 @@ func defaultStringArrayVar(env string) []string {
})
}
// get default value for a command line flag from the env variable, if the env variable is not set, it returns the provided default value 'def'
func defaultStringVar(env, def string) string {
if v, ok := os.LookupEnv(env); ok {
return v
}
return def
}
func (o *ProjectOptions) projectOrName(ctx context.Context, dockerCli command.Cli, services ...string) (*types.Project, string, error) {
name := o.ProjectName
var project *types.Project
if len(o.ConfigPaths) > 0 || o.ProjectName == "" {
p, _, err := o.ToProject(ctx, dockerCli, services, cli.WithDiscardEnvFile)
p, _, err := o.ToProject(ctx, dockerCli, services, cli.WithDiscardEnvFile, cli.WithoutEnvironmentResolution)
if err != nil {
envProjectName := os.Getenv(ComposeProjectName)
if envProjectName != "" {
@@ -392,32 +373,38 @@ func (o *ProjectOptions) remoteLoaders(dockerCli command.Cli) []loader.ResourceL
}
func (o *ProjectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.ProjectOptions, error) {
pwd, err := os.Getwd()
if err != nil {
return nil, err
opts := []cli.ProjectOptionsFn{
cli.WithWorkingDirectory(o.ProjectDir),
// First apply os.Environment, always win
cli.WithOsEnv,
}
return cli.NewProjectOptions(o.ConfigPaths,
append(po,
cli.WithWorkingDirectory(o.ProjectDir),
// First apply os.Environment, always win
cli.WithOsEnv,
// set PWD as this variable is not consistently supported on Windows
cli.WithEnv([]string{"PWD=" + pwd}),
// Load PWD/.env if present and no explicit --env-file has been set
cli.WithEnvFiles(o.EnvFiles...),
// read dot env file to populate project environment
cli.WithDotEnv,
// get compose file path set by COMPOSE_FILE
cli.WithConfigFileEnv,
// if none was selected, get default compose.yaml file from current dir or parent folder
cli.WithDefaultConfigPath,
// .. and then, a project directory != PWD maybe has been set so let's load .env file
cli.WithEnvFiles(o.EnvFiles...),
cli.WithDotEnv,
// eventually COMPOSE_PROFILES should have been set
cli.WithDefaultProfiles(o.Profiles...),
cli.WithName(o.ProjectName))...)
if _, present := os.LookupEnv("PWD"); !present {
if pwd, err := os.Getwd(); err != nil {
return nil, err
} else {
opts = append(opts, cli.WithEnv([]string{"PWD=" + pwd}))
}
}
opts = append(opts,
// Load PWD/.env if present and no explicit --env-file has been set
cli.WithEnvFiles(o.EnvFiles...),
// read dot env file to populate project environment
cli.WithDotEnv,
// get compose file path set by COMPOSE_FILE
cli.WithConfigFileEnv,
// if none was selected, get default compose.yaml file from current dir or parent folder
cli.WithDefaultConfigPath,
// .. and then, a project directory != PWD maybe has been set so let's load .env file
cli.WithEnvFiles(o.EnvFiles...),
cli.WithDotEnv,
// eventually COMPOSE_PROFILES should have been set
cli.WithDefaultProfiles(o.Profiles...),
cli.WithName(o.ProjectName),
)
return cli.NewProjectOptions(o.ConfigPaths, append(po, opts...)...)
}
// PluginName is the name of the plugin
@@ -425,11 +412,11 @@ const PluginName = "compose"
// RunningAsStandalone detects when running as a standalone program
func RunningAsStandalone() bool {
return len(os.Args) < 2 || os.Args[1] != manager.MetadataSubcommandName && os.Args[1] != PluginName
return len(os.Args) < 2 || os.Args[1] != metadata.MetadataSubcommandName && os.Args[1] != PluginName
}
// RootCommand returns the compose command with its child commands
func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //nolint:gocyclo
func RootCommand(dockerCli command.Cli, backend api.Compose) *cobra.Command { //nolint:gocyclo
// filter out useless commandConn.CloseWrite warning message that can occur
// when using a remote context that is unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
// https://github.com/docker/cli/blob/e1f24d3c93df6752d3c27c8d61d18260f141310c/cli/connhelper/commandconn/commandconn.go#L203-L215
@@ -440,7 +427,6 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
"commandConn.CloseRead:",
))
experiments := experimental.NewState()
opts := ProjectOptions{}
var (
ansi string
@@ -516,8 +502,7 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
}
switch opts.Progress {
case ui.ModeAuto:
ui.Mode = ui.ModeAuto
case "", ui.ModeAuto:
if ansi == "never" {
ui.Mode = ui.ModePlain
}
@@ -585,27 +570,6 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
}
cmd.SetContext(ctx)
// (6) Desktop integration
var desktopCli *desktop.Client
if !dryRun {
if desktopCli, err = desktop.NewFromDockerClient(ctx, dockerCli); desktopCli != nil {
logrus.Debugf("Enabled Docker Desktop integration (experimental) @ %s", desktopCli.Endpoint())
backend.SetDesktopClient(desktopCli)
} else if err != nil {
// not fatal, Compose will still work but behave as though
// it's not running as part of Docker Desktop
logrus.Debugf("failed to enable Docker Desktop integration: %v", err)
} else {
logrus.Trace("Docker Desktop integration not enabled")
}
}
// (7) experimental features
if err := experiments.Load(ctx, desktopCli); err != nil {
logrus.Debugf("Failed to query feature flags from Desktop: %v", err)
}
backend.SetExperiments(experiments)
return nil
},
}
@@ -645,6 +609,8 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
watchCommand(&opts, dockerCli, backend),
publishCommand(&opts, dockerCli, backend),
alphaCommand(&opts, dockerCli, backend),
bridgeCommand(&opts, dockerCli),
volumesCommand(&opts, dockerCli, backend),
)
c.Flags().SetInterspersed(false)
@@ -669,6 +635,10 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
"profile",
completeProfileNames(dockerCli, &opts),
)
c.RegisterFlagCompletionFunc( //nolint:errcheck
"progress",
cobra.FixedCompletions(printerModes, cobra.ShellCompDirectiveNoFileComp),
)
c.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`)
c.Flags().IntVar(&parallel, "parallel", -1, `Control max parallelism, -1 for unlimited`)
@@ -697,7 +667,7 @@ func setEnvWithDotEnv(opts ProjectOptions) error {
return nil
}
for k, v := range envFromFile {
if _, ok := os.LookupEnv(k); !ok {
if _, ok := os.LookupEnv(k); !ok && strings.HasPrefix(k, "COMPOSE_") {
if err = os.Setenv(k, v); err != nil {
return nil
}
@@ -713,15 +683,3 @@ var printerModes = []string{
ui.ModeJSON,
ui.ModeQuiet,
}
func SetUnchangedOption(name string, experimentalFlag bool) bool {
var value bool
// If the var is defined we use that value first
if envVar, ok := os.LookupEnv(name); ok {
value = utils.StringToBool(envVar)
} else {
// if not, we try to get it from experimental feature flag
value = experimentalFlag
}
return value
}

View File

@@ -50,6 +50,8 @@ type configOptions struct {
noResolveEnv bool
services bool
volumes bool
networks bool
models bool
profiles bool
images bool
hash string
@@ -111,6 +113,12 @@ func configCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
if opts.volumes {
return runVolumes(ctx, dockerCli, opts)
}
if opts.networks {
return runNetworks(ctx, dockerCli, opts)
}
if opts.models {
return runModels(ctx, dockerCli, opts)
}
if opts.hash != "" {
return runHash(ctx, dockerCli, opts)
}
@@ -147,6 +155,8 @@ func configCommand(p *ProjectOptions, dockerCli command.Cli) *cobra.Command {
flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
flags.BoolVar(&opts.volumes, "volumes", false, "Print the volume names, one per line.")
flags.BoolVar(&opts.networks, "networks", false, "Print the network names, one per line.")
flags.BoolVar(&opts.models, "models", false, "Print the model names, one per line.")
flags.BoolVar(&opts.profiles, "profiles", false, "Print the profile names, one per line.")
flags.BoolVar(&opts.images, "images", false, "Print the image names, one per line.")
flags.StringVar(&opts.hash, "hash", "", "Print the service config hash, one per line.")
@@ -367,6 +377,30 @@ func runVolumes(ctx context.Context, dockerCli command.Cli, opts configOptions)
return nil
}
func runNetworks(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
for n := range project.Networks {
_, _ = fmt.Fprintln(dockerCli.Out(), n)
}
return nil
}
func runModels(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
for _, model := range project.Models {
if model.Model != "" {
_, _ = fmt.Fprintln(dockerCli.Out(), model.Model)
}
}
return nil
}
func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
var services []string
if opts.hash != "*" {

View File

@@ -38,7 +38,7 @@ type copyOptions struct {
copyUIDGID bool
}
func copyCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func copyCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := copyOptions{
ProjectOptions: p,
}
@@ -73,7 +73,7 @@ func copyCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return copyCmd
}
func runCopy(ctx context.Context, dockerCli command.Cli, backend api.Service, opts copyOptions) error {
func runCopy(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts copyOptions) error {
name, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err

View File

@@ -51,7 +51,7 @@ type createOptions struct {
AssumeYes bool
}
func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := createOptions{}
buildOpts := buildOptions{
ProjectOptions: p,
@@ -95,7 +95,7 @@ func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
return cmd
}
func runCreate(ctx context.Context, _ command.Cli, backend api.Service, createOpts createOptions, buildOpts buildOptions, project *types.Project, services []string) error {
func runCreate(ctx context.Context, _ command.Cli, backend api.Compose, createOpts createOptions, buildOpts buildOptions, project *types.Project, services []string) error {
if err := createOpts.Apply(project); err != nil {
return err
}

View File

@@ -40,7 +40,7 @@ type downOptions struct {
images string
}
func downCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func downCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := downOptions{
ProjectOptions: p,
}
@@ -77,7 +77,7 @@ func downCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return downCmd
}
func runDown(ctx context.Context, dockerCli command.Cli, backend api.Service, opts downOptions, services []string) error {
func runDown(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts downOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -29,10 +29,12 @@ import (
type eventsOpts struct {
*composeOptions
json bool
json bool
since string
until string
}
func eventsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func eventsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := eventsOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -48,10 +50,12 @@ func eventsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
}
cmd.Flags().BoolVar(&opts.json, "json", false, "Output events as a stream of json objects")
cmd.Flags().StringVar(&opts.since, "since", "", "Show all events created since timestamp")
cmd.Flags().StringVar(&opts.until, "until", "", "Stream events until this timestamp")
return cmd
}
func runEvents(ctx context.Context, dockerCli command.Cli, backend api.Service, opts eventsOpts, services []string) error {
func runEvents(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts eventsOpts, services []string) error {
name, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err
@@ -59,6 +63,8 @@ func runEvents(ctx context.Context, dockerCli command.Cli, backend api.Service,
return backend.Events(ctx, name, api.EventsOptions{
Services: services,
Since: opts.since,
Until: opts.until,
Consumer: func(event api.Event) error {
if opts.json {
marshal, err := json.Marshal(map[string]interface{}{

View File

@@ -18,13 +18,18 @@ package compose
import (
"context"
"errors"
"fmt"
"os"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type execOpts struct {
@@ -43,7 +48,7 @@ type execOpts struct {
interactive bool
}
func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := execOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -59,7 +64,15 @@ func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runExec(ctx, dockerCli, backend, opts)
err := runExec(ctx, dockerCli, backend, opts)
if err != nil {
logrus.Debugf("%v", err)
var cliError cli.StatusError
if ok := errors.As(err, &cliError); ok {
os.Exit(err.(cli.StatusError).StatusCode) //nolint: errorlint
}
}
return err
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
@@ -69,7 +82,7 @@ func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
runCmd.Flags().IntVar(&opts.index, "index", 0, "Index of the container if service has multiple replicas")
runCmd.Flags().BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the process")
runCmd.Flags().StringVarP(&opts.user, "user", "u", "", "Run the command as this user")
runCmd.Flags().BoolVarP(&opts.noTty, "no-TTY", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")
runCmd.Flags().BoolVarP(&opts.noTty, "no-tty", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")
runCmd.Flags().StringVarP(&opts.workingDir, "workdir", "w", "", "Path to workdir directory for this command")
runCmd.Flags().BoolVarP(&opts.interactive, "interactive", "i", true, "Keep STDIN open even if not attached")
@@ -78,10 +91,16 @@ func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
runCmd.Flags().MarkHidden("tty") //nolint:errcheck
runCmd.Flags().SetInterspersed(false)
runCmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
if name == "no-TTY" { // legacy
name = "no-tty"
}
return pflag.NormalizedName(name)
})
return runCmd
}
func runExec(ctx context.Context, dockerCli command.Cli, backend api.Service, opts execOpts) error {
func runExec(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts execOpts) error {
projectName, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err
@@ -109,8 +128,8 @@ func runExec(ctx context.Context, dockerCli command.Cli, backend api.Service, op
exitCode, err := backend.Exec(ctx, projectName, execOpts)
if exitCode != 0 {
errMsg := ""
if err != nil {
errMsg := fmt.Sprintf("exit status %d", exitCode)
if err != nil && err.Error() != "" {
errMsg = err.Error()
}
return cli.StatusError{StatusCode: exitCode, Status: errMsg}

View File

@@ -33,7 +33,7 @@ type exportOptions struct {
index int
}
func exportCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func exportCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
options := exportOptions{
ProjectOptions: p,
}
@@ -58,7 +58,7 @@ func exportCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
return cmd
}
func runExport(ctx context.Context, dockerCli command.Cli, backend api.Service, options exportOptions) error {
func runExport(ctx context.Context, dockerCli command.Cli, backend api.Compose, options exportOptions) error {
projectName, err := options.toProjectName(ctx, dockerCli)
if err != nil {
return err

View File

@@ -30,7 +30,7 @@ type generateOptions struct {
Format string
}
func generateCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func generateCommand(p *ProjectOptions, backend api.Compose) *cobra.Command {
opts := generateOptions{
ProjectOptions: p,
}
@@ -52,7 +52,7 @@ func generateCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return cmd
}
func runGenerate(ctx context.Context, backend api.Service, opts generateOptions, containers []string) error {
func runGenerate(ctx context.Context, backend api.Compose, 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")

View File

@@ -20,9 +20,12 @@ import (
"context"
"fmt"
"io"
"sort"
"maps"
"slices"
"strings"
"time"
"github.com/containerd/platforms"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
@@ -30,7 +33,6 @@ import (
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
)
type imageOptions struct {
@@ -39,7 +41,7 @@ type imageOptions struct {
Format string
}
func imagesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func imagesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := imageOptions{
ProjectOptions: p,
}
@@ -56,7 +58,7 @@ func imagesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
return imgCmd
}
func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service, opts imageOptions, services []string) error {
func runImages(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts imageOptions, services []string) error {
projectName, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err
@@ -76,7 +78,7 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
if i := strings.IndexRune(img.ID, ':'); i >= 0 {
id = id[i+1:]
}
if !utils.StringContains(ids, id) {
if !slices.Contains(ids, id) {
ids = append(ids, id)
}
}
@@ -85,14 +87,46 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
}
return nil
}
if opts.Format == "json" {
sort.Slice(images, func(i, j int) bool {
return images[i].ContainerName < images[j].ContainerName
})
type img struct {
ID string `json:"ID"`
ContainerName string `json:"ContainerName"`
Repository string `json:"Repository"`
Tag string `json:"Tag"`
Platform string `json:"Platform"`
Size int64 `json:"Size"`
LastTagTime time.Time `json:"LastTagTime"`
}
// Convert map to slice
var imageList []img
for ctr, i := range images {
lastTagTime := i.LastTagTime
if lastTagTime.IsZero() {
lastTagTime = i.Created
}
imageList = append(imageList, img{
ContainerName: ctr,
ID: i.ID,
Repository: i.Repository,
Tag: i.Tag,
Platform: platforms.Format(i.Platform),
Size: i.Size,
LastTagTime: lastTagTime,
})
}
json, err := formatter.ToJSON(imageList, "", "")
if err != nil {
return err
}
_, err = fmt.Fprintln(dockerCli.Out(), json)
return err
}
return formatter.Print(images, opts.Format, dockerCli.Out(),
func(w io.Writer) {
for _, img := range images {
for _, container := range slices.Sorted(maps.Keys(images)) {
img := images[container]
id := stringid.TruncateID(img.ID)
size := units.HumanSizeWithPrecision(float64(img.Size), 3)
repo := img.Repository
@@ -103,8 +137,10 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
if tag == "" {
tag = "<none>"
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", img.ContainerName, repo, tag, id, size)
created := units.HumanDuration(time.Now().UTC().Sub(img.LastTagTime)) + " ago"
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
container, repo, tag, platforms.Format(img.Platform), id, size, created)
}
},
"CONTAINER", "REPOSITORY", "TAG", "IMAGE ID", "SIZE")
"CONTAINER", "REPOSITORY", "TAG", "PLATFORM", "IMAGE ID", "SIZE", "CREATED")
}

View File

@@ -33,7 +33,7 @@ type killOptions struct {
signal string
}
func killCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func killCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := killOptions{
ProjectOptions: p,
}
@@ -54,7 +54,7 @@ func killCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runKill(ctx context.Context, dockerCli command.Cli, backend api.Service, opts killOptions, services []string) error {
func runKill(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts killOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -38,7 +38,7 @@ type lsOptions struct {
Filter opts.FilterOpt
}
func listCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {
func listCommand(dockerCli command.Cli, backend api.Compose) *cobra.Command {
lsOpts := lsOptions{Filter: opts.NewFilterOpt()}
lsCmd := &cobra.Command{
Use: "ls [OPTIONS]",
@@ -61,7 +61,7 @@ var acceptedListFilters = map[string]bool{
"name": true,
}
func runList(ctx context.Context, dockerCli command.Cli, backend api.Service, lsOpts lsOptions) error {
func runList(ctx context.Context, dockerCli command.Cli, backend api.Compose, lsOpts lsOptions) error {
filters := lsOpts.Filter.Value()
err := filters.Validate(acceptedListFilters)
if err != nil {

View File

@@ -40,7 +40,7 @@ type logsOptions struct {
timestamps bool
}
func logsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func logsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := logsOptions{
ProjectOptions: p,
}
@@ -70,7 +70,7 @@ func logsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return logsCmd
}
func runLogs(ctx context.Context, dockerCli command.Cli, backend api.Service, opts logsOptions, services []string) error {
func runLogs(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts logsOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -21,6 +21,7 @@ import (
"fmt"
"io"
"os"
"slices"
"sort"
"strings"
"text/tabwriter"
@@ -29,10 +30,9 @@ import (
"github.com/compose-spec/compose-go/v2/template"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/prompt"
"github.com/docker/compose/v2/internal/tracing"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/prompt"
"github.com/docker/compose/v2/pkg/utils"
)
func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
@@ -44,7 +44,7 @@ func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
// default platform only applies if the service doesn't specify
if defaultPlatform != "" && service.Platform == "" {
if len(service.Build.Platforms) > 0 && !utils.StringContains(service.Build.Platforms, defaultPlatform) {
if len(service.Build.Platforms) > 0 && !slices.Contains(service.Build.Platforms, defaultPlatform) {
return fmt.Errorf("service %q build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: %s", name, defaultPlatform)
}
service.Platform = defaultPlatform
@@ -52,7 +52,7 @@ func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
if service.Platform != "" {
if len(service.Build.Platforms) > 0 {
if !utils.StringContains(service.Build.Platforms, service.Platform) {
if !slices.Contains(service.Build.Platforms, service.Platform) {
return fmt.Errorf("service %q build configuration does not support platform: %s", name, service.Platform)
}
}

View File

@@ -29,7 +29,7 @@ type pauseOptions struct {
*ProjectOptions
}
func pauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func pauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := pauseOptions{
ProjectOptions: p,
}
@@ -44,7 +44,7 @@ func pauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runPause(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pauseOptions, services []string) error {
func runPause(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts pauseOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err
@@ -60,7 +60,7 @@ type unpauseOptions struct {
*ProjectOptions
}
func unpauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func unpauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := unpauseOptions{
ProjectOptions: p,
}
@@ -75,7 +75,7 @@ func unpauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
return cmd
}
func runUnPause(ctx context.Context, dockerCli command.Cli, backend api.Service, opts unpauseOptions, services []string) error {
func runUnPause(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts unpauseOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -35,7 +35,7 @@ type portOptions struct {
index int
}
func portCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func portCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := portOptions{
ProjectOptions: p,
}
@@ -62,7 +62,7 @@ func portCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runPort(ctx context.Context, dockerCli command.Cli, backend api.Service, opts portOptions, service string) error {
func runPort(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts portOptions, service string) error {
projectName, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err

View File

@@ -20,12 +20,12 @@ import (
"context"
"errors"
"fmt"
"slices"
"sort"
"strings"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/cli/cli/command"
cliformatter "github.com/docker/cli/cli/command/formatter"
@@ -64,7 +64,7 @@ func (p *psOptions) parseFilter() error {
return nil
}
func psCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func psCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := psOptions{
ProjectOptions: p,
}
@@ -91,7 +91,7 @@ func psCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *c
return psCmd
}
func runPs(ctx context.Context, dockerCli command.Cli, backend api.Service, services []string, opts psOptions) error {
func runPs(ctx context.Context, dockerCli command.Cli, backend api.Compose, services []string, opts psOptions) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err
@@ -101,7 +101,7 @@ func runPs(ctx context.Context, dockerCli command.Cli, backend api.Service, serv
names := project.ServiceNames()
if len(services) > 0 {
for _, service := range services {
if !utils.StringContains(names, service) {
if !slices.Contains(names, service) {
return fmt.Errorf("no such service: %s", service)
}
}
@@ -139,7 +139,7 @@ func runPs(ctx context.Context, dockerCli command.Cli, backend api.Service, serv
services := []string{}
for _, c := range containers {
s := c.Service
if !utils.StringContains(services, s) {
if !slices.Contains(services, s) {
services = append(services, s)
}
}

View File

@@ -34,9 +34,10 @@ type publishOptions struct {
ociVersion string
withEnvironment bool
assumeYes bool
app bool
}
func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := publishOptions{
ProjectOptions: p,
}
@@ -53,6 +54,7 @@ func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
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, "yes", "y", false, `Assume "yes" as answer to all prompts`)
flags.BoolVar(&opts.app, "app", false, "Published compose application (includes referenced images)")
flags.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
// assumeYes was introduced by mistake as `--y`
if name == "y" {
@@ -65,7 +67,7 @@ func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
return cmd
}
func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Service, opts publishOptions, repository string) error {
func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts publishOptions, repository string) error {
project, metrics, err := opts.ToProject(ctx, dockerCli, nil)
if err != nil {
return err
@@ -76,7 +78,8 @@ func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Service,
}
return backend.Publish(ctx, project, repository, api.PublishOptions{
ResolveImageDigests: opts.resolveImageDigests,
ResolveImageDigests: opts.resolveImageDigests || opts.app,
Application: opts.app,
OCIVersion: api.OCIVersion(opts.ociVersion),
WithEnvironment: opts.withEnvironment,
AssumeYes: opts.assumeYes,

View File

@@ -21,6 +21,7 @@ import (
"fmt"
"os"
"github.com/compose-spec/compose-go/v2/cli"
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli/command"
"github.com/morikuni/aec"
@@ -41,7 +42,7 @@ type pullOptions struct {
policy string
}
func pullCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func pullCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := pullOptions{
ProjectOptions: p,
}
@@ -96,8 +97,8 @@ func (opts pullOptions) apply(project *types.Project, services []string) (*types
return project, nil
}
func runPull(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pullOptions, services []string) error {
project, _, err := opts.ToProject(ctx, dockerCli, services)
func runPull(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts pullOptions, services []string) error {
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}

View File

@@ -34,7 +34,7 @@ type pushOptions struct {
Quiet bool
}
func pushCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func pushCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := pushOptions{
ProjectOptions: p,
}
@@ -53,7 +53,7 @@ func pushCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return pushCmd
}
func runPush(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pushOptions, services []string) error {
func runPush(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts pushOptions, services []string) error {
project, _, err := opts.ToProject(ctx, dockerCli, services)
if err != nil {
return err

View File

@@ -31,7 +31,7 @@ type removeOptions struct {
volumes bool
}
func removeCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func removeCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := removeOptions{
ProjectOptions: p,
}
@@ -59,7 +59,7 @@ Any data which is not in a volume will be lost.`,
return cmd
}
func runRemove(ctx context.Context, dockerCli command.Cli, backend api.Service, opts removeOptions, services []string) error {
func runRemove(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts removeOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -33,7 +33,7 @@ type restartOptions struct {
noDeps bool
}
func restartCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func restartCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := restartOptions{
ProjectOptions: p,
}
@@ -55,7 +55,7 @@ func restartCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
return restartCmd
}
func runRestart(ctx context.Context, dockerCli command.Cli, backend api.Service, opts restartOptions, services []string) error {
func runRestart(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts restartOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli)
if err != nil {
return err

View File

@@ -50,7 +50,6 @@ type runOptions struct {
Detach bool
Remove bool
noTty bool
tty bool
interactive bool
user string
workdir string
@@ -120,8 +119,8 @@ func (options runOptions) apply(project *types.Project) (*types.Project, error)
return project, nil
}
func (options runOptions) getEnvironment() (types.Mapping, error) {
environment := types.NewMappingWithEquals(options.environment).Resolve(os.LookupEnv).ToMapping()
func (options runOptions) getEnvironment(resolve func(string) (string, bool)) (types.Mapping, error) {
environment := types.NewMappingWithEquals(options.environment).Resolve(resolve).ToMapping()
for _, file := range options.envFiles {
f, err := os.Open(file)
if err != nil {
@@ -143,7 +142,7 @@ func (options runOptions) getEnvironment() (types.Mapping, error) {
return environment, nil
}
func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
options := runOptions{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -155,6 +154,10 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
buildOpts := buildOptions{
ProjectOptions: p,
}
// We remove the attribute from the option struct and use a dedicated var, to limit confusion and avoid anyone to use options.tty.
// The tty flag is here for convenience and let user do "docker compose run -it" the same way as they use the "docker run" command.
var ttyFlag bool
cmd := &cobra.Command{
Use: "run [OPTIONS] SERVICE [COMMAND] [ARGS...]",
Short: "Run a one-off command on a service",
@@ -178,9 +181,16 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
if cmd.Flags().Changed("no-TTY") {
return fmt.Errorf("--tty and --no-TTY can't be used together")
} else {
options.noTty = !options.tty
options.noTty = !ttyFlag
}
} else if !cmd.Flags().Changed("no-TTY") && !cmd.Flags().Changed("interactive") && !dockerCli.In().IsTerminal() {
// while `docker run` requires explicit `-it` flags, Compose enables interactive mode and TTY by default
// but when compose is used from a scripr has stdin piped from another command, we just can't
// Here, we detect we run "by default" (user didn't passed explicit flags) and disable TTY allocation if
// we don't have an actual terminal to attach to for interactive mode
options.noTty = true
}
if options.quiet {
progress.Mode = progress.ModeQuiet
devnull, err := os.Open(os.DevNull)
@@ -238,7 +248,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
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")
cmd.Flags().BoolVarP(&ttyFlag, "tty", "t", true, "Allocate a pseudo-TTY")
cmd.Flags().MarkHidden("tty") //nolint:errcheck
flags.SetNormalizeFunc(normalizeRunFlags)
@@ -256,7 +266,7 @@ func normalizeRunFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
return pflag.NormalizedName(name)
}
func runRun(ctx context.Context, backend api.Service, project *types.Project, options runOptions, createOpts createOptions, buildOpts buildOptions, dockerCli command.Cli) error {
func runRun(ctx context.Context, backend api.Compose, project *types.Project, options runOptions, createOpts createOptions, buildOpts buildOptions, dockerCli command.Cli) error {
project, err := options.apply(project)
if err != nil {
return err
@@ -271,22 +281,6 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
return err
}
err = progress.Run(ctx, func(ctx context.Context) error {
var buildForDeps *api.BuildOptions
if !createOpts.noBuild {
// allow dependencies needing build to be implicitly selected
bo, err := buildOpts.toAPIBuildOptions(nil)
if err != nil {
return err
}
buildForDeps = &bo
}
return startDependencies(ctx, backend, *project, buildForDeps, options)
}, dockerCli.Err())
if err != nil {
return err
}
labels := types.Labels{}
for _, s := range options.labels {
parts := strings.SplitN(s, "=", 2)
@@ -298,23 +292,26 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
var buildForRun *api.BuildOptions
if !createOpts.noBuild {
// dependencies have already been started above, so only the service
// being run might need to be built at this point
bo, err := buildOpts.toAPIBuildOptions([]string{options.Service})
bo, err := buildOpts.toAPIBuildOptions(nil)
if err != nil {
return err
}
buildForRun = &bo
}
environment, err := options.getEnvironment()
environment, err := options.getEnvironment(project.Environment.Resolve)
if err != nil {
return err
}
// start container and attach to container streams
runOpts := api.RunOptions{
Build: buildForRun,
CreateOptions: api.CreateOptions{
Build: buildForRun,
RemoveOrphans: options.removeOrphans,
IgnoreOrphans: options.ignoreOrphans,
QuietPull: options.quietPull,
},
Name: options.name,
Service: options.Service,
Command: options.Command,
@@ -324,15 +321,14 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
Interactive: options.interactive,
WorkingDir: options.workdir,
User: options.user,
CapAdd: options.capAdd.GetAll(),
CapDrop: options.capDrop.GetAll(),
CapAdd: options.capAdd.GetSlice(),
CapDrop: options.capDrop.GetSlice(),
Environment: environment.Values(),
Entrypoint: options.entrypointCmd,
Labels: labels,
UseNetworkAliases: options.useAliases,
NoDeps: options.noDeps,
Index: 0,
QuietPull: options.quietPull,
}
for name, service := range project.Services {
@@ -352,34 +348,3 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
}
return err
}
func startDependencies(ctx context.Context, backend api.Service, project types.Project, buildOpts *api.BuildOptions, options runOptions) error {
dependencies := types.Services{}
var requestedService types.ServiceConfig
for name, service := range project.Services {
if name != options.Service {
dependencies[name] = service
} else {
requestedService = service
}
}
project.Services = dependencies
project.DisabledServices[options.Service] = requestedService
err := backend.Create(ctx, &project, api.CreateOptions{
Build: buildOpts,
IgnoreOrphans: options.ignoreOrphans,
RemoveOrphans: options.removeOrphans,
QuietPull: options.quietPull,
})
if err != nil {
return err
}
if len(dependencies) > 0 {
return backend.Start(ctx, project.Name, api.StartOptions{
Project: &project,
})
}
return nil
}

View File

@@ -19,14 +19,13 @@ package compose
import (
"context"
"fmt"
"maps"
"slices"
"strconv"
"strings"
"github.com/docker/cli/cli/command"
"github.com/compose-spec/compose-go/v2/types"
"golang.org/x/exp/maps"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
@@ -36,7 +35,7 @@ type scaleOptions struct {
noDeps bool
}
func scaleCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func scaleCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := scaleOptions{
ProjectOptions: p,
}
@@ -59,8 +58,8 @@ func scaleCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return scaleCmd
}
func runScale(ctx context.Context, dockerCli command.Cli, backend api.Service, opts scaleOptions, serviceReplicaTuples map[string]int) error {
services := maps.Keys(serviceReplicaTuples)
func runScale(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts scaleOptions, serviceReplicaTuples map[string]int) error {
services := slices.Sorted(maps.Keys(serviceReplicaTuples))
project, _, err := opts.ToProject(ctx, dockerCli, services)
if err != nil {
return err

View File

@@ -28,7 +28,7 @@ type startOptions struct {
*ProjectOptions
}
func startCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func startCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := startOptions{
ProjectOptions: p,
}
@@ -43,7 +43,7 @@ func startCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return startCmd
}
func runStart(ctx context.Context, dockerCli command.Cli, backend api.Service, opts startOptions, services []string) error {
func runStart(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts startOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -32,7 +32,7 @@ type stopOptions struct {
timeout int
}
func stopCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func stopCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := stopOptions{
ProjectOptions: p,
}
@@ -53,7 +53,7 @@ func stopCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runStop(ctx context.Context, dockerCli command.Cli, backend api.Service, opts stopOptions, services []string) error {
func runStop(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts stopOptions, services []string) error {
project, name, err := opts.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err

View File

@@ -34,7 +34,7 @@ type topOptions struct {
*ProjectOptions
}
func topCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func topCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := topOptions{
ProjectOptions: p,
}
@@ -54,7 +54,7 @@ type (
topEntries map[string]string
)
func runTop(ctx context.Context, dockerCli command.Cli, backend api.Service, opts topOptions, services []string) error {
func runTop(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts topOptions, services []string) error {
projectName, err := opts.toProjectName(ctx, dockerCli)
if err != nil {
return err

View File

@@ -202,7 +202,7 @@ var topTestCases = []struct {
}
// TestRunTopCore only tests the core functionality of runTop: formatting
// and printing of the output of (api.Service).Top().
// and printing of the output of (api.Compose).Top().
func TestRunTopCore(t *testing.T) {
t.Parallel()

View File

@@ -109,7 +109,7 @@ func (opts upOptions) OnExit() api.Cascade {
}
}
func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
up := upOptions{}
create := createOptions{}
build := buildOptions{ProjectOptions: p}
@@ -165,6 +165,7 @@ func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *c
flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers")
flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information")
flags.BoolVar(&build.quiet, "quiet-build", false, "Suppress the build output")
flags.StringArrayVar(&up.attach, "attach", []string{}, "Restrict attaching to the specified services. Incompatible with --attach-dependencies.")
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")
@@ -223,10 +224,11 @@ func validateFlags(up *upOptions, create *createOptions) error {
return nil
}
//nolint:gocyclo
func runUp(
ctx context.Context,
dockerCli command.Cli,
backend api.Service,
backend api.Compose,
createOptions createOptions,
upOptions upOptions,
buildOptions buildOptions,
@@ -261,6 +263,7 @@ func runUp(
return err
}
bo.Services = services
bo.Deps = !upOptions.noDeps
build = &bo
}
@@ -329,7 +332,7 @@ func runUp(
WaitTimeout: timeout,
Watch: upOptions.watch,
Services: services,
NavigationMenu: upOptions.navigationMenu && ui.Mode != "plain",
NavigationMenu: upOptions.navigationMenu && ui.Mode != "plain" && dockerCli.In().IsTerminal(),
},
})
}

View File

@@ -35,7 +35,7 @@ type vizOptions struct {
indentationStr string
}
func vizCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func vizCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := vizOptions{
ProjectOptions: p,
}
@@ -63,7 +63,7 @@ func vizCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
return cmd
}
func runViz(ctx context.Context, dockerCli command.Cli, backend api.Service, opts *vizOptions) error {
func runViz(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts *vizOptions) error {
_, _ = fmt.Fprintln(os.Stderr, "viz command is EXPERIMENTAL")
project, _, err := opts.ToProject(ctx, dockerCli, nil)
if err != nil {

92
cmd/compose/volumes.go Normal file
View File

@@ -0,0 +1,92 @@
/*
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"
"slices"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/cli/flags"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type volumesOptions struct {
*ProjectOptions
Quiet bool
Format string
}
func volumesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
options := volumesOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "volumes [OPTIONS] [SERVICE...]",
Short: "List volumes",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runVol(ctx, dockerCli, backend, args, options)
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
cmd.Flags().BoolVarP(&options.Quiet, "quiet", "q", false, "Only display volume names")
cmd.Flags().StringVar(&options.Format, "format", "table", flags.FormatHelp)
return cmd
}
func runVol(ctx context.Context, dockerCli command.Cli, backend api.Compose, services []string, options volumesOptions) error {
project, name, err := options.projectOrName(ctx, dockerCli, services...)
if err != nil {
return err
}
if project != nil {
names := project.ServiceNames()
for _, service := range services {
if !slices.Contains(names, service) {
return fmt.Errorf("no such service: %s", service)
}
}
}
volumes, err := backend.Volumes(ctx, name, api.VolumesOptions{
Services: services,
})
if err != nil {
return err
}
if options.Quiet {
for _, v := range volumes {
_, _ = fmt.Fprintln(dockerCli.Out(), v.Name)
}
return nil
}
volumeCtx := formatter.Context{
Output: dockerCli.Out(),
Format: formatter.NewVolumeFormat(options.Format, options.Quiet),
}
return formatter.VolumeWrite(volumeCtx, volumes)
}

View File

@@ -34,7 +34,7 @@ type waitOptions struct {
downProject bool
}
func waitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func waitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
opts := waitOptions{
ProjectOptions: p,
}
@@ -60,7 +60,7 @@ func waitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runWait(ctx context.Context, dockerCli command.Cli, backend api.Service, opts *waitOptions) (int64, error) {
func runWait(ctx context.Context, dockerCli command.Cli, backend api.Compose, opts *waitOptions) (int64, error) {
_, name, err := opts.projectOrName(ctx, dockerCli)
if err != nil {
return 0, err

View File

@@ -36,7 +36,7 @@ type watchOptions struct {
noUp bool
}
func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Compose) *cobra.Command {
watchOpts := watchOptions{
ProjectOptions: p,
}
@@ -64,7 +64,7 @@ func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
return cmd
}
func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, watchOpts watchOptions, buildOpts buildOptions, services []string) error {
func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Compose, watchOpts watchOptions, buildOpts buildOptions, services []string) error {
project, _, err := watchOpts.ToProject(ctx, dockerCli, services)
if err != nil {
return err
@@ -117,9 +117,10 @@ func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, w
}
consumer := formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), false, false, false)
return backend.Watch(ctx, project, services, api.WatchOptions{
Build: &build,
LogTo: consumer,
Prune: watchOpts.prune,
return backend.Watch(ctx, project, api.WatchOptions{
Build: &build,
LogTo: consumer,
Prune: watchOpts.prune,
Services: services,
})
}

View File

@@ -28,49 +28,42 @@ func ansi(code string) string {
return fmt.Sprintf("\033%s", code)
}
func SaveCursor() {
func saveCursor() {
if disableAnsi {
return
}
fmt.Print(ansi("7"))
}
func RestoreCursor() {
func restoreCursor() {
if disableAnsi {
return
}
fmt.Print(ansi("8"))
}
func HideCursor() {
if disableAnsi {
return
}
fmt.Print(ansi("[?25l"))
}
func ShowCursor() {
func showCursor() {
if disableAnsi {
return
}
fmt.Print(ansi("[?25h"))
}
func MoveCursor(y, x int) {
func moveCursor(y, x int) {
if disableAnsi {
return
}
fmt.Print(ansi(fmt.Sprintf("[%d;%dH", y, x)))
}
func MoveCursorX(pos int) {
func carriageReturn() {
if disableAnsi {
return
}
fmt.Print(ansi(fmt.Sprintf("[%dG", pos)))
fmt.Print(ansi(fmt.Sprintf("[%dG", 0)))
}
func ClearLine() {
func clearLine() {
if disableAnsi {
return
}
@@ -78,7 +71,7 @@ func ClearLine() {
fmt.Print(ansi("[2K"))
}
func MoveCursorUp(lines int) {
func moveCursorUp(lines int) {
if disableAnsi {
return
}
@@ -86,7 +79,7 @@ func MoveCursorUp(lines int) {
fmt.Print(ansi(fmt.Sprintf("[%dA", lines)))
}
func MoveCursorDown(lines int) {
func moveCursorDown(lines int) {
if disableAnsi {
return
}
@@ -94,7 +87,7 @@ func MoveCursorDown(lines int) {
fmt.Print(ansi(fmt.Sprintf("[%dB", lines)))
}
func NewLine() {
func newLine() {
// Like \n
fmt.Print("\012")
}

View File

@@ -19,6 +19,7 @@ package formatter
import (
"fmt"
"strconv"
"strings"
"sync"
"github.com/docker/cli/cli/command"
@@ -58,6 +59,9 @@ const (
Auto = "auto"
)
// ansiColorOffset is the offset for basic foreground colors in ANSI escape codes.
const ansiColorOffset = 30
// SetANSIMode configure formatter for colored output on ANSI-compliant console
func SetANSIMode(streams command.Streams, ansi string) {
if !useAnsi(streams, ansi) {
@@ -91,11 +95,15 @@ func ansiColor(code, s string, formatOpts ...string) string {
// Everything about ansiColorCode color https://hyperskill.org/learn/step/18193
func ansiColorCode(code string, formatOpts ...string) string {
res := "\033["
var sb strings.Builder
sb.WriteString("\033[")
for _, c := range formatOpts {
res = fmt.Sprintf("%s%s;", res, c)
sb.WriteString(c)
sb.WriteString(";")
}
return fmt.Sprintf("%s%sm", res, code)
sb.WriteString(code)
sb.WriteString("m")
return sb.String()
}
func makeColorFunc(code string) colorFunc {
@@ -122,8 +130,8 @@ func rainbowColor() colorFunc {
func init() {
colors := map[string]colorFunc{}
for i, name := range names {
colors[name] = makeColorFunc(strconv.Itoa(30 + i))
colors["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
colors[name] = makeColorFunc(strconv.Itoa(ansiColorOffset + i))
colors["intense_"+name] = makeColorFunc(strconv.Itoa(ansiColorOffset+i) + ";1")
}
rainbow = []colorFunc{
colors["cyan"],

View File

@@ -56,10 +56,6 @@ func NewLogConsumer(ctx context.Context, stdout, stderr io.Writer, color, prefix
}
}
func (l *logConsumer) Register(name string) {
l.register(name)
}
func (l *logConsumer) register(name string) *presenter {
var p *presenter
root, _, found := strings.Cut(name, " ")
@@ -73,9 +69,12 @@ func (l *logConsumer) register(name string) *presenter {
} else {
cf := monochrome
if l.color {
if name == api.WatchLogger {
switch name {
case "":
cf = monochrome
case api.WatchLogger:
cf = makeColorFunc("92")
} else {
default:
cf = nextColor()
}
}
@@ -118,23 +117,15 @@ func (l *logConsumer) write(w io.Writer, container, message string) {
if l.ctx.Err() != nil {
return
}
if KeyboardManager != nil {
KeyboardManager.ClearKeyboardInfo()
}
p := l.getPresenter(container)
timestamp := time.Now().Format(jsonmessage.RFC3339NanoFixed)
for _, line := range strings.Split(message, "\n") {
if l.timestamp {
_, _ = fmt.Fprintf(w, "%s%s%s\n", p.prefix, timestamp, line)
_, _ = fmt.Fprintf(w, "%s%s %s\n", p.prefix, timestamp, line)
} else {
_, _ = fmt.Fprintf(w, "%s%s\n", p.prefix, line)
}
}
if KeyboardManager != nil {
KeyboardManager.PrintKeyboardInfo()
}
}
func (l *logConsumer) Status(container, msg string) {
@@ -168,3 +159,27 @@ func (p *presenter) setPrefix(width int) {
}
p.prefix = p.colors(fmt.Sprintf("%-"+strconv.Itoa(width)+"s | ", p.name))
}
type logDecorator struct {
decorated api.LogConsumer
Before func()
After func()
}
func (l logDecorator) Log(containerName, message string) {
l.Before()
l.decorated.Log(containerName, message)
l.After()
}
func (l logDecorator) Err(containerName, message string) {
l.Before()
l.decorated.Err(containerName, message)
l.After()
}
func (l logDecorator) Status(container, msg string) {
l.Before()
l.decorated.Status(container, msg)
l.After()
}

View File

@@ -29,9 +29,7 @@ import (
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/compose/v2/internal/tracing"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/watch"
"github.com/eiannone/keyboard"
"github.com/hashicorp/go-multierror"
"github.com/skratchdot/open-golang/open"
)
@@ -50,8 +48,8 @@ func (ke *KeyboardError) printError(height int, info string) {
if ke.shouldDisplay() {
errMessage := ke.err.Error()
MoveCursor(height-1-extraLines(info)-extraLines(errMessage), 0)
ClearLine()
moveCursor(height-1-extraLines(info)-extraLines(errMessage), 0)
clearLine()
fmt.Print(errMessage)
}
@@ -71,26 +69,14 @@ func (ke *KeyboardError) error() string {
}
type KeyboardWatch struct {
Watcher watch.Notify
Watching bool
WatchFn func(ctx context.Context, doneCh chan bool, project *types.Project, services []string, options api.WatchOptions) error
Ctx context.Context
Cancel context.CancelFunc
Watcher Feature
}
func (kw *KeyboardWatch) isWatching() bool {
return kw.Watching
}
func (kw *KeyboardWatch) switchWatching() {
kw.Watching = !kw.Watching
}
func (kw *KeyboardWatch) newContext(ctx context.Context) context.CancelFunc {
ctx, cancel := context.WithCancel(ctx)
kw.Ctx = ctx
kw.Cancel = cancel
return cancel
// Feature is an compose feature that can be started/stopped by a menu command
type Feature interface {
Start(context.Context) error
Stop() error
}
type KEYBOARD_LOG_LEVEL int
@@ -103,42 +89,26 @@ const (
type LogKeyboard struct {
kError KeyboardError
Watch KeyboardWatch
Watch *KeyboardWatch
IsDockerDesktopActive bool
IsWatchConfigured bool
logLevel KEYBOARD_LOG_LEVEL
signalChannel chan<- os.Signal
}
var (
KeyboardManager *LogKeyboard
eg multierror.Group
)
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured bool,
sc chan<- os.Signal,
watchFn func(ctx context.Context,
doneCh chan bool,
project *types.Project,
services []string,
options api.WatchOptions,
) error,
) {
km := LogKeyboard{}
km.IsDockerDesktopActive = isDockerDesktopActive
km.IsWatchConfigured = isWatchConfigured
km.logLevel = INFO
km.Watch.Watching = false
km.Watch.WatchFn = watchFn
km.signalChannel = sc
KeyboardManager = &km
func NewKeyboardManager(isDockerDesktopActive bool, sc chan<- os.Signal) *LogKeyboard {
return &LogKeyboard{
IsDockerDesktopActive: isDockerDesktopActive,
logLevel: INFO,
signalChannel: sc,
}
}
func (lk *LogKeyboard) ClearKeyboardInfo() {
lk.clearNavigationMenu()
func (lk *LogKeyboard) Decorate(l api.LogConsumer) api.LogConsumer {
return logDecorator{
decorated: l,
Before: lk.clearNavigationMenu,
After: lk.PrintKeyboardInfo,
}
}
func (lk *LogKeyboard) PrintKeyboardInfo() {
@@ -163,7 +133,7 @@ func (lk *LogKeyboard) createBuffer(lines int) {
if lines > 0 {
allocateSpace(lines)
MoveCursorUp(lines)
moveCursorUp(lines)
}
}
@@ -176,17 +146,17 @@ func (lk *LogKeyboard) printNavigationMenu() {
height := goterm.Height()
menu := lk.navigationMenu()
MoveCursorX(0)
SaveCursor()
carriageReturn()
saveCursor()
lk.kError.printError(height, menu)
MoveCursor(height-extraLines(menu), 0)
ClearLine()
moveCursor(height-extraLines(menu), 0)
clearLine()
fmt.Print(menu)
MoveCursorX(0)
RestoreCursor()
carriageReturn()
restoreCursor()
}
}
@@ -209,7 +179,7 @@ func (lk *LogKeyboard) navigationMenu() string {
watchInfo = navColor(" ")
}
isEnabled := " Enable"
if lk.Watch.Watching {
if lk.Watch != nil && lk.Watch.Watching {
isEnabled = " Disable"
}
watchInfo = watchInfo + shortcutKeyColor("w") + navColor(isEnabled+" Watch")
@@ -218,63 +188,66 @@ func (lk *LogKeyboard) navigationMenu() string {
func (lk *LogKeyboard) clearNavigationMenu() {
height := goterm.Height()
MoveCursorX(0)
SaveCursor()
carriageReturn()
saveCursor()
// ClearLine()
// clearLine()
for i := 0; i < height; i++ {
MoveCursorDown(1)
ClearLine()
moveCursorDown(1)
clearLine()
}
RestoreCursor()
restoreCursor()
}
func (lk *LogKeyboard) openDockerDesktop(ctx context.Context, project *types.Project) {
if !lk.IsDockerDesktopActive {
return
}
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/gui", tracing.SpanOptions{},
func(ctx context.Context) error {
link := fmt.Sprintf("docker-desktop://dashboard/apps/%s", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop")
lk.keyboardError("View", err)
}
return err
}),
)
go func() {
_ = tracing.EventWrapFuncForErrGroup(ctx, "menu/gui", tracing.SpanOptions{},
func(ctx context.Context) error {
link := fmt.Sprintf("docker-desktop://dashboard/apps/%s", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop")
lk.keyboardError("View", err)
}
return err
})()
}()
}
func (lk *LogKeyboard) openDDComposeUI(ctx context.Context, project *types.Project) {
if !lk.IsDockerDesktopActive {
return
}
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/composeview", tracing.SpanOptions{},
func(ctx context.Context) error {
link := fmt.Sprintf("docker-desktop://dashboard/docker-compose/%s", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop Compose UI")
lk.keyboardError("View Config", err)
}
return err
}),
)
go func() {
_ = tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/composeview", tracing.SpanOptions{},
func(ctx context.Context) error {
link := fmt.Sprintf("docker-desktop://dashboard/docker-compose/%s", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop Compose UI")
lk.keyboardError("View Config", err)
}
return err
})()
}()
}
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 {
link := fmt.Sprintf("docker-desktop://dashboard/docker-compose/%s/watch", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop Compose UI")
lk.keyboardError("Watch Docs", err)
}
return err
}),
)
go func() {
_ = tracing.EventWrapFuncForErrGroup(ctx, "menu/gui/watch", tracing.SpanOptions{},
func(ctx context.Context) error {
link := fmt.Sprintf("docker-desktop://dashboard/docker-compose/%s/watch", project.Name)
err := open.Run(link)
if err != nil {
err = fmt.Errorf("could not open Docker Desktop Compose UI")
lk.keyboardError("Watch Docs", err)
}
return err
})()
}()
}
func (lk *LogKeyboard) keyboardError(prefix string, err error) {
@@ -288,58 +261,54 @@ 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 {
func (lk *LogKeyboard) ToggleWatch(ctx context.Context, options api.UpOptions) {
if lk.Watch == nil {
return
}
lk.Watch.switchWatching()
if !lk.Watch.isWatching() {
lk.Watch.Cancel()
if lk.Watch.Watching {
err := lk.Watch.Watcher.Stop()
if err != nil {
options.Start.Attach.Err(api.WatchLogger, err.Error())
} else {
lk.Watch.Watching = false
}
} else {
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{},
func(ctx context.Context) error {
if options.Create.Build == nil {
err := fmt.Errorf("cannot run watch mode with flag --no-build")
lk.keyboardError("Watch", err)
go func() {
_ = tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{},
func(ctx context.Context) error {
err := lk.Watch.Watcher.Start(ctx)
if err != nil {
options.Start.Attach.Err(api.WatchLogger, err.Error())
} else {
lk.Watch.Watching = true
}
return err
}
lk.Watch.newContext(ctx)
buildOpts := *options.Create.Build
buildOpts.Quiet = true
err := lk.Watch.WatchFn(lk.Watch.Ctx, doneCh, project, options.Start.Services, api.WatchOptions{
Build: &buildOpts,
LogTo: options.Start.Attach,
})
if err != nil {
lk.Watch.switchWatching()
options.Start.Attach.Err(api.WatchLogger, err.Error())
}
return err
}))
})()
}()
}
}
func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Context, doneCh chan bool, project *types.Project, options api.UpOptions) {
func (lk *LogKeyboard) HandleKeyEvents(ctx context.Context, event keyboard.KeyEvent, project *types.Project, options api.UpOptions) {
switch kRune := event.Rune; kRune {
case 'v':
lk.openDockerDesktop(ctx, project)
case 'w':
if !lk.IsWatchConfigured {
if lk.Watch == nil {
// 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
go func() {
_ = 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
})()
}()
}
lk.StartWatch(ctx, doneCh, project, options)
lk.ToggleWatch(ctx, options)
case 'o':
lk.openDDComposeUI(ctx, project)
}
@@ -347,26 +316,31 @@ func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Cont
case keyboard.KeyCtrlC:
_ = keyboard.Close()
lk.clearNavigationMenu()
ShowCursor()
showCursor()
lk.logLevel = NONE
if lk.Watch.Watching && lk.Watch.Cancel != nil {
lk.Watch.Cancel()
_ = eg.Wait().ErrorOrNil() // Need to print this ?
}
// will notify main thread to kill and will handle gracefully
lk.signalChannel <- syscall.SIGINT
case keyboard.KeyCtrlZ:
handleCtrlZ()
case keyboard.KeyEnter:
NewLine()
newLine()
lk.printNavigationMenu()
}
}
func (lk *LogKeyboard) EnableWatch(enabled bool, watcher Feature) {
lk.Watch = &KeyboardWatch{
Watching: enabled,
Watcher: watcher,
}
}
func allocateSpace(lines int) {
for i := 0; i < lines; i++ {
ClearLine()
NewLine()
MoveCursorX(0)
clearLine()
newLine()
carriageReturn()
}
}

View File

@@ -0,0 +1,25 @@
//go:build !windows
/*
Copyright 2024 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 formatter
import "syscall"
func handleCtrlZ() {
_ = syscall.Kill(0, syscall.SIGSTOP)
}

View File

@@ -0,0 +1,25 @@
//go:build windows
/*
Copyright 2024 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 formatter
// handleCtrlZ is a no-op on Windows as SIGSTOP is not supported
func handleCtrlZ() {
// Windows doesn't support SIGSTOP/SIGCONT signals
// Ctrl+Z behavior is handled differently by the Windows terminal
}

View File

@@ -20,11 +20,11 @@ import (
"os"
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/metadata"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/cmdtrace"
"github.com/docker/docker/client"
"github.com/docker/compose/v2/cmd/prompt"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -35,60 +35,43 @@ import (
)
func pluginMain() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command {
// TODO(milas): this cast is safe but we should not need to do this,
// we should expose the concrete service type so that we do not need
// to rely on the `api.Service` interface internally
backend := compose.NewComposeService(dockerCli).(commands.Backend)
cmd := commands.RootCommand(dockerCli, backend)
originalPreRunE := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
// initialize the dockerCli instance
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
return err
}
// compose-specific initialization
dockerCliPostInitialize(dockerCli)
plugin.Run(
func(cli command.Cli) *cobra.Command {
backend := compose.NewComposeService(cli,
compose.WithPrompt(prompt.NewPrompt(cli.In(), cli.Out()).Confirm),
)
cmd := commands.RootCommand(cli, backend)
originalPreRunE := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
// initialize the cli instance
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
return err
}
if err := cmdtrace.Setup(cmd, cli, os.Args[1:]); err != nil {
logrus.Debugf("failed to enable tracing: %v", err)
}
if err := cmdtrace.Setup(cmd, dockerCli, os.Args[1:]); err != nil {
logrus.Debugf("failed to enable tracing: %v", err)
if originalPreRunE != nil {
return originalPreRunE(cmd, args)
}
return nil
}
if originalPreRunE != nil {
return originalPreRunE(cmd, args)
}
return nil
}
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return dockercli.StatusError{
StatusCode: 1,
Status: err.Error(),
}
})
return cmd
},
manager.Metadata{
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return dockercli.StatusError{
StatusCode: 1,
Status: err.Error(),
}
})
return cmd
},
metadata.Metadata{
SchemaVersion: "0.1.0",
Vendor: "Docker Inc.",
Version: internal.Version,
})
}
// dockerCliPostInitialize performs Compose-specific configuration for the
// command.Cli instance provided by the plugin.Run() initialization.
//
// NOTE: This must be called AFTER plugin.PersistentPreRunE.
func dockerCliPostInitialize(dockerCli command.Cli) {
// HACK(milas): remove once docker/cli#4574 is merged; for now,
// set it in a rather roundabout way by grabbing the underlying
// concrete client and manually invoking an option on it
_ = dockerCli.Apply(func(cli *command.DockerCli) error {
if mobyClient, ok := cli.Client().(*client.Client); ok {
_ = client.WithUserAgent("compose/" + internal.Version)(mobyClient)
}
return nil
})
},
command.WithUserAgent("compose/"+internal.Version),
)
}
func main() {

View File

@@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Container: github.com/docker/compose-cli/pkg/prompt (interfaces: UI)
// Source: github.com/docker/compose-cli/pkg/prompt (interfaces: UI)
// Package prompt is a generated GoMock package.
package prompt

View File

@@ -17,11 +17,13 @@
package main
import (
"encoding/json"
"fmt"
"os"
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func main() {
@@ -37,34 +39,55 @@ func main() {
}
}
type options struct {
db string
size int
}
func composeCommand() *cobra.Command {
c := &cobra.Command{
Use: "compose EVENT",
TraverseChildren: true,
}
c.PersistentFlags().String("project-name", "", "compose project name") // unused
c.AddCommand(&cobra.Command{
Use: "up",
Run: up,
var options options
upCmd := &cobra.Command{
Use: "up",
Run: func(_ *cobra.Command, args []string) {
up(options, args)
},
Args: cobra.ExactArgs(1),
})
c.AddCommand(&cobra.Command{
}
upCmd.Flags().StringVar(&options.db, "type", "", "Database type (mysql, postgres, etc.)")
_ = upCmd.MarkFlagRequired("type")
upCmd.Flags().IntVar(&options.size, "size", 10, "Database size in GB")
upCmd.Flags().String("name", "", "Name of the database to be created")
_ = upCmd.MarkFlagRequired("name")
downCmd := &cobra.Command{
Use: "down",
Run: down,
Args: cobra.ExactArgs(1),
})
}
downCmd.Flags().String("name", "", "Name of the database to be deleted")
_ = downCmd.MarkFlagRequired("name")
c.AddCommand(upCmd, downCmd)
c.AddCommand(metadataCommand(upCmd, downCmd))
return c
}
const lineSeparator = "\n"
func up(_ *cobra.Command, args []string) {
func up(options options, args []string) {
servicename := args[0]
fmt.Printf(`{ "type": "debug", "message": "Starting %s" }%s`, servicename, lineSeparator)
for i := 0; i < 100; i += 10 {
for i := 0; i < options.size; i += 10 {
time.Sleep(1 * time.Second)
fmt.Printf(`{ "type": "info", "message": "Processing ... %d%%" }%s`, i, lineSeparator)
fmt.Printf(`{ "type": "info", "message": "Processing ... %d%%" }%s`, i*100/options.size, lineSeparator)
}
fmt.Printf(`{ "type": "setenv", "message": "URL=https://magic.cloud/%s" }%s`, servicename, lineSeparator)
}
@@ -72,3 +95,58 @@ func up(_ *cobra.Command, args []string) {
func down(_ *cobra.Command, _ []string) {
fmt.Printf(`{ "type": "error", "message": "Permission error" }%s`, lineSeparator)
}
func metadataCommand(upCmd, downCmd *cobra.Command) *cobra.Command {
return &cobra.Command{
Use: "metadata",
Run: func(cmd *cobra.Command, _ []string) {
metadata(upCmd, downCmd)
},
Args: cobra.NoArgs,
}
}
func metadata(upCmd, downCmd *cobra.Command) {
metadata := ProviderMetadata{}
metadata.Description = "Manage services on AwesomeCloud"
metadata.Up = commandParameters(upCmd)
metadata.Down = commandParameters(downCmd)
jsonMetadata, err := json.Marshal(metadata)
if err != nil {
panic(err)
}
fmt.Println(string(jsonMetadata))
}
func commandParameters(cmd *cobra.Command) CommandMetadata {
cmdMetadata := CommandMetadata{}
cmd.Flags().VisitAll(func(f *pflag.Flag) {
_, isRequired := f.Annotations[cobra.BashCompOneRequiredFlag]
cmdMetadata.Parameters = append(cmdMetadata.Parameters, Metadata{
Name: f.Name,
Description: f.Usage,
Required: isRequired,
Type: f.Value.Type(),
Default: f.DefValue,
})
})
return cmdMetadata
}
type ProviderMetadata struct {
Description string `json:"description"`
Up CommandMetadata `json:"up"`
Down CommandMetadata `json:"down"`
}
type CommandMetadata struct {
Parameters []Metadata `json:"parameters"`
}
type Metadata struct {
Name string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Type string `json:"type"`
Default string `json:"default,omitempty"`
}

View File

@@ -20,6 +20,7 @@ the resource(s) needed to run a service.
options:
type: mysql
size: 256
name: myAwesomeCloudDB
```
`provider.type` tells Compose the binary to run, which can be either:
@@ -104,8 +105,72 @@ into its runtime environment.
## Down lifecycle
`down` lifecycle is equivalent to `up` with the `<provider> compose --project-name <NAME> down <SERVICE>` command.
The provider is responsible for releasing all resources associated with the service.
The provider is responsible for releasing all resources associated with the service.
## Provide metadata about options
Compose extensions *MAY* optionally implement a `metadata` subcommand to provide information about the parameters accepted by the `up` and `down` commands.
The `metadata` subcommand takes no parameters and returns a JSON structure on the `stdout` channel that describes the parameters accepted by both the `up` and `down` commands, including whether each parameter is mandatory or optional.
```console
awesomecloud compose metadata
```
The expected JSON output format is:
```json
{
"description": "Manage services on AwesomeCloud",
"up": {
"parameters": [
{
"name": "type",
"description": "Database type (mysql, postgres, etc.)",
"required": true,
"type": "string"
},
{
"name": "size",
"description": "Database size in GB",
"required": false,
"type": "integer",
"default": "10"
},
{
"name": "name",
"description": "Name of the database to be created",
"required": true,
"type": "string"
}
]
},
"down": {
"parameters": [
{
"name": "name",
"description": "Name of the database to be removed",
"required": true,
"type": "string"
}
]
}
}
```
The top elements are:
- `description`: Human-readable description of the provider
- `up`: Object describing the parameters accepted by the `up` command
- `down`: Object describing the parameters accepted by the `down` command
And for each command parameter, you should include the following properties:
- `name`: The parameter name (without `--` prefix)
- `description`: Human-readable description of the parameter
- `required`: Boolean indicating if the parameter is mandatory
- `type`: Parameter type (`string`, `integer`, `boolean`, etc.)
- `default`: Default value (optional, only for non-required parameters)
- `enum`: List of possible values supported by the parameter separated by `,` (optional, only for parameters with a limited set of values)
This metadata allows Compose and other tools to understand the provider's interface and provide better user experience, such as validation, auto-completion, and documentation generation.
## Examples
See [example](examples/provider.go) for illustration on implementing this API in a command line
See [example](examples/provider.go) for illustration on implementing this API in a command line

View File

@@ -12,6 +12,7 @@ Define and run multi-container applications with Docker
| Name | Description |
|:--------------------------------|:----------------------------------------------------------------------------------------|
| [`attach`](compose_attach.md) | Attach local standard input, output, and error streams to a service's running container |
| [`bridge`](compose_bridge.md) | Convert compose files into another model |
| [`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 |
@@ -42,6 +43,7 @@ Define and run multi-container applications with Docker
| [`unpause`](compose_unpause.md) | Unpause services |
| [`up`](compose_up.md) | Create and start containers |
| [`version`](compose_version.md) | Show the Docker Compose version information |
| [`volumes`](compose_volumes.md) | List volumes |
| [`wait`](compose_wait.md) | Block until containers of all (or specified) services stop. |
| [`watch`](compose_watch.md) | Watch build context for service and rebuild/refresh containers when files are updated |
@@ -58,7 +60,7 @@ Define and run multi-container applications with Docker
| `-f`, `--file` | `stringArray` | | Compose configuration files |
| `--parallel` | `int` | `-1` | Control max parallelism, -1 for unlimited |
| `--profile` | `stringArray` | | Specify a profile to enable |
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, json, quiet) |
| `--progress` | `string` | | Set type of progress output (auto, tty, plain, json, quiet) |
| `--project-directory` | `string` | | Specify an alternate working directory<br>(default: the path of the, first specified, Compose file) |
| `-p`, `--project-name` | `string` | | Project name |

View File

@@ -0,0 +1,22 @@
# docker compose bridge
<!---MARKER_GEN_START-->
Convert compose files into another model
### Subcommands
| Name | Description |
|:-------------------------------------------------------|:-----------------------------------------------------------------------------|
| [`convert`](compose_bridge_convert.md) | Convert compose files to Kubernetes manifests, Helm charts, or another model |
| [`transformations`](compose_bridge_transformations.md) | Manage transformation images |
### Options
| Name | Type | Default | Description |
|:------------|:-------|:--------|:--------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,17 @@
# docker compose bridge convert
<!---MARKER_GEN_START-->
Convert compose files to Kubernetes manifests, Helm charts, or another model
### Options
| Name | Type | Default | Description |
|:-------------------------|:--------------|:--------|:-------------------------------------------------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `-o`, `--output` | `string` | `out` | The output directory for the Kubernetes resources |
| `--templates` | `string` | | Directory containing transformation templates |
| `-t`, `--transformation` | `stringArray` | | Transformation to apply to compose model (default: docker/compose-bridge-kubernetes) |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,22 @@
# docker compose bridge transformations
<!---MARKER_GEN_START-->
Manage transformation images
### Subcommands
| Name | Description |
|:-----------------------------------------------------|:-------------------------------|
| [`create`](compose_bridge_transformations_create.md) | Create a new transformation |
| [`list`](compose_bridge_transformations_list.md) | List available transformations |
### Options
| Name | Type | Default | Description |
|:------------|:-------|:--------|:--------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,15 @@
# docker compose bridge transformations create
<!---MARKER_GEN_START-->
Create a new transformation
### Options
| Name | Type | Default | Description |
|:---------------|:---------|:--------|:----------------------------------------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `-f`, `--from` | `string` | | Existing transformation to copy (default: docker/compose-bridge-kubernetes) |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,20 @@
# docker compose bridge transformations list
<!---MARKER_GEN_START-->
List available transformations
### Aliases
`docker compose bridge transformations list`, `docker compose bridge transformations ls`
### Options
| Name | Type | Default | Description |
|:----------------|:---------|:--------|:-------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--format` | `string` | `table` | Format the output. Values: [table \| json] |
| `-q`, `--quiet` | `bool` | | Only display transformer names |
<!---MARKER_GEN_END-->

View File

@@ -22,9 +22,11 @@ run `docker compose build` to rebuild it.
| `-m`, `--memory` | `bytes` | `0` | Set memory limit for the build container. Not supported by BuildKit. |
| `--no-cache` | `bool` | | Do not use cache when building the image |
| `--print` | `bool` | | Print equivalent bake file |
| `--provenance` | `string` | | Add a provenance attestation |
| `--pull` | `bool` | | Always attempt to pull a newer version of the image |
| `--push` | `bool` | | Push service images |
| `-q`, `--quiet` | `bool` | | Don't print anything to STDOUT |
| `-q`, `--quiet` | `bool` | | Suppress the build output |
| `--sbom` | `string` | | Add a SBOM attestation |
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
| `--with-dependencies` | `bool` | | Also build dependencies (transitively) |

View File

@@ -15,6 +15,8 @@ the canonical format.
| `--hash` | `string` | | Print the service config hash, one per line. |
| `--images` | `bool` | | Print the image names, one per line. |
| `--lock-image-digests` | `bool` | | Produces an override file with image digests |
| `--models` | `bool` | | Print the model names, one per line. |
| `--networks` | `bool` | | Print the network names, one per line. |
| `--no-consistency` | `bool` | | Don't check model consistency - warning: may produce invalid Compose output |
| `--no-env-resolution` | `bool` | | Don't resolve service env files |
| `--no-interpolate` | `bool` | | Don't interpolate environment variables |

View File

@@ -23,10 +23,12 @@ The events that can be received using this can be seen [here](/reference/cli/doc
### Options
| Name | Type | Default | Description |
|:------------|:-------|:--------|:------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--json` | `bool` | | Output events as a stream of json objects |
| Name | Type | Default | Description |
|:------------|:---------|:--------|:------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--json` | `bool` | | Output events as a stream of json objects |
| `--since` | `string` | | Show all events created since timestamp |
| `--until` | `string` | | Stream events until this timestamp |
<!---MARKER_GEN_END-->

View File

@@ -6,6 +6,12 @@ This is the equivalent of `docker exec` targeting a Compose service.
With this subcommand, you can run arbitrary commands in your services. Commands allocate a TTY by default, so
you can use a command such as `docker compose exec web sh` to get an interactive prompt.
By default, Compose will enter container in interactive mode and allocate a TTY, while the equivalent `docker exec`
command requires passing `--interactive --tty` flags to get the same behavior. Compose also support those two flags
to offer a smooth migration between commands, whenever they are no-op by default. Still, `interactive` can be used to
force disabling interactive mode (`--interactive=false`), typically when `docker compose exec` command is used inside
a script.
### Options
| Name | Type | Default | Description |
@@ -14,7 +20,7 @@ you can use a command such as `docker compose exec web sh` to get an interactive
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `-e`, `--env` | `stringArray` | | Set environment variables |
| `--index` | `int` | `0` | Index of the container if service has multiple replicas |
| `-T`, `--no-TTY` | `bool` | `true` | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
| `-T`, `--no-tty` | `bool` | `true` | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
| `--privileged` | `bool` | | Give extended privileges to the process |
| `-u`, `--user` | `string` | | Run the command as this user |
| `-w`, `--workdir` | `string` | | Path to workdir directory for this command |
@@ -28,3 +34,9 @@ This is the equivalent of `docker exec` targeting a Compose service.
With this subcommand, you can run arbitrary commands in your services. Commands allocate a TTY by default, so
you can use a command such as `docker compose exec web sh` to get an interactive prompt.
By default, Compose will enter container in interactive mode and allocate a TTY, while the equivalent `docker exec`
command requires passing `--interactive --tty` flags to get the same behavior. Compose also support those two flags
to offer a smooth migration between commands, whenever they are no-op by default. Still, `interactive` can be used to
force disabling interactive mode (`--interactive=false`), typically when `docker compose exec` command is used inside
a script.

View File

@@ -7,6 +7,7 @@ Publish compose application
| Name | Type | Default | Description |
|:--------------------------|:---------|:--------|:-------------------------------------------------------------------------------|
| `--app` | `bool` | | Published compose application (includes referenced images) |
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--oci-version` | `string` | | OCI image/artifact specification version (automatically determined by default) |
| `--resolve-image-digests` | `bool` | | Pin image tags to digests |

View File

@@ -44,6 +44,7 @@ If the process is interrupted using `SIGINT` (ctrl + C) or `SIGTERM`, the contai
| `--no-recreate` | `bool` | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--no-start` | `bool` | | Don't start the services after creating them |
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") |
| `--quiet-build` | `bool` | | Suppress the build output |
| `--quiet-pull` | `bool` | | Pull without printing progress information |
| `--remove-orphans` | `bool` | | Remove containers for services not defined in the Compose file |
| `-V`, `--renew-anon-volumes` | `bool` | | Recreate anonymous volumes instead of retrieving data from the previous containers |

View File

@@ -0,0 +1,16 @@
# docker compose volumes
<!---MARKER_GEN_START-->
List volumes
### Options
| Name | Type | Default | Description |
|:----------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--format` | `string` | `table` | 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 |
| `-q`, `--quiet` | `bool` | | Only display volume names |
<!---MARKER_GEN_END-->

View File

@@ -6,6 +6,7 @@ pname: docker
plink: docker.yaml
cname:
- docker compose attach
- docker compose bridge
- docker compose build
- docker compose commit
- docker compose config
@@ -36,10 +37,12 @@ cname:
- docker compose unpause
- docker compose up
- docker compose version
- docker compose volumes
- docker compose wait
- docker compose watch
clink:
- docker_compose_attach.yaml
- docker_compose_bridge.yaml
- docker_compose_build.yaml
- docker_compose_commit.yaml
- docker_compose_config.yaml
@@ -70,6 +73,7 @@ clink:
- docker_compose_unpause.yaml
- docker_compose_up.yaml
- docker_compose_version.yaml
- docker_compose_volumes.yaml
- docker_compose_wait.yaml
- docker_compose_watch.yaml
options:
@@ -167,7 +171,6 @@ options:
swarm: false
- option: progress
value_type: string
default_value: auto
description: Set type of progress output (auto, tty, plain, json, quiet)
deprecated: false
hidden: false

View File

@@ -45,7 +45,7 @@ inherited_options:
kubernetes: false
swarm: false
deprecated: false
hidden: false
hidden: true
experimental: false
experimentalcli: true
kubernetes: false

View File

@@ -5,6 +5,16 @@ usage: docker compose alpha publish [OPTIONS] REPOSITORY[:TAG]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
options:
- option: app
value_type: bool
default_value: "false"
description: Published compose application (includes referenced images)
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: oci-version
value_type: string
description: |
@@ -58,7 +68,7 @@ inherited_options:
kubernetes: false
swarm: false
deprecated: false
hidden: false
hidden: true
experimental: false
experimentalcli: true
kubernetes: false

View File

@@ -69,7 +69,7 @@ inherited_options:
kubernetes: false
swarm: false
deprecated: false
hidden: false
hidden: true
experimental: false
experimentalcli: true
kubernetes: false

View File

@@ -0,0 +1,29 @@
command: docker compose bridge
short: Convert compose files into another model
long: Convert compose files into another model
pname: docker compose
plink: docker_compose.yaml
cname:
- docker compose bridge convert
- docker compose bridge transformations
clink:
- docker_compose_bridge_convert.yaml
- docker_compose_bridge_transformations.yaml
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

@@ -0,0 +1,59 @@
command: docker compose bridge convert
short: |
Convert compose files to Kubernetes manifests, Helm charts, or another model
long: |
Convert compose files to Kubernetes manifests, Helm charts, or another model
usage: docker compose bridge convert
pname: docker compose bridge
plink: docker_compose_bridge.yaml
options:
- option: output
shorthand: o
value_type: string
default_value: out
description: The output directory for the Kubernetes resources
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: templates
value_type: string
description: Directory containing transformation templates
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: transformation
shorthand: t
value_type: stringArray
default_value: '[]'
description: |
Transformation to apply to compose model (default: docker/compose-bridge-kubernetes)
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

@@ -0,0 +1,29 @@
command: docker compose bridge transformations
short: Manage transformation images
long: Manage transformation images
pname: docker compose bridge
plink: docker_compose_bridge.yaml
cname:
- docker compose bridge transformations create
- docker compose bridge transformations list
clink:
- docker_compose_bridge_transformations_create.yaml
- docker_compose_bridge_transformations_list.yaml
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

@@ -0,0 +1,36 @@
command: docker compose bridge transformations create
short: Create a new transformation
long: Create a new transformation
usage: docker compose bridge transformations create [OPTION] PATH
pname: docker compose bridge transformations
plink: docker_compose_bridge_transformations.yaml
options:
- option: from
shorthand: f
value_type: string
description: |
Existing transformation to copy (default: docker/compose-bridge-kubernetes)
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

@@ -0,0 +1,47 @@
command: docker compose bridge transformations list
aliases: docker compose bridge transformations list, docker compose bridge transformations ls
short: List available transformations
long: List available transformations
usage: docker compose bridge transformations list
pname: docker compose bridge transformations
plink: docker_compose_bridge_transformations.yaml
options:
- option: format
value_type: string
default_value: table
description: 'Format the output. Values: [table | json]'
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: quiet
shorthand: q
value_type: bool
default_value: "false"
description: Only display transformer names
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

@@ -118,7 +118,6 @@ options:
swarm: false
- option: progress
value_type: string
default_value: auto
description: Set type of ui output (auto, tty, plain, json, quiet)
deprecated: false
hidden: true
@@ -126,6 +125,15 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: provenance
value_type: string
description: Add a provenance attestation
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: pull
value_type: bool
default_value: "false"
@@ -150,7 +158,16 @@ options:
shorthand: q
value_type: bool
default_value: "false"
description: Don't print anything to STDOUT
description: Suppress the build output
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: sbom
value_type: string
description: Add a SBOM attestation
deprecated: false
hidden: false
experimental: false

View File

@@ -56,6 +56,26 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: models
value_type: bool
default_value: "false"
description: Print the model names, one per line.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: networks
value_type: bool
default_value: "false"
description: Print the network names, one per line.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: no-consistency
value_type: bool
default_value: "false"

View File

@@ -34,6 +34,24 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: since
value_type: string
description: Show all events created since timestamp
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: until
value_type: string
description: Stream events until this timestamp
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool

View File

@@ -5,6 +5,12 @@ long: |-
With this subcommand, you can run arbitrary commands in your services. Commands allocate a TTY by default, so
you can use a command such as `docker compose exec web sh` to get an interactive prompt.
By default, Compose will enter container in interactive mode and allocate a TTY, while the equivalent `docker exec`
command requires passing `--interactive --tty` flags to get the same behavior. Compose also support those two flags
to offer a smooth migration between commands, whenever they are no-op by default. Still, `interactive` can be used to
force disabling interactive mode (`--interactive=false`), typically when `docker compose exec` command is used inside
a script.
usage: docker compose exec [OPTIONS] SERVICE COMMAND [ARGS...]
pname: docker compose
plink: docker_compose.yaml
@@ -52,7 +58,7 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: no-TTY
- option: no-tty
shorthand: T
value_type: bool
default_value: "true"

View File

@@ -5,6 +5,16 @@ usage: docker compose publish [OPTIONS] REPOSITORY[:TAG]
pname: docker compose
plink: docker_compose.yaml
options:
- option: app
value_type: bool
default_value: "false"
description: Published compose application (includes referenced images)
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: oci-version
value_type: string
description: |

View File

@@ -211,6 +211,16 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: quiet-build
value_type: bool
default_value: "false"
description: Suppress the build output
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: quiet-pull
value_type: bool
default_value: "false"

View File

@@ -0,0 +1,52 @@
command: docker compose volumes
short: List volumes
long: List volumes
usage: docker compose volumes [OPTIONS] [SERVICE...]
pname: docker compose
plink: docker_compose.yaml
options:
- option: format
value_type: string
default_value: table
description: |-
Format output using a custom template:
'table': Print output in table format with column headers (default)
'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
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: quiet
shorthand: q
value_type: bool
default_value: "false"
description: Only display volume names
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

103
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/docker/compose/v2
go 1.23.8
go 1.24.9
require (
github.com/AlecAivazis/survey/v2 v2.3.7
@@ -8,27 +8,28 @@ require (
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.6.4
github.com/containerd/containerd/v2 v2.1.1
github.com/compose-spec/compose-go/v2 v2.9.0
github.com/containerd/containerd/v2 v2.1.4
github.com/containerd/errdefs v1.0.0
github.com/containerd/platforms v1.0.0-rc.1
github.com/davecgh/go-spew v1.1.1
github.com/distribution/reference v0.6.0
github.com/docker/buildx v0.24.0
github.com/docker/cli v28.1.1+incompatible
github.com/docker/cli-docs-tool v0.9.0
github.com/docker/docker v28.1.1+incompatible
github.com/docker/go-connections v0.5.0
github.com/docker/buildx v0.29.1
github.com/docker/cli v28.5.1+incompatible
github.com/docker/cli-docs-tool v0.10.0
github.com/docker/docker v28.5.1+incompatible
github.com/docker/go-connections v0.6.0
github.com/docker/go-units v0.5.0
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
github.com/fsnotify/fsevents v0.2.0
github.com/go-viper/mapstructure/v2 v2.4.0
github.com/google/go-cmp v0.7.0
github.com/hashicorp/go-multierror v1.1.1
github.com/google/uuid v1.6.0
github.com/hashicorp/go-version v1.7.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.22.0
github.com/moby/buildkit v0.25.1
github.com/moby/go-archive v0.1.0
github.com/moby/patternmatcher v0.6.0
github.com/moby/sys/atomicwriter v0.1.0
@@ -39,33 +40,30 @@ require (
github.com/otiai10/copy v1.14.1
github.com/sirupsen/logrus v1.9.3
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
github.com/theupdateframework/notary v0.7.0
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0
go.opentelemetry.io/otel v1.35.0
go.opentelemetry.io/otel v1.36.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0
go.opentelemetry.io/otel/metric v1.35.0
go.opentelemetry.io/otel/sdk v1.35.0
go.opentelemetry.io/otel/trace v1.35.0
go.opentelemetry.io/otel/metric v1.36.0
go.opentelemetry.io/otel/sdk v1.36.0
go.opentelemetry.io/otel/trace v1.36.0
go.uber.org/goleak v1.3.0
go.uber.org/mock v0.5.2
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
golang.org/x/sync v0.14.0
golang.org/x/sys v0.33.0
google.golang.org/grpc v1.72.1
go.uber.org/mock v0.6.0
golang.org/x/sync v0.17.0
golang.org/x/sys v0.37.0
google.golang.org/grpc v1.74.2
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.2
tags.cncf.io/container-device-interface v1.0.1
)
require (
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/semver/v3 v3.4.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
@@ -83,15 +81,14 @@ require (
github.com/beorn7/perks v1.0.1 // 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/console v1.0.5 // indirect
github.com/containerd/containerd/api v1.9.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.7 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
@@ -100,12 +97,11 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-viper/mapstructure/v2 v2.0.0 // indirect
github.com/gofrs/flock v0.12.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
@@ -113,13 +109,13 @@ require (
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
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.26.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/in-toto/in-toto-golang v0.5.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/in-toto/in-toto-golang v0.9.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect
github.com/josharian/intern v1.0.0 // indirect
@@ -134,6 +130,7 @@ require (
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/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect
@@ -159,37 +156,37 @@ require (
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/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.6.0 // indirect
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/theupdateframework/notary v0.7.0 // indirect
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 // indirect
github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 // indirect
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 // indirect
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f // indirect
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
github.com/zclconf/go-cty v1.16.2 // indirect
github.com/zclconf/go-cty v1.17.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.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/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/oauth2 v0.29.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
google.golang.org/protobuf v1.36.6 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
@@ -205,7 +202,7 @@ require (
)
exclude (
// FIXME(thaJeztah): remoove this once kubernetes updated their dependencies to no longer need this.
// FIXME(thaJeztah): remove this once kubernetes updated their dependencies to no longer need this.
//
// For additional details, see this PR and links mentioned in that PR:
// https://github.com/kubernetes-sigs/kustomize/pull/5830#issuecomment-2569960859

201
go.sum
View File

@@ -1,5 +1,3 @@
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
@@ -10,8 +8,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4bOvKmDIx0WeTv9Qz+hghsgyjikFiPrseXHlKepO0=
github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e/go.mod h1:blbwPQh4DTlCZEfk1BLU4oMIhLda2U+A840Uag9DsZw=
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/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
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.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA=
@@ -80,16 +78,16 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
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.6.4 h1:Gjv6x8eAhqwwWvoXIo0oZ4bDQBh0OMwdU7LUL9PDLiM=
github.com/compose-spec/compose-go/v2 v2.6.4/go.mod h1:vPlkN0i+0LjLf9rv52lodNMUTJF5YHVfHVGLLIP67NA=
github.com/compose-spec/compose-go/v2 v2.9.0 h1:UHSv/QHlo6QJtrT4igF1rdORgIUhDo1gWuyJUoiNNIM=
github.com/compose-spec/compose-go/v2 v2.9.0/go.mod h1:Oky9AZGTRB4E+0VbTPZTUu4Kp+oEMMuwZXZtPPVT1iE=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
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/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc=
github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0=
github.com/containerd/containerd/api v1.9.0/go.mod h1:GhghKFmTR3hNtyznBoQ0EMWr9ju5AqHjcZPsSpTKutI=
github.com/containerd/containerd/v2 v2.1.1 h1:znnkm7Ajz8lg8BcIPMhc/9yjBRN3B+OkNKqKisKfwwM=
github.com/containerd/containerd/v2 v2.1.1/go.mod h1:zIfkQj4RIodclYQkX7GSSswSwgP8d/XxDOtOAoSDIGU=
github.com/containerd/containerd/v2 v2.1.4 h1:/hXWjiSFd6ftrBOBGfAZ6T30LJcx1dBjdKEeI8xucKQ=
github.com/containerd/containerd/v2 v2.1.4/go.mod h1:8C5QV9djwsYDNhxfTCFjWtTBZrqjditQ4/ghHSYjnHM=
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=
@@ -100,8 +98,8 @@ github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/nydus-snapshotter v0.15.0 h1:RqZRs1GPeM6T3wmuxJV9u+2Rg4YETVMwTmiDeX+iWC8=
github.com/containerd/nydus-snapshotter v0.15.0/go.mod h1:biq0ijpeZe0I5yZFSJyHzFSjjRZQ7P7y/OuHyd7hYOw=
github.com/containerd/nydus-snapshotter v0.15.2 h1:qsHI4M+Wwrf6Jr4eBqhNx8qh+YU0dSiJ+WPmcLFWNcg=
github.com/containerd/nydus-snapshotter v0.15.2/go.mod h1:FfwH2KBkNYoisK/e+KsmNr7xTU53DmnavQHMFOcXwfM=
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=
@@ -113,8 +111,9 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
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.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
github.com/cpuguy83/go-md2man/v2 v2.0.7/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.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
@@ -125,24 +124,26 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
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.24.0 h1:qiD+xktY+Fs3R79oz8M+7pbhip78qGLx6LBuVmyb+64=
github.com/docker/buildx v0.24.0/go.mod h1:vYkdBUBjFo/i5vUE0mkajGlk03gE0T/HaGXXhgIxo8E=
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
github.com/docker/cli v28.1.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/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/buildx v0.29.1 h1:58hxM5Z4mnNje3G5NKfULT9xCr8ooM8XFtlfUK9bKaA=
github.com/docker/buildx v0.29.1/go.mod h1:J4EFv6oxlPiV1MjO0VyJx2u5tLM7ImDEl9zyB8d4wPI=
github.com/docker/cli v28.5.1+incompatible h1:ESutzBALAD6qyCLqbQSEf1a/U8Ybms5agw59yGVc+yY=
github.com/docker/cli v28.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.10.0 h1:bOD6mKynPQgojQi3s2jgcUWGp/Ebqy1SeCr9VfKQLLU=
github.com/docker/cli-docs-tool v0.10.0/go.mod h1:5EM5zPnT2E7yCLERZmrDA234Vwn09fzRHP4aX1qwp1U=
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 v28.1.1+incompatible h1:49M11BFLsVO1gxY9UX9p/zwkE/rswggs8AdFmXQw51I=
github.com/docker/docker v28.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM=
github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
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-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
github.com/docker/go-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=
@@ -169,8 +170,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/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/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
@@ -186,8 +187,8 @@ github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.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/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -216,8 +217,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
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-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
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=
@@ -243,8 +244,8 @@ github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY=
github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE=
github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU=
github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -315,8 +316,8 @@ 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.22.0 h1:aWN06w1YGSVN1XfeZbj2ZbgY+zi5xDAjEFI8Cy9fTjA=
github.com/moby/buildkit v0.22.0/go.mod h1:j4pP5hxiTWcz7xuTK2cyxQislHl/N2WWHzOy43DlLJw=
github.com/moby/buildkit v0.25.1 h1:j7IlVkeNbEo+ZLoxdudYCHpmTsbwKvhgc/6UJ/mY/o8=
github.com/moby/buildkit v0.25.1/go.mod h1:phM8sdqnvgK2y1dPDnbwI6veUCXHOZ6KFSl6E164tkc=
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/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
@@ -423,8 +424,10 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
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=
github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/secure-systems-lab/go-securesystemslib v0.6.0 h1:T65atpAVCJQK14UA57LMdZGpHi4QYSH/9FZyNGqMYIA=
github.com/secure-systems-lab/go-securesystemslib v0.6.0/go.mod h1:8Mtpo9JKks/qhPG4HGZ2LGMvrPbzuxwfz/f/zLfEWkk=
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU=
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
@@ -436,18 +439,19 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQraY=
github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI=
github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XOmk=
github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk=
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
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.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/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=
@@ -464,18 +468,18 @@ 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA=
github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g=
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4=
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 h1:k9tdF32oJYwtjzMx+D26M6eYiCaAPdJ7tyN7tF1oU5Q=
github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
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/fsutil v0.0.0-20250605211040-586307ad452f h1:MoxeMfHAe5Qj/ySSBfL8A7l1V+hxuluj8owsIEEZipI=
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE=
github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0/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=
@@ -484,56 +488,51 @@ github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnn
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
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=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
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.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0=
github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
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/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
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 v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 h1:0NIXxOCFx+SKbhCVxwl3ETG8ClLPAa0KuKV6p3yhxP8=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0/go.mod h1:ChZSJbbfbl/DcRZNc9Gqh6DYGlfjw4PvO1pEOZH1ZsE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
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=
@@ -542,15 +541,13 @@ 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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
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.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
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=
@@ -560,10 +557,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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
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=
@@ -571,8 +568,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.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
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=
@@ -594,19 +591,19 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
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.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -614,21 +611,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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
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/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0=
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
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.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=

View File

@@ -1,62 +0,0 @@
/*
Copyright 2024 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 desktop
import (
"context"
"fmt"
"strings"
"time"
"github.com/docker/cli/cli/command"
)
// engineLabelDesktopAddress is used to detect that Compose is running with a
// Docker Desktop context. When this label is present, the value is an endpoint
// address for an in-memory socket (AF_UNIX or named pipe).
const engineLabelDesktopAddress = "com.docker.desktop.address"
// NewFromDockerClient creates a Desktop Client using the Docker CLI client to
// auto-discover the Desktop CLI socket endpoint (if available).
//
// An error is returned if there is a failure communicating with Docker Desktop,
// but even on success, a nil Client can be returned if the active Docker Engine
// is not a Desktop instance.
func NewFromDockerClient(ctx context.Context, dockerCli command.Cli) (*Client, error) {
// safeguard to make sure this doesn't get stuck indefinitely
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
info, err := dockerCli.Client().Info(ctx)
if err != nil {
return nil, fmt.Errorf("querying server info: %w", err)
}
for _, l := range info.Labels {
k, v, ok := strings.Cut(l, "=")
if !ok || k != engineLabelDesktopAddress {
continue
}
desktopCli := NewClient(v)
_, err := desktopCli.Ping(ctx)
if err != nil {
return nil, fmt.Errorf("pinging Desktop API: %w", err)
}
return desktopCli, nil
}
return nil, nil
}

View File

@@ -1,4 +1,4 @@
//go:build linux || openbsd
//go:build linux || openbsd || freebsd
/*
Copyright 2020 Docker Compose CLI authors

View File

@@ -14,7 +14,7 @@
limitations under the License.
*/
package ocipush
package oci
import (
"context"
@@ -23,11 +23,12 @@ import (
"fmt"
"net/http"
"path/filepath"
"slices"
"time"
"github.com/containerd/containerd/v2/core/remotes"
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"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
@@ -66,11 +67,6 @@ var clientAuthStatusCodes = []int{
http.StatusProxyAuthRequired,
}
type Pushable struct {
Descriptor v1.Descriptor
Data []byte
}
func DescriptorForComposeFile(path string, content []byte) v1.Descriptor {
return v1.Descriptor{
MediaType: ComposeYAMLMediaType,
@@ -80,6 +76,7 @@ func DescriptorForComposeFile(path string, content []byte) v1.Descriptor {
"com.docker.compose.version": api.ComposeVersion,
"com.docker.compose.file": filepath.Base(path),
},
Data: content,
}
}
@@ -92,26 +89,24 @@ func DescriptorForEnvFile(path string, content []byte) v1.Descriptor {
"com.docker.compose.version": api.ComposeVersion,
"com.docker.compose.envfile": filepath.Base(path),
},
Data: content,
}
}
func PushManifest(
ctx context.Context,
resolver *imagetools.Resolver,
named reference.Named,
layers []Pushable,
ociVersion api.OCIVersion,
) error {
func PushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, 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("{}")})
err := push(ctx, resolver, named, v1.DescriptorEmptyJSON)
if err != nil {
return v1.Descriptor{}, err
}
}
// prepare to push the manifest by pushing the layers
layerDescriptors := make([]v1.Descriptor, len(layers))
for i := range layers {
layerDescriptors[i] = layers[i].Descriptor
if err := resolver.Push(ctx, named, layers[i].Descriptor, layers[i].Data); err != nil {
return err
layerDescriptors[i] = layers[i]
if err := push(ctx, resolver, named, layers[i]); err != nil {
return v1.Descriptor{}, err
}
}
@@ -123,33 +118,36 @@ func PushManifest(
// try to push in the OCI 1.1 format but fallback to OCI 1.0 on 4xx errors
// (other than auth) since it's most likely the result of the registry not
// having support
err := createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_1)
descriptor, err := createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_1)
var pushErr pusherrors.ErrUnexpectedStatus
if errors.As(err, &pushErr) && isNonAuthClientError(pushErr.StatusCode) {
// TODO(milas): show a warning here (won't work with logrus)
return createAndPushManifest(ctx, resolver, named, layerDescriptors, api.OCIVersion1_0)
}
return err
return descriptor, err
}
func createAndPushManifest(
ctx context.Context,
resolver *imagetools.Resolver,
named reference.Named,
layers []v1.Descriptor,
ociVersion api.OCIVersion,
) error {
toPush, err := generateManifest(layers, ociVersion)
func push(ctx context.Context, resolver remotes.Resolver, ref reference.Named, descriptor v1.Descriptor) error {
fullRef, err := reference.WithDigest(reference.TagNameOnly(ref), descriptor.Digest)
if err != nil {
return err
}
return Push(ctx, resolver, fullRef, descriptor)
}
func createAndPushManifest(ctx context.Context, resolver remotes.Resolver, named reference.Named, layers []v1.Descriptor, ociVersion api.OCIVersion) (v1.Descriptor, error) {
descriptor, toPush, err := generateManifest(layers, ociVersion)
if err != nil {
return v1.Descriptor{}, err
}
for _, p := range toPush {
err = resolver.Push(ctx, named, p.Descriptor, p.Data)
err = push(ctx, resolver, named, p)
if err != nil {
return err
return v1.Descriptor{}, err
}
}
return nil
return descriptor, nil
}
func isNonAuthClientError(statusCode int) bool {
@@ -157,18 +155,11 @@ func isNonAuthClientError(statusCode int) bool {
// not a client error
return false
}
for _, v := range clientAuthStatusCodes {
if statusCode == v {
// client auth error
return false
}
}
// any other 4xx client error
return true
return !slices.Contains(clientAuthStatusCodes, statusCode)
}
func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]Pushable, error) {
var toPush []Pushable
func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) (v1.Descriptor, []v1.Descriptor, error) {
var toPush []v1.Descriptor
var config v1.Descriptor
var artifactType string
switch ociCompat {
@@ -188,18 +179,18 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]Pusha
MediaType: ComposeEmptyConfigMediaType,
Digest: digest.FromBytes(configData),
Size: int64(len(configData)),
Data: configData,
}
// N.B. OCI 1.0 does NOT support specifying the artifact type, so it's
// left as an empty string to omit it from the marshaled JSON
artifactType = ""
toPush = append(toPush, Pushable{Descriptor: config, Data: configData})
toPush = append(toPush, config)
case api.OCIVersion1_1:
config = v1.DescriptorEmptyJSON
artifactType = ComposeProjectArtifactType
// N.B. the descriptor has the data embedded in it
toPush = append(toPush, Pushable{Descriptor: config, Data: make([]byte, len(config.Data))})
toPush = append(toPush, config)
default:
return nil, fmt.Errorf("unsupported OCI version: %s", ociCompat)
return v1.Descriptor{}, nil, fmt.Errorf("unsupported OCI version: %s", ociCompat)
}
manifest, err := json.Marshal(v1.Manifest{
@@ -213,7 +204,7 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]Pusha
},
})
if err != nil {
return nil, err
return v1.Descriptor{}, nil, err
}
manifestDescriptor := v1.Descriptor{
@@ -224,7 +215,8 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]Pusha
"com.docker.compose.version": api.ComposeVersion,
},
ArtifactType: artifactType,
Data: manifest,
}
toPush = append(toPush, Pushable{Descriptor: manifestDescriptor, Data: manifest})
return toPush, nil
toPush = append(toPush, manifestDescriptor)
return manifestDescriptor, toPush, nil
}

137
internal/oci/resolver.go Normal file
View File

@@ -0,0 +1,137 @@
/*
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 oci
import (
"context"
"io"
"net/url"
"strings"
"github.com/containerd/containerd/v2/core/remotes"
"github.com/containerd/containerd/v2/core/remotes/docker"
"github.com/containerd/containerd/v2/pkg/labels"
"github.com/containerd/errdefs"
"github.com/distribution/reference"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/compose/v2/internal/registry"
"github.com/moby/buildkit/util/contentutil"
spec "github.com/opencontainers/image-spec/specs-go/v1"
)
// NewResolver setup an OCI Resolver based on docker/cli config to provide registry credentials
func NewResolver(config *configfile.ConfigFile) remotes.Resolver {
return docker.NewResolver(docker.ResolverOptions{
Hosts: docker.ConfigureDefaultRegistries(
docker.WithAuthorizer(docker.NewDockerAuthorizer(
docker.WithAuthCreds(func(host string) (string, string, error) {
host = registry.GetAuthConfigKey(host)
auth, err := config.GetAuthConfig(host)
if err != nil {
return "", "", err
}
if auth.IdentityToken != "" {
return "", auth.IdentityToken, nil
}
return auth.Username, auth.Password, nil
}),
)),
),
})
}
// Get retrieves a Named OCI resource and returns OCI Descriptor and Manifest
func Get(ctx context.Context, resolver remotes.Resolver, ref reference.Named) (spec.Descriptor, []byte, error) {
_, descriptor, err := resolver.Resolve(ctx, ref.String())
if err != nil {
return spec.Descriptor{}, nil, err
}
fetcher, err := resolver.Fetcher(ctx, ref.String())
if err != nil {
return spec.Descriptor{}, nil, err
}
fetch, err := fetcher.Fetch(ctx, descriptor)
if err != nil {
return spec.Descriptor{}, nil, err
}
content, err := io.ReadAll(fetch)
if err != nil {
return spec.Descriptor{}, nil, err
}
return descriptor, content, nil
}
func Copy(ctx context.Context, resolver remotes.Resolver, image reference.Named, named reference.Named) (spec.Descriptor, error) {
src, desc, err := resolver.Resolve(ctx, image.String())
if err != nil {
return spec.Descriptor{}, err
}
if desc.Annotations == nil {
desc.Annotations = make(map[string]string)
}
// set LabelDistributionSource so push will actually use a registry mount
refspec := reference.TrimNamed(image).String()
u, err := url.Parse("dummy://" + refspec)
if err != nil {
return spec.Descriptor{}, err
}
source, repo := u.Hostname(), strings.TrimPrefix(u.Path, "/")
desc.Annotations[labels.LabelDistributionSource+"."+source] = repo
p, err := resolver.Pusher(ctx, named.Name())
if err != nil {
return spec.Descriptor{}, err
}
f, err := resolver.Fetcher(ctx, src)
if err != nil {
return spec.Descriptor{}, err
}
err = contentutil.CopyChain(ctx,
contentutil.FromPusher(p),
contentutil.FromFetcher(f), desc)
return desc, err
}
func Push(ctx context.Context, resolver remotes.Resolver, ref reference.Named, descriptor spec.Descriptor) error {
pusher, err := resolver.Pusher(ctx, ref.String())
if err != nil {
return err
}
ctx = remotes.WithMediaTypeKeyPrefix(ctx, ComposeYAMLMediaType, "artifact-")
ctx = remotes.WithMediaTypeKeyPrefix(ctx, ComposeEnvFileMediaType, "artifact-")
ctx = remotes.WithMediaTypeKeyPrefix(ctx, ComposeEmptyConfigMediaType, "config-")
ctx = remotes.WithMediaTypeKeyPrefix(ctx, spec.MediaTypeEmptyJSON, "config-")
push, err := pusher.Push(ctx, descriptor)
if errdefs.IsAlreadyExists(err) {
return nil
}
if err != nil {
return err
}
_, err = push.Write(descriptor.Data)
if err != nil {
// Close the writer on error since Commit won't be called
_ = push.Close()
return err
}
// Commit will close the writer
return push.Commit(ctx, int64(len(descriptor.Data)), descriptor.Digest)
}

View File

@@ -0,0 +1,44 @@
/*
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 registry
const (
// DefaultNamespace is the default namespace
DefaultNamespace = "docker.io"
// DefaultRegistryHost is the hostname for the default (Docker Hub) registry
// used for pushing and pulling images. This hostname is hard-coded to handle
// the conversion from image references without registry name (e.g. "ubuntu",
// or "ubuntu:latest"), as well as references using the "docker.io" domain
// name, which is used as canonical reference for images on Docker Hub, but
// does not match the domain-name of Docker Hub's registry.
DefaultRegistryHost = "registry-1.docker.io"
// IndexHostname is the index hostname, used for authentication and image search.
IndexHostname = "index.docker.io"
// IndexServer is used for user auth and image search
IndexServer = "https://" + IndexHostname + "/v1/"
// IndexName is the name of the index
IndexName = "docker.io"
)
// GetAuthConfigKey special-cases using the full index address of the official
// index as the AuthConfig key, and uses the (host)name[:port] for private indexes.
func GetAuthConfigKey(indexName string) string {
if indexName == IndexName || indexName == IndexHostname || indexName == DefaultRegistryHost {
return IndexServer
}
return indexName
}

View File

@@ -29,11 +29,11 @@ import (
"path"
"path/filepath"
"strings"
"github.com/hashicorp/go-multierror"
"sync"
"github.com/docker/docker/api/types/container"
"github.com/moby/go-archive"
"golang.org/x/sync/errgroup"
)
type archiveEntry struct {
@@ -84,7 +84,14 @@ func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) er
if len(pathsToDelete) != 0 {
deleteCmd = append([]string{"rm", "-rf"}, pathsToDelete...)
}
var eg multierror.Group
var (
eg errgroup.Group
errMu sync.Mutex
errs = make([]error, 0, len(containers)*2) // max 2 errs per container
)
eg.SetLimit(16) // arbitrary limit, adjust to taste :D
for i := range containers {
containerID := containers[i].ID
tarReader := tarArchive(pathsToCopy)
@@ -92,17 +99,23 @@ func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) er
eg.Go(func() error {
if len(deleteCmd) != 0 {
if err := t.client.Exec(ctx, containerID, deleteCmd, nil); err != nil {
return fmt.Errorf("deleting paths in %s: %w", containerID, err)
errMu.Lock()
errs = append(errs, fmt.Errorf("deleting paths in %s: %w", containerID, err))
errMu.Unlock()
}
}
if err := t.client.Untar(ctx, containerID, tarReader); err != nil {
return fmt.Errorf("copying files to %s: %w", containerID, err)
errMu.Lock()
errs = append(errs, fmt.Errorf("copying files to %s: %w", containerID, err))
errMu.Unlock()
}
return nil
return nil // don't fail-fast; collect all errors
})
}
return eg.Wait().ErrorOrNil()
_ = eg.Wait()
return errors.Join(errs...)
}
type ArchiveBuilder struct {
@@ -229,7 +242,7 @@ func (a *ArchiveBuilder) writeEntry(entry archiveEntry) error {
return nil
}
// tarPath writes the given source path into tarWriter at the given dest (recursively for directories).
// entriesForPath writes the given source path into tarWriter at the given dest (recursively for directories).
// e.g. tarring my_dir --> dest d: d/file_a, d/file_b
// If source path does not exist, quietly skips it and returns no err
func (a *ArchiveBuilder) entriesForPath(localPath, containerPath string) ([]archiveEntry, error) {

View File

@@ -77,11 +77,13 @@ func ProjectOptions(ctx context.Context, proj *types.Project) SpanOptions {
attribute.StringSlice("project.networks", proj.NetworkNames()),
attribute.StringSlice("project.secrets", proj.SecretNames()),
attribute.StringSlice("project.configs", proj.ConfigNames()),
attribute.StringSlice("project.models", proj.ModelNames()),
attribute.StringSlice("project.extensions", keys(proj.Extensions)),
attribute.StringSlice("project.services.active", proj.ServiceNames()),
attribute.StringSlice("project.services.disabled", proj.DisabledServiceNames()),
attribute.StringSlice("project.services.build", proj.ServicesWithBuild()),
attribute.StringSlice("project.services.depends_on", proj.ServicesWithDependsOn()),
attribute.StringSlice("project.services.models", proj.ServicesWithModels()),
attribute.StringSlice("project.services.capabilities", capabilities),
attribute.StringSlice("project.services.capabilities.gpu", gpu),
attribute.StringSlice("project.services.capabilities.tpu", tpu),
@@ -110,6 +112,7 @@ func ServiceOptions(service types.ServiceConfig) SpanOptions {
attribute.String("service.name", service.Name),
attribute.String("service.image", service.Image),
attribute.StringSlice("service.networks", keys(service.Networks)),
attribute.StringSlice("service.models", keys(service.Models)),
}
configNames := make([]string, len(service.Configs))

View File

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

View File

@@ -18,8 +18,9 @@ package tracing
import (
"context"
"errors"
"sync"
"github.com/hashicorp/go-multierror"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
@@ -28,23 +29,45 @@ type MuxExporter struct {
}
func (m MuxExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error {
var eg multierror.Group
for i := range m.exporters {
exporter := m.exporters[i]
eg.Go(func() error {
return exporter.ExportSpans(ctx, spans)
})
var (
wg sync.WaitGroup
errMu sync.Mutex
errs = make([]error, 0, len(m.exporters))
)
for _, exporter := range m.exporters {
wg.Add(1)
go func() {
defer wg.Done()
if err := exporter.ExportSpans(ctx, spans); err != nil {
errMu.Lock()
errs = append(errs, err)
errMu.Unlock()
}
}()
}
return eg.Wait()
wg.Wait()
return errors.Join(errs...)
}
func (m MuxExporter) Shutdown(ctx context.Context) error {
var eg multierror.Group
for i := range m.exporters {
exporter := m.exporters[i]
eg.Go(func() error {
return exporter.Shutdown(ctx)
})
var (
wg sync.WaitGroup
errMu sync.Mutex
errs = make([]error, 0, len(m.exporters))
)
for _, exporter := range m.exporters {
wg.Add(1)
go func() {
defer wg.Done()
if err := exporter.Shutdown(ctx); err != nil {
errMu.Lock()
errs = append(errs, err)
errMu.Unlock()
}
}()
}
return eg.Wait()
wg.Wait()
return errors.Join(errs...)
}

View File

@@ -19,16 +19,20 @@ package api
import (
"context"
"fmt"
"io"
"slices"
"strings"
"time"
"github.com/compose-spec/compose-go/v2/types"
"github.com/containerd/platforms"
"github.com/docker/cli/opts"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/docker/api/types/volume"
)
// Service manages a compose project
type Service interface {
// Compose is the API interface one can use to programmatically use docker/compose in a third-party software
// Use [compose.NewComposeService] to get an actual instance
type Compose interface {
// Build executes the equivalent to a `compose build`
Build(ctx context.Context, project *types.Project, options BuildOptions) error
// Push executes the equivalent to a `compose push`
@@ -78,13 +82,13 @@ type Service interface {
// Publish executes the equivalent to a `compose publish`
Publish(ctx context.Context, project *types.Project, repository string, options PublishOptions) error
// Images executes the equivalent of a `compose images`
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
Images(ctx context.Context, projectName string, options ImagesOptions) (map[string]ImageSummary, error)
// MaxConcurrency defines upper limit for concurrent operations against engine API
MaxConcurrency(parallel int)
// DryRunMode defines if dry run applies to the command
DryRunMode(ctx context.Context, dryRun bool) (context.Context, error)
// Watch services' development context and sync/notify/rebuild/restart on changes
Watch(ctx context.Context, project *types.Project, services []string, options WatchOptions) error
Watch(ctx context.Context, project *types.Project, options WatchOptions) error
// Viz generates a graphviz graph of the project services
Viz(ctx context.Context, project *types.Project, options VizOptions) (string, error)
// Wait blocks until at least one of the services' container exits
@@ -97,8 +101,16 @@ type Service interface {
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)
// Volumes executes the equivalent to a `docker volume ls`
Volumes(ctx context.Context, project string, options VolumesOptions) ([]VolumesSummary, error)
}
type VolumesOptions struct {
Services []string
}
type VolumesSummary = *volume.Volume
type ScaleOptions struct {
Services []string
}
@@ -126,9 +138,10 @@ const WatchLogger = "#watch"
// WatchOptions group options of the Watch API
type WatchOptions struct {
Build *BuildOptions
LogTo LogConsumer
Prune bool
Build *BuildOptions
LogTo LogConsumer
Prune bool
Services []string
}
// BuildOptions group options of the Build API
@@ -159,8 +172,14 @@ type BuildOptions struct {
Print bool
// Check let builder validate build configuration
Check bool
// Provenance
Provenance bool
// Attestations allows to enable attestations generation
Attestations bool
// Provenance generate a provenance attestation
Provenance string
// SBOM generate a SBOM attestation
SBOM string
// Out is the stream to write build progress
Out io.Writer
}
// Apply mutates project according to build options
@@ -175,13 +194,13 @@ func (o BuildOptions) Apply(project *types.Project) error {
continue
}
if platform != "" {
if len(service.Build.Platforms) > 0 && !utils.StringContains(service.Build.Platforms, platform) {
if len(service.Build.Platforms) > 0 && !slices.Contains(service.Build.Platforms, platform) {
return fmt.Errorf("service %q build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: %s", name, platform)
}
service.Platform = platform
}
if service.Platform != "" {
if len(service.Build.Platforms) > 0 && !utils.StringContains(service.Build.Platforms, service.Platform) {
if len(service.Build.Platforms) > 0 && !slices.Contains(service.Build.Platforms, service.Platform) {
return fmt.Errorf("service %q build configuration does not support platform: %s", name, service.Platform)
}
}
@@ -349,7 +368,7 @@ type RemoveOptions struct {
// RunOptions group options of the Run API
type RunOptions struct {
Build *BuildOptions
CreateOptions
// Project is the compose project used to define this app. Might be nil if user ran command just with project name
Project *types.Project
Name string
@@ -369,8 +388,6 @@ type RunOptions struct {
Privileged bool
UseNetworkAliases bool
NoDeps bool
// QuietPull makes the pulling process quiet
QuietPull bool
// used by exec
Index int
}
@@ -389,6 +406,8 @@ type AttachOptions struct {
type EventsOptions struct {
Services []string
Consumer func(event Event) error
Since string
Until string
}
// Event is a container runtime event served by Events API
@@ -426,9 +445,10 @@ const (
// PublishOptions group options of the Publish API
type PublishOptions struct {
ResolveImageDigests bool
Application bool
WithEnvironment bool
AssumeYes bool
AssumeYes bool
OCIVersion OCIVersion
}
@@ -535,12 +555,13 @@ type ContainerProcSummary struct {
// ImageSummary holds container image description
type ImageSummary struct {
ID string
ContainerName string
Repository string
Tag string
Size int64
LastTagTime time.Time
ID string
Repository string
Tag string
Platform platforms.Platform
Size int64
Created time.Time
LastTagTime time.Time
}
// ServiceStatus hold status about a service
@@ -638,7 +659,6 @@ type LogConsumer interface {
Log(containerName, message string)
Err(containerName, message string)
Status(container, msg string)
Register(container string)
}
// ContainerEventListener is a callback to process ContainerEvent from services
@@ -646,16 +666,18 @@ type ContainerEventListener func(event ContainerEvent)
// ContainerEvent notify an event has been collected on source container implementing Service
type ContainerEvent struct {
Type int
// Container is the name of the container _without the project prefix_.
Type int
Time int64
Container *ContainerSummary
// Source is the name of the container _without the project prefix_.
//
// This is only suitable for display purposes within Compose, as it's
// not guaranteed to be unique across services.
Container string
ID string
Service string
Line string
// ContainerEventExit only
Source string
ID string
Service string
Line string
// ExitCode is only set on ContainerEventExited events
ExitCode int
Restarting bool
}
@@ -665,17 +687,19 @@ const (
ContainerEventLog = iota
// ContainerEventErr is a ContainerEvent of type log on stderr. Line is set
ContainerEventErr
// ContainerEventAttach is a ContainerEvent of type attach. First event sent about a container
ContainerEventAttach
// ContainerEventStarted let consumer know a container has been started
ContainerEventStarted
// ContainerEventRestarted let consumer know a container has been restarted
ContainerEventRestarted
// ContainerEventStopped is a ContainerEvent of type stopped.
ContainerEventStopped
// ContainerEventCreated let consumer know a new container has been created
ContainerEventCreated
// ContainerEventRecreated let consumer know container stopped but his being replaced
ContainerEventRecreated
// ContainerEventExit is a ContainerEvent of type exit. ExitCode is set
ContainerEventExit
// ContainerEventExited is a ContainerEvent of type exit. ExitCode is set
ContainerEventExited
// UserCancel user cancelled compose up, we are stopping containers
UserCancel
// HookEventLog is a ContainerEvent of type log on stdout by service hook
HookEventLog
)

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