diff --git a/go.mod b/go.mod index ca66dec4..9c0e81be 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/containerd/continuity v0.3.0 github.com/containerd/typeurl/v2 v2.1.0 github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa - github.com/docker/cli v23.0.6+incompatible + github.com/docker/cli v24.0.0+incompatible github.com/docker/cli-docs-tool v0.5.1 github.com/docker/distribution v2.8.2+incompatible github.com/docker/docker v24.0.0+incompatible diff --git a/go.sum b/go.sum index e9816fe7..5a58b0c3 100644 --- a/go.sum +++ b/go.sum @@ -165,8 +165,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as= github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= -github.com/docker/cli v23.0.6+incompatible h1:CScadyCJ2ZKUDpAMZta6vK8I+6/m60VIjGIV7Wg/Eu4= -github.com/docker/cli v23.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM= +github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli-docs-tool v0.5.1 h1:jIk/cCZurZERhALPVKhqlNxTQGxn2kcI+56gE57PQXg= github.com/docker/cli-docs-tool v0.5.1/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= diff --git a/vendor/github.com/docker/cli/cli-plugins/manager/metadata.go b/vendor/github.com/docker/cli/cli-plugins/manager/metadata.go index 5c80c1db..5aaf5ca1 100644 --- a/vendor/github.com/docker/cli/cli-plugins/manager/metadata.go +++ b/vendor/github.com/docker/cli/cli-plugins/manager/metadata.go @@ -23,6 +23,7 @@ type Metadata struct { // URL is a pointer to the plugin's homepage. URL string `json:",omitempty"` // Experimental specifies whether the plugin is experimental. + // // Deprecated: experimental features are now always enabled in the CLI Experimental bool `json:",omitempty"` } diff --git a/vendor/github.com/docker/cli/cli/cobra.go b/vendor/github.com/docker/cli/cli/cobra.go index 6501197d..c6ce31dc 100644 --- a/vendor/github.com/docker/cli/cli/cobra.go +++ b/vendor/github.com/docker/cli/cli/cobra.go @@ -426,7 +426,7 @@ func invalidPluginReason(cmd *cobra.Command) string { return cmd.Annotations[pluginmanager.CommandAnnotationPluginInvalid] } -var usageTemplate = `Usage: +const usageTemplate = `Usage: {{- if not .HasSubCommands}} {{.UseLine}}{{end}} {{- if .HasSubCommands}} {{ .CommandPath}}{{- if .HasAvailableFlags}} [OPTIONS]{{end}} COMMAND{{end}} @@ -525,5 +525,5 @@ Run '{{.CommandPath}} COMMAND --help' for more information on a command. {{- end}} ` -var helpTemplate = ` +const helpTemplate = ` {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` diff --git a/vendor/github.com/docker/cli/cli/command/cli.go b/vendor/github.com/docker/cli/cli/command/cli.go index 2a61d5e4..4d8b9dc4 100644 --- a/vendor/github.com/docker/cli/cli/command/cli.go +++ b/vendor/github.com/docker/cli/cli/command/cli.go @@ -48,9 +48,7 @@ type Streams interface { // Cli represents the docker command line client. type Cli interface { Client() client.APIClient - Out() *streams.Out - Err() io.Writer - In() *streams.In + Streams SetIn(in *streams.In) Apply(ops ...DockerCliOption) error ConfigFile() *configfile.ConfigFile @@ -191,7 +189,7 @@ func (cli *DockerCli) ManifestStore() manifeststore.Store { // RegistryClient returns a client for communicating with a Docker distribution // registry func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.RegistryClient { - resolver := func(ctx context.Context, index *registry.IndexInfo) types.AuthConfig { + resolver := func(ctx context.Context, index *registry.IndexInfo) registry.AuthConfig { return ResolveAuthConfig(ctx, cli, index) } return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure) diff --git a/vendor/github.com/docker/cli/cli/command/registry.go b/vendor/github.com/docker/cli/cli/command/registry.go index 90cc08c5..90993672 100644 --- a/vendor/github.com/docker/cli/cli/command/registry.go +++ b/vendor/github.com/docker/cli/cli/command/registry.go @@ -3,8 +3,6 @@ package command import ( "bufio" "context" - "encoding/base64" - "encoding/json" "fmt" "io" "os" @@ -21,20 +19,11 @@ import ( "github.com/pkg/errors" ) -// ElectAuthServer returns the default registry to use. +// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload. // -// Deprecated: use [registry.IndexServer] instead. -func ElectAuthServer(_ context.Context, _ Cli) string { - return registry.IndexServer -} - -// EncodeAuthToBase64 serializes the auth configuration as JSON base64 payload -func EncodeAuthToBase64(authConfig types.AuthConfig) (string, error) { - buf, err := json.Marshal(authConfig) - if err != nil { - return "", err - } - return base64.URLEncoding.EncodeToString(buf), nil +// Deprecated: use [registrytypes.EncodeAuthConfig] instead. +func EncodeAuthToBase64(authConfig registrytypes.AuthConfig) (string, error) { + return registrytypes.EncodeAuthConfig(authConfig) } // RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info @@ -52,7 +41,7 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf if err != nil { return "", err } - return EncodeAuthToBase64(authConfig) + return registrytypes.EncodeAuthConfig(authConfig) } } @@ -62,19 +51,19 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf // // It is similar to [registry.ResolveAuthConfig], but uses the credentials- // store, instead of looking up credentials from a map. -func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) types.AuthConfig { +func ResolveAuthConfig(_ context.Context, cli Cli, index *registrytypes.IndexInfo) registrytypes.AuthConfig { configKey := index.Name if index.Official { configKey = registry.IndexServer } a, _ := cli.ConfigFile().GetAuthConfig(configKey) - return types.AuthConfig(a) + return registrytypes.AuthConfig(a) } // GetDefaultAuthConfig gets the default auth config given a serverAddress // If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it -func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) { +func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (registrytypes.AuthConfig, error) { if !isDefaultRegistry { serverAddress = registry.ConvertToHostname(serverAddress) } @@ -83,20 +72,27 @@ func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, is if checkCredStore { authconfig, err = cli.ConfigFile().GetAuthConfig(serverAddress) if err != nil { - return types.AuthConfig{ + return registrytypes.AuthConfig{ ServerAddress: serverAddress, }, err } } authconfig.ServerAddress = serverAddress authconfig.IdentityToken = "" - res := types.AuthConfig(authconfig) + res := registrytypes.AuthConfig(authconfig) return res, nil } // ConfigureAuth handles prompting of user's username and password if needed -func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthConfig, isDefaultRegistry bool) error { - // On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210 +func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes.AuthConfig, isDefaultRegistry bool) error { + // On Windows, force the use of the regular OS stdin stream. + // + // See: + // - https://github.com/moby/moby/issues/14336 + // - https://github.com/moby/moby/issues/14210 + // - https://github.com/moby/moby/pull/17738 + // + // TODO(thaJeztah): we need to confirm if this special handling is still needed, as we may not be doing this in other places. if runtime.GOOS == "windows" { cli.SetIn(streams.NewIn(os.Stdin)) } @@ -120,8 +116,11 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon fmt.Fprintln(cli.Out(), "Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.") } promptWithDefault(cli.Out(), "Username", authconfig.Username) - flUser = readInput(cli.In(), cli.Out()) - flUser = strings.TrimSpace(flUser) + var err error + flUser, err = readInput(cli.In()) + if err != nil { + return err + } if flUser == "" { flUser = authconfig.Username } @@ -135,12 +134,15 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon return err } fmt.Fprintf(cli.Out(), "Password: ") - term.DisableEcho(cli.In().FD(), oldState) - - flPassword = readInput(cli.In(), cli.Out()) + _ = term.DisableEcho(cli.In().FD(), oldState) + defer func() { + _ = term.RestoreTerminal(cli.In().FD(), oldState) + }() + flPassword, err = readInput(cli.In()) + if err != nil { + return err + } fmt.Fprint(cli.Out(), "\n") - - term.RestoreTerminal(cli.In().FD(), oldState) if flPassword == "" { return errors.Errorf("Error: Password Required") } @@ -152,14 +154,15 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *types.AuthCon return nil } -func readInput(in io.Reader, out io.Writer) string { - reader := bufio.NewReader(in) - line, _, err := reader.ReadLine() +// readInput reads, and returns user input from in. It tries to return a +// single line, not including the end-of-line bytes, and trims leading +// and trailing whitespace. +func readInput(in io.Reader) (string, error) { + line, _, err := bufio.NewReader(in).ReadLine() if err != nil { - fmt.Fprintln(out, err.Error()) - os.Exit(1) + return "", errors.Wrap(err, "error while reading input") } - return string(line) + return strings.TrimSpace(string(line)), nil } func promptWithDefault(out io.Writer, prompt string, configDefault string) { @@ -170,14 +173,19 @@ func promptWithDefault(out io.Writer, prompt string, configDefault string) { } } -// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete image +// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete +// image. The auth configuration is serialized as a base64url encoded RFC4648, +// section 5) JSON string for sending through the X-Registry-Auth header. +// +// For details on base64url encoding, see: +// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5 func RetrieveAuthTokenFromImage(ctx context.Context, cli Cli, image string) (string, error) { // Retrieve encoded auth token from the image reference authConfig, err := resolveAuthConfigFromImage(ctx, cli, image) if err != nil { return "", err } - encodedAuth, err := EncodeAuthToBase64(authConfig) + encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig) if err != nil { return "", err } @@ -185,14 +193,14 @@ func RetrieveAuthTokenFromImage(ctx context.Context, cli Cli, image string) (str } // resolveAuthConfigFromImage retrieves that AuthConfig using the image string -func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (types.AuthConfig, error) { +func resolveAuthConfigFromImage(ctx context.Context, cli Cli, image string) (registrytypes.AuthConfig, error) { registryRef, err := reference.ParseNormalizedNamed(image) if err != nil { - return types.AuthConfig{}, err + return registrytypes.AuthConfig{}, err } repoInfo, err := registry.ParseRepositoryInfo(registryRef) if err != nil { - return types.AuthConfig{}, err + return registrytypes.AuthConfig{}, err } return ResolveAuthConfig(ctx, cli, repoInfo.Index), nil } diff --git a/vendor/github.com/docker/cli/cli/command/streams.go b/vendor/github.com/docker/cli/cli/command/streams.go deleted file mode 100644 index 43dc6cd0..00000000 --- a/vendor/github.com/docker/cli/cli/command/streams.go +++ /dev/null @@ -1,32 +0,0 @@ -package command - -import ( - "io" - - "github.com/docker/cli/cli/streams" -) - -// InStream is an input stream used by the DockerCli to read user input -// -// Deprecated: Use [streams.In] instead. -type InStream = streams.In - -// OutStream is an output stream used by the DockerCli to write normal program -// output. -// -// Deprecated: Use [streams.Out] instead. -type OutStream = streams.Out - -// NewInStream returns a new [streams.In] from an [io.ReadCloser]. -// -// Deprecated: Use [streams.NewIn] instead. -func NewInStream(in io.ReadCloser) *streams.In { - return streams.NewIn(in) -} - -// NewOutStream returns a new [streams.Out] from an [io.Writer]. -// -// Deprecated: Use [streams.NewOut] instead. -func NewOutStream(out io.Writer) *streams.Out { - return streams.NewOut(out) -} diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index 609a88c2..5db7f8b8 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -37,7 +37,6 @@ type ConfigFile struct { PruneFilters []string `json:"pruneFilters,omitempty"` Proxies map[string]ProxyConfig `json:"proxies,omitempty"` Experimental string `json:"experimental,omitempty"` - StackOrchestrator string `json:"stackOrchestrator,omitempty"` // Deprecated: swarm is now the default orchestrator, and this option is ignored. CurrentContext string `json:"currentContext,omitempty"` CLIPluginsExtraDirs []string `json:"cliPluginsExtraDirs,omitempty"` Plugins map[string]map[string]string `json:"plugins,omitempty"` diff --git a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go index a0b035c9..202ddb84 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go +++ b/vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go @@ -32,7 +32,7 @@ import ( ) // New returns net.Conn -func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) { +func New(_ context.Context, cmd string, args ...string) (net.Conn, error) { var ( c commandConn err error diff --git a/vendor/github.com/docker/cli/cli/connhelper/connhelper.go b/vendor/github.com/docker/cli/cli/connhelper/connhelper.go index 9ac9d674..397149c3 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/connhelper.go +++ b/vendor/github.com/docker/cli/cli/connhelper/connhelper.go @@ -47,7 +47,12 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper } return &ConnectionHelper{ Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { - return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args("docker", "system", "dial-stdio")...)...) + args := []string{"docker"} + if sp.Path != "" { + args = append(args, "--host", "unix://"+sp.Path) + } + args = append(args, "system", "dial-stdio") + return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args(args...)...)...) }, Host: "http://docker.example.com", }, nil diff --git a/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go b/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go index bde01ae7..fb4c9111 100644 --- a/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go +++ b/vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go @@ -30,9 +30,7 @@ func ParseURL(daemonURL string) (*Spec, error) { return nil, errors.Errorf("no host specified") } sp.Port = u.Port() - if u.Path != "" { - return nil, errors.Errorf("extra path after the host: %q", u.Path) - } + sp.Path = u.Path if u.RawQuery != "" { return nil, errors.Errorf("extra query after the host: %q", u.RawQuery) } @@ -47,6 +45,7 @@ type Spec struct { User string Host string Port string + Path string } // Args returns args except "ssh" itself combined with optional additional command args diff --git a/vendor/github.com/docker/cli/cli/context/docker/load.go b/vendor/github.com/docker/cli/cli/context/docker/load.go index 09ec4050..76f6eaf3 100644 --- a/vendor/github.com/docker/cli/cli/context/docker/load.go +++ b/vendor/github.com/docker/cli/cli/context/docker/load.go @@ -25,12 +25,6 @@ type EndpointMeta = context.EndpointMetaBase type Endpoint struct { EndpointMeta TLSData *context.TLSData - - // Deprecated: Use of encrypted TLS private keys has been deprecated, and - // will be removed in a future release. Golang has deprecated support for - // legacy PEM encryption (as specified in RFC 1423), as it is insecure by - // design (see https://go-review.googlesource.com/c/go/+/264159). - TLSPassword string } // WithTLSData loads TLS materials for the endpoint diff --git a/vendor/github.com/docker/cli/cli/context/store/store.go b/vendor/github.com/docker/cli/cli/context/store/store.go index 037464bb..71012523 100644 --- a/vendor/github.com/docker/cli/cli/context/store/store.go +++ b/vendor/github.com/docker/cli/cli/context/store/store.go @@ -494,20 +494,6 @@ func importEndpointTLS(tlsData *ContextTLSData, path string, data []byte) error return nil } -// IsErrContextDoesNotExist checks if the given error is a "context does not exist" condition. -// -// Deprecated: use github.com/docker/docker/errdefs.IsNotFound() -func IsErrContextDoesNotExist(err error) bool { - return errdefs.IsNotFound(err) -} - -// IsErrTLSDataDoesNotExist checks if the given error is a "context does not exist" condition -// -// Deprecated: use github.com/docker/docker/errdefs.IsNotFound() -func IsErrTLSDataDoesNotExist(err error) bool { - return errdefs.IsNotFound(err) -} - type contextdir string func contextdirOf(name string) contextdir { diff --git a/vendor/github.com/docker/cli/cli/flags/options.go b/vendor/github.com/docker/cli/cli/flags/options.go index cea0faf7..03c1f2db 100644 --- a/vendor/github.com/docker/cli/cli/flags/options.go +++ b/vendor/github.com/docker/cli/cli/flags/options.go @@ -83,7 +83,7 @@ func (o *ClientOptions) InstallFlags(flags *pflag.FlagSet) { // opts.ValidateHost is not used here, so as to allow connection helpers hostOpt := opts.NewNamedListOptsRef("hosts", &o.Hosts, nil) - flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") + flags.VarP(hostOpt, "host", "H", "Daemon socket to connect to") flags.StringVarP(&o.Context, "context", "c", "", `Name of the context to use to connect to the daemon (overrides `+client.EnvOverrideHost+` env var and default context set with "docker context use")`) } diff --git a/vendor/github.com/docker/cli/cli/flags/options_deprecated.go b/vendor/github.com/docker/cli/cli/flags/options_deprecated.go deleted file mode 100644 index 97fb7e4e..00000000 --- a/vendor/github.com/docker/cli/cli/flags/options_deprecated.go +++ /dev/null @@ -1,11 +0,0 @@ -package flags - -// CommonOptions are options common to both the client and the daemon. -// -// Deprecated: use [ClientOptions]. -type CommonOptions = ClientOptions - -// NewCommonOptions returns a new CommonOptions -// -// Deprecated: use [NewClientOptions]. -var NewCommonOptions = NewClientOptions diff --git a/vendor/github.com/docker/cli/cli/registry/client/client.go b/vendor/github.com/docker/cli/cli/registry/client/client.go index ba76a34f..86fc7756 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/client.go +++ b/vendor/github.com/docker/cli/cli/registry/client/client.go @@ -10,7 +10,6 @@ import ( "github.com/docker/distribution" "github.com/docker/distribution/reference" distributionclient "github.com/docker/distribution/registry/client" - "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -36,7 +35,7 @@ func NewRegistryClient(resolver AuthConfigResolver, userAgent string, insecure b } // AuthConfigResolver returns Auth Configuration for an index -type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig +type AuthConfigResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig // PutManifestOptions is the data sent to push a manifest type PutManifestOptions struct { diff --git a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go index f69c5c0d..c6987bad 100644 --- a/vendor/github.com/docker/cli/cli/registry/client/endpoint.go +++ b/vendor/github.com/docker/cli/cli/registry/client/endpoint.go @@ -9,7 +9,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/transport" - authtypes "github.com/docker/docker/api/types" + registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/registry" "github.com/pkg/errors" ) @@ -74,7 +74,7 @@ func getDefaultEndpointFromRepoInfo(repoInfo *registry.RepositoryInfo) (registry } // getHTTPTransport builds a transport for use in communicating with a registry -func getHTTPTransport(authConfig authtypes.AuthConfig, endpoint registry.APIEndpoint, repoName string, userAgent string) (http.RoundTripper, error) { +func getHTTPTransport(authConfig registrytypes.AuthConfig, endpoint registry.APIEndpoint, repoName string, userAgent string) (http.RoundTripper, error) { // get the http transport, this will be used in a client to upload manifest base := &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -120,7 +120,7 @@ type existingTokenHandler struct { token string } -func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, params map[string]string) error { +func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token)) return nil } diff --git a/vendor/github.com/docker/cli/cli/streams/in.go b/vendor/github.com/docker/cli/cli/streams/in.go index 44b0de38..1a10f7c8 100644 --- a/vendor/github.com/docker/cli/cli/streams/in.go +++ b/vendor/github.com/docker/cli/cli/streams/in.go @@ -9,38 +9,42 @@ import ( "github.com/moby/term" ) -// In is an input stream used by the DockerCli to read user input +// In is an input stream to read user input. It implements [io.ReadCloser] +// with additional utilities, such as putting the terminal in raw mode. type In struct { commonStream in io.ReadCloser } +// Read implements the [io.Reader] interface. func (i *In) Read(p []byte) (int, error) { return i.in.Read(p) } -// Close implements the Closer interface +// Close implements the [io.Closer] interface. func (i *In) Close() error { return i.in.Close() } -// SetRawTerminal sets raw mode on the input terminal +// SetRawTerminal sets raw mode on the input terminal. It is a no-op if In +// is not a TTY, or if the "NORAW" environment variable is set to a non-empty +// value. func (i *In) SetRawTerminal() (err error) { - if os.Getenv("NORAW") != "" || !i.commonStream.isTerminal { + if !i.isTerminal || os.Getenv("NORAW") != "" { return nil } - i.commonStream.state, err = term.SetRawTerminal(i.commonStream.fd) + i.state, err = term.SetRawTerminal(i.fd) return err } -// CheckTty checks if we are trying to attach to a container tty -// from a non-tty client input stream, and if so, returns an error. +// CheckTty checks if we are trying to attach to a container TTY +// from a non-TTY client input stream, and if so, returns an error. func (i *In) CheckTty(attachStdin, ttyMode bool) error { // In order to attach to a container tty, input stream for the client must // be a tty itself: redirecting or piping the client standard input is // incompatible with `docker run -t`, `docker exec -t` or `docker attach`. if ttyMode && attachStdin && !i.isTerminal { - eText := "the input device is not a TTY" + const eText = "the input device is not a TTY" if runtime.GOOS == "windows" { return errors.New(eText + ". If you are using mintty, try prefixing the command with 'winpty'") } @@ -49,8 +53,9 @@ func (i *In) CheckTty(attachStdin, ttyMode bool) error { return nil } -// NewIn returns a new In object from a ReadCloser +// NewIn returns a new [In] from an [io.ReadCloser]. func NewIn(in io.ReadCloser) *In { - fd, isTerminal := term.GetFdInfo(in) - return &In{commonStream: commonStream{fd: fd, isTerminal: isTerminal}, in: in} + i := &In{in: in} + i.fd, i.isTerminal = term.GetFdInfo(in) + return i } diff --git a/vendor/github.com/docker/cli/cli/streams/out.go b/vendor/github.com/docker/cli/cli/streams/out.go index 95e21464..2383b085 100644 --- a/vendor/github.com/docker/cli/cli/streams/out.go +++ b/vendor/github.com/docker/cli/cli/streams/out.go @@ -8,8 +8,9 @@ import ( "github.com/sirupsen/logrus" ) -// Out is an output stream used by the DockerCli to write normal program -// output. +// Out is an output stream to write normal program output. It implements +// an [io.Writer], with additional utilities for detecting whether a terminal +// is connected, getting the TTY size, and putting the terminal in raw mode. type Out struct { commonStream out io.Writer @@ -19,23 +20,29 @@ func (o *Out) Write(p []byte) (int, error) { return o.out.Write(p) } -// SetRawTerminal sets raw mode on the input terminal +// SetRawTerminal puts the output of the terminal connected to the stream +// into raw mode. +// +// On UNIX, this does nothing. On Windows, it disables LF -> CRLF/ translation. +// It is a no-op if Out is not a TTY, or if the "NORAW" environment variable is +// set to a non-empty value. func (o *Out) SetRawTerminal() (err error) { - if os.Getenv("NORAW") != "" || !o.commonStream.isTerminal { + if !o.isTerminal || os.Getenv("NORAW") != "" { return nil } - o.commonStream.state, err = term.SetRawTerminalOutput(o.commonStream.fd) + o.state, err = term.SetRawTerminalOutput(o.fd) return err } -// GetTtySize returns the height and width in characters of the tty -func (o *Out) GetTtySize() (uint, uint) { +// GetTtySize returns the height and width in characters of the TTY, or +// zero for both if no TTY is connected. +func (o *Out) GetTtySize() (height uint, width uint) { if !o.isTerminal { return 0, 0 } ws, err := term.GetWinsize(o.fd) if err != nil { - logrus.Debugf("Error getting size: %s", err) + logrus.WithError(err).Debug("Error getting TTY size") if ws == nil { return 0, 0 } @@ -43,8 +50,9 @@ func (o *Out) GetTtySize() (uint, uint) { return uint(ws.Height), uint(ws.Width) } -// NewOut returns a new Out object from a Writer +// NewOut returns a new [Out] from an [io.Writer]. func NewOut(out io.Writer) *Out { - fd, isTerminal := term.GetFdInfo(out) - return &Out{commonStream: commonStream{fd: fd, isTerminal: isTerminal}, out: out} + o := &Out{out: out} + o.fd, o.isTerminal = term.GetFdInfo(out) + return o } diff --git a/vendor/github.com/docker/cli/cli/streams/stream.go b/vendor/github.com/docker/cli/cli/streams/stream.go index 21f0e452..54c9cda0 100644 --- a/vendor/github.com/docker/cli/cli/streams/stream.go +++ b/vendor/github.com/docker/cli/cli/streams/stream.go @@ -4,31 +4,32 @@ import ( "github.com/moby/term" ) -// commonStream is an input stream used by the DockerCli to read user input type commonStream struct { fd uintptr isTerminal bool state *term.State } -// FD returns the file descriptor number for this stream +// FD returns the file descriptor number for this stream. func (s *commonStream) FD() uintptr { return s.fd } -// IsTerminal returns true if this stream is connected to a terminal +// IsTerminal returns true if this stream is connected to a terminal. func (s *commonStream) IsTerminal() bool { return s.isTerminal } -// RestoreTerminal restores normal mode to the terminal +// RestoreTerminal restores normal mode to the terminal. func (s *commonStream) RestoreTerminal() { if s.state != nil { - term.RestoreTerminal(s.fd, s.state) + _ = term.RestoreTerminal(s.fd, s.state) } } -// SetIsTerminal sets the boolean used for isTerminal +// SetIsTerminal overrides whether a terminal is connected. It is used to +// override this property in unit-tests, and should not be depended on for +// other purposes. func (s *commonStream) SetIsTerminal(isTerminal bool) { s.isTerminal = isTerminal } diff --git a/vendor/github.com/docker/cli/cli/trust/trust.go b/vendor/github.com/docker/cli/cli/trust/trust.go index 457f799f..5a862e7f 100644 --- a/vendor/github.com/docker/cli/cli/trust/trust.go +++ b/vendor/github.com/docker/cli/cli/trust/trust.go @@ -17,7 +17,6 @@ import ( "github.com/docker/distribution/registry/client/auth" "github.com/docker/distribution/registry/client/auth/challenge" "github.com/docker/distribution/registry/client/transport" - "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/registry" "github.com/docker/go-connections/tlsconfig" @@ -79,24 +78,23 @@ func Server(index *registrytypes.IndexInfo) (string, error) { } type simpleCredentialStore struct { - auth types.AuthConfig + auth registrytypes.AuthConfig } -func (scs simpleCredentialStore) Basic(u *url.URL) (string, string) { +func (scs simpleCredentialStore) Basic(*url.URL) (string, string) { return scs.auth.Username, scs.auth.Password } -func (scs simpleCredentialStore) RefreshToken(u *url.URL, service string) string { +func (scs simpleCredentialStore) RefreshToken(*url.URL, string) string { return scs.auth.IdentityToken } -func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) { -} +func (scs simpleCredentialStore) SetRefreshToken(*url.URL, string, string) {} // GetNotaryRepository returns a NotaryRepository which stores all the // information needed to operate on a notary repository. // It creates an HTTP transport providing authentication support. -func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *types.AuthConfig, actions ...string) (client.Repository, error) { +func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo *registry.RepositoryInfo, authConfig *registrytypes.AuthConfig, actions ...string) (client.Repository, error) { server, err := Server(repoInfo.Index) if err != nil { return nil, err @@ -160,7 +158,7 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo scope := auth.RepositoryScope{ Repository: repoInfo.Name.Name(), Actions: actions, - Class: repoInfo.Class, + Class: repoInfo.Class, // TODO(thaJeztah): Class is no longer needed for plugins and can likely be removed; see https://github.com/docker/cli/pull/4114#discussion_r1145430825 } creds := simpleCredentialStore{auth: *authConfig} tokenHandlerOptions := auth.TokenHandlerOptions{ @@ -292,7 +290,7 @@ func GetSignableRoles(repo client.Repository, target *client.Target) ([]data.Rol // ImageRefAndAuth contains all reference information and the auth config for an image request type ImageRefAndAuth struct { original string - authConfig *types.AuthConfig + authConfig *registrytypes.AuthConfig reference reference.Named repoInfo *registry.RepositoryInfo tag string @@ -301,8 +299,8 @@ type ImageRefAndAuth struct { // GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name // as an ImageRefAndAuth struct -func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service, - authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig, +func GetImageReferencesAndAuth(ctx context.Context, + authResolver func(ctx context.Context, index *registrytypes.IndexInfo) registrytypes.AuthConfig, imgName string, ) (ImageRefAndAuth, error) { ref, err := reference.ParseNormalizedNamed(imgName) @@ -311,13 +309,7 @@ func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service, } // Resolve the Repository name from fqn to RepositoryInfo - var repoInfo *registry.RepositoryInfo - if rs != nil { - repoInfo, err = rs.ResolveRepository(ref) - } else { - repoInfo, err = registry.ParseRepositoryInfo(ref) - } - + repoInfo, err := registry.ParseRepositoryInfo(ref) if err != nil { return ImageRefAndAuth{}, err } @@ -356,7 +348,7 @@ func getDigest(ref reference.Named) digest.Digest { } // AuthConfig returns the auth information (username, etc) for a given ImageRefAndAuth -func (imgRefAuth *ImageRefAndAuth) AuthConfig() *types.AuthConfig { +func (imgRefAuth *ImageRefAndAuth) AuthConfig() *registrytypes.AuthConfig { return imgRefAuth.authConfig } diff --git a/vendor/github.com/docker/cli/opts/capabilities.go b/vendor/github.com/docker/cli/opts/capabilities.go index 8b578703..82d07185 100644 --- a/vendor/github.com/docker/cli/opts/capabilities.go +++ b/vendor/github.com/docker/cli/opts/capabilities.go @@ -21,15 +21,15 @@ const ( // This function only handles rudimentary formatting; no validation is performed, // as the list of available capabilities can be updated over time, thus should be // handled by the daemon. -func NormalizeCapability(cap string) string { - cap = strings.ToUpper(strings.TrimSpace(cap)) - if cap == AllCapabilities || cap == ResetCapabilities { - return cap +func NormalizeCapability(capability string) string { + capability = strings.ToUpper(strings.TrimSpace(capability)) + if capability == AllCapabilities || capability == ResetCapabilities { + return capability } - if !strings.HasPrefix(cap, "CAP_") { - cap = "CAP_" + cap + if !strings.HasPrefix(capability, "CAP_") { + capability = "CAP_" + capability } - return cap + return capability } // CapabilitiesMap normalizes the given capabilities and converts them to a map. diff --git a/vendor/modules.txt b/vendor/modules.txt index 30ba41f8..c3e09ab0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -228,7 +228,7 @@ github.com/davecgh/go-spew/spew # github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa ## explicit; go 1.18 github.com/distribution/distribution/v3/reference -# github.com/docker/cli v23.0.6+incompatible +# github.com/docker/cli v24.0.0+incompatible ## explicit github.com/docker/cli/cli github.com/docker/cli/cli-plugins/manager