Repository: docker/compose
Pull request #12609 (2025-03-06 09:25:13)

build(deps): bump github.com/moby/buildkit from 0.20.0 to 0.20.1
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.20.0 to 0.20.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/moby/buildkit/releases">github.com/moby/buildkit's releases</a>.</em></p>
<blockquote>
<h2>v0.20.1</h2>
<p>Welcome to the v0.20.1 release of buildkit!</p>
<p>Please try out the release binaries and report any issues at
<a href="https://github.com/moby/buildkit/issues">https://github.com/moby/buildkit/issues</a>.</p>
<h3>Contributors</h3>
<ul>
<li>Tõnis Tiigi</li>
<li>Akihiro Suda</li>
<li>CrazyMax</li>
</ul>
<h3>Notable Changes</h3>
<ul>
<li>Fix panic during CDI manager initialization. <a href="https://redirect.github.com/moby/buildkit/issues/5769">#5769</a> <a href="https://redirect.github.com/cncf-tags/container-device-interface/issues/254">cncf-tags/container-device-interface#254</a></li>
<li>Fix gRPC message size when writing SBOMs. <a href="https://redirect.github.com/moby/buildkit/issues/5798">#5798</a> <a href="https://redirect.github.com/containerd/containerd/issues/11457">containerd/containerd#11457</a></li>
<li>Update azblob client retries for GitHub Actions cache backend. <a href="https://redirect.github.com/moby/buildkit/issues/5797">#5797</a> <a href="https://redirect.github.com/tonistiigi/go-actions-cache/issues/33">tonistiigi/go-actions-cache#33</a></li>
<li>Embedded binfmt emulators in the release image have been updated to QEMU v9.2.2. <a href="https://redirect.github.com/moby/buildkit/issues/5808">#5808</a></li>
<li>Update documentation and examples for rootless mode. <a href="https://redirect.github.com/moby/buildkit/issues/5765">#5765</a></li>
</ul>
<h3>Dependency Changes</h3>
<ul>
<li><strong>github.com/containerd/containerd/v2</strong>      v2.0.2 -&gt; v2.0.3</li>
<li><strong>github.com/tonistiigi/go-actions-cache</strong>   1a5174abd055 -&gt; 3e9a6642607f</li>
<li><strong>tags.cncf.io/container-device-interface</strong>  v0.8.0 -&gt; v0.8.1</li>
</ul>
<p>Previous release can be found at <a href="https://github.com/moby/buildkit/releases/tag/v0.20.0">v0.20.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/moby/buildkit/commit/de56a3c5056341667b5bad71f414ece70b50724f"><code>de56a3c</code></a> Merge pull request <a href="https://redirect.github.com/moby/buildkit/issues/5803">#5803</a> from crazy-max/0.20_picks_0.20.1</li>
<li><a href="https://github.com/moby/buildkit/commit/cc210c8833940ce33eac059fbd04f5de3c3f898f"><code>cc210c8</code></a> vendor: update containerd to v2.0.3</li>
<li><a href="https://github.com/moby/buildkit/commit/2c40436cbb1428aa345847de420174ec1b18e323"><code>2c40436</code></a> dockerfile: normalize platform in image config</li>
<li><a href="https://github.com/moby/buildkit/commit/bfe3c1730a4256a509cbe07390da48de9504975d"><code>bfe3c17</code></a> rootless: update docs and examples</li>
<li><a href="https://github.com/moby/buildkit/commit/b1b594eec53c1b8244432db6ccc36a2d1a50802a"><code>b1b594e</code></a> update binfmt to v9.2.2</li>
<li><a href="https://github.com/moby/buildkit/commit/b15731bd35db82e3cee16697bf5b58e04f9d543e"><code>b15731b</code></a> vendor: update action-cache with longer azure retries</li>
<li><a href="https://github.com/moby/buildkit/commit/547d0836b26071997a30b8a53bfabfa7b05524b2"><code>547d083</code></a> vendor: update cdi to v0.8.1 for panic fix</li>
<li>See full diff in <a href="https://github.com/moby/buildkit/compare/v0.20.0...v0.20.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/moby/buildkit&package-manager=go_modules&previous-version=0.20.0&new-version=0.20.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/cmd/compose/options.go b/cmd/compose/options.go
index c71ee167f..3b6ba1beb 100644
--- a/cmd/compose/options.go
+++ b/cmd/compose/options.go
@@ -29,6 +29,7 @@ import (
 	"github.com/compose-spec/compose-go/v2/template"
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/cli/cli/command"
+	"github.com/docker/compose/v2/internal/tracing"
 	ui "github.com/docker/compose/v2/pkg/progress"
 	"github.com/docker/compose/v2/pkg/prompt"
 	"github.com/docker/compose/v2/pkg/utils"
@@ -103,6 +104,11 @@ func checksForRemoteStack(ctx context.Context, dockerCli command.Cli, project *t
 	if !isRemoteConfig(dockerCli, options) {
 		return nil
 	}
+	if metrics, ok := ctx.Value(tracing.MetricsKey{}).(tracing.Metrics); ok && metrics.CountIncludesRemote > 0 {
+		if err := confirmRemoteIncludes(dockerCli, options, assumeYes); err != nil {
+			return err
+		}
+	}
 	displayLocationRemoteStack(dockerCli, project, options)
 	return promptForInterpolatedVariables(ctx, dockerCli, options.ProjectOptions, assumeYes, cmdEnvs)
 }
@@ -245,3 +251,41 @@ func displayLocationRemoteStack(dockerCli command.Cli, project *types.Project, o
 		_, _ = fmt.Fprintf(dockerCli.Out(), "Your compose stack %q is stored in %q\n", mainComposeFile, project.WorkingDir)
 	}
 }
+
+func confirmRemoteIncludes(dockerCli command.Cli, options buildOptions, assumeYes bool) error {
+	if assumeYes {
+		return nil
+	}
+
+	var remoteIncludes []string
+	remoteLoaders := options.ProjectOptions.remoteLoaders(dockerCli)
+	for _, cf := range options.ProjectOptions.ConfigPaths {
+		for _, loader := range remoteLoaders {
+			if loader.Accept(cf) {
+				remoteIncludes = append(remoteIncludes, cf)
+				break
+			}
+		}
+	}
+
+	if len(remoteIncludes) == 0 {
+		return nil
+	}
+
+	_, _ = fmt.Fprintln(dockerCli.Out(), "\nWarning: This Compose project includes files from remote sources:")
+	for _, include := range remoteIncludes {
+		_, _ = fmt.Fprintf(dockerCli.Out(), "  - %s\n", include)
+	}
+	_, _ = fmt.Fprintln(dockerCli.Out(), "\nRemote includes could potentially be malicious. Make sure you trust the source.")
+
+	msg := "Do you want to continue? [y/N]: "
+	confirmed, err := prompt.NewPrompt(dockerCli.In(), dockerCli.Out()).Confirm(msg, false)
+	if err != nil {
+		return err
+	}
+	if !confirmed {
+		return fmt.Errorf("operation cancelled by user")
+	}
+
+	return nil
+}
diff --git a/go.mod b/go.mod
index c6d5d2c6d..b4f13478e 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
 	github.com/buger/goterm v1.0.4
 	github.com/compose-spec/compose-go/v2 v2.4.9-0.20250306081139-60e14f61e9ef
-	github.com/containerd/containerd/v2 v2.0.2
+	github.com/containerd/containerd/v2 v2.0.3
 	github.com/containerd/platforms v1.0.0-rc.1
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
 	github.com/distribution/reference v0.6.0
@@ -28,7 +28,7 @@ require (
 	github.com/mikefarah/yq/v4 v4.45.1
 	github.com/mitchellh/go-ps v1.0.0
 	github.com/mitchellh/mapstructure v1.5.0
-	github.com/moby/buildkit v0.20.0
+	github.com/moby/buildkit v0.20.1
 	github.com/moby/patternmatcher v0.6.0
 	github.com/moby/term v0.5.2
 	github.com/morikuni/aec v1.0.0
diff --git a/go.sum b/go.sum
index 44beb6940..5f32c6282 100644
--- a/go.sum
+++ b/go.sum
@@ -97,8 +97,8 @@ github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn
 github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
 github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
 github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
-github.com/containerd/containerd/v2 v2.0.2 h1:GmH/tRBlTvrXOLwSpWE2vNAm8+MqI6nmxKpKBNKY8Wc=
-github.com/containerd/containerd/v2 v2.0.2/go.mod h1:wIqEvQ/6cyPFUGJ5yMFanspPabMLor+bF865OHvNTTI=
+github.com/containerd/containerd/v2 v2.0.3 h1:zBKgwgZsuu+LPCMzCLgA4sC4MiZzZ59ZT31XkmiISQM=
+github.com/containerd/containerd/v2 v2.0.3/go.mod h1:5j9QUUaV/cy9ZeAx4S+8n9ffpf+iYnEj4jiExgcbuLY=
 github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
 github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
 github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
@@ -177,8 +177,6 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
 github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c=
 github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
 github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
 github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
@@ -350,8 +348,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
 github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/moby/buildkit v0.20.0 h1:aF5RujjQ310Pn6SLL/wQYIrSsPXy0sQ5KvWifwq1h8Y=
-github.com/moby/buildkit v0.20.0/go.mod h1:HYFUIK+iGDRxRgdphZ9Nv0y1Fz7mv0HrU7xZoXx217E=
+github.com/moby/buildkit v0.20.1 h1:sT0ZXhhNo5rVbMcYfgttma3TdUHfO5JjFA0UAL8p9fY=
+github.com/moby/buildkit v0.20.1/go.mod h1:Rq9nB/fJImdk6QeM0niKtOHJqwKeYMrK847hTTDVuA4=
 github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
 github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
 github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -408,8 +406,6 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw
 github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
 github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
 github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
-github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
 github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
 github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
 github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
@@ -506,8 +502,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
 github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
 github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA=
@@ -724,5 +718,3 @@ sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
 sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
 tags.cncf.io/container-device-interface v0.8.1 h1:c0jN4Mt6781jD67NdPajmZlD1qrqQyov/Xfoab37lj0=
 tags.cncf.io/container-device-interface v0.8.1/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
-tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA=
-tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws=
diff --git a/pkg/prompt/prompt.go b/pkg/prompt/prompt.go
index 6153893f8..07dbbcb42 100644
--- a/pkg/prompt/prompt.go
+++ b/pkg/prompt/prompt.go
@@ -96,6 +96,6 @@ type Pipe struct {
 func (u Pipe) Confirm(message string, defaultValue bool) (bool, error) {
 	_, _ = fmt.Fprint(u.stdout, message)
 	var answer string
-	_, _ = fmt.Scanln(&answer)
+	_, _ = fmt.Fscanln(u.stdin, &answer)
 	return utils.StringToBool(answer), nil
 }


Test patch:
diff --git a/cmd/compose/options_test.go b/cmd/compose/options_test.go
index 3e1700b96..035d1820e 100644
--- a/cmd/compose/options_test.go
+++ b/cmd/compose/options_test.go
@@ -20,6 +20,7 @@ import (
 	"bytes"
 	"context"
 	"fmt"
+	"io"
 	"os"
 	"path/filepath"
 	"strings"
@@ -280,3 +281,114 @@ services:
 		normalizeSpaces(actualOutput),
 		"\nExpected:\n%s\nGot:\n%s", expected, actualOutput)
 }
+
+func TestConfirmRemoteIncludes(t *testing.T) {
+	ctrl := gomock.NewController(t)
+	defer ctrl.Finish()
+	cli := mocks.NewMockCli(ctrl)
+
+	tests := []struct {
+		name       string
+		opts       buildOptions
+		assumeYes  bool
+		userInput  string
+		wantErr    bool
+		errMessage string
+		wantPrompt bool
+		wantOutput string
+	}{
+		{
+			name: "no remote includes",
+			opts: buildOptions{
+				ProjectOptions: &ProjectOptions{
+					ConfigPaths: []string{
+						"docker-compose.yaml",
+						"./local/path/compose.yaml",
+					},
+				},
+			},
+			assumeYes:  false,
+			wantErr:    false,
+			wantPrompt: false,
+		},
+		{
+			name: "assume yes with remote includes",
+			opts: buildOptions{
+				ProjectOptions: &ProjectOptions{
+					ConfigPaths: []string{
+						"oci://registry.example.com/stack:latest",
+						"git://github.com/user/repo.git",
+					},
+				},
+			},
+			assumeYes:  true,
+			wantErr:    false,
+			wantPrompt: false,
+		},
+		{
+			name: "user confirms remote includes",
+			opts: buildOptions{
+				ProjectOptions: &ProjectOptions{
+					ConfigPaths: []string{
+						"oci://registry.example.com/stack:latest",
+						"git://github.com/user/repo.git",
+					},
+				},
+			},
+			assumeYes:  false,
+			userInput:  "y\n",
+			wantErr:    false,
+			wantPrompt: true,
+			wantOutput: "\nWarning: This Compose project includes files from remote sources:\n" +
+				"  - oci://registry.example.com/stack:latest\n" +
+				"  - git://github.com/user/repo.git\n" +
+				"\nRemote includes could potentially be malicious. Make sure you trust the source.\n" +
+				"Do you want to continue? [y/N]: ",
+		},
+		{
+			name: "user rejects remote includes",
+			opts: buildOptions{
+				ProjectOptions: &ProjectOptions{
+					ConfigPaths: []string{
+						"oci://registry.example.com/stack:latest",
+					},
+				},
+			},
+			assumeYes:  false,
+			userInput:  "n\n",
+			wantErr:    true,
+			errMessage: "operation cancelled by user",
+			wantPrompt: true,
+			wantOutput: "\nWarning: This Compose project includes files from remote sources:\n" +
+				"  - oci://registry.example.com/stack:latest\n" +
+				"\nRemote includes could potentially be malicious. Make sure you trust the source.\n" +
+				"Do you want to continue? [y/N]: ",
+		},
+	}
+
+	buf := new(bytes.Buffer)
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			cli.EXPECT().Out().Return(streams.NewOut(buf)).AnyTimes()
+
+			if tt.wantPrompt {
+				inbuf := io.NopCloser(bytes.NewBufferString(tt.userInput))
+				cli.EXPECT().In().Return(streams.NewIn(inbuf)).AnyTimes()
+			}
+
+			err := confirmRemoteIncludes(cli, tt.opts, tt.assumeYes)
+
+			if tt.wantErr {
+				require.Error(t, err)
+				require.Equal(t, tt.errMessage, err.Error())
+			} else {
+				require.NoError(t, err)
+			}
+
+			if tt.wantOutput != "" {
+				require.Equal(t, tt.wantOutput, buf.String())
+			}
+			buf.Reset()
+		})
+	}
+}