diff --git a/cli/command/cli.go b/cli/command/cli.go index 965c410ae..2cdfef35e 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -48,7 +48,6 @@ type Cli interface { config.Provider ServerInfo() ServerInfo CurrentVersion() string - ContentTrustEnabled() bool BuildKitEnabled() (bool, error) ContextStore() store.Store CurrentContext() string @@ -160,6 +159,8 @@ func (cli *DockerCli) ServerInfo() ServerInfo { // ContentTrustEnabled returns whether content trust has been enabled by an // environment variable. +// +// Deprecated: check the value of the DOCKER_CONTENT_TRUST environment variable to detect whether content-trust is enabled. func (cli *DockerCli) ContentTrustEnabled() bool { return cli.contentTrust } diff --git a/cli/command/container/create.go b/cli/command/container/create.go index 6d05c1962..a2733ccf6 100644 --- a/cli/command/container/create.go +++ b/cli/command/container/create.go @@ -90,7 +90,7 @@ func newCreateCommand(dockerCLI command.Cli) *cobra.Command { addPlatformFlag(flags, &options.platform) _ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms()) - flags.BoolVar(&options.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image verification") + flags.BoolVar(&options.untrusted, "disable-content-trust", !trust.Enabled(), "Skip image verification") copts = addFlags(flags) addCompletions(cmd, dockerCLI) diff --git a/cli/command/container/create_test.go b/cli/command/container/create_test.go index d3a08c79d..6776f9c15 100644 --- a/cli/command/container/create_test.go +++ b/cli/command/container/create_test.go @@ -249,6 +249,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Setenv("DOCKER_CONTENT_TRUST", "true") fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, @@ -258,7 +259,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { ) (container.CreateResponse, error) { return container.CreateResponse{}, errors.New("shouldn't try to pull image") }, - }, test.EnableContentTrust) + }) fakeCLI.SetNotaryClient(tc.notaryFunc) cmd := newCreateCommand(fakeCLI) cmd.SetOut(io.Discard) diff --git a/cli/command/container/run.go b/cli/command/container/run.go index 467207bdb..a8630f825 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -11,6 +11,7 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" + "github.com/docker/cli/cli/trust" "github.com/docker/cli/opts" "github.com/moby/moby/api/types/container" "github.com/moby/moby/client" @@ -70,7 +71,7 @@ func newRunCommand(dockerCLI command.Cli) *cobra.Command { // TODO(thaJeztah): consider adding platform as "image create option" on containerOptions addPlatformFlag(flags, &options.platform) - flags.BoolVar(&options.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image verification") + flags.BoolVar(&options.untrusted, "disable-content-trust", !trust.Enabled(), "Skip image verification") copts = addFlags(flags) _ = cmd.RegisterFlagCompletionFunc("detach-keys", completeDetachKeys) diff --git a/cli/command/container/run_test.go b/cli/command/container/run_test.go index 1c09c9c39..925fc0d73 100644 --- a/cli/command/container/run_test.go +++ b/cli/command/container/run_test.go @@ -323,6 +323,7 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Setenv("DOCKER_CONTENT_TRUST", "true") fakeCLI := test.NewFakeCli(&fakeClient{ createContainerFunc: func(config *container.Config, hostConfig *container.HostConfig, @@ -332,7 +333,7 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) { ) (container.CreateResponse, error) { return container.CreateResponse{}, errors.New("shouldn't try to pull image") }, - }, test.EnableContentTrust) + }) fakeCLI.SetNotaryClient(tc.notaryFunc) cmd := newRunCommand(fakeCLI) cmd.SetArgs(tc.args) diff --git a/cli/command/image/build.go b/cli/command/image/build.go index d98b21f49..e53342ddf 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -147,7 +147,7 @@ func newBuildCommand(dockerCLI command.Cli) *cobra.Command { flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/reference/cli/docker/buildx/build/#target"}) flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file") - flags.Bool("disable-content-trust", dockerCLI.ContentTrustEnabled(), "Skip image verification (deprecated)") + flags.Bool("disable-content-trust", true, "Skip image verification (deprecated)") _ = flags.MarkHidden("disable-content-trust") flags.StringVar(&options.platform, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable") diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 00d3eb486..9875b5411 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -50,7 +50,7 @@ func newPullCommand(dockerCLI command.Cli) *cobra.Command { flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress verbose output") addPlatformFlag(flags, &opts.platform) - flags.BoolVar(&opts.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image verification") + flags.BoolVar(&opts.untrusted, "disable-content-trust", !trust.Enabled(), "Skip image verification") _ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms()) diff --git a/cli/command/image/pull_test.go b/cli/command/image/pull_test.go index 6d111993e..dad36f21a 100644 --- a/cli/command/image/pull_test.go +++ b/cli/command/image/pull_test.go @@ -118,11 +118,12 @@ func TestNewPullCommandWithContentTrustErrors(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Setenv("DOCKER_CONTENT_TRUST", "true") cli := test.NewFakeCli(&fakeClient{ imagePullFunc: func(ref string, options client.ImagePullOptions) (io.ReadCloser, error) { return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image") }, - }, test.EnableContentTrust) + }) cli.SetNotaryClient(tc.notaryFunc) cmd := newPullCommand(cli) cmd.SetOut(io.Discard) diff --git a/cli/command/image/push.go b/cli/command/image/push.go index 62d565f24..1e3602b87 100644 --- a/cli/command/image/push.go +++ b/cli/command/image/push.go @@ -16,6 +16,7 @@ import ( "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/streams" + "github.com/docker/cli/cli/trust" "github.com/docker/cli/internal/jsonstream" "github.com/docker/cli/internal/registry" "github.com/docker/cli/internal/tui" @@ -58,7 +59,7 @@ func newPushCommand(dockerCLI command.Cli) *cobra.Command { flags := cmd.Flags() flags.BoolVarP(&opts.all, "all-tags", "a", false, "Push all tags of an image to the repository") flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress verbose output") - flags.BoolVar(&opts.untrusted, "disable-content-trust", !dockerCLI.ContentTrustEnabled(), "Skip image signing") + flags.BoolVar(&opts.untrusted, "disable-content-trust", !trust.Enabled(), "Skip image signing") // Don't default to DOCKER_DEFAULT_PLATFORM env variable, always default to // pushing the image as-is. This also avoids forcing the platform selection diff --git a/cli/command/plugin/install.go b/cli/command/plugin/install.go index 926074e93..652ac8deb 100644 --- a/cli/command/plugin/install.go +++ b/cli/command/plugin/install.go @@ -44,7 +44,7 @@ func newInstallCommand(dockerCLI command.Cli) *cobra.Command { flags.BoolVar(&options.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin") flags.BoolVar(&options.disable, "disable", false, "Do not enable the plugin on install") flags.StringVar(&options.localName, "alias", "", "Local name for plugin") - flags.Bool("disable-content-trust", dockerCLI.ContentTrustEnabled(), "Skip image verification (deprecated)") + flags.Bool("disable-content-trust", true, "Skip image verification (deprecated)") _ = flags.MarkHidden("disable-content-trust") return cmd } diff --git a/cli/command/plugin/push.go b/cli/command/plugin/push.go index 5f1349a90..fc7c5a498 100644 --- a/cli/command/plugin/push.go +++ b/cli/command/plugin/push.go @@ -25,7 +25,7 @@ func newPushCommand(dockerCLI command.Cli) *cobra.Command { } flags := cmd.Flags() - flags.Bool("disable-content-trust", dockerCLI.ContentTrustEnabled(), "Skip image verification (deprecated)") + flags.Bool("disable-content-trust", true, "Skip image verification (deprecated)") _ = flags.MarkHidden("disable-content-trust") return cmd } diff --git a/cli/command/plugin/upgrade.go b/cli/command/plugin/upgrade.go index 2024dfb4f..eb7bbccda 100644 --- a/cli/command/plugin/upgrade.go +++ b/cli/command/plugin/upgrade.go @@ -33,7 +33,7 @@ func newUpgradeCommand(dockerCLI command.Cli) *cobra.Command { flags := cmd.Flags() flags.BoolVar(&options.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin") - flags.Bool("disable-content-trust", dockerCLI.ContentTrustEnabled(), "Skip image verification (deprecated)") + flags.Bool("disable-content-trust", true, "Skip image verification (deprecated)") _ = flags.MarkHidden("disable-content-trust") flags.BoolVar(&options.skipRemoteCheck, "skip-remote-check", false, "Do not check if specified remote plugin matches existing plugin image") return cmd diff --git a/cli/command/service/trust.go b/cli/command/service/trust.go index cec9f712a..cb4f6fe5f 100644 --- a/cli/command/service/trust.go +++ b/cli/command/service/trust.go @@ -16,7 +16,7 @@ import ( ) func resolveServiceImageDigestContentTrust(dockerCli command.Cli, service *swarm.ServiceSpec) error { - if !dockerCli.ContentTrustEnabled() { + if !trust.Enabled() { // When not using content trust, digest resolution happens later when // contacting the registry to retrieve image information. return nil diff --git a/cli/trust/trust.go b/cli/trust/trust.go index 06fb2c071..b961de8ef 100644 --- a/cli/trust/trust.go +++ b/cli/trust/trust.go @@ -12,6 +12,7 @@ import ( "os" "path" "path/filepath" + "strconv" "time" "github.com/distribution/reference" @@ -43,6 +44,20 @@ var ( ActionsPushAndPull = []string{"pull", "push"} ) +// Enabled returns whether content-trust is enabled through the DOCKER_CONTENT_TRUST env-var. +// +// IMPORTANT: this function is for internal use, and may be removed at any moment. +func Enabled() bool { + var enabled bool + if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" { + if t, err := strconv.ParseBool(e); t || err != nil { + // treat any other value as true + enabled = true + } + } + return enabled +} + // NotaryServer is the endpoint serving the Notary trust server const NotaryServer = "https://notary.docker.io" diff --git a/internal/test/cli.go b/internal/test/cli.go index 80044e80f..8a3a69dea 100644 --- a/internal/test/cli.go +++ b/internal/test/cli.go @@ -35,7 +35,6 @@ type FakeCli struct { notaryClientFunc NotaryClientFuncType manifestStore manifeststore.Store registryClient registryclient.RegistryClient - contentTrust bool contextStore store.Store currentContext string dockerEndpoint docker.Endpoint @@ -197,16 +196,6 @@ func (c *FakeCli) SetRegistryClient(registryClient registryclient.RegistryClient c.registryClient = registryClient } -// ContentTrustEnabled on the fake cli -func (c *FakeCli) ContentTrustEnabled() bool { - return c.contentTrust -} - -// EnableContentTrust on the fake cli -func EnableContentTrust(c *FakeCli) { - c.contentTrust = true -} - // BuildKitEnabled on the fake cli func (*FakeCli) BuildKitEnabled() (bool, error) { return true, nil