Compare commits

...

519 Commits

Author SHA1 Message Date
Nicolas De Loof
9c4efbdd92 Strip project prefix from docker-compose up output
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-15 21:39:16 +01:00
Nicolas De Loof
c16943609c render quiet after filtering applied
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-15 20:25:40 +01:00
Guillaume Lours
254a94b07d bump golang to version 1.21.4
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-11-13 22:16:33 +01:00
Nicolas De Loof
cf608fa954 bump compose-go to v1.20.1
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-13 22:07:02 +01:00
Nicolas De Loof
426377a4c9 reject compose file using secrets|configs.driver or template_driver
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-13 17:26:00 +01:00
Guillaume Lours
43c3f54598 Merge pull request #11180 from ulyssessouza/skip-flaky-tests
skips flaky e2e tests on watch and attach
2023-11-10 19:51:00 +01:00
Ulysses Souza
493f6c8055 skips flaky e2e tests on watch and attach
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2023-11-10 18:31:25 +01:00
Guillaume Lours
c1a9ffa07e Merge pull request #11171 from szampardi/main
fix docker/compose#11170 add newline in cmd/compose/build.go fmt.Fprint
2023-11-08 23:23:16 +01:00
szampardi
646a8fc0e8 fix docker/compose#11170 add newline in cmd/compose/build.go fmt.Fprint
Signed-off-by: szampardi <szampardi@deepnull.com>
2023-11-08 16:17:23 +01:00
Nicolas De Loof
2945532f97 fix --pull documentation
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-07 09:03:49 +01:00
Guillaume Lours
e5cd265abb improve watch configuration logging
Add action associated to each managed path

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-11-06 13:48:15 +01:00
Nicolas De Loof
d646d757a2 lint
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 11:16:35 +01:00
Nicolas De Loof
71237ef62b do not resolve cache dir until remote resource is in use
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 11:16:35 +01:00
Nicolas De Loof
0d905a896d add a copyright notice with original author
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 11:16:35 +01:00
Nicolas De Loof
b847c7f5a4 implement runtime file selection
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 11:16:35 +01:00
Nicolas De Loof
5e3d8f671d re-implement cache folder detection
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 11:16:35 +01:00
Nicolas De Loof
6727908803 introduce --resolve-image-digests for publish to seal service images by digest
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-11-02 10:43:45 +01:00
Guillaume Lours
5661fd1bfe Merge pull request #11149 from aevesdocker/ENGDOCS-1764
ENGDOCS-1764: Trivial fixes
2023-11-02 10:30:10 +01:00
aevesdocker
4cd61957ed fix build
Signed-off-by: aevesdocker <allie.sadler@docker.com>
2023-10-31 10:50:42 +00:00
aevesdocker
0d4cbbdbc9 fix
Signed-off-by: aevesdocker <allie.sadler@docker.com>
2023-10-31 10:44:59 +00:00
aevesdocker
9631a49daa ENGDOCS-1764
Signed-off-by: aevesdocker <allie.sadler@docker.com>
2023-10-31 10:40:48 +00:00
David Karlsson
328ca3f239 add docs upstream validation workflow
verifies that the reference docs don't contain broken links etc

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2023-10-30 18:36:30 +01:00
dependabot[bot]
e1bbfc6376 build(deps): bump go.uber.org/goleak from 1.2.1 to 1.3.0
Bumps [go.uber.org/goleak](https://github.com/uber-go/goleak) from 1.2.1 to 1.3.0.
- [Release notes](https://github.com/uber-go/goleak/releases)
- [Changelog](https://github.com/uber-go/goleak/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/goleak/compare/v1.2.1...v1.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 08:18:38 +01:00
kimdcottrell
616bba0afd linter errors fixed
Signed-off-by: kimdcottrell <me@kimdcottrell.com>
2023-10-29 22:08:00 +01:00
kimdcottrell
ee6e3c2a44 NetworkList to NetworkInspect for ID search
Signed-off-by: kimdcottrell <me@kimdcottrell.com>
2023-10-29 22:08:00 +01:00
kimdcottrell
c7e31a3c15 Squashing feature branch commits in order to add signoff message.
- added clarity with error handling. added test to show issue.

- in manual testing, this fixes the issue and allows watch to run after rebuild

- added cleanup back in

- fixed issue where watch extnet rebuild test would start all containers listed in the fixture

Signed-off-by: kimdcottrell <me@kimdcottrell.com>
2023-10-29 22:08:00 +01:00
Matthew Walowski
704a9fd337 Use project.ServiceNames() if no service specified in hash
Signed-off-by: Matthew Walowski <mattwalowski@gmail.com>
2023-10-27 21:16:15 +02:00
temenuzhka-thede
d9e0e42d95 Add branch configuration for pull_request trigger
Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

Add check-latest option to set up go step

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>
2023-10-27 09:17:32 +02:00
temenuzhka-thede
c48e3c4a4f Initial codeql.yml commit
Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

add new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove new line

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove os customization

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>

remove os customization

Signed-off-by: temenuzhka-thede <temenuzhka.thede@docker.com>
2023-10-27 09:17:32 +02:00
Nicolas De Loof
dd0803dba1 fix SIGTERM support to stop/kill stack
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-10-26 12:19:50 +02:00
Nicolas De Loof
39008c539c align with OCI artifact best practices
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-10-23 20:26:13 +02:00
Guillaume Lours
6ab41d629f Merge pull request #11060 from Juneezee/refactor/redundant-len-check
refactor(cmd/compose/run): remove redundant `len` check
2023-10-23 10:32:46 +02:00
Eng Zer Jun
6c345b3755 refactor(cmd/compose/run): remove redundant len check
From the Go specification [1]:

  "1. For a nil slice, the number of iterations is 0."

`len` returns 0 if the slice is nil [2]. Therefore, checking
`len(v) > 0` before a loop is unnecessary.

[1]: https://go.dev/ref/spec#For_range
[2]: https://pkg.go.dev/builtin#len

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2023-10-23 16:06:52 +08:00
Guillaume Lours
b8773ad1c5 Merge pull request #11110 from ndeloof/wait_missing
fail start if depependency is missing
2023-10-19 10:04:32 +02:00
Nicolas De Loof
1ffa194e12 fail start if depependency is missing
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-10-19 09:50:37 +02:00
Guillaume Lours
b92981015e check that the pull policy provided is a valid one
or is not missing when --pull is used

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-18 15:44:37 +02:00
Guillaume Lours
af87f10650 Merge pull request #11108 from ndeloof/down-services
enable profile when down is ran with explicit service names
2023-10-18 13:49:11 +02:00
Guillaume Lours
5e1d3f2b41 Merge pull request #11051 from ndeloof/warn_remote_disabled
warn user remote resource is disabled
2023-10-18 12:54:40 +02:00
Guillaume Lours
3d0207ebc8 remove uncessary return value of pullComposeFiles function
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-18 12:42:11 +02:00
Nicolas De Loof
16a7c20960 enable profile when down is ran with explicit service names
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-10-18 12:19:45 +02:00
Guillaume Lours
818bc3c34a add sync+restart action to watch attribute
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-18 12:11:02 +02:00
Guillaume Lours
cf3e686d8c Merge pull request #11078 from docker/dependabot/go_modules/github.com/containerd/containerd-1.7.7
build(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.7
2023-10-18 11:35:04 +02:00
dependabot[bot]
38bc6d5dbc build(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.7
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.6 to 1.7.7.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.6...v1.7.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 11:20:06 +02:00
Guillaume Lours
4a2d4c44b2 Merge pull request #11083 from docker/dependabot/go_modules/github.com/google/go-cmp-0.6.0
build(deps): bump github.com/google/go-cmp from 0.5.9 to 0.6.0
2023-10-18 11:18:06 +02:00
dependabot[bot]
0b6ce6ee42 build(deps): bump github.com/google/go-cmp from 0.5.9 to 0.6.0
Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.9 to 0.6.0.
- [Release notes](https://github.com/google/go-cmp/releases)
- [Commits](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/google/go-cmp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 11:03:14 +02:00
Guillaume Lours
034458dac7 Merge pull request #11105 from docker/dependabot/go_modules/google.golang.org/grpc-1.59.0
build(deps): bump google.golang.org/grpc from 1.58.2 to 1.59.0
2023-10-18 11:00:43 +02:00
dependabot[bot]
ae16bbbf05 build(deps): bump google.golang.org/grpc from 1.58.2 to 1.59.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.2 to 1.59.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.2...v1.59.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 08:45:06 +00:00
Guillaume Lours
eb5f01baf4 Merge pull request #11068 from docker/dependabot/go_modules/golang.org/x/sync-0.4.0
build(deps): bump golang.org/x/sync from 0.3.0 to 0.4.0
2023-10-18 10:44:00 +02:00
dependabot[bot]
d13ad1f997 build(deps): bump golang.org/x/sync from 0.3.0 to 0.4.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.3.0 to 0.4.0.
- [Commits](https://github.com/golang/sync/compare/v0.3.0...v0.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 10:27:48 +02:00
Guillaume Lours
9b4d577c65 remove refrecence docs generation
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-11 14:19:56 +02:00
Guillaume Lours
b30978fb40 Merge pull request #11076 from glours/remove-cucumber
remove cucumber tests as we haven't added new ones for a while
2023-10-10 23:16:33 +02:00
Guillaume Lours
14b43c1a93 remove cucumber tests as we haven't added new ones for a while
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-10 09:57:25 +02:00
Guillaume Lours
9dd081b92e add support of COMPOSE_ENV_FILES env variable to pass a list of env files
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-05 21:55:43 +02:00
Guillaume Lours
2c0b023273 add dry-run support for publish command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-10-05 21:55:00 +02:00
Nicolas De Loof
599e4b242a extract method to reduce cyclomatic complexity
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-29 10:18:11 +02:00
Nicolas De Loof
fe8c2780c8 warn user remote resource is disabled
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-29 09:30:38 +02:00
Matthew Walowski
a345515f91 Don't delete dependent services
Signed-off-by: Matthew Walowski <mattwalowski@gmail.com>
2023-09-29 06:43:16 +02:00
Matthew Walowski
8967df7a91 Apply platform before hashing
Signed-off-by: Matthew Walowski <mattwalowski@gmail.com>
2023-09-29 06:43:16 +02:00
Matthieu MOREL
4f694919ff deps: remove deprecated github.com/pkg/errors
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2023-09-29 06:28:58 +02:00
Matthew Walowski
6ecab95775 Include image name in error message
Signed-off-by: Matthew Walowski <mattwalowski@gmail.com>
2023-09-29 06:25:10 +02:00
Bjorn Neergaard
12e0ac898a pkg/compose/publish: use empty config descriptor mediaType
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-09-29 05:27:14 +02:00
Bjorn Neergaard
a6b7d78575 pkg/remote/oci: check artifactType instead of config.mediaType
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-09-29 05:27:14 +02:00
Bjorn Neergaard
991901f2ef pkg/remote/oci: refer to the manifest as manifest
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
2023-09-29 05:27:14 +02:00
Guillaume Lours
bd74a9260d Merge pull request #11047 from glours/update-watch-warning-section
update the watch warning message when no services with a develop section
2023-09-27 23:41:53 +02:00
Guillaume Lours
2d971fc97d update the watch warning message when no services with a develop section
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-09-27 23:28:45 +02:00
Djordje Lukic
78f3361921 ci: enable verbose output for e2e tests (#11045)
It's easier to see that something is happening.

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2023-09-27 16:29:54 +00:00
Nicolas De Loof
44d21280e7 truncate command by default, introduce --no-trunc flag to get the full command
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-23 06:34:26 +02:00
Guillaume Lours
cd743d17ba Merge pull request #11036 from docker/dependabot/go_modules/google.golang.org/grpc-1.58.2
build(deps): bump google.golang.org/grpc from 1.58.1 to 1.58.2
2023-09-22 11:23:05 +02:00
dependabot[bot]
ff2ff18cdc build(deps): bump google.golang.org/grpc from 1.58.1 to 1.58.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.1 to 1.58.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.1...v1.58.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-22 09:10:26 +00:00
Guillaume Lours
bd32ed1454 Merge pull request #11025 from ndeloof/SkipResolveEnvironment
config --xx don't need `env_file` being parsed
2023-09-21 12:28:25 +02:00
Nicolas De Loof
ab81db5bdb config --xx don't need env_file being parsed
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-21 10:47:38 +02:00
Guillaume Lours
52a641bf6d Merge pull request #11021 from glours/move-watch-to-main-cmd
move watch from alpha to main command
2023-09-21 10:08:23 +02:00
Guillaume Lours
75f5c07d3d Merge pull request #11023 from glours/fix-watch-e2e-test-cleanup
remove --timeout=0 flag to cleanup function of watch e2e test
2023-09-20 21:43:51 +02:00
Guillaume Lours
61c8be11c0 remove --timeout=0 flag to cleanup function of watch e2e test
compose down command need the watch process to be killed to succeed

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-09-20 21:32:03 +02:00
Guillaume Lours
6be5f3003a move watch from alpha to main command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-09-20 18:55:08 +02:00
Guillaume Lours
421a6b0506 Merge pull request #11031 from ndeloof/TestWatch
TestWatch to use new  `develop` section
2023-09-20 18:54:20 +02:00
Nicolas De Loof
c34c306cb9 TestWatch to use new develop section
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-20 18:39:32 +02:00
Nicolas De Loof
5ca35c88be implement publish
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-20 18:14:58 +02:00
Nicolas De loof
805541be9d watch: use official develop section (#11026)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-20 11:51:53 -04:00
Guillaume Lours
d322ad91e8 Merge pull request #11027 from docker/dependabot/go_modules/github.com/opencontainers/image-spec-1.1.0-rc5
build(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc4 to 1.1.0-rc5
2023-09-20 12:03:40 +02:00
dependabot[bot]
8f489d6d61 build(deps): bump github.com/opencontainers/image-spec
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc4 to 1.1.0-rc5.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/compare/v1.1.0-rc4...v1.1.0-rc5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 11:50:03 +02:00
Guillaume Lours
a214a715a0 Merge pull request #11017 from docker/dependabot/go_modules/github.com/moby/buildkit-0.12.2
build(deps): bump github.com/moby/buildkit from 0.12.1 to 0.12.2
2023-09-20 11:39:08 +02:00
dependabot[bot]
9ea8fbc69b build(deps): bump github.com/moby/buildkit from 0.12.1 to 0.12.2
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.12.1 to 0.12.2.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.12.1...v0.12.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 11:26:04 +02:00
Guillaume Lours
062fa75534 Merge pull request #11020 from docker/dependabot/go_modules/gotest.tools/v3-3.5.1
build(deps): bump gotest.tools/v3 from 3.5.0 to 3.5.1
2023-09-20 10:53:36 +02:00
dependabot[bot]
76f150e49d build(deps): bump gotest.tools/v3 from 3.5.0 to 3.5.1
Bumps [gotest.tools/v3](https://github.com/gotestyourself/gotest.tools) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/gotestyourself/gotest.tools/releases)
- [Commits](https://github.com/gotestyourself/gotest.tools/compare/v3.5.0...v3.5.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 08:21:25 +00:00
Guillaume Lours
d45d943e91 Merge pull request #11019 from docker/dependabot/go_modules/google.golang.org/grpc-1.58.1
build(deps): bump google.golang.org/grpc from 1.58.0 to 1.58.1
2023-09-20 10:19:32 +02:00
dependabot[bot]
f447c8096f build(deps): bump google.golang.org/grpc from 1.58.0 to 1.58.1
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.0 to 1.58.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.58.0...v1.58.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-20 10:05:44 +02:00
Guillaume Lours
722796ca28 Merge pull request #11016 from docker/dependabot/go_modules/github.com/containerd/containerd-1.7.6
build(deps): bump github.com/containerd/containerd from 1.7.3 to 1.7.6
2023-09-19 21:31:46 +02:00
dependabot[bot]
4587d4bad5 build(deps): bump github.com/containerd/containerd from 1.7.3 to 1.7.6
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.3 to 1.7.6.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.3...v1.7.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-19 09:41:32 +00:00
Nicolas De Loof
a697a0690a introduce pull --missing flag to only pull images not present in cache
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-15 08:41:27 +02:00
Nicolas De Loof
8af49ff369 resolve service reference into container based on observed state
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-14 15:29:50 +02:00
Nicolas De Loof
f6e31dbc6a don't rely on depends_on to resolve volume_from, better use observed state
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-14 15:29:50 +02:00
Guillaume Lours
e19232e8a3 Merge pull request #11000 from thaJeztah/update_golang_1.21.1
update to go1.21.1
2023-09-14 09:50:50 +02:00
Sebastiaan van Stijn
6d5eb6fde6 update to go1.21.1
go1.21.1 (released 2023-09-06) includes four security fixes to the cmd/go,
crypto/tls, and html/template packages, as well as bug fixes to the compiler,
the go command, the linker, the runtime, and the context, crypto/tls,
encoding/gob, encoding/xml, go/types, net/http, os, and path/filepath packages.
See the Go 1.21.1 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.21.1+label%3ACherryPickApproved

full diff: https://github.com/golang/go/compare/go1.21.0...go1.21.1

From the security mailing:

[security] Go 1.21.1 and Go 1.20.8 are released

Hello gophers,

We have just released Go versions 1.21.1 and 1.20.8, minor point releases.

These minor releases include 4 security fixes following the security policy:

- cmd/go: go.mod toolchain directive allows arbitrary execution
  The go.mod toolchain directive, introduced in Go 1.21, could be leveraged to
  execute scripts and binaries relative to the root of the module when the "go"
  command was executed within the module. This applies to modules downloaded using
  the "go" command from the module proxy, as well as modules downloaded directly
  using VCS software.

  Thanks to Juho Nurminen of Mattermost for reporting this issue.

  This is CVE-2023-39320 and Go issue https://go.dev/issue/62198.

- html/template: improper handling of HTML-like comments within script contexts
  The html/template package did not properly handle HMTL-like "<!--" and "-->"
  comment tokens, nor hashbang "#!" comment tokens, in <script> contexts. This may
  cause the template parser to improperly interpret the contents of <script>
  contexts, causing actions to be improperly escaped. This could be leveraged to
  perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39318 and Go issue https://go.dev/issue/62196.

- html/template: improper handling of special tags within script contexts
  The html/template package did not apply the proper rules for handling occurrences
  of "<script", "<!--", and "</script" within JS literals in <script> contexts.
  This may cause the template parser to improperly consider script contexts to be
  terminated early, causing actions to be improperly escaped. This could be
  leveraged to perform an XSS attack.

  Thanks to Takeshi Kaneko (GMO Cybersecurity by Ierae, Inc.) for reporting this
  issue.

  This is CVE-2023-39319 and Go issue https://go.dev/issue/62197.

- crypto/tls: panic when processing post-handshake message on QUIC connections
  Processing an incomplete post-handshake message for a QUIC connection caused a panic.

  Thanks to Marten Seemann for reporting this issue.

  This is CVE-2023-39321 and CVE-2023-39322 and Go issue https://go.dev/issue/62266.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-14 09:29:39 +02:00
Guillaume Lours
9d7e0ad6cb correct scale error messages formatting
Co-authored-by: Milas Bowman <devnull@milas.dev>
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-09-13 11:15:14 +02:00
Guillaume Lours
1a98a70b8a add scale command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-09-13 11:15:14 +02:00
Milas Bowman
19bbb12fac ci: tweak restricted imports in linter (#10992)
* Eliminate direct dependency on gopkg.in/yaml.v2
* Add gopkg.in/yaml.v2 as a restricted import
* Add github.com/distribution/distribution as a restricted dependency in favor of distribution/reference which is the subset of functionality that Compose needs
* Remove an unused exclusion

NOTE: This does change the `compose config` output slightly but does NOT  change the semantics:
* YAML indentation is slightly different for lists (this is a `v2` / `v3` thing)
* JSON is now "minified" instead of pretty-printed (I think this generally desirable and more consistent with other JSON command outputs)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-11 15:53:19 +00:00
Milas Bowman
7a13457853 deps: upgrade Moby to v24.0.6 and gRPC to v1.58.0 (#10991)
There are numerous transitive dependency upgrades as a result here.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-11 11:37:42 -04:00
Milas Bowman
13115468d5 cli: fix --build flag for create (#10982)
I missed this during a refactor and there wasn't test coverage.
Instead of adding more heavy-weight integration tests, I tried
to use `gomock` here to assert on the options objects after CLI
flag parsing. I think with a few more helpers, this could be a
good way to get a lot more combinations covered without adding
a ton of slow E2E tests.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-08 11:35:57 -04:00
Rory
e1aa4f779b otel: add args & flags to cli traces (#10974)
Signed-off-by: rvigus <roryvigus@gmail.com>
2023-09-07 16:04:36 -04:00
Milas Bowman
d7b0b2bd7d watch: build & launch the project at start (#10957)
The `alpha watch` command current "attaches" to an already-running
Compose project, so it's necessary to run something like
`docker compose up --wait` first.

Now, we'll do the equivalent of an `up --build` before starting the
watch, so that we know the project is up-to-date and running.

Additionally, unlike an interactive `up`, the services are not stopped
when `watch` exits (e.g. via `Ctrl-C`). This prevents the need to start
from scratch each time the command is run - if some services are already
running and up-to-date, they can be used as-is. A `down` can always be
used to destroy everything, and we can consider introducing a flag like
`--down-on-exit` to `watch` or changing the default.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-07 13:27:23 -04:00
Nicolas De Loof
e0f39ebbef pull OCI remote resource
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-07 07:27:32 +02:00
Nicolas De Loof
c9d54f09cf introduce publish (alpha) command
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-07 07:27:32 +02:00
Guillaume Lours
aeb835a525 Merge pull request #10966 from kumarlokesh/patch-1
doc: updated README.md to remove broken link
2023-09-04 21:47:05 +02:00
Lokesh Kumar
52e54ef910 doc: updated README.md to remove broken link
- Removed the broken link in README.md file about `backward compatibility`.
- The section 
`# About update and backward compatibility` was removed in an earlier PR (https://github.com/docker/compose/pull/10889/files).

Signed-off-by: Lokesh Kumar <lkumar94@gmail.com>
2023-09-04 20:57:41 +02:00
Guillaume Lours
203bce883c Merge pull request #10954 from thaJeztah/swap_reference
migrate to github.com/distribution/reference
2023-09-04 17:46:16 +02:00
Sebastiaan van Stijn
f4f2e934ac migrate to github.com/distribution/reference
The "reference" package was moved to a separate module, which was extracted
from b9b19409cf

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-04 14:36:36 +02:00
Nicolas De Loof
32c3d0a3ff Enable service explicitly requested to be restarted
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-09-01 12:01:02 +02:00
Milas Bowman
1fdbcb6255 build: pass BuildOptions around explicitly & fix multi-platform issues
The big change here is to pass around an explicit `*BuildOptions` object
as part of Compose operations like `up` & `run` that may or may not do
builds. If the options object is `nil`, no builds whatsoever will be
attempted.

Motivation is to allow for partial rebuilds in the context of an `up`
for watch. This was broken and tricky to accomplish because various parts
of the Compose APIs mutate the `*Project` for convenience in ways that
make it unusable afterwards. (For example, it might set `service.Build = nil`
because it's not going to build that service right _then_. But we might
still want to build it later!)

NOTE: This commit does not actually touch the watch logic. This is all
      in preparation to make it possible.

As part of this, a bunch of code moved around and I eliminated a bunch
of partially redundant logic, mostly around multi-platform. Several
edge cases have been addressed as part of this:
 * `DOCKER_DEFAULT_PLATFORM` was _overriding_ explicitly set platforms
   in some cases, this is no longer true, and it behaves like the Docker
   CLI now
 * It was possible for Compose to build an image for one platform and
   then try to run it for a different platform (and fail)
 * Errors are no longer returned if a local image exists but for the
   wrong platform - the correct platform will be fetched/built (if
   possible).

Because there's a LOT of subtlety and tricky logic here, I've also tried
to add an excessive amount of explanatory comments.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-09-01 08:32:56 +02:00
Milas Bowman
407a0d5b53 up: fix various race/deadlock conditions on exit (#10934)
If running `up` in foreground mode (i.e. not `-d`),
when exiting via `Ctrl-C`, Compose stops all the
services it launched directly as part of that `up`
command.

In one of the E2E tests (`TestUpDependenciesNotStopped`),
this was occasionally flaking because the stop
behavior was racy: the return might not block on
the stop operation because it gets added to the
error group in a goroutine. As a result, it was
possible for no services to get terminated on exit.

There were a few other related pieces here that
I uncovered and tried to fix while stressing this.
For example, the printer could cause a deadlock if
an event was sent to it after it stopped.

Also, an error group wasn't really appropriate here;
each goroutine is a different operation for printing,
signal-handling, etc. If one part fails, we don't
actually want printing to stop, for example. This has
been switched to a `multierror.Group`, which has the
same API but coalesces errors instead of canceling a
context the moment the first one fails and returning
that single error.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-31 10:47:14 -04:00
Milas Bowman
d0dfb848df Merge pull request #10953 from thaJeztah/drop_uuid
pkg/api: replace uuid for basic random id
2023-08-31 10:43:34 -04:00
Sebastiaan van Stijn
8caa6f1f3e pkg/api: replace uuid for basic random id
The uuid package in distribution was created as a utility for the distribution
project itself, to cut down external dependencies (see [1][1]).

For compose, this has the reverse effect, as it now brings all the dependencies
of the distribution module with it.

This patch switches to the uuid generation to crypto/rand to produce a random
id. I was considering using a different uuid implementation, or docker's
"stringid.GenerateRandomID", but all of those are doing more than needed,
so keep it simple.

Currently, this change has little effect, because compose also uses the
distribution module for other purposes, but the distribution project is
in the process of moving the "reference" package to a separate module,
in which case we don't want to depend on the distribution module only for
the uuid package.

[1]: 36e34a55ad

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-31 10:13:32 +02:00
Milas Bowman
d6f842b042 test: e2e test reliability improvements (#10950)
* Use unique project name prefixes (some of these tests assert
  on output using the project name as a magic string, so could
  be impacted by other tests with the same project name prefix)
* Tear down port range project before starting to try and avoid
  race conditions with the engine and port assignment

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-30 16:01:15 -04:00
Milas Bowman
4fbbf201cd build(deps): upgrade to compose-go v1.18.3 (#10947)
https://github.com/compose-spec/compose-go/releases/tag/v1.18.3

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-30 09:17:57 -04:00
Bilal Khan
935d72f46f added the dot at the end of the sentence
Signed-off-by: Bilal Khan <bilalkhanrecovered@gmail.com>
2023-08-28 09:19:26 +02:00
Nicolas De Loof
41682acc77 add support for attributes exposed by docker ps
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-25 16:36:45 +02:00
Nicolas De Loof
1054792b47 align docker compose ps with docker CLI to support --format
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-25 16:36:45 +02:00
Milas Bowman
19f66918cc watch: only allow a single instance per-project
This is a good place to start introducing (local) exclusivity
to Compose. Now, when `alpha watch` launches, it will check for
the existence of a PID file in the user XDG runtime directory,
and create one if the existing one is stale or does not exist.
If the PID file exists and is valid, an error is returned and
Compose exits.

A slight tweak to the experimental remote Git loader has been
made to use the XDG package for consistency.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-25 15:49:28 +02:00
Milas Bowman
186744e034 ci: bump golangci-lint to v1.54.2
Also improve incremental lint caching.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-24 08:57:47 +02:00
Milas Bowman
bc9d696fa0 Merge pull request #10922 from thaJeztah/replace_dockerignore
replace dockerfile/dockerignore with patternmatcher/ignorefile
2023-08-23 16:04:19 -04:00
Nicolas De loof
6204fb1c94 logs: fix for missing output on container exit (#10925)
We can't assume we receive container logs line by line. Some framework won't buffer output and will send char by char, and we also can receive looong lines which get buffered to 32kb and then cut into multiple logs.

This assumes we will catch container streams being closed before we receive a die event for container, which could be subject to race condition, but at least the impact here is minimal and the fix works for reproduction examples provided in linked issues.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-23 08:57:18 -04:00
Sebastiaan van Stijn
5d732010a7 replace dockerfile/dockerignore with patternmatcher/ignorefile
The BuildKit dockerignore package was integrated in the patternmatcher
repository / module. This patch updates our uses of the BuildKit package
with its new location.

A small local change was made to keep the format of the existing error message,
because the "ignorefile" package is slightly more agnostic in that respect
and doesn't include ".dockerignore" in the error message.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:43:17 +02:00
Sebastiaan van Stijn
2006f3fe7d go.mod: github.com/moby/patternmatcher v0.6.0
- integrate frontend/dockerfile/dockerignore from buildkit

full diff: https://github.com/moby/patternmatcher/compare/v0.5.0...v0.6.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:40:12 +02:00
Sebastiaan van Stijn
192718c001 go.mod: remove some outdated comments
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-23 00:39:35 +02:00
Milas Bowman
c79f67fead otel: add include to project up span
Flatten the list of included files and add as a slice attribute.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-22 16:10:18 +02:00
dependabot[bot]
3b294bfdda build(deps): bump github.com/compose-spec/compose-go from 1.18.1 to 1.18.2 (#10915)
build(deps): bump github.com/compose-spec/compose-go

Bumps [github.com/compose-spec/compose-go](https://github.com/compose-spec/compose-go) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/compose-spec/compose-go/releases)
- [Commits](https://github.com/compose-spec/compose-go/compare/v1.18.1...v1.18.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-21 14:02:03 -04:00
Nicolas De loof
dd34f7a22b include: add experimental support for Git resources (#10811)
Requires setting `COMPOSE_EXPERIMENTAL_GIT_REMOTE=1`.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-18 09:16:45 -04:00
Milas Bowman
caad72713b up: handle various attach use cases better
By default, `compose up` attaches to all services (i.e.
shows log output from every associated container). If
a service is specified, e.g. `compose up foo`, then
only `foo`'s logs are tailed. The `--attach-dependencies`
flag can also be used, so that if `foo` depended upon
`bar`, then `bar`'s logs would also be followed. It's
also possible to use `--no-attach` to filter out one
or more services explicitly, e.g. `compose up --no-attach=noisy`
would launch all services, including `noisy`, and would
show log output from every service _except_ `noisy`.
Lastly, it's possible to use `up --attach` to explicitly
restrict to a subset of services (or their dependencies).

How these flags interact with each other is also worth
thinking through.

There were a few different connected issues here, but
the primary issue was that running `compose up foo` was
always attaching dependencies regardless of `--attach-dependencies`.

The filtering logic here has been updated so that it
behaves predictably both when launching all services
(`compose up`) or a subset (`compose up foo`) as well
as various flag combinations on top of those.

Notably, this required making some changes to how it
watches containers. The logic here between attaching
for logs and monitoring for lifecycle changes is
tightly coupled, so some changes were needed to ensure
that the full set of services being `up`'d are _watched_
and the subset that should have logs shown are _attached_.
(This does mean faking the attach with an event but not
actually doing it.)

While handling that, I adjusted the context lifetimes
here, which improves error handling that gets shown to
the user and should help avoid potential leaks by getting
rid of a `context.Background()`.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-18 12:38:38 +02:00
Nicolas De loof
792afb8d13 build: use correct values for proxy variables (#10908)
clone variable before we capture a pointer

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-17 14:25:28 -04:00
Nicolas De Loof
150449bbd2 warn user secret uid/gid/mode is not supported
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-08-16 19:17:28 +02:00
Guillaume Lours
8d0df18762 Merge pull request #10867 from docker/dependabot/go_modules/github.com/moby/buildkit-0.12.1
build(deps): bump github.com/moby/buildkit from 0.12.1-0.20230717122532-faa0cc7da353 to 0.12.1
2023-08-11 10:45:05 +02:00
dependabot[bot]
5b53f8e47f build(deps): bump github.com/moby/buildkit
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.12.1-0.20230717122532-faa0cc7da353 to 0.12.1.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/commits/v0.12.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-11 08:28:23 +00:00
Guillaume Lours
c5fef61383 Merge pull request #10893 from glours/bump-compose-go-v1.18.1
bump compose-go to version v1.18.1
2023-08-10 21:08:07 +02:00
Guillaume Lours
ce3cb2b00c bump compose-go to version v1.18.1
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 20:51:22 +02:00
Guillaume Lours
d9e73db8e6 Merge pull request #10891 from glours/bump-compose-go-v1.18.0
bump compose-go to version v1.18.0
2023-08-10 17:13:53 +02:00
Guillaume Lours
d6b4d1c755 bump compose-go to version v1.18.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 17:00:32 +02:00
Guillaume Lours
0baf24a269 Merge pull request #10890 from glours/bump-golang-1.21
upgrade Golang to 1.21
2023-08-10 15:22:50 +02:00
Guillaume Lours
0511b0c2b8 Merge pull request #10878 from relrelb/profiles_completion
Add shell completion for `--profile`
2023-08-10 15:16:24 +02:00
Guillaume Lours
5bbdf3d84a Merge pull request #10879 from relrelb/project_directory_completion
Improve shell completion for `--project-directory`
2023-08-10 15:15:58 +02:00
Guillaume Lours
52103cce74 update README and CI workflows to match main branch
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 15:11:27 +02:00
Guillaume Lours
020b57ca31 upgrade Golang to 1.21
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-08-10 15:07:09 +02:00
Milas Bowman
bfa54081d4 build: fix missing proxy build args for classic builder (#10887)
Refactor to use a consistent code path for determining the build
args for a service image regardless of whether BuildKit or the
classic builder is being used.

After recent changes, these code paths had diverged, so the classic
builder was missing the proxy variables from the Docker client
config.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-10 08:57:28 -04:00
Milas Bowman
0be8e4a676 trace: do not block connecting to OTLP endpoint (#10882)
This was left over from debugging, but we should not block.
OTel will handle the connection in the background.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-08 15:47:18 -04:00
Milas Bowman
fd8ab2f7ac watch: enable tar-based syncer by default (#10877)
Swap the default implementation now that batching is merged.
Keeping the `docker cp` based implementation around for the
moment, but it needs to be _explicitly_ disabled now by setting
`COMPOSE_EXPERIMENTAL_WATCH_TAR=0`.

After the next release, we should remove the `docker cp`
implementation entirely.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-04 16:58:01 -04:00
Guillaume Lours
b406b393bf Merge pull request #10881 from silvin-lubecki/display-builder-name
Display builder's name on the first build line.
2023-08-04 17:36:18 +02:00
Silvin Lubecki
0a9d1277c5 Display builder's name on the first build line.
Code borrowed from buildx commands/build.go.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2023-08-04 17:11:44 +02:00
Milas Bowman
c350f80d4b up: do not warn on successful optional dependency complete (#10870)
If an optional dependency exits successfully (exit code of 0),
with a service condition of `service_completed_successfully`,
don't log a warning.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 21:00:49 +00:00
relrelb
8a4095b507 Improve shell completion for --project-directory
Signed-off-by: Ariel Bachar <relrelb@users.noreply.github.com>
Signed-off-by: relrelb <relrelb@users.noreply.github.com>
2023-08-03 23:40:56 +03:00
relrelb
0345461412 Add shell completion for --profile
Signed-off-by: Ariel Bachar <relrelb@users.noreply.github.com>
Signed-off-by: relrelb <relrelb@users.noreply.github.com>
2023-08-03 23:09:13 +03:00
Milas Bowman
80856eacaf progress: minor correctness fixes (#10871)
* When waiting for dependencies, `select` on the context as well
  as the ticker
* Write multiple progress events "transactionally" (i.e. hold the
  lock for the duration to avoid other events being interleaved)
* Do not change "finished" steps back to "in progress" to prevent
  flickering

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 15:14:17 -04:00
Praful Gupta
d7b1972d5e doc: update Config() comment in API Service interface (#10840)
Update Config comment in Service interface

Signed-off-by: Praful Gupta <prafulgupta6@gmail.com>
2023-08-03 15:13:26 -04:00
Silvin Lubecki
7c42776770 Improve buildkit node creation (#10843)
Move builder and nodes initialization code up, avoiding to recreate/load them for every service build.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2023-08-03 15:11:16 -04:00
Milas Bowman
3b0742fd57 watch: batch & de-duplicate file events (#10865)
Adjust the debouncing logic so that it applies to all inbound file
events, regardless of whether they match a sync or rebuild rule.

When the batch is flushed out, if any event for the service is a
rebuild event, then the service is rebuilt and all sync events for
the batch are ignored. If _all_ events in the batch are sync events,
then a sync is triggered, passing the entire batch at once. This
provides a substantial performance win for the new `tar`-based
implementation, as it can efficiently transfer the changes in bulk.

Additionally, this helps with jitter, e.g. it's not uncommon for
there to be double-writes in quick succession to a file, so even if
there's not many files being modified at once, it can still prevent
some unnecessary transfers.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:53:02 -04:00
Milas Bowman
efd44de1b7 watch: support multiple containers for tar implementation (#10860)
Support services with scale > 1 for the tar watch sync.

Add a "lossy" multi-writer specific to pipes that writes the
tar data to each `io.PipeWriter`, which is connected to `stdin`
for the `tar` process being exec'd in the container.

The data is written serially to each writer. This could be
adjusted to do concurrent writes but that will rapidly increase
the I/O load, so is not done here - in general, 99% of the
time you'll be developing (and thus using watch/sync) with a
single replica of a service.

If a write fails, the corresponding `io.PipeWriter` is removed
from the active set and closed with an error.

This means that a single container copy failing won't stop
writes to the others that are succeeding. Of course, they will
be in an inconsistent state afterwards still, but that's a
different problem.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:52:39 -04:00
Milas Bowman
bdb3f91eb4 test: temporarily disable an exit-code-from Cucumber test case (#10875)
Something is wrong here, disabling while we investigate.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 14:49:59 -04:00
Milas Bowman
f94cb49062 test: fix e2e test for privileged builds (#10873)
We cannot guarantee the exact value of `CapEff` across
environments, and this test has started failing some places,
e.g. Docker Desktop, and now GitHub Actions (likely due to
a kernel upgrade on the runners or similar).

By setting `privileged: true` on the build, we're asking for
the `security.insecure` entitlement on the build. A safe
assumption is that will include `CAP_SYS_ADMIN`, which won't
be present otherwise, so mask the `CapEff` value and check
for that.

It's worth noting that realistically, the build won't even
be able to complete without the correct entitlement, since the
`Dockerfile` uses `RUN --security=insecure`, so this is really
an additional sanity check.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-03 12:23:24 -04:00
Milas Bowman
e7ed070690 Merge pull request #10861 from thaJeztah/update_go1.20.7
update to go1.20.7
2023-08-02 10:08:37 -04:00
Sebastiaan van Stijn
8a1bf5d28b update to go1.20.7
Includes a fix for CVE-2023-29409

go1.20.7 (released 2023-08-01) includes a security fix to the crypto/tls
package, as well as bug fixes to the assembler and the compiler. See the
Go 1.20.7 milestone on our issue tracker for details:

- https://github.com/golang/go/issues?q=milestone%3AGo1.20.7+label%3ACherryPickApproved
- full diff: https://github.com/golang/go/compare/go1.20.6...go1.20.7

From the mailing list announcement:

[security] Go 1.20.7 and Go 1.19.12 are released

Hello gophers,

We have just released Go versions 1.20.7 and 1.19.12, minor point releases.

These minor releases include 1 security fixes following the security policy:

- crypto/tls: restrict RSA keys in certificates to <= 8192 bits

  Extremely large RSA keys in certificate chains can cause a client/server
  to expend significant CPU time verifying signatures. Limit this by
  restricting the size of RSA keys transmitted during handshakes to <=
  8192 bits.

  Based on a survey of publicly trusted RSA keys, there are currently only
  three certificates in circulation with keys larger than this, and all
  three appear to be test certificates that are not actively deployed. It
  is possible there are larger keys in use in private PKIs, but we target
  the web PKI, so causing breakage here in the interests of increasing the
  default safety of users of crypto/tls seems reasonable.

  Thanks to Mateusz Poliwczak for reporting this issue.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.20.7

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-02 00:22:13 +02:00
dependabot[bot]
7ef392004f build(deps): bump github.com/docker/docker from 24.0.5-0.20230714235725-36e9e796c6fc+incompatible to 24.0.5+incompatible (#10844)
build(deps): bump github.com/docker/docker

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 24.0.5-0.20230714235725-36e9e796c6fc+incompatible to 24.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/commits/v24.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-01 18:46:15 +00:00
dependabot[bot]
f34f5b4d26 build(deps): bump github.com/containerd/containerd from 1.7.2 to 1.7.3 (#10850)
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.2...v1.7.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-01 14:41:57 -04:00
dependabot[bot]
b0484700da build(deps): bump google.golang.org/grpc from 1.56.2 to 1.57.0 (#10847)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.2 to 1.57.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.2...v1.57.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-01 14:40:31 -04:00
Milas Bowman
f65fd02383 watch: add tar sync implementation (#10853)
Brought to you by Tilt ❤️ 

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-08-01 14:39:08 -04:00
Milas Bowman
cf8dc46560 Merge pull request #10845 from docker/dependabot/go_modules/github.com/docker/cli-24.0.5incompatible
build(deps): bump github.com/docker/cli from 24.0.4+incompatible to 24.0.5+incompatible
2023-08-01 14:29:27 -04:00
dependabot[bot]
2cfbe63533 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 24.0.4+incompatible to 24.0.5+incompatible.
- [Commits](https://github.com/docker/cli/compare/v24.0.4...v24.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-25 09:25:44 +00:00
Guillaume Lours
8318f66330 Merge pull request #10791 from milas/watch-refactor-sync
watch: move sync logic into separate package
2023-07-19 13:11:24 +02:00
Milas Bowman
cb17c3c8a6 watch: move sync logic into separate package
Just moving some code around in preparation for an alternative
sync implementation that can do bulk transfers by using `tar`.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-19 12:25:13 +02:00
Guillaume Lours
9174a99d27 Merge pull request #10828 from thaJeztah/minor_cli_changes
pkg/compose: RunOneOffContainer: don't use NewStartOptions()
2023-07-19 12:24:37 +02:00
Sebastiaan van Stijn
4eb43c53fa pkg/compose: RunOneOffContainer: don't use NewStartOptions()
It's no longer used in docker/cli, and doesn't do anything other than
creating an empty struct, so replacing it (as we're planning to
deprecate that function)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-19 12:13:40 +02:00
Guillaume Lours
150b88ab5d Merge pull request #10829 from milas/e2e-watch-test-fix
test: watch e2e reliability tweaks
2023-07-19 12:07:10 +02:00
Guillaume Lours
5159058c7e Merge pull request #10831 from milas/instrument-up
trace: instrument `compose up` at a high-level
2023-07-19 12:06:56 +02:00
Milas Bowman
1ae191a936 trace: instrument compose up at a high-level
* Image pull
* Image build
* Service apply
  * Scale down/up (event)
  * Recreate container (event)
  * Scale up (event)
  * Container start (event)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-19 11:26:12 +02:00
Guillaume Lours
3b2f3cdce3 Merge pull request #10819 from ndeloof/windows_abs
check secret target is an absolute windows path
2023-07-19 11:24:45 +02:00
Nicolas De Loof
47778f8b77 check secret target is an absolute windows path
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-07-19 10:57:22 +02:00
Guillaume Lours
7d88edaf24 Merge pull request #10814 from milas/fix-build-push
build: do not attempt to push unnamed service images
2023-07-19 10:57:00 +02:00
Milas Bowman
636c13f818 build: do not attempt to push unnamed service images
When building, if images are being pushed, ensure that only
named images (i.e. services with a populated `image` field)
are attempted to be pushed.

Services without `image` get an auto-generated name, which
will be a "Docker library" reference since they're in the
format `$project-$service`, which is implicitly the same as
`docker.io/library/$project-$service`. A push for that is
never desirable / will always fail.

The key here is that we cannot overwrite the `<svc>.image`
field when doing builds, as we need to be able to check for
its presence to determine whether a push makes sense.

Fixes #10813.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-19 09:58:37 +02:00
Guillaume Lours
5a072b1ad5 Merge pull request #10792 from glours/add-depends_on-required
add support of depends_on.required attribute
2023-07-19 09:53:49 +02:00
Milas Bowman
ddceb1ac9d test: do not run watch e2e tests in parallel
This isn't playing nicely with the GHA CI runner.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-18 18:54:23 -04:00
Milas Bowman
d48f28c72c test: skip watch e2e test on macOS for the moment
Fix forthcoming via https://github.com/compose-spec/compose-go/pull/436
which addresses some symlink limitations. These can
actually effect other platforms but are most common
on macOS because the test creates temporary directories,
which are symlinked on macOS.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-18 18:53:26 -04:00
Guillaume Lours
2d16a05afa only check if a dependency is required when something unexpected happens
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-07-18 23:45:31 +02:00
Guillaume Lours
bb94ea034e add support of depends_on.required attribute
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-07-18 23:13:47 +02:00
Milas Bowman
0938c7e96f Merge pull request #10827 from thaJeztah/bump_buildx_buildkit
go.mod: buildx v0.11.2, buildkit v0.12, docker/cli v24.0.5-dev
2023-07-18 16:43:24 -04:00
Sebastiaan van Stijn
f429ee958a go.mod: github.com/docker/docker v24.0.5-dev (tip of 24 release branch)
full diff: 8443a06149...f329397077

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-18 22:25:50 +02:00
Sebastiaan van Stijn
e9ded2c518 go.mod: github.com/docker/buildx v0.11.2
full diff:

- https://github.com/docker/buildx/compare/v0.11.1...v0.11.2
- https://github.com/moby/buildkit/v0.12.0...faa0cc7da353

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-18 21:57:42 +02:00
Sebastiaan van Stijn
54e6e0bd8f go.mod: github.com/moby/buildkit v0.12.0
Switching to back to released versions / release-branche. The old version
was a commit from master (v0.12.0-dev).

full diff:

- https://github.com/moby/buildkit/compare/2d91ddcceedc...v0.12.0
- https://github.com/tonistiigi/fsutil/compare/9e7a6df48576...36ef4d8c0dbb

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-18 21:54:49 +02:00
Milas Bowman
3bc871e64b test: speed up the e2e test suite
Lots of our phony Compose files launch pointless long-lived processes
so we can assert on state. However, this means they often don't respond
well to signals on their own, requiring Compose to timeout and kill
them when doing a `down`.

Add in lots of `init: true` where appropriate so that we don't block
for no reason while running E2E tests all over the place.

Additionally, a couple tests have gotten a cleanup so they don't leave
behind containers. I still want to build this into the framework in
the future, but this is easier for the moment and won't cause any
trouble in the future.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-18 11:08:06 +02:00
Milas Bowman
6ff15d9472 Merge pull request #10812 from thaJeztah/update_go_1.20.6
update go to go1.20.6
2023-07-17 12:08:05 -04:00
Sebastiaan van Stijn
49bc0603e3 update go to go1.20.6
go1.20.6 (released 2023-07-11) includes a security fix to the net/http package,
as well as bug fixes to the compiler, cgo, the cover tool, the go command,
the runtime, and the crypto/ecdsa, go/build, go/printer, net/mail, and text/template
packages. See the Go 1.20.6 milestone on our issue tracker for details.

https://github.com/golang/go/issues?q=milestone%3AGo1.20.6+label%3ACherryPickApproved

Full diff: https://github.com/golang/go/compare/go1.20.5...go1.20.6

These minor releases include 1 security fixes following the security policy:

net/http: insufficient sanitization of Host header

The HTTP/1 client did not fully validate the contents of the Host header.
A maliciously crafted Host header could inject additional headers or entire
requests. The HTTP/1 client now refuses to send requests containing an
invalid Request.Host or Request.URL.Host value.

Thanks to Bartek Nowotarski for reporting this issue.

Includes security fixes for [CVE-2023-29406 ][1] and Go issue https://go.dev/issue/60374

[1]: https://github.com/advisories/GHSA-f8f7-69v5-w4vx

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 17:35:48 +02:00
Sebastiaan van Stijn
ce8a09b53f go.mod: github.com/docker/docker 8443a06149b5 (v24.0.5-dev) (#10810)
relevant changes:

- client: define a "dummy" hostname to use for local connections
  fixes "http: invalid Host header" errors when compiling with
  go1.20.6 or go1.19.11

full diff: https://github.com/docker/docker/compare/v24.0.4...8443a06149b5ba9c0763b92f832698474bcf2a13

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-17 10:47:52 -04:00
Milas Bowman
3dc8734897 watch: add end-to-end test (#10801)
Add an end-to-end test that covers the core watch functionality,
i.e. CRUD on files & directories.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-17 10:47:36 -04:00
Guillaume Lours
852e192820 bump buildkit to version v0.11.0-rc3.0.20230620112432-2d91ddcceedc (#10794)
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-07-12 08:23:02 -04:00
dependabot[bot]
d9e7859664 build(deps): bump github.com/docker/cli from 24.0.2+incompatible to 24.0.4+incompatible (#10799)
build(deps): bump github.com/docker/cli

Bumps [github.com/docker/cli](https://github.com/docker/cli) from 24.0.2+incompatible to 24.0.4+incompatible.
- [Commits](https://github.com/docker/cli/compare/v24.0.2...v24.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-12 08:21:46 -04:00
Guillaume Lours
e28b223650 Merge pull request #10793 from milas/dockerfile-cache-mounts
ci: speed up a couple Dockerfile targets w/ cache mount
2023-07-10 19:26:41 +02:00
Milas Bowman
1964693074 ci: speed up a couple Dockerfile targets w/ cache mount
The local Go package module path was missing from a couple of jobs,
which made them slower than needed since they were re-downloading
a bunch of dependencies.

In particular, this makes `make lint` waaaay faster!

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-10 13:13:10 -04:00
Guillaume Lours
dc74e6aa0e Merge pull request #10776 from docker/dependabot/go_modules/github.com/docker/buildx-0.11.1
build(deps): bump github.com/docker/buildx from 0.11.0 to 0.11.1
2023-07-10 18:15:39 +02:00
dependabot[bot]
b182cf6850 build(deps): bump github.com/docker/buildx from 0.11.0 to 0.11.1
Bumps [github.com/docker/buildx](https://github.com/docker/buildx) from 0.11.0 to 0.11.1.
- [Release notes](https://github.com/docker/buildx/releases)
- [Commits](https://github.com/docker/buildx/compare/v0.11.0...v0.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 15:51:31 +00:00
Guillaume Lours
f330b24632 Merge pull request #10788 from docker/dependabot/go_modules/github.com/docker/docker-24.0.4incompatible
build(deps): bump github.com/docker/docker from 24.0.2+incompatible to 24.0.4+incompatible
2023-07-10 17:49:45 +02:00
Guillaume Lours
8339269e13 Merge pull request #10789 from ndeloof/run_no_deps
Apply no-deps before we select and mutate target service
2023-07-10 15:46:01 +02:00
Guillaume Lours
ee6aeed84e Merge pull request #10700 from ndeloof/attach
support `attach`
2023-07-10 15:17:44 +02:00
Guillaume Lours
7a9dfa4284 Merge pull request #10790 from milas/e2e-process-leak
test: fix process leak in wait e2e test
2023-07-10 15:09:41 +02:00
Guillaume Lours
29daae3d6e Merge pull request #10784 from shantanoo-desai/v2
fix(secrets): file permission value does not comply with spec
2023-07-10 14:54:16 +02:00
Milas Bowman
8dea7b5cae test: fix process leak in wait e2e test
* Run `down` before and after test to not leave around containers
* Kill the `wait` process that's waiting on `infinity`
  * NOTE: If the test is actually working, this should exit once
    the `down` happens, but this ensures that we kill everything
    we start

I'd like to generalize more of this into the framework, but this
is a quick fix to prevent filling up CI machines with tons of
processes over time.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-10 08:42:09 -04:00
Guillaume Lours
bc6ad2e4a4 Merge pull request #10764 from docker/dependabot/go_modules/github.com/opencontainers/image-spec-1.1.0-rc4
build(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc3 to 1.1.0-rc4
2023-07-10 14:39:44 +02:00
Nicolas De Loof
e6a7694b8d Apply no-deps before we select and mutate target service
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-07-10 14:37:42 +02:00
Nicolas De Loof
46d936c750 support attach
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-07-10 14:34:28 +02:00
dependabot[bot]
15bc7850bb build(deps): bump github.com/opencontainers/image-spec
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc3 to 1.1.0-rc4.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/compare/v1.1.0-rc3...v1.1.0-rc4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 14:17:14 +02:00
Guillaume Lours
8a64ab56a0 Merge pull request #10760 from docker/dependabot/go_modules/gotest.tools/v3-3.5.0
build(deps): bump gotest.tools/v3 from 3.4.0 to 3.5.0
2023-07-10 14:16:34 +02:00
dependabot[bot]
1178c51e6a build(deps): bump gotest.tools/v3 from 3.4.0 to 3.5.0
Bumps [gotest.tools/v3](https://github.com/gotestyourself/gotest.tools) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/gotestyourself/gotest.tools/releases)
- [Commits](https://github.com/gotestyourself/gotest.tools/compare/v3.4.0...v3.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 12:40:37 +02:00
dependabot[bot]
3b3fd3e56c build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 24.0.2+incompatible to 24.0.4+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v24.0.2...v24.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 10:39:23 +00:00
Guillaume Lours
b1e10f559e Merge pull request #10781 from milas/deps-docs-0.6
deps: bump docker/cli-docs-tool to v0.6.0
2023-07-10 12:38:04 +02:00
Milas Bowman
baea5a48f5 deps: bump docker/cli-docs-tool to v0.6.0
Required re-running `make docs` to pick up changes.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-10 12:23:48 +02:00
Guillaume Lours
cb3a6ce52b Merge pull request #10787 from docker/dependabot/go_modules/google.golang.org/grpc-1.56.2
build(deps): bump google.golang.org/grpc from 1.56.0 to 1.56.2
2023-07-10 12:23:25 +02:00
dependabot[bot]
28f3802a07 build(deps): bump google.golang.org/grpc from 1.56.0 to 1.56.2
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.0 to 1.56.2.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.56.0...v1.56.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 09:23:22 +00:00
Shan Desai
fd0e0a2cbd fix(secrets): file permission value does not comply with spec
closes #10783

Compose Spec mentions that default values for secrets is `0444` aka. world-readable permissions. However, the value was previously set to `0400`. 


Signed-off-by: Shan Desai <shantanoo.desai@gmail.com>
2023-07-07 18:58:21 +02:00
Guillaume Lours
e90df62bb0 Merge pull request #10763 from ndeloof/exec_index
when --index is not set select first service container
2023-07-07 14:39:50 +02:00
Nicolas De Loof
b0af2deb2b when --index is not set select first service container
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-07-07 14:08:24 +02:00
Milas Bowman
be22bc735a network: fix random missing network when service has more than one
As part of the fix for #10668, the logic was adjusted so that the
default (highest-priority) network is used in the `ContainerCreate`,
and then the remaining networks are connected via calls to
`NetworkConnect` before starting the container.

Unfortunately, `ServiceConfig::NetworksByPriority` is neither
deterministic nor stable when networks have the same priority.

It's non-deterministic because the order of networks from parsing
YAML is random, since they are loaded into a Go map (which have
random iteration order). Additionally, it's not using a `SortStable`
in `compose-go`, so even if the load order was predictable, it
still might produce different results.

While I look at improving `compose-go` here to prevent this from
tripping us up in the future, this fix looks at _all_ networks for
a service and ignores the "default" one now. Before, it would
always skip the first one in the slice since that _should_ have
been the "default".

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-07-07 09:18:01 +02:00
Nicolas De Loof
b5f5e27597 don't use unitialized cli to setup DryRunClient
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-07-06 14:27:57 +02:00
Guillaume Lours
b1334b8dfc Merge pull request #10768 from cloud-native-team/v2
fix some comments
2023-07-06 10:06:05 +02:00
cui fliter
25ca75db4d fix some comments
Signed-off-by: cui fliter <imcusg@gmail.com>
2023-07-04 11:34:49 +08:00
Guillaume Lours
827e864ed0 Merge pull request #10745 from glours/add-builder-support
add support of --builder and BUILDX_BUILDER
2023-07-03 10:46:02 +02:00
Guillaume Lours
28301fb1a4 add support of --builder and BUILDX_BUILDER
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-07-03 10:11:18 +02:00
Ulysses Souza
fa3e16c66b Merge pull request #10742 from ulyssessouza/add-wait
Add `docker compose wait`
2023-07-02 13:54:34 +02:00
Ulysses Souza
edd76bfd70 Add docker compose wait
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2023-06-30 16:07:03 +02:00
Milas Bowman
c496c23071 ci: upgrade compose-go to v1.15.1 (#10757)
* Fix for "`build.context` is required" errors

https://github.com/compose-spec/compose-go/releases/tag/v1.15.1

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-29 16:50:10 -04:00
Guillaume Lours
02284378bf Merge pull request #10756 from milas/network-race
up: fix race condition on network connect
2023-06-29 22:47:29 +02:00
Milas Bowman
10b290e682 up: fix race condition on network connect
Engine API only allows at most one network to be connected as
part of the ContainerCreate API request. Compose will pick the
highest priority network.

Afterwards, the remaining networks (if any) are connected before
the container is actually started.

The big change here is that, previously, the highest-priority
network was connected in the create, and then disconnected and
immediately reconnected along with all the others. This was
racy because evidently connecting the container to the network
as part of the create isn't synchronous, so sometimes when Compose
tried to disconnect it, the API would return an error like:
```
container <id> is not connected to the network <network>
```

To avoid needing to disconnect and immediately reconnect, the
network config logic has been refactored to ensure that it sets
up the network config correctly the first time.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-29 16:00:55 -04:00
aroramrinaal
3906a7a67c Updated documentation files for my contribution
Ran 'make docs' to generate updated doc files from the reference.

Signed-off-by: aroramrinaal <aroramrinaal@gmail.com>
2023-06-27 22:48:17 +02:00
aroramrinaal
83671db3dd Fix capitalization error in sentence by adding an uppercase letter at beginning
Signed-off-by: aroramrinaal <aroramrinaal@gmail.com>
2023-06-27 22:48:17 +02:00
Jes Cok
1a41678c58 fix typos
Signed-off-by: Jes Cok <xigua67damn@gmail.com>
2023-06-27 16:12:25 +02:00
Guillaume Lours
035276e027 watch: add warning when a path is already used by a bind mount volume (#10741)
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-26 18:56:04 -04:00
Guillaume Lours
db24023884 Merge pull request #10720 from docker/dependabot/go_modules/google.golang.org/grpc-1.56.0
build(deps): bump google.golang.org/grpc from 1.53.0 to 1.56.0
2023-06-21 13:02:20 +02:00
dependabot[bot]
c48f542962 build(deps): bump google.golang.org/grpc from 1.53.0 to 1.56.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.56.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.56.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-21 12:08:40 +02:00
Guillaume Lours
42dc7a6a87 Merge pull request #10730 from glours/bump-compose-go-1.15.0
bump compose-go to version v1.15.0
2023-06-21 11:58:37 +02:00
Guillaume Lours
30b3b47383 bump compose-go to version v1.15.0
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-21 11:45:36 +02:00
Milas Bowman
061b52da9a ci: build fix for new buildx
Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-21 11:17:39 +02:00
Milas Bowman
04aa155878 ci: upgrade to buildx v0.11
https://github.com/docker/buildx/releases/tag/v0.11.0

Several `replace` directives have been removed and dependencies
aligned with buildx as needed.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-21 11:17:39 +02:00
Guillaume Lours
2d4f8d31fc Merge pull request #10709 from ndeloof/secret_uid
warn user build.secrets uid,gid,mode are not implemented
2023-06-21 10:19:43 +02:00
Milas Bowman
e1f8603a62 otel: refactor root command span reporting
* Move all the initialization code out of `main.go`
* Ensure spans are reported when there's an error with the
  command
* Attach the Compose version & active Docker context to the
  resource instead of the span
* Name the root CLI span `cli/<cmd>` for clarity and grab
  the full subcommand path (e.g. `alpha-viz` instead of just
  `viz`)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-20 17:25:58 +02:00
Nicolas De Loof
a2ce602f6c fix race condition, waiting for containers when one exit
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-20 16:17:15 +02:00
dependabot[bot]
401334e03f build(deps): bump github.com/AlecAivazis/survey/v2 from 2.3.6 to 2.3.7 (#10699)
Bumps [github.com/AlecAivazis/survey/v2](https://github.com/AlecAivazis/survey) from 2.3.6 to 2.3.7.
- [Release notes](https://github.com/AlecAivazis/survey/releases)
- [Commits](https://github.com/AlecAivazis/survey/compare/v2.3.6...v2.3.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-20 09:15:33 -04:00
Guillaume Lours
93cf2b921a use main branch of Docker Desktop repo to trigger remote workflow
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-20 12:14:08 +02:00
Guillaume Lours
83b2433a27 Merge pull request #10724 from glours/add-missing-comma-merge
add missing comma in desktop-edge-test job
2023-06-19 21:02:00 +02:00
Guillaume Lours
c8d06137b5 add missing comma in desktop-edge-test job
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-19 20:01:52 +02:00
Nicolas De Loof
c61b8aa5ac introduce run --cap-add to run maintenance commands using service image
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-19 14:20:20 +02:00
Milas Bowman
ff3984e609 otel: fix initialization / error-handling (#10717)
* If there's no `otel` key (or the value is `null`) in the config,
  don't return an error
* Propagate error from the exporter instead of panicking

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-15 12:43:15 -04:00
Guillaume Lours
2efea2e9f5 Merge pull request #10715 from docker/dependabot/go_modules/golang.org/x/sync-0.3.0
build(deps): bump golang.org/x/sync from 0.2.0 to 0.3.0
2023-06-15 18:03:23 +02:00
dependabot[bot]
6a3a95c4a8 build(deps): bump golang.org/x/sync from 0.2.0 to 0.3.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.2.0 to 0.3.0.
- [Commits](https://github.com/golang/sync/compare/v0.2.0...v0.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-15 17:52:44 +02:00
Guillaume Lours
fee8a1c6c6 Merge pull request #10703 from glours/add-repo-input-dd-token
specify origin repo in generation token step of docker desktop edge testing
2023-06-15 17:47:48 +02:00
Nicolas De Loof
7ffe83dc95 don't apply "rebuild" watch strategy by default
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-15 15:30:21 +02:00
Nicolas De Loof
d20c2551f2 warn user build.secrets uid,gid,mode are not implemented
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-14 10:21:20 +02:00
Guillaume Lours
0e9a5b6b78 specify origin repo in generation token step of docker desktop edge testing
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-13 16:23:51 +02:00
Guillaume Lours
6887a3fc3e Merge pull request #10702 from glours/fix-DD-APP-ID
add vars. prefix to DOCKERDESKTOP_APP_ID
2023-06-13 14:46:52 +02:00
Guillaume Lours
586fe87f98 add vars. prefix to DOCKERDESKTOP_APP_ID
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-13 14:45:26 +02:00
Guillaume Lours
6d66130266 Merge pull request #10701 from glours/fix-DD-APP-ID
use directly DOCKERDESKTOP_APP_ID without env. prefix
2023-06-13 14:21:01 +02:00
Guillaume Lours
0f83a8630e use directly DOCKERDESKTOP_APP_ID without env. prefix
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-13 14:19:56 +02:00
Guillaume Lours
26cb941f79 Merge pull request #10698 from glours/fix-DD-APP-ID
fix typo in merge workflow for DOCKERDESKTOP_APP_ID
2023-06-13 10:23:28 +02:00
Guillaume Lours
43783d36e2 fix typo in merge workflow for DOCKERDESKTOP_APP_ID
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-13 10:18:58 +02:00
Guillaume Lours
08e6bfc859 Merge pull request #10691 from glours/fix-dd-workflow-json-parsing
escape containerimage.digest attribute in merge.yml GHA worlflow
2023-06-13 09:52:13 +02:00
Guillaume Lours
7a870e2449 Update .github/workflows/merge.yml
Co-authored-by: CrazyMax <github@crazymax.dev>
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-12 16:54:21 +02:00
Guillaume Lours
8cd8f08d77 escape containerimage.digest attribut in merge.yml GHA worlflow
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-12 16:54:21 +02:00
Nicolas De Loof
cfe91becc7 use --progress to configure progress UI stylet push
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-12 16:53:42 +02:00
Guillaume Lours
9384e5f4d7 Merge pull request #10694 from milas/dependabot-ignore-more
ci: add more ignore rules to dependabot
2023-06-12 16:32:17 +02:00
robbert-ef
68bd0eb523 cli: fix timeout behavior on up / restart / stop (#10672)
Do not set a hardcoded default timeout of 10 seconds when restarting / stopping but use the container `StopTimeout` (defaults to 10 seconds).

Also fixed custom timeout not used when invoking `up`.

Signed-off-by: Robbert Segeren <robbert.segeren@easyflex.nl>
2023-06-12 09:18:25 -04:00
Milas Bowman
3fe665b93d ci: add more ignore rules to dependabot
Reduce PR spam for dependencies that we manually manage.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-12 09:06:21 -04:00
Guillaume Lours
508d71c5df ci: fix merge workflow (#10685)
use env instead of variables prefix to use `DOCKERDESKTOP_APPID`

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-09 15:35:47 -04:00
Guillaume Lours
58c5ea8217 Merge pull request #10625 from glours/compose-edge-desktop-integration
add GitHub action to trigger Docker Desktop e2e tests with Compose edge version
2023-06-09 21:18:37 +02:00
Guillaume Lours
ec31d3c2ac add GitHub action to trigger Docker Desktop e2e tests with Compose edge version
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-06-09 21:07:03 +02:00
Laura Brehm
599723f890 Merge pull request #10677 from docker/dependabot/go_modules/github.com/Microsoft/go-winio-0.6.1
build(deps): bump github.com/Microsoft/go-winio from 0.5.2 to 0.6.1
2023-06-09 12:13:09 +02:00
dependabot[bot]
0a9b9fd8fe build(deps): bump github.com/Microsoft/go-winio from 0.5.2 to 0.6.1
Bumps [github.com/Microsoft/go-winio](https://github.com/Microsoft/go-winio) from 0.5.2 to 0.6.1.
- [Release notes](https://github.com/Microsoft/go-winio/releases)
- [Commits](https://github.com/Microsoft/go-winio/compare/v0.5.2...v0.6.1)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/go-winio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-09 10:00:25 +00:00
Milas Bowman
3c8a56dbf3 trace: add OTEL initialization (#10526)
This is a bunch of OTEL initialization code. It's all in
`internal/` because there are re-usable parts here, but Compose
isn't the right spot. Once we've stabilized the interfaces a bit
and the need arises, we can move it to a separate module.

Currently, a single span is produced to wrap the root Compose
command.

Compose will respect the standard OTEL environment variables
as well as OTEL metadata from the Docker context. Both can be
used simultaneously. The latter is intended for local system
integration and is restricted to Unix sockets / named pipes.

None of this is enabled by default. It requires setting the
`COMPOSE_EXPERIMENTAL_OTEL=1` environment variable to
gate it during development.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-08 16:46:07 -04:00
Milas Bowman
e63ab14b1e ci: merge Go coverage reports before upload (#10666)
Attempting to fix the state of codecov action checks right now,
which are behaving very erratically.

Using the new functionality in Go 1.20 to merge multiple reports,
so now the unit & E2E coverage data reports are stored as artifacts
and then downloaded, merged, and finally uploaded to codecov as a
new job.

Additionally, add a `codecov.yml` config and try to turn down the
aggressiveness of it for CI checks.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-08 14:58:21 -04:00
Guillaume Lours
32cf776ecd Merge pull request #10620 from ndeloof/Building
do not render `Building` when no build is needed
2023-06-08 12:16:46 +02:00
Guillaume Lours
955784c406 Merge pull request #10662 from milas/bump-deps
ci: upgrade to Go 1.20.5 and Moby v24.x
2023-06-08 12:03:23 +02:00
Guillaume Lours
2d22c2b5ce Merge pull request #10652 from ndeloof/watch_mkdir
create directory in container using `mkdir -p`
2023-06-08 11:39:21 +02:00
Nicolas De Loof
852c9e80b4 create directory in container using mkdir -p
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-08 11:28:22 +02:00
Milas Bowman
37850f7955 ci: upgrade to Go 1.20.5 and Moby v24.x
Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-07 10:41:49 -04:00
Nicolas De Loof
4bf2fe9fed assume we receive logs by lines and don't ignore those without EOL
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-07 10:40:37 +02:00
Guillaume Lours
e21a8d6293 Merge pull request #10657 from ndeloof/compose_project_name
don't skip `compose` used as project name
2023-06-07 08:26:21 +02:00
dependabot[bot]
f8b6459403 build(deps): bump github.com/sirupsen/logrus from 1.9.2 to 1.9.3 (#10653)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.2 to 1.9.3.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.2...v1.9.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-06 16:44:25 -04:00
Milas Bowman
be6c9565e3 ci: bump golangci-lint to v1.53.x (#10659)
Requires some changes for depguard config

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-06-06 16:31:41 -04:00
Nicolas De Loof
60fe97416c don't skip compose used as project name
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-06 10:24:59 +02:00
Nicolas De Loof
629c9f62e9 better diagnostic message on network label mismatch
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-05 16:54:58 +02:00
Guillaume Lours
7c3fe359b7 Merge pull request #10622 from ndeloof/logs_follow
fix `compose -p x logs -f` detect new services started after command
2023-06-02 09:39:20 +02:00
Nicolas De Loof
d2aa15c06e bump buildx and use confutil.ConfigDir
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-01 12:09:13 +02:00
Guillaume Lours
6530880361 Merge pull request #10623 from jfly/jfly/tweak-warning-message
Fix typo in warning about existing volume
2023-06-01 08:50:33 +02:00
Nicolas De loof
1bd8a773a7 detect network conflict as name is not guaranteed to be unique (#10612)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-31 14:46:23 -04:00
Nicolas De Loof
fed8ef6b79 forward signal to container
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-31 15:10:11 +02:00
Guillaume Lours
419fcdd6c8 Merge pull request #10604 from aevesdocker/ENGDOCS-1373
update docs to reflect dry run mode is feature complete
2023-05-31 12:49:14 +02:00
Allie Sadler
65b714c108 fix build issue
Signed-off-by: Allie Sadler <102604716+aevesdocker@users.noreply.github.com>
2023-05-31 10:24:49 +01:00
Allie Sadler
44dd232e97 Merge branch 'v2' into ENGDOCS-1373 2023-05-31 10:18:45 +01:00
Guillaume Lours
83ad5e97b7 add Windows drive prefix to temp dir usage in the doc generation task
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-31 10:18:23 +02:00
Guillaume Lours
b0a35ccc98 Merge pull request #10632 from docker/dependabot/go_modules/github.com/stretchr/testify-1.8.4
build(deps): bump github.com/stretchr/testify from 1.8.3 to 1.8.4
2023-05-30 12:15:51 +02:00
dependabot[bot]
f5480ee3ed build(deps): bump github.com/stretchr/testify from 1.8.3 to 1.8.4
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.3 to 1.8.4.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.3...v1.8.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-30 10:00:07 +00:00
Nick Sieger
b4924dee83 Merge pull request #10627 from nicksieger/test-cucumber-port-conflict 2023-05-27 08:34:50 -05:00
Nick Sieger
2ca8ab914a e2e: make test re-runnable on the same machine
Signed-off-by: Nick Sieger <nick@nicksieger.com>
2023-05-26 15:54:39 -05:00
Nick Sieger
3ec8c60657 e2e: add a cuke feature to test compose errors with port conflicts
Signed-off-by: Nick Sieger <nick@nicksieger.com>
2023-05-26 15:54:35 -05:00
Nicolas De Loof
06ec06472f up should not silently ignore missing depends_on service
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-26 21:59:29 +02:00
Nicolas De Loof
466e1d3197 prevent buildkt's progress to render Building when no built is needed
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-26 15:04:37 +02:00
Nicolas De Loof
0d6b99e6f9 e2e test to cover logs -f managing service being added/scaled
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-26 14:51:23 +02:00
Nicolas De Loof
01d91c490c detect new container from project have started when running compose logs with no explicit services
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-26 14:15:48 +02:00
Nicolas De Loof
6f6e1635fd compute service hash with a default DeployConfig
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-26 14:15:33 +02:00
Jeremy Fleischman
3d05a1becf Fix typo in warning about existing volume
Previously, this was telling us "but was not created for project
[project-it-was-created-for]", which is wrong. I opted to make the
message super explicit and print both the actual project and the
expected project.

Signed-off-by: Jeremy Fleischman <jeremyfleischman@gmail.com>
2023-05-25 17:16:47 -07:00
Laura Brehm
42cd961d58 Merge pull request #10582 from docker/dependabot/go_modules/github.com/stretchr/testify-1.8.3 2023-05-25 14:16:17 +02:00
dependabot[bot]
d15fcc6444 build(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.3
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 12:03:43 +00:00
Laura Brehm
22c2471a08 Merge pull request #10572 from docker/dependabot/go_modules/github.com/cloudflare/cfssl-1.6.4 2023-05-25 13:53:07 +02:00
dependabot[bot]
29a1cc452d build(deps): bump github.com/cloudflare/cfssl from 1.4.1 to 1.6.4
Bumps [github.com/cloudflare/cfssl](https://github.com/cloudflare/cfssl) from 1.4.1 to 1.6.4.
- [Release notes](https://github.com/cloudflare/cfssl/releases)
- [Changelog](https://github.com/cloudflare/cfssl/blob/master/CHANGELOG)
- [Commits](https://github.com/cloudflare/cfssl/compare/v1.4.1...v1.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-24 21:10:49 +00:00
Milas Bowman
b05a94fd66 progress: remove errant import (#10614)
Write the warning using `logrus.Warn`. The function being used was
coming from `cfssl`'s log package, which was presumably the result
of auto-import being _slightly_ too aggressive.

(Note: `cfssl` is still an indirect dependency after this.)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-05-24 17:08:46 -04:00
Guillaume Lours
15cad92b61 fix display of volumes flag in down help command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-24 22:11:58 +02:00
Nicolas De Loof
c7afc6188b detect conflict removing volume/image and warn user
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-24 17:32:32 +02:00
Nicolas De Loof
ca19b7fcc9 introduce WithRootNodesAndDown to walk the graph from specified nodes and down
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-24 17:32:32 +02:00
Nicolas De Loof
93bd27a0cc introduce ability to select service to be stopped by compose down
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-24 17:32:32 +02:00
Nicolas De loof
68c462e607 scale: sort containers by creation date to remove older ones first (#10571)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-23 13:58:32 -04:00
Nicolas De loof
916aac6c27 watch: only monitor configured paths (#10599)
For performance, don't watch the entire build context.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-23 13:35:50 -04:00
Nicolas De loof
eafcd1b35e secrets: only set CopyUIDGID when required (#10598)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-23 13:34:24 -04:00
Allie Sadler
1e399c271a update docs to reflect dry run mode is feature complete
Signed-off-by: Allie Sadler <102604716+aevesdocker@users.noreply.github.com>
2023-05-23 15:53:48 +01:00
Guillaume Lours
544b579cb0 Merge pull request #10597 from ndeloof/ComposeProjectName
fix support for project name set by COMPOSE_PROJECT_NAME env var
2023-05-22 20:24:13 +02:00
Nicolas De Loof
daa6bec80a fix support for project name set by COMPOSE_PROJECT_NAME env var
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-22 19:14:57 +02:00
Sebastiaan van Stijn
34bd41cc0c go.mod: golang.org/x/oauth2 v0.1.0
docker/docker already depends on oauth2 v0.1.0, which differs only in
dependencies;

https://github.com/golang/oauth2/compare/6fdb5e3db783...v0.1.0

The replace rule is still needed to help with some dependency hell when
resolving the version to use;

    go mod tidy
    go: downloading cloud.google.com/go v0.75.0
    github.com/docker/compose/v2/pkg/compose imports
        github.com/moby/buildkit/client imports
        go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc tested by
        go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc.test imports
        google.golang.org/grpc/interop imports
        golang.org/x/oauth2/google imports
        cloud.google.com/go/compute/metadata: ambiguous import: found package cloud.google.com/go/compute/metadata in multiple modules:
        cloud.google.com/go v0.75.0 (/Users/thajeztah/go/pkg/mod/cloud.google.com/go@v0.75.0/compute/metadata)
        cloud.google.com/go/compute/metadata v0.2.1 (/Users/thajeztah/go/pkg/mod/cloud.google.com/go/compute/metadata@v0.2.1)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-22 15:01:38 +02:00
Guillaume Lours
70953b18c0 Merge pull request #10591 from ndeloof/fix_detect_swarm_enabled
fix detection of swarm mode
2023-05-22 09:25:56 +02:00
Nicolas De Loof
cfe1a860ff fix detection of swarm mode
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-22 08:26:22 +02:00
Laura Brehm
4dcda432cf Merge pull request #10578 from docker/dependabot/go_modules/github.com/sirupsen/logrus-1.9.2
build(deps): bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
2023-05-18 11:14:10 +01:00
dependabot[bot]
5c2a885647 build(deps): bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.2.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-18 09:59:38 +00:00
Guillaume Lours
cd0fc214a5 only check the platform of cached image if image found
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-17 08:04:54 +02:00
Nicolas De Loof
9b5a4588f9 introduce --no-path-resolution to skip relative path to be resolved
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-16 13:02:56 +02:00
Nicolas De Loof
00f72cb553 report external network not found when swarm is disabled
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-15 20:57:19 +02:00
Nicolas De Loof
fd7847f2ac parallel flag belong do top-level "compose" cobra command, not the current one
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-15 20:57:09 +02:00
Nicolas De Loof
18a112e88c detect terminal is not a console.File to avoid a panic
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-15 20:56:33 +02:00
Guillaume Lours
dc01b98aa6 Merge pull request #10559 from ndeloof/COMPOSE_ANSI
introduce COMPOSE_ANSI to define --ansi default value
2023-05-15 10:42:06 +02:00
Guillaume Lours
312f0d1d61 Update dry-run documentation
Co-authored-by: Allie Sadler <102604716+aevesdocker@users.noreply.github.com>
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-15 09:39:46 +02:00
Guillaume Lours
e8caad1903 move dry-run support from alpha to main command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-15 09:39:46 +02:00
Nicolas De Loof
fca454b41f introduce COMPOSE_ANSI to define --ansi default value
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-12 12:52:20 +02:00
Mateus Esdras
77dc9b54f3 rm: remove debugging output (#10554)
For example, when no container was being removed,
this would print `[]`.

Signed-off-by: Mateus Esdras <linux.esdras@gmail.com>
2023-05-11 16:32:29 -04:00
Nicolas De loof
bceb3c1876 detect active endpoint trying to remove network and skip with a warning (#10555)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-11 16:31:29 -04:00
Nicolas De loof
a14abb9044 cli: option to write status messages on stdout (#10549)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-11 12:45:00 -04:00
Nicolas De loof
0363d9260a fix local image removal when compose down is ran with --project-name (#10558)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-11 12:41:14 -04:00
Nicolas De loof
0e375a8c61 restore long description to be included in docker compose help (#10504)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-11 12:33:45 -04:00
Nicolas De Loof
b776826d92 check local image matches the required platform
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-10 16:57:21 +02:00
Guillaume Lours
3b32a264c7 Merge pull request #10544 from ndeloof/parallel_race
fix race condition when --parallel is used with a large number of dependent services
2023-05-10 11:50:59 +02:00
Nicolas De Loof
e92c5d1392 fix race condition running compose up with --parallel < number of services
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-10 11:39:07 +02:00
Nicolas De loof
0c1a691fa5 fix container being recreated while config has not changed (#10540)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-09 15:15:40 -04:00
Laura Brehm
f72d5d6099 Merge pull request #10508 from laurazard/tests-inline-dockerfile
Update 🥒 tests to use `dockerfile_inline`
2023-05-09 17:38:05 +01:00
Laura Brehm
ee70085fba tests: inline dockerfile
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-09 17:27:47 +01:00
dependabot[bot]
90bcf610b3 build(deps): bump github.com/moby/term from 0.0.0-20221205130635-1aeaba878587 to 0.5.0 (#10523)
build(deps): bump github.com/moby/term

Bumps [github.com/moby/term](https://github.com/moby/term) from 0.0.0-20221205130635-1aeaba878587 to 0.5.0.
- [Release notes](https://github.com/moby/term/releases)
- [Commits](https://github.com/moby/term/commits/v0.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-09 10:07:14 -04:00
Laura Brehm
2d25019fe9 Merge pull request #10521 from docker/dependabot/go_modules/go.opentelemetry.io/otel-1.15.1
build(deps): bump go.opentelemetry.io/otel from 1.15.0 to 1.15.1
2023-05-09 11:38:30 +01:00
Laura Brehm
fb16e49cb2 Merge pull request #10542 from docker/dependabot/go_modules/github.com/docker/cli-23.0.6incompatible
build(deps): bump github.com/docker/cli from 23.0.5+incompatible to 23.0.6+incompatible
2023-05-09 11:34:27 +01:00
Laura Brehm
109ce190c4 deps: update related modules
(see https://github.com/docker/compose/pull/10542/files#r1188432369)

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-05-09 11:18:09 +01:00
dependabot[bot]
ef03c906b9 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.5+incompatible to 23.0.6+incompatible.
- [Commits](https://github.com/docker/cli/compare/v23.0.5...v23.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-09 09:59:44 +00:00
dependabot[bot]
865a0867a4 build(deps): bump go.opentelemetry.io/otel from 1.15.0 to 1.15.1
Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.15.0 to 1.15.1.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.15.0...v1.15.1)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 13:23:13 +00:00
dependabot[bot]
6ee0376bb6 build(deps): bump golang.org/x/sync from 0.1.0 to 0.2.0 (#10534)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.1.0 to 0.2.0.
- [Commits](https://github.com/golang/sync/compare/v0.1.0...v0.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-08 09:22:03 -04:00
Nicolas De loof
67455e9f33 fix builkit progressui integration (#10535)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-08 09:21:41 -04:00
Guillaume Lours
5fdcaa0fe1 Merge pull request #10529 from glours/dry-run-up-support
add dry-run support to up command
2023-05-05 09:41:18 +02:00
Guillaume Lours
01afe5265e Merge pull request #10527 from ndeloof/build_secret_id
let user declare build secret target
2023-05-04 15:17:30 +02:00
Guillaume Lours
2e4faf80f5 add dry-run support to up command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-04 15:11:11 +02:00
Guillaume Lours
e88836ffbd Merge pull request #10525 from thaJeztah/update_go1.20.4
update go to go1.20.4
2023-05-04 11:52:37 +02:00
Nicolas De Loof
b45ca82791 let user declare build secret target (id)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-05-04 10:01:10 +02:00
Sebastiaan van Stijn
d1c36c6e6b update go to go1.20.4
go1.20.4 (released 2023-05-02) includes three security fixes to the html/template
package, as well as bug fixes to the compiler, the runtime, and the crypto/subtle,
crypto/tls, net/http, and syscall packages. See the Go 1.20.4 milestone on our
issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.20.4+label%3ACherryPickApproved

release notes: https://go.dev/doc/devel/release#go1.20.4
full diff: https://github.com/golang/go/compare/go1.20.3...go1.20.4

from the announcement:

> These minor releases include 3 security fixes following the security policy:
>
> - html/template: improper sanitization of CSS values
>
>   Angle brackets (`<>`) were not considered dangerous characters when inserted
>   into CSS contexts. Templates containing multiple actions separated by a '/'
>   character could result in unexpectedly closing the CSS context and allowing
>   for injection of unexpected HMTL, if executed with untrusted input.
>
>   Thanks to Juho Nurminen of Mattermost for reporting this issue.
>
>   This is CVE-2023-24539 and Go issue https://go.dev/issue/59720.
>
> - html/template: improper handling of JavaScript whitespace
>
>   Not all valid JavaScript whitespace characters were considered to be
>   whitespace. Templates containing whitespace characters outside of the character
>   set "\t\n\f\r\u0020\u2028\u2029" in JavaScript contexts that also contain
>   actions may not be properly sanitized during execution.
>
>   Thanks to Juho Nurminen of Mattermost for reporting this issue.
>
>   This is CVE-2023-24540 and Go issue https://go.dev/issue/59721.
>
> - html/template: improper handling of empty HTML attributes
>
>   Templates containing actions in unquoted HTML attributes (e.g. "attr={{.}}")
>   executed with empty input could result in output that would have unexpected
>   results when parsed due to HTML normalization rules. This may allow injection
>   of arbitrary attributes into tags.
>
>   Thanks to Juho Nurminen of Mattermost for reporting this issue.
>
>   This is CVE-2023-29400 and Go issue https://go.dev/issue/59722.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-03 21:38:19 +02:00
TP-O
b304c4e154 stop containers after termination
Signed-off-by: TP-O <letranphong2k1@gmail.com>
2023-05-03 11:47:56 +02:00
Guillaume Lours
eca1365d42 cli: dry run support for build (#10502)
* add dry-run support for classic builder
* add dry-run support for buildkit

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-02 14:23:26 -04:00
Guillaume Lours
03f4c0e631 progress: make title configurable (#10507)
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-02 14:15:35 -04:00
Guillaume Lours
2a0e83ad9a Merge pull request #10519 from glours/revert-image-spec-upgrade
Revert "build(deps): bump github.com/opencontainers/image-spec"
2023-05-02 13:13:13 +02:00
Guillaume Lours
2df9919ece Revert "build(deps): bump github.com/opencontainers/image-spec"
This reverts commit d54a95fed7.

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-05-02 12:31:27 +02:00
Guillaume Lours
74fc40d895 Merge pull request #10518 from docker/dependabot/go_modules/github.com/opencontainers/image-spec-1.1.0-rc.3
build(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3
2023-05-02 12:11:16 +02:00
dependabot[bot]
d54a95fed7 build(deps): bump github.com/opencontainers/image-spec
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-02 09:58:57 +00:00
Guillaume Lours
c1369869f5 Merge pull request #10515 from docker/dependabot/go_modules/go.opentelemetry.io/otel-1.15.0
build(deps): bump go.opentelemetry.io/otel from 1.14.0 to 1.15.0
2023-05-02 11:32:07 +02:00
dependabot[bot]
f5ff40a2f3 build(deps): bump go.opentelemetry.io/otel from 1.14.0 to 1.15.0
Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-02 10:51:17 +02:00
Guillaume Lours
6347b49f9c Merge pull request #10516 from docker/dependabot/go_modules/github.com/moby/buildkit-0.11.6
build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6
2023-05-02 10:50:09 +02:00
dependabot[bot]
c072a6f5f5 build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 10:05:25 +00:00
Guillaume Lours
a06d32e7b6 Merge pull request #10506 from docker/dependabot/go_modules/github.com/opencontainers/image-spec-1.1.0-rc.3
build(deps): bump github.com/opencontainers/image-spec from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3
2023-04-28 12:41:15 +02:00
dependabot[bot]
28fa309c23 build(deps): bump github.com/opencontainers/image-spec
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-28 12:26:50 +02:00
Laura Brehm
4f2c933f78 Merge pull request #10501 from docker/dependabot/go_modules/github.com/docker/cli-23.0.5incompatible
build(deps): bump github.com/docker/cli from 23.0.4+incompatible to 23.0.5+incompatible
2023-04-28 10:59:34 +01:00
dependabot[bot]
e22c8964b9 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.4+incompatible to 23.0.5+incompatible.
- [Release notes](https://github.com/docker/cli/releases)
- [Commits](https://github.com/docker/cli/compare/v23.0.4...v23.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-28 09:49:02 +00:00
Nicolas De Loof
07c4849cb9 TailMsgf must format with args
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-27 22:12:12 +02:00
Guillaume Lours
e606701d9f Merge pull request #10500 from docker/dependabot/go_modules/github.com/docker/docker-23.0.5incompatible
build(deps): bump github.com/docker/docker from 23.0.4+incompatible to 23.0.5+incompatible
2023-04-27 12:12:33 +02:00
dependabot[bot]
114e5c6425 build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.4+incompatible to 23.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v23.0.4...v23.0.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-27 10:00:06 +00:00
dependabot[bot]
37dfb5bf26 build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#10489)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-25 13:34:18 -04:00
Nicolas De Loof
d01ef5887a restore support for --memory
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-25 15:41:08 +02:00
Nicolas De Loof
dec608f3cd don't block events loop collecting logs
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-25 15:20:05 +02:00
Guillaume Lours
eb0632b1d8 Merge pull request #10494 from milas/e2e-dd-419
test: fix E2E tests under Engine v23 / DD 4.19
2023-04-25 08:37:24 +02:00
Milas Bowman
1383ab09ec test: fix E2E tests under Engine v23 / DD 4.19
Some error messages have been tweaked slightly, this adapts the
assertions to work on both Engine v20.10.x and v23.x.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-04-25 08:27:42 +02:00
Benjamín Guzmán
5eaafe4237 Fixed issue when project name contains dashes (-)
Signed-off-by: Benjamín Guzmán <bg@benjaminguzman.dev>
2023-04-24 12:18:37 +02:00
Benjamín Guzmán
7840a92c40 Added tests to viz subcommand
Signed-off-by: Benjamín Guzmán <bg@benjaminguzman.dev>
2023-04-24 12:18:37 +02:00
Benjamín Guzmán
3751c3074b Added docs
Signed-off-by: Benjamín Guzmán <bg@benjaminguzman.dev>
2023-04-24 12:18:37 +02:00
Benjamín Guzmán
2bc6a45c0b Replaced calls to WriteRune with WriteByte and reformatted imports
Signed-off-by: Benjamín Guzmán <bg@benjaminguzman.dev>
2023-04-24 12:18:37 +02:00
Benjamín Guzmán
2268d1e573 Started working on viz subcommand
Signed-off-by: Benjamín Guzmán <bg@benjaminguzman.dev>
2023-04-24 12:18:37 +02:00
Nicolas De Loof
7b0ed13209 bump compose-go to v1.13.4
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-20 11:12:07 +02:00
Laura Brehm
d4441efe1e Merge pull request #10474 from docker/dependabot/go_modules/github.com/docker/docker-23.0.4incompatible
build(deps): bump github.com/docker/docker from 23.0.3+incompatible to 23.0.4+incompatible
2023-04-18 19:44:16 +01:00
dependabot[bot]
58368f69e9 build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.3+incompatible to 23.0.4+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v23.0.3...v23.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-18 18:29:07 +00:00
Laura Brehm
bc2b2e52e5 Merge pull request #10475 from docker/dependabot/go_modules/github.com/docker/cli-23.0.4incompatible
build(deps): bump github.com/docker/cli from 23.0.3+incompatible to 23.0.4+incompatible
2023-04-18 19:27:54 +01:00
dependabot[bot]
7723d11930 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.3+incompatible to 23.0.4+incompatible.
- [Release notes](https://github.com/docker/cli/releases)
- [Commits](https://github.com/docker/cli/compare/v23.0.3...v23.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-18 09:59:33 +00:00
Nicolas De Loof
65fda18821 bump compose-go
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-17 17:19:56 +02:00
Tran Phong
0e7e1b940b Remove redundant goroutine while removing containers (#10449)
don't use goroutine to stop container while removing

Signed-off-by: TP-O <letranphong2k1@gmail.com>
2023-04-17 10:57:29 -04:00
Milas Bowman
af6f0ffb9e Merge pull request #10458 from thaJeztah/simplify_auth
Don't use "info.IndexServerAddress" for authentication
2023-04-12 12:19:04 -04:00
Milas Bowman
9ef173a3ac log: fix race on container kill (#10459)
If we go to inspect a container that we got an event for and it
no longer exists on the server, handle clean up without erroring
out.

Fixes #10373.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-04-12 12:15:58 -04:00
Guillaume Lours
1fb0c03e8b Merge pull request #10457 from thaJeztah/mod_tidy
go.mod: fix grouping of dependencies, and tidy
2023-04-11 23:36:19 +02:00
Sebastiaan van Stijn
1892be8c70 Don't use "info.IndexServerAddress" for authentication
The IndexServerAddress field was  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.

This replaces the code that calls out to the "/info" endpoint to use the
GetAuthConfigKey() function instead.

Related PR in docker/cli:
b4ca1c7368

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-04-11 23:10:22 +02:00
Sebastiaan van Stijn
37068a700f go.mod: fix grouping of dependencies, and tidy
go mod tidy sometimes messes up grouping of imports, and may
need a bit of hand-holding in those cases :)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-04-11 22:32:53 +02:00
Guillaume Lours
a4af5e229d Merge pull request #10455 from docker/dependabot/go_modules/github.com/opencontainers/runc-1.1.5
build(deps): bump github.com/opencontainers/runc from 1.1.3 to 1.1.5
2023-04-10 20:59:28 +02:00
dependabot[bot]
87da6c1470 build(deps): bump github.com/opencontainers/runc from 1.1.3 to 1.1.5
Bumps [github.com/opencontainers/runc](https://github.com/opencontainers/runc) from 1.1.3 to 1.1.5.
- [Release notes](https://github.com/opencontainers/runc/releases)
- [Changelog](https://github.com/opencontainers/runc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/opencontainers/runc/compare/v1.1.3...v1.1.5)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/runc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 18:47:06 +00:00
Guillaume Lours
a99acd940a Merge pull request #10444 from glours/dry-run-down-support
add dry-run support to down command
2023-04-07 15:46:39 +02:00
Guillaume Lours
7fb87856aa add dry-run support to down command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-04-07 10:41:51 +02:00
Guillaume Lours
eb933adde0 Merge pull request #10451 from glours/fix-gocyclo-ci-issue
fix gocyclo lint error which currently block Compose CI
2023-04-07 10:41:36 +02:00
Guillaume Lours
cb688b5fd4 fix gocyclo lint error which currently block Compose CI
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-04-07 10:19:06 +02:00
Nicolas De Loof
8b5b78fbb6 can't watch a service without a build section
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-06 08:55:49 +02:00
Nicolas De Loof
d3e49fe360 ansi=auto|never|always
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-06 08:24:04 +02:00
Guillaume Lours
1bca8d5c01 Merge pull request #10438 from glours/bump-docker-23.0.3
bump docker version to 23.0.3 (CVE-2023-28840)
2023-04-05 12:17:47 +02:00
Guillaume Lours
76d9cf2711 bump docker version to 23.0.3 (CVE-2023-28840)
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-04-05 12:02:57 +02:00
Nicolas De loof
d762f5f473 better support NO_COLOR by disabling colors, not ANSI TUI (#10434)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-04 17:00:10 -04:00
Guillaume Lours
90eda35f3d Merge pull request #10437 from milas/bump-go-1.20.3
ci: bump Go to 1.20.3 and various dependencies
2023-04-04 21:33:20 +02:00
Milas Bowman
7ce0096f40 ci: bump Go to 1.20.3 and various dependencies
Use latest Go minor release. Note: this release included fixes for
several CVEs, but they do not impact Compose.

Small errors have been fixed to keep the linter happy.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-04-04 15:15:02 -04:00
Milas Bowman
00eca0af70 Merge pull request #10432 from ndeloof/timeout
restore `--timeout` flag renamed by mistake
2023-04-04 15:03:04 -04:00
Nicolas De Loof
a10c4c6df5 restore --timeout flag renamed by mistake
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-04-04 08:48:00 +02:00
Guillaume Lours
6a37428491 Merge pull request #10413 from glours/dry-run-create-support
add dry-run support to create command
2023-04-03 18:25:55 +02:00
Guillaume Lours
449a46a252 Merge pull request #10423 from ndeloof/build_classic_panic
prevent panic using classic builder
2023-03-31 12:36:27 +02:00
Nicolas De Loof
981cb2024e prevent panic using classic builder
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-31 11:59:22 +02:00
Guillaume Lours
b83edbd039 add dry-run support to create command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-30 10:25:56 +02:00
Milas Bowman
02ad467f89 Merge pull request #10415 from docker/dependabot/go_modules/github.com/docker/cli-23.0.2incompatible
build(deps): bump github.com/docker/cli from 23.0.1+incompatible to 23.0.2+incompatible
2023-03-29 09:28:45 -04:00
Milas Bowman
d9e1d419c1 Merge pull request #10414 from docker/dependabot/go_modules/github.com/docker/docker-23.0.2incompatible
build(deps): bump github.com/docker/docker from 23.0.1+incompatible to 23.0.2+incompatible
2023-03-29 09:28:20 -04:00
dependabot[bot]
a4c324b8e6 build(deps): bump github.com/docker/cli
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.1+incompatible to 23.0.2+incompatible.
- [Release notes](https://github.com/docker/cli/releases)
- [Commits](https://github.com/docker/cli/compare/v23.0.1...v23.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 09:59:37 +00:00
dependabot[bot]
087fae98b6 build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.1+incompatible to 23.0.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v23.0.1...v23.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 09:59:27 +00:00
Milas Bowman
aafeaa66e2 Merge pull request #10409 from ndeloof/ContainerList_race
workaround race condition in ContainerList
2023-03-28 14:53:53 -04:00
Nicolas De Loof
c5317496ac workaround race condition in ContainerList
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-28 12:28:41 +02:00
Milas Bowman
67c9ecb4f4 Merge pull request #10404 from glours/dry-run-run-support
add dry-run support to run command
2023-03-27 17:42:28 -04:00
Guillaume Lours
72a61c0602 add dry-run support to run command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-27 18:57:11 +02:00
Guillaume Lours
0b6133f75b Merge pull request #10406 from milas/fix-name-validation
ci: bump compose-go to v1.13.2
2023-03-26 16:09:47 +02:00
Milas Bowman
b24af42bcc ci: bump compose-go to v1.13.2
https://github.com/compose-spec/compose-go/releases/tag/v1.13.2

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-26 09:55:53 -04:00
Milas Bowman
cc70851bc8 Merge pull request #10403 from milas/fix-e2e-win
test: fix e2e commands on Windows
2023-03-24 12:13:42 -04:00
Milas Bowman
3b85cd2fa9 test: fix e2e commands on Windows
Instead of trying to make this work nicely cross-platform,
just push the Coverage logic into the GitHub Actions job,
as that's really where we care about it.

(It's surprisingly difficult to make this nicely portable;
to make PowerShell not error out if the path does not exist
you have to ignore ALL errors and the way that env vars are
passed to processes is not the same.)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-24 11:50:05 -04:00
Milas Bowman
d818bf6f34 Merge pull request #10401 from milas/deps-update
ci: upgrade to Go 1.20.2 & bump deps
2023-03-24 11:05:53 -04:00
Milas Bowman
45a852f438 test: generate valid Compose project names from Cucumber specs
Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-24 10:54:33 -04:00
Milas Bowman
f0bf4fca76 Merge pull request #10402 from milas/fix-e2e-race
test: fix race in e2e build test
2023-03-24 10:44:54 -04:00
Milas Bowman
cd17c8a950 test: update error message
Validation got improved in `compose-go` so the error message is
slightly different.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-24 10:42:43 -04:00
Milas Bowman
36625ed229 test: fix race in e2e build test
This was running two tests in parallel that would build/delete the
same images. Run in serial instead since that's not safe.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-24 10:32:55 -04:00
Milas Bowman
a6ffdf6110 ci: upgrade to Go 1.20.2 & bump deps
* Go 1.20.2
* golangci-lint v1.52.0
* compose-go v1.13.1: https://github.com/compose-spec/compose-go/releases/tag/v1.13.1

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-24 09:31:28 -04:00
Milas Bowman
72260d615d Merge pull request #10400 from docker/dependabot/go_modules/github.com/moby/buildkit-0.11.5
build(deps): bump github.com/moby/buildkit from 0.11.4 to 0.11.5
2023-03-24 09:12:51 -04:00
Milas Bowman
fd28ab8d38 Merge pull request #10399 from ndeloof/watch_rebuild
watch involves up --build after change has been detected
2023-03-24 09:10:56 -04:00
dependabot[bot]
9ab5d8c44e build(deps): bump github.com/moby/buildkit from 0.11.4 to 0.11.5
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.4 to 0.11.5.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.4...v0.11.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-24 10:00:03 +00:00
Nicolas De Loof
d637cc3ade watch involves up --build after change has been detected
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-24 10:49:27 +01:00
Milas Bowman
925bc6fbf3 Merge pull request #10393 from milas/fix-watch-segfault
watch: data race / segfault fixes
2023-03-23 17:07:49 -04:00
Milas Bowman
16d5354d70 watch: add note about goroutine-safety & test
Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-23 11:33:03 -04:00
Milas Bowman
7aaea283ca watch: data race / segfault fixes
Was getting segfaults with multiple services using
`x-develop` and `watch` at the same time. Turns out
the Moby path matcher lazily initializes the regex
pattern internally the first time it's used, so it's
not goroutine-safe.

Change here is to not use a global instance for the
ephemeral path matcher, but a per-watcher instance.

Additionally, the data race detector caught a couple
other issues that were easy enough to fix:
 * Use the lock that's used elsewhere for convergence
   before manipulating
 * Eliminate concurrent map access when triggering
   rebuilds

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-22 18:05:56 -04:00
Guillaume Lours
6bedc196cc update -p project name flag documentation
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-22 10:53:54 +01:00
Nicolas De Loof
a11515e038 introduce ignore attribute for watch triggers
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-21 18:29:49 +01:00
Nicolas De Loof
6c1f06e420 Run classic builder with BuildConfig, not buildx.Options
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-21 15:37:55 +01:00
Nicolas De Loof
88b0d17ff8 use build as common API for build scenarios
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-21 15:37:55 +01:00
Nicolas De Loof
9e19bc8441 use progress to show copy status
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-21 14:40:52 +01:00
Guillaume Lours
bef9c48a1a Merge pull request #10386 from milas/fw-renames
watch: add file delete/rename handling
2023-03-21 13:48:56 +01:00
Milas Bowman
105a7c5b70 watch: add file delete/rename handling
This approach mimics Tilt's behavior[^1]:
 1. At sync time, `stat` the path on host
 2. If the path does not exist -> `rm` from container
 3. If the path exists -> sync to container

By handling things this way, we're always syncing based on the true
state, regardless of what's happened in the interim. For example, a
common pattern in POSIX tools is to create a file and then rename it
over an existing file. Based on timing, this could be a sync, delete,
sync (every file gets seen & processed) OR a delete, sync (by the
the time we process the event, the "temp" file is already gone, so
we just delete it from the container, where it never existed, but
that's fine since we deletes are idempotent thanks to the `-f` flag
on `rm`).

Additionally, when syncing, if the `stat` call shows it's for a
directory, we ignore it. Otherwise, duplicate, nested copies of the
entire path could get synced in. (On some OSes, an event for the
directory gets dispatched when a file inside of it is modified. In
practice, I think we might want this pushed further down in the
watching code, but since we're already `stat`ing the paths here now,
it's a good place to handle it.)

Lastly, there's some very light changes to the text when it does a
full rebuild that will list out the (merged) set of paths that
triggered it. We can continue to improve the output, but this is
really helpful for understanding why it's rebuilding.

[^1]: db7f887b06/internal/controllers/core/liveupdate/reconciler.go (L911)

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-03-21 08:37:18 -04:00
Laura Brehm
03f0ed132d Merge pull request #10352 from docker/dependabot/go_modules/github.com/docker/buildx-0.10.4
build(deps): bump github.com/docker/buildx from 0.10.3 to 0.10.4
2023-03-19 21:11:57 +00:00
Laura Brehm
f7a13aee11 build(deps): bump github.com/docker/buildx from 0.10.3 to 0.10.4
Bumps [github.com/docker/buildx](https://github.com/docker/buildx) from 0.10.3 to 0.10.4.
- [Release notes](https://github.com/docker/buildx/releases)
- [Commits](https://github.com/docker/buildx/compare/v0.10.3...v0.10.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-03-19 20:59:58 +00:00
Luis Rascao
bfeb1dc277 Fix concurrent map read/write when recreating containers
Signed-off-by: Luis Rascao <luis.rascao@gmail.com>
2023-03-19 21:56:06 +01:00
Laura Brehm
9ec43973e2 Merge pull request #10353 from docker/dependabot/go_modules/github.com/moby/buildkit-0.11.4
build(deps): bump github.com/moby/buildkit from 0.11.3 to 0.11.4
2023-03-19 20:40:31 +00:00
dependabot[bot]
0b41df9821 build(deps): bump github.com/moby/buildkit from 0.11.3 to 0.11.4
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.3 to 0.11.4.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.3...v0.11.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-19 20:28:31 +00:00
Guillaume Lours
643557d534 build and push binaries images when a PR is merged or a tag pushed
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-16 11:23:49 +01:00
Laura Brehm
200f47e5be Add support for additional_contexts in build service config
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
2023-03-15 14:00:51 +01:00
Nicolas De Loof
e0aaccf430 introduce dockerfile_inline
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-15 10:19:04 +01:00
Nicolas De Loof
754c06886f one off container name use configured Separator for naming
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-15 09:47:43 +01:00
Nicolas De Loof
e492330dd5 collect built image IDs
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-15 09:47:32 +01:00
Nicolas De Loof
bbe1b77a67 progress writer uses dockercli.Err stream
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-15 09:47:13 +01:00
Tianon Gravi
fc4d2dfdd8 Remove "-s" from LDFLAGS
While this stripping does decrease the binary size by some amount, it also removes the ability for `govulncheck` (https://go.dev/blog/vuln) to scan the binary for actual uses of vulnerable functions, requiring the user to clone the code locally and hope they're testing against the same version of the stdlib, etc that the binary was built with.  If we stop passing `-s`, then we can then run `govulncheck` on the binary directly (making it easier to flag both false positives in CVE scans _and_ actual issues worth looking into).

Here's an example of the output on a freshly built binary with this change:

```console
$ govulncheck ./bin/build/docker-compose
govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.

Using govulncheck@v0.0.0 with
vulnerability data from https://vuln.go.dev (last modified 27 Feb 23 16:29 UTC).

Scanning your binary for known vulnerabilities...
No vulnerabilities found.
```

Compared to the 1.16.0 release binary:

```console
$ govulncheck ./docker-compose
go: downloading golang.org/x/vuln v0.0.0-20230224180816-edec1fb0a9c7
govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.

Using govulncheck@v0.0.0 with
vulnerability data from https://vuln.go.dev (last modified 27 Feb 23 16:29 UTC).

Scanning your binary for known vulnerabilities...
govulncheck: vulncheck.Binary: reading go:func.*: no symbol "go:func.*"
```

It's not 100% apples-to-apples, but the size difference between these binaries is ~46MiB for the 1.16.0 release and ~52MiB for the binary I built from this commit.

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
2023-03-13 08:16:48 +00:00
Nicolas De Loof
85ddfde5d6 use go 1.20 -cover support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-10 16:54:39 +00:00
Nicolas De Loof
6a0398d786 pad can be negative on small terminal
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-09 10:27:43 +00:00
Guillaume Lours
4434cea535 add dry-run support for push command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-08 14:23:57 +00:00
Guillaume Lours
62fbf20887 Merge pull request #10341 from glours/dry-run-pull-support
add dry-run support for pull command
2023-03-06 11:13:42 +01:00
Guillaume Lours
3f7d3c2661 add dry-run support for pull command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-05 22:04:32 +01:00
Nicolas De Loof
9cc1613b55 adopt http://no-color.org/
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-03 11:15:40 +01:00
Guillaume Lours
c4b47fe911 Merge pull request #10339 from glours/dry-run-restart-support
Dry run restart support
2023-03-02 10:25:51 +01:00
Guillaume Lours
167c6a89b1 add dry-run support to restart command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-02 10:14:59 +01:00
Guillaume Lours
a84345be8f Merge pull request #10338 from glours/fix-restart-depends_on
restart only needed services by checking depends_on relations
2023-03-02 10:14:28 +01:00
Guillaume Lours
3cfbac6624 restart only needed services by checking depends_on relations
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-03-01 18:22:40 +01:00
Nicolas De Loof
a3bed265f2 update compose-go
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-01 17:14:53 +01:00
Nicolas De Loof
ae26426cc8 Report error if project name is empty after normalization
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-01 16:37:43 +01:00
Nicolas De Loof
4ea44797f5 only consider containers with config_hash labels (i.e, created by compose)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-03-01 15:46:50 +01:00
Guillaume Lours
a99a0b50ef Merge pull request #10320 from milas/e2e-win-pause
test: tweak pause test to try and prevent failures in Windows CI
2023-03-01 10:36:11 +01:00
Guillaume Lours
af414e9e2c Merge pull request #10330 from docker/dependabot/go_modules/github.com/containerd/containerd-1.6.19
build(deps): bump github.com/containerd/containerd from 1.6.18 to 1.6.19
2023-03-01 10:34:25 +01:00
dependabot[bot]
89633748d2 build(deps): bump github.com/containerd/containerd from 1.6.18 to 1.6.19
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.18 to 1.6.19.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.6.18...v1.6.19)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 10:10:11 +01:00
Laura Brehm
f648c2949b Merge pull request #10329 from docker/dependabot/go_modules/go.opentelemetry.io/otel-1.14.0
build(deps): bump go.opentelemetry.io/otel from 1.13.0 to 1.14.0
2023-02-28 12:50:06 +01:00
dependabot[bot]
33aa6acefe build(deps): bump go.opentelemetry.io/otel from 1.13.0 to 1.14.0
Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 10:01:36 +00:00
Milas Bowman
e31b95c16d test: tweak pause test to try and prevent failures in Windows CI
This test keeps failing with a timeout in Windows. I don't actually
think it should take that long to bring up an nginx container, so
I'm guessing that there's something else going on that's causing
trouble.

Increase the verbosity when running Compose commands: I think this
will generally make E2E test failures easier to diagnose by always
logging the full command that's going to be run and also capturing
stdout.

Add a health check and use `--wait` when launching the fixture for
the pause test. Combined with the verbosity increase, this should
make it easier to understand what's going on here.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-02-27 14:20:20 -05:00
Milas Bowman
d4f156cc7d Merge pull request #10311 from milas/fw-ephemeral
watch: ignore ephemeral files & minor output tweaks
2023-02-27 09:26:18 -05:00
Laura Brehm
c0daf8d3b5 Merge pull request #10316 from docker/dependabot/go_modules/github.com/stretchr/testify-1.8.2
build(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
2023-02-27 11:31:43 +01:00
dependabot[bot]
7bb60d091c build(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.1...v1.8.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 10:04:52 +00:00
Milas Bowman
da1ca578b5 watch: ignore ephemeral files & minor output tweaks
Big change here is to import the ephemeral ignore set from Tilt.

The `.git` directory is also ignored for now: this restriction
should probably be lifted and made configurable in the future,
but it's not generally important to watch and triggers a LOT of
events (e.g. Git creates `index.lock` files that will appear and
disappear rapidly as terminals/IDEs/etc interact with Git, even
for read-only operations).

The Tilt-provided ephemeral file set has been slowly devised over
time based on temporary files that can cause trouble. We can also
look at a more robust/configurable solution here in the future,
but thse provide a reasonable out-of-the-box configuration for
the moment.

There's also some small tweaks to the output to add missing
newlines in a few edge cases and such.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-02-24 14:34:51 -05:00
Milas Bowman
267cde91df Merge pull request #10302 from glours/update-golang-x-net
bump golang/x/net to v0.7.0 (CVE-2022-41723)
2023-02-21 14:35:03 -05:00
Guillaume Lours
18af72af87 bump golang/x/net to v0.7.0 (CVE-2022-41723)
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-02-21 18:32:48 +01:00
Nicolas De Loof
e831ea826b add support for restart for depends_on
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-18 12:55:29 +01:00
Milas Bowman
8d56db5e1d Merge pull request #10287 from docker/dependabot/go_modules/github.com/containerd/containerd-1.6.18
build(deps): bump github.com/containerd/containerd from 1.6.17 to 1.6.18
2023-02-17 11:23:29 -05:00
dependabot[bot]
1edc64ef93 build(deps): bump github.com/containerd/containerd from 1.6.17 to 1.6.18
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.17 to 1.6.18.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.6.17...v1.6.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-17 15:13:16 +00:00
Milas Bowman
156e54a09e Merge pull request #10291 from docker/dependabot/go_modules/github.com/docker/buildx-0.10.3
build(deps): bump github.com/docker/buildx from 0.10.2 to 0.10.3
2023-02-17 10:11:40 -05:00
Milas Bowman
762cf9d998 Merge pull request #10252 from glours/dry-run-exec-support
support dry-run for exec command
2023-02-17 10:05:31 -05:00
Nicolas De Loof
f3e543fd6a apply config options for pseudo-subcommands
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-17 12:11:18 +01:00
dependabot[bot]
9732608ec2 build(deps): bump github.com/docker/buildx from 0.10.2 to 0.10.3
Bumps [github.com/docker/buildx](https://github.com/docker/buildx) from 0.10.2 to 0.10.3.
- [Release notes](https://github.com/docker/buildx/releases)
- [Commits](https://github.com/docker/buildx/compare/v0.10.2...v0.10.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-17 10:00:59 +00:00
Nicolas De Loof
24ff098252 compact TUI to monitor layers download progress
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-16 17:55:59 +01:00
Milas Bowman
593c4263f3 ci: bump to Go 1.20.1 and latest deps
* Go v1.20.1
* golangci-lint v1.51.1
* compose-go v1.10.0
* buildx v0.10.2
* BuildKit v0.11.3
* moby v23.0.1

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-02-16 07:26:18 +01:00
Nicolas De Loof
313b82e94c ignore services without a build section
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-14 15:18:44 +01:00
Nicolas De Loof
5e3e2171d4 sort service --hash output by service name
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-14 12:17:00 +01:00
Nicolas De Loof
9ac0392baf introduce --timeout on up
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-14 12:16:41 +01:00
Nicolas De Loof
0612b34c68 introduce --no-deps on restart
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-14 11:30:15 +01:00
Nicolas De Loof
92e0cd4047 also restart dependent services after a service has been restarted
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-14 11:30:15 +01:00
Laura Brehm
1a410ffe30 Merge pull request #10279 from docker/dependabot/go_modules/go.uber.org/goleak-1.2.1
build(deps): bump go.uber.org/goleak from 1.1.12 to 1.2.1
2023-02-14 11:22:59 +01:00
dependabot[bot]
282a29e67e build(deps): bump go.uber.org/goleak from 1.1.12 to 1.2.1
Bumps [go.uber.org/goleak](https://github.com/uber-go/goleak) from 1.1.12 to 1.2.1.
- [Release notes](https://github.com/uber-go/goleak/releases)
- [Changelog](https://github.com/uber-go/goleak/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/goleak/compare/v1.1.12...v1.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-14 10:01:06 +00:00
Nicolas De Loof
256ec49974 exclude unstable labels from config hash
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-13 17:02:28 +01:00
Nicolas De Loof
9765f171cd store exec details to offer better dry-run status on ExecStart
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-13 11:59:01 +01:00
Nicolas De Loof
b19df5c96c add support for excludes and rebuild
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-10 17:24:48 +01:00
Nicolas De Loof
7a42ba7eec use CGO to enable fsevent on OSX
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-02-10 17:24:48 +01:00
Milas Bowman
5b043c4d59 ci: don't use -race on Windows
I misunderstood the cause of the symptom in #10261 - thought that
we'd explicitly turned off CGO for Windows with some of the build
changes recently, but we don't even have `gcc` on the CI node, so
it's actually just `-race` entirely that's the trouble.

For right now, going the easy route and disabling it. We can look
at getting a C toolchain on the Windows machine later.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-02-10 15:51:48 +01:00
Milas Bowman
d93da187f2 Merge pull request #10261 from milas/ci-win-e2e
ci: use CGO for tests to enable race detector
2023-02-09 15:52:56 -05:00
Milas Bowman
15f7104cd3 ci: use CGO for tests to enable race detector
```
go: -race requires cgo; enable cgo by setting CGO_ENABLED=1
```

We're explicitly using CGO on macOS now for FSEvents support and
purposefully NOT using CGO on other platforms since we don't need
it.

The race detector (`-race`) requires it, however, so for the e2e
make task, it should alway be on.

Signed-off-by: Milas Bowman <milas.bowman@docker.com>
2023-02-09 13:29:51 -05:00
Guillaume Lours
eb1c798912 support dry-run for rm command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-02-09 17:34:10 +01:00
Guillaume Lours
78b9404767 support dry-run for stop command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-02-09 17:34:10 +01:00
Guillaume Lours
25be264ed8 support dry-run for exec command
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
2023-02-08 11:21:47 +01:00
Josh Wilson
6fae6a41f9 Update emacs ignore patterns (#5903)
Currently the emacs ignore patterns include `**/.#*` (lock files), but
doesn't include `**/#*#` (autosave files;
https://www.emacswiki.org/emacs/AutoSave, not to be confused with
`**/*~` backup files which are ignored.)

Add autosave files.
2022-07-26 08:57:40 -05:00
Milas Bowman
dd5ea044bb ignore: add Go umask files to ephemeral set (#5740)
When creating files in Go, the stdlib will create (and then rapidly
delete) files ending with `-go-tmp-umask` to determine the umask
to use for permission purposes.

This can cause trouble with Live Update because the files tend to
vanish underneath it, for example.

Fixes #5117.
2022-04-27 16:42:51 -04:00
Milas Bowman
12de97b8d1 filewatch: use apiserver FileWatch model in EngineState (#4277)
This follows the "action-first" approach to use the apiserver model
for `FileWatch` and dispatch simple create/update/delete actions.
2021-03-09 13:05:32 -05:00
Iggy Jackson
62b5f78fd9 Add .kate-swp files to ignore pattern (#3380)
KDE's text editor, kate, uses a file similar to Vim's .swp files. Ignore
these files so we don't rebuild on every keypress.

Fixes #3378
2020-05-27 07:36:06 -07:00
Nick Santos
3f526c5c7b change org name from windmilleng to tilt-dev (#3346) 2020-05-15 10:34:39 -04:00
Matt Landis
12916b75a2 tilt: ignore a few more vim swap files (#2190) 2019-09-12 11:57:39 -04:00
Maia McCormick
e3948f6bae ignore: auto-ignore jetbrains .idea file (#2065) 2019-08-15 14:38:44 -04:00
Dan Miller
91a2bdd6de model: move to pkg (#2024) 2019-08-09 12:52:31 -04:00
Nick Santos
ce61e7bf18 ignore: improve the ephemeral temp file patterns [ch2663] (#1925) 2019-07-29 11:18:22 -04:00
290 changed files with 11937 additions and 3791 deletions

View File

@@ -5,14 +5,20 @@ updates:
schedule:
interval: daily
ignore:
# docker/buildx + docker/cli + docker/docker require coordination to
# ensure compatibility between them
# docker + moby deps require coordination
- dependency-name: "github.com/docker/buildx"
# buildx is still 0.x
update-types: ["version-update:semver-minor"]
- dependency-name: "github.com/moby/buildkit"
# buildkit is still 0.x
update-types: [ "version-update:semver-minor" ]
- dependency-name: "github.com/docker/cli"
# docker/cli uses CalVer rather than SemVer
update-types: ["version-update:semver-major", "version-update:semver-minor"]
update-types: ["version-update:semver-major"]
- dependency-name: "github.com/docker/docker"
# docker/docker uses CalVer rather than SemVer
update-types: ["version-update:semver-major", "version-update:semver-minor"]
update-types: ["version-update:semver-major"]
- dependency-name: "github.com/containerd/containerd"
# containerd major/minor must be kept in sync with moby
update-types: [ "version-update:semver-major", "version-update:semver-minor" ]
- dependency-name: "go.opentelemetry.io/otel/*"
# OTEL is v1.x but has some parts that are not API stable yet
update-types: [ "version-update:semver-major", "version-update:semver-minor"]

View File

@@ -7,7 +7,7 @@ concurrency:
on:
push:
branches:
- 'v2'
- 'main'
tags:
- 'v*'
pull_request:
@@ -19,7 +19,6 @@ on:
default: "false"
env:
DESTDIR: "./bin"
DOCKER_CLI_VERSION: "20.10.17"
permissions:
@@ -103,7 +102,7 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: compose
path: ${{ env.DESTDIR }}/*
path: ./bin/release/*
if-no-files-found: error
test:
@@ -123,18 +122,22 @@ jobs:
set: |
*.cache-from=type=gha,scope=test
*.cache-to=type=gha,scope=test
-
name: Gather coverage data
uses: actions/upload-artifact@v3
with:
name: coverage-data-unit
path: bin/coverage/unit/
if-no-files-found: error
e2e:
runs-on: ubuntu-latest
env:
DESTDIR: "./bin/build"
strategy:
fail-fast: false
matrix:
mode:
- plugin
- standalone
- cucumber
steps:
-
name: Checkout
@@ -158,7 +161,7 @@ jobs:
name: Build
uses: docker/bake-action@v2
with:
targets: binary
targets: binary-with-coverage
set: |
*.cache-from=type=gha,scope=binary-linux-amd64
*.cache-from=type=gha,scope=binary-e2e-${{ matrix.mode }}
@@ -176,10 +179,17 @@ jobs:
name: Test plugin mode
if: ${{ matrix.mode == 'plugin' }}
run: |
make e2e-compose
rm -rf ./bin/coverage/e2e
mkdir -p ./bin/coverage/e2e
make e2e-compose GOCOVERDIR=bin/coverage/e2e TEST_FLAGS="-v"
-
name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
name: Gather coverage data
if: ${{ matrix.mode == 'plugin' }}
uses: actions/upload-artifact@v3
with:
name: coverage-data-e2e
path: bin/coverage/e2e/
if-no-files-found: error
-
name: Test standalone mode
if: ${{ matrix.mode == 'standalone' }}
@@ -187,11 +197,44 @@ jobs:
rm -f /usr/local/bin/docker-compose
cp bin/build/docker-compose /usr/local/bin
make e2e-compose-standalone
-
name: Run cucumber tests
if: ${{ matrix.mode == 'cucumber'}}
coverage:
runs-on: ubuntu-22.04
needs:
- test
- e2e
steps:
# codecov won't process the report without the source code available
- name: Checkout
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
check-latest: true
- name: Download unit test coverage
uses: actions/download-artifact@v3
with:
name: coverage-data-unit
path: coverage/unit
- name: Download E2E test coverage
uses: actions/download-artifact@v3
with:
name: coverage-data-e2e
path: coverage/e2e
- name: Merge coverage reports
run: |
make test-cucumber
go tool covdata textfmt -i=./coverage/unit,./coverage/e2e -o ./coverage.txt
- name: Store coverage report in GitHub Actions
uses: actions/upload-artifact@v3
with:
name: go-covdata-txt
path: ./coverage.txt
if-no-files-found: error
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: ./coverage.txt
release:
permissions:
@@ -209,10 +252,10 @@ jobs:
uses: actions/download-artifact@v3
with:
name: compose
path: ${{ env.DESTDIR }}
path: bin/release
-
name: Create checksums
working-directory: ${{ env.DESTDIR }}
working-directory: bin/release
run: |
find . -type f -print0 | sort -z | xargs -r0 shasum -a 256 -b | sed 's# \*\./# *#' > $RUNNER_TEMP/checksums.txt
shasum -a 256 -U -c $RUNNER_TEMP/checksums.txt
@@ -220,21 +263,21 @@ jobs:
cat checksums.txt | while read sum file; do echo "$sum $file" > ${file#\*}.sha256; done
-
name: License
run: cp packaging/* ${{ env.DESTDIR }}/
run: cp packaging/* bin/release/
-
name: List artifacts
run: |
tree -nh ${{ env.DESTDIR }}
tree -nh bin/release
-
name: Check artifacts
run: |
find ${{ env.DESTDIR }} -type f -exec file -e ascii -- {} +
find bin/release -type f -exec file -e ascii -- {} +
-
name: GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
uses: ncipollo/release-action@58ae73b360456532aafd58ee170c045abbeaee37 # v1.10.0
with:
artifacts: ${{ env.DESTDIR }}/*
artifacts: bin/release/*
generateReleaseNotes: true
draft: true
token: ${{ secrets.GITHUB_TOKEN }}

58
.github/workflows/codeql.yml vendored Normal file
View File

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

42
.github/workflows/docs-upstream.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
# this workflow runs the remote validate bake target from docker/docs
# to check if yaml reference docs used in this repo are valid
name: docs-upstream
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- 'main'
- 'v[0-9]*'
paths:
- '.github/workflows/docs-upstream.yml'
- 'docs/**'
pull_request:
paths:
- '.github/workflows/docs-upstream.yml'
- 'docs/**'
jobs:
docs-yaml:
runs-on: ubuntu-22.04
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Upload reference YAML docs
uses: actions/upload-artifact@v3
with:
name: docs-yaml
path: docs/reference
retention-days: 1
validate:
uses: docker/docs/.github/workflows/validate-upstream.yml@main
needs:
- docs-yaml
with:
module-name: docker/compose

View File

@@ -1,56 +0,0 @@
name: Docs
on:
release:
types: [published]
permissions: {}
jobs:
open-pr:
permissions:
contents: write # to create branch (peter-evans/create-pull-request)
pull-requests: write # to create a PR (peter-evans/create-pull-request)
runs-on: ubuntu-latest
steps:
-
name: Checkout docs repo
uses: actions/checkout@v3
with:
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
repository: docker/docs
ref: main
-
name: Prepare
run: |
rm -rf ./_data/compose-cli/*
-
name: Build
uses: docker/build-push-action@v3
with:
context: ${{ github.server_url }}/${{ github.repository }}.git#${{ github.event.release.name }}
target: docs-reference
outputs: ./_data/compose-cli
-
name: Update compose_version in _config.yml
run: |
sed -i "s|^compose_version\:.*|compose_version\: \"${{ github.event.release.name }}\"|g" _config.yml
cat _config.yml | yq .compose_version
-
name: Commit changes
run: |
git add -A .
-
name: Create PR on docs repo
uses: peter-evans/create-pull-request@923ad837f191474af6b1721408744feb989a4c27 # v4.0.4
with:
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
push-to-fork: docker-tools-robot/docker.github.io
commit-message: Update Compose reference API to ${{ github.event.release.name }}
signoff: true
branch: dispatch/compose-api-reference-${{ github.event.release.name }}
delete-branch: true
title: Update Compose reference API to ${{ github.event.release.name }}
body: |
Update the Compose reference API documentation to keep in sync with the latest release `${{ github.event.release.name }}`
draft: false

View File

@@ -7,14 +7,16 @@ concurrency:
on:
push:
branches:
- 'v2'
- 'main'
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: read # to fetch code (actions/checkout)
env:
REPO_SLUG: "docker/compose-bin"
jobs:
e2e:
name: Build and test
@@ -72,3 +74,78 @@ jobs:
run: |
make e2e-compose-standalone
bin-image:
runs-on: ubuntu-22.04
outputs:
digest: ${{ fromJSON(steps.bake.outputs.metadata).image-cross['containerimage.digest'] }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ env.REPO_SLUG }}
tags: |
type=ref,event=tag
type=edge
bake-target: meta-helper
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
-
name: Build and push image
uses: docker/bake-action@v2
id: bake
with:
files: |
./docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
targets: image-cross
push: ${{ github.event_name != 'pull_request' }}
set: |
*.cache-from=type=gha,scope=bin-image
*.cache-to=type=gha,scope=bin-image,mode=max
*.attest=type=sbom
*.attest=type=provenance,mode=max,builder-id=https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}
desktop-edge-test:
runs-on: ubuntu-latest
needs: bin-image
steps:
-
name: Generate Token
id: generate_token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ vars.DOCKERDESKTOP_APP_ID }}
private_key: ${{ secrets.DOCKERDESKTOP_APP_PRIVATEKEY }}
repository: docker/${{ secrets.DOCKERDESKTOP_REPO }}
-
name: Trigger Docker Desktop e2e with edge version
uses: actions/github-script@v6
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: 'docker',
repo: '${{ secrets.DOCKERDESKTOP_REPO }}',
workflow_id: 'compose-edge-integration.yml',
ref: 'main',
inputs: {
"image-tag": "${{ needs.bin-image.outputs.digest }}"
}
})

View File

@@ -5,7 +5,7 @@ on:
schedule:
- cron: '44 9 * * 4'
push:
branches: [ "v2" ]
branches: [ "main" ]
# Declare default permissions as read only.
permissions: read-all

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
bin/
/.vscode/
coverage.out
covdatafiles/
.DS_Store

View File

@@ -7,6 +7,7 @@ linters:
enable:
- depguard
- errcheck
- errorlint
- gocritic
- gocyclo
- gofmt
@@ -31,15 +32,23 @@ linters-settings:
- name: package-comments
disabled: true
depguard:
list-type: denylist
include-go-root: true
packages:
# The io/ioutil package has been deprecated.
# https://go.dev/doc/go1.16#ioutil
- io/ioutil
rules:
all:
deny:
- pkg: io/ioutil
desc: 'io/ioutil package has been deprecated'
- pkg: gopkg.in/yaml.v2
desc: 'compose-go uses yaml.v3'
gomodguard:
blocked:
modules:
- github.com/pkg/errors:
recommendations:
- errors
- fmt
versions:
- github.com/distribution/distribution:
reason: "use distribution/reference"
- gotest.tools:
version: "< 3.0.0"
reason: "deprecated, pre-modules version"
@@ -62,5 +71,3 @@ issues:
# golangci hides some golint warnings (the warning about exported things
# withtout documentation for example), this will make it show them anyway.
exclude-use-default: false
exclude:
- should not use dot imports

View File

@@ -15,9 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARG GO_VERSION=1.20.0
ARG XX_VERSION=1.1.2
ARG GOLANGCI_LINT_VERSION=v1.51.0
ARG GO_VERSION=1.21.4
ARG XX_VERSION=1.2.1
ARG GOLANGCI_LINT_VERSION=v1.54.2
ARG ADDLICENSE_VERSION=v1.0.0
ARG BUILD_TAGS="e2e"
@@ -27,12 +27,16 @@ ARG LICENSE_FILES=".*\(Dockerfile\|Makefile\|\.go\|\.hcl\|\.sh\)"
# xx is a helper for cross-compilation
FROM --platform=${BUILDPLATFORM} tonistiigi/xx:${XX_VERSION} AS xx
# osxcross contains the MacOSX cross toolchain for xx
FROM crazymax/osxcross:11.3-alpine AS osxcross
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base
COPY --from=xx / /
RUN apk add --no-cache \
clang \
docker \
file \
findutils \
@@ -72,19 +76,26 @@ EOT
FROM build-base AS build
ARG BUILD_TAGS
ARG BUILD_FLAGS
ARG TARGETPLATFORM
RUN xx-go --wrap
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
make build GO_BUILDTAGS="$BUILD_TAGS" DESTDIR=/usr/bin && \
xx-verify --static /usr/bin/docker-compose
--mount=type=bind,from=osxcross,src=/osxsdk,target=/xx-sdk \
xx-go --wrap && \
if [ "$(xx-info os)" == "darwin" ]; then export CGO_ENABLED=1; fi && \
make build GO_BUILDTAGS="$BUILD_TAGS" DESTDIR=/out && \
xx-verify --static /out/docker-compose
FROM build-base AS lint
ARG BUILD_TAGS
ENV GOLANGCI_LINT_CACHE=/cache/golangci-lint
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/cache/golangci-lint \
--mount=from=golangci-lint,source=/usr/bin/golangci-lint,target=/usr/bin/golangci-lint \
golangci-lint cache status && \
golangci-lint run --build-tags "$BUILD_TAGS" ./...
FROM build-base AS test
@@ -93,11 +104,13 @@ ARG BUILD_TAGS
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
go test -tags "$BUILD_TAGS" -v -coverprofile=/tmp/coverage.txt -covermode=atomic $(go list $(TAGS) ./... | grep -vE 'e2e') && \
go tool cover -func=/tmp/coverage.txt
rm -rf /tmp/coverage && \
mkdir -p /tmp/coverage && \
go test -tags "$BUILD_TAGS" -v -cover -covermode=atomic $(go list $(TAGS) ./... | grep -vE 'e2e') -args -test.gocoverdir="/tmp/coverage" && \
go tool covdata percent -i=/tmp/coverage
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage.txt /coverage.txt
COPY --from=test --link /tmp/coverage /
FROM base AS license-set
ARG LICENSE_FILES
@@ -120,6 +133,7 @@ FROM base AS docsgen
WORKDIR /src
RUN --mount=target=. \
--mount=target=/root/.cache,type=cache \
--mount=type=cache,target=/go/pkg/mod \
go build -o /out/docsgen ./docs/yaml/main/generate.go
FROM --platform=${BUILDPLATFORM} alpine AS docs-build
@@ -155,12 +169,14 @@ RUN --mount=target=/context \
EOT
FROM scratch AS binary-unix
COPY --link --from=build /usr/bin/docker-compose /
COPY --link --from=build /out/docker-compose /
FROM binary-unix AS binary-darwin
FROM binary-unix AS binary-linux
FROM scratch AS binary-windows
COPY --link --from=build /usr/bin/docker-compose /docker-compose.exe
COPY --link --from=build /out/docker-compose /docker-compose.exe
FROM binary-$TARGETOS AS binary
# enable scanning for this stage
ARG BUILDKIT_SBOM_SCAN_STAGE=true
FROM --platform=$BUILDPLATFORM alpine AS releaser
WORKDIR /work
@@ -176,9 +192,3 @@ RUN --mount=from=binary \
FROM scratch AS release
COPY --from=releaser /out/ /
# docs-reference is a target used as remote context to update docs on release
# with latest changes on docs.docker.com.
# see open-pr job in .github/workflows/docs.yml for more details
FROM scratch AS docs-reference
COPY docs/reference/*.yaml .

View File

@@ -15,25 +15,21 @@
PKG := github.com/docker/compose/v2
VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
GO_LDFLAGS ?= -s -w -X ${PKG}/internal.Version=${VERSION}
GO_LDFLAGS ?= -w -X ${PKG}/internal.Version=${VERSION}
GO_BUILDTAGS ?= e2e
DRIVE_PREFIX?=
ifeq ($(OS),Windows_NT)
DETECTED_OS = Windows
DRIVE_PREFIX=C:
else
DETECTED_OS = $(shell uname -s)
endif
ifeq ($(DETECTED_OS),Linux)
MOBY_DOCKER=/usr/bin/docker
endif
ifeq ($(DETECTED_OS),Darwin)
MOBY_DOCKER=/Applications/Docker.app/Contents/Resources/bin/docker
endif
ifeq ($(DETECTED_OS),Windows)
BINARY_EXT=.exe
endif
TEST_COVERAGE_FLAGS = -race -coverprofile=coverage.out -covermode=atomic
BUILD_FLAGS?=
TEST_FLAGS?=
E2E_TEST?=
ifeq ($(E2E_TEST),)
@@ -42,35 +38,45 @@ else
endif
BUILDX_CMD ?= docker buildx
DESTDIR ?= ./bin/build
# DESTDIR overrides the output path for binaries and other artifacts
# this is used by docker/docker-ce-packaging for the apt/rpm builds,
# so it's important that the resulting binary ends up EXACTLY at the
# path $DESTDIR/docker-compose when specified.
#
# See https://github.com/docker/docker-ce-packaging/blob/e43fbd37e48fde49d907b9195f23b13537521b94/rpm/SPECS/docker-compose-plugin.spec#L47
#
# By default, all artifacts go to subdirectories under ./bin/ in the
# repo root, e.g. ./bin/build, ./bin/coverage, ./bin/release.
DESTDIR ?=
all: build
.PHONY: build ## Build the compose cli-plugin
build:
CGO_ENABLED=0 GO111MODULE=on go build -trimpath -tags "$(GO_BUILDTAGS)" -ldflags "$(GO_LDFLAGS)" -o "$(DESTDIR)/docker-compose$(BINARY_EXT)" ./cmd
GO111MODULE=on go build $(BUILD_FLAGS) -trimpath -tags "$(GO_BUILDTAGS)" -ldflags "$(GO_LDFLAGS)" -o "$(or $(DESTDIR),./bin/build)/docker-compose$(BINARY_EXT)" ./cmd
.PHONY: binary
binary:
$(BUILDX_CMD) bake binary
.PHONY: binary-with-coverage
binary-with-coverage:
$(BUILDX_CMD) bake binary-with-coverage
.PHONY: install
install: binary
mkdir -p ~/.docker/cli-plugins
install bin/build/docker-compose ~/.docker/cli-plugins/docker-compose
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
go test $(TEST_FLAGS) $(TEST_COVERAGE_FLAGS) -count=1 ./pkg/e2e
go test -v $(TEST_FLAGS) -count=1 ./pkg/e2e
.PHONY: e2e-compose-standalone
e2e-compose-standalone: ## Run End to end local tests in standalone mode. Set E2E_TEST=TestName to run a single test
go test $(TEST_FLAGS) -v -count=1 -parallel=1 --tags=standalone ./pkg/e2e
.PHONY: test-cucumber
test-cucumber:
go test $(TEST_FLAGS) -v -count=1 -parallel=1 ./e2e
.PHONY: build-and-e2e-compose
build-and-e2e-compose: build e2e-compose ## Compile the compose cli-plugin and run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test
@@ -111,8 +117,8 @@ docs: ## generate documentation
$(eval $@_TMP_OUT := $(shell mktemp -d -t compose-output.XXXXXXXXXX))
$(BUILDX_CMD) bake --set "*.output=type=local,dest=$($@_TMP_OUT)" docs-update
rm -rf ./docs/internal
cp -R "$($@_TMP_OUT)"/out/* ./docs/
rm -rf "$($@_TMP_OUT)"/*
cp -R "$(DRIVE_PREFIX)$($@_TMP_OUT)"/out/* ./docs/
rm -rf "$(DRIVE_PREFIX)$($@_TMP_OUT)"/*
.PHONY: validate-docs
validate-docs: ## validate the doc does not change

View File

@@ -1,18 +1,18 @@
# Table of Contents
- [Docker Compose v2](#docker-compose-v2)
- [About update and backward compatibility](#about-update-and-backward-compatibility)
- [Where to get Docker Compose](#where-to-get-docker-compose)
+ [Windows and macOS](#windows-and-macos)
+ [Linux](#linux)
- [Quick Start](#quick-start)
- [Contributing](#contributing)
- [Legacy](#legacy)
# Docker Compose v2
[![GitHub release](https://img.shields.io/github/release/docker/compose.svg?style=flat-square)](https://github.com/docker/compose/releases/latest)
[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?style=flat-square&logo=go&logoColor=white)](https://pkg.go.dev/github.com/docker/compose/v2)
[![Build Status](https://img.shields.io/github/workflow/status/docker/compose/ci?label=ci&logo=github&style=flat-square)](https://github.com/docker/compose/actions?query=workflow%3Aci)
[![Build Status](https://img.shields.io/github/actions/workflow/status/docker/compose/ci.yml?label=ci&logo=github&style=flat-square)](https://github.com/docker/compose/actions?query=workflow%3Aci)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/compose/v2?style=flat-square)](https://goreportcard.com/report/github.com/docker/compose/v2)
[![Codecov](https://codecov.io/gh/docker/compose/branch/master/graph/badge.svg?token=HP3K4Y4ctu)](https://codecov.io/gh/docker/compose)
[![Codecov](https://codecov.io/gh/docker/compose/branch/main/graph/badge.svg?token=HP3K4Y4ctu)](https://codecov.io/gh/docker/compose)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/docker/compose/badge)](https://api.securityscorecards.dev/projects/github.com/docker/compose)
![Docker Compose](logo.png?raw=true "Docker Compose Logo")
@@ -23,12 +23,6 @@ your application are configured.
Once you have a Compose file, you can create and start your application with a
single command: `docker compose up`.
# About update and backward compatibility
Docker Compose V2 is a major version bump release of Docker Compose. It has been completely rewritten from scratch in Golang (V1 was in Python). The installation instructions for Compose V2 differ from V1. V2 is not a standalone binary anymore, and installation scripts will have to be adjusted. Some commands are different.
For a smooth transition from legacy docker-compose 1.xx, please consider installing [compose-switch](https://github.com/docker/compose-switch) to translate `docker-compose ...` commands into Compose V2's `docker compose .... `. Also check V2's `--compatibility` flag.
# Where to get Docker Compose
### Windows and macOS
@@ -85,3 +79,8 @@ Want to help develop Docker Compose? Check out our
If you find an issue, please report it on the
[issue tracker](https://github.com/docker/compose/issues/new/choose).
Legacy
-------------
The Python version of Compose is available under the `v1` [branch](https://github.com/docker/compose/tree/v1).

143
cmd/cmdtrace/cmd_span.go Normal file
View File

@@ -0,0 +1,143 @@
/*
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 cmdtrace
import (
"context"
"errors"
"fmt"
"sort"
"strings"
"time"
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
commands "github.com/docker/compose/v2/cmd/compose"
"github.com/docker/compose/v2/internal/tracing"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
// Setup should be called as part of the command's PersistentPreRunE
// as soon as possible after initializing the dockerCli.
//
// It initializes the tracer for the CLI using both auto-detection
// from the Docker context metadata as well as standard OTEL_ env
// vars, creates a root span for the command, and wraps the actual
// command invocation to ensure the span is properly finalized and
// exported before exit.
func Setup(cmd *cobra.Command, dockerCli command.Cli, args []string) error {
tracingShutdown, err := tracing.InitTracing(dockerCli)
if err != nil {
return fmt.Errorf("initializing tracing: %w", err)
}
ctx := cmd.Context()
ctx, cmdSpan := tracing.Tracer.Start(
ctx,
"cli/"+strings.Join(commandName(cmd), "-"),
)
cmdSpan.SetAttributes(attribute.StringSlice("cli.args", args))
cmdSpan.SetAttributes(attribute.StringSlice("cli.flags", getFlags(cmd.Flags())))
cmd.SetContext(ctx)
wrapRunE(cmd, cmdSpan, tracingShutdown)
return nil
}
// wrapRunE injects a wrapper function around the command's actual RunE (or Run)
// method. This is necessary to capture the command result for reporting as well
// as flushing any spans before exit.
//
// Unfortunately, PersistentPostRun(E) can't be used for this purpose because it
// only runs if RunE does _not_ return an error, but this should run unconditionally.
func wrapRunE(c *cobra.Command, cmdSpan trace.Span, tracingShutdown tracing.ShutdownFunc) {
origRunE := c.RunE
if origRunE == nil {
origRun := c.Run
//nolint:unparam // wrapper function for RunE, always returns nil by design
origRunE = func(cmd *cobra.Command, args []string) error {
origRun(cmd, args)
return nil
}
c.Run = nil
}
c.RunE = func(cmd *cobra.Command, args []string) error {
cmdErr := origRunE(cmd, args)
if cmdSpan != nil {
if cmdErr != nil && !errors.Is(cmdErr, context.Canceled) {
// default exit code is 1 if a more descriptive error
// wasn't returned
exitCode := 1
var statusErr dockercli.StatusError
if errors.As(cmdErr, &statusErr) {
exitCode = statusErr.StatusCode
}
cmdSpan.SetStatus(codes.Error, "CLI command returned error")
cmdSpan.RecordError(cmdErr, trace.WithAttributes(
attribute.Int("exit_code", exitCode),
))
} else {
cmdSpan.SetStatus(codes.Ok, "")
}
cmdSpan.End()
}
if tracingShutdown != nil {
// use background for root context because the cmd's context might have
// been canceled already
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
// TODO(milas): add an env var to enable logging from the
// OTel components for debugging purposes
_ = tracingShutdown(ctx)
}
return cmdErr
}
}
// commandName returns the path components for a given command.
//
// The root Compose command and anything before (i.e. "docker")
// are not included.
//
// For example:
// - docker compose alpha watch -> [alpha, watch]
// - docker-compose up -> [up]
func commandName(cmd *cobra.Command) []string {
var name []string
for c := cmd; c != nil; c = c.Parent() {
if c.Name() == commands.PluginName {
break
}
name = append(name, c.Name())
}
sort.Sort(sort.Reverse(sort.StringSlice(name)))
return name
}
func getFlags(fs *flag.FlagSet) []string {
var result []string
fs.Visit(func(flag *flag.Flag) {
result = append(result, flag.Name)
})
return result
}

View File

@@ -0,0 +1,64 @@
/*
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 cmdtrace
import (
"reflect"
"testing"
flag "github.com/spf13/pflag"
)
func TestGetFlags(t *testing.T) {
// Initialize flagSet with flags
fs := flag.NewFlagSet("up", flag.ContinueOnError)
var (
detach string
timeout string
)
fs.StringVar(&detach, "detach", "d", "")
fs.StringVar(&timeout, "timeout", "t", "")
_ = fs.Set("detach", "detach")
_ = fs.Set("timeout", "timeout")
tests := []struct {
name string
input *flag.FlagSet
expected []string
}{
{
name: "NoFlags",
input: flag.NewFlagSet("NoFlags", flag.ContinueOnError),
expected: nil,
},
{
name: "Flags",
input: fs,
expected: []string{"detach", "timeout"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := getFlags(test.input)
if !reflect.DeepEqual(result, test.expected) {
t.Errorf("Expected %v, but got %v", test.expected, result)
}
})
}
}

View File

@@ -62,10 +62,6 @@ func Convert(args []string) []string {
continue
}
if len(arg) > 0 && arg[0] != '-' {
// not a top-level flag anymore, keep the rest of the command unmodified
if arg == compose.PluginName {
i++
}
command = append(command, args[i:]...)
break
}

View File

@@ -83,6 +83,11 @@ func Test_convert(t *testing.T) {
args: []string{"--project-directory", "", "ps"},
want: []string{"compose", "--project-directory", "", "ps"},
},
{
name: "compose as project name",
args: []string{"--project-name", "compose", "down", "--remove-orphans"},
want: []string{"compose", "--project-name", "compose", "down", "--remove-orphans"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -15,14 +15,13 @@
package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
// alphaCommand groups all experimental subcommands
func alphaCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func alphaCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
cmd := &cobra.Command{
Short: "Experimental commands",
Use: "alpha [COMMAND]",
@@ -32,26 +31,9 @@ func alphaCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
},
}
cmd.AddCommand(
watchCommand(p, backend),
dryRunRedirectCommand(p),
watchCommand(p, dockerCli, backend),
vizCommand(p, dockerCli, backend),
publishCommand(p, dockerCli, backend),
)
return cmd
}
// Temporary alpha command as the dry-run will be implemented with a flag
func dryRunRedirectCommand(p *ProjectOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "dry-run -- [COMMAND...]",
Short: "EXPERIMENTAL - Dry run command allow you to test a command without applying changes",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
return nil
}),
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
rootCmd := cmd.Root()
rootCmd.SetArgs(append([]string{"compose", "--dry-run"}, args...))
return rootCmd.Execute()
}),
ValidArgsFunction: completeServiceNames(p),
}
return cmd
}

View File

@@ -26,8 +26,9 @@ import (
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
buildx "github.com/docker/buildx/util/progress"
"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/cli/cli/command"
cliopts "github.com/docker/cli/opts"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -35,15 +36,14 @@ import (
type buildOptions struct {
*ProjectOptions
composeOptions
quiet bool
pull bool
push bool
progress string
args []string
noCache bool
memory string
ssh string
quiet bool
pull bool
push bool
args []string
noCache bool
memory cliopts.MemBytes
ssh string
builder string
}
func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions, error) {
@@ -55,27 +55,25 @@ func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions,
return api.BuildOptions{}, err
}
}
builderName := opts.builder
if builderName == "" {
builderName = os.Getenv("BUILDX_BUILDER")
}
return api.BuildOptions{
Pull: opts.pull,
Push: opts.push,
Progress: opts.progress,
Progress: ui.Mode,
Args: types.NewMappingWithEquals(opts.args),
NoCache: opts.noCache,
Quiet: opts.quiet,
Services: services,
SSHs: SSHKeys,
Builder: builderName,
}, nil
}
var printerModes = []string{
buildx.PrinterModeAuto,
buildx.PrinterModeTty,
buildx.PrinterModePlain,
buildx.PrinterModeQuiet,
}
func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := buildOptions{
ProjectOptions: p,
}
@@ -83,39 +81,33 @@ func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *
Use: "build [OPTIONS] [SERVICE...]",
Short: "Build or rebuild services",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.memory != "" {
fmt.Fprintln(streams.Err(), "WARNING --memory is ignored as not supported in buildkit.")
}
if opts.quiet {
opts.progress = buildx.PrinterModeQuiet
ui.Mode = ui.ModeQuiet
devnull, err := os.Open(os.DevNull)
if err != nil {
return err
}
os.Stdout = devnull
}
if !utils.StringContains(printerModes, opts.progress) {
return fmt.Errorf("unsupported --progress value %q", opts.progress)
}
return nil
}),
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("ssh") && opts.ssh == "" {
opts.ssh = "default"
}
if progress.Mode == progress.ModePlain && !cmd.Flags().Changed("progress") {
opts.progress = buildx.PrinterModePlain
if cmd.Flags().Changed("progress") && opts.ssh == "" {
fmt.Fprint(os.Stderr, "--progress is a global compose flag, better use `docker compose --progress xx build ...\n")
}
return runBuild(ctx, backend, opts, args)
return runBuild(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
cmd.Flags().BoolVar(&opts.push, "push", false, "Push service images.")
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT")
cmd.Flags().BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image.")
cmd.Flags().StringVar(&opts.progress, "progress", buildx.PrinterModeAuto, fmt.Sprintf(`Set type of progress output (%s)`, strings.Join(printerModes, ", ")))
cmd.Flags().StringArrayVar(&opts.args, "build-arg", []string{}, "Set build-time variables for services.")
cmd.Flags().StringVar(&opts.ssh, "ssh", "", "Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent)")
cmd.Flags().StringVar(&opts.builder, "builder", "", "Set builder to use.")
cmd.Flags().Bool("parallel", true, "Build images in parallel. DEPRECATED")
cmd.Flags().MarkHidden("parallel") //nolint:errcheck
cmd.Flags().Bool("compress", true, "Compress the build context using gzip. DEPRECATED")
@@ -125,21 +117,28 @@ func buildCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *
cmd.Flags().BoolVar(&opts.noCache, "no-cache", false, "Do not use cache when building the image")
cmd.Flags().Bool("no-rm", false, "Do not remove intermediate containers after a successful build. DEPRECATED")
cmd.Flags().MarkHidden("no-rm") //nolint:errcheck
cmd.Flags().StringVarP(&opts.memory, "memory", "m", "", "Set memory limit for the build container. Not supported on buildkit yet.")
cmd.Flags().MarkHidden("memory") //nolint:errcheck
cmd.Flags().VarP(&opts.memory, "memory", "m", "Set memory limit for the build container. Not supported by BuildKit.")
cmd.Flags().StringVar(&p.Progress, "progress", buildx.PrinterModeAuto, fmt.Sprintf(`Set type of ui output (%s)`, strings.Join(printerModes, ", ")))
cmd.Flags().MarkHidden("progress") //nolint:errcheck
return cmd
}
func runBuild(ctx context.Context, backend api.Service, opts buildOptions, services []string) error {
project, err := opts.ToProject(services, cli.WithResolvedPaths(true))
func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, opts buildOptions, services []string) error {
project, err := opts.ToProject(dockerCli, services, cli.WithResolvedPaths(true))
if err != nil {
return err
}
if err := applyPlatforms(project, false); err != nil {
return err
}
apiBuildOptions, err := opts.toAPIBuildOptions(services)
if err != nil {
return err
}
apiBuildOptions.Memory = int64(opts.memory)
return backend.Build(ctx, project, apiBuildOptions)
}

View File

@@ -17,8 +17,10 @@
package compose
import (
"sort"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
@@ -32,9 +34,10 @@ func noCompletion() validArgsFn {
}
}
func completeServiceNames(p *ProjectOptions) validArgsFn {
func completeServiceNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
project, err := p.ToProject(nil)
p.Offline = true
project, err := p.ToProject(dockerCli, nil)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
@@ -65,3 +68,24 @@ func completeProjectNames(backend api.Service) func(cmd *cobra.Command, args []s
return values, cobra.ShellCompDirectiveNoFileComp
}
}
func completeProfileNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
p.Offline = true
project, err := p.ToProject(dockerCli, nil)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
allProfileNames := project.AllServices().GetProfiles()
sort.Strings(allProfileNames)
var values []string
for _, profileName := range allProfileNames {
if strings.HasPrefix(profileName, toComplete) {
values = append(values, profileName)
}
}
return values, cobra.ShellCompDirectiveNoFileComp
}
}

View File

@@ -18,6 +18,7 @@ package compose
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
@@ -26,16 +27,17 @@ import (
"strings"
"syscall"
"github.com/docker/cli/cli/command"
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/dotenv"
"github.com/compose-spec/compose-go/types"
composegoutils "github.com/compose-spec/compose-go/utils"
"github.com/docker/buildx/util/logutil"
buildx "github.com/docker/buildx/util/progress"
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/remote"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -43,10 +45,25 @@ import (
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
"github.com/docker/compose/v2/pkg/progress"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
)
const (
// ComposeParallelLimit set the limit running concurrent operation on docker engine
ComposeParallelLimit = "COMPOSE_PARALLEL_LIMIT"
// ComposeProjectName define the project name to be used, instead of guessing from parent directory
ComposeProjectName = "COMPOSE_PROJECT_NAME"
// ComposeCompatibility try to mimic compose v1 as much as possible
ComposeCompatibility = "COMPOSE_COMPATIBILITY"
// ComposeRemoveOrphans remove “orphaned" containers, i.e. containers tagged for current project but not declared as service
ComposeRemoveOrphans = "COMPOSE_REMOVE_ORPHANS"
// ComposeIgnoreOrphans ignore "orphaned" containers
ComposeIgnoreOrphans = "COMPOSE_IGNORE_ORPHANS"
// ComposeEnvFiles defines the env files to use if --env-file isn't used
ComposeEnvFiles = "COMPOSE_ENV_FILES"
)
// Command defines a compose CLI command as a func with args
type Command func(context.Context, []string) error
@@ -66,6 +83,8 @@ func AdaptCmd(fn CobraCommand) func(cmd *cobra.Command, args []string) error {
go func() {
<-s
cancel()
signal.Stop(s)
close(s)
}()
}
err := fn(ctx, cmd, args)
@@ -99,8 +118,10 @@ type ProjectOptions struct {
ConfigPaths []string
WorkDir string
ProjectDir string
EnvFile string
EnvFiles []string
Compatibility bool
Progress string
Offline bool
}
// ProjectFunc does stuff within a types.Project
@@ -110,16 +131,22 @@ type ProjectFunc func(ctx context.Context, project *types.Project) error
type ProjectServicesFunc func(ctx context.Context, project *types.Project, services []string) error
// WithProject creates a cobra run command from a ProjectFunc based on configured project options and selected services
func (o *ProjectOptions) WithProject(fn ProjectFunc) func(cmd *cobra.Command, args []string) error {
return o.WithServices(func(ctx context.Context, project *types.Project, services []string) error {
func (o *ProjectOptions) WithProject(fn ProjectFunc, dockerCli command.Cli) func(cmd *cobra.Command, args []string) error {
return o.WithServices(dockerCli, func(ctx context.Context, project *types.Project, services []string) error {
return fn(ctx, project)
})
}
// WithServices creates a cobra run command from a ProjectFunc based on configured project options and selected services
func (o *ProjectOptions) WithServices(fn ProjectServicesFunc) func(cmd *cobra.Command, args []string) error {
func (o *ProjectOptions) WithServices(dockerCli command.Cli, fn ProjectServicesFunc) func(cmd *cobra.Command, args []string) error {
return Adapt(func(ctx context.Context, args []string) error {
project, err := o.ToProject(args, cli.WithResolvedPaths(true))
options := []cli.ProjectOptionsFn{
cli.WithResolvedPaths(true),
cli.WithDiscardEnvFile,
cli.WithContext(ctx),
}
project, err := o.ToProject(dockerCli, args, options...)
if err != nil {
return err
}
@@ -132,20 +159,21 @@ func (o *ProjectOptions) addProjectFlags(f *pflag.FlagSet) {
f.StringArrayVar(&o.Profiles, "profile", []string{}, "Specify a profile to enable")
f.StringVarP(&o.ProjectName, "project-name", "p", "", "Project name")
f.StringArrayVarP(&o.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
f.StringVar(&o.EnvFile, "env-file", "", "Specify an alternate environment file.")
f.StringArrayVar(&o.EnvFiles, "env-file", nil, "Specify an alternate environment file.")
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", buildx.PrinterModeAuto, fmt.Sprintf(`Set type of progress output (%s)`, strings.Join(printerModes, ", ")))
_ = f.MarkHidden("workdir")
}
func (o *ProjectOptions) projectOrName(services ...string) (*types.Project, string, error) {
func (o *ProjectOptions) projectOrName(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(services)
p, err := o.ToProject(dockerCli, services, cli.WithDiscardEnvFile)
if err != nil {
envProjectName := os.Getenv("COMPOSE_PROJECT_NAME")
envProjectName := os.Getenv(ComposeProjectName)
if envProjectName != "" {
return nil, envProjectName, nil
}
@@ -157,30 +185,34 @@ func (o *ProjectOptions) projectOrName(services ...string) (*types.Project, stri
return project, name, nil
}
func (o *ProjectOptions) toProjectName() (string, error) {
func (o *ProjectOptions) toProjectName(dockerCli command.Cli) (string, error) {
if o.ProjectName != "" {
return o.ProjectName, nil
}
envProjectName := os.Getenv("COMPOSE_PROJECT_NAME")
envProjectName := os.Getenv(ComposeProjectName)
if envProjectName != "" {
return envProjectName, nil
}
project, err := o.ToProject(nil)
project, err := o.ToProject(dockerCli, nil)
if err != nil {
return "", err
}
return project.Name, nil
}
func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
func (o *ProjectOptions) ToProject(dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
if !o.Offline {
po = o.configureRemoteLoaders(dockerCli, po)
}
options, err := o.toProjectOptions(po...)
if err != nil {
return nil, compose.WrapComposeError(err)
}
if o.Compatibility || utils.StringToBool(options.Environment["COMPOSE_COMPATIBILITY"]) {
if o.Compatibility || utils.StringToBool(options.Environment[ComposeCompatibility]) {
api.Separator = "_"
}
@@ -189,6 +221,15 @@ func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn
return nil, compose.WrapComposeError(err)
}
if project.Name == "" {
return nil, errors.New("project name can't be empty. Use `--project-name` to set a valid name")
}
err = project.EnableServices(services...)
if err != nil {
return nil, err
}
for i, s := range project.Services {
s.CustomLabels = map[string]string{
api.ProjectLabel: project.Name,
@@ -198,41 +239,36 @@ func (o *ProjectOptions) ToProject(services []string, po ...cli.ProjectOptionsFn
api.ConfigFilesLabel: strings.Join(project.ComposeFiles, ","),
api.OneoffLabel: "False", // default, will be overridden by `run` command
}
if o.EnvFile != "" {
s.CustomLabels[api.EnvironmentFileLabel] = o.EnvFile
if len(o.EnvFiles) != 0 {
s.CustomLabels[api.EnvironmentFileLabel] = strings.Join(o.EnvFiles, ",")
}
project.Services[i] = s
}
if profiles, ok := options.Environment["COMPOSE_PROFILES"]; ok && len(o.Profiles) == 0 {
o.Profiles = append(o.Profiles, strings.Split(profiles, ",")...)
}
if len(services) > 0 {
s, err := project.GetServices(services...)
if err != nil {
return nil, err
}
o.Profiles = append(o.Profiles, s.GetProfiles()...)
}
project.ApplyProfiles(o.Profiles)
project.WithoutUnnecessaryResources()
err = project.ForServices(services)
return project, err
}
func (o *ProjectOptions) configureRemoteLoaders(dockerCli command.Cli, po []cli.ProjectOptionsFn) []cli.ProjectOptionsFn {
git := remote.NewGitRemoteLoader(o.Offline)
oci := remote.NewOCIRemoteLoader(dockerCli, o.Offline)
po = append(po, cli.WithResourceLoader(git), cli.WithResourceLoader(oci))
return po
}
func (o *ProjectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.ProjectOptions, error) {
return cli.NewProjectOptions(o.ConfigPaths,
append(po,
cli.WithWorkingDirectory(o.ProjectDir),
cli.WithOsEnv,
cli.WithEnvFile(o.EnvFile),
cli.WithEnvFiles(o.EnvFiles...),
cli.WithDotEnv,
cli.WithConfigFileEnv,
cli.WithDefaultConfigPath,
cli.WithDefaultProfiles(o.Profiles...),
cli.WithName(o.ProjectName))...)
}
@@ -245,7 +281,7 @@ func RunningAsStandalone() bool {
}
// RootCommand returns the compose command with its child commands
func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //nolint:gocyclo
func RootCommand(dockerCli command.Cli, backend api.Service) *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
@@ -267,6 +303,7 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
)
c := &cobra.Command{
Short: "Docker Compose",
Long: "Define and run multi-container applications with Docker.",
Use: PluginName,
TraverseChildren: true,
// By default (no Run/RunE in parent c) for typos in subcommands, cobra displays the help of parent c but exit(0) !
@@ -275,7 +312,7 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
return cmd.Help()
}
if version {
return versionCommand().Execute()
return versionCommand(dockerCli).Execute()
}
_ = cmd.Help()
return dockercli.StatusError{
@@ -308,13 +345,44 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
if verbose {
logrus.SetLevel(logrus.TraceLevel)
}
formatter.SetANSIMode(streams, ansi)
if v, ok := os.LookupEnv("COMPOSE_ANSI"); ok && !cmd.Flags().Changed("ansi") {
ansi = v
}
formatter.SetANSIMode(dockerCli, ansi)
if noColor, ok := os.LookupEnv("NO_COLOR"); ok && noColor != "" {
ui.NoColor()
formatter.SetANSIMode(dockerCli, formatter.Never)
}
switch ansi {
case "never":
progress.Mode = progress.ModePlain
case "tty":
progress.Mode = progress.ModeTTY
ui.Mode = ui.ModePlain
case "always":
ui.Mode = ui.ModeTTY
}
switch opts.Progress {
case ui.ModeAuto:
ui.Mode = ui.ModeAuto
case ui.ModeTTY:
if ansi == "never" {
return fmt.Errorf("can't use --progress tty while ANSI support is disabled")
}
ui.Mode = ui.ModeTTY
case ui.ModePlain:
if ansi == "always" {
return fmt.Errorf("can't use --progress plain while ANSI support is forced")
}
ui.Mode = ui.ModePlain
case ui.ModeQuiet, "none":
ui.Mode = ui.ModeQuiet
default:
return fmt.Errorf("unsupported --progress value %q", opts.Progress)
}
if opts.WorkDir != "" {
if opts.ProjectDir != "" {
return errors.New(`cannot specify DEPRECATED "--workdir" and "--project-directory". Please use only "--project-directory" instead`)
@@ -322,16 +390,31 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
opts.ProjectDir = opts.WorkDir
fmt.Fprint(os.Stderr, aec.Apply("option '--workdir' is DEPRECATED at root level! Please use '--project-directory' instead.\n", aec.RedF))
}
if opts.EnvFile != "" && !filepath.IsAbs(opts.EnvFile) {
opts.EnvFile, err = filepath.Abs(opts.EnvFile)
if err != nil {
return err
for i, file := range opts.EnvFiles {
if !filepath.IsAbs(file) {
file, err = filepath.Abs(file)
if err != nil {
return err
}
opts.EnvFiles[i] = file
}
}
if v, ok := os.LookupEnv("COMPOSE_PARALLEL_LIMIT"); ok && !cmd.Flags().Changed("parallel") {
composeCmd := cmd
for {
if composeCmd.Name() == PluginName {
break
}
if !composeCmd.HasParent() {
return fmt.Errorf("error parsing command line, expected %q", PluginName)
}
composeCmd = composeCmd.Parent()
}
if v, ok := os.LookupEnv(ComposeParallelLimit); ok && !composeCmd.Flags().Changed("parallel") {
i, err := strconv.Atoi(v)
if err != nil {
return fmt.Errorf("COMPOSE_PARALLEL_LIMIT must be an integer (found: %q)", v)
return fmt.Errorf("%s must be an integer (found: %q)", ComposeParallelLimit, v)
}
parallel = i
}
@@ -348,32 +431,35 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
}
c.AddCommand(
upCommand(&opts, streams, backend),
downCommand(&opts, backend),
startCommand(&opts, backend),
restartCommand(&opts, backend),
stopCommand(&opts, backend),
psCommand(&opts, streams, backend),
listCommand(streams, backend),
logsCommand(&opts, streams, backend),
convertCommand(&opts, streams, backend),
killCommand(&opts, backend),
runCommand(&opts, streams, backend),
removeCommand(&opts, backend),
execCommand(&opts, streams, backend),
pauseCommand(&opts, backend),
unpauseCommand(&opts, backend),
topCommand(&opts, streams, backend),
eventsCommand(&opts, streams, backend),
portCommand(&opts, streams, backend),
imagesCommand(&opts, streams, backend),
versionCommand(),
buildCommand(&opts, streams, backend),
pushCommand(&opts, backend),
pullCommand(&opts, backend),
createCommand(&opts, backend),
copyCommand(&opts, backend),
alphaCommand(&opts, backend),
upCommand(&opts, dockerCli, backend),
downCommand(&opts, dockerCli, backend),
startCommand(&opts, dockerCli, backend),
restartCommand(&opts, dockerCli, backend),
stopCommand(&opts, dockerCli, backend),
psCommand(&opts, dockerCli, backend),
listCommand(dockerCli, backend),
logsCommand(&opts, dockerCli, backend),
configCommand(&opts, dockerCli, backend),
killCommand(&opts, dockerCli, backend),
runCommand(&opts, dockerCli, backend),
removeCommand(&opts, dockerCli, backend),
execCommand(&opts, dockerCli, backend),
pauseCommand(&opts, dockerCli, backend),
unpauseCommand(&opts, dockerCli, backend),
topCommand(&opts, dockerCli, backend),
eventsCommand(&opts, dockerCli, backend),
portCommand(&opts, dockerCli, backend),
imagesCommand(&opts, dockerCli, backend),
versionCommand(dockerCli),
buildCommand(&opts, dockerCli, backend),
pushCommand(&opts, dockerCli, backend),
pullCommand(&opts, dockerCli, backend),
createCommand(&opts, dockerCli, backend),
copyCommand(&opts, dockerCli, backend),
waitCommand(&opts, dockerCli, backend),
scaleCommand(&opts, dockerCli, backend),
watchCommand(&opts, dockerCli, backend),
alphaCommand(&opts, dockerCli, backend),
)
c.Flags().SetInterspersed(false)
@@ -382,27 +468,41 @@ func RootCommand(streams command.Cli, backend api.Service) *cobra.Command { //no
"project-name",
completeProjectNames(backend),
)
c.RegisterFlagCompletionFunc( //nolint:errcheck
"project-directory",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{}, cobra.ShellCompDirectiveFilterDirs
},
)
c.RegisterFlagCompletionFunc( //nolint:errcheck
"file",
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"yaml", "yml"}, cobra.ShellCompDirectiveFilterFileExt
},
)
c.RegisterFlagCompletionFunc( //nolint:errcheck
"profile",
completeProfileNames(dockerCli, &opts),
)
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`)
c.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information")
c.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Execute command in dry run mode")
c.Flags().MarkHidden("version") //nolint:errcheck
c.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`)
c.Flags().MarkHidden("no-ansi") //nolint:errcheck
c.Flags().BoolVar(&verbose, "verbose", false, "Show more output")
c.Flags().MarkHidden("verbose") //nolint:errcheck
c.Flags().BoolVar(&dryRun, "dry-run", false, "Execute command in dry run mode")
c.Flags().MarkHidden("dry-run") //nolint:errcheck
return c
}
func setEnvWithDotEnv(prjOpts *ProjectOptions) error {
if len(prjOpts.EnvFiles) == 0 {
if envFiles := os.Getenv(ComposeEnvFiles); envFiles != "" {
prjOpts.EnvFiles = strings.Split(envFiles, ",")
}
}
options, err := prjOpts.toProjectOptions()
if err != nil {
return compose.WrapComposeError(err)
@@ -412,7 +512,7 @@ func setEnvWithDotEnv(prjOpts *ProjectOptions) error {
return err
}
envFromFile, err := cli.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), workingDir, options.EnvFile)
envFromFile, err := dotenv.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), workingDir, options.EnvFiles)
if err != nil {
return err
}
@@ -425,3 +525,10 @@ func setEnvWithDotEnv(prjOpts *ProjectOptions) error {
}
return nil
}
var printerModes = []string{
ui.ModeAuto,
ui.ModeTTY,
ui.ModePlain,
ui.ModeQuiet,
}

View File

@@ -31,8 +31,10 @@ func TestFilterServices(t *testing.T) {
Links: []string{"bar"},
},
{
Name: "bar",
NetworkMode: types.NetworkModeServicePrefix + "zot",
Name: "bar",
DependsOn: map[string]types.ServiceDependency{
"zot": {},
},
},
{
Name: "zot",

View File

@@ -26,13 +26,14 @@ import (
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
)
type convertOptions struct {
type configOptions struct {
*ProjectOptions
Format string
Output string
@@ -40,6 +41,7 @@ type convertOptions struct {
resolveImageDigests bool
noInterpolate bool
noNormalize bool
noResolvePath bool
services bool
volumes bool
profiles bool
@@ -48,8 +50,20 @@ type convertOptions struct {
noConsistency bool
}
func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := convertOptions{
func (o *configOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
po = append(po,
cli.WithInterpolation(!o.noInterpolate),
cli.WithResolvedPaths(!o.noResolvePath),
cli.WithNormalization(!o.noNormalize),
cli.WithConsistency(!o.noConsistency),
cli.WithDefaultProfiles(o.Profiles...),
cli.WithDiscardEnvFile,
cli.WithContext(ctx))
return o.ProjectOptions.ToProject(dockerCli, services, po...)
}
func configCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := configOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
@@ -71,24 +85,24 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
if opts.services {
return runServices(streams, opts)
return runServices(ctx, dockerCli, opts)
}
if opts.volumes {
return runVolumes(streams, opts)
return runVolumes(ctx, dockerCli, opts)
}
if opts.hash != "" {
return runHash(streams, opts)
return runHash(ctx, dockerCli, opts)
}
if opts.profiles {
return runProfiles(streams, opts, args)
return runProfiles(ctx, dockerCli, opts, args)
}
if opts.images {
return runConfigImages(streams, opts, args)
return runConfigImages(ctx, dockerCli, opts, args)
}
return runConfig(ctx, streams, backend, opts, args)
return runConfig(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")
@@ -96,6 +110,7 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables.")
flags.BoolVar(&opts.noNormalize, "no-normalize", false, "Don't normalize compose model.")
flags.BoolVar(&opts.noResolvePath, "no-path-resolution", false, "Don't resolve file paths.")
flags.BoolVar(&opts.noConsistency, "no-consistency", false, "Don't check model consistency - warning: may produce invalid Compose output")
flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
@@ -108,14 +123,9 @@ func convertCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
return cmd
}
func runConfig(ctx context.Context, streams api.Streams, backend api.Service, opts convertOptions, services []string) error {
func runConfig(ctx context.Context, dockerCli command.Cli, backend api.Service, opts configOptions, services []string) error {
var content []byte
project, err := opts.ToProject(services,
cli.WithInterpolation(!opts.noInterpolate),
cli.WithResolvedPaths(true),
cli.WithNormalization(!opts.noNormalize),
cli.WithConsistency(!opts.noConsistency),
cli.WithDiscardEnvFile)
project, err := opts.ToProject(ctx, dockerCli, services)
if err != nil {
return err
}
@@ -140,54 +150,74 @@ func runConfig(ctx context.Context, streams api.Streams, backend api.Service, op
if opts.Output != "" && len(content) > 0 {
return os.WriteFile(opts.Output, content, 0o666)
}
_, err = fmt.Fprint(streams.Out(), string(content))
_, err = fmt.Fprint(dockerCli.Out(), string(content))
return err
}
func runServices(streams api.Streams, opts convertOptions) error {
project, err := opts.ToProject(nil)
func runServices(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
return project.WithServices(project.ServiceNames(), func(s types.ServiceConfig) error {
fmt.Fprintln(streams.Out(), s.Name)
fmt.Fprintln(dockerCli.Out(), s.Name)
return nil
})
}
func runVolumes(streams api.Streams, opts convertOptions) error {
project, err := opts.ToProject(nil)
func runVolumes(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.Volumes {
fmt.Fprintln(streams.Out(), n)
fmt.Fprintln(dockerCli.Out(), n)
}
return nil
}
func runHash(streams api.Streams, opts convertOptions) error {
func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
var services []string
if opts.hash != "*" {
services = append(services, strings.Split(opts.hash, ",")...)
}
project, err := opts.ToProject(services)
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
for _, s := range project.Services {
hash, err := compose.ServiceHash(s)
if err := applyPlatforms(project, true); err != nil {
return err
}
if len(services) == 0 {
services = project.ServiceNames()
}
sorted := services
sort.Slice(sorted, func(i, j int) bool {
return sorted[i] < sorted[j]
})
for _, name := range sorted {
s, err := project.GetService(name)
if err != nil {
return err
}
fmt.Fprintf(streams.Out(), "%s %s\n", s.Name, hash)
hash, err := compose.ServiceHash(s)
if err != nil {
return err
}
fmt.Fprintf(dockerCli.Out(), "%s %s\n", s.Name, hash)
}
return nil
}
func runProfiles(streams api.Streams, opts convertOptions, services []string) error {
func runProfiles(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) error {
set := map[string]struct{}{}
project, err := opts.ToProject(services)
project, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
@@ -202,22 +232,18 @@ func runProfiles(streams api.Streams, opts convertOptions, services []string) er
}
sort.Strings(profiles)
for _, p := range profiles {
fmt.Fprintln(streams.Out(), p)
fmt.Fprintln(dockerCli.Out(), p)
}
return nil
}
func runConfigImages(streams api.Streams, opts convertOptions, services []string) error {
project, err := opts.ToProject(services)
func runConfigImages(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) error {
project, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
if err != nil {
return err
}
for _, s := range project.Services {
if s.Image != "" {
fmt.Fprintln(streams.Out(), s.Image)
} else {
fmt.Fprintf(streams.Out(), "%s%s%s\n", project.Name, api.Separator, s.Name)
}
fmt.Fprintln(dockerCli.Out(), api.GetImageNameOrDefault(s, project.Name))
}
return nil
}

View File

@@ -21,6 +21,7 @@ import (
"errors"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -37,7 +38,7 @@ type copyOptions struct {
copyUIDGID bool
}
func copyCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func copyCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := copyOptions{
ProjectOptions: p,
}
@@ -58,24 +59,24 @@ func copyCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.source = args[0]
opts.destination = args[1]
return runCopy(ctx, backend, opts)
return runCopy(ctx, dockerCli, backend, opts)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := copyCmd.Flags()
flags.IntVar(&opts.index, "index", 0, "Index of the container if there are multiple instances of a service .")
flags.BoolVar(&opts.all, "all", false, "Copy to all the containers of the service.")
flags.IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
flags.BoolVar(&opts.all, "all", false, "copy to all the containers of the service.")
flags.MarkHidden("all") //nolint:errcheck
flags.MarkDeprecated("all", "By default all the containers of the service will get the source file/directory to be copied.") //nolint:errcheck
flags.MarkDeprecated("all", "by default all the containers of the service will get the source file/directory to be copied.") //nolint:errcheck
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
return copyCmd
}
func runCopy(ctx context.Context, backend api.Service, opts copyOptions) error {
name, err := opts.toProjectName()
func runCopy(ctx context.Context, dockerCli command.Cli, backend api.Service, opts copyOptions) error {
name, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}

View File

@@ -19,11 +19,13 @@ package compose
import (
"context"
"fmt"
"slices"
"strconv"
"strings"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -46,8 +48,11 @@ type createOptions struct {
scale []string
}
func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func createCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := createOptions{}
buildOpts := buildOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "create [OPTIONS] [SERVICE...]",
Short: "Creates containers for a service.",
@@ -61,26 +66,15 @@ func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
}
return nil
}),
RunE: p.WithProject(func(ctx context.Context, project *types.Project) error {
if err := opts.Apply(project); err != nil {
return err
}
return backend.Create(ctx, project, api.CreateOptions{
RemoveOrphans: opts.removeOrphans,
IgnoreOrphans: opts.ignoreOrphans,
Recreate: opts.recreateStrategy(),
RecreateDependencies: opts.dependenciesRecreateStrategy(),
Inherit: !opts.noInherit,
Timeout: opts.GetTimeout(),
QuietPull: false,
})
RunE: p.WithServices(dockerCli, func(ctx context.Context, project *types.Project, services []string) error {
return runCreate(ctx, dockerCli, backend, opts, buildOpts, project, services)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.")
flags.BoolVar(&opts.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
flags.StringVar(&opts.Pull, "pull", "missing", `Pull image before running ("always"|"missing"|"never")`)
flags.BoolVar(&opts.noBuild, "no-build", false, "Don't build an image, even if it's policy.")
flags.StringVar(&opts.Pull, "pull", "policy", `Pull image before running ("always"|"missing"|"never"|"build")`)
flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
@@ -88,6 +82,33 @@ func createCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return cmd
}
func runCreate(ctx context.Context, _ command.Cli, backend api.Service, createOpts createOptions, buildOpts buildOptions, project *types.Project, services []string) error {
if err := createOpts.Apply(project); err != nil {
return err
}
var build *api.BuildOptions
if !createOpts.noBuild {
bo, err := buildOpts.toAPIBuildOptions(services)
if err != nil {
return err
}
build = &bo
}
return backend.Create(ctx, project, api.CreateOptions{
Build: build,
Services: services,
RemoveOrphans: createOpts.removeOrphans,
IgnoreOrphans: createOpts.ignoreOrphans,
Recreate: createOpts.recreateStrategy(),
RecreateDependencies: createOpts.dependenciesRecreateStrategy(),
Inherit: !createOpts.noInherit,
Timeout: createOpts.GetTimeout(),
QuietPull: false,
})
}
func (opts createOptions) recreateStrategy() string {
if opts.noRecreate {
return api.RecreateNever
@@ -118,11 +139,17 @@ func (opts createOptions) GetTimeout() *time.Duration {
func (opts createOptions) Apply(project *types.Project) error {
if opts.pullChanged {
if !opts.isPullPolicyValid() {
return fmt.Errorf("invalid --pull option %q", opts.Pull)
}
for i, service := range project.Services {
service.PullPolicy = opts.Pull
project.Services[i] = service
}
}
// N.B. opts.Build means "force build all", but images can still be built
// when this is false
// e.g. if a service has pull_policy: build or its local image is policy
if opts.Build {
for i, service := range project.Services {
if service.Build == nil {
@@ -132,6 +159,7 @@ func (opts createOptions) Apply(project *types.Project) error {
project.Services[i] = service
}
}
// opts.noBuild, however, means do not perform ANY builds
if opts.noBuild {
for i, service := range project.Services {
service.Build = nil
@@ -141,6 +169,11 @@ func (opts createOptions) Apply(project *types.Project) error {
project.Services[i] = service
}
}
if err := applyPlatforms(project, true); err != nil {
return err
}
for _, scale := range opts.scale {
split := strings.Split(scale, "=")
if len(split) != 2 {
@@ -158,3 +191,9 @@ func (opts createOptions) Apply(project *types.Project) error {
}
return nil
}
func (opts createOptions) isPullPolicyValid() bool {
pullPolicies := []string{types.PullPolicyAlways, types.PullPolicyNever, types.PullPolicyBuild,
types.PullPolicyMissing, types.PullPolicyIfNotPresent}
return slices.Contains(pullPolicies, opts.Pull)
}

170
cmd/compose/create_test.go Normal file
View File

@@ -0,0 +1,170 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"context"
"fmt"
"testing"
"github.com/compose-spec/compose-go/types"
"github.com/davecgh/go-spew/spew"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/mocks"
"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)
func TestRunCreate(t *testing.T) {
ctrl, ctx := gomock.WithContext(context.Background(), t)
backend := mocks.NewMockService(ctrl)
backend.EXPECT().Create(
gomock.Eq(ctx),
pullPolicy(""),
deepEqual(defaultCreateOptions(true)),
)
createOpts := createOptions{}
buildOpts := buildOptions{}
project := sampleProject()
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
require.NoError(t, err)
}
func TestRunCreate_Build(t *testing.T) {
ctrl, ctx := gomock.WithContext(context.Background(), t)
backend := mocks.NewMockService(ctrl)
backend.EXPECT().Create(
gomock.Eq(ctx),
pullPolicy("build"),
deepEqual(defaultCreateOptions(true)),
)
createOpts := createOptions{
Build: true,
}
buildOpts := buildOptions{}
project := sampleProject()
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
require.NoError(t, err)
}
func TestRunCreate_NoBuild(t *testing.T) {
ctrl, ctx := gomock.WithContext(context.Background(), t)
backend := mocks.NewMockService(ctrl)
backend.EXPECT().Create(
gomock.Eq(ctx),
pullPolicy(""),
deepEqual(defaultCreateOptions(false)),
)
createOpts := createOptions{
noBuild: true,
}
buildOpts := buildOptions{}
project := sampleProject()
err := runCreate(ctx, nil, backend, createOpts, buildOpts, project, nil)
require.NoError(t, err)
}
func sampleProject() *types.Project {
return &types.Project{
Name: "test",
Services: types.Services{
{
Name: "svc",
Build: &types.BuildConfig{
Context: ".",
},
},
},
}
}
func defaultCreateOptions(includeBuild bool) api.CreateOptions {
var build *api.BuildOptions
if includeBuild {
bo := defaultBuildOptions()
build = &bo
}
return api.CreateOptions{
Build: build,
Services: nil,
RemoveOrphans: false,
IgnoreOrphans: false,
Recreate: "diverged",
RecreateDependencies: "diverged",
Inherit: true,
Timeout: nil,
QuietPull: false,
}
}
func defaultBuildOptions() api.BuildOptions {
return api.BuildOptions{
Args: make(types.MappingWithEquals),
Progress: "auto",
}
}
// deepEqual returns a nice diff on failure vs gomock.Eq when used
// on structs.
func deepEqual(x interface{}) gomock.Matcher {
return gomock.GotFormatterAdapter(
gomock.GotFormatterFunc(func(got interface{}) string {
return cmp.Diff(x, got)
}),
gomock.Eq(x),
)
}
func spewAdapter(m gomock.Matcher) gomock.Matcher {
return gomock.GotFormatterAdapter(
gomock.GotFormatterFunc(func(got interface{}) string {
return spew.Sdump(got)
}),
m,
)
}
type withPullPolicy struct {
policy string
}
func pullPolicy(policy string) gomock.Matcher {
return spewAdapter(withPullPolicy{policy: policy})
}
func (w withPullPolicy) Matches(x interface{}) bool {
proj, ok := x.(*types.Project)
if !ok || proj == nil || len(proj.Services) == 0 {
return false
}
for _, svc := range proj.Services {
if svc.PullPolicy != w.policy {
return false
}
}
return true
}
func (w withPullPolicy) String() string {
return fmt.Sprintf("has pull policy %q for all services", w.policy)
}

View File

@@ -22,6 +22,7 @@ import (
"os"
"time"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/utils"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -39,12 +40,12 @@ type downOptions struct {
images string
}
func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func downCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := downOptions{
ProjectOptions: p,
}
downCmd := &cobra.Command{
Use: "down [OPTIONS]",
Use: "down [OPTIONS] [SERVICES]",
Short: "Stop and remove containers, networks",
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.timeChanged = cmd.Flags().Changed("timeout")
@@ -56,16 +57,15 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runDown(ctx, backend, opts)
return runDown(ctx, dockerCli, backend, opts, args)
}),
Args: cobra.NoArgs,
ValidArgsFunction: noCompletion(),
}
flags := downCmd.Flags()
removeOrphans := utils.StringToBool(os.Getenv("COMPOSE_REMOVE_ORPHANS"))
removeOrphans := utils.StringToBool(os.Getenv(ComposeRemoveOrphans))
flags.BoolVar(&opts.removeOrphans, "remove-orphans", removeOrphans, "Remove containers for services not defined in the Compose file.")
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
flags.BoolVarP(&opts.volumes, "volumes", "v", false, "Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.")
flags.IntVarP(&opts.timeout, "timeout", "t", 0, "Specify a shutdown timeout in seconds")
flags.BoolVarP(&opts.volumes, "volumes", "v", false, `Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers.`)
flags.StringVar(&opts.images, "rmi", "", `Remove images used by services. "local" remove only images that don't have a custom tag ("local"|"all")`)
flags.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
if name == "volume" {
@@ -77,8 +77,8 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return downCmd
}
func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
project, name, err := opts.projectOrName()
func runDown(ctx context.Context, dockerCli command.Cli, backend api.Service, opts downOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}
@@ -94,5 +94,6 @@ func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
Timeout: timeout,
Images: opts.images,
Volumes: opts.volumes,
Services: services,
})
}

View File

@@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
@@ -31,7 +32,7 @@ type eventsOpts struct {
json bool
}
func eventsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func eventsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := eventsOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -41,17 +42,17 @@ func eventsCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
Use: "events [OPTIONS] [SERVICE...]",
Short: "Receive real time events from containers.",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runEvents(ctx, streams, backend, opts, args)
return runEvents(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
cmd.Flags().BoolVar(&opts.json, "json", false, "Output events as a stream of json objects")
return cmd
}
func runEvents(ctx context.Context, streams api.Streams, backend api.Service, opts eventsOpts, services []string) error {
name, err := opts.toProjectName()
func runEvents(ctx context.Context, dockerCli command.Cli, backend api.Service, opts eventsOpts, services []string) error {
name, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}
@@ -71,9 +72,9 @@ func runEvents(ctx context.Context, streams api.Streams, backend api.Service, op
if err != nil {
return err
}
fmt.Fprintln(streams.Out(), string(marshal))
fmt.Fprintln(dockerCli.Out(), string(marshal))
} else {
fmt.Fprintln(streams.Out(), event)
fmt.Fprintln(dockerCli.Out(), event)
}
return nil
},

View File

@@ -21,6 +21,7 @@ import (
"github.com/compose-spec/compose-go/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/spf13/cobra"
@@ -42,7 +43,7 @@ type execOpts struct {
interactive bool
}
func execCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func execCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := execOpts{
composeOptions: &composeOptions{
ProjectOptions: p,
@@ -58,17 +59,17 @@ func execCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runExec(ctx, backend, opts)
return runExec(ctx, dockerCli, backend, opts)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
runCmd.Flags().BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: Run command in the background.")
runCmd.Flags().StringArrayVarP(&opts.environment, "env", "e", []string{}, "Set environment variables")
runCmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if there are multiple instances of a service [default: 1].")
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", !streams.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.")
@@ -80,8 +81,8 @@ func execCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
return runCmd
}
func runExec(ctx context.Context, backend api.Service, opts execOpts) error {
projectName, err := opts.toProjectName()
func runExec(ctx context.Context, dockerCli command.Cli, backend api.Service, opts execOpts) error {
projectName, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}

View File

@@ -23,6 +23,7 @@ import (
"sort"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
"github.com/spf13/cobra"
@@ -38,7 +39,7 @@ type imageOptions struct {
Format string
}
func imagesCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func imagesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := imageOptions{
ProjectOptions: p,
}
@@ -46,17 +47,17 @@ func imagesCommand(p *ProjectOptions, streams api.Streams, backend api.Service)
Use: "images [OPTIONS] [SERVICE...]",
Short: "List images used by the created containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runImages(ctx, streams, backend, opts, args)
return runImages(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
imgCmd.Flags().StringVar(&opts.Format, "format", "table", "Format the output. Values: [table | json].")
imgCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
return imgCmd
}
func runImages(ctx context.Context, streams api.Streams, backend api.Service, opts imageOptions, services []string) error {
projectName, err := opts.toProjectName()
func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service, opts imageOptions, services []string) error {
projectName, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}
@@ -80,7 +81,7 @@ func runImages(ctx context.Context, streams api.Streams, backend api.Service, op
}
}
for _, img := range ids {
fmt.Fprintln(streams.Out(), img)
fmt.Fprintln(dockerCli.Out(), img)
}
return nil
}
@@ -89,7 +90,7 @@ func runImages(ctx context.Context, streams api.Streams, backend api.Service, op
return images[i].ContainerName < images[j].ContainerName
})
return formatter.Print(images, opts.Format, streams.Out(),
return formatter.Print(images, opts.Format, dockerCli.Out(),
func(w io.Writer) {
for _, img := range images {
id := stringid.TruncateID(img.ID)

View File

@@ -20,6 +20,7 @@ import (
"context"
"os"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -32,7 +33,7 @@ type killOptions struct {
signal string
}
func killCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func killCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := killOptions{
ProjectOptions: p,
}
@@ -40,21 +41,21 @@ func killCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "kill [OPTIONS] [SERVICE...]",
Short: "Force stop service containers.",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runKill(ctx, backend, opts, args)
return runKill(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
removeOrphans := utils.StringToBool(os.Getenv("COMPOSE_REMOVE_ORPHANS"))
removeOrphans := utils.StringToBool(os.Getenv(ComposeRemoveOrphans))
flags.BoolVar(&opts.removeOrphans, "remove-orphans", removeOrphans, "Remove containers for services not defined in the Compose file.")
flags.StringVarP(&opts.signal, "signal", "s", "SIGKILL", "SIGNAL to send to the container.")
return cmd
}
func runKill(ctx context.Context, backend api.Service, opts killOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runKill(ctx context.Context, dockerCli command.Cli, backend api.Service, opts killOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}

View File

@@ -22,6 +22,7 @@ import (
"io"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/cli/opts"
@@ -37,13 +38,13 @@ type lsOptions struct {
Filter opts.FilterOpt
}
func listCommand(streams api.Streams, backend api.Service) *cobra.Command {
func listCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {
lsOpts := lsOptions{Filter: opts.NewFilterOpt()}
lsCmd := &cobra.Command{
Use: "ls [OPTIONS]",
Short: "List running compose projects",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runList(ctx, streams, backend, lsOpts)
return runList(ctx, dockerCli, backend, lsOpts)
}),
Args: cobra.NoArgs,
ValidArgsFunction: noCompletion(),
@@ -60,7 +61,7 @@ var acceptedListFilters = map[string]bool{
"name": true,
}
func runList(ctx context.Context, streams api.Streams, backend api.Service, lsOpts lsOptions) error {
func runList(ctx context.Context, dockerCli command.Cli, backend api.Service, lsOpts lsOptions) error {
filters := lsOpts.Filter.Value()
err := filters.Validate(acceptedListFilters)
if err != nil {
@@ -71,12 +72,6 @@ func runList(ctx context.Context, streams api.Streams, backend api.Service, lsOp
if err != nil {
return err
}
if lsOpts.Quiet {
for _, s := range stackList {
fmt.Fprintln(streams.Out(), s.Name)
}
return nil
}
if filters.Len() > 0 {
var filtered []api.Stack
@@ -89,8 +84,15 @@ func runList(ctx context.Context, streams api.Streams, backend api.Service, lsOp
stackList = filtered
}
if lsOpts.Quiet {
for _, s := range stackList {
fmt.Fprintln(dockerCli.Out(), s.Name)
}
return nil
}
view := viewFromStackList(stackList)
return formatter.Print(view, lsOpts.Format, streams.Out(), func(w io.Writer) {
return formatter.Print(view, lsOpts.Format, dockerCli.Out(), func(w io.Writer) {
for _, stack := range view {
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", stack.Name, stack.Status, stack.ConfigFiles)
}

View File

@@ -19,6 +19,7 @@ package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/cmd/formatter"
@@ -37,7 +38,7 @@ type logsOptions struct {
timestamps bool
}
func logsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func logsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := logsOptions{
ProjectOptions: p,
}
@@ -45,9 +46,9 @@ func logsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
Use: "logs [OPTIONS] [SERVICE...]",
Short: "View output from containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runLogs(ctx, streams, backend, opts, args)
return runLogs(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := logsCmd.Flags()
flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output.")
@@ -60,12 +61,12 @@ func logsCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
return logsCmd
}
func runLogs(ctx context.Context, streams api.Streams, backend api.Service, opts logsOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runLogs(ctx context.Context, dockerCli command.Cli, backend api.Service, opts logsOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}
consumer := formatter.NewLogConsumer(ctx, streams.Out(), streams.Err(), !opts.noColor, !opts.noPrefix, false)
consumer := formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), !opts.noColor, !opts.noPrefix, false)
return backend.Logs(ctx, name, consumer, api.LogOptions{
Project: project,
Services: services,

76
cmd/compose/options.go Normal file
View File

@@ -0,0 +1,76 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"fmt"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/utils"
)
func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
defaultPlatform := project.Environment["DOCKER_DEFAULT_PLATFORM"]
for i := range project.Services {
// mutable reference so platform fields can be updated
service := &project.Services[i]
if service.Build == nil {
continue
}
// 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) {
return fmt.Errorf("service %q build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: %s", service.Name, defaultPlatform)
}
service.Platform = defaultPlatform
}
if service.Platform != "" {
if len(service.Build.Platforms) > 0 {
if !utils.StringContains(service.Build.Platforms, service.Platform) {
return fmt.Errorf("service %q build configuration does not support platform: %s", service.Name, service.Platform)
}
}
if buildForSinglePlatform || len(service.Build.Platforms) == 0 {
// if we're building for a single platform, we want to build for the platform we'll use to run the image
// similarly, if no build platforms were explicitly specified, it makes sense to build for the platform
// the image is designed for rather than allowing the builder to infer the platform
service.Build.Platforms = []string{service.Platform}
}
}
// services can specify that they should be built for multiple platforms, which can be used
// with `docker compose build` to produce a multi-arch image
// other cases, such as `up` and `run`, need a single architecture to actually run
// if there is only a single platform present (which might have been inferred
// from service.Platform above), it will be used, even if it requires emulation.
// if there's more than one platform, then the list is cleared so that the builder
// can decide.
// TODO(milas): there's no validation that the platform the builder will pick is actually one
// of the supported platforms from the build definition
// e.g. `build.platforms: [linux/arm64, linux/amd64]` on a `linux/ppc64` machine would build
// for `linux/ppc64` instead of returning an error that it's not a valid platform for the service.
if buildForSinglePlatform && len(service.Build.Platforms) > 1 {
// empty indicates that the builder gets to decide
service.Build.Platforms = nil
}
}
return nil
}

130
cmd/compose/options_test.go Normal file
View File

@@ -0,0 +1,130 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"testing"
"github.com/compose-spec/compose-go/types"
"github.com/stretchr/testify/require"
)
func TestApplyPlatforms_InferFromRuntime(t *testing.T) {
makeProject := func() *types.Project {
return &types.Project{
Services: []types.ServiceConfig{
{
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Context: ".",
Platforms: []string{
"linux/amd64",
"linux/arm64",
"alice/32",
},
},
Platform: "alice/32",
},
},
}
}
t.Run("SinglePlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, true))
require.EqualValues(t, []string{"alice/32"}, project.Services[0].Build.Platforms)
})
t.Run("MultiPlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, false))
require.EqualValues(t, []string{"linux/amd64", "linux/arm64", "alice/32"},
project.Services[0].Build.Platforms)
})
}
func TestApplyPlatforms_DockerDefaultPlatform(t *testing.T) {
makeProject := func() *types.Project {
return &types.Project{
Environment: map[string]string{
"DOCKER_DEFAULT_PLATFORM": "linux/amd64",
},
Services: []types.ServiceConfig{
{
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Context: ".",
Platforms: []string{
"linux/amd64",
"linux/arm64",
},
},
},
},
}
}
t.Run("SinglePlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, true))
require.EqualValues(t, []string{"linux/amd64"}, project.Services[0].Build.Platforms)
})
t.Run("MultiPlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, false))
require.EqualValues(t, []string{"linux/amd64", "linux/arm64"},
project.Services[0].Build.Platforms)
})
}
func TestApplyPlatforms_UnsupportedPlatform(t *testing.T) {
makeProject := func() *types.Project {
return &types.Project{
Environment: map[string]string{
"DOCKER_DEFAULT_PLATFORM": "commodore/64",
},
Services: []types.ServiceConfig{
{
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Context: ".",
Platforms: []string{
"linux/amd64",
"linux/arm64",
},
},
},
},
}
}
t.Run("SinglePlatform", func(t *testing.T) {
project := makeProject()
require.EqualError(t, applyPlatforms(project, true),
`service "test" build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: commodore/64`)
})
t.Run("MultiPlatform", func(t *testing.T) {
project := makeProject()
require.EqualError(t, applyPlatforms(project, false),
`service "test" build.platforms does not support value set by DOCKER_DEFAULT_PLATFORM: commodore/64`)
})
}

View File

@@ -19,6 +19,7 @@ package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -28,7 +29,7 @@ type pauseOptions struct {
*ProjectOptions
}
func pauseCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func pauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := pauseOptions{
ProjectOptions: p,
}
@@ -36,15 +37,15 @@ func pauseCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "pause [SERVICE...]",
Short: "Pause services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPause(ctx, backend, opts, args)
return runPause(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
return cmd
}
func runPause(ctx context.Context, backend api.Service, opts pauseOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runPause(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pauseOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}
@@ -59,7 +60,7 @@ type unpauseOptions struct {
*ProjectOptions
}
func unpauseCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func unpauseCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := unpauseOptions{
ProjectOptions: p,
}
@@ -67,15 +68,15 @@ func unpauseCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "unpause [SERVICE...]",
Short: "Unpause services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runUnPause(ctx, backend, opts, args)
return runUnPause(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
return cmd
}
func runUnPause(ctx context.Context, backend api.Service, opts unpauseOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runUnPause(ctx context.Context, dockerCli command.Cli, backend api.Service, opts unpauseOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}

View File

@@ -22,6 +22,7 @@ import (
"strconv"
"strings"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -34,7 +35,7 @@ type portOptions struct {
index int
}
func portCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func portCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := portOptions{
ProjectOptions: p,
}
@@ -52,17 +53,17 @@ func portCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPort(ctx, streams, backend, opts, args[0])
return runPort(ctx, dockerCli, backend, opts, args[0])
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
cmd.Flags().StringVar(&opts.protocol, "protocol", "tcp", "tcp or udp")
cmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if service has multiple replicas")
cmd.Flags().IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
return cmd
}
func runPort(ctx context.Context, streams api.Streams, backend api.Service, opts portOptions, service string) error {
projectName, err := opts.toProjectName()
func runPort(ctx context.Context, dockerCli command.Cli, backend api.Service, opts portOptions, service string) error {
projectName, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}
@@ -74,6 +75,6 @@ func runPort(ctx context.Context, streams api.Streams, backend api.Service, opts
return err
}
fmt.Fprintf(streams.Out(), "%s:%d\n", ip, port)
fmt.Fprintf(dockerCli.Out(), "%s:%d\n", ip, port)
return nil
}

View File

@@ -18,23 +18,19 @@ package compose
import (
"context"
"errors"
"fmt"
"io"
"sort"
"strconv"
"strings"
"time"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/docker/api/types"
formatter2 "github.com/docker/cli/cli/command/formatter"
"github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"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"
cliflags "github.com/docker/cli/cli/flags"
"github.com/spf13/cobra"
)
type psOptions struct {
@@ -45,6 +41,7 @@ type psOptions struct {
Services bool
Filter string
Status []string
noTrunc bool
}
func (p *psOptions) parseFilter() error {
@@ -66,7 +63,7 @@ func (p *psOptions) parseFilter() error {
return nil
}
func psCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func psCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := psOptions{
ProjectOptions: p,
}
@@ -77,22 +74,23 @@ func psCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
return opts.parseFilter()
},
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPs(ctx, streams, backend, args, opts)
return runPs(ctx, dockerCli, backend, args, opts)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := psCmd.Flags()
flags.StringVar(&opts.Format, "format", "table", "Format the output. Values: [table | json]")
flags.StringVar(&opts.Format, "format", "table", cliflags.FormatHelp)
flags.StringVar(&opts.Filter, "filter", "", "Filter services by a property (supported filters: status).")
flags.StringArrayVar(&opts.Status, "status", []string{}, "Filter services by status. Values: [paused | restarting | removing | running | dead | created | exited]")
flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
flags.BoolVar(&opts.Services, "services", false, "Display services")
flags.BoolVarP(&opts.All, "all", "a", false, "Show all stopped containers (including those created by the run command)")
flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
return psCmd
}
func runPs(ctx context.Context, streams api.Streams, backend api.Service, services []string, opts psOptions) error {
project, name, err := opts.projectOrName(services...)
func runPs(ctx context.Context, dockerCli command.Cli, backend api.Service, services []string, opts psOptions) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}
@@ -125,38 +123,33 @@ func runPs(ctx context.Context, streams api.Streams, backend api.Service, servic
if opts.Quiet {
for _, c := range containers {
fmt.Fprintln(streams.Out(), c.ID)
fmt.Fprintln(dockerCli.Out(), c.ID)
}
return nil
}
if opts.Services {
services := []string{}
for _, s := range containers {
if !utils.StringContains(services, s.Service) {
services = append(services, s.Service)
for _, c := range containers {
s := c.Service
if !utils.StringContains(services, s) {
services = append(services, s)
}
}
fmt.Fprintln(streams.Out(), strings.Join(services, "\n"))
fmt.Fprintln(dockerCli.Out(), strings.Join(services, "\n"))
return nil
}
return formatter.Print(containers, opts.Format, streams.Out(),
writer(containers),
"NAME", "IMAGE", "COMMAND", "SERVICE", "CREATED", "STATUS", "PORTS")
}
func writer(containers []api.ContainerSummary) func(w io.Writer) {
return func(w io.Writer) {
for _, container := range containers {
ports := displayablePorts(container)
createdAt := time.Unix(container.Created, 0)
created := units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
status := container.Status
command := formatter2.Ellipsis(container.Command, 20)
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", container.Name, container.Image, strconv.Quote(command), container.Service, created, status, ports)
}
if opts.Format == "" {
opts.Format = dockerCli.ConfigFile().PsFormat
}
containerCtx := cliformatter.Context{
Output: dockerCli.Out(),
Format: formatter.NewContainerFormat(opts.Format, opts.Quiet, false),
Trunc: !opts.noTrunc,
}
return formatter.ContainerWrite(containerCtx, containers)
}
func filterByStatus(containers []api.ContainerSummary, statuses []string) []api.ContainerSummary {
@@ -177,21 +170,3 @@ func hasStatus(c api.ContainerSummary, statuses []string) bool {
}
return false
}
func displayablePorts(c api.ContainerSummary) string {
if c.Publishers == nil {
return ""
}
ports := make([]types.Port, len(c.Publishers))
for i, pub := range c.Publishers {
ports[i] = types.Port{
IP: pub.URL,
PrivatePort: uint16(pub.TargetPort),
PublicPort: uint16(pub.PublishedPort),
Type: pub.Protocol,
}
}
return formatter2.DisplayablePorts(ports)
}

View File

@@ -18,11 +18,11 @@ package compose
import (
"context"
"io"
"os"
"path/filepath"
"testing"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/streams"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/mocks"
@@ -69,7 +69,11 @@ func TestPsTable(t *testing.T) {
}).AnyTimes()
opts := psOptions{ProjectOptions: &ProjectOptions{ProjectName: "test"}}
err = runPs(ctx, stream{out: streams.NewOut(f)}, backend, nil, opts)
stdout := streams.NewOut(f)
cli := mocks.NewMockCli(ctrl)
cli.EXPECT().Out().Return(stdout).AnyTimes()
cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
err = runPs(ctx, cli, backend, nil, opts)
assert.NoError(t, err)
_, err = f.Seek(0, 0)
@@ -80,21 +84,3 @@ func TestPsTable(t *testing.T) {
assert.Contains(t, string(output), "8080/tcp, 8443/tcp")
}
type stream struct {
out *streams.Out
err io.Writer
in *streams.In
}
func (s stream) Out() *streams.Out {
return s.out
}
func (s stream) Err() io.Writer {
return s.err
}
func (s stream) In() *streams.In {
return s.in
}

59
cmd/compose/publish.go Normal file
View File

@@ -0,0 +1,59 @@
/*
Copyright 2020 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
)
type publishOptions struct {
*ProjectOptions
resolveImageDigests bool
}
func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := publishOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "publish [OPTIONS] [REPOSITORY]",
Short: "Publish compose application",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPublish(ctx, dockerCli, backend, opts, args[0])
}),
Args: cobra.ExactArgs(1),
}
flags := cmd.Flags()
flags.BoolVar(&opts.resolveImageDigests, "resolve-image-digests", false, "Pin image tags to digests.")
return cmd
}
func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Service, opts publishOptions, repository string) error {
project, err := opts.ToProject(dockerCli, nil)
if err != nil {
return err
}
return backend.Publish(ctx, project, repository, api.PublishOptions{
ResolveImageDigests: opts.resolveImageDigests,
})
}

View File

@@ -22,11 +22,11 @@ import (
"os"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/morikuni/aec"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
)
type pullOptions struct {
@@ -38,9 +38,10 @@ type pullOptions struct {
includeDeps bool
ignorePullFailures bool
noBuildable bool
policy string
}
func pullCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func pullCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := pullOptions{
ProjectOptions: p,
}
@@ -54,9 +55,9 @@ func pullCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPull(ctx, backend, opts, args)
return runPull(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Pull without printing progress information.")
@@ -67,37 +68,41 @@ func pullCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
flags.MarkHidden("no-parallel") //nolint:errcheck
cmd.Flags().BoolVar(&opts.ignorePullFailures, "ignore-pull-failures", false, "Pull what it can and ignores images with pull failures.")
cmd.Flags().BoolVar(&opts.noBuildable, "ignore-buildable", false, "Ignore images that can be built.")
cmd.Flags().StringVar(&opts.policy, "policy", "", `Apply pull policy ("missing"|"always").`)
return cmd
}
func withSelectedServicesOnly(project *types.Project, services []string) error {
enabled, err := project.GetServices(services...)
if err != nil {
return err
}
for _, s := range project.Services {
if !utils.StringContains(services, s.Name) {
project.DisabledServices = append(project.DisabledServices, s)
}
}
project.Services = enabled
return nil
}
func runPull(ctx context.Context, backend api.Service, opts pullOptions, services []string) error {
project, err := opts.ToProject(services)
if err != nil {
return err
}
func (opts pullOptions) apply(project *types.Project, services []string) error {
if !opts.includeDeps {
err := withSelectedServicesOnly(project, services)
err := project.ForServices(services, types.IgnoreDependencies)
if err != nil {
return err
}
}
if opts.policy != "" {
for i, service := range project.Services {
if service.Image == "" {
continue
}
service.PullPolicy = opts.policy
project.Services[i] = service
}
}
return nil
}
func runPull(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pullOptions, services []string) error {
project, err := opts.ToProject(dockerCli, services)
if err != nil {
return err
}
err = opts.apply(project, services)
if err != nil {
return err
}
return backend.Pull(ctx, project, api.PullOptions{
Quiet: opts.quiet,
IgnoreFailures: opts.ignorePullFailures,

View File

@@ -0,0 +1,57 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"testing"
"github.com/compose-spec/compose-go/types"
"gotest.tools/v3/assert"
)
func TestApplyPullOptions(t *testing.T) {
project := &types.Project{
Services: []types.ServiceConfig{
{
Name: "must-build",
// No image, local build only
Build: &types.BuildConfig{
Context: ".",
},
},
{
Name: "has-build",
Image: "registry.example.com/myservice",
Build: &types.BuildConfig{
Context: ".",
},
},
{
Name: "must-pull",
Image: "registry.example.com/another-service",
},
},
}
err := pullOptions{
policy: types.PullPolicyMissing,
}.apply(project, nil)
assert.NilError(t, err)
assert.Equal(t, project.Services[0].PullPolicy, "") // still default
assert.Equal(t, project.Services[1].PullPolicy, types.PullPolicyMissing)
assert.Equal(t, project.Services[2].PullPolicy, types.PullPolicyMissing)
}

View File

@@ -19,6 +19,8 @@ package compose
import (
"context"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -32,7 +34,7 @@ type pushOptions struct {
Quiet bool
}
func pushCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func pushCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := pushOptions{
ProjectOptions: p,
}
@@ -40,9 +42,9 @@ func pushCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "push [OPTIONS] [SERVICE...]",
Short: "Push service images",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPush(ctx, backend, opts, args)
return runPush(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
pushCmd.Flags().BoolVar(&opts.Ignorefailures, "ignore-push-failures", false, "Push what it can and ignores images with push failures")
pushCmd.Flags().BoolVar(&opts.IncludeDeps, "include-deps", false, "Also push images of services declared as dependencies")
@@ -51,14 +53,14 @@ func pushCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return pushCmd
}
func runPush(ctx context.Context, backend api.Service, opts pushOptions, services []string) error {
project, err := opts.ToProject(services)
func runPush(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pushOptions, services []string) error {
project, err := opts.ToProject(dockerCli, services)
if err != nil {
return err
}
if !opts.IncludeDeps {
err := withSelectedServicesOnly(project, services)
err := project.ForServices(services, types.IgnoreDependencies)
if err != nil {
return err
}

View File

@@ -19,6 +19,7 @@ package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
@@ -30,7 +31,7 @@ type removeOptions struct {
volumes bool
}
func removeCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func removeCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := removeOptions{
ProjectOptions: p,
}
@@ -44,9 +45,9 @@ can override this with -v. To list all volumes, use "docker volume ls".
Any data which is not in a volume will be lost.`,
RunE: Adapt(func(ctx context.Context, args []string) error {
return runRemove(ctx, backend, opts, args)
return runRemove(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
f := cmd.Flags()
f.BoolVarP(&opts.force, "force", "f", false, "Don't ask to confirm removal")
@@ -58,26 +59,17 @@ Any data which is not in a volume will be lost.`,
return cmd
}
func runRemove(ctx context.Context, backend api.Service, opts removeOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runRemove(ctx context.Context, dockerCli command.Cli, backend api.Service, opts removeOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}
if opts.stop {
err := backend.Stop(ctx, name, api.StopOptions{
Services: services,
Project: project,
})
if err != nil {
return err
}
}
return backend.Remove(ctx, name, api.RemoveOptions{
Services: services,
Force: opts.force,
Volumes: opts.volumes,
Project: project,
Stop: opts.stop,
})
}

View File

@@ -20,6 +20,7 @@ import (
"context"
"time"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -27,37 +28,56 @@ import (
type restartOptions struct {
*ProjectOptions
timeout int
timeChanged bool
timeout int
noDeps bool
}
func restartCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func restartCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := restartOptions{
ProjectOptions: p,
}
restartCmd := &cobra.Command{
Use: "restart [OPTIONS] [SERVICE...]",
Short: "Restart service containers",
PreRun: func(cmd *cobra.Command, args []string) {
opts.timeChanged = cmd.Flags().Changed("timeout")
},
RunE: Adapt(func(ctx context.Context, args []string) error {
return runRestart(ctx, backend, opts, args)
return runRestart(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := restartCmd.Flags()
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
flags.IntVarP(&opts.timeout, "timeout", "t", 0, "Specify a shutdown timeout in seconds")
flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't restart dependent services.")
return restartCmd
}
func runRestart(ctx context.Context, backend api.Service, opts restartOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runRestart(ctx context.Context, dockerCli command.Cli, backend api.Service, opts restartOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli)
if err != nil {
return err
}
timeout := time.Duration(opts.timeout) * time.Second
if project != nil && len(services) > 0 {
err := project.EnableServices(services...)
if err != nil {
return err
}
}
var timeout *time.Duration
if opts.timeChanged {
timeoutValue := time.Duration(opts.timeout) * time.Second
timeout = &timeoutValue
}
return backend.Restart(ctx, name, api.RestartOptions{
Timeout: &timeout,
Timeout: timeout,
Services: services,
Project: project,
NoDeps: opts.noDeps,
})
}

View File

@@ -21,9 +21,13 @@ import (
"fmt"
"strings"
xprogress "github.com/docker/buildx/util/progress"
cgo "github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
"github.com/mattn/go-shellwords"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -48,6 +52,8 @@ type runOptions struct {
workdir string
entrypoint string
entrypointCmd []string
capAdd opts.ListOpts
capDrop opts.ListOpts
labels []string
volumes []string
publish []string
@@ -59,20 +65,26 @@ type runOptions struct {
quietPull bool
}
func (opts runOptions) apply(project *types.Project) error {
target, err := project.GetService(opts.Service)
func (options runOptions) apply(project *types.Project) error {
if options.noDeps {
err := project.ForServices([]string{options.Service}, types.IgnoreDependencies)
if err != nil {
return err
}
}
target, err := project.GetService(options.Service)
if err != nil {
return err
}
target.Tty = !opts.noTty
target.StdinOpen = opts.interactive
if !opts.servicePorts {
target.Tty = !options.noTty
target.StdinOpen = options.interactive
// --service-ports and --publish are incompatible
if !options.servicePorts {
target.Ports = []types.ServicePortConfig{}
}
if len(opts.publish) > 0 {
target.Ports = []types.ServicePortConfig{}
for _, p := range opts.publish {
for _, p := range options.publish {
config, err := types.ParsePortConfig(p)
if err != nil {
return err
@@ -80,27 +92,17 @@ func (opts runOptions) apply(project *types.Project) error {
target.Ports = append(target.Ports, config...)
}
}
if len(opts.volumes) > 0 {
for _, v := range opts.volumes {
volume, err := loader.ParseVolume(v)
if err != nil {
return err
}
target.Volumes = append(target.Volumes, volume)
}
}
if opts.noDeps {
for _, s := range project.Services {
if s.Name != opts.Service {
project.DisabledServices = append(project.DisabledServices, s)
}
for _, v := range options.volumes {
volume, err := loader.ParseVolume(v)
if err != nil {
return err
}
project.Services = types.Services{target}
target.Volumes = append(target.Volumes, volume)
}
for i, s := range project.Services {
if s.Name == opts.Service {
if s.Name == options.Service {
project.Services[i] = target
break
}
@@ -108,72 +110,84 @@ func (opts runOptions) apply(project *types.Project) error {
return nil
}
func runCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
opts := runOptions{
func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
options := runOptions{
composeOptions: &composeOptions{
ProjectOptions: p,
},
capAdd: opts.NewListOpts(nil),
capDrop: opts.NewListOpts(nil),
}
createOpts := createOptions{}
buildOpts := buildOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "run [OPTIONS] SERVICE [COMMAND] [ARGS...]",
Short: "Run a one-off command on a service.",
Args: cobra.MinimumNArgs(1),
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.Service = args[0]
options.Service = args[0]
if len(args) > 1 {
opts.Command = args[1:]
options.Command = args[1:]
}
if len(opts.publish) > 0 && opts.servicePorts {
if len(options.publish) > 0 && options.servicePorts {
return fmt.Errorf("--service-ports and --publish are incompatible")
}
if cmd.Flags().Changed("entrypoint") {
command, err := shellwords.Parse(opts.entrypoint)
command, err := shellwords.Parse(options.entrypoint)
if err != nil {
return err
}
opts.entrypointCmd = command
options.entrypointCmd = command
}
if cmd.Flags().Changed("tty") {
if cmd.Flags().Changed("no-TTY") {
return fmt.Errorf("--tty and --no-TTY can't be used together")
} else {
opts.noTty = !opts.tty
options.noTty = !options.tty
}
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
project, err := p.ToProject([]string{opts.Service}, cgo.WithResolvedPaths(true))
project, err := p.ToProject(dockerCli, []string{options.Service}, cgo.WithResolvedPaths(true), cgo.WithDiscardEnvFile)
if err != nil {
return err
}
opts.ignoreOrphans = utils.StringToBool(project.Environment["COMPOSE_IGNORE_ORPHANS"])
return runRun(ctx, backend, project, opts, createOpts)
if createOpts.quietPull {
buildOpts.Progress = xprogress.PrinterModeQuiet
}
options.ignoreOrphans = utils.StringToBool(project.Environment[ComposeIgnoreOrphans])
return runRun(ctx, backend, project, options, createOpts, buildOpts, dockerCli)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.BoolVarP(&opts.Detach, "detach", "d", false, "Run container in background and print container ID")
flags.StringArrayVarP(&opts.environment, "env", "e", []string{}, "Set environment variables")
flags.StringArrayVarP(&opts.labels, "label", "l", []string{}, "Add or override a label")
flags.BoolVar(&opts.Remove, "rm", false, "Automatically remove the container when it exits")
flags.BoolVarP(&opts.noTty, "no-TTY", "T", !streams.Out().IsTerminal(), "Disable pseudo-TTY allocation (default: auto-detected).")
flags.StringVar(&opts.name, "name", "", "Assign a name to the container")
flags.StringVarP(&opts.user, "user", "u", "", "Run as specified username or uid")
flags.StringVarP(&opts.workdir, "workdir", "w", "", "Working directory inside the container")
flags.StringVar(&opts.entrypoint, "entrypoint", "", "Override the entrypoint of the image")
flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.")
flags.StringArrayVarP(&opts.volumes, "volume", "v", []string{}, "Bind mount a volume.")
flags.StringArrayVarP(&opts.publish, "publish", "p", []string{}, "Publish a container's port(s) to the host.")
flags.BoolVar(&opts.useAliases, "use-aliases", false, "Use the service's network useAliases in the network(s) the container connects to.")
flags.BoolVar(&opts.servicePorts, "service-ports", false, "Run command with the service's ports enabled and mapped to the host.")
flags.BoolVar(&opts.quietPull, "quiet-pull", false, "Pull without printing progress information.")
flags.BoolVarP(&options.Detach, "detach", "d", false, "Run container in background and print container ID")
flags.StringArrayVarP(&options.environment, "env", "e", []string{}, "Set environment variables")
flags.StringArrayVarP(&options.labels, "label", "l", []string{}, "Add or override a label")
flags.BoolVar(&options.Remove, "rm", false, "Automatically remove the container when it exits")
flags.BoolVarP(&options.noTty, "no-TTY", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation (default: auto-detected).")
flags.StringVar(&options.name, "name", "", "Assign a name to the container")
flags.StringVarP(&options.user, "user", "u", "", "Run as specified username or uid")
flags.StringVarP(&options.workdir, "workdir", "w", "", "Working directory inside the container")
flags.StringVar(&options.entrypoint, "entrypoint", "", "Override the entrypoint of the image")
flags.Var(&options.capAdd, "cap-add", "Add Linux capabilities")
flags.Var(&options.capDrop, "cap-drop", "Drop Linux capabilities")
flags.BoolVar(&options.noDeps, "no-deps", false, "Don't start linked services.")
flags.StringArrayVarP(&options.volumes, "volume", "v", []string{}, "Bind mount a volume.")
flags.StringArrayVarP(&options.publish, "publish", "p", []string{}, "Publish a container's port(s) to the host.")
flags.BoolVar(&options.useAliases, "use-aliases", false, "Use the service's network useAliases in the network(s) the container connects to.")
flags.BoolVar(&options.servicePorts, "service-ports", false, "Run command with the service's ports enabled and mapped to the host.")
flags.BoolVar(&options.quietPull, "quiet-pull", false, "Pull without printing progress information.")
flags.BoolVar(&createOpts.Build, "build", false, "Build image before starting container.")
flags.BoolVar(&createOpts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
cmd.Flags().BoolVarP(&opts.interactive, "interactive", "i", true, "Keep STDIN open even if not attached.")
cmd.Flags().BoolVarP(&opts.tty, "tty", "t", true, "Allocate a pseudo-TTY.")
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().MarkHidden("tty") //nolint:errcheck
flags.SetNormalizeFunc(normalizeRunFlags)
@@ -191,8 +205,8 @@ func normalizeRunFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
return pflag.NormalizedName(name)
}
func runRun(ctx context.Context, backend api.Service, project *types.Project, opts runOptions, createOpts createOptions) error {
err := opts.apply(project)
func runRun(ctx context.Context, backend api.Service, project *types.Project, options runOptions, createOpts createOptions, buildOpts buildOptions, dockerCli command.Cli) error {
err := options.apply(project)
if err != nil {
return err
}
@@ -203,14 +217,23 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
}
err = progress.Run(ctx, func(ctx context.Context) error {
return startDependencies(ctx, backend, *project, opts.Service, opts.ignoreOrphans)
})
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.Service, options.ignoreOrphans)
}, dockerCli.Err())
if err != nil {
return err
}
labels := types.Labels{}
for _, s := range opts.labels {
for _, s := range options.labels {
parts := strings.SplitN(s, "=", 2)
if len(parts) != 2 {
return fmt.Errorf("label must be set as KEY=VALUE")
@@ -218,29 +241,43 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
labels[parts[0]] = parts[1]
}
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})
if err != nil {
return err
}
buildForRun = &bo
}
// start container and attach to container streams
runOpts := api.RunOptions{
Name: opts.name,
Service: opts.Service,
Command: opts.Command,
Detach: opts.Detach,
AutoRemove: opts.Remove,
Tty: !opts.noTty,
Interactive: opts.interactive,
WorkingDir: opts.workdir,
User: opts.user,
Environment: opts.environment,
Entrypoint: opts.entrypointCmd,
Build: buildForRun,
Name: options.name,
Service: options.Service,
Command: options.Command,
Detach: options.Detach,
AutoRemove: options.Remove,
Tty: !options.noTty,
Interactive: options.interactive,
WorkingDir: options.workdir,
User: options.user,
CapAdd: options.capAdd.GetAll(),
CapDrop: options.capDrop.GetAll(),
Environment: options.environment,
Entrypoint: options.entrypointCmd,
Labels: labels,
UseNetworkAliases: opts.useAliases,
NoDeps: opts.noDeps,
UseNetworkAliases: options.useAliases,
NoDeps: options.noDeps,
Index: 0,
QuietPull: opts.quietPull,
QuietPull: options.quietPull,
}
for i, service := range project.Services {
if service.Name == opts.Service {
service.StdinOpen = opts.interactive
if service.Name == options.Service {
service.StdinOpen = options.interactive
project.Services[i] = service
}
}
@@ -256,7 +293,7 @@ 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, requestedServiceName string, ignoreOrphans bool) error {
func startDependencies(ctx context.Context, backend api.Service, project types.Project, buildOpts *api.BuildOptions, requestedServiceName string, ignoreOrphans bool) error {
dependencies := types.Services{}
var requestedService types.ServiceConfig
for _, service := range project.Services {
@@ -270,6 +307,7 @@ func startDependencies(ctx context.Context, backend api.Service, project types.P
project.Services = dependencies
project.DisabledServices = append(project.DisabledServices, requestedService)
err := backend.Create(ctx, &project, api.CreateOptions{
Build: buildOpts,
IgnoreOrphans: ignoreOrphans,
})
if err != nil {

108
cmd/compose/scale.go Normal file
View File

@@ -0,0 +1,108 @@
/*
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"
"strconv"
"strings"
"github.com/docker/cli/cli/command"
"github.com/compose-spec/compose-go/types"
"golang.org/x/exp/maps"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type scaleOptions struct {
*ProjectOptions
noDeps bool
}
func scaleCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := scaleOptions{
ProjectOptions: p,
}
scaleCmd := &cobra.Command{
Use: "scale [SERVICE=REPLICAS...]",
Short: "Scale services ",
Args: cobra.MinimumNArgs(1),
RunE: Adapt(func(ctx context.Context, args []string) error {
serviceTuples, err := parseServicesReplicasArgs(args)
if err != nil {
return err
}
return runScale(ctx, dockerCli, backend, opts, serviceTuples)
}),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := scaleCmd.Flags()
flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.")
return scaleCmd
}
func runScale(ctx context.Context, dockerCli command.Cli, backend api.Service, opts scaleOptions, serviceReplicaTuples map[string]int) error {
services := maps.Keys(serviceReplicaTuples)
project, err := opts.ToProject(dockerCli, services)
if err != nil {
return err
}
if opts.noDeps {
if err := project.ForServices(services, types.IgnoreDependencies); err != nil {
return err
}
}
for key, value := range serviceReplicaTuples {
for i, service := range project.Services {
if service.Name != key {
continue
}
if service.Deploy == nil {
service.Deploy = &types.DeployConfig{}
}
scale := uint64(value)
service.Deploy.Replicas = &scale
project.Services[i] = service
break
}
}
return backend.Scale(ctx, project, api.ScaleOptions{Services: services})
}
func parseServicesReplicasArgs(args []string) (map[string]int, error) {
serviceReplicaTuples := map[string]int{}
for _, arg := range args {
key, val, ok := strings.Cut(arg, "=")
if !ok || key == "" || val == "" {
return nil, fmt.Errorf("invalid scale specifier: %s", arg)
}
intValue, err := strconv.Atoi(val)
if err != nil {
return nil, fmt.Errorf("invalid scale specifier: can't parse replica value as int: %v", arg)
}
serviceReplicaTuples[key] = intValue
}
return serviceReplicaTuples, nil
}

View File

@@ -19,6 +19,7 @@ package compose
import (
"context"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
@@ -27,7 +28,7 @@ type startOptions struct {
*ProjectOptions
}
func startCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func startCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := startOptions{
ProjectOptions: p,
}
@@ -35,15 +36,15 @@ func startCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
Use: "start [SERVICE...]",
Short: "Start services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runStart(ctx, backend, opts, args)
return runStart(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
return startCmd
}
func runStart(ctx context.Context, backend api.Service, opts startOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runStart(ctx context.Context, dockerCli command.Cli, backend api.Service, opts startOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}

View File

@@ -20,6 +20,7 @@ import (
"context"
"time"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -31,7 +32,7 @@ type stopOptions struct {
timeout int
}
func stopCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
func stopCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := stopOptions{
ProjectOptions: p,
}
@@ -42,18 +43,18 @@ func stopCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
opts.timeChanged = cmd.Flags().Changed("timeout")
},
RunE: Adapt(func(ctx context.Context, args []string) error {
return runStop(ctx, backend, opts, args)
return runStop(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := cmd.Flags()
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
flags.IntVarP(&opts.timeout, "timeout", "t", 0, "Specify a shutdown timeout in seconds")
return cmd
}
func runStop(ctx context.Context, backend api.Service, opts stopOptions, services []string) error {
project, name, err := opts.projectOrName(services...)
func runStop(ctx context.Context, dockerCli command.Cli, backend api.Service, opts stopOptions, services []string) error {
project, name, err := opts.projectOrName(dockerCli, services...)
if err != nil {
return err
}

View File

@@ -24,6 +24,7 @@ import (
"strings"
"text/tabwriter"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -33,7 +34,7 @@ type topOptions struct {
*ProjectOptions
}
func topCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func topCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := topOptions{
ProjectOptions: p,
}
@@ -41,15 +42,15 @@ func topCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *co
Use: "top [SERVICES...]",
Short: "Display the running processes",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runTop(ctx, streams, backend, opts, args)
return runTop(ctx, dockerCli, backend, opts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
return topCmd
}
func runTop(ctx context.Context, streams api.Streams, backend api.Service, opts topOptions, services []string) error {
projectName, err := opts.toProjectName()
func runTop(ctx context.Context, dockerCli command.Cli, backend api.Service, opts topOptions, services []string) error {
projectName, err := opts.toProjectName(dockerCli)
if err != nil {
return err
}
@@ -63,8 +64,8 @@ func runTop(ctx context.Context, streams api.Streams, backend api.Service, opts
})
for _, container := range containers {
fmt.Fprintf(streams.Out(), "%s\n", container.Name)
err := psPrinter(streams.Out(), func(w io.Writer) {
fmt.Fprintf(dockerCli.Out(), "%s\n", container.Name)
err := psPrinter(dockerCli.Out(), func(w io.Writer) {
for _, proc := range container.Processes {
info := []interface{}{}
for _, p := range proc {

View File

@@ -18,11 +18,16 @@ package compose
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/docker/compose/v2/cmd/formatter"
xprogress "github.com/docker/buildx/util/progress"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
@@ -48,11 +53,12 @@ type upOptions struct {
noAttach []string
timestamp bool
wait bool
waitTimeout int
}
func (opts upOptions) apply(project *types.Project, services []string) error {
if opts.noDeps {
err := withSelectedServicesOnly(project, services)
err := project.ForServices(services, types.IgnoreDependencies)
if err != nil {
return err
}
@@ -68,9 +74,10 @@ func (opts upOptions) apply(project *types.Project, services []string) error {
return nil
}
func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cobra.Command {
func upCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
up := upOptions{}
create := createOptions{}
build := buildOptions{ProjectOptions: p}
upCmd := &cobra.Command{
Use: "up [OPTIONS] [SERVICE...]",
Short: "Create and start containers",
@@ -79,20 +86,23 @@ func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
create.timeChanged = cmd.Flags().Changed("timeout")
return validateFlags(&up, &create)
}),
RunE: p.WithServices(func(ctx context.Context, project *types.Project, services []string) error {
create.ignoreOrphans = utils.StringToBool(project.Environment["COMPOSE_IGNORE_ORPHANS"])
RunE: p.WithServices(dockerCli, func(ctx context.Context, project *types.Project, services []string) error {
create.ignoreOrphans = utils.StringToBool(project.Environment[ComposeIgnoreOrphans])
if create.ignoreOrphans && create.removeOrphans {
return fmt.Errorf("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined")
return fmt.Errorf("cannot combine %s and --remove-orphans", ComposeIgnoreOrphans)
}
return runUp(ctx, streams, backend, create, up, project, services)
if len(up.attach) != 0 && up.attachDependencies {
return errors.New("cannot combine --attach and --attach-dependencies")
}
return runUp(ctx, dockerCli, backend, create, up, build, project, services)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
flags := upCmd.Flags()
flags.BoolVarP(&up.Detach, "detach", "d", false, "Detached mode: Run containers in the background")
flags.BoolVar(&create.Build, "build", false, "Build images before starting containers.")
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
flags.StringVar(&create.Pull, "pull", "missing", `Pull image before running ("always"|"missing"|"never")`)
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's policy.")
flags.StringVar(&create.Pull, "pull", "policy", `Pull image before running ("always"|"missing"|"never")`)
flags.BoolVar(&create.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
flags.StringArrayVar(&create.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.")
@@ -102,16 +112,17 @@ func upCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *cob
flags.BoolVar(&up.noStart, "no-start", false, "Don't start the services after creating them.")
flags.BoolVar(&up.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
flags.StringVar(&up.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
flags.IntVarP(&create.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
flags.IntVarP(&create.timeout, "timeout", "t", 0, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
flags.BoolVar(&up.timestamp, "timestamps", false, "Show timestamps.")
flags.BoolVar(&up.noDeps, "no-deps", false, "Don't start linked services.")
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(&up.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information.")
flags.StringArrayVar(&up.attach, "attach", []string{}, "Attach to service output.")
flags.StringArrayVar(&up.noAttach, "no-attach", []string{}, "Don't attach to specified service.")
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.")
flags.BoolVar(&up.wait, "wait", false, "Wait for services to be running|healthy. Implies detached mode.")
flags.IntVar(&up.waitTimeout, "wait-timeout", 0, "Maximum duration to wait for the project to be running|healthy.")
return upCmd
}
@@ -141,7 +152,16 @@ func validateFlags(up *upOptions, create *createOptions) error {
return nil
}
func runUp(ctx context.Context, streams api.Streams, backend api.Service, createOptions createOptions, upOptions upOptions, project *types.Project, services []string) error {
func runUp(
ctx context.Context,
dockerCli command.Cli,
backend api.Service,
createOptions createOptions,
upOptions upOptions,
buildOptions buildOptions,
project *types.Project,
services []string,
) error {
if len(project.Services) == 0 {
return fmt.Errorf("no service selected")
}
@@ -156,24 +176,26 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
return err
}
var consumer api.LogConsumer
if !upOptions.Detach {
consumer = formatter.NewLogConsumer(ctx, streams.Out(), streams.Err(), !upOptions.noColor, !upOptions.noPrefix, upOptions.timestamp)
var build *api.BuildOptions
// this check is technically redundant as createOptions::apply()
// already removed all the build sections
if !createOptions.noBuild {
if createOptions.quietPull {
buildOptions.Progress = xprogress.PrinterModeQuiet
}
// BuildOptions here is nested inside CreateOptions, so
// no service list is passed, it will implicitly pick all
// services being created, which includes any explicitly
// specified via "services" arg here as well as deps
bo, err := buildOptions.toAPIBuildOptions(nil)
if err != nil {
return err
}
build = &bo
}
attachTo := services
if len(upOptions.attach) > 0 {
attachTo = upOptions.attach
}
if upOptions.attachDependencies {
attachTo = project.ServiceNames()
}
if len(attachTo) == 0 {
attachTo = project.ServiceNames()
}
attachTo = utils.Remove(attachTo, upOptions.noAttach...)
create := api.CreateOptions{
Build: build,
Services: services,
RemoveOrphans: createOptions.removeOrphans,
IgnoreOrphans: createOptions.ignoreOrphans,
@@ -188,15 +210,52 @@ func runUp(ctx context.Context, streams api.Streams, backend api.Service, create
return backend.Create(ctx, project, create)
}
var consumer api.LogConsumer
var attach []string
if !upOptions.Detach {
consumer = formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), !upOptions.noColor, !upOptions.noPrefix, upOptions.timestamp)
var attachSet utils.Set[string]
if len(upOptions.attach) != 0 {
// services are passed explicitly with --attach, verify they're valid and then use them as-is
attachSet = utils.NewSet(upOptions.attach...)
unexpectedSvcs := attachSet.Diff(utils.NewSet(project.ServiceNames()...))
if len(unexpectedSvcs) != 0 {
return fmt.Errorf("cannot attach to services not included in up: %s", strings.Join(unexpectedSvcs.Elements(), ", "))
}
} else {
// mark services being launched (and potentially their deps) for attach
// if they didn't opt-out via Compose YAML
attachSet = utils.NewSet[string]()
var dependencyOpt types.DependencyOption = types.IgnoreDependencies
if upOptions.attachDependencies {
dependencyOpt = types.IncludeDependencies
}
if err := project.WithServices(services, func(s types.ServiceConfig) error {
if s.Attach == nil || *s.Attach {
attachSet.Add(s.Name)
}
return nil
}, dependencyOpt); err != nil {
return err
}
}
// filter out any services that have been explicitly marked for ignore with `--no-attach`
attachSet.RemoveAll(upOptions.noAttach...)
attach = attachSet.Elements()
}
timeout := time.Duration(upOptions.waitTimeout) * time.Second
return backend.Up(ctx, project, api.UpOptions{
Create: create,
Start: api.StartOptions{
Project: project,
Attach: consumer,
AttachTo: attachTo,
AttachTo: attach,
ExitCodeFrom: upOptions.exitCodeFrom,
CascadeStop: upOptions.cascadeStop,
Wait: upOptions.wait,
WaitTimeout: timeout,
Services: services,
},
})

View File

@@ -20,6 +20,7 @@ import (
"fmt"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/spf13/cobra"
@@ -32,14 +33,14 @@ type versionOptions struct {
short bool
}
func versionCommand() *cobra.Command {
func versionCommand(dockerCli command.Cli) *cobra.Command {
opts := versionOptions{}
cmd := &cobra.Command{
Use: "version [OPTIONS]",
Short: "Show the Docker Compose version information",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
runVersion(opts)
runVersion(opts, dockerCli)
return nil
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
@@ -56,14 +57,14 @@ func versionCommand() *cobra.Command {
return cmd
}
func runVersion(opts versionOptions) {
func runVersion(opts versionOptions, dockerCli command.Cli) {
if opts.short {
fmt.Println(strings.TrimPrefix(internal.Version, "v"))
fmt.Fprintln(dockerCli.Out(), strings.TrimPrefix(internal.Version, "v"))
return
}
if opts.format == formatter.JSON {
fmt.Printf("{\"version\":%q}\n", internal.Version)
fmt.Fprintf(dockerCli.Out(), "{\"version\":%q}\n", internal.Version)
return
}
fmt.Println("Docker Compose version", internal.Version)
fmt.Fprintln(dockerCli.Out(), "Docker Compose version", internal.Version)
}

97
cmd/compose/viz.go Normal file
View File

@@ -0,0 +1,97 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"context"
"fmt"
"os"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type vizOptions struct {
*ProjectOptions
includeNetworks bool
includePorts bool
includeImageName bool
indentationStr string
}
func vizCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := vizOptions{
ProjectOptions: p,
}
var indentationSize int
var useSpaces bool
cmd := &cobra.Command{
Use: "viz [OPTIONS]",
Short: "EXPERIMENTAL - Generate a graphviz graph from your compose file",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
var err error
opts.indentationStr, err = preferredIndentationStr(indentationSize, useSpaces)
return err
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runViz(ctx, dockerCli, backend, &opts)
}),
}
cmd.Flags().BoolVar(&opts.includePorts, "ports", false, "Include service's exposed ports in output graph")
cmd.Flags().BoolVar(&opts.includeNetworks, "networks", false, "Include service's attached networks in output graph")
cmd.Flags().BoolVar(&opts.includeImageName, "image", false, "Include service's image name in output graph")
cmd.Flags().IntVar(&indentationSize, "indentation-size", 1, "Number of tabs or spaces to use for indentation")
cmd.Flags().BoolVar(&useSpaces, "spaces", false, "If given, space character ' ' will be used to indent,\notherwise tab character '\\t' will be used")
return cmd
}
func runViz(ctx context.Context, dockerCli command.Cli, backend api.Service, opts *vizOptions) error {
_, _ = fmt.Fprintln(os.Stderr, "viz command is EXPERIMENTAL")
project, err := opts.ToProject(dockerCli, nil)
if err != nil {
return err
}
// build graph
graphStr, _ := backend.Viz(ctx, project, api.VizOptions{
IncludeNetworks: opts.includeNetworks,
IncludePorts: opts.includePorts,
IncludeImageName: opts.includeImageName,
Indentation: opts.indentationStr,
})
fmt.Println(graphStr)
return nil
}
// preferredIndentationStr returns a single string given the indentation preference
func preferredIndentationStr(size int, useSpace bool) (string, error) {
if size < 0 {
return "", fmt.Errorf("invalid indentation size: %d", size)
}
indentationStr := "\t"
if useSpace {
indentationStr = " "
}
return strings.Repeat(indentationStr, size), nil
}

92
cmd/compose/viz_test.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 (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPreferredIndentationStr(t *testing.T) {
type args struct {
size int
useSpace bool
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "should return '\\t\\t'",
args: args{
size: 2,
useSpace: false,
},
want: "\t\t",
wantErr: false,
},
{
name: "should return ' '",
args: args{
size: 4,
useSpace: true,
},
want: " ",
wantErr: false,
},
{
name: "should return ''",
args: args{
size: 0,
useSpace: false,
},
want: "",
wantErr: false,
},
{
name: "should return ''",
args: args{
size: 0,
useSpace: true,
},
want: "",
wantErr: false,
},
{
name: "should throw error because indentation size < 0",
args: args{
size: -1,
useSpace: false,
},
want: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := preferredIndentationStr(tt.args.size, tt.args.useSpace)
if tt.wantErr && assert.NotNilf(t, err, fmt.Sprintf("preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)) {
return
}
assert.Equalf(t, tt.want, got, "preferredIndentationStr(%v, %v)", tt.args.size, tt.args.useSpace)
})
}
}

73
cmd/compose/wait.go Normal file
View File

@@ -0,0 +1,73 @@
/*
Copyright 2023 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compose
import (
"context"
"os"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
"github.com/spf13/cobra"
)
type waitOptions struct {
*ProjectOptions
services []string
downProject bool
}
func waitCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
opts := waitOptions{
ProjectOptions: p,
}
var statusCode int64
var err error
cmd := &cobra.Command{
Use: "wait SERVICE [SERVICE...] [OPTIONS]",
Short: "Block until the first service container stops",
Args: cli.RequiresMinArgs(1),
RunE: Adapt(func(ctx context.Context, services []string) error {
opts.services = services
statusCode, err = runWait(ctx, dockerCli, backend, &opts)
return err
}),
PostRun: func(cmd *cobra.Command, args []string) {
os.Exit(int(statusCode))
},
}
cmd.Flags().BoolVar(&opts.downProject, "down-project", false, "Drops project when the first container stops")
return cmd
}
func runWait(ctx context.Context, dockerCli command.Cli, backend api.Service, opts *waitOptions) (int64, error) {
_, name, err := opts.projectOrName(dockerCli)
if err != nil {
return 0, err
}
return backend.Wait(ctx, name, api.WaitOptions{
Services: opts.services,
DownProjectOnContainerExit: opts.downProject,
})
}

View File

@@ -19,43 +19,94 @@ package compose
import (
"context"
"fmt"
"os"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/internal/locker"
"github.com/docker/compose/v2/pkg/api"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
type watchOptions struct {
*ProjectOptions
quiet bool
noUp bool
}
func watchCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
opts := watchOptions{
func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
watchOpts := watchOptions{
ProjectOptions: p,
}
buildOpts := buildOptions{
ProjectOptions: p,
}
cmd := &cobra.Command{
Use: "watch [SERVICE...]",
Short: "EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated",
Short: "Watch build context for service and rebuild/refresh containers when files are updated",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runWatch(ctx, backend, opts, args)
RunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
if cmd.Parent().Name() == "alpha" {
logrus.Warn("watch command is now available as a top level command")
}
return runWatch(ctx, dockerCli, backend, watchOpts, buildOpts, args)
}),
ValidArgsFunction: completeServiceNames(p),
ValidArgsFunction: completeServiceNames(dockerCli, p),
}
cmd.Flags().BoolVar(&opts.quiet, "quiet", false, "hide build output")
cmd.Flags().BoolVar(&watchOpts.quiet, "quiet", false, "hide build output")
cmd.Flags().BoolVar(&watchOpts.noUp, "no-up", false, "Do not build & start services before watching")
return cmd
}
func runWatch(ctx context.Context, backend api.Service, opts watchOptions, services []string) error {
fmt.Fprintln(os.Stderr, "watch command is EXPERIMENTAL")
project, err := opts.ToProject(nil)
func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, watchOpts watchOptions, buildOpts buildOptions, services []string) error {
project, err := watchOpts.ToProject(dockerCli, nil)
if err != nil {
return err
}
return backend.Watch(ctx, project, services, api.WatchOptions{})
if err := applyPlatforms(project, true); err != nil {
return err
}
build, err := buildOpts.toAPIBuildOptions(nil)
if err != nil {
return err
}
// validation done -- ensure we have the lockfile for this project before doing work
l, err := locker.NewPidfile(project.Name)
if err != nil {
return fmt.Errorf("cannot take exclusive lock for project %q: %w", project.Name, err)
}
if err := l.Lock(); err != nil {
return fmt.Errorf("cannot take exclusive lock for project %q: %w", project.Name, err)
}
if !watchOpts.noUp {
upOpts := api.UpOptions{
Create: api.CreateOptions{
Build: &build,
Services: services,
RemoveOrphans: false,
Recreate: api.RecreateDiverged,
RecreateDependencies: api.RecreateNever,
Inherit: true,
QuietPull: watchOpts.quiet,
},
Start: api.StartOptions{
Project: project,
Attach: nil,
CascadeStop: false,
Services: services,
},
}
if err := backend.Up(ctx, project, upOpts); err != nil {
return err
}
}
return backend.Watch(ctx, project, services, api.WatchOptions{
Build: build,
})
}

281
cmd/formatter/container.go Normal file
View File

@@ -0,0 +1,281 @@
/*
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 formatter
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
)
const (
defaultContainerTableFormat = "table {{.Name}}\t{{.Image}}\t{{.Command}}\t{{.Service}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}"
nameHeader = "NAME"
serviceHeader = "SERVICE"
commandHeader = "COMMAND"
runningForHeader = "CREATED"
mountsHeader = "MOUNTS"
localVolumes = "LOCAL VOLUMES"
networksHeader = "NETWORKS"
)
// NewContainerFormat returns a Format for rendering using a Context
func NewContainerFormat(source string, quiet bool, size bool) formatter.Format {
switch source {
case formatter.TableFormatKey, "": // table formatting is the default if none is set.
if quiet {
return formatter.DefaultQuietFormat
}
format := defaultContainerTableFormat
if size {
format += `\t{{.Size}}`
}
return formatter.Format(format)
case formatter.RawFormatKey:
if quiet {
return `container_id: {{.ID}}`
}
format := `container_id: {{.ID}}
image: {{.Image}}
command: {{.Command}}
created_at: {{.CreatedAt}}
state: {{- pad .State 1 0}}
status: {{- pad .Status 1 0}}
names: {{.Names}}
labels: {{- pad .Labels 1 0}}
ports: {{- pad .Ports 1 0}}
`
if size {
format += `size: {{.Size}}\n`
}
return formatter.Format(format)
default: // custom format
if quiet {
return formatter.DefaultQuietFormat
}
return formatter.Format(source)
}
}
// ContainerWrite renders the context for a list of containers
func ContainerWrite(ctx formatter.Context, containers []api.ContainerSummary) error {
render := func(format func(subContext formatter.SubContext) error) error {
for _, container := range containers {
err := format(&ContainerContext{trunc: ctx.Trunc, c: container})
if err != nil {
return err
}
}
return nil
}
return ctx.Write(NewContainerContext(), render)
}
// ContainerContext is a struct used for rendering a list of containers in a Go template.
type ContainerContext struct {
formatter.HeaderContext
trunc bool
c api.ContainerSummary
// FieldsUsed is used in the pre-processing step to detect which fields are
// used in the template. It's currently only used to detect use of the .Size
// field which (if used) automatically sets the '--size' option when making
// the API call.
FieldsUsed map[string]interface{}
}
// NewContainerContext creates a new context for rendering containers
func NewContainerContext() *ContainerContext {
containerCtx := ContainerContext{}
containerCtx.Header = formatter.SubHeaderContext{
"ID": formatter.ContainerIDHeader,
"Name": nameHeader,
"Service": serviceHeader,
"Image": formatter.ImageHeader,
"Command": commandHeader,
"CreatedAt": formatter.CreatedAtHeader,
"RunningFor": runningForHeader,
"Ports": formatter.PortsHeader,
"State": formatter.StateHeader,
"Status": formatter.StatusHeader,
"Size": formatter.SizeHeader,
"Labels": formatter.LabelsHeader,
}
return &containerCtx
}
// MarshalJSON makes ContainerContext implement json.Marshaler
func (c *ContainerContext) MarshalJSON() ([]byte, error) {
return formatter.MarshalJSON(c)
}
// ID returns the container's ID as a string. Depending on the `--no-trunc`
// option being set, the full or truncated ID is returned.
func (c *ContainerContext) ID() string {
if c.trunc {
return stringid.TruncateID(c.c.ID)
}
return c.c.ID
}
func (c *ContainerContext) Name() string {
return c.c.Name
}
// Names returns a comma-separated string of the container's names, with their
// slash (/) prefix stripped. Additional names for the container (related to the
// legacy `--link` feature) are omitted.
func (c *ContainerContext) Names() string {
names := formatter.StripNamePrefix(c.c.Names)
if c.trunc {
for _, name := range names {
if len(strings.Split(name, "/")) == 1 {
names = []string{name}
break
}
}
}
return strings.Join(names, ",")
}
func (c *ContainerContext) Service() string {
return c.c.Service
}
func (c *ContainerContext) Image() string {
return c.c.Image
}
func (c *ContainerContext) Command() string {
command := c.c.Command
if c.trunc {
command = formatter.Ellipsis(command, 20)
}
return strconv.Quote(command)
}
func (c *ContainerContext) CreatedAt() string {
return time.Unix(c.c.Created, 0).String()
}
func (c *ContainerContext) RunningFor() string {
createdAt := time.Unix(c.c.Created, 0)
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
}
func (c *ContainerContext) ExitCode() int {
return c.c.ExitCode
}
func (c *ContainerContext) State() string {
return c.c.State
}
func (c *ContainerContext) Status() string {
return c.c.Status
}
func (c *ContainerContext) Health() string {
return c.c.Health
}
func (c *ContainerContext) Publishers() api.PortPublishers {
return c.c.Publishers
}
func (c *ContainerContext) Ports() string {
var ports []types.Port
for _, publisher := range c.c.Publishers {
ports = append(ports, types.Port{
IP: publisher.URL,
PrivatePort: uint16(publisher.TargetPort),
PublicPort: uint16(publisher.PublishedPort),
Type: publisher.Protocol,
})
}
return formatter.DisplayablePorts(ports)
}
// Labels returns a comma-separated string of labels present on the container.
func (c *ContainerContext) Labels() string {
if c.c.Labels == nil {
return ""
}
var joinLabels []string
for k, v := range c.c.Labels {
joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v))
}
return strings.Join(joinLabels, ",")
}
// Label returns the value of the label with the given name or an empty string
// if the given label does not exist.
func (c *ContainerContext) Label(name string) string {
if c.c.Labels == nil {
return ""
}
return c.c.Labels[name]
}
// Mounts returns a comma-separated string of mount names present on the container.
// If the trunc option is set, names can be truncated (ellipsized).
func (c *ContainerContext) Mounts() string {
var mounts []string
for _, name := range c.c.Mounts {
if c.trunc {
name = formatter.Ellipsis(name, 15)
}
mounts = append(mounts, name)
}
return strings.Join(mounts, ",")
}
// LocalVolumes returns the number of volumes using the "local" volume driver.
func (c *ContainerContext) LocalVolumes() string {
return fmt.Sprintf("%d", c.c.LocalVolumes)
}
// Networks returns a comma-separated string of networks that the container is
// attached to.
func (c *ContainerContext) Networks() string {
return strings.Join(c.c.Networks, ",")
}
// Size returns the container's size and virtual size (e.g. "2B (virtual 21.5MB)")
func (c *ContainerContext) Size() string {
if c.FieldsUsed == nil {
c.FieldsUsed = map[string]interface{}{}
}
c.FieldsUsed["Size"] = struct{}{}
srw := units.HumanSizeWithPrecision(float64(c.c.SizeRw), 3)
sv := units.HumanSizeWithPrecision(float64(c.c.SizeRootFs), 3)
sf := srw
if c.c.SizeRootFs > 0 {
sf = fmt.Sprintf("%s (virtual %s)", srw, sv)
}
return sf
}

View File

@@ -23,8 +23,6 @@ import (
"strings"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
)
// Print prints formatted lists in different formats
@@ -67,7 +65,7 @@ func Print(toJSON interface{}, format string, outWriter io.Writer, writerFn func
_, _ = fmt.Fprintln(outWriter, outJSON)
}
default:
return errors.Wrapf(api.ErrParsingFailed, "format value %q could not be parsed", format)
return fmt.Errorf("format value %q could not be parsed: %w", format, api.ErrParsingFailed)
}
return nil
}

View File

@@ -23,6 +23,7 @@ import (
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/cmd/cmdtrace"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/cmd/compatibility"
@@ -38,14 +39,20 @@ func pluginMain() {
cmd := commands.RootCommand(dockerCli, serviceProxy)
originalPreRun := 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
}
// TODO(milas): add an env var to enable logging from the
// OTel components for debugging purposes
_ = cmdtrace.Setup(cmd, dockerCli, os.Args[1:])
if originalPreRun != nil {
return originalPreRun(cmd, args)
}
return nil
}
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return dockercli.StatusError{
StatusCode: compose.CommandSyntaxFailure.ExitCode,

21
codecov.yml Normal file
View File

@@ -0,0 +1,21 @@
coverage:
status:
project:
default:
informational: true
target: auto
threshold: 2%
patch:
default:
informational: true
comment:
require_changes: true
ignore:
- "packaging"
- "docs"
- "bin"
- "e2e"
- "pkg/e2e"
- "**/*_test.go"

View File

@@ -13,7 +13,8 @@
// limitations under the License.
variable "GO_VERSION" {
default = "1.20.0"
# default ARG value set in Dockerfile
default = null
}
variable "BUILD_TAGS" {
@@ -24,15 +25,21 @@ variable "DOCS_FORMATS" {
default = "md,yaml"
}
# Defines the output folder
# Defines the output folder to override the default behavior.
# See Makefile for details, this is generally only useful for
# the packaging scripts and care should be taken to not break
# them.
variable "DESTDIR" {
default = ""
}
function "bindir" {
function "outdir" {
params = [defaultdir]
result = DESTDIR != "" ? DESTDIR : "./bin/${defaultdir}"
result = DESTDIR != "" ? DESTDIR : "${defaultdir}"
}
# Special target: https://github.com/docker/metadata-action#bake-definition
target "meta-helper" {}
target "_common" {
args = {
GO_VERSION = GO_VERSION
@@ -80,13 +87,23 @@ target "vendor-update" {
target "test" {
inherits = ["_common"]
target = "test-coverage"
output = [bindir("coverage")]
output = [outdir("./bin/coverage/unit")]
}
target "binary-with-coverage" {
inherits = ["_common"]
target = "binary"
args = {
BUILD_FLAGS = "-cover -covermode=atomic"
}
output = [outdir("./bin/build")]
platforms = ["local"]
}
target "binary" {
inherits = ["_common"]
target = "binary"
output = [bindir("build")]
output = [outdir("./bin/build")]
platforms = ["local"]
}
@@ -110,7 +127,7 @@ target "binary-cross" {
target "release" {
inherits = ["binary-cross"]
target = "release"
output = [bindir("release")]
output = [outdir("./bin/release")]
}
target "docs-validate" {
@@ -124,3 +141,8 @@ target "docs-update" {
target = "docs-update"
output = ["./docs"]
}
target "image-cross" {
inherits = ["meta-helper", "binary-cross"]
output = ["type=image"]
}

View File

@@ -1,38 +1,40 @@
# docker compose
<!---MARKER_GEN_START-->
Docker Compose
Define and run multi-container applications with Docker.
### Subcommands
| Name | Description |
|:--------------------------------|:------------------------------------------------------------------------|
| [`alpha`](compose_alpha.md) | Experimental commands |
| [`build`](compose_build.md) | Build or rebuild services |
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
| [`create`](compose_create.md) | Creates containers for a service. |
| [`down`](compose_down.md) | Stop and remove containers, networks |
| [`events`](compose_events.md) | Receive real time events from containers. |
| [`exec`](compose_exec.md) | Execute a command in a running container. |
| [`images`](compose_images.md) | List images used by the created containers |
| [`kill`](compose_kill.md) | Force stop service containers. |
| [`logs`](compose_logs.md) | View output from containers |
| [`ls`](compose_ls.md) | List running compose projects |
| [`pause`](compose_pause.md) | Pause services |
| [`port`](compose_port.md) | Print the public port for a port binding. |
| [`ps`](compose_ps.md) | List containers |
| [`pull`](compose_pull.md) | Pull service images |
| [`push`](compose_push.md) | Push service images |
| [`restart`](compose_restart.md) | Restart service containers |
| [`rm`](compose_rm.md) | Removes stopped service containers |
| [`run`](compose_run.md) | Run a one-off command on a service. |
| [`start`](compose_start.md) | Start services |
| [`stop`](compose_stop.md) | Stop services |
| [`top`](compose_top.md) | Display the running processes |
| [`unpause`](compose_unpause.md) | Unpause services |
| [`up`](compose_up.md) | Create and start containers |
| [`version`](compose_version.md) | Show the Docker Compose version information |
| Name | Description |
|:--------------------------------|:--------------------------------------------------------------------------------------|
| [`build`](compose_build.md) | Build or rebuild services |
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
| [`create`](compose_create.md) | Creates containers for a service. |
| [`down`](compose_down.md) | Stop and remove containers, networks |
| [`events`](compose_events.md) | Receive real time events from containers. |
| [`exec`](compose_exec.md) | Execute a command in a running container. |
| [`images`](compose_images.md) | List images used by the created containers |
| [`kill`](compose_kill.md) | Force stop service containers. |
| [`logs`](compose_logs.md) | View output from containers |
| [`ls`](compose_ls.md) | List running compose projects |
| [`pause`](compose_pause.md) | Pause services |
| [`port`](compose_port.md) | Print the public port for a port binding. |
| [`ps`](compose_ps.md) | List containers |
| [`pull`](compose_pull.md) | Pull service images |
| [`push`](compose_push.md) | Push service images |
| [`restart`](compose_restart.md) | Restart service containers |
| [`rm`](compose_rm.md) | Removes stopped service containers |
| [`run`](compose_run.md) | Run a one-off command on a service. |
| [`scale`](compose_scale.md) | Scale services |
| [`start`](compose_start.md) | Start services |
| [`stop`](compose_stop.md) | Stop services |
| [`top`](compose_top.md) | Display the running processes |
| [`unpause`](compose_unpause.md) | Unpause services |
| [`up`](compose_up.md) | Create and start containers |
| [`version`](compose_version.md) | Show the Docker Compose version information |
| [`wait`](compose_wait.md) | Block until the first service container stops |
| [`watch`](compose_watch.md) | Watch build context for service and rebuild/refresh containers when files are updated |
### Options
@@ -41,10 +43,12 @@ Docker Compose
|:-----------------------|:--------------|:--------|:----------------------------------------------------------------------------------------------------|
| `--ansi` | `string` | `auto` | Control when to print ANSI control characters ("never"\|"always"\|"auto") |
| `--compatibility` | | | Run compose in backward compatibility mode |
| `--env-file` | `string` | | Specify an alternate environment file. |
| `--dry-run` | | | Execute command in dry run mode |
| `--env-file` | `stringArray` | | Specify an alternate environment file. |
| `-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, 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 |
@@ -53,7 +57,7 @@ Docker Compose
## Description
You can use compose subcommand, `docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]`, to build and manage
You can use the compose subcommand, `docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]`, to build and manage
multiple services in Docker containers.
### Use `-f` to specify the name and path of one or more Compose files
@@ -115,12 +119,19 @@ $ docker compose -f ~/sandbox/rails/compose.yaml pull db
### Use `-p` to specify a project name
Each configuration has a project name. If you supply a `-p` flag, you can specify a project name. If you dont
specify the flag, Compose uses the current directory name.
Project name can also be set by `COMPOSE_PROJECT_NAME` environment variable.
Many Compose subcommands can be run without a Compose file by passing
the project name.
Each configuration has a project name. Compose sets the project name using
the following mechanisms, in order of precedence:
- The `-p` command line flag
- The `COMPOSE_PROJECT_NAME` environment variable
- The top level `name:` variable from the config file (or the last `name:`
from a series of config files specified using `-f`)
- The `basename` of the project directory containing the config file (or
containing the first config file specified using `-f`)
- The `basename` of the current directory if no config file is specified
Project names must contain only lowercase letters, decimal digits, dashes,
and underscores, and must begin with a lowercase letter or decimal digit. If
the `basename` of the project directory or current directory violates this
constraint, you must use one of the other mechanisms.
```console
$ docker compose -p my_project ps -a
@@ -135,16 +146,16 @@ demo_1 | 64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.095 ms
### Use profiles to enable optional services
Use `--profile` to specify one or more active profiles
Calling `docker compose --profile frontend up` will start the services with the profile `frontend` and services
Calling `docker compose --profile frontend up` starts the services with the profile `frontend` and services
without any specified profiles.
You can also enable multiple profiles, e.g. with `docker compose --profile frontend --profile debug up` the profiles `frontend` and `debug` will be enabled.
You can also enable multiple profiles, e.g. with `docker compose --profile frontend --profile debug up` the profiles `frontend` and `debug` is enabled.
Profiles can also be set by `COMPOSE_PROFILES` environment variable.
### Configuring parallelism
Use `--parallel` to specify the maximum level of parallelism for concurrent engine calls.
Calling `docker compose --parallel 1 pull` will pull the pullable images defined in the Compose file
Calling `docker compose --parallel 1 pull` pulls the pullable images defined in the Compose file
one at a time. This can also be used to control build concurrency.
Parallelism can also be set by the `COMPOSE_PARALLEL_LIMIT` environment variable.
@@ -160,5 +171,30 @@ and `COMPOSE_PARALLEL_LIMIT` does the same as the `--parallel` flag.
If flags are explicitly set on the command line, the associated environment variable is ignored.
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` will stop docker compose from detecting orphaned
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` stops docker compose from detecting orphaned
containers for the project.
### Use Dry Run mode to test your command
Use `--dry-run` flag to test a command without changing your application stack state.
Dry Run mode shows you all the steps Compose applies when executing a command, for example:
```console
$ docker compose --dry-run up --build -d
[+] Pulling 1/1
✔ DRY-RUN MODE - db Pulled 0.9s
[+] Running 10/8
✔ DRY-RUN MODE - build service backend 0.0s
✔ DRY-RUN MODE - ==> ==> writing image dryRun-754a08ddf8bcb1cf22f310f09206dd783d42f7dd 0.0s
✔ DRY-RUN MODE - ==> ==> naming to nginx-golang-mysql-backend 0.0s
✔ DRY-RUN MODE - Network nginx-golang-mysql_default Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Healthy 0.5s
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Started 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Started Started
```
From the example above, you can see that the first step is to pull the image defined by `db` service, then build the `backend` service.
Next, the containers are created. The `db` service is started, and the `backend` and `proxy` wait until the `db` service is healthy before starting.
Dry Run mode works with almost all commands. You cannot use Dry Run mode with a command that doesn't change the state of a Compose stack such as `ps`, `ls`, `logs` for example.

View File

@@ -5,12 +5,18 @@ Experimental commands
### Subcommands
| Name | Description |
|:--------------------------------------|:-----------------------------------------------------------------------------------------------------|
| [`dry-run`](compose_alpha_dry-run.md) | EXPERIMENTAL - Dry run command allow you to test a command without applying changes |
| [`watch`](compose_alpha_watch.md) | EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated |
| Name | Description |
|:----------------------------------|:-----------------------------------------------------------------------------------------------------|
| [`viz`](compose_alpha_viz.md) | EXPERIMENTAL - Generate a graphviz graph from your compose file |
| [`watch`](compose_alpha_watch.md) | EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated |
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -1,7 +1,7 @@
# docker compose alpha dry-run
<!---MARKER_GEN_START-->
EXPERIMENTAL - Dry run command allow you to test a command without applying changes
Dry run command allows you to test a command without applying changes.
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,15 @@
# docker compose alpha publish
<!---MARKER_GEN_START-->
Publish compose application
### Options
| Name | Type | Default | Description |
|:--------------------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--resolve-image-digests` | | | Pin image tags to digests. |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,15 @@
# docker compose alpha scale
<!---MARKER_GEN_START-->
Scale services.
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--no-deps` | | | Don't start linked services |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,19 @@
# docker compose alpha viz
<!---MARKER_GEN_START-->
EXPERIMENTAL - Generate a graphviz graph from your compose file
### Options
| Name | Type | Default | Description |
|:---------------------|:------|:--------|:---------------------------------------------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--image` | | | Include service's image name in output graph |
| `--indentation-size` | `int` | `1` | Number of tabs or spaces to use for indentation |
| `--networks` | | | Include service's attached networks in output graph |
| `--ports` | | | Include service's exposed ports in output graph |
| `--spaces` | | | If given, space character ' ' will be used to indent,<br>otherwise tab character '\t' will be used |
<!---MARKER_GEN_END-->

View File

@@ -1,13 +1,15 @@
# docker compose alpha watch
<!---MARKER_GEN_START-->
EXPERIMENTAL - Watch build context for service and rebuild/refresh containers when files are updated
Watch build context for service and rebuild/refresh containers when files are updated
### Options
| Name | Type | Default | Description |
|:----------|:-----|:--------|:------------------|
| `--quiet` | | | hide build output |
| Name | Type | Default | Description |
|:------------|:-----|:--------|:----------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--no-up` | | | Do not build & start services before watching |
| `--quiet` | | | hide build output |
<!---MARKER_GEN_END-->

View File

@@ -5,15 +5,17 @@ Build or rebuild services
### Options
| Name | Type | Default | Description |
|:----------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------|
| `--build-arg` | `stringArray` | | Set build-time variables for services. |
| `--no-cache` | | | Do not use cache when building the image |
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, quiet) |
| `--pull` | | | Always attempt to pull a newer version of the image. |
| `--push` | | | Push service images. |
| `-q`, `--quiet` | | | Don't print anything to STDOUT |
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
| Name | Type | Default | Description |
|:-----------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------|
| `--build-arg` | `stringArray` | | Set build-time variables for services. |
| `--builder` | `string` | | Set builder to use. |
| `--dry-run` | | | Execute command in dry run mode |
| `-m`, `--memory` | `bytes` | `0` | Set memory limit for the build container. Not supported by BuildKit. |
| `--no-cache` | | | Do not use cache when building the image |
| `--pull` | | | Always attempt to pull a newer version of the image. |
| `--push` | | | Push service images. |
| `-q`, `--quiet` | | | Don't print anything to STDOUT |
| `--ssh` | `string` | | Set SSH authentications used when building service images. (use 'default' for using your default SSH Agent) |
<!---MARKER_GEN_END-->

View File

@@ -11,12 +11,14 @@ Parse, resolve and render compose file in canonical format
| Name | Type | Default | Description |
|:--------------------------|:---------|:--------|:----------------------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--format` | `string` | `yaml` | Format the output. Values: [yaml \| json] |
| `--hash` | `string` | | Print the service config hash, one per line. |
| `--images` | | | Print the image names, one per line. |
| `--no-consistency` | | | Don't check model consistency - warning: may produce invalid Compose output |
| `--no-interpolate` | | | Don't interpolate environment variables. |
| `--no-normalize` | | | Don't normalize compose model. |
| `--no-path-resolution` | | | Don't resolve file paths. |
| `-o`, `--output` | `string` | | Save to file (default to stdout) |
| `--profiles` | | | Print the profile names, one per line. |
| `-q`, `--quiet` | | | Only validate the configuration, don't print anything. |
@@ -29,6 +31,6 @@ Parse, resolve and render compose file in canonical format
## Description
`docker compose config` renders the actual data model to be applied on the Docker engine.
it merges the Compose files set by `-f` flags, resolves variables in the Compose file, and expands short-notation into
`docker compose config` renders the actual data model to be applied on the Docker Engine.
It merges the Compose files set by `-f` flags, resolves variables in the Compose file, and expands short-notation into
the canonical format.

View File

@@ -5,11 +5,12 @@ Copy files/folders between a service container and the local filesystem
### Options
| Name | Type | Default | Description |
|:----------------------|:------|:--------|:----------------------------------------------------------------------|
| `-a`, `--archive` | | | Archive mode (copy all uid/gid information) |
| `-L`, `--follow-link` | | | Always follow symbol link in SRC_PATH |
| `--index` | `int` | `0` | Index of the container if there are multiple instances of a service . |
| Name | Type | Default | Description |
|:----------------------|:------|:--------|:--------------------------------------------------------|
| `-a`, `--archive` | | | Archive mode (copy all uid/gid information) |
| `--dry-run` | | | Execute command in dry run mode |
| `-L`, `--follow-link` | | | Always follow symbol link in SRC_PATH |
| `--index` | `int` | `0` | index of the container if service has multiple replicas |
<!---MARKER_GEN_END-->

View File

@@ -5,15 +5,16 @@ Creates containers for a service.
### Options
| Name | Type | Default | Description |
|:-------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------|
| `--build` | | | Build images before starting containers. |
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
| `--no-build` | | | Don't build an image, even if it's missing. |
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--pull` | `string` | `missing` | Pull image before running ("always"\|"missing"\|"never") |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
| Name | Type | Default | Description |
|:-------------------|:--------------|:---------|:----------------------------------------------------------------------------------------------|
| `--build` | | | Build images before starting containers. |
| `--dry-run` | | | Execute command in dry run mode |
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
| `--no-build` | | | Don't build an image, even if it's policy. |
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never"\|"build") |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
<!---MARKER_GEN_END-->

View File

@@ -7,10 +7,11 @@ Stop and remove containers, networks
| Name | Type | Default | Description |
|:-------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `--rmi` | `string` | | Remove images used by services. "local" remove only images that don't have a custom tag ("local"\|"all") |
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
| `-v`, `--volumes` | | | Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers. |
| `-t`, `--timeout` | `int` | `0` | Specify a shutdown timeout in seconds |
| `-v`, `--volumes` | | | Remove named volumes declared in the "volumes" section of the Compose file and anonymous volumes attached to containers. |
<!---MARKER_GEN_END-->
@@ -21,12 +22,12 @@ Stops containers and removes containers, networks, volumes, and images created b
By default, the only things removed are:
- Containers for services defined in the Compose file
- Networks defined in the networks section of the Compose file
- The default network, if one is used
- Containers for services defined in the Compose file.
- Networks defined in the networks section of the Compose file.
- The default network, if one is used.
Networks and volumes defined as external are never removed.
Anonymous volumes are not removed by default. However, as they dont have a stable name, they will not be automatically
Anonymous volumes are not removed by default. However, as they dont have a stable name, they are not automatically
mounted by a subsequent `up`. For data that needs to persist between updates, use explicit paths as bind mounts or
named volumes.

View File

@@ -5,9 +5,10 @@ Receive real time events from containers.
### Options
| Name | Type | Default | Description |
|:---------|:-----|:--------|:------------------------------------------|
| `--json` | | | Output events as a stream of json objects |
| Name | Type | Default | Description |
|:------------|:-----|:--------|:------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--json` | | | Output events as a stream of json objects |
<!---MARKER_GEN_END-->

View File

@@ -5,15 +5,16 @@ Execute a command in a running container.
### Options
| Name | Type | Default | Description |
|:------------------|:--------------|:--------|:----------------------------------------------------------------------------------|
| `-d`, `--detach` | | | Detached mode: Run command in the background. |
| `-e`, `--env` | `stringArray` | | Set environment variables |
| `--index` | `int` | `1` | index of the container if there are multiple instances of a service [default: 1]. |
| `-T`, `--no-TTY` | | | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
| `--privileged` | | | 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. |
| Name | Type | Default | Description |
|:------------------|:--------------|:--------|:---------------------------------------------------------------------------------|
| `-d`, `--detach` | | | Detached mode: Run command in the background. |
| `--dry-run` | | | 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` | | | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
| `--privileged` | | | 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. |
<!---MARKER_GEN_END-->

View File

@@ -7,6 +7,7 @@ List images used by the created containers
| Name | Type | Default | Description |
|:----------------|:---------|:--------|:--------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--format` | `string` | `table` | Format the output. Values: [table \| json]. |
| `-q`, `--quiet` | | | Only display IDs |

View File

@@ -7,6 +7,7 @@ Force stop service containers.
| Name | Type | Default | Description |
|:-------------------|:---------|:----------|:----------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `-s`, `--signal` | `string` | `SIGKILL` | SIGNAL to send to the container. |

View File

@@ -7,6 +7,7 @@ View output from containers
| Name | Type | Default | Description |
|:---------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `-f`, `--follow` | | | Follow log output. |
| `--no-color` | | | Produce monochrome output. |
| `--no-log-prefix` | | | Don't print prefix in logs. |

View File

@@ -8,6 +8,7 @@ List running compose projects
| Name | Type | Default | Description |
|:----------------|:---------|:--------|:--------------------------------------------|
| `-a`, `--all` | | | Show all stopped Compose projects |
| `--dry-run` | | | Execute command in dry run mode |
| `--filter` | `filter` | | Filter output based on conditions provided. |
| `--format` | `string` | `table` | Format the output. Values: [table \| json]. |
| `-q`, `--quiet` | | | Only display IDs. |

View File

@@ -3,6 +3,12 @@
<!---MARKER_GEN_START-->
Pause services
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -7,7 +7,8 @@ Print the public port for a port binding.
| Name | Type | Default | Description |
|:-------------|:---------|:--------|:--------------------------------------------------------|
| `--index` | `int` | `1` | index of the container if service has multiple replicas |
| `--dry-run` | | | Execute command in dry run mode |
| `--index` | `int` | `0` | index of the container if service has multiple replicas |
| `--protocol` | `string` | `tcp` | tcp or udp |

View File

@@ -5,14 +5,16 @@ List containers
### Options
| Name | Type | Default | Description |
|:----------------------|:--------------|:--------|:--------------------------------------------------------------------------------------------------------------|
| `-a`, `--all` | | | Show all stopped containers (including those created by the run command) |
| [`--filter`](#filter) | `string` | | Filter services by a property (supported filters: status). |
| [`--format`](#format) | `string` | `table` | Format the output. Values: [table \| json] |
| `-q`, `--quiet` | | | Only display IDs |
| `--services` | | | Display services |
| [`--status`](#status) | `stringArray` | | Filter services by status. Values: [paused \| restarting \| removing \| running \| dead \| created \| exited] |
| Name | Type | Default | Description |
|:----------------------|:--------------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-a`, `--all` | | | Show all stopped containers (including those created by the run command) |
| `--dry-run` | | | Execute command in dry run mode |
| [`--filter`](#filter) | `string` | | Filter services by a property (supported filters: status). |
| [`--format`](#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 |
| `--no-trunc` | | | Don't truncate output |
| `-q`, `--quiet` | | | Only display IDs |
| `--services` | | | Display services |
| [`--status`](#status) | `stringArray` | | Filter services by status. Values: [paused \| restarting \| removing \| running \| dead \| created \| exited] |
<!---MARKER_GEN_END-->
@@ -27,7 +29,7 @@ NAME IMAGE COMMAND SERVICE CREATED STATUS
example-foo-1 alpine "/entrypoint.…" foo 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp
```
By default, only running containers are shown. `--all` flag can be used to include stopped containers
By default, only running containers are shown. `--all` flag can be used to include stopped containers.
```console
$ docker compose ps --all
@@ -51,7 +53,7 @@ $ docker compose ps --format json
```
The JSON output allows you to use the information in other tools for further
processing, for example, using the [`jq` utility](https://stedolan.github.io/jq/){:target="_blank" rel="noopener" class="_"}
processing, for example, using the [`jq` utility](https://stedolan.github.io/jq/)
to pretty-print the JSON:
```console

View File

@@ -5,12 +5,14 @@ Pull service images
### Options
| Name | Type | Default | Description |
|:-------------------------|:-----|:--------|:--------------------------------------------------------|
| `--ignore-buildable` | | | Ignore images that can be built. |
| `--ignore-pull-failures` | | | Pull what it can and ignores images with pull failures. |
| `--include-deps` | | | Also pull services declared as dependencies. |
| `-q`, `--quiet` | | | Pull without printing progress information. |
| Name | Type | Default | Description |
|:-------------------------|:---------|:--------|:--------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--ignore-buildable` | | | Ignore images that can be built. |
| `--ignore-pull-failures` | | | Pull what it can and ignores images with pull failures. |
| `--include-deps` | | | Also pull services declared as dependencies. |
| `--policy` | `string` | | Apply pull policy ("missing"\|"always"). |
| `-q`, `--quiet` | | | Pull without printing progress information. |
<!---MARKER_GEN_END-->
@@ -23,7 +25,7 @@ those images.
## Examples
suppose you have this `compose.yaml`:
Consider the following `compose.yaml`:
```yaml
services:
@@ -64,5 +66,4 @@ $ docker compose pull db
⠹ c8752d5b785c Waiting 9.3s
```
`docker compose pull` will try to pull image for services with a build section. If pull fails, it will let
user know this service image MUST be built. You can skip this by setting `--ignore-buildable` flag
`docker compose pull` tries to pull image for services with a build section. If pull fails, it lets you know this service image must be built. You can skip this by setting `--ignore-buildable` flag.

View File

@@ -7,6 +7,7 @@ Push service images
| Name | Type | Default | Description |
|:-------------------------|:-----|:--------|:-------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--ignore-push-failures` | | | Push what it can and ignores images with push failures |
| `--include-deps` | | | Also push images of services declared as dependencies |
| `-q`, `--quiet` | | | Push without printing progress information |

View File

@@ -7,7 +7,9 @@ Restart service containers
| Name | Type | Default | Description |
|:------------------|:------|:--------|:--------------------------------------|
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
| `--dry-run` | | | Execute command in dry run mode |
| `--no-deps` | | | Don't restart dependent services. |
| `-t`, `--timeout` | `int` | `0` | Specify a shutdown timeout in seconds |
<!---MARKER_GEN_END-->
@@ -21,6 +23,6 @@ after running this command. For example, changes to environment variables (which
after a container is built, but before the container's command is executed) are not updated
after restarting.
If you are looking to configure a service's restart policy, please refer to
If you are looking to configure a service's restart policy, refer to
[restart](https://github.com/compose-spec/compose-spec/blob/master/spec.md#restart)
or [restart_policy](https://github.com/compose-spec/compose-spec/blob/master/deploy.md#restart_policy).

View File

@@ -12,6 +12,7 @@ Any data which is not in a volume will be lost.
| Name | Type | Default | Description |
|:------------------|:-----|:--------|:----------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `-f`, `--force` | | | Don't ask to confirm removal |
| `-s`, `--stop` | | | Stop the containers, if required, before removing |
| `-v`, `--volumes` | | | Remove any anonymous volumes attached to containers |

View File

@@ -8,7 +8,10 @@ Run a one-off command on a service.
| Name | Type | Default | Description |
|:----------------------|:--------------|:--------|:----------------------------------------------------------------------------------|
| `--build` | | | Build image before starting container. |
| `--cap-add` | `list` | | Add Linux capabilities |
| `--cap-drop` | `list` | | Drop Linux capabilities |
| `-d`, `--detach` | | | Run container in background and print container ID |
| `--dry-run` | | | Execute command in dry run mode |
| `--entrypoint` | `string` | | Override the entrypoint of the image |
| `-e`, `--env` | `stringArray` | | Set environment variables |
| `-i`, `--interactive` | | | Keep STDIN open even if not attached. |
@@ -33,7 +36,7 @@ Run a one-off command on a service.
Runs a one-time command against a service.
the following command starts the `web` service and runs `bash` as its command:
The following command starts the `web` service and runs `bash` as its command:
```console
$ docker compose run web bash

View File

@@ -0,0 +1,15 @@
# docker compose scale
<!---MARKER_GEN_START-->
Scale services
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--no-deps` | | | Don't start linked services. |
<!---MARKER_GEN_END-->

View File

@@ -3,6 +3,12 @@
<!---MARKER_GEN_START-->
Start services
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -7,7 +7,8 @@ Stop services
| Name | Type | Default | Description |
|:------------------|:------|:--------|:--------------------------------------|
| `-t`, `--timeout` | `int` | `10` | Specify a shutdown timeout in seconds |
| `--dry-run` | | | Execute command in dry run mode |
| `-t`, `--timeout` | `int` | `0` | Specify a shutdown timeout in seconds |
<!---MARKER_GEN_END-->

View File

@@ -3,6 +3,12 @@
<!---MARKER_GEN_START-->
Display the running processes
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -3,6 +3,12 @@
<!---MARKER_GEN_START-->
Unpause services
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:--------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -5,31 +5,33 @@ Create and start containers
### Options
| Name | Type | Default | Description |
|:-----------------------------|:--------------|:----------|:---------------------------------------------------------------------------------------------------------|
| `--abort-on-container-exit` | | | Stops all containers if any container was stopped. Incompatible with -d |
| `--always-recreate-deps` | | | Recreate dependent containers. Incompatible with --no-recreate. |
| `--attach` | `stringArray` | | Attach to service output. |
| `--attach-dependencies` | | | Attach to dependent containers. |
| `--build` | | | Build images before starting containers. |
| `-d`, `--detach` | | | Detached mode: Run containers in the background |
| `--exit-code-from` | `string` | | Return the exit code of the selected service container. Implies --abort-on-container-exit |
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
| `--no-attach` | `stringArray` | | Don't attach to specified service. |
| `--no-build` | | | Don't build an image, even if it's missing. |
| `--no-color` | | | Produce monochrome output. |
| `--no-deps` | | | Don't start linked services. |
| `--no-log-prefix` | | | Don't print prefix in logs. |
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--no-start` | | | Don't start the services after creating them. |
| `--pull` | `string` | `missing` | Pull image before running ("always"\|"missing"\|"never") |
| `--quiet-pull` | | | Pull without printing progress information. |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `-V`, `--renew-anon-volumes` | | | Recreate anonymous volumes instead of retrieving data from the previous containers. |
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
| `-t`, `--timeout` | `int` | `10` | Use this timeout in seconds for container shutdown when attached or when containers are already running. |
| `--timestamps` | | | Show timestamps. |
| `--wait` | | | Wait for services to be running\|healthy. Implies detached mode. |
| Name | Type | Default | Description |
|:-----------------------------|:--------------|:---------|:---------------------------------------------------------------------------------------------------------|
| `--abort-on-container-exit` | | | Stops all containers if any container was stopped. Incompatible with -d |
| `--always-recreate-deps` | | | Recreate dependent containers. Incompatible with --no-recreate. |
| `--attach` | `stringArray` | | Restrict attaching to the specified services. Incompatible with --attach-dependencies. |
| `--attach-dependencies` | | | Automatically attach to log output of dependent services. |
| `--build` | | | Build images before starting containers. |
| `-d`, `--detach` | | | Detached mode: Run containers in the background |
| `--dry-run` | | | Execute command in dry run mode |
| `--exit-code-from` | `string` | | Return the exit code of the selected service container. Implies --abort-on-container-exit |
| `--force-recreate` | | | Recreate containers even if their configuration and image haven't changed. |
| `--no-attach` | `stringArray` | | Do not attach (stream logs) to the specified services. |
| `--no-build` | | | Don't build an image, even if it's policy. |
| `--no-color` | | | Produce monochrome output. |
| `--no-deps` | | | Don't start linked services. |
| `--no-log-prefix` | | | Don't print prefix in logs. |
| `--no-recreate` | | | If containers already exist, don't recreate them. Incompatible with --force-recreate. |
| `--no-start` | | | Don't start the services after creating them. |
| `--pull` | `string` | `policy` | Pull image before running ("always"\|"missing"\|"never") |
| `--quiet-pull` | | | Pull without printing progress information. |
| `--remove-orphans` | | | Remove containers for services not defined in the Compose file. |
| `-V`, `--renew-anon-volumes` | | | Recreate anonymous volumes instead of retrieving data from the previous containers. |
| `--scale` | `stringArray` | | Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. |
| `-t`, `--timeout` | `int` | `0` | Use this timeout in seconds for container shutdown when attached or when containers are already running. |
| `--timestamps` | | | Show timestamps. |
| `--wait` | | | Wait for services to be running\|healthy. Implies detached mode. |
| `--wait-timeout` | `int` | `0` | Maximum duration to wait for the project to be running\|healthy. |
<!---MARKER_GEN_END-->

View File

@@ -7,6 +7,7 @@ Show the Docker Compose version information
| Name | Type | Default | Description |
|:-----------------|:---------|:--------|:---------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `-f`, `--format` | `string` | | Format the output. Values: [pretty \| json]. (Default: pretty) |
| `--short` | | | Shows only Compose's version number. |

View File

@@ -0,0 +1,15 @@
# docker compose wait
<!---MARKER_GEN_START-->
Block until the first service container stops
### Options
| Name | Type | Default | Description |
|:-----------------|:-----|:--------|:---------------------------------------------|
| `--down-project` | | | Drops project when the first container stops |
| `--dry-run` | | | Execute command in dry run mode |
<!---MARKER_GEN_END-->

View File

@@ -0,0 +1,16 @@
# docker compose watch
<!---MARKER_GEN_START-->
Watch build context for service and rebuild/refresh containers when files are updated
### Options
| Name | Type | Default | Description |
|:------------|:-----|:--------|:----------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode |
| `--no-up` | | | Do not build & start services before watching |
| `--quiet` | | | hide build output |
<!---MARKER_GEN_END-->

View File

@@ -1,7 +1,7 @@
command: docker compose
short: Docker Compose
long: |-
You can use compose subcommand, `docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]`, to build and manage
You can use the compose subcommand, `docker compose [-f <arg>...] [options] [COMMAND] [ARGS...]`, to build and manage
multiple services in Docker containers.
### Use `-f` to specify the name and path of one or more Compose files
@@ -63,12 +63,19 @@ long: |-
### Use `-p` to specify a project name
Each configuration has a project name. If you supply a `-p` flag, you can specify a project name. If you dont
specify the flag, Compose uses the current directory name.
Project name can also be set by `COMPOSE_PROJECT_NAME` environment variable.
Many Compose subcommands can be run without a Compose file by passing
the project name.
Each configuration has a project name. Compose sets the project name using
the following mechanisms, in order of precedence:
- The `-p` command line flag
- The `COMPOSE_PROJECT_NAME` environment variable
- The top level `name:` variable from the config file (or the last `name:`
from a series of config files specified using `-f`)
- The `basename` of the project directory containing the config file (or
containing the first config file specified using `-f`)
- The `basename` of the current directory if no config file is specified
Project names must contain only lowercase letters, decimal digits, dashes,
and underscores, and must begin with a lowercase letter or decimal digit. If
the `basename` of the project directory or current directory violates this
constraint, you must use one of the other mechanisms.
```console
$ docker compose -p my_project ps -a
@@ -83,16 +90,16 @@ long: |-
### Use profiles to enable optional services
Use `--profile` to specify one or more active profiles
Calling `docker compose --profile frontend up` will start the services with the profile `frontend` and services
Calling `docker compose --profile frontend up` starts the services with the profile `frontend` and services
without any specified profiles.
You can also enable multiple profiles, e.g. with `docker compose --profile frontend --profile debug up` the profiles `frontend` and `debug` will be enabled.
You can also enable multiple profiles, e.g. with `docker compose --profile frontend --profile debug up` the profiles `frontend` and `debug` is enabled.
Profiles can also be set by `COMPOSE_PROFILES` environment variable.
### Configuring parallelism
Use `--parallel` to specify the maximum level of parallelism for concurrent engine calls.
Calling `docker compose --parallel 1 pull` will pull the pullable images defined in the Compose file
Calling `docker compose --parallel 1 pull` pulls the pullable images defined in the Compose file
one at a time. This can also be used to control build concurrency.
Parallelism can also be set by the `COMPOSE_PARALLEL_LIMIT` environment variable.
@@ -108,8 +115,33 @@ long: |-
If flags are explicitly set on the command line, the associated environment variable is ignored.
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` will stop docker compose from detecting orphaned
Setting the `COMPOSE_IGNORE_ORPHANS` environment variable to `true` stops docker compose from detecting orphaned
containers for the project.
### Use Dry Run mode to test your command
Use `--dry-run` flag to test a command without changing your application stack state.
Dry Run mode shows you all the steps Compose applies when executing a command, for example:
```console
$ docker compose --dry-run up --build -d
[+] Pulling 1/1
✔ DRY-RUN MODE - db Pulled 0.9s
[+] Running 10/8
✔ DRY-RUN MODE - build service backend 0.0s
✔ DRY-RUN MODE - ==> ==> writing image dryRun-754a08ddf8bcb1cf22f310f09206dd783d42f7dd 0.0s
✔ DRY-RUN MODE - ==> ==> naming to nginx-golang-mysql-backend 0.0s
✔ DRY-RUN MODE - Network nginx-golang-mysql_default Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Created 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-db-1 Healthy 0.5s
✔ DRY-RUN MODE - Container nginx-golang-mysql-backend-1 Started 0.0s
✔ DRY-RUN MODE - Container nginx-golang-mysql-proxy-1 Started Started
```
From the example above, you can see that the first step is to pull the image defined by `db` service, then build the `backend` service.
Next, the containers are created. The `db` service is started, and the `backend` and `proxy` wait until the `db` service is healthy before starting.
Dry Run mode works with almost all commands. You cannot use Dry Run mode with a command that doesn't change the state of a Compose stack such as `ps`, `ls`, `logs` for example.
usage: docker compose
pname: docker
plink: docker.yaml
@@ -133,12 +165,15 @@ cname:
- docker compose restart
- docker compose rm
- docker compose run
- docker compose scale
- docker compose start
- docker compose stop
- docker compose top
- docker compose unpause
- docker compose up
- docker compose version
- docker compose wait
- docker compose watch
clink:
- docker_compose_build.yaml
- docker_compose_config.yaml
@@ -159,12 +194,15 @@ clink:
- docker_compose_restart.yaml
- docker_compose_rm.yaml
- docker_compose_run.yaml
- docker_compose_scale.yaml
- docker_compose_start.yaml
- docker_compose_stop.yaml
- docker_compose_top.yaml
- docker_compose_unpause.yaml
- docker_compose_up.yaml
- docker_compose_version.yaml
- docker_compose_wait.yaml
- docker_compose_watch.yaml
options:
- option: ansi
value_type: string
@@ -192,13 +230,14 @@ options:
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: true
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: env-file
value_type: string
value_type: stringArray
default_value: '[]'
description: Specify an alternate environment file.
deprecated: false
hidden: false
@@ -247,6 +286,16 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: progress
value_type: string
default_value: auto
description: Set type of progress output (auto, tty, plain, quiet)
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: project-directory
value_type: string
description: |-
@@ -302,6 +351,7 @@ options:
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false

View File

@@ -4,12 +4,26 @@ long: Experimental commands
pname: docker compose
plink: docker_compose.yaml
cname:
- docker compose alpha dry-run
- docker compose alpha publish
- docker compose alpha viz
- docker compose alpha watch
clink:
- docker_compose_alpha_dry-run.yaml
- docker_compose_alpha_publish.yaml
- docker_compose_alpha_viz.yaml
- docker_compose_alpha_watch.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: true
experimental: false
experimentalcli: true
kubernetes: false

View File

@@ -0,0 +1,35 @@
command: docker compose alpha publish
short: Publish compose application
long: Publish compose application
usage: docker compose alpha publish [OPTIONS] [REPOSITORY]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
options:
- option: resolve-image-digests
value_type: bool
default_value: "false"
description: Pin image tags to digests.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: true
kubernetes: false
swarm: false

View File

@@ -0,0 +1,35 @@
command: docker compose alpha scale
short: Scale services
long: Scale services
usage: docker compose alpha scale [SERVICE=REPLICAS...]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
options:
- option: no-deps
value_type: bool
default_value: "false"
description: Don't start linked services.
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: true
kubernetes: false
swarm: false

View File

@@ -0,0 +1,77 @@
command: docker compose alpha viz
short: EXPERIMENTAL - Generate a graphviz graph from your compose file
long: EXPERIMENTAL - Generate a graphviz graph from your compose file
usage: docker compose alpha viz [OPTIONS]
pname: docker compose alpha
plink: docker_compose_alpha.yaml
options:
- option: image
value_type: bool
default_value: "false"
description: Include service's image name in output graph
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: indentation-size
value_type: int
default_value: "1"
description: Number of tabs or spaces to use for indentation
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: networks
value_type: bool
default_value: "false"
description: Include service's attached networks in output graph
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: ports
value_type: bool
default_value: "false"
description: Include service's exposed ports in output graph
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: spaces
value_type: bool
default_value: "false"
description: |-
If given, space character ' ' will be used to indent,
otherwise tab character '\t' will be used
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
inherited_options:
- option: dry-run
value_type: bool
default_value: "false"
description: Execute command in dry run mode
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
deprecated: false
hidden: false
experimental: false
experimentalcli: true
kubernetes: false
swarm: false

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