From 4a93a41589fe4369ad48464f1e67051bf83a046b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 19 Oct 2026 12:52:27 +0200 Subject: [PATCH 1/3] cmd/docker-trust: Inline the JSON stream display helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin only needed progress display and an auxiliary callback. Inlined that use while preserving cancellation and terminal handling. Signed-off-by: Paweł Gronowski --- cmd/docker-trust/internal/trust/trust_push.go | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/cmd/docker-trust/internal/trust/trust_push.go b/cmd/docker-trust/internal/trust/trust_push.go index c65085f2c81c..7798565bcbb3 100644 --- a/cmd/docker-trust/internal/trust/trust_push.go +++ b/cmd/docker-trust/internal/trust/trust_push.go @@ -11,8 +11,9 @@ import ( "github.com/distribution/reference" "github.com/docker/cli/cli/streams" - "github.com/docker/cli/internal/jsonstream" + "github.com/moby/moby/api/types/jsonstream" registrytypes "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/client/pkg/jsonmessage" "github.com/opencontainers/go-digest" "github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/tuf/data" @@ -46,7 +47,7 @@ func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *Repo // Count the times of calling for handleTarget, // if it is called more that once, that should be considered an error in a trusted push. cnt := 0 - handleTarget := func(msg jsonstream.JSONMessage) { + handleTarget := func(msg jsonstream.Message) { cnt++ if cnt > 1 { // handleTarget should only be called once. This will be treated as an error. @@ -78,14 +79,14 @@ func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *Repo default: // We want trust signatures to always take an explicit tag, // otherwise it will act as an untrusted push. - if err := jsonstream.Display(ctx, in, ioStreams.Out()); err != nil { + if err := displayJSONMessages(ctx, in, ioStreams.Out(), nil); err != nil { return err } _, _ = fmt.Fprintln(ioStreams.Err(), "No tag specified, skipping trust metadata push") return nil } - if err := jsonstream.Display(ctx, in, ioStreams.Out(), jsonstream.WithAuxCallback(handleTarget)); err != nil { + if err := displayJSONMessages(ctx, in, ioStreams.Out(), handleTarget); err != nil { return err } @@ -147,3 +148,34 @@ func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *Repo _, _ = fmt.Fprintf(ioStreams.Out(), "Successfully signed %s:%s\n", repoInfo.Name.Name(), tag) return nil } + +type ctxReader struct { + err chan error + r io.Reader +} + +func (r *ctxReader) Read(p []byte) (int, error) { + select { + case err := <-r.err: + return 0, err + default: + return r.r.Read(p) + } +} + +// displayJSONMessages prints the JSON messages from in to out. It returns +// ctx.Err() if ctx is canceled, but not when in is closed. +func displayJSONMessages(ctx context.Context, in io.Reader, out *streams.Out, auxCallback func(jsonstream.Message)) error { + if ctx.Err() != nil { + return ctx.Err() + } + + reader := &ctxReader{err: make(chan error, 1), r: in} + stop := context.AfterFunc(ctx, func() { reader.err <- ctx.Err() }) + defer stop() + + if err := jsonmessage.DisplayJSONMessagesStream(reader, out, out.FD(), out.IsTerminal(), auxCallback); err != nil { + return err + } + return ctx.Err() +} From 00bf2d970d2d52fbec0a45f23985f18ac5e24b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 19 Oct 2026 13:16:53 +0200 Subject: [PATCH 2/3] cmd/docker-trust: Remove unused command registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both entry points use NewRootCmd, which adds subcommands directly. Removed the unused registry registration and constructor. Signed-off-by: Paweł Gronowski --- cmd/docker-trust/trust/cmd.go | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 cmd/docker-trust/trust/cmd.go diff --git a/cmd/docker-trust/trust/cmd.go b/cmd/docker-trust/trust/cmd.go deleted file mode 100644 index 55c80fe68a97..000000000000 --- a/cmd/docker-trust/trust/cmd.go +++ /dev/null @@ -1,32 +0,0 @@ -package trust - -import ( - "github.com/docker/cli/cli" - "github.com/docker/cli/cli/command" - "github.com/docker/cli/internal/commands" - "github.com/spf13/cobra" -) - -func init() { - commands.Register(newTrustCommand) -} - -// newTrustCommand returns a cobra command for `trust` subcommands. -func newTrustCommand(dockerCLI command.Cli) *cobra.Command { - cmd := &cobra.Command{ - Use: "trust", - Short: "Manage trust on Docker images", - Args: cli.NoArgs, - RunE: command.ShowHelp(dockerCLI.Err()), - - DisableFlagsInUseLine: true, - } - cmd.AddCommand( - newRevokeCommand(dockerCLI), - newSignCommand(dockerCLI), - newTrustKeyCommand(dockerCLI), - newTrustSignerCommand(dockerCLI), - newInspectCommand(dockerCLI), - ) - return cmd -} From 5e1e84ee5d9f10167a21c500d5cdb564584e36cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 19 Oct 2026 13:17:13 +0200 Subject: [PATCH 3/3] cmd/docker-trust: Use standard regexps for name validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin only used lazyregexp for two small, fixed name patterns. Replaced it with regexp.MustCompile without changing validation. Signed-off-by: Paweł Gronowski --- cmd/docker-trust/trust/key_generate.go | 4 ++-- cmd/docker-trust/trust/signer_add.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/docker-trust/trust/key_generate.go b/cmd/docker-trust/trust/key_generate.go index cf42ffc9bc96..16398933e47b 100644 --- a/cmd/docker-trust/trust/key_generate.go +++ b/cmd/docker-trust/trust/key_generate.go @@ -5,12 +5,12 @@ import ( "fmt" "os" "path/filepath" + "regexp" "strings" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cmd/docker-trust/internal/trust" - "github.com/docker/cli/internal/lazyregexp" "github.com/spf13/cobra" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/trustmanager" @@ -41,7 +41,7 @@ func newKeyGenerateCommand(dockerCLI command.Streams) *cobra.Command { } // key names can use lowercase alphanumeric + _ + - characters -var validKeyName = lazyregexp.New(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString +var validKeyName = regexp.MustCompile(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString // validate that all of the key names are unique and are alphanumeric + _ + - // and that we do not already have public key files in the target dir on disk diff --git a/cmd/docker-trust/trust/signer_add.go b/cmd/docker-trust/trust/signer_add.go index 0d94b9c46fcd..f4e938f01065 100644 --- a/cmd/docker-trust/trust/signer_add.go +++ b/cmd/docker-trust/trust/signer_add.go @@ -7,12 +7,12 @@ import ( "io" "os" "path" + "regexp" "strings" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cmd/docker-trust/internal/trust" - "github.com/docker/cli/internal/lazyregexp" "github.com/docker/cli/opts" "github.com/spf13/cobra" "github.com/theupdateframework/notary/client" @@ -45,7 +45,7 @@ func newSignerAddCommand(dockerCLI command.Cli) *cobra.Command { return cmd } -var validSignerName = lazyregexp.New(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString +var validSignerName = regexp.MustCompile(`^[a-z0-9][a-z0-9\_\-]*$`).MatchString func addSigner(ctx context.Context, dockerCLI command.Cli, options signerAddOptions) error { signerName := options.signer