forked from toolshed/abra
chore: make deps
This commit is contained in:
12
vendor/github.com/docker/cli/AUTHORS
generated
vendored
12
vendor/github.com/docker/cli/AUTHORS
generated
vendored
@ -63,6 +63,7 @@ Andreas Köhler <andi5.py@gmx.net>
|
||||
Andres G. Aragoneses <knocte@gmail.com>
|
||||
Andres Leon Rangel <aleon1220@gmail.com>
|
||||
Andrew France <andrew@avito.co.uk>
|
||||
Andrew He <he.andrew.mail@gmail.com>
|
||||
Andrew Hsu <andrewhsu@docker.com>
|
||||
Andrew Macpherson <hopscotch23@gmail.com>
|
||||
Andrew McDonnell <bugs@andrewmcdonnell.net>
|
||||
@ -86,11 +87,12 @@ Archimedes Trajano <developer@trajano.net>
|
||||
Arko Dasgupta <arko@tetrate.io>
|
||||
Arnaud Porterie <icecrime@gmail.com>
|
||||
Arnaud Rebillout <elboulangero@gmail.com>
|
||||
Arthur Flageul <arthur.flageul@gmail.com>
|
||||
Arthur Peka <arthur.peka@outlook.com>
|
||||
Ashly Mathew <ashly.mathew@sap.com>
|
||||
Ashwini Oruganti <ashwini.oruganti@gmail.com>
|
||||
Aslam Ahemad <aslamahemad@gmail.com>
|
||||
Austin Vazquez <austin.vazquez.dev@gmail.com>
|
||||
Austin Vazquez <austin.vazquez@docker.com>
|
||||
Azat Khuyiyakhmetov <shadow_uz@mail.ru>
|
||||
Bardia Keyoumarsi <bkeyouma@ucsc.edu>
|
||||
Barnaby Gray <barnaby@pickle.me.uk>
|
||||
@ -135,10 +137,12 @@ Cao Weiwei <cao.weiwei30@zte.com.cn>
|
||||
Carlo Mion <mion00@gmail.com>
|
||||
Carlos Alexandro Becker <caarlos0@gmail.com>
|
||||
Carlos de Paula <me@carlosedp.com>
|
||||
carsontham <carsontham@outlook.com>
|
||||
Carston Schilds <Carston.Schilds@visier.com>
|
||||
Casey Korver <casey@korver.dev>
|
||||
Ce Gao <ce.gao@outlook.com>
|
||||
Cedric Davies <cedricda@microsoft.com>
|
||||
Cesar Talledo <cesar.talledo@docker.com>
|
||||
Cezar Sa Espinola <cezarsa@gmail.com>
|
||||
Chad Faragher <wyckster@hotmail.com>
|
||||
Chao Wang <wangchao.fnst@cn.fujitsu.com>
|
||||
@ -220,7 +224,7 @@ David Alvarez <david.alvarez@flyeralarm.com>
|
||||
David Beitey <david@davidjb.com>
|
||||
David Calavera <david.calavera@gmail.com>
|
||||
David Cramer <davcrame@cisco.com>
|
||||
David Dooling <dooling@gmail.com>
|
||||
David Dooling <david.dooling@docker.com>
|
||||
David Gageot <david@gageot.net>
|
||||
David Karlsson <david.karlsson@docker.com>
|
||||
David le Blanc <systemmonkey42@users.noreply.github.com>
|
||||
@ -265,6 +269,7 @@ Eli Uriegas <eli.uriegas@docker.com>
|
||||
Eli Uriegas <seemethere101@gmail.com>
|
||||
Elias Faxö <elias.faxo@tre.se>
|
||||
Elliot Luo <956941328@qq.com>
|
||||
Eng Zer Jun <engzerjun@gmail.com>
|
||||
Eric Bode <eric.bode@foundries.io>
|
||||
Eric Curtin <ericcurtin17@gmail.com>
|
||||
Eric Engestrom <eric@engestrom.ch>
|
||||
@ -345,6 +350,7 @@ Henning Sprang <henning.sprang@gmail.com>
|
||||
Henry N <henrynmail-github@yahoo.de>
|
||||
Hernan Garcia <hernandanielg@gmail.com>
|
||||
Hongbin Lu <hongbin034@gmail.com>
|
||||
Hossein Abbasi <16090309+hsnabszhdn@users.noreply.github.com>
|
||||
Hu Keping <hukeping@huawei.com>
|
||||
Huayi Zhang <irachex@gmail.com>
|
||||
Hugo Chastel <Hugo-C@users.noreply.github.com>
|
||||
@ -595,6 +601,7 @@ Michael Prokop <github@michael-prokop.at>
|
||||
Michael Scharf <github@scharf.gr>
|
||||
Michael Spetsiotis <michael_spets@hotmail.com>
|
||||
Michael Steinert <mike.steinert@gmail.com>
|
||||
Michael Tews <michael@tews.dev>
|
||||
Michael West <mwest@mdsol.com>
|
||||
Michal Minář <miminar@redhat.com>
|
||||
Michał Czeraszkiewicz <czerasz@gmail.com>
|
||||
@ -896,6 +903,7 @@ Wenlong Zhang <zhangwenlong@loongson.cn>
|
||||
Wenzhi Liang <wenzhi.liang@gmail.com>
|
||||
Wes Morgan <cap10morgan@gmail.com>
|
||||
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
|
||||
Will Wang <willww64@gmail.com>
|
||||
William Henry <whenry@redhat.com>
|
||||
Xianglin Gao <xlgao@zju.edu.cn>
|
||||
Xiaodong Liu <liuxiaodong@loongson.cn>
|
||||
|
||||
2
vendor/github.com/docker/cli/cli-plugins/metadata/metadata.go
generated
vendored
2
vendor/github.com/docker/cli/cli-plugins/metadata/metadata.go
generated
vendored
@ -33,4 +33,6 @@ type Metadata struct {
|
||||
ShortDescription string `json:",omitempty"`
|
||||
// URL is a pointer to the plugin's homepage.
|
||||
URL string `json:",omitempty"`
|
||||
// Hidden hides the plugin in completion and help message output.
|
||||
Hidden bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
42
vendor/github.com/docker/cli/cli/cobra.go
generated
vendored
42
vendor/github.com/docker/cli/cli/cobra.go
generated
vendored
@ -12,7 +12,6 @@ import (
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/moby/term"
|
||||
"github.com/morikuni/aec"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@ -167,31 +166,6 @@ func (tcmd *TopLevelCommand) Initialize(ops ...command.CLIOption) error {
|
||||
return tcmd.dockerCli.Initialize(tcmd.opts, ops...)
|
||||
}
|
||||
|
||||
// VisitAll will traverse all commands from the root.
|
||||
//
|
||||
// Deprecated: this utility was only used internally and will be removed in the next release.
|
||||
func VisitAll(root *cobra.Command, fn func(*cobra.Command)) {
|
||||
visitAll(root, fn)
|
||||
}
|
||||
|
||||
func visitAll(root *cobra.Command, fn func(*cobra.Command)) {
|
||||
for _, cmd := range root.Commands() {
|
||||
visitAll(cmd, fn)
|
||||
}
|
||||
fn(root)
|
||||
}
|
||||
|
||||
// DisableFlagsInUseLine sets the DisableFlagsInUseLine flag on all
|
||||
// commands within the tree rooted at cmd.
|
||||
//
|
||||
// Deprecated: this utility was only used internally and will be removed in the next release.
|
||||
func DisableFlagsInUseLine(cmd *cobra.Command) {
|
||||
visitAll(cmd, func(ccmd *cobra.Command) {
|
||||
// do not add a `[flags]` to the end of the usage line.
|
||||
ccmd.DisableFlagsInUseLine = true
|
||||
})
|
||||
}
|
||||
|
||||
var helpCommand = &cobra.Command{
|
||||
Use: "help [command]",
|
||||
Short: "Help about the command",
|
||||
@ -200,7 +174,7 @@ var helpCommand = &cobra.Command{
|
||||
RunE: func(c *cobra.Command, args []string) error {
|
||||
cmd, args, e := c.Root().Find(args)
|
||||
if cmd == nil || e != nil || len(args) > 0 {
|
||||
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
|
||||
return fmt.Errorf("unknown help topic: %v", strings.Join(args, " "))
|
||||
}
|
||||
helpFunc := cmd.HelpFunc()
|
||||
helpFunc(cmd, args)
|
||||
@ -276,11 +250,12 @@ func commandAliases(cmd *cobra.Command) string {
|
||||
if cmd.HasParent() {
|
||||
parentPath = cmd.Parent().CommandPath() + " "
|
||||
}
|
||||
aliases := cmd.CommandPath()
|
||||
var aliases strings.Builder
|
||||
aliases.WriteString(cmd.CommandPath())
|
||||
for _, alias := range cmd.Aliases {
|
||||
aliases += ", " + parentPath + alias
|
||||
aliases.WriteString(", " + parentPath + alias)
|
||||
}
|
||||
return aliases
|
||||
return aliases.String()
|
||||
}
|
||||
|
||||
func topCommands(cmd *cobra.Command) []*cobra.Command {
|
||||
@ -376,13 +351,10 @@ func orchestratorSubCommands(cmd *cobra.Command) []*cobra.Command {
|
||||
func allManagementSubCommands(cmd *cobra.Command) []*cobra.Command {
|
||||
cmds := []*cobra.Command{}
|
||||
for _, sub := range cmd.Commands() {
|
||||
if isPlugin(sub) {
|
||||
if invalidPluginReason(sub) == "" {
|
||||
cmds = append(cmds, sub)
|
||||
}
|
||||
if invalidPluginReason(sub) != "" {
|
||||
continue
|
||||
}
|
||||
if sub.IsAvailableCommand() && sub.HasSubCommands() {
|
||||
if sub.IsAvailableCommand() && (isPlugin(sub) || sub.HasSubCommands()) {
|
||||
cmds = append(cmds, sub)
|
||||
}
|
||||
}
|
||||
|
||||
91
vendor/github.com/docker/cli/cli/command/cli.go
generated
vendored
91
vendor/github.com/docker/cli/cli/command/cli.go
generated
vendored
@ -1,10 +1,11 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -23,11 +24,8 @@ import (
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/cli/cli/version"
|
||||
dopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -45,12 +43,9 @@ type Cli interface {
|
||||
Client() client.APIClient
|
||||
Streams
|
||||
SetIn(in *streams.In)
|
||||
Apply(ops ...CLIOption) error
|
||||
config.Provider
|
||||
ServerInfo() ServerInfo
|
||||
DefaultVersion() string
|
||||
CurrentVersion() string
|
||||
ContentTrustEnabled() bool
|
||||
BuildKitEnabled() (bool, error)
|
||||
ContextStore() store.Store
|
||||
CurrentContext() string
|
||||
@ -70,7 +65,6 @@ type DockerCli struct {
|
||||
err *streams.Out
|
||||
client client.APIClient
|
||||
serverInfo ServerInfo
|
||||
contentTrust bool
|
||||
contextStore store.Store
|
||||
currentContext string
|
||||
init sync.Once
|
||||
@ -78,6 +72,7 @@ type DockerCli struct {
|
||||
dockerEndpoint docker.Endpoint
|
||||
contextStoreConfig *store.Config
|
||||
initTimeout time.Duration
|
||||
userAgent string
|
||||
res telemetryResource
|
||||
|
||||
// baseCtx is the base context used for internal operations. In the future
|
||||
@ -88,17 +83,12 @@ type DockerCli struct {
|
||||
enableGlobalMeter, enableGlobalTracer bool
|
||||
}
|
||||
|
||||
// DefaultVersion returns [api.DefaultVersion].
|
||||
func (*DockerCli) DefaultVersion() string {
|
||||
return api.DefaultVersion
|
||||
}
|
||||
|
||||
// CurrentVersion returns the API version currently negotiated, or the default
|
||||
// version otherwise.
|
||||
func (cli *DockerCli) CurrentVersion() string {
|
||||
_ = cli.initialize()
|
||||
if cli.client == nil {
|
||||
return api.DefaultVersion
|
||||
return client.MaxAPIVersion
|
||||
}
|
||||
return cli.client.ClientVersion()
|
||||
}
|
||||
@ -157,19 +147,13 @@ func (cli *DockerCli) ServerInfo() ServerInfo {
|
||||
return cli.serverInfo
|
||||
}
|
||||
|
||||
// ContentTrustEnabled returns whether content trust has been enabled by an
|
||||
// environment variable.
|
||||
func (cli *DockerCli) ContentTrustEnabled() bool {
|
||||
return cli.contentTrust
|
||||
}
|
||||
|
||||
// BuildKitEnabled returns buildkit is enabled or not.
|
||||
func (cli *DockerCli) BuildKitEnabled() (bool, error) {
|
||||
// use DOCKER_BUILDKIT env var value if set and not empty
|
||||
if v := os.Getenv("DOCKER_BUILDKIT"); v != "" {
|
||||
enabled, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "DOCKER_BUILDKIT environment variable expects boolean value")
|
||||
return false, fmt.Errorf("DOCKER_BUILDKIT environment variable expects boolean value: %w", err)
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
@ -269,7 +253,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
|
||||
cli.contextStore = &ContextStoreWithDefault{
|
||||
Store: store.New(config.ContextStoreDir(), *cli.contextStoreConfig),
|
||||
Resolver: func() (*DefaultContext, error) {
|
||||
return ResolveDefaultContext(cli.options, *cli.contextStoreConfig)
|
||||
return resolveDefaultContext(cli.options, *cli.contextStoreConfig)
|
||||
},
|
||||
}
|
||||
|
||||
@ -306,17 +290,17 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
|
||||
contextStore := &ContextStoreWithDefault{
|
||||
Store: store.New(config.ContextStoreDir(), storeConfig),
|
||||
Resolver: func() (*DefaultContext, error) {
|
||||
return ResolveDefaultContext(opts, storeConfig)
|
||||
return resolveDefaultContext(opts, storeConfig)
|
||||
},
|
||||
}
|
||||
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
|
||||
return nil, fmt.Errorf("unable to resolve docker endpoint: %w", err)
|
||||
}
|
||||
return newAPIClientFromEndpoint(endpoint, configFile)
|
||||
return newAPIClientFromEndpoint(endpoint, configFile, client.WithUserAgent(UserAgent()))
|
||||
}
|
||||
|
||||
func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigFile) (client.APIClient, error) {
|
||||
func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigFile, extraOpts ...client.Opt) (client.APIClient, error) {
|
||||
opts, err := ep.ClientOpts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -324,8 +308,15 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
|
||||
if len(configFile.HTTPHeaders) > 0 {
|
||||
opts = append(opts, client.WithHTTPHeaders(configFile.HTTPHeaders))
|
||||
}
|
||||
opts = append(opts, withCustomHeadersFromEnv(), client.WithUserAgent(UserAgent()))
|
||||
return client.NewClientWithOpts(opts...)
|
||||
withCustomHeaders, err := withCustomHeadersFromEnv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if withCustomHeaders != nil {
|
||||
opts = append(opts, withCustomHeaders)
|
||||
}
|
||||
opts = append(opts, extraOpts...)
|
||||
return client.New(opts...)
|
||||
}
|
||||
|
||||
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
|
||||
@ -386,24 +377,21 @@ func (cli *DockerCli) initializeFromClient() {
|
||||
ctx, cancel := context.WithTimeout(cli.baseCtx, cli.getInitTimeout())
|
||||
defer cancel()
|
||||
|
||||
ping, err := cli.client.Ping(ctx)
|
||||
ping, err := cli.client.Ping(ctx, client.PingOptions{
|
||||
NegotiateAPIVersion: true,
|
||||
ForceNegotiate: true,
|
||||
})
|
||||
if err != nil {
|
||||
// Default to true if we fail to connect to daemon
|
||||
cli.serverInfo = ServerInfo{HasExperimental: true}
|
||||
|
||||
if ping.APIVersion != "" {
|
||||
cli.client.NegotiateAPIVersionPing(ping)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
cli.serverInfo = ServerInfo{
|
||||
HasExperimental: ping.Experimental,
|
||||
OSType: ping.OSType,
|
||||
BuildkitVersion: ping.BuilderVersion,
|
||||
SwarmStatus: ping.SwarmStatus,
|
||||
}
|
||||
cli.client.NegotiateAPIVersionPing(ping)
|
||||
}
|
||||
|
||||
// ContextStore returns the ContextStore
|
||||
@ -541,11 +529,12 @@ func (cli *DockerCli) initialize() error {
|
||||
cli.init.Do(func() {
|
||||
cli.dockerEndpoint, cli.initErr = cli.getDockerEndPoint()
|
||||
if cli.initErr != nil {
|
||||
cli.initErr = errors.Wrap(cli.initErr, "unable to resolve docker endpoint")
|
||||
cli.initErr = fmt.Errorf("unable to resolve docker endpoint: %w", cli.initErr)
|
||||
return
|
||||
}
|
||||
if cli.client == nil {
|
||||
if cli.client, cli.initErr = newAPIClientFromEndpoint(cli.dockerEndpoint, cli.configFile); cli.initErr != nil {
|
||||
ops := []client.Opt{client.WithUserAgent(cli.userAgent)}
|
||||
if cli.client, cli.initErr = newAPIClientFromEndpoint(cli.dockerEndpoint, cli.configFile, ops...); cli.initErr != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -557,16 +546,6 @@ func (cli *DockerCli) initialize() error {
|
||||
return cli.initErr
|
||||
}
|
||||
|
||||
// Apply all the operation on the cli
|
||||
func (cli *DockerCli) Apply(ops ...CLIOption) error {
|
||||
for _, op := range ops {
|
||||
if err := op(cli); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ServerInfo stores details about the supported features and platform of the
|
||||
// server
|
||||
type ServerInfo struct {
|
||||
@ -581,7 +560,7 @@ type ServerInfo struct {
|
||||
// in the ping response, or if an error occurred, in which case the client
|
||||
// should use other ways to get the current swarm status, such as the /swarm
|
||||
// endpoint.
|
||||
SwarmStatus *swarm.Status
|
||||
SwarmStatus *client.SwarmStatus
|
||||
}
|
||||
|
||||
// NewDockerCli returns a DockerCli instance with all operators applied on it.
|
||||
@ -589,15 +568,17 @@ type ServerInfo struct {
|
||||
// environment.
|
||||
func NewDockerCli(ops ...CLIOption) (*DockerCli, error) {
|
||||
defaultOps := []CLIOption{
|
||||
WithContentTrustFromEnv(),
|
||||
WithDefaultContextStoreConfig(),
|
||||
WithStandardStreams(),
|
||||
WithUserAgent(UserAgent()),
|
||||
}
|
||||
ops = append(defaultOps, ops...)
|
||||
|
||||
cli := &DockerCli{baseCtx: context.Background()}
|
||||
if err := cli.Apply(ops...); err != nil {
|
||||
return nil, err
|
||||
for _, op := range ops {
|
||||
if err := op(cli); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
@ -609,11 +590,11 @@ func getServerHost(hosts []string, defaultToTLS bool) (string, error) {
|
||||
case 1:
|
||||
return dopts.ParseHost(defaultToTLS, hosts[0])
|
||||
default:
|
||||
return "", errors.New("Specify only one -H")
|
||||
return "", errors.New("specify only one -H")
|
||||
}
|
||||
}
|
||||
|
||||
// UserAgent returns the user agent string used for making API requests
|
||||
// UserAgent returns the default user agent string used for making API requests.
|
||||
func UserAgent() string {
|
||||
return "Docker-Client/" + version.Version + " (" + runtime.GOOS + ")"
|
||||
}
|
||||
|
||||
133
vendor/github.com/docker/cli/cli/command/cli_options.go
generated
vendored
133
vendor/github.com/docker/cli/cli/command/cli_options.go
generated
vendored
@ -3,16 +3,16 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/term"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// CLIOption is a functional argument to apply options to a [DockerCli]. These
|
||||
@ -75,28 +75,6 @@ func WithErrorStream(err io.Writer) CLIOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithContentTrustFromEnv enables content trust on a cli from environment variable DOCKER_CONTENT_TRUST value.
|
||||
func WithContentTrustFromEnv() CLIOption {
|
||||
return func(cli *DockerCli) error {
|
||||
cli.contentTrust = false
|
||||
if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
|
||||
if t, err := strconv.ParseBool(e); t || err != nil {
|
||||
// treat any other value as true
|
||||
cli.contentTrust = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithContentTrust enables content trust on a cli.
|
||||
func WithContentTrust(enabled bool) CLIOption {
|
||||
return func(cli *DockerCli) error {
|
||||
cli.contentTrust = enabled
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDefaultContextStoreConfig configures the cli to use the default context store configuration.
|
||||
func WithDefaultContextStoreConfig() CLIOption {
|
||||
return func(cli *DockerCli) error {
|
||||
@ -180,61 +158,70 @@ const envOverrideHTTPHeaders = "DOCKER_CUSTOM_HEADERS"
|
||||
// override headers with the same name).
|
||||
//
|
||||
// TODO(thaJeztah): this is a client Option, and should be moved to the client. It is non-exported for that reason.
|
||||
func withCustomHeadersFromEnv() client.Opt {
|
||||
return func(apiClient *client.Client) error {
|
||||
value := os.Getenv(envOverrideHTTPHeaders)
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
csvReader := csv.NewReader(strings.NewReader(value))
|
||||
fields, err := csvReader.Read()
|
||||
if err != nil {
|
||||
return invalidParameter(errors.Errorf(
|
||||
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
|
||||
envOverrideHTTPHeaders,
|
||||
func withCustomHeadersFromEnv() (client.Opt, error) {
|
||||
value := os.Getenv(envOverrideHTTPHeaders)
|
||||
if value == "" {
|
||||
return nil, nil
|
||||
}
|
||||
csvReader := csv.NewReader(strings.NewReader(value))
|
||||
fields, err := csvReader.Read()
|
||||
if err != nil {
|
||||
return nil, invalidParameter(fmt.Errorf(
|
||||
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
|
||||
envOverrideHTTPHeaders,
|
||||
))
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
env := map[string]string{}
|
||||
for _, kv := range fields {
|
||||
k, v, hasValue := strings.Cut(kv, "=")
|
||||
|
||||
// Only strip whitespace in keys; preserve whitespace in values.
|
||||
k = strings.TrimSpace(k)
|
||||
|
||||
if k == "" {
|
||||
return nil, invalidParameter(fmt.Errorf(
|
||||
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
|
||||
// We don't currently allow empty key=value pairs, and produce an error.
|
||||
// This is something we could allow in future (e.g. to read value
|
||||
// from an environment variable with the same name). In the meantime,
|
||||
// produce an error to prevent users from depending on this.
|
||||
if !hasValue {
|
||||
return nil, invalidParameter(fmt.Errorf(
|
||||
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
}
|
||||
|
||||
env := map[string]string{}
|
||||
for _, kv := range fields {
|
||||
k, v, hasValue := strings.Cut(kv, "=")
|
||||
env[http.CanonicalHeaderKey(k)] = v
|
||||
}
|
||||
|
||||
// Only strip whitespace in keys; preserve whitespace in values.
|
||||
k = strings.TrimSpace(k)
|
||||
if len(env) == 0 {
|
||||
// We should probably not hit this case, as we don't skip values
|
||||
// (only return errors), but we don't want to discard existing
|
||||
// headers with an empty set.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if k == "" {
|
||||
return invalidParameter(errors.Errorf(
|
||||
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
}
|
||||
// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
|
||||
// see https://github.com/docker/cli/pull/5098#issuecomment-2147403871 (when updating, also update the WARNING in the function and env-var GoDoc)
|
||||
return client.WithHTTPHeaders(env), nil
|
||||
}
|
||||
|
||||
// We don't currently allow empty key=value pairs, and produce an error.
|
||||
// This is something we could allow in future (e.g. to read value
|
||||
// from an environment variable with the same name). In the meantime,
|
||||
// produce an error to prevent users from depending on this.
|
||||
if !hasValue {
|
||||
return invalidParameter(errors.Errorf(
|
||||
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
}
|
||||
|
||||
env[http.CanonicalHeaderKey(k)] = v
|
||||
// WithUserAgent configures the User-Agent string for cli HTTP requests.
|
||||
func WithUserAgent(userAgent string) CLIOption {
|
||||
return func(cli *DockerCli) error {
|
||||
if userAgent == "" {
|
||||
return errors.New("user agent cannot be blank")
|
||||
}
|
||||
|
||||
if len(env) == 0 {
|
||||
// We should probably not hit this case, as we don't skip values
|
||||
// (only return errors), but we don't want to discard existing
|
||||
// headers with an empty set.
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
|
||||
// see https://github.com/docker/cli/pull/5098#issuecomment-2147403871 (when updating, also update the WARNING in the function and env-var GoDoc)
|
||||
return client.WithHTTPHeaders(env)(apiClient)
|
||||
cli.userAgent = userAgent
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/command/context.go
generated
vendored
2
vendor/github.com/docker/cli/cli/command/context.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package command
|
||||
|
||||
|
||||
12
vendor/github.com/docker/cli/cli/command/defaultcontextstore.go
generated
vendored
12
vendor/github.com/docker/cli/cli/command/defaultcontextstore.go
generated
vendored
@ -1,13 +1,15 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/cli/cli/context/docker"
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
cliflags "github.com/docker/cli/cli/flags"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -51,8 +53,8 @@ type EndpointDefaultResolver interface {
|
||||
ResolveDefault() (any, *store.EndpointTLSData, error)
|
||||
}
|
||||
|
||||
// ResolveDefaultContext creates a Metadata for the current CLI invocation parameters
|
||||
func ResolveDefaultContext(opts *cliflags.ClientOptions, config store.Config) (*DefaultContext, error) {
|
||||
// resolveDefaultContext creates a Metadata for the current CLI invocation parameters
|
||||
func resolveDefaultContext(opts *cliflags.ClientOptions, config store.Config) (*DefaultContext, error) {
|
||||
contextTLSData := store.ContextTLSData{
|
||||
Endpoints: make(map[string]store.EndpointTLSData),
|
||||
}
|
||||
@ -185,7 +187,7 @@ func (s *ContextStoreWithDefault) GetTLSData(contextName, endpointName, fileName
|
||||
return nil, err
|
||||
}
|
||||
if defaultContext.TLS.Endpoints[endpointName].Files[fileName] == nil {
|
||||
return nil, notFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
||||
return nil, notFound(fmt.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
||||
}
|
||||
return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/docker/cli/cli/command/formatter/buildcache.go
generated
vendored
10
vendor/github.com/docker/cli/cli/command/formatter/buildcache.go
generated
vendored
@ -6,8 +6,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -51,7 +51,7 @@ shared: {{.Shared}}
|
||||
return Format(source)
|
||||
}
|
||||
|
||||
func buildCacheSort(buildCache []*build.CacheRecord) {
|
||||
func buildCacheSort(buildCache []build.CacheRecord) {
|
||||
sort.Slice(buildCache, func(i, j int) bool {
|
||||
lui, luj := buildCache[i].LastUsedAt, buildCache[j].LastUsedAt
|
||||
switch {
|
||||
@ -70,7 +70,7 @@ func buildCacheSort(buildCache []*build.CacheRecord) {
|
||||
}
|
||||
|
||||
// BuildCacheWrite renders the context for a list of containers
|
||||
func BuildCacheWrite(ctx Context, buildCaches []*build.CacheRecord) error {
|
||||
func BuildCacheWrite(ctx Context, buildCaches []build.CacheRecord) error {
|
||||
render := func(format func(subContext SubContext) error) error {
|
||||
buildCacheSort(buildCaches)
|
||||
for _, bc := range buildCaches {
|
||||
@ -87,7 +87,7 @@ func BuildCacheWrite(ctx Context, buildCaches []*build.CacheRecord) error {
|
||||
type buildCacheContext struct {
|
||||
HeaderContext
|
||||
trunc bool
|
||||
v *build.CacheRecord
|
||||
v build.CacheRecord
|
||||
}
|
||||
|
||||
func newBuildCacheContext() *buildCacheContext {
|
||||
@ -126,8 +126,6 @@ func (c *buildCacheContext) Parent() string {
|
||||
var parent string
|
||||
if len(c.v.Parents) > 0 {
|
||||
parent = strings.Join(c.v.Parents, ", ")
|
||||
} else {
|
||||
parent = c.v.Parent //nolint:staticcheck // Ignore SA1019: Field was deprecated in API v1.42, but kept for backward compatibility
|
||||
}
|
||||
if c.trunc {
|
||||
return TruncateID(parent)
|
||||
|
||||
56
vendor/github.com/docker/cli/cli/command/formatter/container.go
generated
vendored
56
vendor/github.com/docker/cli/cli/command/formatter/container.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package formatter
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@ -170,27 +170,33 @@ func (c *ContainerContext) Image() string {
|
||||
if c.c.Image == "" {
|
||||
return "<no image>"
|
||||
}
|
||||
if c.trunc {
|
||||
if trunc := TruncateID(c.c.ImageID); trunc == TruncateID(c.c.Image) {
|
||||
return trunc
|
||||
if !c.trunc {
|
||||
return c.c.Image
|
||||
}
|
||||
if trunc := TruncateID(c.c.ImageID); trunc == TruncateID(c.c.Image) {
|
||||
return trunc
|
||||
}
|
||||
ref, err := reference.ParseNormalizedNamed(c.c.Image)
|
||||
if err != nil {
|
||||
return c.c.Image
|
||||
}
|
||||
|
||||
if _, ok := ref.(reference.Digested); ok {
|
||||
// strip the digest, but preserve the tag (if any)
|
||||
var tag string
|
||||
if t, ok := ref.(reference.Tagged); ok {
|
||||
tag = t.Tag()
|
||||
}
|
||||
// truncate digest if no-trunc option was not selected
|
||||
ref, err := reference.ParseNormalizedNamed(c.c.Image)
|
||||
if err == nil {
|
||||
if nt, ok := ref.(reference.NamedTagged); ok {
|
||||
// case for when a tag is provided
|
||||
if namedTagged, err := reference.WithTag(reference.TrimNamed(nt), nt.Tag()); err == nil {
|
||||
return reference.FamiliarString(namedTagged)
|
||||
}
|
||||
} else {
|
||||
// case for when a tag is not provided
|
||||
named := reference.TrimNamed(ref)
|
||||
return reference.FamiliarString(named)
|
||||
ref = reference.TrimNamed(ref)
|
||||
if tag != "" {
|
||||
if out, err := reference.WithTag(ref, tag); err == nil {
|
||||
ref = out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.c.Image
|
||||
// Format as "familiar" name with "docker.io[/library]" trimmed.
|
||||
return reference.FamiliarString(ref)
|
||||
}
|
||||
|
||||
// Command returns's the container's command. If the trunc option is set, the
|
||||
@ -241,7 +247,7 @@ func (c *ContainerContext) Ports() string {
|
||||
// State returns the container's current state (e.g. "running" or "paused").
|
||||
// Refer to [container.ContainerState] for possible states.
|
||||
func (c *ContainerContext) State() string {
|
||||
return c.c.State
|
||||
return string(c.c.State)
|
||||
}
|
||||
|
||||
// Status returns the container's status in a human readable form (for example,
|
||||
@ -338,7 +344,7 @@ func (c *ContainerContext) Networks() string {
|
||||
// DisplayablePorts returns formatted string representing open ports of container
|
||||
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
|
||||
// it's used by command 'docker ps'
|
||||
func DisplayablePorts(ports []container.Port) string {
|
||||
func DisplayablePorts(ports []container.PortSummary) string {
|
||||
type portGroup struct {
|
||||
first uint16
|
||||
last uint16
|
||||
@ -354,13 +360,13 @@ func DisplayablePorts(ports []container.Port) string {
|
||||
for _, port := range ports {
|
||||
current := port.PrivatePort
|
||||
portKey := port.Type
|
||||
if port.IP != "" {
|
||||
if port.IP.IsValid() {
|
||||
if port.PublicPort != current {
|
||||
hAddrPort := net.JoinHostPort(port.IP, strconv.Itoa(int(port.PublicPort)))
|
||||
hAddrPort := net.JoinHostPort(port.IP.String(), strconv.Itoa(int(port.PublicPort)))
|
||||
hostMappings = append(hostMappings, fmt.Sprintf("%s->%d/%s", hAddrPort, port.PrivatePort, port.Type))
|
||||
continue
|
||||
}
|
||||
portKey = port.IP + "/" + port.Type
|
||||
portKey = port.IP.String() + "/" + port.Type
|
||||
}
|
||||
group := groupMap[portKey]
|
||||
|
||||
@ -404,13 +410,13 @@ func formGroup(key string, start, last uint16) string {
|
||||
return group + "/" + groupType
|
||||
}
|
||||
|
||||
func comparePorts(i, j container.Port) bool {
|
||||
func comparePorts(i, j container.PortSummary) bool {
|
||||
if i.PrivatePort != j.PrivatePort {
|
||||
return i.PrivatePort < j.PrivatePort
|
||||
}
|
||||
|
||||
if i.IP != j.IP {
|
||||
return i.IP < j.IP
|
||||
return i.IP.String() < j.IP.String()
|
||||
}
|
||||
|
||||
if i.PublicPort != j.PublicPort {
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/command/formatter/custom.go
generated
vendored
2
vendor/github.com/docker/cli/cli/command/formatter/custom.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package formatter
|
||||
|
||||
|
||||
253
vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go
generated
vendored
253
vendor/github.com/docker/cli/cli/command/formatter/disk_usage.go
generated
vendored
@ -7,19 +7,20 @@ import (
|
||||
"text/template"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultDiskUsageImageTableFormat = "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}\t{{.SharedSize}}\t{{.UniqueSize}}\t{{.Containers}}"
|
||||
defaultDiskUsageContainerTableFormat = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.Size}}\t{{.RunningFor}}\t{{.Status}}\t{{.Names}}"
|
||||
defaultDiskUsageVolumeTableFormat = "table {{.Name}}\t{{.Links}}\t{{.Size}}"
|
||||
defaultDiskUsageBuildCacheTableFormat = "table {{.ID}}\t{{.CacheType}}\t{{.Size}}\t{{.CreatedSince}}\t{{.LastUsedSince}}\t{{.UsageCount}}\t{{.Shared}}"
|
||||
defaultDiskUsageTableFormat = "table {{.Type}}\t{{.TotalCount}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}"
|
||||
defaultDiskUsageImageTableFormat Format = "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedSince}}\t{{.Size}}\t{{.SharedSize}}\t{{.UniqueSize}}\t{{.Containers}}"
|
||||
defaultDiskUsageContainerTableFormat Format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.Size}}\t{{.RunningFor}}\t{{.Status}}\t{{.Names}}"
|
||||
defaultDiskUsageVolumeTableFormat Format = "table {{.Name}}\t{{.Links}}\t{{.Size}}"
|
||||
defaultDiskUsageBuildCacheTableFormat Format = "table {{.ID}}\t{{.CacheType}}\t{{.Size}}\t{{.CreatedSince}}\t{{.LastUsedSince}}\t{{.UsageCount}}\t{{.Shared}}"
|
||||
defaultDiskUsageTableFormat Format = "table {{.Type}}\t{{.TotalCount}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}"
|
||||
|
||||
typeHeader = "TYPE"
|
||||
totalHeader = "TOTAL"
|
||||
@ -33,19 +34,18 @@ const (
|
||||
// DiskUsageContext contains disk usage specific information required by the formatter, encapsulate a Context struct.
|
||||
type DiskUsageContext struct {
|
||||
Context
|
||||
Verbose bool
|
||||
LayersSize int64
|
||||
Images []*image.Summary
|
||||
Containers []*container.Summary
|
||||
Volumes []*volume.Volume
|
||||
BuildCache []*build.CacheRecord
|
||||
BuilderSize int64
|
||||
Verbose bool
|
||||
|
||||
ImageDiskUsage client.ImagesDiskUsage
|
||||
BuildCacheDiskUsage client.BuildCacheDiskUsage
|
||||
ContainerDiskUsage client.ContainersDiskUsage
|
||||
VolumeDiskUsage client.VolumesDiskUsage
|
||||
}
|
||||
|
||||
func (ctx *DiskUsageContext) startSubsection(format string) (*template.Template, error) {
|
||||
func (ctx *DiskUsageContext) startSubsection(format Format) (*template.Template, error) {
|
||||
ctx.buffer = &bytes.Buffer{}
|
||||
ctx.header = ""
|
||||
ctx.Format = Format(format)
|
||||
ctx.Format = format
|
||||
ctx.preFormat()
|
||||
|
||||
return ctx.parseFormat()
|
||||
@ -69,7 +69,7 @@ func NewDiskUsageFormat(source string, verbose bool) Format {
|
||||
{{end -}}`
|
||||
return format
|
||||
case !verbose && source == TableFormatKey:
|
||||
return Format(defaultDiskUsageTableFormat)
|
||||
return defaultDiskUsageTableFormat
|
||||
case !verbose && source == RawFormatKey:
|
||||
format := `type: {{.Type}}
|
||||
total: {{.TotalCount}}
|
||||
@ -96,35 +96,49 @@ func (ctx *DiskUsageContext) Write() (err error) {
|
||||
}
|
||||
|
||||
err = ctx.contextFormat(tmpl, &diskUsageImagesContext{
|
||||
totalSize: ctx.LayersSize,
|
||||
images: ctx.Images,
|
||||
totalCount: ctx.ImageDiskUsage.TotalCount,
|
||||
activeCount: ctx.ImageDiskUsage.ActiveCount,
|
||||
totalSize: ctx.ImageDiskUsage.TotalSize,
|
||||
reclaimable: ctx.ImageDiskUsage.Reclaimable,
|
||||
images: ctx.ImageDiskUsage.Items,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ctx.contextFormat(tmpl, &diskUsageContainersContext{
|
||||
containers: ctx.Containers,
|
||||
totalCount: ctx.ContainerDiskUsage.TotalCount,
|
||||
activeCount: ctx.ContainerDiskUsage.ActiveCount,
|
||||
totalSize: ctx.ContainerDiskUsage.TotalSize,
|
||||
reclaimable: ctx.ContainerDiskUsage.Reclaimable,
|
||||
containers: ctx.ContainerDiskUsage.Items,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ctx.contextFormat(tmpl, &diskUsageVolumesContext{
|
||||
volumes: ctx.Volumes,
|
||||
totalCount: ctx.VolumeDiskUsage.TotalCount,
|
||||
activeCount: ctx.VolumeDiskUsage.ActiveCount,
|
||||
totalSize: ctx.VolumeDiskUsage.TotalSize,
|
||||
reclaimable: ctx.VolumeDiskUsage.Reclaimable,
|
||||
volumes: ctx.VolumeDiskUsage.Items,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ctx.contextFormat(tmpl, &diskUsageBuilderContext{
|
||||
builderSize: ctx.BuilderSize,
|
||||
buildCache: ctx.BuildCache,
|
||||
totalCount: ctx.BuildCacheDiskUsage.TotalCount,
|
||||
activeCount: ctx.BuildCacheDiskUsage.ActiveCount,
|
||||
builderSize: ctx.BuildCacheDiskUsage.TotalSize,
|
||||
reclaimable: ctx.BuildCacheDiskUsage.Reclaimable,
|
||||
buildCache: ctx.BuildCacheDiskUsage.Items,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
diskUsageContainersCtx := diskUsageContainersContext{containers: []*container.Summary{}}
|
||||
diskUsageContainersCtx := diskUsageContainersContext{containers: []container.Summary{}}
|
||||
diskUsageContainersCtx.Header = SubHeaderContext{
|
||||
"Type": typeHeader,
|
||||
"TotalCount": totalHeader,
|
||||
@ -146,18 +160,18 @@ type diskUsageContext struct {
|
||||
|
||||
func (ctx *DiskUsageContext) verboseWrite() error {
|
||||
duc := &diskUsageContext{
|
||||
Images: make([]*imageContext, 0, len(ctx.Images)),
|
||||
Containers: make([]*ContainerContext, 0, len(ctx.Containers)),
|
||||
Volumes: make([]*volumeContext, 0, len(ctx.Volumes)),
|
||||
BuildCache: make([]*buildCacheContext, 0, len(ctx.BuildCache)),
|
||||
Images: make([]*imageContext, 0, len(ctx.ImageDiskUsage.Items)),
|
||||
Containers: make([]*ContainerContext, 0, len(ctx.ContainerDiskUsage.Items)),
|
||||
Volumes: make([]*volumeContext, 0, len(ctx.VolumeDiskUsage.Items)),
|
||||
BuildCache: make([]*buildCacheContext, 0, len(ctx.BuildCacheDiskUsage.Items)),
|
||||
}
|
||||
trunc := ctx.Format.IsTable()
|
||||
|
||||
// First images
|
||||
for _, i := range ctx.Images {
|
||||
for _, i := range ctx.ImageDiskUsage.Items {
|
||||
repo := "<none>"
|
||||
tag := "<none>"
|
||||
if len(i.RepoTags) > 0 && !isDangling(*i) {
|
||||
if len(i.RepoTags) > 0 && !isDangling(i) {
|
||||
// Only show the first tag
|
||||
ref, err := reference.ParseNormalizedNamed(i.RepoTags[0])
|
||||
if err != nil {
|
||||
@ -173,25 +187,25 @@ func (ctx *DiskUsageContext) verboseWrite() error {
|
||||
repo: repo,
|
||||
tag: tag,
|
||||
trunc: trunc,
|
||||
i: *i,
|
||||
i: i,
|
||||
})
|
||||
}
|
||||
|
||||
// Now containers
|
||||
for _, c := range ctx.Containers {
|
||||
for _, c := range ctx.ContainerDiskUsage.Items {
|
||||
// Don't display the virtual size
|
||||
c.SizeRootFs = 0
|
||||
duc.Containers = append(duc.Containers, &ContainerContext{trunc: trunc, c: *c})
|
||||
duc.Containers = append(duc.Containers, &ContainerContext{trunc: trunc, c: c})
|
||||
}
|
||||
|
||||
// And volumes
|
||||
for _, v := range ctx.Volumes {
|
||||
duc.Volumes = append(duc.Volumes, &volumeContext{v: *v})
|
||||
for _, v := range ctx.VolumeDiskUsage.Items {
|
||||
duc.Volumes = append(duc.Volumes, &volumeContext{v: v})
|
||||
}
|
||||
|
||||
// And build cache
|
||||
buildCacheSort(ctx.BuildCache)
|
||||
for _, v := range ctx.BuildCache {
|
||||
buildCacheSort(ctx.BuildCacheDiskUsage.Items)
|
||||
for _, v := range ctx.BuildCacheDiskUsage.Items {
|
||||
duc.BuildCache = append(duc.BuildCache, &buildCacheContext{v: v, trunc: trunc})
|
||||
}
|
||||
|
||||
@ -212,7 +226,7 @@ func (ctx *DiskUsageContext) verboseWriteTable(duc *diskUsageContext) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Output.Write([]byte("Images space usage:\n\n"))
|
||||
_, _ = ctx.Output.Write([]byte("Images space usage:\n\n"))
|
||||
for _, img := range duc.Images {
|
||||
if err := ctx.contextFormat(tmpl, img); err != nil {
|
||||
return err
|
||||
@ -224,7 +238,7 @@ func (ctx *DiskUsageContext) verboseWriteTable(duc *diskUsageContext) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Output.Write([]byte("\nContainers space usage:\n\n"))
|
||||
_, _ = ctx.Output.Write([]byte("\nContainers space usage:\n\n"))
|
||||
for _, c := range duc.Containers {
|
||||
if err := ctx.contextFormat(tmpl, c); err != nil {
|
||||
return err
|
||||
@ -248,7 +262,7 @@ func (ctx *DiskUsageContext) verboseWriteTable(duc *diskUsageContext) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(ctx.Output, "\nBuild cache usage: %s\n\n", units.HumanSize(float64(ctx.BuilderSize)))
|
||||
_, _ = fmt.Fprintf(ctx.Output, "\nBuild cache usage: %s\n\n", units.HumanSize(float64(ctx.BuildCacheDiskUsage.TotalSize)))
|
||||
for _, v := range duc.BuildCache {
|
||||
if err := ctx.contextFormat(tmpl, v); err != nil {
|
||||
return err
|
||||
@ -261,8 +275,11 @@ func (ctx *DiskUsageContext) verboseWriteTable(duc *diskUsageContext) error {
|
||||
|
||||
type diskUsageImagesContext struct {
|
||||
HeaderContext
|
||||
totalSize int64
|
||||
images []*image.Summary
|
||||
totalSize int64
|
||||
reclaimable int64
|
||||
totalCount int64
|
||||
activeCount int64
|
||||
images []image.Summary
|
||||
}
|
||||
|
||||
func (c *diskUsageImagesContext) MarshalJSON() ([]byte, error) {
|
||||
@ -274,18 +291,11 @@ func (*diskUsageImagesContext) Type() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageImagesContext) TotalCount() string {
|
||||
return strconv.Itoa(len(c.images))
|
||||
return strconv.FormatInt(c.totalCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageImagesContext) Active() string {
|
||||
used := 0
|
||||
for _, i := range c.images {
|
||||
if i.Containers > 0 {
|
||||
used++
|
||||
}
|
||||
}
|
||||
|
||||
return strconv.Itoa(used)
|
||||
return strconv.FormatInt(c.activeCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageImagesContext) Size() string {
|
||||
@ -293,27 +303,19 @@ func (c *diskUsageImagesContext) Size() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageImagesContext) Reclaimable() string {
|
||||
var used int64
|
||||
|
||||
for _, i := range c.images {
|
||||
if i.Containers != 0 {
|
||||
if i.Size == -1 || i.SharedSize == -1 {
|
||||
continue
|
||||
}
|
||||
used += i.Size - i.SharedSize
|
||||
}
|
||||
}
|
||||
|
||||
reclaimable := c.totalSize - used
|
||||
if c.totalSize > 0 {
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/c.totalSize)
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(c.reclaimable)), (c.reclaimable*100)/c.totalSize)
|
||||
}
|
||||
return units.HumanSize(float64(reclaimable))
|
||||
return units.HumanSize(float64(c.reclaimable))
|
||||
}
|
||||
|
||||
type diskUsageContainersContext struct {
|
||||
HeaderContext
|
||||
containers []*container.Summary
|
||||
totalCount int64
|
||||
activeCount int64
|
||||
totalSize int64
|
||||
reclaimable int64
|
||||
containers []container.Summary
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) MarshalJSON() ([]byte, error) {
|
||||
@ -325,62 +327,32 @@ func (*diskUsageContainersContext) Type() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) TotalCount() string {
|
||||
return strconv.Itoa(len(c.containers))
|
||||
}
|
||||
|
||||
func (*diskUsageContainersContext) isActive(ctr container.Summary) bool {
|
||||
switch ctr.State {
|
||||
case container.StateRunning, container.StatePaused, container.StateRestarting:
|
||||
return true
|
||||
case container.StateCreated, container.StateRemoving, container.StateExited, container.StateDead:
|
||||
return false
|
||||
default:
|
||||
// Unknown state (should never happen).
|
||||
return false
|
||||
}
|
||||
return strconv.FormatInt(c.totalCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) Active() string {
|
||||
used := 0
|
||||
for _, ctr := range c.containers {
|
||||
if c.isActive(*ctr) {
|
||||
used++
|
||||
}
|
||||
}
|
||||
|
||||
return strconv.Itoa(used)
|
||||
return strconv.FormatInt(c.activeCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) Size() string {
|
||||
var size int64
|
||||
|
||||
for _, ctr := range c.containers {
|
||||
size += ctr.SizeRw
|
||||
}
|
||||
|
||||
return units.HumanSize(float64(size))
|
||||
return units.HumanSize(float64(c.totalSize))
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) Reclaimable() string {
|
||||
var reclaimable, totalSize int64
|
||||
|
||||
for _, ctr := range c.containers {
|
||||
if !c.isActive(*ctr) {
|
||||
reclaimable += ctr.SizeRw
|
||||
}
|
||||
totalSize += ctr.SizeRw
|
||||
if c.totalSize > 0 {
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(c.reclaimable)), (c.reclaimable*100)/c.totalSize)
|
||||
}
|
||||
|
||||
if totalSize > 0 {
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/totalSize)
|
||||
}
|
||||
|
||||
return units.HumanSize(float64(reclaimable))
|
||||
return units.HumanSize(float64(c.reclaimable))
|
||||
}
|
||||
|
||||
type diskUsageVolumesContext struct {
|
||||
HeaderContext
|
||||
volumes []*volume.Volume
|
||||
totalCount int64
|
||||
activeCount int64
|
||||
totalSize int64
|
||||
reclaimable int64
|
||||
volumes []volume.Volume
|
||||
}
|
||||
|
||||
func (c *diskUsageVolumesContext) MarshalJSON() ([]byte, error) {
|
||||
@ -392,56 +364,32 @@ func (*diskUsageVolumesContext) Type() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageVolumesContext) TotalCount() string {
|
||||
return strconv.Itoa(len(c.volumes))
|
||||
return strconv.FormatInt(c.totalCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageVolumesContext) Active() string {
|
||||
used := 0
|
||||
for _, v := range c.volumes {
|
||||
if v.UsageData.RefCount > 0 {
|
||||
used++
|
||||
}
|
||||
}
|
||||
|
||||
return strconv.Itoa(used)
|
||||
return strconv.FormatInt(c.activeCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageVolumesContext) Size() string {
|
||||
var size int64
|
||||
|
||||
for _, v := range c.volumes {
|
||||
if v.UsageData.Size != -1 {
|
||||
size += v.UsageData.Size
|
||||
}
|
||||
}
|
||||
|
||||
return units.HumanSize(float64(size))
|
||||
return units.HumanSize(float64(c.totalSize))
|
||||
}
|
||||
|
||||
func (c *diskUsageVolumesContext) Reclaimable() string {
|
||||
var reclaimable int64
|
||||
var totalSize int64
|
||||
|
||||
for _, v := range c.volumes {
|
||||
if v.UsageData.Size != -1 {
|
||||
if v.UsageData.RefCount == 0 {
|
||||
reclaimable += v.UsageData.Size
|
||||
}
|
||||
totalSize += v.UsageData.Size
|
||||
}
|
||||
if c.totalSize > 0 {
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(c.reclaimable)), (c.reclaimable*100)/c.totalSize)
|
||||
}
|
||||
|
||||
if totalSize > 0 {
|
||||
return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/totalSize)
|
||||
}
|
||||
|
||||
return units.HumanSize(float64(reclaimable))
|
||||
return units.HumanSize(float64(c.reclaimable))
|
||||
}
|
||||
|
||||
type diskUsageBuilderContext struct {
|
||||
HeaderContext
|
||||
totalCount int64
|
||||
activeCount int64
|
||||
builderSize int64
|
||||
buildCache []*build.CacheRecord
|
||||
reclaimable int64
|
||||
buildCache []build.CacheRecord
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) MarshalJSON() ([]byte, error) {
|
||||
@ -453,17 +401,11 @@ func (*diskUsageBuilderContext) Type() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) TotalCount() string {
|
||||
return strconv.Itoa(len(c.buildCache))
|
||||
return strconv.FormatInt(c.totalCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) Active() string {
|
||||
numActive := 0
|
||||
for _, bc := range c.buildCache {
|
||||
if bc.InUse {
|
||||
numActive++
|
||||
}
|
||||
}
|
||||
return strconv.Itoa(numActive)
|
||||
return strconv.FormatInt(c.activeCount, 10)
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) Size() string {
|
||||
@ -471,12 +413,5 @@ func (c *diskUsageBuilderContext) Size() string {
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) Reclaimable() string {
|
||||
var inUseBytes int64
|
||||
for _, bc := range c.buildCache {
|
||||
if bc.InUse && !bc.Shared {
|
||||
inUseBytes += bc.Size
|
||||
}
|
||||
}
|
||||
|
||||
return units.HumanSize(float64(c.builderSize - inUseBytes))
|
||||
return units.HumanSize(float64(c.reclaimable))
|
||||
}
|
||||
|
||||
18
vendor/github.com/docker/cli/cli/command/formatter/displayutils.go
generated
vendored
18
vendor/github.com/docker/cli/cli/command/formatter/displayutils.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package formatter
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/moby/moby/client/pkg/stringid"
|
||||
"golang.org/x/text/width"
|
||||
)
|
||||
|
||||
@ -27,23 +28,12 @@ func charWidth(r rune) int {
|
||||
}
|
||||
}
|
||||
|
||||
const shortLen = 12
|
||||
|
||||
// TruncateID returns a shorthand version of a string identifier for presentation,
|
||||
// after trimming digest algorithm prefix (if any).
|
||||
//
|
||||
// This function is a copy of [stringid.TruncateID] for presentation / formatting
|
||||
// purposes.
|
||||
//
|
||||
// [stringid.TruncateID]: https://github.com/moby/moby/blob/v28.3.2/pkg/stringid/stringid.go#L19
|
||||
// This function is a wrapper for [stringid.TruncateID] for convenience.
|
||||
func TruncateID(id string) string {
|
||||
if i := strings.IndexRune(id, ':'); i >= 0 {
|
||||
id = id[i+1:]
|
||||
}
|
||||
if len(id) > shortLen {
|
||||
id = id[:shortLen]
|
||||
}
|
||||
return id
|
||||
return stringid.TruncateID(id)
|
||||
}
|
||||
|
||||
// Ellipsis truncates a string to fit within maxDisplayWidth, and appends ellipsis (…).
|
||||
|
||||
8
vendor/github.com/docker/cli/cli/command/formatter/formatter.go
generated
vendored
8
vendor/github.com/docker/cli/cli/command/formatter/formatter.go
generated
vendored
@ -1,17 +1,17 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package formatter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter/tabwriter"
|
||||
"github.com/docker/cli/templates"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Format keys used to specify certain kinds of output formats
|
||||
@ -76,7 +76,7 @@ func (c *Context) preFormat() {
|
||||
func (c *Context) parseFormat() (*template.Template, error) {
|
||||
tmpl, err := templates.Parse(c.finalFormat)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "template parsing error")
|
||||
return nil, fmt.Errorf("template parsing error: %w", err)
|
||||
}
|
||||
return tmpl, nil
|
||||
}
|
||||
@ -100,7 +100,7 @@ func (c *Context) postFormat(tmpl *template.Template, subContext SubContext) {
|
||||
|
||||
func (c *Context) contextFormat(tmpl *template.Template, subContext SubContext) error {
|
||||
if err := tmpl.Execute(c.buffer, subContext); err != nil {
|
||||
return errors.Wrap(err, "template parsing error")
|
||||
return fmt.Errorf("template parsing error: %w", err)
|
||||
}
|
||||
if c.Format.IsTable() && c.header != nil {
|
||||
c.header = subContext.FullHeader()
|
||||
|
||||
12
vendor/github.com/docker/cli/cli/command/formatter/image.go
generated
vendored
12
vendor/github.com/docker/cli/cli/command/formatter/image.go
generated
vendored
@ -5,8 +5,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -202,7 +202,6 @@ func newImageContext() *imageContext {
|
||||
"CreatedAt": CreatedAtHeader,
|
||||
"Size": SizeHeader,
|
||||
"Containers": containersHeader,
|
||||
"VirtualSize": SizeHeader, // Deprecated: VirtualSize is deprecated, and equivalent to Size.
|
||||
"SharedSize": sharedSizeHeader,
|
||||
"UniqueSize": uniqueSizeHeader,
|
||||
}
|
||||
@ -257,15 +256,6 @@ func (c *imageContext) Containers() string {
|
||||
return strconv.FormatInt(c.i.Containers, 10)
|
||||
}
|
||||
|
||||
// VirtualSize shows the virtual size of the image and all of its parent
|
||||
// images. Starting with docker 1.10, images are self-contained, and
|
||||
// the VirtualSize is identical to Size.
|
||||
//
|
||||
// Deprecated: VirtualSize is deprecated, and equivalent to [imageContext.Size].
|
||||
func (c *imageContext) VirtualSize() string {
|
||||
return units.HumanSize(float64(c.i.Size))
|
||||
}
|
||||
|
||||
func (c *imageContext) SharedSize() string {
|
||||
if c.i.SharedSize == -1 {
|
||||
return "N/A"
|
||||
|
||||
14
vendor/github.com/docker/cli/cli/command/formatter/reflect.go
generated
vendored
14
vendor/github.com/docker/cli/cli/command/formatter/reflect.go
generated
vendored
@ -1,14 +1,14 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package formatter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// MarshalJSON marshals x into json
|
||||
@ -25,14 +25,14 @@ func MarshalJSON(x any) ([]byte, error) {
|
||||
func marshalMap(x any) (map[string]any, error) {
|
||||
val := reflect.ValueOf(x)
|
||||
if val.Kind() != reflect.Ptr {
|
||||
return nil, errors.Errorf("expected a pointer to a struct, got %v", val.Kind())
|
||||
return nil, fmt.Errorf("expected a pointer to a struct, got %v", val.Kind())
|
||||
}
|
||||
if val.IsNil() {
|
||||
return nil, errors.Errorf("expected a pointer to a struct, got nil pointer")
|
||||
return nil, errors.New("expected a pointer to a struct, got nil pointer")
|
||||
}
|
||||
valElem := val.Elem()
|
||||
if valElem.Kind() != reflect.Struct {
|
||||
return nil, errors.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
|
||||
return nil, fmt.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
|
||||
}
|
||||
typ := val.Type()
|
||||
m := make(map[string]any)
|
||||
@ -54,7 +54,7 @@ var unmarshallableNames = map[string]struct{}{"FullHeader": {}}
|
||||
// It returns ("", nil, nil) for valid but non-marshallable parameter. (e.g. "unexportedFunc()")
|
||||
func marshalForMethod(typ reflect.Method, val reflect.Value) (string, any, error) {
|
||||
if val.Kind() != reflect.Func {
|
||||
return "", nil, errors.Errorf("expected func, got %v", val.Kind())
|
||||
return "", nil, fmt.Errorf("expected func, got %v", val.Kind())
|
||||
}
|
||||
name, numIn, numOut := typ.Name, val.Type().NumIn(), val.Type().NumOut()
|
||||
_, blackListed := unmarshallableNames[name]
|
||||
|
||||
6
vendor/github.com/docker/cli/cli/command/formatter/volume.go
generated
vendored
6
vendor/github.com/docker/cli/cli/command/formatter/volume.go
generated
vendored
@ -5,8 +5,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -40,10 +40,10 @@ func NewVolumeFormat(source string, quiet bool) Format {
|
||||
}
|
||||
|
||||
// VolumeWrite writes formatted volumes using the Context
|
||||
func VolumeWrite(ctx Context, volumes []*volume.Volume) error {
|
||||
func VolumeWrite(ctx Context, volumes []volume.Volume) error {
|
||||
render := func(format func(subContext SubContext) error) error {
|
||||
for _, vol := range volumes {
|
||||
if err := format(&volumeContext{v: *vol}); err != nil {
|
||||
if err := format(&volumeContext{v: vol}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
82
vendor/github.com/docker/cli/cli/command/registry.go
generated
vendored
82
vendor/github.com/docker/cli/cli/command/registry.go
generated
vendored
@ -2,6 +2,7 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
@ -15,9 +16,9 @@ import (
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/docker/cli/internal/tui"
|
||||
registrytypes "github.com/docker/docker/api/types/registry"
|
||||
"github.com/moby/moby/api/pkg/authconfig"
|
||||
registrytypes "github.com/moby/moby/api/types/registry"
|
||||
"github.com/morikuni/aec"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -34,42 +35,11 @@ const (
|
||||
// [registry.IndexServer]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/registry#IndexServer
|
||||
const authConfigKey = "https://index.docker.io/v1/"
|
||||
|
||||
// RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info
|
||||
// for the given command to prompt the user for username and password.
|
||||
//
|
||||
// Deprecated: this function is no longer used and will be removed in the next release.
|
||||
func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) registrytypes.RequestAuthConfig {
|
||||
configKey := getAuthConfigKey(index.Name)
|
||||
isDefaultRegistry := configKey == authConfigKey || index.Official
|
||||
return func(ctx context.Context) (string, error) {
|
||||
_, _ = fmt.Fprintf(cli.Out(), "\nLogin prior to %s:\n", cmdName)
|
||||
authConfig, err := GetDefaultAuthConfig(cli.ConfigFile(), true, configKey, isDefaultRegistry)
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", configKey, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
authConfig, err = PromptUserForCredentials(ctx, cli, "", "", authConfig.Username, configKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return registrytypes.EncodeAuthConfig(authConfig)
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveAuthConfig returns auth-config for the given registry from the
|
||||
// credential-store. It returns an empty AuthConfig if no credentials were
|
||||
// found.
|
||||
//
|
||||
// It is similar to [registry.ResolveAuthConfig], but uses the credentials-
|
||||
// store, instead of looking up credentials from a map.
|
||||
//
|
||||
// [registry.ResolveAuthConfig]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/registry#ResolveAuthConfig
|
||||
// Deprecated: this function is no longer used, and will be removed in the next release.
|
||||
func ResolveAuthConfig(cfg *configfile.ConfigFile, index *registrytypes.IndexInfo) registrytypes.AuthConfig {
|
||||
configKey := index.Name
|
||||
if index.Official {
|
||||
@ -77,7 +47,16 @@ func ResolveAuthConfig(cfg *configfile.ConfigFile, index *registrytypes.IndexInf
|
||||
}
|
||||
|
||||
a, _ := cfg.GetAuthConfig(configKey)
|
||||
return registrytypes.AuthConfig(a)
|
||||
return registrytypes.AuthConfig{
|
||||
Username: a.Username,
|
||||
Password: a.Password,
|
||||
ServerAddress: a.ServerAddress,
|
||||
|
||||
// TODO(thaJeztah): Are these expected to be included?
|
||||
Auth: a.Auth,
|
||||
IdentityToken: a.IdentityToken,
|
||||
RegistryToken: a.RegistryToken,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDefaultAuthConfig gets the default auth config given a serverAddress
|
||||
@ -86,19 +65,27 @@ func GetDefaultAuthConfig(cfg *configfile.ConfigFile, checkCredStore bool, serve
|
||||
if !isDefaultRegistry {
|
||||
serverAddress = credentials.ConvertToHostname(serverAddress)
|
||||
}
|
||||
authconfig := configtypes.AuthConfig{}
|
||||
authCfg := configtypes.AuthConfig{}
|
||||
var err error
|
||||
if checkCredStore {
|
||||
authconfig, err = cfg.GetAuthConfig(serverAddress)
|
||||
authCfg, err = cfg.GetAuthConfig(serverAddress)
|
||||
if err != nil {
|
||||
return registrytypes.AuthConfig{
|
||||
ServerAddress: serverAddress,
|
||||
}, err
|
||||
}
|
||||
}
|
||||
authconfig.ServerAddress = serverAddress
|
||||
authconfig.IdentityToken = ""
|
||||
return registrytypes.AuthConfig(authconfig), nil
|
||||
|
||||
return registrytypes.AuthConfig{
|
||||
Username: authCfg.Username,
|
||||
Password: authCfg.Password,
|
||||
ServerAddress: serverAddress,
|
||||
|
||||
// TODO(thaJeztah): Are these expected to be included?
|
||||
Auth: authCfg.Auth,
|
||||
IdentityToken: "",
|
||||
RegistryToken: authCfg.RegistryToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PromptUserForCredentials handles the CLI prompt for the user to input
|
||||
@ -153,7 +140,7 @@ func PromptUserForCredentials(ctx context.Context, cli Cli, argUser, argPassword
|
||||
argUser = defaultUsername
|
||||
}
|
||||
if argUser == "" {
|
||||
return registrytypes.AuthConfig{}, errors.Errorf("Error: Non-null Username Required")
|
||||
return registrytypes.AuthConfig{}, errors.New("error: username is required")
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +172,7 @@ func PromptUserForCredentials(ctx context.Context, cli Cli, argUser, argPassword
|
||||
}
|
||||
_, _ = fmt.Fprintln(cli.Out())
|
||||
if argPassword == "" {
|
||||
return registrytypes.AuthConfig{}, errors.Errorf("Error: Password Required")
|
||||
return registrytypes.AuthConfig{}, errors.New("error: password is required")
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +200,16 @@ func RetrieveAuthTokenFromImage(cfg *configfile.ConfigFile, image string) (strin
|
||||
return "", err
|
||||
}
|
||||
|
||||
encodedAuth, err := registrytypes.EncodeAuthConfig(registrytypes.AuthConfig(authConfig))
|
||||
encodedAuth, err := authconfig.Encode(registrytypes.AuthConfig{
|
||||
Username: authConfig.Username,
|
||||
Password: authConfig.Password,
|
||||
ServerAddress: authConfig.ServerAddress,
|
||||
|
||||
// TODO(thaJeztah): Are these expected to be included?
|
||||
Auth: authConfig.Auth,
|
||||
IdentityToken: authConfig.IdentityToken,
|
||||
RegistryToken: authConfig.RegistryToken,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
70
vendor/github.com/docker/cli/cli/command/service/progress/progress.go
generated
vendored
70
vendor/github.com/docker/cli/cli/command/service/progress/progress.go
generated
vendored
@ -12,11 +12,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/client/pkg/progress"
|
||||
"github.com/moby/moby/client/pkg/streamformatter"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -88,24 +87,24 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
)
|
||||
|
||||
for {
|
||||
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, swarm.ServiceInspectOptions{})
|
||||
res, err := apiClient.ServiceInspect(ctx, serviceID, client.ServiceInspectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if service.Spec.UpdateConfig != nil && service.Spec.UpdateConfig.Monitor != 0 {
|
||||
monitor = service.Spec.UpdateConfig.Monitor
|
||||
if res.Service.Spec.UpdateConfig != nil && res.Service.Spec.UpdateConfig.Monitor != 0 {
|
||||
monitor = res.Service.Spec.UpdateConfig.Monitor
|
||||
}
|
||||
|
||||
if updater == nil {
|
||||
updater, err = initializeUpdater(service, progressOut)
|
||||
updater, err = initializeUpdater(res.Service, progressOut)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if service.UpdateStatus != nil {
|
||||
switch service.UpdateStatus.State {
|
||||
if res.Service.UpdateStatus != nil {
|
||||
switch res.Service.UpdateStatus.State {
|
||||
case swarm.UpdateStateUpdating:
|
||||
rollback = false
|
||||
case swarm.UpdateStateCompleted:
|
||||
@ -113,39 +112,38 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
return nil
|
||||
}
|
||||
case swarm.UpdateStatePaused:
|
||||
return fmt.Errorf("service update paused: %s", service.UpdateStatus.Message)
|
||||
return fmt.Errorf("service update paused: %s", res.Service.UpdateStatus.Message)
|
||||
case swarm.UpdateStateRollbackStarted:
|
||||
if !rollback && service.UpdateStatus.Message != "" {
|
||||
if !rollback && res.Service.UpdateStatus.Message != "" {
|
||||
progressOut.WriteProgress(progress.Progress{
|
||||
ID: "rollback",
|
||||
Action: service.UpdateStatus.Message,
|
||||
Action: res.Service.UpdateStatus.Message,
|
||||
})
|
||||
}
|
||||
rollback = true
|
||||
case swarm.UpdateStateRollbackPaused:
|
||||
return fmt.Errorf("service rollback paused: %s", service.UpdateStatus.Message)
|
||||
return fmt.Errorf("service rollback paused: %s", res.Service.UpdateStatus.Message)
|
||||
case swarm.UpdateStateRollbackCompleted:
|
||||
if !converged {
|
||||
message = &progress.Progress{ID: "rollback", Message: service.UpdateStatus.Message}
|
||||
message = &progress.Progress{ID: "rollback", Message: res.Service.UpdateStatus.Message}
|
||||
}
|
||||
rollback = true
|
||||
}
|
||||
}
|
||||
if converged && time.Since(convergedAt) >= monitor {
|
||||
progressOut.WriteProgress(progress.Progress{
|
||||
_ = progressOut.WriteProgress(progress.Progress{
|
||||
ID: "verify",
|
||||
Action: fmt.Sprintf("Service %s converged", serviceID),
|
||||
})
|
||||
if message != nil {
|
||||
progressOut.WriteProgress(*message)
|
||||
_ = progressOut.WriteProgress(*message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
tasks, err := apiClient.TaskList(ctx, swarm.TaskListOptions{Filters: filters.NewArgs(
|
||||
filters.KeyValuePair{Key: "service", Value: service.ID},
|
||||
filters.KeyValuePair{Key: "_up-to-date", Value: "true"},
|
||||
)})
|
||||
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
|
||||
Filters: make(client.Filters).Add("service", res.Service.ID).Add("_up-to-date", "true"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -155,7 +153,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
return err
|
||||
}
|
||||
|
||||
converged, err = updater.update(service, tasks, activeNodes, rollback)
|
||||
converged, err = updater.update(res.Service, tasks.Items, activeNodes, rollback)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -167,7 +165,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
// only job services have a non-nil job status, which means we can
|
||||
// use the presence of this field to check if the service is a job
|
||||
// here.
|
||||
if service.JobStatus != nil {
|
||||
if res.Service.JobStatus != nil {
|
||||
progress.Message(progressOut, "", "job complete")
|
||||
return nil
|
||||
}
|
||||
@ -177,7 +175,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
}
|
||||
wait := monitor - time.Since(convergedAt)
|
||||
if wait >= 0 {
|
||||
progressOut.WriteProgress(progress.Progress{
|
||||
_ = progressOut.WriteProgress(progress.Progress{
|
||||
// Ideally this would have no ID, but
|
||||
// the progress rendering code behaves
|
||||
// poorly on an "action" with no ID. It
|
||||
@ -192,7 +190,7 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
}
|
||||
} else {
|
||||
if !convergedAt.IsZero() {
|
||||
progressOut.WriteProgress(progress.Progress{
|
||||
_ = progressOut.WriteProgress(progress.Progress{
|
||||
ID: "verify",
|
||||
Action: "Detected task failure",
|
||||
})
|
||||
@ -216,13 +214,13 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
|
||||
//
|
||||
// TODO(thaJeztah): this should really be a filter on [apiClient.NodeList] instead of being filtered on the client side.
|
||||
func getActiveNodes(ctx context.Context, apiClient client.NodeAPIClient) (map[string]struct{}, error) {
|
||||
nodes, err := apiClient.NodeList(ctx, swarm.NodeListOptions{})
|
||||
res, err := apiClient.NodeList(ctx, client.NodeListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
activeNodes := make(map[string]struct{})
|
||||
for _, n := range nodes {
|
||||
for _, n := range res.Items {
|
||||
if n.Status.State != swarm.NodeStateDown {
|
||||
activeNodes[n.ID] = struct{}{}
|
||||
}
|
||||
@ -652,7 +650,7 @@ func (u *replicatedJobProgressUpdater) update(_ swarm.Service, tasks []swarm.Tas
|
||||
}
|
||||
|
||||
func (u *replicatedJobProgressUpdater) writeOverallProgress(active, completed int) {
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: "job progress",
|
||||
Action: fmt.Sprintf(
|
||||
// * means "use the next positional arg to compute padding"
|
||||
@ -669,7 +667,7 @@ func (u *replicatedJobProgressUpdater) writeOverallProgress(active, completed in
|
||||
actualDesired = u.concurrent
|
||||
}
|
||||
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: "active tasks",
|
||||
Action: fmt.Sprintf(
|
||||
// [n] notation lets us select a specific argument, 1-indexed
|
||||
@ -692,14 +690,14 @@ func (u *replicatedJobProgressUpdater) writeTaskProgress(task swarm.Task) {
|
||||
}
|
||||
|
||||
if task.Status.Err != "" {
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: fmt.Sprintf("%d/%d", task.Slot+1, u.total),
|
||||
Action: truncError(task.Status.Err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: fmt.Sprintf("%d/%d", task.Slot+1, u.total),
|
||||
Action: fmt.Sprintf("%-*s", longestState, task.Status.State),
|
||||
Current: numberedStates[task.Status.State],
|
||||
@ -732,7 +730,7 @@ func (u *globalJobProgressUpdater) update(service swarm.Service, tasks []swarm.T
|
||||
if !u.initialized {
|
||||
// if there are not yet tasks, then return early.
|
||||
if len(tasks) == 0 && len(activeNodes) != 0 {
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: "job progress",
|
||||
Action: "waiting for tasks",
|
||||
})
|
||||
@ -810,14 +808,14 @@ func (u *globalJobProgressUpdater) writeTaskProgress(task swarm.Task) {
|
||||
}
|
||||
|
||||
if task.Status.Err != "" {
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: task.NodeID,
|
||||
Action: truncError(task.Status.Err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
ID: task.NodeID,
|
||||
Action: fmt.Sprintf("%-*s", longestState, task.Status.State),
|
||||
Current: numberedStates[task.Status.State],
|
||||
@ -829,7 +827,7 @@ func (u *globalJobProgressUpdater) writeTaskProgress(task swarm.Task) {
|
||||
func (u *globalJobProgressUpdater) writeOverallProgress(complete int) {
|
||||
// all tasks for a global job are active at once, so we only write out the
|
||||
// total progress.
|
||||
u.progressOut.WriteProgress(progress.Progress{
|
||||
_ = u.progressOut.WriteProgress(progress.Progress{
|
||||
// see (*replicatedJobProgressUpdater).writeOverallProgress for an
|
||||
// explanation of the advanced fmt use in this function.
|
||||
ID: "job progress",
|
||||
|
||||
82
vendor/github.com/docker/cli/cli/command/stack/formatter/formatter.go
generated
vendored
82
vendor/github.com/docker/cli/cli/command/stack/formatter/formatter.go
generated
vendored
@ -1,82 +0,0 @@
|
||||
package formatter
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
)
|
||||
|
||||
const (
|
||||
// SwarmStackTableFormat is the default Swarm stack format
|
||||
//
|
||||
// Deprecated: this type was for internal use and will be removed in the next release.
|
||||
SwarmStackTableFormat formatter.Format = "table {{.Name}}\t{{.Services}}"
|
||||
|
||||
stackServicesHeader = "SERVICES"
|
||||
|
||||
// TableFormatKey is an alias for formatter.TableFormatKey
|
||||
//
|
||||
// Deprecated: this type was for internal use and will be removed in the next release.
|
||||
TableFormatKey = formatter.TableFormatKey
|
||||
)
|
||||
|
||||
// Context is an alias for formatter.Context
|
||||
//
|
||||
// Deprecated: this type was for internal use and will be removed in the next release.
|
||||
type Context = formatter.Context
|
||||
|
||||
// Format is an alias for formatter.Format
|
||||
//
|
||||
// Deprecated: this type was for internal use and will be removed in the next release.
|
||||
type Format = formatter.Format
|
||||
|
||||
// Stack contains deployed stack information.
|
||||
//
|
||||
// Deprecated: this type was for internal use and will be removed in the next release.
|
||||
type Stack struct {
|
||||
// Name is the name of the stack
|
||||
Name string
|
||||
// Services is the number of the services
|
||||
Services int
|
||||
}
|
||||
|
||||
// StackWrite writes formatted stacks using the Context
|
||||
//
|
||||
// Deprecated: this function was for internal use and will be removed in the next release.
|
||||
func StackWrite(ctx formatter.Context, stacks []*Stack) error {
|
||||
render := func(format func(subContext formatter.SubContext) error) error {
|
||||
for _, stack := range stacks {
|
||||
if err := format(&stackContext{s: stack}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return ctx.Write(newStackContext(), render)
|
||||
}
|
||||
|
||||
type stackContext struct {
|
||||
formatter.HeaderContext
|
||||
s *Stack
|
||||
}
|
||||
|
||||
func newStackContext() *stackContext {
|
||||
stackCtx := stackContext{}
|
||||
stackCtx.Header = formatter.SubHeaderContext{
|
||||
"Name": formatter.NameHeader,
|
||||
"Services": stackServicesHeader,
|
||||
}
|
||||
return &stackCtx
|
||||
}
|
||||
|
||||
func (s *stackContext) MarshalJSON() ([]byte, error) {
|
||||
return formatter.MarshalJSON(s)
|
||||
}
|
||||
|
||||
func (s *stackContext) Name() string {
|
||||
return s.s.Name
|
||||
}
|
||||
|
||||
func (s *stackContext) Services() string {
|
||||
return strconv.Itoa(s.s.Services)
|
||||
}
|
||||
20
vendor/github.com/docker/cli/cli/command/telemetry.go
generated
vendored
20
vendor/github.com/docker/cli/cli/command/telemetry.go
generated
vendored
@ -11,11 +11,12 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
otelsdk "go.opentelemetry.io/otel/sdk"
|
||||
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/metric/metricdata"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
@ -146,7 +147,7 @@ func defaultResourceOptions() []resource.Option {
|
||||
semconv.ServiceInstanceID(uuid.NewString()),
|
||||
),
|
||||
resource.WithFromEnv(),
|
||||
resource.WithTelemetrySDK(),
|
||||
resource.WithDetectors(telemetrySDK{}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +158,10 @@ func (r *telemetryResource) AppendOptions(opts ...resource.Option) {
|
||||
r.opts = append(r.opts, opts...)
|
||||
}
|
||||
|
||||
type serviceNameDetector struct{}
|
||||
type (
|
||||
serviceNameDetector struct{}
|
||||
telemetrySDK struct{}
|
||||
)
|
||||
|
||||
func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, error) {
|
||||
return resource.StringDetector(
|
||||
@ -169,6 +173,16 @@ func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, erro
|
||||
).Detect(ctx)
|
||||
}
|
||||
|
||||
// Detect returns a *Resource that describes the OpenTelemetry SDK used.
|
||||
func (telemetrySDK) Detect(context.Context) (*resource.Resource, error) {
|
||||
return resource.NewWithAttributes(
|
||||
semconv.SchemaURL,
|
||||
semconv.TelemetrySDKName("opentelemetry"),
|
||||
semconv.TelemetrySDKLanguageGo,
|
||||
semconv.TelemetrySDKVersion(otelsdk.Version()),
|
||||
), nil
|
||||
}
|
||||
|
||||
// cliReader is an implementation of Reader that will automatically
|
||||
// report to a designated Exporter when Shutdown is called.
|
||||
type cliReader struct {
|
||||
|
||||
7
vendor/github.com/docker/cli/cli/command/telemetry_docker.go
generated
vendored
7
vendor/github.com/docker/cli/cli/command/telemetry_docker.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package command
|
||||
|
||||
@ -14,7 +14,6 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
|
||||
@ -48,7 +47,7 @@ func dockerExporterOTLPEndpoint(cli Cli) (endpoint string, secure bool) {
|
||||
if otelCfg != nil {
|
||||
otelMap, ok := otelCfg.(map[string]any)
|
||||
if !ok {
|
||||
otel.Handle(errors.Errorf(
|
||||
otel.Handle(fmt.Errorf(
|
||||
"unexpected type for field %q: %T (expected: %T)",
|
||||
otelContextFieldName,
|
||||
otelCfg,
|
||||
@ -76,7 +75,7 @@ func dockerExporterOTLPEndpoint(cli Cli) (endpoint string, secure bool) {
|
||||
// We pretend we're the same as the environment reader.
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
otel.Handle(errors.Errorf("docker otel endpoint is invalid: %s", err))
|
||||
otel.Handle(fmt.Errorf("docker otel endpoint is invalid: %s", err))
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/command/telemetry_utils.go
generated
vendored
2
vendor/github.com/docker/cli/cli/command/telemetry_utils.go
generated
vendored
@ -2,12 +2,12 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/version"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
||||
70
vendor/github.com/docker/cli/cli/command/utils.go
generated
vendored
70
vendor/github.com/docker/cli/cli/command/utils.go
generated
vendored
@ -1,74 +1,30 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/cli/internal/prompt"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
// ErrPromptTerminated is returned if the user terminated the prompt.
|
||||
//
|
||||
// Deprecated: this error is for internal use and will be removed in the next release.
|
||||
const ErrPromptTerminated = prompt.ErrTerminated
|
||||
|
||||
// DisableInputEcho disables input echo on the provided streams.In.
|
||||
// This is useful when the user provides sensitive information like passwords.
|
||||
// The function returns a restore function that should be called to restore the
|
||||
// terminal state.
|
||||
//
|
||||
// Deprecated: this function is for internal use and will be removed in the next release.
|
||||
func DisableInputEcho(ins *streams.In) (restore func() error, err error) {
|
||||
return prompt.DisableInputEcho(ins)
|
||||
}
|
||||
|
||||
// PromptForInput requests input from the user.
|
||||
//
|
||||
// If the user terminates the CLI with SIGINT or SIGTERM while the prompt is
|
||||
// active, the prompt will return an empty string ("") with an ErrPromptTerminated error.
|
||||
// When the prompt returns an error, the caller should propagate the error up
|
||||
// the stack and close the io.Reader used for the prompt which will prevent the
|
||||
// background goroutine from blocking indefinitely.
|
||||
//
|
||||
// Deprecated: this function is for internal use and will be removed in the next release.
|
||||
func PromptForInput(ctx context.Context, in io.Reader, out io.Writer, message string) (string, error) {
|
||||
return prompt.ReadInput(ctx, in, out, message)
|
||||
}
|
||||
|
||||
// PromptForConfirmation requests and checks confirmation from the user.
|
||||
// This will display the provided message followed by ' [y/N] '. If the user
|
||||
// input 'y' or 'Y' it returns true otherwise false. If no message is provided,
|
||||
// "Are you sure you want to proceed? [y/N] " will be used instead.
|
||||
//
|
||||
// If the user terminates the CLI with SIGINT or SIGTERM while the prompt is
|
||||
// active, the prompt will return false with an ErrPromptTerminated error.
|
||||
// When the prompt returns an error, the caller should propagate the error up
|
||||
// the stack and close the io.Reader used for the prompt which will prevent the
|
||||
// background goroutine from blocking indefinitely.
|
||||
//
|
||||
// Deprecated: this function is for internal use and will be removed in the next release.
|
||||
func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, message string) (bool, error) {
|
||||
return prompt.Confirm(ctx, ins, outs, message)
|
||||
}
|
||||
|
||||
// PruneFilters merges prune filters specified in config.json with those specified
|
||||
// as command-line flags.
|
||||
// as command-line flags. It returns a deep copy of filters to prevent mutating
|
||||
// the original.
|
||||
//
|
||||
// CLI label filters have precedence over those specified in config.json. If a
|
||||
// label filter specified as flag conflicts with a label defined in config.json
|
||||
// (i.e., "label=some-value" conflicts with "label!=some-value", and vice versa),
|
||||
// then the filter defined in config.json is omitted.
|
||||
func PruneFilters(dockerCLI config.Provider, pruneFilters filters.Args) filters.Args {
|
||||
func PruneFilters(dockerCLI config.Provider, filters client.Filters) client.Filters {
|
||||
pruneFilters := filters.Clone()
|
||||
|
||||
cfg := dockerCLI.ConfigFile()
|
||||
if cfg == nil {
|
||||
return pruneFilters
|
||||
@ -84,13 +40,13 @@ func PruneFilters(dockerCLI config.Provider, pruneFilters filters.Args) filters.
|
||||
switch k {
|
||||
case "label":
|
||||
// "label != some-value" conflicts with "label = some-value"
|
||||
if pruneFilters.ExactMatch("label!", v) {
|
||||
if pruneFilters["label!"][v] {
|
||||
continue
|
||||
}
|
||||
pruneFilters.Add(k, v)
|
||||
case "label!":
|
||||
// "label != some-value" conflicts with "label = some-value"
|
||||
if pruneFilters.ExactMatch("label", v) {
|
||||
if pruneFilters["label"][v] {
|
||||
continue
|
||||
}
|
||||
pruneFilters.Add(k, v)
|
||||
@ -107,7 +63,7 @@ func ValidateOutputPath(path string) error {
|
||||
dir := filepath.Dir(filepath.Clean(path))
|
||||
if dir != "" && dir != "." {
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
return errors.Errorf("invalid output path: directory %q does not exist", dir)
|
||||
return fmt.Errorf("invalid output path: directory %q does not exist", dir)
|
||||
}
|
||||
}
|
||||
// check whether `path` points to a regular file
|
||||
@ -122,7 +78,7 @@ func ValidateOutputPath(path string) error {
|
||||
}
|
||||
|
||||
if err := ValidateOutputPathFileMode(fileInfo.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "invalid output path: %q must be a directory or a regular file", path)
|
||||
return fmt.Errorf("invalid output path: %q must be a directory or a regular file: %w", path, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
10
vendor/github.com/docker/cli/cli/compose/interpolation/interpolation.go
generated
vendored
10
vendor/github.com/docker/cli/cli/compose/interpolation/interpolation.go
generated
vendored
@ -1,14 +1,14 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package interpolation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/compose/template"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Options supported by Interpolate
|
||||
@ -68,7 +68,7 @@ func recursiveInterpolate(value any, path Path, opts Options) (any, error) {
|
||||
}
|
||||
casted, err := caster(newValue)
|
||||
if err != nil {
|
||||
return casted, newPathError(path, errors.Wrap(err, "failed to cast to expected type"))
|
||||
return casted, newPathError(path, fmt.Errorf("failed to cast to expected type: %w", err))
|
||||
}
|
||||
return casted, nil
|
||||
|
||||
@ -104,11 +104,11 @@ func newPathError(path Path, err error) error {
|
||||
case nil:
|
||||
return nil
|
||||
case *template.InvalidTemplateError:
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"invalid interpolation format for %s: %#v; you may need to escape any $ with another $",
|
||||
path, err.Template)
|
||||
default:
|
||||
return errors.Wrapf(err, "error while interpolating %s", path)
|
||||
return fmt.Errorf("error while interpolating %s: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
6
vendor/github.com/docker/cli/cli/compose/loader/interpolate.go
generated
vendored
6
vendor/github.com/docker/cli/cli/compose/loader/interpolate.go
generated
vendored
@ -1,14 +1,14 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
interp "github.com/docker/cli/cli/compose/interpolation"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var interpolateTypeCastMapping = map[interp.Path]interp.Cast{
|
||||
@ -67,7 +67,7 @@ func toBoolean(value string) (any, error) {
|
||||
case "n", "no", "false", "off":
|
||||
return false, nil
|
||||
default:
|
||||
return nil, errors.Errorf("invalid boolean: %s", value)
|
||||
return nil, fmt.Errorf("invalid boolean: %s", value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
81
vendor/github.com/docker/cli/cli/compose/loader/loader.go
generated
vendored
81
vendor/github.com/docker/cli/cli/compose/loader/loader.go
generated
vendored
@ -1,9 +1,10 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -20,12 +21,12 @@ import (
|
||||
"github.com/docker/cli/internal/volumespec"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/cli/opts/swarmopts"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
"github.com/google/shlex"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/client/pkg/versions"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@ -64,7 +65,7 @@ func ParseYAML(source []byte) (map[string]any, error) {
|
||||
}
|
||||
_, ok := cfg.(map[string]any)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("top-level object must be a mapping")
|
||||
return nil, errors.New("top-level object must be a mapping")
|
||||
}
|
||||
converted, err := convertToStringKeysRecursive(cfg, "")
|
||||
if err != nil {
|
||||
@ -76,7 +77,7 @@ func ParseYAML(source []byte) (map[string]any, error) {
|
||||
// Load reads a ConfigDetails and returns a fully loaded configuration
|
||||
func Load(configDetails types.ConfigDetails, opt ...func(*Options)) (*types.Config, error) {
|
||||
if len(configDetails.ConfigFiles) < 1 {
|
||||
return nil, errors.Errorf("No files specified")
|
||||
return nil, errors.New("no files specified")
|
||||
}
|
||||
|
||||
options := &Options{
|
||||
@ -101,7 +102,7 @@ func Load(configDetails types.ConfigDetails, opt ...func(*Options)) (*types.Conf
|
||||
configDetails.Version = version
|
||||
}
|
||||
if configDetails.Version != version {
|
||||
return nil, errors.Errorf("version mismatched between two composefiles : %v and %v", configDetails.Version, version)
|
||||
return nil, fmt.Errorf("version mismatched between two composefiles : %v and %v", configDetails.Version, version)
|
||||
}
|
||||
|
||||
if err := validateForbidden(configDict); err != nil {
|
||||
@ -532,7 +533,7 @@ func transformUlimits(data any) (any, error) {
|
||||
ulimit.Hard = value["hard"].(int)
|
||||
return ulimit, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for ulimits", value)
|
||||
return data, fmt.Errorf("invalid type %T for ulimits", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,33 +545,31 @@ func LoadNetworks(source map[string]any, version string) (map[string]types.Netwo
|
||||
if err != nil {
|
||||
return networks, err
|
||||
}
|
||||
for name, network := range networks {
|
||||
if !network.External.External {
|
||||
for name, nw := range networks {
|
||||
if !nw.External.External {
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case network.External.Name != "":
|
||||
if network.Name != "" {
|
||||
return nil, errors.Errorf("network %s: network.external.name and network.name conflict; only use network.name", name)
|
||||
case nw.External.Name != "":
|
||||
if nw.Name != "" {
|
||||
return nil, fmt.Errorf("network %s: network.external.name and network.name conflict; only use network.name", name)
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(version, "3.5") {
|
||||
logrus.Warnf("network %s: network.external.name is deprecated in favor of network.name", name)
|
||||
}
|
||||
network.Name = network.External.Name
|
||||
network.External.Name = ""
|
||||
case network.Name == "":
|
||||
network.Name = name
|
||||
nw.Name = nw.External.Name
|
||||
nw.External.Name = ""
|
||||
case nw.Name == "":
|
||||
nw.Name = name
|
||||
}
|
||||
network.Extras = loadExtras(name, source)
|
||||
networks[name] = network
|
||||
nw.Extras = loadExtras(name, source)
|
||||
networks[name] = nw
|
||||
}
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func externalVolumeError(volume, key string) error {
|
||||
return errors.Errorf(
|
||||
"conflicting parameters \"external\" and %q specified for volume %q",
|
||||
key, volume)
|
||||
return fmt.Errorf(`conflicting parameters "external" and %q specified for volume %q`, key, volume)
|
||||
}
|
||||
|
||||
// LoadVolumes produces a VolumeConfig map from a compose file Dict
|
||||
@ -594,7 +593,7 @@ func LoadVolumes(source map[string]any, version string) (map[string]types.Volume
|
||||
return nil, externalVolumeError(name, "labels")
|
||||
case volume.External.Name != "":
|
||||
if volume.Name != "" {
|
||||
return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name)
|
||||
return nil, fmt.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name)
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(version, "3.4") {
|
||||
logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name)
|
||||
@ -655,7 +654,7 @@ func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfi
|
||||
// handle deprecated external.name
|
||||
if obj.External.Name != "" {
|
||||
if obj.Name != "" {
|
||||
return obj, errors.Errorf("%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name", objType, name)
|
||||
return obj, fmt.Errorf("%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name", objType, name)
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(details.Version, "3.5") {
|
||||
logrus.Warnf("%[1]s %[2]s: %[1]s.external.name is deprecated in favor of %[1]s.name", objType, name)
|
||||
@ -668,7 +667,7 @@ func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfi
|
||||
// if not "external: true"
|
||||
case obj.Driver != "":
|
||||
if obj.File != "" {
|
||||
return obj, errors.Errorf("%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver", objType, name)
|
||||
return obj, fmt.Errorf("%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver", objType, name)
|
||||
}
|
||||
default:
|
||||
obj.File = absPath(details.WorkingDir, obj.File)
|
||||
@ -691,7 +690,7 @@ var transformMapStringString TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]string:
|
||||
return value, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for map[string]string", value)
|
||||
return data, fmt.Errorf("invalid type %T for map[string]string", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,7 +701,7 @@ var transformExternal TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]any:
|
||||
return map[string]any{"external": true, "name": value["name"]}, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for external", value)
|
||||
return data, fmt.Errorf("invalid type %T for external", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -730,12 +729,12 @@ var transformServicePort TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]any:
|
||||
ports = append(ports, value)
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for port", value)
|
||||
return data, fmt.Errorf("invalid type %T for port", value)
|
||||
}
|
||||
}
|
||||
return ports, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for port", entries)
|
||||
return data, fmt.Errorf("invalid type %T for port", entries)
|
||||
}
|
||||
}
|
||||
|
||||
@ -746,7 +745,7 @@ var transformStringSourceMap TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]any:
|
||||
return data, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for secret", value)
|
||||
return data, fmt.Errorf("invalid type %T for secret", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -757,7 +756,7 @@ var transformBuildConfig TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]any:
|
||||
return data, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for service build", value)
|
||||
return data, fmt.Errorf("invalid type %T for service build", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,7 +767,7 @@ var transformServiceVolumeConfig TransformerFunc = func(data any) (any, error) {
|
||||
case map[string]any:
|
||||
return data, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for service volume", value)
|
||||
return data, fmt.Errorf("invalid type %T for service volume", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,7 +798,7 @@ var transformStringList TransformerFunc = func(data any) (any, error) {
|
||||
case []any:
|
||||
return value, nil
|
||||
default:
|
||||
return data, errors.Errorf("invalid type %T for string list", value)
|
||||
return data, fmt.Errorf("invalid type %T for string list", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,7 +845,7 @@ func transformListOrMapping(listOrMapping any, sep string, allowNil bool, allowS
|
||||
}
|
||||
return result
|
||||
}
|
||||
panic(errors.Errorf("expected a map or a list, got %T: %#v", listOrMapping, listOrMapping))
|
||||
panic(fmt.Errorf("expected a map or a list, got %T: %#v", listOrMapping, listOrMapping))
|
||||
}
|
||||
|
||||
func transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc {
|
||||
@ -874,7 +873,7 @@ func transformMappingOrList(mappingOrList any, sep string, allowNil bool) any {
|
||||
}
|
||||
return result
|
||||
}
|
||||
panic(errors.Errorf("expected a map or a list, got %T: %#v", mappingOrList, mappingOrList))
|
||||
panic(fmt.Errorf("expected a map or a list, got %T: %#v", mappingOrList, mappingOrList))
|
||||
}
|
||||
|
||||
var transformShellCommand TransformerFunc = func(value any) (any, error) {
|
||||
@ -891,7 +890,7 @@ var transformHealthCheckTest TransformerFunc = func(data any) (any, error) {
|
||||
case []any:
|
||||
return value, nil
|
||||
default:
|
||||
return value, errors.Errorf("invalid type %T for healthcheck.test", value)
|
||||
return value, fmt.Errorf("invalid type %T for healthcheck.test", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,7 +901,7 @@ var transformSize TransformerFunc = func(value any) (any, error) {
|
||||
case string:
|
||||
return units.RAMInBytes(value)
|
||||
}
|
||||
panic(errors.Errorf("invalid type for size %T", value))
|
||||
panic(fmt.Errorf("invalid type for size %T", value))
|
||||
}
|
||||
|
||||
var transformStringToDuration TransformerFunc = func(value any) (any, error) {
|
||||
@ -914,7 +913,7 @@ var transformStringToDuration TransformerFunc = func(value any) (any, error) {
|
||||
}
|
||||
return types.Duration(d), nil
|
||||
default:
|
||||
return value, errors.Errorf("invalid type %T for duration", value)
|
||||
return value, fmt.Errorf("invalid type %T for duration", value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -926,7 +925,7 @@ func toServicePortConfigs(value string) ([]any, error) {
|
||||
return nil, err
|
||||
}
|
||||
// We need to sort the key of the ports to make sure it is consistent
|
||||
keys := []string{}
|
||||
keys := make([]string, 0, len(ports))
|
||||
for port := range ports {
|
||||
keys = append(keys, string(port))
|
||||
}
|
||||
@ -934,7 +933,11 @@ func toServicePortConfigs(value string) ([]any, error) {
|
||||
|
||||
for _, key := range keys {
|
||||
// Reuse ConvertPortToPortConfig so that it is consistent
|
||||
portConfig, err := swarmopts.ConvertPortToPortConfig(nat.Port(key), portBindings)
|
||||
port, err := network.ParsePort(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
portConfig, err := swarmopts.ConvertPortToPortConfig(port, portBindings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
26
vendor/github.com/docker/cli/cli/compose/loader/merge.go
generated
vendored
26
vendor/github.com/docker/cli/cli/compose/loader/merge.go
generated
vendored
@ -1,15 +1,15 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"dario.cat/mergo"
|
||||
"github.com/docker/cli/cli/compose/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type specials struct {
|
||||
@ -29,23 +29,23 @@ func merge(configs []*types.Config) (*types.Config, error) {
|
||||
var err error
|
||||
base.Services, err = mergeServices(base.Services, override.Services)
|
||||
if err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge services from %s", override.Filename)
|
||||
return base, fmt.Errorf("cannot merge services from %s: %w", override.Filename, err)
|
||||
}
|
||||
base.Volumes, err = mergeVolumes(base.Volumes, override.Volumes)
|
||||
if err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge volumes from %s", override.Filename)
|
||||
return base, fmt.Errorf("cannot merge volumes from %s: %w", override.Filename, err)
|
||||
}
|
||||
base.Networks, err = mergeNetworks(base.Networks, override.Networks)
|
||||
if err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge networks from %s", override.Filename)
|
||||
return base, fmt.Errorf("cannot merge networks from %s: %w", override.Filename, err)
|
||||
}
|
||||
base.Secrets, err = mergeSecrets(base.Secrets, override.Secrets)
|
||||
if err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge secrets from %s", override.Filename)
|
||||
return base, fmt.Errorf("cannot merge secrets from %s: %w", override.Filename, err)
|
||||
}
|
||||
base.Configs, err = mergeConfigs(base.Configs, override.Configs)
|
||||
if err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge configs from %s", override.Filename)
|
||||
return base, fmt.Errorf("cannot merge configs from %s: %w", override.Filename, err)
|
||||
}
|
||||
}
|
||||
return base, nil
|
||||
@ -70,7 +70,7 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig,
|
||||
for name, overrideService := range overrideServices {
|
||||
if baseService, ok := baseServices[name]; ok {
|
||||
if err := mergo.Merge(&baseService, &overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil {
|
||||
return base, errors.Wrapf(err, "cannot merge service %s", name)
|
||||
return base, fmt.Errorf("cannot merge service %s: %w", name, err)
|
||||
}
|
||||
baseServices[name] = baseService
|
||||
continue
|
||||
@ -88,7 +88,7 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig,
|
||||
func toServiceSecretConfigsMap(s any) (map[any]any, error) {
|
||||
secrets, ok := s.([]types.ServiceSecretConfig)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("not a serviceSecretConfig: %v", s)
|
||||
return nil, fmt.Errorf("not a serviceSecretConfig: %v", s)
|
||||
}
|
||||
m := map[any]any{}
|
||||
for _, secret := range secrets {
|
||||
@ -100,7 +100,7 @@ func toServiceSecretConfigsMap(s any) (map[any]any, error) {
|
||||
func toServiceConfigObjConfigsMap(s any) (map[any]any, error) {
|
||||
secrets, ok := s.([]types.ServiceConfigObjConfig)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("not a serviceSecretConfig: %v", s)
|
||||
return nil, fmt.Errorf("not a serviceSecretConfig: %v", s)
|
||||
}
|
||||
m := map[any]any{}
|
||||
for _, secret := range secrets {
|
||||
@ -112,7 +112,7 @@ func toServiceConfigObjConfigsMap(s any) (map[any]any, error) {
|
||||
func toServicePortConfigsMap(s any) (map[any]any, error) {
|
||||
ports, ok := s.([]types.ServicePortConfig)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("not a servicePortConfig slice: %v", s)
|
||||
return nil, fmt.Errorf("not a servicePortConfig slice: %v", s)
|
||||
}
|
||||
m := map[any]any{}
|
||||
for _, p := range ports {
|
||||
@ -124,7 +124,7 @@ func toServicePortConfigsMap(s any) (map[any]any, error) {
|
||||
func toServiceVolumeConfigsMap(s any) (map[any]any, error) {
|
||||
volumes, ok := s.([]types.ServiceVolumeConfig)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("not a serviceVolumeConfig slice: %v", s)
|
||||
return nil, fmt.Errorf("not a serviceVolumeConfig slice: %v", s)
|
||||
}
|
||||
m := map[any]any{}
|
||||
for _, v := range volumes {
|
||||
@ -211,7 +211,7 @@ func mergeSlice(tomap tomapFn, writeValue writeValueFromMapFn) func(dst, src ref
|
||||
func sliceToMap(tomap tomapFn, v reflect.Value) (map[any]any, error) {
|
||||
// check if valid
|
||||
if !v.IsValid() {
|
||||
return nil, errors.Errorf("invalid value : %+v", v)
|
||||
return nil, fmt.Errorf("invalid value : %+v", v)
|
||||
}
|
||||
return tomap(v.Interface())
|
||||
}
|
||||
|
||||
5
vendor/github.com/docker/cli/cli/compose/schema/schema.go
generated
vendored
5
vendor/github.com/docker/cli/cli/compose/schema/schema.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package schema
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
)
|
||||
|
||||
@ -80,7 +79,7 @@ func Validate(config map[string]any, version string) error {
|
||||
version = normalizeVersion(version)
|
||||
schemaData, err := schemas.ReadFile("data/config_schema_v" + version + ".json")
|
||||
if err != nil {
|
||||
return errors.Errorf("unsupported Compose file version: %s", version)
|
||||
return fmt.Errorf("unsupported Compose file version: %s", version)
|
||||
}
|
||||
|
||||
schemaLoader := gojsonschema.NewStringLoader(string(schemaData))
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/compose/template/template.go
generated
vendored
2
vendor/github.com/docker/cli/cli/compose/template/template.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package template
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/compose/types/types.go
generated
vendored
2
vendor/github.com/docker/cli/cli/compose/types/types.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package types
|
||||
|
||||
|
||||
9
vendor/github.com/docker/cli/cli/config/config.go
generated
vendored
9
vendor/github.com/docker/cli/cli/config/config.go
generated
vendored
@ -13,7 +13,6 @@ import (
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -101,7 +100,7 @@ func SetDir(dir string) {
|
||||
func Path(p ...string) (string, error) {
|
||||
path := filepath.Join(append([]string{Dir()}, p...)...)
|
||||
if !strings.HasPrefix(path, Dir()+string(filepath.Separator)) {
|
||||
return "", errors.Errorf("path %q is outside of root config directory %q", path, Dir())
|
||||
return "", fmt.Errorf("path %q is outside of root config directory %q", path, Dir())
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
@ -143,12 +142,12 @@ func load(configDir string) (*configfile.ConfigFile, error) {
|
||||
return configFile, nil
|
||||
}
|
||||
// Any other error happening when failing to read the file must be returned.
|
||||
return configFile, errors.Wrap(err, "loading config file")
|
||||
return configFile, fmt.Errorf("loading config file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
defer func() { _ = file.Close() }()
|
||||
err = configFile.LoadFromReader(file)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "parsing config file (%s)", filename)
|
||||
err = fmt.Errorf("parsing config file (%s): %w", filename, err)
|
||||
}
|
||||
return configFile, err
|
||||
}
|
||||
|
||||
13
vendor/github.com/docker/cli/cli/config/configfile/file.go
generated
vendored
13
vendor/github.com/docker/cli/cli/config/configfile/file.go
generated
vendored
@ -3,6 +3,7 @@ package configfile
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -12,7 +13,6 @@ import (
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/cli/cli/config/memorystore"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -43,9 +43,6 @@ type ConfigFile struct {
|
||||
Plugins map[string]map[string]string `json:"plugins,omitempty"`
|
||||
Aliases map[string]string `json:"aliases,omitempty"`
|
||||
Features map[string]string `json:"features,omitempty"`
|
||||
|
||||
// Deprecated: experimental CLI features are always enabled and this field is no longer used. Use [Features] instead for optional features. This field will be removed in a future release.
|
||||
Experimental string `json:"experimental,omitempty"`
|
||||
}
|
||||
|
||||
type configEnvAuth struct {
|
||||
@ -167,7 +164,7 @@ func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {
|
||||
// Save encodes and writes out all the authorization information
|
||||
func (configFile *ConfigFile) Save() (retErr error) {
|
||||
if configFile.Filename == "" {
|
||||
return errors.Errorf("Can't save config with empty filename")
|
||||
return errors.New("can't save config with empty filename")
|
||||
}
|
||||
|
||||
dir := filepath.Dir(configFile.Filename)
|
||||
@ -194,7 +191,7 @@ func (configFile *ConfigFile) Save() (retErr error) {
|
||||
}
|
||||
|
||||
if err := temp.Close(); err != nil {
|
||||
return errors.Wrap(err, "error closing temp file")
|
||||
return fmt.Errorf("error closing temp file: %w", err)
|
||||
}
|
||||
|
||||
// Handle situation where the configfile is a symlink, and allow for dangling symlinks
|
||||
@ -278,11 +275,11 @@ func decodeAuth(authStr string) (string, string, error) {
|
||||
return "", "", err
|
||||
}
|
||||
if n > decLen {
|
||||
return "", "", errors.Errorf("Something went wrong decoding auth config")
|
||||
return "", "", errors.New("something went wrong decoding auth config")
|
||||
}
|
||||
userName, password, ok := strings.Cut(string(decoded), ":")
|
||||
if !ok || userName == "" {
|
||||
return "", "", errors.Errorf("Invalid auth configuration file")
|
||||
return "", "", errors.New("invalid auth configuration file")
|
||||
}
|
||||
return userName, strings.Trim(password, "\x00"), nil
|
||||
}
|
||||
|
||||
15
vendor/github.com/docker/cli/cli/config/memorystore/store.go
generated
vendored
15
vendor/github.com/docker/cli/cli/config/memorystore/store.go
generated
vendored
@ -1,9 +1,9 @@
|
||||
//go:build go1.23
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.24
|
||||
|
||||
package memorystore
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
@ -13,12 +13,17 @@ import (
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
)
|
||||
|
||||
var errValueNotFound = errors.New("value not found")
|
||||
// notFoundErr is the error returned when a plugin could not be found.
|
||||
type notFoundErr string
|
||||
|
||||
func IsErrValueNotFound(err error) bool {
|
||||
return errors.Is(err, errValueNotFound)
|
||||
func (notFoundErr) NotFound() {}
|
||||
|
||||
func (e notFoundErr) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
var errValueNotFound notFoundErr = "value not found"
|
||||
|
||||
type Config struct {
|
||||
lock sync.RWMutex
|
||||
memoryCredentials map[string]types.AuthConfig
|
||||
|
||||
5
vendor/github.com/docker/cli/cli/config/types/authconfig.go
generated
vendored
5
vendor/github.com/docker/cli/cli/config/types/authconfig.go
generated
vendored
@ -6,11 +6,6 @@ type AuthConfig struct {
|
||||
Password string `json:"password,omitempty"`
|
||||
Auth string `json:"auth,omitempty"`
|
||||
|
||||
// Email is an optional value associated with the username.
|
||||
//
|
||||
// Deprecated: This field is deprecated since docker 1.11 (API v1.23) and will be removed in the next release.
|
||||
Email string `json:"email,omitempty"`
|
||||
|
||||
ServerAddress string `json:"serveraddress,omitempty"`
|
||||
|
||||
// IdentityToken is used to authenticate the user and get
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go
generated
vendored
2
vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go
generated
vendored
@ -233,11 +233,9 @@ func (c *commandConn) Close() error {
|
||||
defer c.closing.Store(false)
|
||||
|
||||
if err := c.CloseRead(); err != nil {
|
||||
logrus.Warnf("commandConn.Close: CloseRead: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := c.CloseWrite(); err != nil {
|
||||
logrus.Warnf("commandConn.Close: CloseWrite: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go
generated
vendored
2
vendor/github.com/docker/cli/cli/connhelper/ssh/ssh.go
generated
vendored
@ -175,7 +175,7 @@ func quoteCommand(commandAndArgs ...string) (string, error) {
|
||||
quotedCmd = a
|
||||
continue
|
||||
}
|
||||
quotedCmd += " " + a
|
||||
quotedCmd += " " + a //nolint:perfsprint // ignore "concat-loop"; no need to use a string-builder for this.
|
||||
}
|
||||
// each part is quoted appropriately, so now we'll have a full
|
||||
// shell command to pass off to "ssh"
|
||||
|
||||
45
vendor/github.com/docker/cli/cli/context/docker/load.go
generated
vendored
45
vendor/github.com/docker/cli/cli/context/docker/load.go
generated
vendored
@ -4,6 +4,8 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -12,9 +14,8 @@ import (
|
||||
"github.com/docker/cli/cli/connhelper"
|
||||
"github.com/docker/cli/cli/context"
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
// EndpointMeta is a typed wrapper around a context-store generic endpoint describing
|
||||
@ -68,7 +69,7 @@ func (ep *Endpoint) tlsConfig() (*tls.Config, error) {
|
||||
|
||||
x509cert, err := tls.X509KeyPair(ep.TLSData.Cert, keyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to retrieve context tls info")
|
||||
return nil, fmt.Errorf("failed to retrieve context tls info: %w", err)
|
||||
}
|
||||
tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
|
||||
cfg.Certificates = []tls.Certificate{x509cert}
|
||||
@ -101,7 +102,22 @@ func (ep *Endpoint) ClientOpts() ([]client.Opt, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, withHTTPClient(tlsConfig))
|
||||
|
||||
// If there's no tlsConfig available, we use the default HTTPClient.
|
||||
if tlsConfig != nil {
|
||||
result = append(result,
|
||||
client.WithHTTPClient(&http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
DialContext: (&net.Dialer{
|
||||
KeepAlive: 30 * time.Second,
|
||||
Timeout: 30 * time.Second,
|
||||
}).DialContext,
|
||||
},
|
||||
CheckRedirect: client.CheckRedirect,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
result = append(result, client.WithHost(ep.Host))
|
||||
} else {
|
||||
@ -133,25 +149,6 @@ func isSocket(addr string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func withHTTPClient(tlsConfig *tls.Config) func(*client.Client) error {
|
||||
return func(c *client.Client) error {
|
||||
if tlsConfig == nil {
|
||||
// Use the default HTTPClient
|
||||
return nil
|
||||
}
|
||||
return client.WithHTTPClient(&http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
DialContext: (&net.Dialer{
|
||||
KeepAlive: 30 * time.Second,
|
||||
Timeout: 30 * time.Second,
|
||||
}).DialContext,
|
||||
},
|
||||
CheckRedirect: client.CheckRedirect,
|
||||
})(c)
|
||||
}
|
||||
}
|
||||
|
||||
// EndpointFromContext parses a context docker endpoint metadata into a typed EndpointMeta structure
|
||||
func EndpointFromContext(metadata store.Metadata) (EndpointMeta, error) {
|
||||
ep, ok := metadata.Endpoints[DockerEndpoint]
|
||||
@ -160,7 +157,7 @@ func EndpointFromContext(metadata store.Metadata) (EndpointMeta, error) {
|
||||
}
|
||||
typed, ok := ep.(EndpointMeta)
|
||||
if !ok {
|
||||
return EndpointMeta{}, errors.Errorf("endpoint %q is not of type EndpointMeta", DockerEndpoint)
|
||||
return EndpointMeta{}, fmt.Errorf("endpoint %q is not of type EndpointMeta", DockerEndpoint)
|
||||
}
|
||||
return typed, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/context/store/metadatastore.go
generated
vendored
2
vendor/github.com/docker/cli/cli/context/store/metadatastore.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package store
|
||||
|
||||
|
||||
42
vendor/github.com/docker/cli/cli/context/store/store.go
generated
vendored
42
vendor/github.com/docker/cli/cli/context/store/store.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package store
|
||||
|
||||
@ -18,14 +18,9 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = lazyregexp.New(restrictedNamePattern)
|
||||
|
||||
// Store provides a context store for easily remembering endpoints configuration
|
||||
type Store interface {
|
||||
Reader
|
||||
@ -225,12 +220,43 @@ func ValidateContextName(name string) error {
|
||||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
if !isValidName(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, validNameFormat)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validNameFormat is used as part of errors for invalid context-names.
|
||||
// We should consider making this less technical ("must start with "a-z",
|
||||
// and only consist of alphanumeric characters and separators").
|
||||
const validNameFormat = `^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$`
|
||||
|
||||
// isValidName checks if the context-name is valid ("^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$").
|
||||
//
|
||||
// Names must start with an alphanumeric character (a-zA-Z0-9), followed by
|
||||
// alphanumeric or separators ("_", ".", "+", "-").
|
||||
func isValidName(s string) bool {
|
||||
if len(s) < 2 || !isAlphaNum(s[0]) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 1; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if isAlphaNum(c) || c == '_' || c == '.' || c == '+' || c == '-' {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func isAlphaNum(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9')
|
||||
}
|
||||
|
||||
// Export exports an existing namespace into an opaque data stream
|
||||
// This stream is actually a tarball containing context metadata and TLS materials, but it does
|
||||
// not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import)
|
||||
|
||||
2
vendor/github.com/docker/cli/cli/context/store/storeconfig.go
generated
vendored
2
vendor/github.com/docker/cli/cli/context/store/storeconfig.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package store
|
||||
|
||||
|
||||
6
vendor/github.com/docker/cli/cli/context/tlsdata.go
generated
vendored
6
vendor/github.com/docker/cli/cli/context/tlsdata.go
generated
vendored
@ -1,10 +1,10 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -45,14 +45,14 @@ func (data *TLSData) ToStoreTLSData() *store.EndpointTLSData {
|
||||
func LoadTLSData(s store.Reader, contextName, endpointName string) (*TLSData, error) {
|
||||
tlsFiles, err := s.ListTLSFiles(contextName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to retrieve TLS files for context %q", contextName)
|
||||
return nil, fmt.Errorf("failed to retrieve TLS files for context %q: %w", contextName, err)
|
||||
}
|
||||
if epTLSFiles, ok := tlsFiles[endpointName]; ok {
|
||||
var tlsData TLSData
|
||||
for _, f := range epTLSFiles {
|
||||
data, err := s.GetTLSData(contextName, endpointName, f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to retrieve TLS data (%s) for context %q", f, contextName)
|
||||
return nil, fmt.Errorf("failed to retrieve TLS data (%s) for context %q: %w", f, contextName, err)
|
||||
}
|
||||
switch f {
|
||||
case caKey:
|
||||
|
||||
50
vendor/github.com/docker/cli/cli/flags/options.go
generated
vendored
50
vendor/github.com/docker/cli/cli/flags/options.go
generated
vendored
@ -7,8 +7,8 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@ -110,22 +110,20 @@ func (o *ClientOptions) InstallFlags(flags *pflag.FlagSet) {
|
||||
if dockerCertPath == "" {
|
||||
dockerCertPath = configDir
|
||||
}
|
||||
o.TLSOptions = &tlsconfig.Options{
|
||||
CAFile: filepath.Join(dockerCertPath, DefaultCaFile),
|
||||
CertFile: filepath.Join(dockerCertPath, DefaultCertFile),
|
||||
KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile),
|
||||
}
|
||||
|
||||
flags.StringVar(&o.ConfigDir, "config", configDir, "Location of client config files")
|
||||
flags.BoolVarP(&o.Debug, "debug", "D", false, "Enable debug mode")
|
||||
flags.StringVarP(&o.LogLevel, "log-level", "l", "info", `Set the logging level ("debug", "info", "warn", "error", "fatal")`)
|
||||
flags.BoolVar(&o.TLS, "tls", dockerTLS, "Use TLS; implied by --tlsverify")
|
||||
flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote")
|
||||
|
||||
o.TLSOptions = &tlsconfig.Options{
|
||||
CAFile: filepath.Join(dockerCertPath, DefaultCaFile),
|
||||
CertFile: filepath.Join(dockerCertPath, DefaultCertFile),
|
||||
KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile),
|
||||
}
|
||||
tlsOptions := o.TLSOptions
|
||||
flags.Var("edString{&tlsOptions.CAFile}, "tlscacert", "Trust certs signed only by this CA")
|
||||
flags.Var("edString{&tlsOptions.CertFile}, "tlscert", "Path to TLS certificate file")
|
||||
flags.Var("edString{&tlsOptions.KeyFile}, "tlskey", "Path to TLS key file")
|
||||
flags.StringVar(&o.TLSOptions.CAFile, "tlscacert", o.TLSOptions.CAFile, "Trust certs signed only by this CA")
|
||||
flags.StringVar(&o.TLSOptions.CertFile, "tlscert", o.TLSOptions.CertFile, "Path to TLS certificate file")
|
||||
flags.StringVar(&o.TLSOptions.KeyFile, "tlskey", o.TLSOptions.KeyFile, "Path to TLS key file")
|
||||
|
||||
// TODO(thaJeztah): show the default host.
|
||||
// TODO(thaJeztah): this should be a string, not an "array" as we only allow a single host.
|
||||
@ -179,33 +177,3 @@ func SetLogLevel(logLevel string) {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
}
|
||||
|
||||
type quotedString struct {
|
||||
value *string
|
||||
}
|
||||
|
||||
func (s *quotedString) Set(val string) error {
|
||||
*s.value = trimQuotes(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*quotedString) Type() string {
|
||||
return "string"
|
||||
}
|
||||
|
||||
func (s *quotedString) String() string {
|
||||
return *s.value
|
||||
}
|
||||
|
||||
func trimQuotes(value string) string {
|
||||
if len(value) < 2 {
|
||||
return value
|
||||
}
|
||||
lastIndex := len(value) - 1
|
||||
for _, char := range []byte{'\'', '"'} {
|
||||
if value[0] == char && value[lastIndex] == char {
|
||||
return value[1:lastIndex]
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
17
vendor/github.com/docker/cli/cli/required.go
generated
vendored
17
vendor/github.com/docker/cli/cli/required.go
generated
vendored
@ -1,7 +1,8 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -12,7 +13,7 @@ func NoArgs(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if cmd.HasSubCommands() {
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"%[1]s: unknown command: %[2]s %[3]s\n\nUsage: %[4]s\n\nRun '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
@ -21,7 +22,7 @@ func NoArgs(cmd *cobra.Command, args []string) error {
|
||||
)
|
||||
}
|
||||
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"%[1]s: '%[2]s' accepts no arguments\n\nUsage: %[3]s\n\nRun '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
@ -35,7 +36,7 @@ func RequiresMinArgs(minArgs int) cobra.PositionalArgs {
|
||||
if len(args) >= minArgs {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"%[1]s: '%[2]s' requires at least %[3]d %[4]s\n\nUsage: %[5]s\n\nSee '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
@ -52,8 +53,8 @@ func RequiresMaxArgs(maxArgs int) cobra.PositionalArgs {
|
||||
if len(args) <= maxArgs {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf(
|
||||
"%[1]s: '%[2]s' requires at most %[3]d %[4]s\n\nUsage: %[5]s\n\nSRun '%[2]s --help' for more information",
|
||||
return fmt.Errorf(
|
||||
"%[1]s: '%[2]s' requires at most %[3]d %[4]s\n\nUsage: %[5]s\n\nRun '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
maxArgs,
|
||||
@ -69,7 +70,7 @@ func RequiresRangeArgs(minArgs int, maxArgs int) cobra.PositionalArgs {
|
||||
if len(args) >= minArgs && len(args) <= maxArgs {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"%[1]s: '%[2]s' requires at least %[3]d and at most %[4]d %[5]s\n\nUsage: %[6]s\n\nRun '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
@ -87,7 +88,7 @@ func ExactArgs(number int) cobra.PositionalArgs {
|
||||
if len(args) == number {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf(
|
||||
return fmt.Errorf(
|
||||
"%[1]s: '%[2]s' requires %[3]d %[4]s\n\nUsage: %[5]s\n\nRun '%[2]s --help' for more information",
|
||||
binName(cmd),
|
||||
cmd.CommandPath(),
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/chip.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/chip.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/colors.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/colors.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/count.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/count.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/note.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/note.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/output.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/output.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/internal/tui/str.go
generated
vendored
2
vendor/github.com/docker/cli/internal/tui/str.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package tui
|
||||
|
||||
|
||||
9
vendor/github.com/docker/cli/internal/volumespec/volumespec.go
generated
vendored
9
vendor/github.com/docker/cli/internal/volumespec/volumespec.go
generated
vendored
@ -1,12 +1,13 @@
|
||||
package volumespec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
)
|
||||
|
||||
const endOfSpec = rune(0)
|
||||
@ -24,7 +25,7 @@ func Parse(spec string) (VolumeConfig, error) {
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
buffer := []rune{}
|
||||
var buffer []rune
|
||||
for _, char := range spec + string(endOfSpec) {
|
||||
switch {
|
||||
case isWindowsDrive(buffer, char):
|
||||
@ -32,7 +33,7 @@ func Parse(spec string) (VolumeConfig, error) {
|
||||
case char == ':' || char == endOfSpec:
|
||||
if err := populateFieldFromBuffer(char, buffer, &volume); err != nil {
|
||||
populateType(&volume)
|
||||
return volume, errors.Wrapf(err, "invalid spec: %s", spec)
|
||||
return volume, fmt.Errorf("invalid spec: %s: %w", spec, err)
|
||||
}
|
||||
buffer = []rune{}
|
||||
default:
|
||||
|
||||
14
vendor/github.com/docker/cli/opts/envfile_deprecated.go
generated
vendored
14
vendor/github.com/docker/cli/opts/envfile_deprecated.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
package opts
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/pkg/kvfile"
|
||||
)
|
||||
|
||||
// ParseEnvFile reads a file with environment variables enumerated by lines
|
||||
//
|
||||
// Deprecated: use [kvfile.Parse] and pass [os.LookupEnv] to lookup env-vars from the current environment.
|
||||
func ParseEnvFile(filename string) ([]string, error) {
|
||||
return kvfile.Parse(filename, os.LookupEnv)
|
||||
}
|
||||
2
vendor/github.com/docker/cli/opts/gpus.go
generated
vendored
2
vendor/github.com/docker/cli/opts/gpus.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// GpuOpts is a Value type for parsing mounts
|
||||
|
||||
17
vendor/github.com/docker/cli/opts/hosts.go
generated
vendored
17
vendor/github.com/docker/cli/opts/hosts.go
generated
vendored
@ -32,23 +32,6 @@ const (
|
||||
hostGatewayName = "host-gateway"
|
||||
)
|
||||
|
||||
// ValidateHost validates that the specified string is a valid host and returns it.
|
||||
//
|
||||
// Deprecated: this function is no longer used, and will be removed in the next release.
|
||||
func ValidateHost(val string) (string, error) {
|
||||
host := strings.TrimSpace(val)
|
||||
// The empty string means default and is not handled by parseDockerDaemonHost
|
||||
if host != "" {
|
||||
_, err := parseDockerDaemonHost(host)
|
||||
if err != nil {
|
||||
return val, err
|
||||
}
|
||||
}
|
||||
// Note: unlike most flag validators, we don't return the mutated value here
|
||||
// we need to know what the user entered later (using ParseHost) to adjust for TLS
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// ParseHost and set defaults for a Daemon host string
|
||||
func ParseHost(defaultToTLS bool, val string) (string, error) {
|
||||
host := strings.TrimSpace(val)
|
||||
|
||||
14
vendor/github.com/docker/cli/opts/mount.go
generated
vendored
14
vendor/github.com/docker/cli/opts/mount.go
generated
vendored
@ -9,9 +9,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/sirupsen/logrus"
|
||||
mounttypes "github.com/moby/moby/api/types/mount"
|
||||
)
|
||||
|
||||
// MountOpt is a Value type for parsing mounts
|
||||
@ -88,8 +87,7 @@ func (m *MountOpt) Set(value string) error {
|
||||
volumeOptions().NoCopy = true
|
||||
continue
|
||||
case "bind-nonrecursive":
|
||||
bindOptions().NonRecursive = true
|
||||
continue
|
||||
return errors.New("bind-nonrecursive is deprecated, use bind-recursive=disabled instead")
|
||||
default:
|
||||
return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
|
||||
}
|
||||
@ -117,16 +115,12 @@ func (m *MountOpt) Set(value string) error {
|
||||
case "bind-propagation":
|
||||
bindOptions().Propagation = mounttypes.Propagation(strings.ToLower(val))
|
||||
case "bind-nonrecursive":
|
||||
bindOptions().NonRecursive, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid value for %s: %s", key, val)
|
||||
}
|
||||
logrus.Warn("bind-nonrecursive is deprecated, use bind-recursive=disabled instead")
|
||||
return errors.New("bind-nonrecursive is deprecated, use bind-recursive=disabled instead")
|
||||
case "bind-recursive":
|
||||
switch val {
|
||||
case "enabled": // read-only mounts are recursively read-only if Engine >= v25 && kernel >= v5.12, otherwise writable
|
||||
// NOP
|
||||
case "disabled": // alias of bind-nonrecursive=true
|
||||
case "disabled": // previously "bind-nonrecursive=true"
|
||||
bindOptions().NonRecursive = true
|
||||
case "writable": // conforms to the default read-only bind-mount of Docker v24; read-only mounts are recursively mounted but not recursively read-only
|
||||
bindOptions().ReadOnlyNonRecursive = true
|
||||
|
||||
23
vendor/github.com/docker/cli/opts/network.go
generated
vendored
23
vendor/github.com/docker/cli/opts/network.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -26,9 +27,9 @@ type NetworkAttachmentOpts struct {
|
||||
Aliases []string
|
||||
DriverOpts map[string]string
|
||||
Links []string // TODO add support for links in the csv notation of `--network`
|
||||
IPv4Address string
|
||||
IPv6Address string
|
||||
LinkLocalIPs []string
|
||||
IPv4Address netip.Addr
|
||||
IPv6Address netip.Addr
|
||||
LinkLocalIPs []netip.Addr
|
||||
MacAddress string
|
||||
GwPriority int
|
||||
}
|
||||
@ -70,13 +71,23 @@ func (n *NetworkOpt) Set(value string) error { //nolint:gocyclo
|
||||
case networkOptAlias:
|
||||
netOpt.Aliases = append(netOpt.Aliases, val)
|
||||
case networkOptIPv4Address:
|
||||
netOpt.IPv4Address = val
|
||||
netOpt.IPv4Address, err = netip.ParseAddr(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case networkOptIPv6Address:
|
||||
netOpt.IPv6Address = val
|
||||
netOpt.IPv6Address, err = netip.ParseAddr(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case networkOptMacAddress:
|
||||
netOpt.MacAddress = val
|
||||
case networkOptLinkLocalIP:
|
||||
netOpt.LinkLocalIPs = append(netOpt.LinkLocalIPs, val)
|
||||
a, err := netip.ParseAddr(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
netOpt.LinkLocalIPs = append(netOpt.LinkLocalIPs, a)
|
||||
case driverOpt:
|
||||
key, val, err = parseDriverOpt(val)
|
||||
if err != nil {
|
||||
|
||||
93
vendor/github.com/docker/cli/opts/opts.go
generated
vendored
93
vendor/github.com/docker/cli/opts/opts.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package opts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@ -9,8 +10,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -60,6 +61,8 @@ func (opts *ListOpts) Set(value string) error {
|
||||
}
|
||||
|
||||
// Delete removes the specified element from the slice.
|
||||
//
|
||||
// Deprecated: this method is no longer used and will be removed in the next release.
|
||||
func (opts *ListOpts) Delete(key string) {
|
||||
for i, k := range *opts.values {
|
||||
if k == key {
|
||||
@ -79,13 +82,6 @@ func (opts *ListOpts) GetMap() map[string]struct{} {
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetAll returns the values of slice.
|
||||
//
|
||||
// Deprecated: use [ListOpts.GetSlice] instead. This method will be removed in a future release.
|
||||
func (opts *ListOpts) GetAll() []string {
|
||||
return *opts.values
|
||||
}
|
||||
|
||||
// GetSlice returns the values of slice.
|
||||
//
|
||||
// It implements [cobra.SliceValue] to allow shell completion to be provided
|
||||
@ -132,43 +128,6 @@ func (opts *ListOpts) WithValidator(validator ValidatorFctType) *ListOpts {
|
||||
return opts
|
||||
}
|
||||
|
||||
// NamedOption is an interface that list and map options
|
||||
// with names implement.
|
||||
//
|
||||
// Deprecated: NamedOption is no longer used and will be removed in the next release.
|
||||
type NamedOption interface {
|
||||
Name() string
|
||||
}
|
||||
|
||||
// NamedListOpts is a ListOpts with a configuration name.
|
||||
// This struct is useful to keep reference to the assigned
|
||||
// field name in the internal configuration struct.
|
||||
//
|
||||
// Deprecated: NamedListOpts is no longer used and will be removed in the next release.
|
||||
type NamedListOpts struct {
|
||||
name string
|
||||
ListOpts
|
||||
}
|
||||
|
||||
var _ NamedOption = &NamedListOpts{}
|
||||
|
||||
// NewNamedListOptsRef creates a reference to a new NamedListOpts struct.
|
||||
//
|
||||
// Deprecated: NewNamedListOptsRef is no longer used and will be removed in the next release.
|
||||
func NewNamedListOptsRef(name string, values *[]string, validator ValidatorFctType) *NamedListOpts {
|
||||
return &NamedListOpts{
|
||||
name: name,
|
||||
ListOpts: *NewListOptsRef(values, validator),
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the name of the NamedListOpts in the configuration.
|
||||
//
|
||||
// Deprecated: NamedListOpts is no longer used and will be removed in the next release.
|
||||
func (o *NamedListOpts) Name() string {
|
||||
return o.name
|
||||
}
|
||||
|
||||
// MapOpts holds a map of values and a validation function.
|
||||
type MapOpts struct {
|
||||
values map[string]string
|
||||
@ -215,35 +174,6 @@ func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// NamedMapOpts is a MapOpts struct with a configuration name.
|
||||
// This struct is useful to keep reference to the assigned
|
||||
// field name in the internal configuration struct.
|
||||
//
|
||||
// Deprecated: NamedMapOpts is no longer used and will be removed in the next release.
|
||||
type NamedMapOpts struct {
|
||||
name string
|
||||
MapOpts
|
||||
}
|
||||
|
||||
var _ NamedOption = &NamedMapOpts{}
|
||||
|
||||
// NewNamedMapOpts creates a reference to a new NamedMapOpts struct.
|
||||
//
|
||||
// Deprecated: NamedMapOpts is no longer used and will be removed in the next release.
|
||||
func NewNamedMapOpts(name string, values map[string]string, validator ValidatorFctType) *NamedMapOpts {
|
||||
return &NamedMapOpts{
|
||||
name: name,
|
||||
MapOpts: *NewMapOpts(values, validator),
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the name of the NamedMapOpts in the configuration.
|
||||
//
|
||||
// Deprecated: NamedMapOpts is no longer used and will be removed in the next release.
|
||||
func (o *NamedMapOpts) Name() string {
|
||||
return o.name
|
||||
}
|
||||
|
||||
// ValidatorFctType defines a validator function that returns a validated string and/or an error.
|
||||
type ValidatorFctType func(val string) (string, error)
|
||||
|
||||
@ -264,6 +194,8 @@ func ValidateIPAddress(val string) (string, error) {
|
||||
}
|
||||
|
||||
// ValidateMACAddress validates a MAC address.
|
||||
//
|
||||
// Deprecated: use [net.ParseMAC]. This function will be removed in the next release.
|
||||
func ValidateMACAddress(val string) (string, error) {
|
||||
_, err := net.ParseMAC(strings.TrimSpace(val))
|
||||
if err != nil {
|
||||
@ -350,20 +282,23 @@ func ValidateSysctl(val string) (string, error) {
|
||||
|
||||
// FilterOpt is a flag type for validating filters
|
||||
type FilterOpt struct {
|
||||
filter filters.Args
|
||||
filter client.Filters
|
||||
}
|
||||
|
||||
// NewFilterOpt returns a new FilterOpt
|
||||
func NewFilterOpt() FilterOpt {
|
||||
return FilterOpt{filter: filters.NewArgs()}
|
||||
return FilterOpt{filter: make(client.Filters)}
|
||||
}
|
||||
|
||||
func (o *FilterOpt) String() string {
|
||||
repr, err := filters.ToJSON(o.filter)
|
||||
if o == nil || len(o.filter) == 0 {
|
||||
return ""
|
||||
}
|
||||
repr, err := json.Marshal(o.filter)
|
||||
if err != nil {
|
||||
return "invalid filters"
|
||||
}
|
||||
return repr
|
||||
return string(repr)
|
||||
}
|
||||
|
||||
// Set sets the value of the opt by parsing the command line value
|
||||
@ -389,7 +324,7 @@ func (*FilterOpt) Type() string {
|
||||
}
|
||||
|
||||
// Value returns the value of this option
|
||||
func (o *FilterOpt) Value() filters.Args {
|
||||
func (o *FilterOpt) Value() client.Filters {
|
||||
return o.filter
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/docker/cli/opts/parse.go
generated
vendored
2
vendor/github.com/docker/cli/opts/parse.go
generated
vendored
@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/pkg/kvfile"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// ReadKVStrings reads a file of line terminated key=value pairs, and overrides any keys
|
||||
|
||||
44
vendor/github.com/docker/cli/opts/quotedstring.go
generated
vendored
44
vendor/github.com/docker/cli/opts/quotedstring.go
generated
vendored
@ -1,44 +0,0 @@
|
||||
package opts
|
||||
|
||||
// QuotedString is a string that may have extra quotes around the value. The
|
||||
// quotes are stripped from the value.
|
||||
//
|
||||
// Deprecated: This option type is no longer used and will be removed in the next release.
|
||||
type QuotedString struct {
|
||||
value *string
|
||||
}
|
||||
|
||||
// Set sets a new value
|
||||
func (s *QuotedString) Set(val string) error {
|
||||
*s.value = trimQuotes(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns the type of the value
|
||||
func (*QuotedString) Type() string {
|
||||
return "string"
|
||||
}
|
||||
|
||||
func (s *QuotedString) String() string {
|
||||
return *s.value
|
||||
}
|
||||
|
||||
func trimQuotes(value string) string {
|
||||
if len(value) < 2 {
|
||||
return value
|
||||
}
|
||||
lastIndex := len(value) - 1
|
||||
for _, char := range []byte{'\'', '"'} {
|
||||
if value[0] == char && value[lastIndex] == char {
|
||||
return value[1:lastIndex]
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// NewQuotedString returns a new quoted string option
|
||||
//
|
||||
// Deprecated: This option type is no longer used and will be removed in the next release.
|
||||
func NewQuotedString(value *string) *QuotedString {
|
||||
return &QuotedString{value: value}
|
||||
}
|
||||
2
vendor/github.com/docker/cli/opts/swarmopts/config.go
generated
vendored
2
vendor/github.com/docker/cli/opts/swarmopts/config.go
generated
vendored
@ -8,7 +8,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// ConfigOpt is a Value type for parsing configs
|
||||
|
||||
55
vendor/github.com/docker/cli/opts/swarmopts/port.go
generated
vendored
55
vendor/github.com/docker/cli/opts/swarmopts/port.go
generated
vendored
@ -9,8 +9,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -41,7 +42,10 @@ func (p *PortOpt) Set(value string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pConfig := swarm.PortConfig{}
|
||||
pConfig := swarm.PortConfig{
|
||||
Protocol: network.TCP,
|
||||
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||
}
|
||||
for _, field := range fields {
|
||||
// TODO(thaJeztah): these options should not be case-insensitive.
|
||||
key, val, ok := strings.Cut(strings.ToLower(field), "=")
|
||||
@ -50,17 +54,19 @@ func (p *PortOpt) Set(value string) error {
|
||||
}
|
||||
switch key {
|
||||
case portOptProtocol:
|
||||
if val != string(swarm.PortConfigProtocolTCP) && val != string(swarm.PortConfigProtocolUDP) && val != string(swarm.PortConfigProtocolSCTP) {
|
||||
switch proto := network.IPProtocol(val); proto {
|
||||
case network.TCP, network.UDP, network.SCTP:
|
||||
pConfig.Protocol = proto
|
||||
default:
|
||||
return fmt.Errorf("invalid protocol value '%s'", val)
|
||||
}
|
||||
|
||||
pConfig.Protocol = swarm.PortConfigProtocol(val)
|
||||
case portOptMode:
|
||||
if val != string(swarm.PortConfigPublishModeIngress) && val != string(swarm.PortConfigPublishModeHost) {
|
||||
switch swarm.PortConfigPublishMode(val) {
|
||||
case swarm.PortConfigPublishModeIngress, swarm.PortConfigPublishModeHost:
|
||||
pConfig.PublishMode = swarm.PortConfigPublishMode(val)
|
||||
default:
|
||||
return fmt.Errorf("invalid publish mode value (%s): must be either '%s' or '%s'", val, swarm.PortConfigPublishModeIngress, swarm.PortConfigPublishModeHost)
|
||||
}
|
||||
|
||||
pConfig.PublishMode = swarm.PortConfigPublishMode(val)
|
||||
case portOptTargetPort:
|
||||
tPort, err := strconv.ParseUint(val, 10, 16)
|
||||
if err != nil {
|
||||
@ -92,18 +98,9 @@ func (p *PortOpt) Set(value string) error {
|
||||
return fmt.Errorf("missing mandatory field '%s'", portOptTargetPort)
|
||||
}
|
||||
|
||||
if pConfig.PublishMode == "" {
|
||||
pConfig.PublishMode = swarm.PortConfigPublishModeIngress
|
||||
}
|
||||
|
||||
if pConfig.Protocol == "" {
|
||||
pConfig.Protocol = swarm.PortConfigProtocolTCP
|
||||
}
|
||||
|
||||
p.ports = append(p.ports, pConfig)
|
||||
} else {
|
||||
// short syntax
|
||||
portConfigs := []swarm.PortConfig{}
|
||||
ports, portBindingMap, err := nat.ParsePortSpecs([]string{value})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -116,8 +113,13 @@ func (p *PortOpt) Set(value string) error {
|
||||
}
|
||||
}
|
||||
|
||||
var portConfigs []swarm.PortConfig
|
||||
for port := range ports {
|
||||
portConfig, err := ConvertPortToPortConfig(port, portBindingMap)
|
||||
portProto, err := network.ParsePort(string(port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
portConfig, err := ConvertPortToPortConfig(portProto, portBindingMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -135,7 +137,7 @@ func (*PortOpt) Type() string {
|
||||
|
||||
// String returns a string repr of this option
|
||||
func (p *PortOpt) String() string {
|
||||
ports := []string{}
|
||||
ports := make([]string, 0, len(p.ports))
|
||||
for _, port := range p.ports {
|
||||
repr := fmt.Sprintf("%v:%v/%s/%s", port.PublishedPort, port.TargetPort, port.Protocol, port.PublishMode)
|
||||
ports = append(ports, repr)
|
||||
@ -150,28 +152,27 @@ func (p *PortOpt) Value() []swarm.PortConfig {
|
||||
|
||||
// ConvertPortToPortConfig converts ports to the swarm type
|
||||
func ConvertPortToPortConfig(
|
||||
port nat.Port,
|
||||
portProto network.Port,
|
||||
portBindings map[nat.Port][]nat.PortBinding,
|
||||
) ([]swarm.PortConfig, error) {
|
||||
ports := []swarm.PortConfig{}
|
||||
|
||||
for _, binding := range portBindings[port] {
|
||||
ports := make([]swarm.PortConfig, 0, len(portBindings))
|
||||
for _, binding := range portBindings[nat.Port(portProto.String())] {
|
||||
if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {
|
||||
// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).
|
||||
logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port)
|
||||
logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), portProto.String())
|
||||
}
|
||||
|
||||
startHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)
|
||||
|
||||
if err != nil && binding.HostPort != "" {
|
||||
return nil, fmt.Errorf("invalid hostport binding (%s) for port (%s)", binding.HostPort, port.Port())
|
||||
return nil, fmt.Errorf("invalid hostport binding (%s) for port (%d)", binding.HostPort, portProto.Num())
|
||||
}
|
||||
|
||||
for i := startHostPort; i <= endHostPort; i++ {
|
||||
ports = append(ports, swarm.PortConfig{
|
||||
// TODO Name: ?
|
||||
Protocol: swarm.PortConfigProtocol(strings.ToLower(port.Proto())),
|
||||
TargetPort: uint32(port.Int()),
|
||||
Protocol: portProto.Proto(),
|
||||
TargetPort: uint32(portProto.Num()),
|
||||
PublishedPort: uint32(i),
|
||||
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||
})
|
||||
|
||||
2
vendor/github.com/docker/cli/opts/swarmopts/secret.go
generated
vendored
2
vendor/github.com/docker/cli/opts/swarmopts/secret.go
generated
vendored
@ -8,7 +8,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// SecretOpt is a Value type for parsing secrets
|
||||
|
||||
2
vendor/github.com/docker/cli/opts/throttledevice.go
generated
vendored
2
vendor/github.com/docker/cli/opts/throttledevice.go
generated
vendored
@ -5,8 +5,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/blkiodev"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/blkiodev"
|
||||
)
|
||||
|
||||
// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error.
|
||||
|
||||
2
vendor/github.com/docker/cli/opts/ulimit.go
generated
vendored
2
vendor/github.com/docker/cli/opts/ulimit.go
generated
vendored
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
)
|
||||
|
||||
// UlimitOpt defines a map of Ulimits
|
||||
|
||||
2
vendor/github.com/docker/cli/opts/weightdevice.go
generated
vendored
2
vendor/github.com/docker/cli/opts/weightdevice.go
generated
vendored
@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/blkiodev"
|
||||
"github.com/moby/moby/api/types/blkiodev"
|
||||
)
|
||||
|
||||
// ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error.
|
||||
|
||||
36
vendor/github.com/docker/cli/templates/templates.go
generated
vendored
36
vendor/github.com/docker/cli/templates/templates.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.23
|
||||
//go:build go1.24
|
||||
|
||||
package templates
|
||||
|
||||
@ -13,18 +13,7 @@ import (
|
||||
// basicFunctions are the set of initial
|
||||
// functions provided to every template.
|
||||
var basicFunctions = template.FuncMap{
|
||||
"json": func(v any) string {
|
||||
buf := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(buf)
|
||||
enc.SetEscapeHTML(false)
|
||||
err := enc.Encode(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Remove the trailing new line added by the encoder
|
||||
return strings.TrimSpace(buf.String())
|
||||
},
|
||||
"json": formatJSON,
|
||||
"split": strings.Split,
|
||||
"join": strings.Join,
|
||||
"title": strings.Title, //nolint:nolintlint,staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope
|
||||
@ -71,7 +60,7 @@ var HeaderFunctions = template.FuncMap{
|
||||
// Parse creates a new anonymous template with the basic functions
|
||||
// and parses the given format.
|
||||
func Parse(format string) (*template.Template, error) {
|
||||
return NewParse("", format)
|
||||
return template.New("").Funcs(basicFunctions).Parse(format)
|
||||
}
|
||||
|
||||
// New creates a new empty template with the provided tag and built-in
|
||||
@ -80,12 +69,6 @@ func New(tag string) *template.Template {
|
||||
return template.New(tag).Funcs(basicFunctions)
|
||||
}
|
||||
|
||||
// NewParse creates a new tagged template with the basic functions
|
||||
// and parses the given format.
|
||||
func NewParse(tag, format string) (*template.Template, error) {
|
||||
return New(tag).Parse(format)
|
||||
}
|
||||
|
||||
// padWithSpace adds whitespace to the input if the input is non-empty
|
||||
func padWithSpace(source string, prefix, suffix int) string {
|
||||
if source == "" {
|
||||
@ -101,3 +84,16 @@ func truncateWithLength(source string, length int) string {
|
||||
}
|
||||
return source[:length]
|
||||
}
|
||||
|
||||
func formatJSON(v any) string {
|
||||
buf := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(buf)
|
||||
enc.SetEscapeHTML(false)
|
||||
err := enc.Encode(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Remove the trailing new line added by the encoder
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user