chore: go mod tidy / vendor / make deps

This commit is contained in:
2025-10-02 08:25:31 +02:00
parent 1c10e64c58
commit d63a1c28ea
505 changed files with 34448 additions and 35285 deletions

View File

@ -168,34 +168,30 @@ func (tcmd *TopLevelCommand) Initialize(ops ...command.CLIOption) error {
}
// VisitAll will traverse all commands from the root.
// This is different from the VisitAll of cobra.Command where only parents
// are checked.
//
// 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)
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) {
visitAll(cmd, func(ccmd *cobra.Command) {
// do not add a `[flags]` to the end of the usage line.
ccmd.DisableFlagsInUseLine = true
})
}
// HasCompletionArg returns true if a cobra completion arg request is found.
func HasCompletionArg(args []string) bool {
for _, arg := range args {
if arg == cobra.ShellCompRequestCmd || arg == cobra.ShellCompNoDescRequestCmd {
return true
}
}
return false
}
var helpCommand = &cobra.Command{
Use: "help [command]",
Short: "Help about the command",

View File

@ -282,6 +282,17 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
}
filterResourceAttributesEnvvar()
// early return if GODEBUG is already set or the docker context is
// the default context, i.e. is a virtual context where we won't override
// any GODEBUG values.
if v := os.Getenv("GODEBUG"); cli.currentContext == DefaultContextName || v != "" {
return nil
}
meta, err := cli.contextStore.GetMetadata(cli.currentContext)
if err == nil {
setGoDebug(meta)
}
return nil
}
@ -475,6 +486,57 @@ func (cli *DockerCli) getDockerEndPoint() (ep docker.Endpoint, err error) {
return resolveDockerEndpoint(cli.contextStore, cn)
}
// setGoDebug is an escape hatch that sets the GODEBUG environment
// variable value using docker context metadata.
//
// {
// "Name": "my-context",
// "Metadata": { "GODEBUG": "x509negativeserial=1" }
// }
//
// WARNING: Setting x509negativeserial=1 allows Go's x509 library to accept
// X.509 certificates with negative serial numbers.
// This behavior is deprecated and non-compliant with current security
// standards (RFC 5280). Accepting negative serial numbers can introduce
// serious security vulnerabilities, including the risk of certificate
// collision or bypass attacks.
// This option should only be used for legacy compatibility and never in
// production environments.
// Use at your own risk.
func setGoDebug(meta store.Metadata) {
fieldName := "GODEBUG"
godebugEnv := os.Getenv(fieldName)
// early return if GODEBUG is already set. We don't want to override what
// the user already sets.
if godebugEnv != "" {
return
}
var cfg any
var ok bool
switch m := meta.Metadata.(type) {
case DockerContext:
cfg, ok = m.AdditionalFields[fieldName]
if !ok {
return
}
case map[string]any:
cfg, ok = m[fieldName]
if !ok {
return
}
default:
return
}
v, ok := cfg.(string)
if !ok {
return
}
// set the GODEBUG environment variable with whatever was in the context
_ = os.Setenv(fieldName, v)
}
func (cli *DockerCli) initialize() error {
cli.init.Do(func() {
cli.dockerEndpoint, cli.initErr = cli.getDockerEndPoint()

View File

@ -31,11 +31,13 @@ const (
// authConfigKey is the key used to store credentials for Docker Hub. It is
// a copy of [registry.IndexServer].
//
// [registry.IndexServer]: https://pkg.go.dev/github.com/docker/docker/registry#IndexServer
// [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
@ -66,6 +68,8 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf
//
// It is similar to [registry.ResolveAuthConfig], but uses the credentials-
// store, instead of looking up credentials from a map.
//
// [registry.ResolveAuthConfig]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/registry#ResolveAuthConfig
func ResolveAuthConfig(cfg *configfile.ConfigFile, index *registrytypes.IndexInfo) registrytypes.AuthConfig {
configKey := index.Name
if index.Official {
@ -97,23 +101,6 @@ func GetDefaultAuthConfig(cfg *configfile.ConfigFile, checkCredStore bool, serve
return registrytypes.AuthConfig(authconfig), nil
}
// ConfigureAuth handles prompting of user's username and password if needed.
//
// Deprecated: use [PromptUserForCredentials] instead.
func ConfigureAuth(ctx context.Context, cli Cli, flUser, flPassword string, authConfig *registrytypes.AuthConfig, _ bool) error {
defaultUsername := authConfig.Username
serverAddress := authConfig.ServerAddress
newAuthConfig, err := PromptUserForCredentials(ctx, cli, flUser, flPassword, defaultUsername, serverAddress)
if err != nil {
return err
}
authConfig.Username = newAuthConfig.Username
authConfig.Password = newAuthConfig.Password
return nil
}
// PromptUserForCredentials handles the CLI prompt for the user to input
// credentials.
// If argUser is not empty, then the user is only prompted for their password.
@ -209,47 +196,38 @@ func PromptUserForCredentials(ctx context.Context, cli Cli, argUser, argPassword
}, nil
}
// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete
// image. The auth configuration is serialized as a base64url encoded RFC4648,
// section 5) JSON string for sending through the X-Registry-Auth header.
// RetrieveAuthTokenFromImage retrieves an encoded auth token given a
// complete image reference. The auth configuration is serialized as a
// base64url encoded ([RFC 4648, Section 5]) JSON string for sending through
// the "X-Registry-Auth" header.
//
// For details on base64url encoding, see:
// - RFC4648, section 5: https://tools.ietf.org/html/rfc4648#section-5
// [RFC 4648, Section 5]: https://tools.ietf.org/html/rfc4648#section-5
func RetrieveAuthTokenFromImage(cfg *configfile.ConfigFile, image string) (string, error) {
// Retrieve encoded auth token from the image reference
authConfig, err := resolveAuthConfigFromImage(cfg, image)
registryRef, err := reference.ParseNormalizedNamed(image)
if err != nil {
return "", err
}
encodedAuth, err := registrytypes.EncodeAuthConfig(authConfig)
configKey := getAuthConfigKey(reference.Domain(registryRef))
authConfig, err := cfg.GetAuthConfig(configKey)
if err != nil {
return "", err
}
encodedAuth, err := registrytypes.EncodeAuthConfig(registrytypes.AuthConfig(authConfig))
if err != nil {
return "", err
}
return encodedAuth, nil
}
// resolveAuthConfigFromImage retrieves that AuthConfig using the image string
func resolveAuthConfigFromImage(cfg *configfile.ConfigFile, image string) (registrytypes.AuthConfig, error) {
registryRef, err := reference.ParseNormalizedNamed(image)
if err != nil {
return registrytypes.AuthConfig{}, err
}
configKey := getAuthConfigKey(reference.Domain(registryRef))
a, err := cfg.GetAuthConfig(configKey)
if err != nil {
return registrytypes.AuthConfig{}, err
}
return registrytypes.AuthConfig(a), nil
}
// getAuthConfigKey special-cases using the full index address of the official
// index as the AuthConfig key, and uses the (host)name[:port] for private indexes.
//
// It is similar to [registry.GetAuthConfigKey], but does not require on
// [registrytypes.IndexInfo] as intermediate.
//
// [registry.GetAuthConfigKey]: https://pkg.go.dev/github.com/docker/docker/registry#GetAuthConfigKey
// [registrytypes.IndexInfo]:https://pkg.go.dev/github.com/docker/docker/api/types/registry#IndexInfo
// [registry.GetAuthConfigKey]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/registry#GetAuthConfigKey
// [registrytypes.IndexInfo]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/api/types/registry#IndexInfo
func getAuthConfigKey(domainName string) string {
if domainName == "docker.io" || domainName == "index.docker.io" {
return authConfigKey

View File

@ -8,21 +8,31 @@ import (
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
@ -31,6 +41,8 @@ type Stack struct {
}
// 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 {

View File

@ -1,15 +0,0 @@
package command
import (
"github.com/spf13/pflag"
)
// AddTrustVerificationFlags adds content trust flags to the provided flagset
func AddTrustVerificationFlags(fs *pflag.FlagSet, v *bool, trusted bool) {
fs.BoolVar(v, "disable-content-trust", !trusted, "Skip image verification")
}
// AddTrustSigningFlags adds "signing" flags to the provided flagset
func AddTrustSigningFlags(fs *pflag.FlagSet, v *bool, trusted bool) {
fs.BoolVar(v, "disable-content-trust", !trusted, "Skip image signing")
}

View File

@ -14,30 +14,20 @@ import (
"github.com/docker/cli/cli/streams"
"github.com/docker/cli/internal/prompt"
"github.com/docker/docker/api/types/filters"
"github.com/moby/sys/atomicwriter"
"github.com/pkg/errors"
"github.com/spf13/pflag"
)
// CopyToFile writes the content of the reader to the specified file
// ErrPromptTerminated is returned if the user terminated the prompt.
//
// Deprecated: use [atomicwriter.New].
func CopyToFile(outfile string, r io.Reader) error {
writer, err := atomicwriter.New(outfile, 0o600)
if err != nil {
return err
}
defer writer.Close()
_, err = io.Copy(writer, r)
return err
}
// 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)
}
@ -49,6 +39,8 @@ func DisableInputEcho(ins *streams.In) (restore func() error, err 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)
}
@ -63,6 +55,8 @@ func PromptForInput(ctx context.Context, in io.Reader, out io.Writer, message st
// 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)
}
@ -108,12 +102,6 @@ func PruneFilters(dockerCLI config.Provider, pruneFilters filters.Args) filters.
return pruneFilters
}
// AddPlatformFlag adds `platform` to a set of flags for API version 1.32 and later.
func AddPlatformFlag(flags *pflag.FlagSet, target *string) {
flags.StringVar(target, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable")
_ = flags.SetAnnotation("platform", "version", []string{"1.32"})
}
// ValidateOutputPath validates the output paths of the "docker cp" command.
func ValidateOutputPath(path string) error {
dir := filepath.Dir(filepath.Clean(path))

View File

@ -1,4 +1,4 @@
package opts
package loader
import (
"os"
@ -6,19 +6,21 @@ import (
"github.com/docker/cli/pkg/kvfile"
)
// ParseEnvFile reads a file with environment variables enumerated by lines
// parseEnvFile reads a file with environment variables enumerated by lines
//
// “Environment variable names used by the utilities in the Shell and
// Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase
// Utilities volume of [IEEE Std 1003.1-2001] consist solely of uppercase
// letters, digits, and the '_' (underscore) from the characters defined in
// Portable Character Set and do not begin with a digit. *But*, other
// characters may be permitted by an implementation; applications shall
// tolerate the presence of such names.”
// -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
//
// As of #16585, it's up to application inside docker to validate or not
// As of [moby-16585], it's up to application inside docker to validate or not
// environment variables, that's why we just strip leading whitespace and
// nothing more.
func ParseEnvFile(filename string) ([]string, error) {
//
// [IEEE Std 1003.1-2001]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
// [moby-16585]: https://github.com/moby/moby/issues/16585
func parseEnvFile(filename string) ([]string, error) {
return kvfile.Parse(filename, os.LookupEnv)
}

View File

@ -17,6 +17,7 @@ import (
"github.com/docker/cli/cli/compose/schema"
"github.com/docker/cli/cli/compose/template"
"github.com/docker/cli/cli/compose/types"
"github.com/docker/cli/internal/volumespec"
"github.com/docker/cli/opts"
"github.com/docker/cli/opts/swarmopts"
"github.com/docker/docker/api/types/versions"
@ -41,6 +42,13 @@ type Options struct {
discardEnvFiles bool
}
// ParseVolume parses a volume spec without any knowledge of the target platform.
//
// This function is unused, but kept for backward-compatibility for external users.
func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
return volumespec.Parse(spec)
}
// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to
// the `environment` section
func WithDiscardEnvFiles(options *Options) {
@ -460,7 +468,7 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, l
for _, file := range serviceConfig.EnvFile {
filePath := absPath(workingDir, file)
fileVars, err := opts.ParseEnvFile(filePath)
fileVars, err := parseEnvFile(filePath)
if err != nil {
return err
}
@ -756,7 +764,7 @@ var transformBuildConfig TransformerFunc = func(data any) (any, error) {
var transformServiceVolumeConfig TransformerFunc = func(data any) (any, error) {
switch value := data.(type) {
case string:
return ParseVolume(value)
return volumespec.Parse(value)
case map[string]any:
return data, nil
default:

View File

@ -8,6 +8,8 @@ import (
"fmt"
"strconv"
"time"
"github.com/docker/cli/internal/volumespec"
)
// UnsupportedProperties not yet supported by this implementation of the compose file
@ -390,43 +392,23 @@ type ServicePortConfig struct {
}
// ServiceVolumeConfig are references to a volume used by a service
type ServiceVolumeConfig struct {
Type string `yaml:",omitempty" json:"type,omitempty"`
Source string `yaml:",omitempty" json:"source,omitempty"`
Target string `yaml:",omitempty" json:"target,omitempty"`
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"`
Consistency string `yaml:",omitempty" json:"consistency,omitempty"`
Bind *ServiceVolumeBind `yaml:",omitempty" json:"bind,omitempty"`
Volume *ServiceVolumeVolume `yaml:",omitempty" json:"volume,omitempty"`
Image *ServiceVolumeImage `yaml:",omitempty" json:"image,omitempty"`
Tmpfs *ServiceVolumeTmpfs `yaml:",omitempty" json:"tmpfs,omitempty"`
Cluster *ServiceVolumeCluster `yaml:",omitempty" json:"cluster,omitempty"`
}
type ServiceVolumeConfig = volumespec.VolumeConfig
// ServiceVolumeBind are options for a service volume of type bind
type ServiceVolumeBind struct {
Propagation string `yaml:",omitempty" json:"propagation,omitempty"`
}
type ServiceVolumeBind = volumespec.BindOpts
// ServiceVolumeVolume are options for a service volume of type volume
type ServiceVolumeVolume struct {
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
type ServiceVolumeVolume = volumespec.VolumeOpts
// ServiceVolumeImage are options for a service volume of type image
type ServiceVolumeImage struct {
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
type ServiceVolumeImage = volumespec.ImageOpts
// ServiceVolumeTmpfs are options for a service volume of type tmpfs
type ServiceVolumeTmpfs struct {
Size int64 `yaml:",omitempty" json:"size,omitempty"`
}
type ServiceVolumeTmpfs = volumespec.TmpFsOpts
// ServiceVolumeCluster are options for a service volume of type cluster.
// Deliberately left blank for future options, but unused now.
type ServiceVolumeCluster struct{}
type ServiceVolumeCluster = volumespec.ClusterOpts
// FileReferenceConfig for a reference to a swarm file object
type FileReferenceConfig struct {

View File

@ -7,8 +7,8 @@ type AuthConfig struct {
Auth string `json:"auth,omitempty"`
// Email is an optional value associated with the username.
// This field is deprecated and will be removed in a later
// version of docker.
//
// 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"`

View File

@ -1,9 +1,9 @@
package store
import cerrdefs "github.com/containerd/errdefs"
import "github.com/containerd/errdefs"
func invalidParameter(err error) error {
if err == nil || cerrdefs.IsInvalidArgument(err) {
if err == nil || errdefs.IsInvalidArgument(err) {
return err
}
return invalidParameterErr{err}
@ -14,7 +14,7 @@ type invalidParameterErr struct{ error }
func (invalidParameterErr) InvalidParameter() {}
func notFound(err error) error {
if err == nil || cerrdefs.IsNotFound(err) {
if err == nil || errdefs.IsNotFound(err) {
return err
}
return notFoundErr{err}

View File

@ -1,12 +1,12 @@
package flags
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/opts"
"github.com/docker/docker/client"
"github.com/docker/go-connections/tlsconfig"
"github.com/sirupsen/logrus"
@ -54,6 +54,39 @@ var (
dockerTLS = os.Getenv(EnvEnableTLS) != ""
)
// hostVar is used for the '--host' / '-H' flag to set [ClientOptions.Hosts].
// The [ClientOptions.Hosts] field is a slice because it was originally shared
// with the daemon config. However, the CLI only allows for a single host to
// be specified.
//
// hostVar presents itself as a "string", but stores the value in a string
// slice. It produces an error when trying to set multiple values, matching
// the check in [getServerHost].
//
// [getServerHost]: https://github.com/docker/cli/blob/7eab668982645def1cd46fe1b60894cba6fd17a4/cli/command/cli.go#L542-L551
type hostVar struct {
dst *[]string
set bool
}
func (h *hostVar) String() string {
if h.dst == nil || len(*h.dst) == 0 {
return ""
}
return (*h.dst)[0]
}
func (h *hostVar) Set(s string) error {
if h.set {
return errors.New("specify only one -H")
}
*h.dst = []string{s}
h.set = true
return nil
}
func (*hostVar) Type() string { return "string" }
// ClientOptions are the options used to configure the client cli.
type ClientOptions struct {
Debug bool
@ -90,13 +123,13 @@ func (o *ClientOptions) InstallFlags(flags *pflag.FlagSet) {
KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile),
}
tlsOptions := o.TLSOptions
flags.Var(opts.NewQuotedString(&tlsOptions.CAFile), "tlscacert", "Trust certs signed only by this CA")
flags.Var(opts.NewQuotedString(&tlsOptions.CertFile), "tlscert", "Path to TLS certificate file")
flags.Var(opts.NewQuotedString(&tlsOptions.KeyFile), "tlskey", "Path to TLS key file")
flags.Var(&quotedString{&tlsOptions.CAFile}, "tlscacert", "Trust certs signed only by this CA")
flags.Var(&quotedString{&tlsOptions.CertFile}, "tlscert", "Path to TLS certificate file")
flags.Var(&quotedString{&tlsOptions.KeyFile}, "tlskey", "Path to TLS key file")
// opts.ValidateHost is not used here, so as to allow connection helpers
hostOpt := opts.NewNamedListOptsRef("hosts", &o.Hosts, nil)
flags.VarP(hostOpt, "host", "H", "Daemon socket to connect to")
// TODO(thaJeztah): show the default host.
// TODO(thaJeztah): this should be a string, not an "array" as we only allow a single host.
flags.VarP(&hostVar{dst: &o.Hosts}, "host", "H", "Daemon socket to connect to")
flags.StringVarP(&o.Context, "context", "c", "",
`Name of the context to use to connect to the daemon (overrides `+client.EnvOverrideHost+` env var and default context set with "docker context use")`)
}
@ -146,3 +179,33 @@ 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
}

View File

@ -0,0 +1,40 @@
package volumespec
// VolumeConfig are references to a volume used by a service
type VolumeConfig struct {
Type string `yaml:",omitempty" json:"type,omitempty"`
Source string `yaml:",omitempty" json:"source,omitempty"`
Target string `yaml:",omitempty" json:"target,omitempty"`
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"`
Consistency string `yaml:",omitempty" json:"consistency,omitempty"`
Bind *BindOpts `yaml:",omitempty" json:"bind,omitempty"`
Volume *VolumeOpts `yaml:",omitempty" json:"volume,omitempty"`
Image *ImageOpts `yaml:",omitempty" json:"image,omitempty"`
Tmpfs *TmpFsOpts `yaml:",omitempty" json:"tmpfs,omitempty"`
Cluster *ClusterOpts `yaml:",omitempty" json:"cluster,omitempty"`
}
// BindOpts are options for a service volume of type bind
type BindOpts struct {
Propagation string `yaml:",omitempty" json:"propagation,omitempty"`
}
// VolumeOpts are options for a service volume of type volume
type VolumeOpts struct {
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
// ImageOpts are options for a service volume of type image
type ImageOpts struct {
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
}
// TmpFsOpts are options for a service volume of type tmpfs
type TmpFsOpts struct {
Size int64 `yaml:",omitempty" json:"size,omitempty"`
}
// ClusterOpts are options for a service volume of type cluster.
// Deliberately left blank for future options, but unused now.
type ClusterOpts struct{}

View File

@ -1,20 +1,19 @@
package loader
package volumespec
import (
"strings"
"unicode"
"unicode/utf8"
"github.com/docker/cli/cli/compose/types"
"github.com/docker/docker/api/types/mount"
"github.com/pkg/errors"
)
const endOfSpec = rune(0)
// ParseVolume parses a volume spec without any knowledge of the target platform
func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
volume := types.ServiceVolumeConfig{}
// Parse parses a volume spec without any knowledge of the target platform
func Parse(spec string) (VolumeConfig, error) {
volume := VolumeConfig{}
switch len(spec) {
case 0:
@ -49,7 +48,7 @@ func isWindowsDrive(buffer []rune, char rune) bool {
return char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])
}
func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolumeConfig) error {
func populateFieldFromBuffer(char rune, buffer []rune, volume *VolumeConfig) error {
strBuffer := string(buffer)
switch {
case len(buffer) == 0:
@ -74,10 +73,10 @@ func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolu
case "rw":
volume.ReadOnly = false
case "nocopy":
volume.Volume = &types.ServiceVolumeVolume{NoCopy: true}
volume.Volume = &VolumeOpts{NoCopy: true}
default:
if isBindOption(option) {
volume.Bind = &types.ServiceVolumeBind{Propagation: option}
volume.Bind = &BindOpts{Propagation: option}
}
// ignore unknown options
}
@ -94,7 +93,7 @@ func isBindOption(option string) bool {
return false
}
func populateType(volume *types.ServiceVolumeConfig) {
func populateType(volume *VolumeConfig) {
switch {
// Anonymous volume
case volume.Source == "":

View File

@ -7,13 +7,14 @@ import (
)
// ValidateEnv validates an environment variable and returns it.
// If no value is specified, it obtains its value from the current environment
// If no value is specified, it obtains its value from the current environment.
//
// As on ParseEnvFile and related to #16585, environment variable names
// are not validated, and it's up to the application inside the container
// to validate them or not.
// Environment variable names are not validated, and it's up to the application
// inside the container to validate them (see [moby-16585]). The only validation
// here is to check if name is empty, per [moby-25099].
//
// The only validation here is to check if name is empty, per #25099
// [moby-16585]: https://github.com/moby/moby/issues/16585
// [moby-25099]: https://github.com/moby/moby/issues/25099
func ValidateEnv(val string) (string, error) {
k, _, hasValue := strings.Cut(val, "=")
if k == "" {

View File

@ -0,0 +1,14 @@
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)
}

View File

@ -34,7 +34,7 @@ const (
// ValidateHost validates that the specified string is a valid host and returns it.
//
// TODO(thaJeztah): ValidateHost appears to be unused; deprecate 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

View File

@ -134,6 +134,8 @@ func (opts *ListOpts) WithValidator(validator ValidatorFctType) *ListOpts {
// 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
}
@ -141,6 +143,8 @@ type NamedOption interface {
// 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
@ -149,6 +153,8 @@ type NamedListOpts struct {
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,
@ -157,6 +163,8 @@ func NewNamedListOptsRef(name string, values *[]string, validator ValidatorFctTy
}
// 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
}
@ -210,6 +218,8 @@ 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
@ -218,6 +228,8 @@ type NamedMapOpts struct {
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,
@ -226,6 +238,8 @@ func NewNamedMapOpts(name string, values map[string]string, validator ValidatorF
}
// 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
}

View File

@ -2,6 +2,8 @@ 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
}
@ -35,6 +37,8 @@ func trimQuotes(value string) string {
}
// 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}
}

View File

@ -1608,6 +1608,8 @@ definitions:
Bridge:
description: |
Name of the default bridge interface when dockerd's --bridge flag is set.
Deprecated: This field is only set when the daemon is started with the --bridge flag specified.
type: "string"
example: "docker0"
SandboxID:
@ -2234,6 +2236,10 @@ definitions:
password:
type: "string"
email:
description: |
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 a future release.
type: "string"
serveraddress:
type: "string"
@ -4392,6 +4398,7 @@ definitions:
A counter that triggers an update even if no relevant parameters have
been changed.
type: "integer"
format: "uint64"
Runtime:
description: |
Runtime is the type of runtime specified for the task executor.

View File

@ -1,6 +1,8 @@
package build
// CacheDiskUsage contains disk usage for the build cache.
//
// Deprecated: this type is no longer used and will be removed in the next release.
type CacheDiskUsage struct {
TotalSize int64
Reclaimable int64

View File

@ -1,6 +1,8 @@
package container
// DiskUsage contains disk usage for containers.
//
// Deprecated: this type is no longer used and will be removed in the next release.
type DiskUsage struct {
TotalSize int64
Reclaimable int64

View File

@ -13,8 +13,11 @@ type NetworkSettings struct {
}
// NetworkSettingsBase holds networking state for a container when inspecting it.
//
// Deprecated: Most fields in NetworkSettingsBase are deprecated. Fields which aren't deprecated will move to
// NetworkSettings in v29.0, and this struct will be removed.
type NetworkSettingsBase struct {
Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.
Bridge string // Deprecated: This field is only set when the daemon is started with the --bridge flag specified.
SandboxID string // SandboxID uniquely represents a container's network stack
SandboxKey string // SandboxKey identifies the sandbox
Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port
@ -35,18 +38,44 @@ type NetworkSettingsBase struct {
SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
}
// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
// DefaultNetworkSettings holds the networking state for the default bridge, if the container is connected to that
// network.
//
// Deprecated: this struct is deprecated since Docker v1.11 and will be removed in v29. You should look for the default
// network in NetworkSettings.Networks instead.
type DefaultNetworkSettings struct {
EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox
Gateway string // Gateway holds the gateway address for the network
GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address
GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
IPAddress string // IPAddress holds the IPv4 address for the network
IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address
IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6
MacAddress string // MacAddress holds the MAC address for the network
// EndpointID uniquely represents a service endpoint in a Sandbox
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
EndpointID string
// Gateway holds the gateway address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
Gateway string
// GlobalIPv6Address holds network's global IPv6 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
GlobalIPv6Address string
// GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
GlobalIPv6PrefixLen int
// IPAddress holds the IPv4 address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPAddress string
// IPPrefixLen represents mask length of network's IPv4 address
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPPrefixLen int
// IPv6Gateway holds gateway address specific for IPv6
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
IPv6Gateway string
// MacAddress holds the MAC address for the network
//
// Deprecated: This field will be removed in v29. You should look for the default network in NetworkSettings.Networks instead.
MacAddress string
}
// NetworkSettingsSummary provides a summary of container's networks

View File

@ -0,0 +1,61 @@
package filters
import (
"encoding/json"
"github.com/docker/docker/api/types/versions"
)
// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22
// then the encoded format will use an older legacy format where the values are a
// list of strings, instead of a set.
//
// Deprecated: do not use in any new code; use ToJSON instead
func ToParamWithVersion(version string, a Args) (string, error) {
out, err := ToJSON(a)
if out == "" || err != nil {
return "", nil
}
if version != "" && versions.LessThan(version, "1.22") {
return encodeLegacyFilters(out)
}
return out, nil
}
// encodeLegacyFilters encodes Args in the legacy format as used in API v1.21 and older.
// where values are a list of strings, instead of a set.
//
// Don't use in any new code; use [filters.ToJSON]] instead.
func encodeLegacyFilters(currentFormat string) (string, error) {
// The Args.fields field is not exported, but used to marshal JSON,
// so we'll marshal to the new format, then unmarshal to get the
// fields, and marshal again.
//
// This is far from optimal, but this code is only used for deprecated
// API versions, so should not be hit commonly.
var argsFields map[string]map[string]bool
err := json.Unmarshal([]byte(currentFormat), &argsFields)
if err != nil {
return "", err
}
buf, err := json.Marshal(convertArgsToSlice(argsFields))
if err != nil {
return "", err
}
return string(buf), nil
}
func convertArgsToSlice(f map[string]map[string]bool) map[string][]string {
m := map[string][]string{}
for k, v := range f {
values := []string{}
for kk := range v {
if v[kk] {
values = append(values, kk)
}
}
m[k] = values
}
return m
}

View File

@ -8,8 +8,6 @@ import (
"encoding/json"
"regexp"
"strings"
"github.com/docker/docker/api/types/versions"
)
// Args stores a mapping of keys to a set of multiple values.
@ -63,24 +61,6 @@ func ToJSON(a Args) (string, error) {
return string(buf), err
}
// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22
// then the encoded format will use an older legacy format where the values are a
// list of strings, instead of a set.
//
// Deprecated: do not use in any new code; use ToJSON instead
func ToParamWithVersion(version string, a Args) (string, error) {
if a.Len() == 0 {
return "", nil
}
if version != "" && versions.LessThan(version, "1.22") {
buf, err := json.Marshal(convertArgsToSlice(a.fields))
return string(buf), err
}
return ToJSON(a)
}
// FromJSON decodes a JSON encoded string into Args
func FromJSON(p string) (Args, error) {
args := NewArgs()
@ -320,17 +300,3 @@ func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
}
return m
}
func convertArgsToSlice(f map[string]map[string]bool) map[string][]string {
m := map[string][]string{}
for k, v := range f {
values := []string{}
for kk := range v {
if v[kk] {
values = append(values, kk)
}
}
m[k] = values
}
return m
}

View File

@ -1,6 +1,8 @@
package image
// DiskUsage contains disk usage for images.
//
// Deprecated: this type is no longer used and will be removed in the next release.
type DiskUsage struct {
TotalSize int64
Reclaimable int64

View File

@ -4,8 +4,6 @@ import (
"errors"
"fmt"
"net"
"github.com/docker/docker/internal/multierror"
)
// EndpointSettings stores the network endpoint details
@ -99,7 +97,7 @@ func (cfg *EndpointIPAMConfig) IsInRange(v4Subnets []NetworkSubnet, v6Subnets []
errs = append(errs, err)
}
return multierror.Join(errs...)
return errJoin(errs...)
}
func validateEndpointIPAddress(epAddr string, ipamSubnets []NetworkSubnet) error {
@ -149,5 +147,5 @@ func (cfg *EndpointIPAMConfig) Validate() error {
}
}
return multierror.Join(errs...)
return errJoin(errs...)
}

View File

@ -4,8 +4,7 @@ import (
"errors"
"fmt"
"net/netip"
"github.com/docker/docker/internal/multierror"
"strings"
)
// IPAM represents IP Address Management
@ -72,7 +71,7 @@ func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error {
}
}
if err := multierror.Join(errs...); err != nil {
if err := errJoin(errs...); err != nil {
return fmt.Errorf("invalid network config:\n%w", err)
}
@ -132,3 +131,43 @@ func validateAddress(address string, subnet netip.Prefix, subnetFamily ipFamily)
return nil
}
func errJoin(errs ...error) error {
n := 0
for _, err := range errs {
if err != nil {
n++
}
}
if n == 0 {
return nil
}
e := &joinError{
errs: make([]error, 0, n),
}
for _, err := range errs {
if err != nil {
e.errs = append(e.errs, err)
}
}
return e
}
type joinError struct {
errs []error
}
func (e *joinError) Error() string {
if len(e.errs) == 1 {
return strings.TrimSpace(e.errs[0].Error())
}
stringErrs := make([]string, 0, len(e.errs))
for _, subErr := range e.errs {
stringErrs = append(stringErrs, strings.ReplaceAll(subErr.Error(), "\n", "\n\t"))
}
return "* " + strings.Join(stringErrs, "\n* ")
}
func (e *joinError) Unwrap() []error {
return e.errs
}

View File

@ -32,8 +32,8 @@ type AuthConfig struct {
Auth string `json:"auth,omitempty"`
// Email is an optional value associated with the username.
// This field is deprecated and will be removed in a later
// version of docker.
//
// 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"`

View File

@ -1,5 +1,7 @@
package swarm
import "github.com/docker/docker/api/types/swarm/runtime"
// RuntimeType is the type of runtime used for the TaskSpec
type RuntimeType string
@ -25,3 +27,11 @@ const (
type NetworkAttachmentSpec struct {
ContainerID string
}
// RuntimeSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime.
type RuntimeSpec = runtime.PluginSpec
// RuntimePrivilege describes a permission the user has to accept
// upon installing a plugin.
type RuntimePrivilege = runtime.PluginPrivilege

View File

@ -1,3 +0,0 @@
//go:generate protoc --gogofaster_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto
package runtime

View File

@ -1,808 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: plugin.proto
package runtime
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// PluginSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime.
type PluginSpec struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges,proto3" json:"privileges,omitempty"`
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
Env []string `protobuf:"bytes,5,rep,name=env,proto3" json:"env,omitempty"`
}
func (m *PluginSpec) Reset() { *m = PluginSpec{} }
func (m *PluginSpec) String() string { return proto.CompactTextString(m) }
func (*PluginSpec) ProtoMessage() {}
func (*PluginSpec) Descriptor() ([]byte, []int) {
return fileDescriptor_22a625af4bc1cc87, []int{0}
}
func (m *PluginSpec) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PluginSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PluginSpec.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PluginSpec) XXX_Merge(src proto.Message) {
xxx_messageInfo_PluginSpec.Merge(m, src)
}
func (m *PluginSpec) XXX_Size() int {
return m.Size()
}
func (m *PluginSpec) XXX_DiscardUnknown() {
xxx_messageInfo_PluginSpec.DiscardUnknown(m)
}
var xxx_messageInfo_PluginSpec proto.InternalMessageInfo
func (m *PluginSpec) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *PluginSpec) GetRemote() string {
if m != nil {
return m.Remote
}
return ""
}
func (m *PluginSpec) GetPrivileges() []*PluginPrivilege {
if m != nil {
return m.Privileges
}
return nil
}
func (m *PluginSpec) GetDisabled() bool {
if m != nil {
return m.Disabled
}
return false
}
func (m *PluginSpec) GetEnv() []string {
if m != nil {
return m.Env
}
return nil
}
// PluginPrivilege describes a permission the user has to accept
// upon installing a plugin.
type PluginPrivilege struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
Value []string `protobuf:"bytes,3,rep,name=value,proto3" json:"value,omitempty"`
}
func (m *PluginPrivilege) Reset() { *m = PluginPrivilege{} }
func (m *PluginPrivilege) String() string { return proto.CompactTextString(m) }
func (*PluginPrivilege) ProtoMessage() {}
func (*PluginPrivilege) Descriptor() ([]byte, []int) {
return fileDescriptor_22a625af4bc1cc87, []int{1}
}
func (m *PluginPrivilege) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PluginPrivilege) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PluginPrivilege.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PluginPrivilege) XXX_Merge(src proto.Message) {
xxx_messageInfo_PluginPrivilege.Merge(m, src)
}
func (m *PluginPrivilege) XXX_Size() int {
return m.Size()
}
func (m *PluginPrivilege) XXX_DiscardUnknown() {
xxx_messageInfo_PluginPrivilege.DiscardUnknown(m)
}
var xxx_messageInfo_PluginPrivilege proto.InternalMessageInfo
func (m *PluginPrivilege) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *PluginPrivilege) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
func (m *PluginPrivilege) GetValue() []string {
if m != nil {
return m.Value
}
return nil
}
func init() {
proto.RegisterType((*PluginSpec)(nil), "PluginSpec")
proto.RegisterType((*PluginPrivilege)(nil), "PluginPrivilege")
}
func init() { proto.RegisterFile("plugin.proto", fileDescriptor_22a625af4bc1cc87) }
var fileDescriptor_22a625af4bc1cc87 = []byte{
// 225 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x9a, 0xc1, 0xc8, 0xc5, 0x15, 0x00, 0x16,
0x08, 0x2e, 0x48, 0x4d, 0x16, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60,
0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xc4, 0xb8, 0xd8, 0x8a, 0x52, 0x73, 0xf3, 0x4b, 0x52, 0x25,
0x98, 0xc0, 0xa2, 0x50, 0x9e, 0x90, 0x01, 0x17, 0x57, 0x41, 0x51, 0x66, 0x59, 0x66, 0x4e, 0x6a,
0x7a, 0x6a, 0xb1, 0x04, 0xb3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x80, 0x1e, 0xc4, 0xb0, 0x00, 0x98,
0x44, 0x10, 0x92, 0x1a, 0x21, 0x29, 0x2e, 0x8e, 0x94, 0xcc, 0xe2, 0xc4, 0xa4, 0x9c, 0xd4, 0x14,
0x09, 0x16, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0x39, 0x35, 0xaf, 0x4c,
0x82, 0x55, 0x81, 0x59, 0x83, 0x33, 0x08, 0xc4, 0x54, 0x8a, 0xe5, 0xe2, 0x47, 0x33, 0x0c, 0xab,
0xf3, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
0x6e, 0x44, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x91, 0x33,
0x08, 0xc2, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x24, 0x36,
0x70, 0xd0, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x37, 0xea, 0xe2, 0xca, 0x2a, 0x01, 0x00,
0x00,
}
func (m *PluginSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PluginSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Env) > 0 {
for iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Env[iNdEx])
copy(dAtA[i:], m.Env[iNdEx])
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Env[iNdEx])))
i--
dAtA[i] = 0x2a
}
}
if m.Disabled {
i--
if m.Disabled {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x20
}
if len(m.Privileges) > 0 {
for iNdEx := len(m.Privileges) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Privileges[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintPlugin(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.Remote) > 0 {
i -= len(m.Remote)
copy(dAtA[i:], m.Remote)
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote)))
i--
dAtA[i] = 0x12
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *PluginPrivilege) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PluginPrivilege) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Value) > 0 {
for iNdEx := len(m.Value) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.Value[iNdEx])
copy(dAtA[i:], m.Value[iNdEx])
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Value[iNdEx])))
i--
dAtA[i] = 0x1a
}
}
if len(m.Description) > 0 {
i -= len(m.Description)
copy(dAtA[i:], m.Description)
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Description)))
i--
dAtA[i] = 0x12
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
offset -= sovPlugin(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *PluginSpec) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Name)
if l > 0 {
n += 1 + l + sovPlugin(uint64(l))
}
l = len(m.Remote)
if l > 0 {
n += 1 + l + sovPlugin(uint64(l))
}
if len(m.Privileges) > 0 {
for _, e := range m.Privileges {
l = e.Size()
n += 1 + l + sovPlugin(uint64(l))
}
}
if m.Disabled {
n += 2
}
if len(m.Env) > 0 {
for _, s := range m.Env {
l = len(s)
n += 1 + l + sovPlugin(uint64(l))
}
}
return n
}
func (m *PluginPrivilege) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Name)
if l > 0 {
n += 1 + l + sovPlugin(uint64(l))
}
l = len(m.Description)
if l > 0 {
n += 1 + l + sovPlugin(uint64(l))
}
if len(m.Value) > 0 {
for _, s := range m.Value {
l = len(s)
n += 1 + l + sovPlugin(uint64(l))
}
}
return n
}
func sovPlugin(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozPlugin(x uint64) (n int) {
return sovPlugin(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *PluginSpec) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PluginSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PluginSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Remote", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Remote = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Privileges", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Privileges = append(m.Privileges, &PluginPrivilege{})
if err := m.Privileges[len(m.Privileges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Disabled", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Disabled = bool(v != 0)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlugin(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlugin
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PluginPrivilege: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PluginPrivilege: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Description = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPlugin
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Value = append(m.Value, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlugin(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthPlugin
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPlugin(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlugin
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlugin
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPlugin
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthPlugin
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupPlugin
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthPlugin
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthPlugin = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowPlugin = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupPlugin = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -1,19 +0,0 @@
syntax = "proto3";
// PluginSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime.
message PluginSpec {
string name = 1;
string remote = 2;
repeated PluginPrivilege privileges = 3;
bool disabled = 4;
repeated string env = 5;
}
// PluginPrivilege describes a permission the user has to accept
// upon installing a plugin.
message PluginPrivilege {
string name = 1;
string description = 2;
repeated string value = 3;
}

View File

@ -0,0 +1,27 @@
package runtime
import "fmt"
// PluginSpec defines the base payload which clients can specify for creating
// a service with the plugin runtime.
type PluginSpec struct {
Name string `json:"name,omitempty"`
Remote string `json:"remote,omitempty"`
Privileges []*PluginPrivilege `json:"privileges,omitempty"`
Disabled bool `json:"disabled,omitempty"`
Env []string `json:"env,omitempty"`
}
// PluginPrivilege describes a permission the user has to accept
// upon installing a plugin.
type PluginPrivilege struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Value []string `json:"value,omitempty"`
}
var (
ErrInvalidLengthPlugin = fmt.Errorf("proto: negative length found during unmarshaling") // Deprecated: this error was only used internally and is no longer used.
ErrIntOverflowPlugin = fmt.Errorf("proto: integer overflow") // Deprecated: this error was only used internally and is no longer used.
ErrUnexpectedEndOfGroupPlugin = fmt.Errorf("proto: unexpected end of group") // Deprecated: this error was only used internally and is no longer used.
)

View File

@ -4,7 +4,6 @@ import (
"time"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm/runtime"
)
// TaskState represents the state of a task.
@ -77,7 +76,7 @@ type TaskSpec struct {
// NetworkAttachmentSpec is used if the `Runtime` field is set to
// `attachment`.
ContainerSpec *ContainerSpec `json:",omitempty"`
PluginSpec *runtime.PluginSpec `json:",omitempty"`
PluginSpec *RuntimeSpec `json:",omitempty"`
NetworkAttachmentSpec *NetworkAttachmentSpec `json:",omitempty"`
Resources *ResourceRequirements `json:",omitempty"`

View File

@ -1,17 +0,0 @@
package system
import (
"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"
)
// DiskUsage contains response of Engine API for API 1.49 and greater:
// GET "/system/df"
type DiskUsage struct {
Images *image.DiskUsage
Containers *container.DiskUsage
Volumes *volume.DiskUsage
BuildCache *build.CacheDiskUsage
}

View File

@ -46,15 +46,16 @@ type NetworkSettings = container.NetworkSettings
// NetworkSettingsBase holds networking state for a container when inspecting it.
//
// Deprecated: use [container.NetworkSettingsBase].
type NetworkSettingsBase = container.NetworkSettingsBase
// Deprecated: [container.NetworkSettingsBase] will be removed in v29. Prefer
// accessing the fields it contains through [container.NetworkSettings].
type NetworkSettingsBase = container.NetworkSettingsBase //nolint:staticcheck // ignore SA1019: NetworkSettingsBase is deprecated in v28.4.
// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
//
// Deprecated: use [container.DefaultNetworkSettings].
type DefaultNetworkSettings = container.DefaultNetworkSettings
type DefaultNetworkSettings = container.DefaultNetworkSettings //nolint:staticcheck // ignore SA1019: DefaultNetworkSettings is deprecated in v28.4.
// SummaryNetworkSettings provides a summary of container's networks
// in /containers/json.

View File

@ -1,6 +1,8 @@
package volume
// DiskUsage contains disk usage for volumes.
//
// Deprecated: this type is no longer used and will be removed in the next release.
type DiskUsage struct {
TotalSize int64
Reclaimable int64

View File

@ -463,7 +463,9 @@ func (cli *Client) dialer() func(context.Context) (net.Conn, error) {
case "unix":
return net.Dial(cli.proto, cli.addr)
case "npipe":
return sockets.DialPipe(cli.addr, 32*time.Second)
ctx, cancel := context.WithTimeout(ctx, 32*time.Second)
defer cancel()
return dialPipeContext(ctx, cli.addr)
default:
if tlsConfig := cli.tlsConfig(); tlsConfig != nil {
return tls.Dial(cli.proto, cli.addr, tlsConfig)

View File

@ -2,6 +2,17 @@
package client
import (
"context"
"net"
"syscall"
)
// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "unix:///var/run/docker.sock"
// dialPipeContext connects to a Windows named pipe. It is not supported on non-Windows.
func dialPipeContext(_ context.Context, _ string) (net.Conn, error) {
return nil, syscall.EAFNOSUPPORT
}

View File

@ -1,5 +1,17 @@
package client
import (
"context"
"net"
"github.com/Microsoft/go-winio"
)
// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST
// (EnvOverrideHost) environment variable is unset or empty.
const DefaultDockerHost = "npipe:////./pipe/docker_engine"
// dialPipeContext connects to a Windows named pipe. It is not supported on non-Windows.
func dialPipeContext(ctx context.Context, addr string) (net.Conn, error) {
return winio.DialPipeContext(ctx, addr)
}

View File

@ -28,7 +28,7 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
return container.StatsResponseReader{
Body: resp.Body,
OSType: getDockerOS(resp.Header.Get("Server")),
OSType: resp.Header.Get("Ostype"),
}, nil
}
@ -51,6 +51,6 @@ func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string
return container.StatsResponseReader{
Body: resp.Body,
OSType: getDockerOS(resp.Header.Get("Server")),
OSType: resp.Header.Get("Ostype"),
}, nil
}

View File

@ -40,7 +40,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
return build.ImageBuildResponse{
Body: resp.Body,
OSType: getDockerOS(resp.Header.Get("Server")),
OSType: resp.Header.Get("Ostype"),
}, nil
}

View File

@ -8,12 +8,9 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/internal/lazyregexp"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
var headerRegexp = lazyregexp.New(`\ADocker/.+\s\((.+)\)\z`)
type emptyIDError string
func (e emptyIDError) InvalidParameter() {}
@ -31,16 +28,6 @@ func trimID(objType, id string) (string, error) {
return id, nil
}
// getDockerOS returns the operating system based on the server header from the daemon.
func getDockerOS(serverHeader string) string {
var osType string
matches := headerRegexp.FindStringSubmatch(serverHeader)
if len(matches) > 0 {
osType = matches[1]
}
return osType
}
// getFiltersQuery returns a url query with "filters" query term, based on the
// filters provided.
func getFiltersQuery(f filters.Args) (url.Values, error) {

View File

@ -1,90 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code below was largely copied from golang.org/x/mod@v0.22;
// https://github.com/golang/mod/blob/v0.22.0/internal/lazyregexp/lazyre.go
// with some additional methods added.
// Package lazyregexp is a thin wrapper over regexp, allowing the use of global
// regexp variables without forcing them to be compiled at init.
package lazyregexp
import (
"os"
"regexp"
"strings"
"sync"
)
// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be
// compiled the first time it is needed.
type Regexp struct {
str string
once sync.Once
rx *regexp.Regexp
}
func (r *Regexp) re() *regexp.Regexp {
r.once.Do(r.build)
return r.rx
}
func (r *Regexp) build() {
r.rx = regexp.MustCompile(r.str)
r.str = ""
}
func (r *Regexp) FindSubmatch(s []byte) [][]byte {
return r.re().FindSubmatch(s)
}
func (r *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
return r.re().FindAllStringSubmatch(s, n)
}
func (r *Regexp) FindStringSubmatch(s string) []string {
return r.re().FindStringSubmatch(s)
}
func (r *Regexp) FindStringSubmatchIndex(s string) []int {
return r.re().FindStringSubmatchIndex(s)
}
func (r *Regexp) ReplaceAllString(src, repl string) string {
return r.re().ReplaceAllString(src, repl)
}
func (r *Regexp) FindString(s string) string {
return r.re().FindString(s)
}
func (r *Regexp) FindAllString(s string, n int) []string {
return r.re().FindAllString(s, n)
}
func (r *Regexp) MatchString(s string) bool {
return r.re().MatchString(s)
}
func (r *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
return r.re().ReplaceAllStringFunc(src, repl)
}
func (r *Regexp) SubexpNames() []string {
return r.re().SubexpNames()
}
var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
// New creates a new lazy regexp, delaying the compiling work until it is first
// needed. If the code is being run as part of tests, the regexp compiling will
// happen immediately.
func New(str string) *Regexp {
lr := &Regexp{str: str}
if inTest {
// In tests, always compile the regexps early.
lr.re()
}
return lr
}

View File

@ -1,46 +0,0 @@
package multierror
import (
"strings"
)
// Join is a drop-in replacement for errors.Join with better formatting.
func Join(errs ...error) error {
n := 0
for _, err := range errs {
if err != nil {
n++
}
}
if n == 0 {
return nil
}
e := &joinError{
errs: make([]error, 0, n),
}
for _, err := range errs {
if err != nil {
e.errs = append(e.errs, err)
}
}
return e
}
type joinError struct {
errs []error
}
func (e *joinError) Error() string {
if len(e.errs) == 1 {
return strings.TrimSpace(e.errs[0].Error())
}
stringErrs := make([]string, 0, len(e.errs))
for _, subErr := range e.errs {
stringErrs = append(stringErrs, strings.ReplaceAll(subErr.Error(), "\n", "\n\t"))
}
return "* " + strings.Join(stringErrs, "\n* ")
}
func (e *joinError) Unwrap() []error {
return e.errs
}

View File

@ -151,9 +151,9 @@ type JSONMessage struct {
// Deprecated: this field is deprecated since docker v0.7.1 / API v1.8. Use the information in [Progress] instead. This field will be omitted in a future release.
ProgressMessage string `json:"progress,omitempty"`
ID string `json:"id,omitempty"`
From string `json:"from,omitempty"`
Time int64 `json:"time,omitempty"`
TimeNano int64 `json:"timeNano,omitempty"`
From string `json:"from,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used.
Time int64 `json:"time,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used.
TimeNano int64 `json:"timeNano,omitempty"` // Deprecated: this field is no longer set in stream responses and should not be used.
Error *JSONError `json:"errorDetail,omitempty"`
// ErrorMessage contains errors encountered during the operation.