Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package docker-compose for openSUSE:Factory checked in at 2022-09-28 17:51:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/docker-compose (Old) and /work/SRC/openSUSE:Factory/.docker-compose.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "docker-compose" Wed Sep 28 17:51:43 2022 rev:7 rq:1006562 version:2.11.2 Changes: -------- --- /work/SRC/openSUSE:Factory/docker-compose/docker-compose.changes 2022-09-21 14:44:10.398034281 +0200 +++ /work/SRC/openSUSE:Factory/.docker-compose.new.2275/docker-compose.changes 2022-09-28 17:51:44.319230509 +0200 @@ -1,0 +2,24 @@ +Wed Sep 28 05:01:37 UTC 2022 - ka...@b1-systems.de + +- Update to version 2.11.2: + * deps: fix race condition during graph traversal (#9878) + * ci: limit job permissions from default (#9874) + * remove unnecessary code + * add more information when service.platform isn't part of service.build.platforms + * ci: upgrade to compose-go v1.6.0 + * cli: add shell completion function (#9269) + * run: clean service command if entrypoint is overridden (#9836) + * Remove support for `DOCKER_HOST` in `.env` files (#9871) + * keep the platform defined, in priority, via DOCKER_DEFAULT_PLATFORM or the service.plaform one if no build platforms provided + * Restore `-s` in `uname` OS detection logic in `Makefile` + * Streamline GHA workflow + * Upgrade `actions/setup-go` to v3 + * Skip some tests in CI due to flakiness + * Increase E2E test timeouts to reduce flakiness + * Temporarily disable broken E2E tests on Windows + * Rework Makefile for better Windows support + * Add GitHub Action workflow to run tests on Mac/Windows runners + * configure default builder export when no build.platforms defined + * Remove `/rebase` GitHub Action since it's no longer necessary + +------------------------------------------------------------------- Old: ---- compose-2.11.1.tar.gz New: ---- compose-2.11.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ docker-compose.spec ++++++ --- /var/tmp/diff_new_pack.HoG9YB/_old 2022-09-28 17:51:44.859231595 +0200 +++ /var/tmp/diff_new_pack.HoG9YB/_new 2022-09-28 17:51:44.863231603 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: docker-compose -Version: 2.11.1 +Version: 2.11.2 Release: 0 Summary: Define and run multi-container applications with Docker License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.HoG9YB/_old 2022-09-28 17:51:44.895231668 +0200 +++ /var/tmp/diff_new_pack.HoG9YB/_new 2022-09-28 17:51:44.899231675 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/docker/compose</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v2.11.1</param> + <param name="revision">v2.11.2</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> @@ -16,7 +16,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">compose-2.11.1.tar.gz</param> + <param name="archive">compose-2.11.2.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.HoG9YB/_old 2022-09-28 17:51:44.919231716 +0200 +++ /var/tmp/diff_new_pack.HoG9YB/_new 2022-09-28 17:51:44.923231724 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/docker/compose</param> - <param name="changesrevision">a1c50ef2c987d4709865aa02c237f45b08c529e2</param></service></servicedata> + <param name="changesrevision">616777eb4ad4d1101622d6727d9b7adaeb7943bb</param></service></servicedata> (No newline at EOF) ++++++ compose-2.11.1.tar.gz -> compose-2.11.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/.github/workflows/ci.yml new/compose-2.11.2/.github/workflows/ci.yml --- old/compose-2.11.1/.github/workflows/ci.yml 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/.github/workflows/ci.yml 2022-09-27 15:01:13.000000000 +0200 @@ -22,6 +22,9 @@ DESTDIR: "./bin" DOCKER_CLI_VERSION: "20.10.17" +permissions: + contents: read # to fetch code (actions/checkout) + jobs: prepare: runs-on: ubuntu-latest @@ -182,6 +185,9 @@ make e2e-compose-standalone release: + permissions: + contents: write # to create a release (ncipollo/release-action) + runs-on: ubuntu-latest needs: - binary diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/.github/workflows/docs.yml new/compose-2.11.2/.github/workflows/docs.yml --- old/compose-2.11.1/.github/workflows/docs.yml 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/.github/workflows/docs.yml 2022-09-27 15:01:13.000000000 +0200 @@ -4,8 +4,13 @@ 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: - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/.github/workflows/merge.yml new/compose-2.11.2/.github/workflows/merge.yml --- old/compose-2.11.1/.github/workflows/merge.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/compose-2.11.2/.github/workflows/merge.yml 2022-09-27 15:01:13.000000000 +0200 @@ -0,0 +1,74 @@ +name: merge + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: + - 'v2' + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + e2e: + name: Build and test + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + os: [desktop-windows, desktop-macos, desktop-m1] + # mode: [plugin, standalone] + mode: [plugin] + env: + GO111MODULE: "on" + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + cache: true + check-latest: true + + - name: List Docker resources on machine + run: | + docker ps --all + docker volume ls + docker network ls + docker image ls + - name: Remove Docker resources on machine + continue-on-error: true + run: | + docker kill $(docker ps -q) + docker rm -f $(docker ps -aq) + docker volume rm -f $(docker volume ls -q) + docker ps --all + + - name: Unit tests + run: make test + + - name: Build binaries + run: | + make + - name: Check arch of go compose binary + run: | + file ./bin/build/docker-compose + if: ${{ !contains(matrix.os, 'desktop-windows') }} + - + name: Test plugin mode + if: ${{ matrix.mode == 'plugin' }} + run: | + make e2e-compose + - + name: Test standalone mode + if: ${{ matrix.mode == 'standalone' }} + run: | + make e2e-compose-standalone + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/.github/workflows/rebase.yml new/compose-2.11.2/.github/workflows/rebase.yml --- old/compose-2.11.1/.github/workflows/rebase.yml 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/.github/workflows/rebase.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,19 +0,0 @@ -name: Automatic Rebase -on: - issue_comment: - types: [created] -jobs: - rebase: - name: Rebase - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') - runs-on: ubuntu-latest - steps: - - name: Checkout the latest code - uses: actions/checkout@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # otherwise, you will fail to push refs to dest repo - - name: Automatic Rebase - uses: cirrus-actions/rebase@1.4 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/Makefile new/compose-2.11.2/Makefile --- old/compose-2.11.1/Makefile 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/Makefile 2022-09-27 15:01:13.000000000 +0200 @@ -18,13 +18,20 @@ GO_LDFLAGS ?= -s -w -X ${PKG}/internal.Version=${VERSION} GO_BUILDTAGS ?= e2e,kube -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) +ifeq ($(OS),Windows_NT) + DETECTED_OS = Windows +else + DETECTED_OS = $(shell uname -s) +endif +ifeq ($(DETECTED_OS),Linux) MOBY_DOCKER=/usr/bin/docker endif -ifeq ($(UNAME_S),Darwin) +ifeq ($(DETECTED_OS),Darwin) MOBY_DOCKER=/Applications/Docker.app/Contents/Resources/bin/docker endif +ifeq ($(DETECTED_OS),Windows) + BINARY_EXT=.exe +endif TEST_FLAGS?= E2E_TEST?= @@ -40,7 +47,7 @@ .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" ./cmd + CGO_ENABLED=0 GO111MODULE=on go build -trimpath -tags "$(GO_BUILDTAGS)" -ldflags "$(GO_LDFLAGS)" -o "$(DESTDIR)/docker-compose$(BINARY_EXT)" ./cmd .PHONY: binary binary: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compatibility/convert.go new/compose-2.11.2/cmd/compatibility/convert.go --- old/compose-2.11.1/cmd/compatibility/convert.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compatibility/convert.go 2022-09-27 15:01:13.000000000 +0200 @@ -23,6 +23,13 @@ "github.com/docker/compose/v2/cmd/compose" ) +func getCompletionCommands() []string { + return []string{ + "__complete", + "__completeNoDesc", + } +} + func getBoolFlags() []string { return []string{ "--debug", "-D", @@ -50,6 +57,10 @@ l := len(args) for i := 0; i < l; i++ { arg := args[i] + if contains(getCompletionCommands(), arg) { + command = append([]string{arg}, command...) + continue + } if len(arg) > 0 && arg[0] != '-' { // not a top-level flag anymore, keep the rest of the command unmodified if arg == compose.PluginName { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/build.go new/compose-2.11.2/cmd/compose/build.go --- old/compose-2.11.1/cmd/compose/build.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/build.go 2022-09-27 15:01:13.000000000 +0200 @@ -102,7 +102,7 @@ } return runBuild(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } 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.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/completion.go new/compose-2.11.2/cmd/compose/completion.go --- old/compose-2.11.1/cmd/compose/completion.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/completion.go 2022-09-27 15:01:13.000000000 +0200 @@ -19,6 +19,7 @@ import ( "strings" + "github.com/docker/compose/v2/pkg/api" "github.com/spf13/cobra" ) @@ -27,11 +28,11 @@ func noCompletion() validArgsFn { return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return nil, cobra.ShellCompDirectiveNoFileComp + return []string{}, cobra.ShellCompDirectiveNoSpace } } -func serviceCompletion(p *projectOptions) validArgsFn { +func completeServiceNames(p *projectOptions) validArgsFn { return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { project, err := p.toProject(nil) if err != nil { @@ -46,3 +47,21 @@ return serviceNames, cobra.ShellCompDirectiveNoFileComp } } + +func completeProjectNames(backend api.Service) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + list, err := backend.List(cmd.Context(), api.ListOptions{ + All: true, + }) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + var values []string + for _, stack := range list { + if strings.HasPrefix(stack.Name, toComplete) { + values = append(values, stack.Name) + } + } + return values, cobra.ShellCompDirectiveNoFileComp + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/compose.go new/compose-2.11.2/cmd/compose/compose.go --- old/compose-2.11.1/cmd/compose/compose.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/compose.go 2022-09-27 15:01:13.000000000 +0200 @@ -25,7 +25,6 @@ "strings" "syscall" - cnabgodocker "github.com/cnabio/cnab-go/driver/docker" "github.com/compose-spec/compose-go/cli" "github.com/compose-spec/compose-go/types" composegoutils "github.com/compose-spec/compose-go/utils" @@ -33,7 +32,6 @@ dockercli "github.com/docker/cli/cli" "github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli/command" - "github.com/docker/docker/client" "github.com/morikuni/aec" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -293,16 +291,6 @@ if err != nil { return err } - // Reset DockerCli and APIClient to get possible `DOCKER_HOST` and/or `DOCKER_CONTEXT` loaded from environment file. - err = dockerCli.Apply(func(cli *command.DockerCli) error { - return cli.Initialize(cnabgodocker.BuildDockerClientOptions(), - command.WithInitializeClient(func(_ *command.DockerCli) (client.APIClient, error) { - return nil, nil - })) - }) - if err != nil { - return err - } parent := cmd.Root() if parent != nil { parentPrerun := parent.PersistentPreRunE @@ -370,6 +358,17 @@ ) c.Flags().SetInterspersed(false) opts.addProjectFlags(c.Flags()) + c.RegisterFlagCompletionFunc( //nolint:errcheck + "project-name", + completeProjectNames(backend), + ) + c.RegisterFlagCompletionFunc( //nolint:errcheck + "file", + func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"yaml", "yml"}, cobra.ShellCompDirectiveFilterFileExt + }, + ) + c.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`) c.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information") c.Flags().MarkHidden("version") //nolint:errcheck diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/convert.go new/compose-2.11.2/cmd/compose/convert.go --- old/compose-2.11.1/cmd/compose/convert.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/convert.go 2022-09-27 15:01:13.000000000 +0200 @@ -93,7 +93,7 @@ return runConvert(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/cp.go new/compose-2.11.2/cmd/compose/cp.go --- old/compose-2.11.1/cmd/compose/cp.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/cp.go 2022-09-27 15:01:13.000000000 +0200 @@ -60,7 +60,7 @@ opts.destination = args[1] return runCopy(ctx, backend, opts) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := copyCmd.Flags() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/create.go new/compose-2.11.2/cmd/compose/create.go --- old/compose-2.11.1/cmd/compose/create.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/create.go 2022-09-27 15:01:13.000000000 +0200 @@ -70,7 +70,7 @@ QuietPull: false, }) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/events.go new/compose-2.11.2/cmd/compose/events.go --- old/compose-2.11.1/cmd/compose/events.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/events.go 2022-09-27 15:01:13.000000000 +0200 @@ -43,7 +43,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runEvents(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } cmd.Flags().BoolVar(&opts.json, "json", false, "Output events as a stream of json objects") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/exec.go new/compose-2.11.2/cmd/compose/exec.go --- old/compose-2.11.1/cmd/compose/exec.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/exec.go 2022-09-27 15:01:13.000000000 +0200 @@ -61,7 +61,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runExec(ctx, backend, opts) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } runCmd.Flags().BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: Run command in the background.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/images.go new/compose-2.11.2/cmd/compose/images.go --- old/compose-2.11.1/cmd/compose/images.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/images.go 2022-09-27 15:01:13.000000000 +0200 @@ -48,7 +48,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runImages(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } imgCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs") return imgCmd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/kill.go new/compose-2.11.2/cmd/compose/kill.go --- old/compose-2.11.1/cmd/compose/kill.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/kill.go 2022-09-27 15:01:13.000000000 +0200 @@ -42,7 +42,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runKill(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/logs.go new/compose-2.11.2/cmd/compose/logs.go --- old/compose-2.11.1/cmd/compose/logs.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/logs.go 2022-09-27 15:01:13.000000000 +0200 @@ -49,7 +49,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runLogs(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := logsCmd.Flags() flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/pause.go new/compose-2.11.2/cmd/compose/pause.go --- old/compose-2.11.1/cmd/compose/pause.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/pause.go 2022-09-27 15:01:13.000000000 +0200 @@ -38,7 +38,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runPause(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } return cmd } @@ -69,7 +69,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runUnPause(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } return cmd } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/port.go new/compose-2.11.2/cmd/compose/port.go --- old/compose-2.11.1/cmd/compose/port.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/port.go 2022-09-27 15:01:13.000000000 +0200 @@ -52,7 +52,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runPort(ctx, backend, opts, args[0]) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(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") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/ps.go new/compose-2.11.2/cmd/compose/ps.go --- old/compose-2.11.1/cmd/compose/ps.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/ps.go 2022-09-27 15:01:13.000000000 +0200 @@ -78,7 +78,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runPs(ctx, backend, args, opts) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := psCmd.Flags() flags.StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json]") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/pull.go new/compose-2.11.2/cmd/compose/pull.go --- old/compose-2.11.1/cmd/compose/pull.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/pull.go 2022-09-27 15:01:13.000000000 +0200 @@ -54,7 +54,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runPull(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Pull without printing progress information") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/push.go new/compose-2.11.2/cmd/compose/push.go --- old/compose-2.11.1/cmd/compose/push.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/push.go 2022-09-27 15:01:13.000000000 +0200 @@ -41,7 +41,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runPush(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } pushCmd.Flags().BoolVar(&opts.Ignorefailures, "ignore-push-failures", false, "Push what it can and ignores images with push failures") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/remove.go new/compose-2.11.2/cmd/compose/remove.go --- old/compose-2.11.1/cmd/compose/remove.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/remove.go 2022-09-27 15:01:13.000000000 +0200 @@ -46,7 +46,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runRemove(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } f := cmd.Flags() f.BoolVarP(&opts.force, "force", "f", false, "Don't ask to confirm removal") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/restart.go new/compose-2.11.2/cmd/compose/restart.go --- old/compose-2.11.1/cmd/compose/restart.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/restart.go 2022-09-27 15:01:13.000000000 +0200 @@ -40,7 +40,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runRestart(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := restartCmd.Flags() flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/run.go new/compose-2.11.2/cmd/compose/run.go --- old/compose-2.11.1/cmd/compose/run.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/run.go 2022-09-27 15:01:13.000000000 +0200 @@ -143,7 +143,7 @@ opts.ignoreOrphans = strings.ToLower(ignore) == "true" return runRun(ctx, backend, project, opts) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() flags.BoolVarP(&opts.Detach, "detach", "d", false, "Run container in background and print container ID") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/start.go new/compose-2.11.2/cmd/compose/start.go --- old/compose-2.11.1/cmd/compose/start.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/start.go 2022-09-27 15:01:13.000000000 +0200 @@ -37,7 +37,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runStart(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } return startCmd } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/stop.go new/compose-2.11.2/cmd/compose/stop.go --- old/compose-2.11.1/cmd/compose/stop.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/stop.go 2022-09-27 15:01:13.000000000 +0200 @@ -44,7 +44,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runStop(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := cmd.Flags() flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/top.go new/compose-2.11.2/cmd/compose/top.go --- old/compose-2.11.1/cmd/compose/top.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/top.go 2022-09-27 15:01:13.000000000 +0200 @@ -44,7 +44,7 @@ RunE: Adapt(func(ctx context.Context, args []string) error { return runTop(ctx, backend, opts, args) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } return topCmd } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/compose/up.go new/compose-2.11.2/cmd/compose/up.go --- old/compose-2.11.1/cmd/compose/up.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/compose/up.go 2022-09-27 15:01:13.000000000 +0200 @@ -109,7 +109,7 @@ } return runUp(ctx, backend, create, up, project, services) }), - ValidArgsFunction: serviceCompletion(p), + ValidArgsFunction: completeServiceNames(p), } flags := upCmd.Flags() flags.BoolVarP(&up.Detach, "detach", "d", false, "Detached mode: Run containers in the background") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/cmd/main.go new/compose-2.11.2/cmd/main.go --- old/compose-2.11.1/cmd/main.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/cmd/main.go 2022-09-27 15:01:13.000000000 +0200 @@ -34,14 +34,13 @@ func pluginMain() { plugin.Run(func(dockerCli command.Cli) *cobra.Command { - lazyInit := api.NewServiceProxy() - cmd := commands.RootCommand(dockerCli, lazyInit) + serviceProxy := api.NewServiceProxy().WithService(compose.NewComposeService(dockerCli)) + cmd := commands.RootCommand(dockerCli, serviceProxy) originalPreRun := cmd.PersistentPreRunE cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { if err := plugin.PersistentPreRunE(cmd, args); err != nil { return err } - lazyInit.WithService(compose.NewComposeService(dockerCli)) if originalPreRun != nil { return originalPreRun(cmd, args) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/go.mod new/compose-2.11.2/go.mod --- old/compose-2.11.1/go.mod 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/go.mod 2022-09-27 15:01:13.000000000 +0200 @@ -5,9 +5,8 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.6 github.com/buger/goterm v1.0.4 - github.com/cnabio/cnab-go v0.24.1-0.20220907172316-1ca5c8721bf7 github.com/cnabio/cnab-to-oci v0.3.7 - github.com/compose-spec/compose-go v1.5.1 + github.com/compose-spec/compose-go v1.6.0 github.com/containerd/console v1.0.3 github.com/containerd/containerd v1.6.8 github.com/distribution/distribution/v3 v3.0.0-20220902125104-0122d7ddaec0 @@ -45,6 +44,7 @@ github.com/Microsoft/go-winio v0.5.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cnabio/cnab-go v0.23.4 // indirect github.com/containerd/continuity v0.2.3-0.20220330195504-d132b287edc8 // indirect github.com/containerd/ttrpc v1.1.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect @@ -133,8 +133,6 @@ github.com/cenkalti/backoff/v4 v4.1.2 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 // indirect github.com/googleapis/gnostic v0.5.5 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/go.sum new/compose-2.11.2/go.sum --- old/compose-2.11.1/go.sum 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/go.sum 2022-09-27 15:01:13.000000000 +0200 @@ -269,8 +269,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v1.4.1 h1:vScfU2DrIUI9VPHBVeeAQ0q5A+9yshO1Gz+3QoUQiKw= -github.com/cnabio/cnab-go v0.24.1-0.20220907172316-1ca5c8721bf7 h1:6cETeoyahKaH4hNShuB4KUqkTdjLVKEpTakHW5bpDW8= -github.com/cnabio/cnab-go v0.24.1-0.20220907172316-1ca5c8721bf7/go.mod h1:Zm0HTH8xxzinB64SXm7KFSna7DEN0ZjZwrRwZpfgChU= +github.com/cnabio/cnab-go v0.23.4 h1:jplQcSnvFyQlD6swiqL3BmqRnhbnS+lc/EKdBLH9E80= +github.com/cnabio/cnab-go v0.23.4/go.mod h1:9EmgHR51LFqQStzaC+xHPJlkD4OPsF6Ev5Y8e/YHEns= github.com/cnabio/cnab-to-oci v0.3.7 h1:wA2AG3HQMaJZhWlr3zsfVoa2m5B1R/SP+YcoFuNfP9o= github.com/cnabio/cnab-to-oci v0.3.7/go.mod h1:AvVNl0Hh3VBk1zqeLdyE5S3bTQ5EsZPPF4mUUJYyy1Y= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -287,8 +287,8 @@ github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/compose-spec/compose-go v1.2.1/go.mod h1:pAy7Mikpeft4pxkFU565/DRHEbDfR84G6AQuiL+Hdg8= -github.com/compose-spec/compose-go v1.5.1 h1:qch68VrytuoNMtklbdkhkI6FgDVLuFrUwWK1Lj828Xo= -github.com/compose-spec/compose-go v1.5.1/go.mod h1:nVa8sWM16GzxGLZ1kGrUtEt6RGimsdMmIzULVVD6S9k= +github.com/compose-spec/compose-go v1.6.0 h1:7Ol/UULMUtbPmB0EYrETASRoum821JpOh/XaEf+hN+Q= +github.com/compose-spec/compose-go v1.6.0/go.mod h1:os+Ulh2jlZxY1XT1hbciERadjSUU/BtZ6+gcN7vD7J0= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -1002,8 +1002,6 @@ github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= @@ -1022,8 +1020,6 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ= github.com/moby/buildkit v0.10.1-0.20220403220257-10e6f94bf90d/go.mod h1:WvwAZv8aRScHkqc/+X46cRC2CKMKpqcaX+pRvUTtPes= github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/compose/build.go new/compose-2.11.2/pkg/compose/build.go --- old/compose-2.11.1/pkg/compose/build.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/compose/build.go 2022-09-27 15:01:13.000000000 +0200 @@ -81,6 +81,12 @@ Attrs: map[string]string{"ref": image}, }) } + buildOptions.Exports = []bclient.ExportEntry{{ + Type: "docker", + Attrs: map[string]string{ + "load": "true", + }, + }} if len(buildOptions.Platforms) > 1 { buildOptions.Exports = []bclient.ExportEntry{{ Type: "image", @@ -173,7 +179,7 @@ "load": "true", }, }} - if opt.Platforms, err = useDockerDefaultPlatform(project, service.Build.Platforms); err != nil { + if opt.Platforms, err = useDockerDefaultOrServicePlatform(project, service, true); err != nil { opt.Platforms = []specs.Platform{} } opts[imageName] = opt @@ -357,23 +363,11 @@ } func addPlatforms(project *types.Project, service types.ServiceConfig) ([]specs.Platform, error) { - plats, err := useDockerDefaultPlatform(project, service.Build.Platforms) + plats, err := useDockerDefaultOrServicePlatform(project, service, false) if err != nil { return nil, err } - if service.Platform != "" && !utils.StringContains(service.Build.Platforms, service.Platform) { - if len(service.Build.Platforms) > 0 { - return nil, fmt.Errorf("service.platform should be part of the service.build.platforms: %q", service.Platform) - } - // User defined a service platform and no build platforms, so we should keep the one define on the service level - p, err := platforms.Parse(service.Platform) - if !utils.Contains(plats, p) { - plats = append(plats, p) - } - return plats, err - } - for _, buildPlatform := range service.Build.Platforms { p, err := platforms.Parse(buildPlatform) if err != nil { @@ -404,7 +398,7 @@ var plats []specs.Platform if platform, ok := project.Environment["DOCKER_DEFAULT_PLATFORM"]; ok { if len(platformList) > 0 && !utils.StringContains(platformList, platform) { - return nil, fmt.Errorf("the DOCKER_DEFAULT_PLATFORM value should be part of the service.build.platforms: %q", platform) + return nil, fmt.Errorf("the DOCKER_DEFAULT_PLATFORM %q value should be part of the service.build.platforms: %q", platform, platformList) } p, err := platforms.Parse(platform) if err != nil { @@ -414,3 +408,23 @@ } return plats, nil } + +func useDockerDefaultOrServicePlatform(project *types.Project, service types.ServiceConfig, useOnePlatform bool) ([]specs.Platform, error) { + plats, err := useDockerDefaultPlatform(project, service.Build.Platforms) + if (len(plats) > 0 && useOnePlatform) || err != nil { + return plats, err + } + + if service.Platform != "" && !utils.StringContains(service.Build.Platforms, service.Platform) { + if len(service.Build.Platforms) > 0 { + return nil, fmt.Errorf("service.platform %q should be part of the service.build.platforms: %q", service.Platform, service.Build.Platforms) + } + // User defined a service platform and no build platforms, so we should keep the one define on the service level + p, err := platforms.Parse(service.Platform) + if !utils.Contains(plats, p) { + plats = append(plats, p) + } + return plats, err + } + return plats, nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/compose/dependencies.go new/compose-2.11.2/pkg/compose/dependencies.go --- old/compose-2.11.1/pkg/compose/dependencies.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/compose/dependencies.go 2022-09-27 15:01:13.000000000 +0200 @@ -37,38 +37,49 @@ ServiceStarted ) -type graphTraversalConfig struct { +type graphTraversal struct { + mu sync.Mutex + seen map[string]struct{} + extremityNodesFn func(*Graph) []*Vertex // leaves or roots adjacentNodesFn func(*Vertex) []*Vertex // getParents or getChildren filterAdjacentByStatusFn func(*Graph, string, ServiceStatus) []*Vertex // filterChildren or filterParents targetServiceStatus ServiceStatus adjacentServiceStatusToSkip ServiceStatus + + visitorFn func(context.Context, string) error } -var ( - upDirectionTraversalConfig = graphTraversalConfig{ +func upDirectionTraversal(visitorFn func(context.Context, string) error) *graphTraversal { + return &graphTraversal{ extremityNodesFn: leaves, adjacentNodesFn: getParents, filterAdjacentByStatusFn: filterChildren, adjacentServiceStatusToSkip: ServiceStopped, targetServiceStatus: ServiceStarted, + visitorFn: visitorFn, } - downDirectionTraversalConfig = graphTraversalConfig{ +} + +func downDirectionTraversal(visitorFn func(context.Context, string) error) *graphTraversal { + return &graphTraversal{ extremityNodesFn: roots, adjacentNodesFn: getChildren, filterAdjacentByStatusFn: filterParents, adjacentServiceStatusToSkip: ServiceStarted, targetServiceStatus: ServiceStopped, + visitorFn: visitorFn, } -) +} // InDependencyOrder applies the function to the services of the project taking in account the dependency order -func InDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversalConfig)) error { +func InDependencyOrder(ctx context.Context, project *types.Project, fn func(context.Context, string) error, options ...func(*graphTraversal)) error { graph, err := NewGraph(project.Services, ServiceStopped) if err != nil { return err } - return visit(ctx, graph, upDirectionTraversalConfig, fn) + t := upDirectionTraversal(fn) + return t.visit(ctx, graph) } // InReverseDependencyOrder applies the function to the services of the project in reverse order of dependencies @@ -77,43 +88,59 @@ if err != nil { return err } - return visit(ctx, graph, downDirectionTraversalConfig, fn) + t := downDirectionTraversal(fn) + return t.visit(ctx, graph) } -func visit(ctx context.Context, g *Graph, traversalConfig graphTraversalConfig, fn func(context.Context, string) error) error { - nodes := traversalConfig.extremityNodesFn(g) +func (t *graphTraversal) visit(ctx context.Context, g *Graph) error { + nodes := t.extremityNodesFn(g) - eg, _ := errgroup.WithContext(ctx) - eg.Go(func() error { - return run(ctx, g, eg, nodes, traversalConfig, fn) - }) + eg, ctx := errgroup.WithContext(ctx) + t.run(ctx, g, eg, nodes) return eg.Wait() } // Note: this could be `graph.walk` or whatever -func run(ctx context.Context, graph *Graph, eg *errgroup.Group, nodes []*Vertex, traversalConfig graphTraversalConfig, fn func(context.Context, string) error) error { +func (t *graphTraversal) run(ctx context.Context, graph *Graph, eg *errgroup.Group, nodes []*Vertex) { for _, node := range nodes { // Don't start this service yet if all of its children have // not been started yet. - if len(traversalConfig.filterAdjacentByStatusFn(graph, node.Key, traversalConfig.adjacentServiceStatusToSkip)) != 0 { + if len(t.filterAdjacentByStatusFn(graph, node.Key, t.adjacentServiceStatusToSkip)) != 0 { continue } node := node + if !t.consume(node.Key) { + // another worker already visited this node + continue + } + eg.Go(func() error { - err := fn(ctx, node.Service) + err := t.visitorFn(ctx, node.Service) if err != nil { return err } - graph.UpdateStatus(node.Key, traversalConfig.targetServiceStatus) + graph.UpdateStatus(node.Key, t.targetServiceStatus) - return run(ctx, graph, eg, traversalConfig.adjacentNodesFn(node), traversalConfig, fn) + t.run(ctx, graph, eg, t.adjacentNodesFn(node)) + return nil }) } +} - return nil +func (t *graphTraversal) consume(nodeKey string) bool { + t.mu.Lock() + defer t.mu.Unlock() + if t.seen == nil { + t.seen = make(map[string]struct{}) + } + if _, ok := t.seen[nodeKey]; ok { + return false + } + t.seen[nodeKey] = struct{}{} + return true } // Graph represents project as service dependencies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/compose/dependencies_test.go new/compose-2.11.2/pkg/compose/dependencies_test.go --- old/compose-2.11.1/pkg/compose/dependencies_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/compose/dependencies_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -22,6 +22,7 @@ "testing" "github.com/compose-spec/compose-go/types" + testify "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gotest.tools/assert" ) @@ -46,6 +47,51 @@ }, } +func TestTraversalWithMultipleParents(t *testing.T) { + dependent := types.ServiceConfig{ + Name: "dependent", + DependsOn: make(types.DependsOnConfig), + } + + project := types.Project{ + Services: []types.ServiceConfig{dependent}, + } + + for i := 1; i <= 100; i++ { + name := fmt.Sprintf("svc_%d", i) + dependent.DependsOn[name] = types.ServiceDependency{} + + svc := types.ServiceConfig{Name: name} + project.Services = append(project.Services, svc) + } + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + + svc := make(chan string, 10) + seen := make(map[string]int) + done := make(chan struct{}) + go func() { + for service := range svc { + seen[service]++ + } + done <- struct{}{} + }() + + err := InDependencyOrder(ctx, &project, func(ctx context.Context, service string) error { + svc <- service + return nil + }) + require.NoError(t, err, "Error during iteration") + close(svc) + <-done + + testify.Len(t, seen, 101) + for svc, count := range seen { + assert.Equal(t, 1, count, "Service: %s", svc) + } +} + func TestInDependencyUpCommandOrder(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/compose/run.go new/compose-2.11.2/pkg/compose/run.go --- old/compose-2.11.1/pkg/compose/run.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/compose/run.go 2022-09-27 15:01:13.000000000 +0200 @@ -112,6 +112,9 @@ } if opts.Entrypoint != nil { service.Entrypoint = opts.Entrypoint + if len(opts.Command) == 0 { + service.Command = []string{} + } } if len(opts.Environment) > 0 { cmdEnv := types.NewMappingWithEquals(opts.Environment) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/buffer.go new/compose-2.11.2/pkg/e2e/buffer.go --- old/compose-2.11.1/pkg/e2e/buffer.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/buffer.go 2022-09-27 15:01:13.000000000 +0200 @@ -60,7 +60,7 @@ "Error: %v", err) } return strings.Contains(bufContents.String(), v) - }, 2*time.Second, 20*time.Millisecond, + }, 5*time.Second, 20*time.Millisecond, "Buffer did not contain %q\n============\n%s\n============", v, &bufContents) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/build_test.go new/compose-2.11.2/pkg/e2e/build_test.go --- old/compose-2.11.1/pkg/e2e/build_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/build_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -18,6 +18,7 @@ import ( "net/http" + "runtime" "strings" "testing" "time" @@ -85,6 +86,51 @@ res.Assert(t, icmd.Expected{Out: `"RESULT": "SUCCESS"`}) }) + t.Run("build as part of up", func(t *testing.T) { + c.RunDockerOrExitError(t, "rmi", "build-test-nginx") + c.RunDockerOrExitError(t, "rmi", "custom-nginx") + + res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d") + t.Cleanup(func() { + c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down") + }) + + res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) + res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"}) + + output := HTTPGetWithRetry(t, "http://localhost:8070", http.StatusOK, 2*time.Second, 20*time.Second) + assert.Assert(t, strings.Contains(output, "Hello from Nginx container")) + + c.RunDockerCmd(t, "image", "inspect", "build-test-nginx") + c.RunDockerCmd(t, "image", "inspect", "custom-nginx") + }) + + t.Run("no rebuild when up again", func(t *testing.T) { + res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d") + + assert.Assert(t, !strings.Contains(res.Stdout(), "COPY static"), res.Stdout()) + }) + + t.Run("rebuild when up --build", func(t *testing.T) { + res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "up", "-d", "--build") + + res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) + res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"}) + }) + + t.Run("cleanup build project", func(t *testing.T) { + c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down") + c.RunDockerCmd(t, "rmi", "build-test-nginx") + c.RunDockerCmd(t, "rmi", "custom-nginx") + }) +} + +func TestBuildSSH(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Running on Windows. Skipping...") + } + c := NewParallelCLI(t) + t.Run("build failed with ssh default value", func(t *testing.T) { res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test", "build", "--ssh", "") res.Assert(t, icmd.Expected{ @@ -130,47 +176,12 @@ }) c.RunDockerCmd(t, "image", "inspect", "build-test-ssh") }) - - t.Run("build as part of up", func(t *testing.T) { - c.RunDockerOrExitError(t, "rmi", "build-test-nginx") - c.RunDockerOrExitError(t, "rmi", "custom-nginx") - - res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d") - t.Cleanup(func() { - c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down") - }) - - res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) - res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"}) - - output := HTTPGetWithRetry(t, "http://localhost:8070", http.StatusOK, 2*time.Second, 20*time.Second) - assert.Assert(t, strings.Contains(output, "Hello from Nginx container")) - - c.RunDockerCmd(t, "image", "inspect", "build-test-nginx") - c.RunDockerCmd(t, "image", "inspect", "custom-nginx") - }) - - t.Run("no rebuild when up again", func(t *testing.T) { - res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d") - - assert.Assert(t, !strings.Contains(res.Stdout(), "COPY static"), res.Stdout()) - }) - - t.Run("rebuild when up --build", func(t *testing.T) { - res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "up", "-d", "--build") - - res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"}) - res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"}) - }) - - t.Run("cleanup build project", func(t *testing.T) { - c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "down") - c.RunDockerCmd(t, "rmi", "build-test-nginx") - c.RunDockerCmd(t, "rmi", "custom-nginx") - }) } func TestBuildSecrets(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skipping test on windows") + } c := NewParallelCLI(t) t.Run("build with secrets", func(t *testing.T) { @@ -259,6 +270,9 @@ } func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Running on Windows. Skipping...") + } c := NewParallelCLI(t) // declare builder @@ -352,7 +366,7 @@ "-f", "fixtures/build-test/platforms/compose-service-platform-not-in-build-platforms.yaml", "build") res.Assert(t, icmd.Expected{ ExitCode: 1, - Err: `service.platform should be part of the service.build.platforms: "linux/riscv64"`, + Err: `service.platform "linux/riscv64" should be part of the service.build.platforms: ["linux/amd64" "linux/arm64"]`, }) }) @@ -363,7 +377,7 @@ }) res.Assert(t, icmd.Expected{ ExitCode: 1, - Err: `DOCKER_DEFAULT_PLATFORM value should be part of the service.build.platforms: "windows/amd64"`, + Err: `DOCKER_DEFAULT_PLATFORM "windows/amd64" value should be part of the service.build.platforms: ["linux/amd64" "linux/arm64"]`, }) }) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/compose_test.go new/compose-2.11.2/pkg/e2e/compose_test.go --- old/compose-2.11.1/pkg/e2e/compose_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/compose_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -135,6 +135,9 @@ } func TestAttachRestart(t *testing.T) { + if _, ok := os.LookupEnv("CI"); ok { + t.Skip("Skipping test on CI... flaky") + } c := NewParallelCLI(t) cmd := c.NewDockerComposeCmd(t, "--ansi=never", "--project-directory", "./fixtures/attach-restart", "up") @@ -146,7 +149,7 @@ return strings.Count(res.Stdout(), "failing-1 exited with code 1") == 3, fmt.Sprintf("'failing-1 exited with code 1' not found 3 times in : \n%s\n", debug) - }, 2*time.Minute, 2*time.Second) + }, 4*time.Minute, 2*time.Second) assert.Equal(t, strings.Count(res.Stdout(), "failing-1 | world"), 3, res.Combined()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/pause_test.go new/compose-2.11.2/pkg/e2e/pause_test.go --- old/compose-2.11.1/pkg/e2e/pause_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/pause_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -21,6 +21,7 @@ "fmt" "net" "net/http" + "os" "testing" "time" @@ -29,6 +30,9 @@ ) func TestPause(t *testing.T) { + if _, ok := os.LookupEnv("CI"); ok { + t.Skip("Skipping test on CI... flaky") + } cli := NewParallelCLI(t, WithEnv( "COMPOSE_PROJECT_NAME=e2e-pause", "COMPOSE_FILE=./fixtures/pause/compose.yaml")) @@ -46,7 +50,7 @@ "b": urlForService(t, cli, "b", 80), } for _, url := range urls { - HTTPGetWithRetry(t, url, http.StatusOK, 50*time.Millisecond, 5*time.Second) + HTTPGetWithRetry(t, url, http.StatusOK, 50*time.Millisecond, 20*time.Second) } // pause a and verify that it can no longer be hit but b still can @@ -98,7 +102,7 @@ // launch a and wait for it to come up cli.RunDockerComposeCmd(t, "up", "-d", "a") - HTTPGetWithRetry(t, urlForService(t, cli, "a", 80), http.StatusOK, 50*time.Millisecond, 5*time.Second) + HTTPGetWithRetry(t, urlForService(t, cli, "a", 80), http.StatusOK, 50*time.Millisecond, 10*time.Second) // pause a twice - first time should pass, second time fail cli.RunDockerComposeCmd(t, "pause", "a") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/up_test.go new/compose-2.11.2/pkg/e2e/up_test.go --- old/compose-2.11.1/pkg/e2e/up_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/up_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -1,3 +1,6 @@ +//go:build !windows +// +build !windows + /* Copyright 2022 Docker Compose CLI authors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/compose-2.11.1/pkg/e2e/volumes_test.go new/compose-2.11.2/pkg/e2e/volumes_test.go --- old/compose-2.11.1/pkg/e2e/volumes_test.go 2022-09-20 10:00:10.000000000 +0200 +++ new/compose-2.11.2/pkg/e2e/volumes_test.go 2022-09-27 15:01:13.000000000 +0200 @@ -20,6 +20,7 @@ "net/http" "os" "path/filepath" + "runtime" "strings" "testing" "time" @@ -99,6 +100,9 @@ const projectName = "compose-e2e-project-volume-bind" t.Run("up on project volume with bind specification", func(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Running on Windows. Skipping...") + } tmpDir, err := os.MkdirTemp("", projectName) assert.NilError(t, err) defer os.RemoveAll(tmpDir) //nolint ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/docker-compose/vendor.tar.gz /work/SRC/openSUSE:Factory/.docker-compose.new.2275/vendor.tar.gz differ: char 5, line 1