vendor: github.com/moby/moby/api, client 0769fe708773 (master)
full diff: 4ca8aedf92...0769fe7087
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
67
vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go
generated
vendored
67
vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go
generated
vendored
@ -1,12 +1,10 @@
|
||||
package stdcopy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// StdType is the type of standard stream
|
||||
@ -28,71 +26,6 @@ const (
|
||||
startingBufLen = 32*1024 + stdWriterPrefixLen + 1
|
||||
)
|
||||
|
||||
var bufPool = &sync.Pool{New: func() any { return bytes.NewBuffer(nil) }}
|
||||
|
||||
// stdWriter is wrapper of io.Writer with extra customized info.
|
||||
type stdWriter struct {
|
||||
io.Writer
|
||||
prefix byte
|
||||
}
|
||||
|
||||
// Write sends the buffer to the underlying writer.
|
||||
// It inserts the prefix header before the buffer,
|
||||
// so [StdCopy] knows where to multiplex the output.
|
||||
//
|
||||
// It implements [io.Writer].
|
||||
func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
if w == nil || w.Writer == nil {
|
||||
return 0, errors.New("writer not instantiated")
|
||||
}
|
||||
if p == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
header := [stdWriterPrefixLen]byte{stdWriterFdIndex: w.prefix}
|
||||
binary.BigEndian.PutUint32(header[stdWriterSizeIndex:], uint32(len(p)))
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
buf.Write(header[:])
|
||||
buf.Write(p)
|
||||
|
||||
n, err := w.Writer.Write(buf.Bytes())
|
||||
n -= stdWriterPrefixLen
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
bufPool.Put(buf)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// NewStdWriter instantiates a new writer using a custom format to multiplex
|
||||
// multiple streams to a single writer. All messages written using this writer
|
||||
// are encapsulated using a custom format, and written to the underlying
|
||||
// stream "w".
|
||||
//
|
||||
// Writers created through NewStdWriter allow for multiple write streams
|
||||
// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// single connection. "streamType" indicates the type of stream to encapsulate,
|
||||
// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to
|
||||
// include server-side errors in the stream. Information on this stream
|
||||
// is returned as an error by [StdCopy] and terminates processing the
|
||||
// stream.
|
||||
//
|
||||
// The [Stdin] stream is present for completeness and should generally
|
||||
// NOT be used. It is output on [Stdout] when reading the stream with
|
||||
// [StdCopy].
|
||||
//
|
||||
// All streams must share the same underlying [io.Writer] to ensure proper
|
||||
// multiplexing. Each call to NewStdWriter wraps that shared writer with
|
||||
// a header indicating the target stream.
|
||||
func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
return &stdWriter{
|
||||
Writer: w,
|
||||
prefix: byte(streamType),
|
||||
}
|
||||
}
|
||||
|
||||
// StdCopy is a modified version of [io.Copy] to de-multiplex messages
|
||||
// from "multiplexedSource" and copy them to destination streams
|
||||
// "destOut" and "destErr".
|
||||
|
||||
3
vendor/github.com/moby/moby/api/types/container/config.go
generated
vendored
3
vendor/github.com/moby/moby/api/types/container/config.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
)
|
||||
|
||||
// MinimumDuration puts a minimum on user configured duration.
|
||||
@ -28,7 +29,7 @@ type Config struct {
|
||||
AttachStdin bool // Attach the standard input, makes possible user interaction
|
||||
AttachStdout bool // Attach the standard output
|
||||
AttachStderr bool // Attach the standard error
|
||||
ExposedPorts PortSet `json:",omitempty"` // List of exposed ports
|
||||
ExposedPorts network.PortSet `json:",omitempty"` // List of exposed ports
|
||||
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
|
||||
OpenStdin bool // Open stdin
|
||||
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
||||
|
||||
5
vendor/github.com/moby/moby/api/types/container/hostconfig.go
generated
vendored
5
vendor/github.com/moby/moby/api/types/container/hostconfig.go
generated
vendored
@ -3,6 +3,7 @@ package container
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/go-units"
|
||||
@ -420,7 +421,7 @@ type HostConfig struct {
|
||||
ContainerIDFile string // File (path) where the containerId is written
|
||||
LogConfig LogConfig // Configuration of the logs for this container
|
||||
NetworkMode NetworkMode // Network mode to use for the container
|
||||
PortBindings PortMap // Port mapping between the exposed port (container) and the host
|
||||
PortBindings network.PortMap // Port mapping between the exposed port (container) and the host
|
||||
RestartPolicy RestartPolicy // Restart policy to be used for the container
|
||||
AutoRemove bool // Automatically remove container when it exits
|
||||
VolumeDriver string // Name of the volume driver used to mount volumes
|
||||
@ -432,7 +433,7 @@ type HostConfig struct {
|
||||
CapAdd []string // List of kernel capabilities to add to the container
|
||||
CapDrop []string // List of kernel capabilities to remove from the container
|
||||
CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container
|
||||
DNS []string `json:"Dns"` // List of DNS server to lookup
|
||||
DNS []netip.Addr `json:"Dns"` // List of DNS server to lookup
|
||||
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
||||
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
||||
ExtraHosts []string // List of extra hosts
|
||||
|
||||
24
vendor/github.com/moby/moby/api/types/container/nat_aliases.go
generated
vendored
24
vendor/github.com/moby/moby/api/types/container/nat_aliases.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package container
|
||||
|
||||
import "github.com/docker/go-connections/nat"
|
||||
|
||||
// PortRangeProto is a string containing port number and protocol in the format "80/tcp",
|
||||
// or a port range and protocol in the format "80-83/tcp".
|
||||
//
|
||||
// It is currently an alias for [nat.Port] but may become a concrete type in a future release.
|
||||
type PortRangeProto = nat.Port
|
||||
|
||||
// PortSet is a collection of structs indexed by [HostPort].
|
||||
//
|
||||
// It is currently an alias for [nat.PortSet] but may become a concrete type in a future release.
|
||||
type PortSet = nat.PortSet
|
||||
|
||||
// PortBinding represents a binding between a Host IP address and a [HostPort].
|
||||
//
|
||||
// It is currently an alias for [nat.PortBinding] but may become a concrete type in a future release.
|
||||
type PortBinding = nat.PortBinding
|
||||
|
||||
// PortMap is a collection of [PortBinding] indexed by [HostPort].
|
||||
//
|
||||
// It is currently an alias for [nat.PortMap] but may become a concrete type in a future release.
|
||||
type PortMap = nat.PortMap
|
||||
11
vendor/github.com/moby/moby/api/types/container/network_settings.go
generated
vendored
11
vendor/github.com/moby/moby/api/types/container/network_settings.go
generated
vendored
@ -6,10 +6,13 @@ import (
|
||||
|
||||
// NetworkSettings exposes the network settings in the api
|
||||
type NetworkSettings struct {
|
||||
SandboxID string // SandboxID uniquely represents a container's network stack
|
||||
SandboxKey string // SandboxKey identifies the sandbox
|
||||
Ports PortMap // Ports is a collection of PortBinding indexed by Port
|
||||
Networks map[string]*network.EndpointSettings
|
||||
SandboxID string // SandboxID uniquely represents a container's network stack
|
||||
SandboxKey string // SandboxKey identifies the sandbox
|
||||
|
||||
// Ports is a collection of [network.PortBinding] indexed by [network.Port]
|
||||
Ports network.PortMap
|
||||
|
||||
Networks map[string]*network.EndpointSettings
|
||||
}
|
||||
|
||||
// NetworkSettingsSummary provides a summary of container's networks
|
||||
|
||||
6
vendor/github.com/moby/moby/api/types/container/port_summary.go
generated
vendored
6
vendor/github.com/moby/moby/api/types/container/port_summary.go
generated
vendored
@ -5,6 +5,10 @@ package container
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// PortSummary Describes a port-mapping between the container and the host.
|
||||
//
|
||||
// Example: {"PrivatePort":8080,"PublicPort":80,"Type":"tcp"}
|
||||
@ -13,7 +17,7 @@ package container
|
||||
type PortSummary struct {
|
||||
|
||||
// Host IP address that the container's port is mapped to
|
||||
IP string `json:"IP,omitempty"`
|
||||
IP netip.Addr `json:"IP,omitempty"`
|
||||
|
||||
// Port on the container
|
||||
// Required: true
|
||||
|
||||
24
vendor/github.com/moby/moby/api/types/filters/errors.go
generated
vendored
24
vendor/github.com/moby/moby/api/types/filters/errors.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package filters
|
||||
|
||||
import "fmt"
|
||||
|
||||
// invalidFilter indicates that the provided filter or its value is invalid
|
||||
type invalidFilter struct {
|
||||
Filter string
|
||||
Value []string
|
||||
}
|
||||
|
||||
func (e invalidFilter) Error() string {
|
||||
msg := "invalid filter"
|
||||
if e.Filter != "" {
|
||||
msg += " '" + e.Filter
|
||||
if e.Value != nil {
|
||||
msg = fmt.Sprintf("%s=%s", msg, e.Value)
|
||||
}
|
||||
msg += "'"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// InvalidParameter marks this error as ErrInvalidParameter
|
||||
func (e invalidFilter) InvalidParameter() {}
|
||||
302
vendor/github.com/moby/moby/api/types/filters/parse.go
generated
vendored
302
vendor/github.com/moby/moby/api/types/filters/parse.go
generated
vendored
@ -1,302 +0,0 @@
|
||||
/*
|
||||
Package filters provides tools for encoding a mapping of keys to a set of
|
||||
multiple values.
|
||||
*/
|
||||
package filters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Args stores a mapping of keys to a set of multiple values.
|
||||
type Args struct {
|
||||
fields map[string]map[string]bool
|
||||
}
|
||||
|
||||
// KeyValuePair are used to initialize a new Args
|
||||
type KeyValuePair struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
// Arg creates a new KeyValuePair for initializing Args
|
||||
func Arg(key, value string) KeyValuePair {
|
||||
return KeyValuePair{Key: key, Value: value}
|
||||
}
|
||||
|
||||
// NewArgs returns a new Args populated with the initial args
|
||||
func NewArgs(initialArgs ...KeyValuePair) Args {
|
||||
args := Args{fields: map[string]map[string]bool{}}
|
||||
for _, arg := range initialArgs {
|
||||
args.Add(arg.Key, arg.Value)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
// Keys returns all the keys in list of Args
|
||||
func (args Args) Keys() []string {
|
||||
keys := make([]string, 0, len(args.fields))
|
||||
for k := range args.fields {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// MarshalJSON returns a JSON byte representation of the Args
|
||||
func (args Args) MarshalJSON() ([]byte, error) {
|
||||
if len(args.fields) == 0 {
|
||||
return []byte("{}"), nil
|
||||
}
|
||||
return json.Marshal(args.fields)
|
||||
}
|
||||
|
||||
// ToJSON returns the Args as a JSON encoded string
|
||||
func ToJSON(a Args) (string, error) {
|
||||
if a.Len() == 0 {
|
||||
return "", nil
|
||||
}
|
||||
buf, err := json.Marshal(a)
|
||||
return string(buf), err
|
||||
}
|
||||
|
||||
// FromJSON decodes a JSON encoded string into Args
|
||||
func FromJSON(p string) (Args, error) {
|
||||
args := NewArgs()
|
||||
|
||||
if p == "" {
|
||||
return args, nil
|
||||
}
|
||||
|
||||
raw := []byte(p)
|
||||
err := json.Unmarshal(raw, &args)
|
||||
if err == nil {
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// Fallback to parsing arguments in the legacy slice format
|
||||
deprecated := map[string][]string{}
|
||||
if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {
|
||||
return args, &invalidFilter{}
|
||||
}
|
||||
|
||||
args.fields = deprecatedArgs(deprecated)
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON populates the Args from JSON encode bytes
|
||||
func (args Args) UnmarshalJSON(raw []byte) error {
|
||||
return json.Unmarshal(raw, &args.fields)
|
||||
}
|
||||
|
||||
// Get returns the list of values associated with the key
|
||||
func (args Args) Get(key string) []string {
|
||||
values := args.fields[key]
|
||||
if values == nil {
|
||||
return make([]string, 0)
|
||||
}
|
||||
slice := make([]string, 0, len(values))
|
||||
for key := range values {
|
||||
slice = append(slice, key)
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
// Add a new value to the set of values
|
||||
func (args Args) Add(key, value string) {
|
||||
if _, ok := args.fields[key]; ok {
|
||||
args.fields[key][value] = true
|
||||
} else {
|
||||
args.fields[key] = map[string]bool{value: true}
|
||||
}
|
||||
}
|
||||
|
||||
// Del removes a value from the set
|
||||
func (args Args) Del(key, value string) {
|
||||
if _, ok := args.fields[key]; ok {
|
||||
delete(args.fields[key], value)
|
||||
if len(args.fields[key]) == 0 {
|
||||
delete(args.fields, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of keys in the mapping
|
||||
func (args Args) Len() int {
|
||||
return len(args.fields)
|
||||
}
|
||||
|
||||
// MatchKVList returns true if all the pairs in sources exist as key=value
|
||||
// pairs in the mapping at key, or if there are no values at key.
|
||||
func (args Args) MatchKVList(key string, sources map[string]string) bool {
|
||||
fieldValues := args.fields[key]
|
||||
|
||||
// do not filter if there is no filter set or cannot determine filter
|
||||
if len(fieldValues) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(sources) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
for value := range fieldValues {
|
||||
testK, testV, hasValue := strings.Cut(value, "=")
|
||||
|
||||
v, ok := sources[testK]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if hasValue && testV != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Match returns true if any of the values at key match the source string
|
||||
func (args Args) Match(field, source string) bool {
|
||||
if args.ExactMatch(field, source) {
|
||||
return true
|
||||
}
|
||||
|
||||
fieldValues := args.fields[field]
|
||||
for name2match := range fieldValues {
|
||||
match, err := regexp.MatchString(name2match, source)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetBoolOrDefault returns a boolean value of the key if the key is present
|
||||
// and is interpretable as a boolean value. Otherwise the default value is returned.
|
||||
// Error is not nil only if the filter values are not valid boolean or are conflicting.
|
||||
func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
|
||||
fieldValues, ok := args.fields[key]
|
||||
if !ok {
|
||||
return defaultValue, nil
|
||||
}
|
||||
|
||||
if len(fieldValues) == 0 {
|
||||
return defaultValue, &invalidFilter{key, nil}
|
||||
}
|
||||
|
||||
isFalse := fieldValues["0"] || fieldValues["false"]
|
||||
isTrue := fieldValues["1"] || fieldValues["true"]
|
||||
if isFalse == isTrue {
|
||||
// Either no or conflicting truthy/falsy value were provided
|
||||
return defaultValue, &invalidFilter{key, args.Get(key)}
|
||||
}
|
||||
return isTrue, nil
|
||||
}
|
||||
|
||||
// ExactMatch returns true if the source matches exactly one of the values.
|
||||
func (args Args) ExactMatch(key, source string) bool {
|
||||
fieldValues, ok := args.fields[key]
|
||||
// do not filter if there is no filter set or cannot determine filter
|
||||
if !ok || len(fieldValues) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// try to match full name value to avoid O(N) regular expression matching
|
||||
return fieldValues[source]
|
||||
}
|
||||
|
||||
// UniqueExactMatch returns true if there is only one value and the source
|
||||
// matches exactly the value.
|
||||
func (args Args) UniqueExactMatch(key, source string) bool {
|
||||
fieldValues := args.fields[key]
|
||||
// do not filter if there is no filter set or cannot determine filter
|
||||
if len(fieldValues) == 0 {
|
||||
return true
|
||||
}
|
||||
if len(args.fields[key]) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
// try to match full name value to avoid O(N) regular expression matching
|
||||
return fieldValues[source]
|
||||
}
|
||||
|
||||
// FuzzyMatch returns true if the source matches exactly one value, or the
|
||||
// source has one of the values as a prefix.
|
||||
func (args Args) FuzzyMatch(key, source string) bool {
|
||||
if args.ExactMatch(key, source) {
|
||||
return true
|
||||
}
|
||||
|
||||
fieldValues := args.fields[key]
|
||||
for prefix := range fieldValues {
|
||||
if strings.HasPrefix(source, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Contains returns true if the key exists in the mapping
|
||||
func (args Args) Contains(field string) bool {
|
||||
_, ok := args.fields[field]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Validate compared the set of accepted keys against the keys in the mapping.
|
||||
// An error is returned if any mapping keys are not in the accepted set.
|
||||
func (args Args) Validate(accepted map[string]bool) error {
|
||||
for name := range args.fields {
|
||||
if !accepted[name] {
|
||||
return &invalidFilter{name, nil}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WalkValues iterates over the list of values for a key in the mapping and calls
|
||||
// op() for each value. If op returns an error the iteration stops and the
|
||||
// error is returned.
|
||||
func (args Args) WalkValues(field string, op func(value string) error) error {
|
||||
if _, ok := args.fields[field]; !ok {
|
||||
return nil
|
||||
}
|
||||
for v := range args.fields[field] {
|
||||
if err := op(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clone returns a copy of args.
|
||||
func (args Args) Clone() (newArgs Args) {
|
||||
newArgs.fields = make(map[string]map[string]bool, len(args.fields))
|
||||
for k, m := range args.fields {
|
||||
var mm map[string]bool
|
||||
if m != nil {
|
||||
mm = make(map[string]bool, len(m))
|
||||
for kk, v := range m {
|
||||
mm[kk] = v
|
||||
}
|
||||
}
|
||||
newArgs.fields[k] = mm
|
||||
}
|
||||
return newArgs
|
||||
}
|
||||
|
||||
func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
|
||||
m := map[string]map[string]bool{}
|
||||
for k, v := range d {
|
||||
values := map[string]bool{}
|
||||
for _, vv := range v {
|
||||
values[vv] = true
|
||||
}
|
||||
m[k] = values
|
||||
}
|
||||
return m
|
||||
}
|
||||
42
vendor/github.com/moby/moby/api/types/image/image_inspect.go
generated
vendored
42
vendor/github.com/moby/moby/api/types/image/image_inspect.go
generated
vendored
@ -2,7 +2,6 @@ package image
|
||||
|
||||
import (
|
||||
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/storage"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
@ -43,16 +42,9 @@ type InspectResponse struct {
|
||||
// the manifest is generated and its digest calculated.
|
||||
RepoDigests []string
|
||||
|
||||
// Parent is the ID of the parent image.
|
||||
//
|
||||
// Depending on how the image was created, this field may be empty and
|
||||
// is only set for images that were built/created locally. This field
|
||||
// is empty if the image was pulled from an image registry.
|
||||
Parent string
|
||||
|
||||
// Comment is an optional message that can be set when committing or
|
||||
// importing the image.
|
||||
Comment string
|
||||
// importing the image. This field is omitted if not set.
|
||||
Comment string `json:",omitempty"`
|
||||
|
||||
// Created is the date and time at which the image was created, formatted in
|
||||
// RFC 3339 nano-seconds (time.RFC3339Nano).
|
||||
@ -61,30 +53,10 @@ type InspectResponse struct {
|
||||
// and omitted otherwise.
|
||||
Created string `json:",omitempty"`
|
||||
|
||||
// Container is the ID of the container that was used to create the image.
|
||||
//
|
||||
// Depending on how the image was created, this field may be empty.
|
||||
//
|
||||
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
|
||||
Container string `json:",omitempty"`
|
||||
|
||||
// ContainerConfig is an optional field containing the configuration of the
|
||||
// container that was last committed when creating the image.
|
||||
//
|
||||
// Previous versions of Docker builder used this field to store build cache,
|
||||
// and it is not in active use anymore.
|
||||
//
|
||||
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
|
||||
ContainerConfig *container.Config `json:",omitempty"`
|
||||
|
||||
// DockerVersion is the version of Docker that was used to build the image.
|
||||
//
|
||||
// Depending on how the image was created, this field may be empty.
|
||||
DockerVersion string
|
||||
|
||||
// Author is the name of the author that was specified when committing the
|
||||
// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.
|
||||
Author string
|
||||
// This field is omitted if not set.
|
||||
Author string `json:",omitempty"`
|
||||
Config *dockerspec.DockerOCIImageConfig
|
||||
|
||||
// Architecture is the hardware CPU architecture that the image runs on.
|
||||
@ -103,12 +75,6 @@ type InspectResponse struct {
|
||||
// Size is the total size of the image including all layers it is composed of.
|
||||
Size int64
|
||||
|
||||
// VirtualSize is the total size of the image including all layers it is
|
||||
// composed of.
|
||||
//
|
||||
// Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.
|
||||
VirtualSize int64 `json:"VirtualSize,omitempty"`
|
||||
|
||||
// GraphDriver holds information about the storage driver used to store the
|
||||
// container's and image's filesystem.
|
||||
GraphDriver *storage.DriverData `json:"GraphDriver,omitempty"`
|
||||
|
||||
91
vendor/github.com/moby/moby/api/types/network/endpoint.go
generated
vendored
91
vendor/github.com/moby/moby/api/types/network/endpoint.go
generated
vendored
@ -1,10 +1,8 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net"
|
||||
"net/netip"
|
||||
"slices"
|
||||
)
|
||||
|
||||
@ -28,11 +26,11 @@ type EndpointSettings struct {
|
||||
// Operational data
|
||||
NetworkID string
|
||||
EndpointID string
|
||||
Gateway string
|
||||
IPAddress string
|
||||
Gateway netip.Addr
|
||||
IPAddress netip.Addr
|
||||
IPPrefixLen int
|
||||
IPv6Gateway string
|
||||
GlobalIPv6Address string
|
||||
IPv6Gateway netip.Addr
|
||||
GlobalIPv6Address netip.Addr
|
||||
GlobalIPv6PrefixLen int
|
||||
// DNSNames holds all the (non fully qualified) DNS names associated to this endpoint. First entry is used to
|
||||
// generate PTR records.
|
||||
@ -57,9 +55,9 @@ func (es *EndpointSettings) Copy() *EndpointSettings {
|
||||
|
||||
// EndpointIPAMConfig represents IPAM configurations for the endpoint
|
||||
type EndpointIPAMConfig struct {
|
||||
IPv4Address string `json:",omitempty"`
|
||||
IPv6Address string `json:",omitempty"`
|
||||
LinkLocalIPs []string `json:",omitempty"`
|
||||
IPv4Address netip.Addr `json:",omitempty"`
|
||||
IPv6Address netip.Addr `json:",omitempty"`
|
||||
LinkLocalIPs []netip.Addr `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Copy makes a copy of the endpoint ipam config
|
||||
@ -71,76 +69,3 @@ func (cfg *EndpointIPAMConfig) Copy() *EndpointIPAMConfig {
|
||||
cfgCopy.LinkLocalIPs = slices.Clone(cfg.LinkLocalIPs)
|
||||
return &cfgCopy
|
||||
}
|
||||
|
||||
// NetworkSubnet describes a user-defined subnet for a specific network. It's only used to validate if an
|
||||
// EndpointIPAMConfig is valid for a specific network.
|
||||
type NetworkSubnet interface {
|
||||
// Contains checks whether the NetworkSubnet contains [addr].
|
||||
Contains(addr net.IP) bool
|
||||
// IsStatic checks whether the subnet was statically allocated (ie. user-defined).
|
||||
IsStatic() bool
|
||||
}
|
||||
|
||||
// IsInRange checks whether static IP addresses are valid in a specific network.
|
||||
func (cfg *EndpointIPAMConfig) IsInRange(v4Subnets []NetworkSubnet, v6Subnets []NetworkSubnet) error {
|
||||
var errs []error
|
||||
|
||||
if err := validateEndpointIPAddress(cfg.IPv4Address, v4Subnets); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
if err := validateEndpointIPAddress(cfg.IPv6Address, v6Subnets); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
return errJoin(errs...)
|
||||
}
|
||||
|
||||
func validateEndpointIPAddress(epAddr string, ipamSubnets []NetworkSubnet) error {
|
||||
if epAddr == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var staticSubnet bool
|
||||
parsedAddr := net.ParseIP(epAddr)
|
||||
for _, subnet := range ipamSubnets {
|
||||
if subnet.IsStatic() {
|
||||
staticSubnet = true
|
||||
if subnet.Contains(parsedAddr) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if staticSubnet {
|
||||
return fmt.Errorf("no configured subnet or ip-range contain the IP address %s", epAddr)
|
||||
}
|
||||
|
||||
return errors.New("user specified IP address is supported only when connecting to networks with user configured subnets")
|
||||
}
|
||||
|
||||
// Validate checks whether cfg is valid.
|
||||
func (cfg *EndpointIPAMConfig) Validate() error {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errs []error
|
||||
|
||||
if cfg.IPv4Address != "" {
|
||||
if addr := net.ParseIP(cfg.IPv4Address); addr == nil || addr.To4() == nil || addr.IsUnspecified() {
|
||||
errs = append(errs, fmt.Errorf("invalid IPv4 address: %s", cfg.IPv4Address))
|
||||
}
|
||||
}
|
||||
if cfg.IPv6Address != "" {
|
||||
if addr := net.ParseIP(cfg.IPv6Address); addr == nil || addr.To4() != nil || addr.IsUnspecified() {
|
||||
errs = append(errs, fmt.Errorf("invalid IPv6 address: %s", cfg.IPv6Address))
|
||||
}
|
||||
}
|
||||
for _, addr := range cfg.LinkLocalIPs {
|
||||
if parsed := net.ParseIP(addr); parsed == nil || parsed.IsUnspecified() {
|
||||
errs = append(errs, fmt.Errorf("invalid link-local IP address: %s", addr))
|
||||
}
|
||||
}
|
||||
|
||||
return errJoin(errs...)
|
||||
}
|
||||
|
||||
8
vendor/github.com/moby/moby/api/types/network/endpoint_resource.go
generated
vendored
8
vendor/github.com/moby/moby/api/types/network/endpoint_resource.go
generated
vendored
@ -5,6 +5,10 @@ package network
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// EndpointResource contains network resources allocated and used for a container in a network.
|
||||
//
|
||||
// swagger:model EndpointResource
|
||||
@ -24,8 +28,8 @@ type EndpointResource struct {
|
||||
|
||||
// IPv4 address
|
||||
// Example: 172.19.0.2/16
|
||||
IPv4Address string `json:"IPv4Address"`
|
||||
IPv4Address netip.Prefix `json:"IPv4Address"`
|
||||
|
||||
// IPv6 address
|
||||
IPv6Address string `json:"IPv6Address"`
|
||||
IPv6Address netip.Prefix `json:"IPv6Address"`
|
||||
}
|
||||
|
||||
161
vendor/github.com/moby/moby/api/types/network/ipam.go
generated
vendored
161
vendor/github.com/moby/moby/api/types/network/ipam.go
generated
vendored
@ -1,10 +1,7 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPAM represents IP Address Management
|
||||
@ -16,160 +13,10 @@ type IPAM struct {
|
||||
|
||||
// IPAMConfig represents IPAM configurations
|
||||
type IPAMConfig struct {
|
||||
Subnet string `json:",omitempty"`
|
||||
IPRange string `json:",omitempty"`
|
||||
Gateway string `json:",omitempty"`
|
||||
AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
|
||||
Subnet netip.Prefix `json:",omitempty"`
|
||||
IPRange netip.Prefix `json:",omitempty"`
|
||||
Gateway netip.Addr `json:",omitempty"`
|
||||
AuxAddress map[string]netip.Addr `json:"AuxiliaryAddresses,omitempty"`
|
||||
}
|
||||
|
||||
type SubnetStatuses = map[netip.Prefix]SubnetStatus
|
||||
|
||||
type ipFamily string
|
||||
|
||||
const (
|
||||
ip4 ipFamily = "IPv4"
|
||||
ip6 ipFamily = "IPv6"
|
||||
)
|
||||
|
||||
// ValidateIPAM checks whether the network's IPAM passed as argument is valid. It returns a joinError of the list of
|
||||
// errors found.
|
||||
func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error {
|
||||
if ipam == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errs []error
|
||||
for _, cfg := range ipam.Config {
|
||||
subnet, err := netip.ParsePrefix(cfg.Subnet)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("invalid subnet %s: invalid CIDR block notation", cfg.Subnet))
|
||||
continue
|
||||
}
|
||||
subnetFamily := ip4
|
||||
if subnet.Addr().Is6() {
|
||||
subnetFamily = ip6
|
||||
}
|
||||
|
||||
if !enableIPv6 && subnetFamily == ip6 {
|
||||
continue
|
||||
}
|
||||
|
||||
if subnet != subnet.Masked() {
|
||||
errs = append(errs, fmt.Errorf("invalid subnet %s: it should be %s", subnet, subnet.Masked()))
|
||||
}
|
||||
|
||||
if ipRangeErrs := validateIPRange(cfg.IPRange, subnet, subnetFamily); len(ipRangeErrs) > 0 {
|
||||
errs = append(errs, ipRangeErrs...)
|
||||
}
|
||||
|
||||
if err := validateAddress(cfg.Gateway, subnet, subnetFamily); err != nil {
|
||||
errs = append(errs, fmt.Errorf("invalid gateway %s: %w", cfg.Gateway, err))
|
||||
}
|
||||
|
||||
for auxName, aux := range cfg.AuxAddress {
|
||||
if err := validateAddress(aux, subnet, subnetFamily); err != nil {
|
||||
errs = append(errs, fmt.Errorf("invalid auxiliary address %s: %w", auxName, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := errJoin(errs...); err != nil {
|
||||
return fmt.Errorf("invalid network config:\n%w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateIPRange(ipRange string, subnet netip.Prefix, subnetFamily ipFamily) []error {
|
||||
if ipRange == "" {
|
||||
return nil
|
||||
}
|
||||
prefix, err := netip.ParsePrefix(ipRange)
|
||||
if err != nil {
|
||||
return []error{fmt.Errorf("invalid ip-range %s: invalid CIDR block notation", ipRange)}
|
||||
}
|
||||
family := ip4
|
||||
if prefix.Addr().Is6() {
|
||||
family = ip6
|
||||
}
|
||||
|
||||
if family != subnetFamily {
|
||||
return []error{fmt.Errorf("invalid ip-range %s: parent subnet is an %s block", ipRange, subnetFamily)}
|
||||
}
|
||||
|
||||
var errs []error
|
||||
if prefix.Bits() < subnet.Bits() {
|
||||
errs = append(errs, fmt.Errorf("invalid ip-range %s: CIDR block is bigger than its parent subnet %s", ipRange, subnet))
|
||||
}
|
||||
if prefix != prefix.Masked() {
|
||||
errs = append(errs, fmt.Errorf("invalid ip-range %s: it should be %s", prefix, prefix.Masked()))
|
||||
}
|
||||
if !subnet.Overlaps(prefix) {
|
||||
errs = append(errs, fmt.Errorf("invalid ip-range %s: parent subnet %s doesn't contain ip-range", ipRange, subnet))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
func validateAddress(address string, subnet netip.Prefix, subnetFamily ipFamily) error {
|
||||
if address == "" {
|
||||
return nil
|
||||
}
|
||||
addr, err := netip.ParseAddr(address)
|
||||
if err != nil {
|
||||
return errors.New("invalid address")
|
||||
}
|
||||
family := ip4
|
||||
if addr.Is6() {
|
||||
family = ip6
|
||||
}
|
||||
|
||||
if family != subnetFamily {
|
||||
return fmt.Errorf("parent subnet is an %s block", subnetFamily)
|
||||
}
|
||||
if !subnet.Contains(addr) {
|
||||
return fmt.Errorf("parent subnet %s doesn't contain this address", subnet)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
8
vendor/github.com/moby/moby/api/types/network/network_types.go
generated
vendored
8
vendor/github.com/moby/moby/api/types/network/network_types.go
generated
vendored
@ -30,14 +30,6 @@ type CreateRequest struct {
|
||||
Labels map[string]string // Labels holds metadata specific to the network being created.
|
||||
}
|
||||
|
||||
// ServiceInfo represents service parameters with the list of service's tasks
|
||||
type ServiceInfo struct {
|
||||
VIP string
|
||||
Ports []string
|
||||
LocalLBIndex int
|
||||
Tasks []Task
|
||||
}
|
||||
|
||||
// NetworkingConfig represents the container's networking configuration for each of its interfaces
|
||||
// Carries the networking configs specified in the `docker run` and `docker network connect` commands
|
||||
type NetworkingConfig struct {
|
||||
|
||||
6
vendor/github.com/moby/moby/api/types/network/peer_info.go
generated
vendored
6
vendor/github.com/moby/moby/api/types/network/peer_info.go
generated
vendored
@ -5,6 +5,10 @@ package network
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// PeerInfo represents one peer of an overlay network.
|
||||
//
|
||||
// swagger:model PeerInfo
|
||||
@ -16,5 +20,5 @@ type PeerInfo struct {
|
||||
|
||||
// IP-address of the peer-node in the Swarm cluster.
|
||||
// Example: 10.133.77.91
|
||||
IP string `json:"IP"`
|
||||
IP netip.Addr `json:"IP"`
|
||||
}
|
||||
|
||||
346
vendor/github.com/moby/moby/api/types/network/port.go
generated
vendored
Normal file
346
vendor/github.com/moby/moby/api/types/network/port.go
generated
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"iter"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unique"
|
||||
)
|
||||
|
||||
// IPProtocol represents a network protocol for a port.
|
||||
type IPProtocol string
|
||||
|
||||
const (
|
||||
TCP IPProtocol = "tcp"
|
||||
UDP IPProtocol = "udp"
|
||||
SCTP IPProtocol = "sctp"
|
||||
)
|
||||
|
||||
// Sentinel port proto value for zero Port and PortRange values.
|
||||
var protoZero unique.Handle[IPProtocol]
|
||||
|
||||
// Port is a type representing a single port number and protocol in the format "<portnum>/[<proto>]".
|
||||
//
|
||||
// The zero port value, i.e. Port{}, is invalid; use [ParsePort] to create a valid Port value.
|
||||
type Port struct {
|
||||
num uint16
|
||||
proto unique.Handle[IPProtocol]
|
||||
}
|
||||
|
||||
// ParsePort parses s as a [Port].
|
||||
//
|
||||
// It normalizes the provided protocol such that "80/tcp", "80/TCP", and "80/tCp" are equivalent.
|
||||
// If a port number is provided, but no protocol, the default ("tcp") protocol is returned.
|
||||
func ParsePort(s string) (Port, error) {
|
||||
if s == "" {
|
||||
return Port{}, errors.New("invalid port: value is empty")
|
||||
}
|
||||
|
||||
port, proto, _ := strings.Cut(s, "/")
|
||||
|
||||
portNum, err := parsePortNumber(port)
|
||||
if err != nil {
|
||||
return Port{}, fmt.Errorf("invalid port '%s': %w", port, err)
|
||||
}
|
||||
|
||||
normalizedPortProto := normalizePortProto(proto)
|
||||
return Port{num: portNum, proto: normalizedPortProto}, nil
|
||||
}
|
||||
|
||||
// MustParsePort calls [ParsePort](s) and panics on error.
|
||||
//
|
||||
// It is intended for use in tests with hard-coded strings.
|
||||
func MustParsePort(s string) Port {
|
||||
p, err := ParsePort(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// PortFrom returns a [Port] with the given number and protocol.
|
||||
//
|
||||
// If no protocol is specified (i.e. proto == ""), then PortFrom returns Port{}, false.
|
||||
func PortFrom(num uint16, proto IPProtocol) (p Port, ok bool) {
|
||||
if proto == "" {
|
||||
return Port{}, false
|
||||
}
|
||||
normalized := normalizePortProto(string(proto))
|
||||
return Port{num: num, proto: normalized}, true
|
||||
}
|
||||
|
||||
// Num returns p's port number.
|
||||
func (p Port) Num() uint16 {
|
||||
return p.num
|
||||
}
|
||||
|
||||
// Proto returns p's network protocol.
|
||||
func (p Port) Proto() IPProtocol {
|
||||
return p.proto.Value()
|
||||
}
|
||||
|
||||
// IsZero reports whether p is the zero value.
|
||||
func (p Port) IsZero() bool {
|
||||
return p.proto == protoZero
|
||||
}
|
||||
|
||||
// IsValid reports whether p is an initialized valid port (not the zero value).
|
||||
func (p Port) IsValid() bool {
|
||||
return p.proto != protoZero
|
||||
}
|
||||
|
||||
// String returns a string representation of the port in the format "<portnum>/<proto>".
|
||||
// If the port is the zero value, it returns "invalid port".
|
||||
func (p Port) String() string {
|
||||
switch p.proto {
|
||||
case protoZero:
|
||||
return "invalid port"
|
||||
default:
|
||||
return string(p.AppendTo(nil))
|
||||
}
|
||||
}
|
||||
|
||||
// AppendText implements [encoding.TextAppender] interface.
|
||||
// It is the same as [Port.AppendTo] but returns an error to satisfy the interface.
|
||||
func (p Port) AppendText(b []byte) ([]byte, error) {
|
||||
return p.AppendTo(b), nil
|
||||
}
|
||||
|
||||
// AppendTo appends a text encoding of p to b and returns the extended buffer.
|
||||
func (p Port) AppendTo(b []byte) []byte {
|
||||
if p.IsZero() {
|
||||
return b
|
||||
}
|
||||
return fmt.Appendf(b, "%d/%s", p.num, p.proto.Value())
|
||||
}
|
||||
|
||||
// MarshalText implements [encoding.TextMarshaler] interface.
|
||||
func (p Port) MarshalText() ([]byte, error) {
|
||||
return p.AppendText(nil)
|
||||
}
|
||||
|
||||
// UnmarshalText implements [encoding.TextUnmarshaler] interface.
|
||||
func (p *Port) UnmarshalText(text []byte) error {
|
||||
if len(text) == 0 {
|
||||
*p = Port{}
|
||||
return nil
|
||||
}
|
||||
|
||||
port, err := ParsePort(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*p = port
|
||||
return nil
|
||||
}
|
||||
|
||||
// Range returns a [PortRange] representing the single port.
|
||||
func (p Port) Range() PortRange {
|
||||
return PortRange{start: p.num, end: p.num, proto: p.proto}
|
||||
}
|
||||
|
||||
// PortSet is a collection of structs indexed by [Port].
|
||||
type PortSet = map[Port]struct{}
|
||||
|
||||
// PortBinding represents a binding between a Host IP address and a Host Port.
|
||||
type PortBinding struct {
|
||||
// HostIP is the host IP Address
|
||||
HostIP netip.Addr `json:"HostIp"`
|
||||
// HostPort is the host port number
|
||||
HostPort string `json:"HostPort"`
|
||||
}
|
||||
|
||||
// PortMap is a collection of [PortBinding] indexed by [Port].
|
||||
type PortMap = map[Port][]PortBinding
|
||||
|
||||
// PortRange represents a range of port numbers and a protocol in the format "8000-9000/tcp".
|
||||
//
|
||||
// The zero port range value, i.e. PortRange{}, is invalid; use [ParsePortRange] to create a valid PortRange value.
|
||||
type PortRange struct {
|
||||
start uint16
|
||||
end uint16
|
||||
proto unique.Handle[IPProtocol]
|
||||
}
|
||||
|
||||
// ParsePortRange parses s as a [PortRange].
|
||||
//
|
||||
// It normalizes the provided protocol such that "80-90/tcp", "80-90/TCP", and "80-90/tCp" are equivalent.
|
||||
// If a port number range is provided, but no protocol, the default ("tcp") protocol is returned.
|
||||
func ParsePortRange(s string) (PortRange, error) {
|
||||
if s == "" {
|
||||
return PortRange{}, errors.New("invalid port range: value is empty")
|
||||
}
|
||||
|
||||
portRange, proto, _ := strings.Cut(s, "/")
|
||||
|
||||
start, end, ok := strings.Cut(portRange, "-")
|
||||
startVal, err := parsePortNumber(start)
|
||||
if err != nil {
|
||||
return PortRange{}, fmt.Errorf("invalid start port '%s': %w", start, err)
|
||||
}
|
||||
|
||||
portProto := normalizePortProto(proto)
|
||||
|
||||
if !ok || start == end {
|
||||
return PortRange{start: startVal, end: startVal, proto: portProto}, nil
|
||||
}
|
||||
|
||||
endVal, err := parsePortNumber(end)
|
||||
if err != nil {
|
||||
return PortRange{}, fmt.Errorf("invalid end port '%s': %w", end, err)
|
||||
}
|
||||
if endVal < startVal {
|
||||
return PortRange{}, errors.New("invalid port range: " + s)
|
||||
}
|
||||
return PortRange{start: startVal, end: endVal, proto: portProto}, nil
|
||||
}
|
||||
|
||||
// MustParsePortRange calls [ParsePortRange](s) and panics on error.
|
||||
// It is intended for use in tests with hard-coded strings.
|
||||
func MustParsePortRange(s string) PortRange {
|
||||
pr, err := ParsePortRange(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pr
|
||||
}
|
||||
|
||||
// PortRangeFrom returns a [PortRange] with the given start and end port numbers and protocol.
|
||||
//
|
||||
// If end < start or no protocol is specified (i.e. proto == ""), then PortRangeFrom returns PortRange{}, false.
|
||||
func PortRangeFrom(start, end uint16, proto IPProtocol) (pr PortRange, ok bool) {
|
||||
if end < start || proto == "" {
|
||||
return PortRange{}, false
|
||||
}
|
||||
normalized := normalizePortProto(string(proto))
|
||||
return PortRange{start: start, end: end, proto: normalized}, true
|
||||
}
|
||||
|
||||
// Start returns pr's start port number.
|
||||
func (pr PortRange) Start() uint16 {
|
||||
return pr.start
|
||||
}
|
||||
|
||||
// End returns pr's end port number.
|
||||
func (pr PortRange) End() uint16 {
|
||||
return pr.end
|
||||
}
|
||||
|
||||
// Proto returns pr's network protocol.
|
||||
func (pr PortRange) Proto() IPProtocol {
|
||||
return pr.proto.Value()
|
||||
}
|
||||
|
||||
// IsZero reports whether pr is the zero value.
|
||||
func (pr PortRange) IsZero() bool {
|
||||
return pr.proto == protoZero
|
||||
}
|
||||
|
||||
// IsValid reports whether pr is an initialized valid port range (not the zero value).
|
||||
func (pr PortRange) IsValid() bool {
|
||||
return pr.proto != protoZero
|
||||
}
|
||||
|
||||
// String returns a string representation of the port range in the format "<start>-<end>/<proto>" or "<portnum>/<proto>" if start == end.
|
||||
// If the port range is the zero value, it returns "invalid port range".
|
||||
func (pr PortRange) String() string {
|
||||
switch pr.proto {
|
||||
case protoZero:
|
||||
return "invalid port range"
|
||||
default:
|
||||
return string(pr.AppendTo(nil))
|
||||
}
|
||||
}
|
||||
|
||||
// AppendText implements [encoding.TextAppender] interface.
|
||||
// It is the same as [PortRange.AppendTo] but returns an error to satisfy the interface.
|
||||
func (pr PortRange) AppendText(b []byte) ([]byte, error) {
|
||||
return pr.AppendTo(b), nil
|
||||
}
|
||||
|
||||
// AppendTo appends a text encoding of pr to b and returns the extended buffer.
|
||||
func (pr PortRange) AppendTo(b []byte) []byte {
|
||||
if pr.IsZero() {
|
||||
return b
|
||||
}
|
||||
if pr.start == pr.end {
|
||||
return fmt.Appendf(b, "%d/%s", pr.start, pr.proto.Value())
|
||||
}
|
||||
return fmt.Appendf(b, "%d-%d/%s", pr.start, pr.end, pr.proto.Value())
|
||||
}
|
||||
|
||||
// MarshalText implements [encoding.TextMarshaler] interface.
|
||||
func (pr PortRange) MarshalText() ([]byte, error) {
|
||||
return pr.AppendText(nil)
|
||||
}
|
||||
|
||||
// UnmarshalText implements [encoding.TextUnmarshaler] interface.
|
||||
func (pr *PortRange) UnmarshalText(text []byte) error {
|
||||
if len(text) == 0 {
|
||||
*pr = PortRange{}
|
||||
return nil
|
||||
}
|
||||
|
||||
portRange, err := ParsePortRange(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*pr = portRange
|
||||
return nil
|
||||
}
|
||||
|
||||
// Range returns pr.
|
||||
func (pr PortRange) Range() PortRange {
|
||||
return pr
|
||||
}
|
||||
|
||||
// All returns an iterator over all the individual ports in the range.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// for port := range pr.All() {
|
||||
// // ...
|
||||
// }
|
||||
func (pr PortRange) All() iter.Seq[Port] {
|
||||
return func(yield func(Port) bool) {
|
||||
for i := uint32(pr.Start()); i <= uint32(pr.End()); i++ {
|
||||
if !yield(Port{num: uint16(i), proto: pr.proto}) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parsePortNumber parses rawPort into an int, unwrapping strconv errors
|
||||
// and returning a single "out of range" error for any value outside 0–65535.
|
||||
func parsePortNumber(rawPort string) (uint16, error) {
|
||||
if rawPort == "" {
|
||||
return 0, errors.New("value is empty")
|
||||
}
|
||||
port, err := strconv.ParseUint(rawPort, 10, 16)
|
||||
if err != nil {
|
||||
var numErr *strconv.NumError
|
||||
if errors.As(err, &numErr) {
|
||||
err = numErr.Err
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return uint16(port), nil
|
||||
}
|
||||
|
||||
// normalizePortProto normalizes the protocol string such that "tcp", "TCP", and "tCp" are equivalent.
|
||||
// If proto is not specified, it defaults to "tcp".
|
||||
func normalizePortProto(proto string) unique.Handle[IPProtocol] {
|
||||
if proto == "" {
|
||||
return unique.Make(TCP)
|
||||
}
|
||||
|
||||
proto = strings.ToLower(proto)
|
||||
|
||||
return unique.Make(IPProtocol(proto))
|
||||
}
|
||||
28
vendor/github.com/moby/moby/api/types/network/service_info.go
generated
vendored
Normal file
28
vendor/github.com/moby/moby/api/types/network/service_info.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package network
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// ServiceInfo represents service parameters with the list of service's tasks
|
||||
//
|
||||
// swagger:model ServiceInfo
|
||||
type ServiceInfo struct {
|
||||
|
||||
// v IP
|
||||
VIP netip.Addr `json:"VIP"`
|
||||
|
||||
// ports
|
||||
Ports []string `json:"Ports"`
|
||||
|
||||
// local l b index
|
||||
LocalLBIndex int `json:"LocalLBIndex"`
|
||||
|
||||
// tasks
|
||||
Tasks []Task `json:"Tasks"`
|
||||
}
|
||||
6
vendor/github.com/moby/moby/api/types/network/task.go
generated
vendored
6
vendor/github.com/moby/moby/api/types/network/task.go
generated
vendored
@ -5,6 +5,10 @@ package network
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// Task carries the information about one backend task
|
||||
//
|
||||
// swagger:model Task
|
||||
@ -17,7 +21,7 @@ type Task struct {
|
||||
EndpointID string `json:"EndpointID"`
|
||||
|
||||
// endpoint IP
|
||||
EndpointIP string `json:"EndpointIP"`
|
||||
EndpointIP netip.Addr `json:"EndpointIP"`
|
||||
|
||||
// info
|
||||
Info map[string]string `json:"Info"`
|
||||
|
||||
7
vendor/github.com/moby/moby/api/types/plugin/plugin.go
generated
vendored
7
vendor/github.com/moby/moby/api/types/plugin/plugin.go
generated
vendored
@ -51,8 +51,11 @@ type Config struct {
|
||||
// Required: true
|
||||
Description string `json:"Description"`
|
||||
|
||||
// Docker Version used to create the plugin
|
||||
// Example: 17.06.0-ce
|
||||
// Docker Version used to create the plugin.
|
||||
//
|
||||
// Depending on how the plugin was created, this field may be empty or omitted.
|
||||
//
|
||||
// Deprecated: this field is no longer set, and will be removed in the next API version.
|
||||
DockerVersion string `json:"DockerVersion,omitempty"`
|
||||
|
||||
// documentation
|
||||
|
||||
36
vendor/github.com/moby/moby/api/types/registry/registry.go
generated
vendored
36
vendor/github.com/moby/moby/api/types/registry/registry.go
generated
vendored
@ -1,48 +1,16 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ServiceConfig stores daemon registry services configuration.
|
||||
type ServiceConfig struct {
|
||||
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
|
||||
InsecureRegistryCIDRs []netip.Prefix `json:"InsecureRegistryCIDRs"`
|
||||
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
|
||||
Mirrors []string
|
||||
|
||||
// ExtraFields is for internal use to include deprecated fields on older API versions.
|
||||
ExtraFields map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// NetIPNet is the net.IPNet type, which can be marshalled and
|
||||
// unmarshalled to JSON
|
||||
type NetIPNet net.IPNet
|
||||
|
||||
// String returns the CIDR notation of ipnet
|
||||
func (ipnet *NetIPNet) String() string {
|
||||
return (*net.IPNet)(ipnet).String()
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON representation of the IPNet
|
||||
func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal((*net.IPNet)(ipnet).String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets the IPNet from a byte array of JSON
|
||||
func (ipnet *NetIPNet) UnmarshalJSON(b []byte) error {
|
||||
var ipnetStr string
|
||||
if err := json.Unmarshal(b, &ipnetStr); err != nil {
|
||||
return err
|
||||
}
|
||||
_, cidr, err := net.ParseCIDR(ipnetStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*ipnet = NetIPNet(*cidr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IndexInfo contains information about a registry
|
||||
|
||||
3
vendor/github.com/moby/moby/api/types/swarm/container.go
generated
vendored
3
vendor/github.com/moby/moby/api/types/swarm/container.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
// TODO: `domain` is not supported yet.
|
||||
type DNSConfig struct {
|
||||
// Nameservers specifies the IP addresses of the name servers
|
||||
Nameservers []string `json:",omitempty"`
|
||||
Nameservers []netip.Addr `json:",omitempty"`
|
||||
// Search specifies the search list for host-name lookup
|
||||
Search []string `json:",omitempty"`
|
||||
// Options allows certain internal resolver variables to be modified
|
||||
|
||||
38
vendor/github.com/moby/moby/api/types/swarm/network.go
generated
vendored
38
vendor/github.com/moby/moby/api/types/swarm/network.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/moby/moby/api/types/network"
|
||||
)
|
||||
|
||||
@ -30,7 +32,7 @@ const (
|
||||
// PortConfig represents the config of a port.
|
||||
type PortConfig struct {
|
||||
Name string `json:",omitempty"`
|
||||
Protocol PortConfigProtocol `json:",omitempty"`
|
||||
Protocol network.IPProtocol `json:",omitempty"`
|
||||
// TargetPort is the port inside the container
|
||||
TargetPort uint32 `json:",omitempty"`
|
||||
// PublishedPort is the port on the swarm hosts
|
||||
@ -52,24 +54,14 @@ const (
|
||||
PortConfigPublishModeHost PortConfigPublishMode = "host"
|
||||
)
|
||||
|
||||
// PortConfigProtocol represents the protocol of a port.
|
||||
type PortConfigProtocol string
|
||||
|
||||
const (
|
||||
// TODO(stevvooe): These should be used generally, not just for PortConfig.
|
||||
|
||||
// PortConfigProtocolTCP TCP
|
||||
PortConfigProtocolTCP PortConfigProtocol = "tcp"
|
||||
// PortConfigProtocolUDP UDP
|
||||
PortConfigProtocolUDP PortConfigProtocol = "udp"
|
||||
// PortConfigProtocolSCTP SCTP
|
||||
PortConfigProtocolSCTP PortConfigProtocol = "sctp"
|
||||
)
|
||||
|
||||
// EndpointVirtualIP represents the virtual ip of a port.
|
||||
type EndpointVirtualIP struct {
|
||||
NetworkID string `json:",omitempty"`
|
||||
Addr string `json:",omitempty"`
|
||||
|
||||
// Addr is the virtual ip address.
|
||||
// This field accepts CIDR notation, for example `10.0.0.1/24`, to maintain backwards
|
||||
// compatibility, but only the IP address is used.
|
||||
Addr netip.Prefix `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Network represents a network.
|
||||
@ -103,8 +95,12 @@ type NetworkAttachmentConfig struct {
|
||||
|
||||
// NetworkAttachment represents a network attachment.
|
||||
type NetworkAttachment struct {
|
||||
Network Network `json:",omitempty"`
|
||||
Addresses []string `json:",omitempty"`
|
||||
Network Network `json:",omitempty"`
|
||||
|
||||
// Addresses contains the IP addresses associated with the endpoint in the network.
|
||||
// This field accepts CIDR notation, for example `10.0.0.1/24`, to maintain backwards
|
||||
// compatibility, but only the IP address is used.
|
||||
Addresses []netip.Prefix `json:",omitempty"`
|
||||
}
|
||||
|
||||
// IPAMOptions represents ipam options.
|
||||
@ -115,7 +111,7 @@ type IPAMOptions struct {
|
||||
|
||||
// IPAMConfig represents ipam configuration.
|
||||
type IPAMConfig struct {
|
||||
Subnet string `json:",omitempty"`
|
||||
Range string `json:",omitempty"`
|
||||
Gateway string `json:",omitempty"`
|
||||
Subnet netip.Prefix `json:",omitempty"`
|
||||
Range netip.Prefix `json:",omitempty"`
|
||||
Gateway netip.Addr `json:",omitempty"`
|
||||
}
|
||||
|
||||
5
vendor/github.com/moby/moby/api/types/swarm/swarm.go
generated
vendored
5
vendor/github.com/moby/moby/api/types/swarm/swarm.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package swarm
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -12,7 +13,7 @@ type ClusterInfo struct {
|
||||
Spec Spec
|
||||
TLSInfo TLSInfo
|
||||
RootRotationInProgress bool
|
||||
DefaultAddrPool []string
|
||||
DefaultAddrPool []netip.Prefix
|
||||
SubnetSize uint32
|
||||
DataPathPort uint32
|
||||
}
|
||||
@ -159,7 +160,7 @@ type InitRequest struct {
|
||||
Spec Spec
|
||||
AutoLockManagers bool
|
||||
Availability NodeAvailability
|
||||
DefaultAddrPool []string
|
||||
DefaultAddrPool []netip.Prefix
|
||||
SubnetSize uint32
|
||||
}
|
||||
|
||||
|
||||
9
vendor/github.com/moby/moby/api/types/system/info.go
generated
vendored
9
vendor/github.com/moby/moby/api/types/system/info.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
@ -137,16 +139,11 @@ type PluginsInfo struct {
|
||||
type Commit struct {
|
||||
// ID is the actual commit ID or version of external tool.
|
||||
ID string
|
||||
|
||||
// Expected is the commit ID of external tool expected by dockerd as set at build time.
|
||||
//
|
||||
// Deprecated: this field is no longer used in API v1.49, but kept for backward-compatibility with older API versions.
|
||||
Expected string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// NetworkAddressPool is a temp struct used by [Info] struct.
|
||||
type NetworkAddressPool struct {
|
||||
Base string
|
||||
Base netip.Prefix
|
||||
Size int
|
||||
}
|
||||
|
||||
|
||||
9
vendor/github.com/moby/moby/api/types/types.go
generated
vendored
9
vendor/github.com/moby/moby/api/types/types.go
generated
vendored
@ -11,6 +11,15 @@ const (
|
||||
|
||||
// MediaTypeMultiplexedStream is vendor specific MIME-Type set for stdin/stdout/stderr multiplexed streams
|
||||
MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream"
|
||||
|
||||
// MediaTypeJSON is the MIME-Type for JSON objects
|
||||
MediaTypeJSON = "application/json"
|
||||
|
||||
// MediaTypeNDJson is the MIME-Type for Newline Delimited JSON objects streams
|
||||
MediaTypeNDJSON = "application/x-ndjson"
|
||||
|
||||
// MediaTypeJsonSequence is the MIME-Type for JSON Text Sequences (RFC7464)
|
||||
MediaTypeJSONSequence = "application/json-seq"
|
||||
)
|
||||
|
||||
// Ping contains response of Engine API:
|
||||
|
||||
4
vendor/github.com/moby/moby/client/build_cancel.go
generated
vendored
4
vendor/github.com/moby/moby/client/build_cancel.go
generated
vendored
@ -5,9 +5,11 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type BuildCancelOptions struct{}
|
||||
|
||||
// BuildCancel requests the daemon to cancel the ongoing build request
|
||||
// with the given id.
|
||||
func (cli *Client) BuildCancel(ctx context.Context, id string) error {
|
||||
func (cli *Client) BuildCancel(ctx context.Context, id string, _ BuildCancelOptions) error {
|
||||
query := url.Values{}
|
||||
query.Set("id", id)
|
||||
|
||||
|
||||
24
vendor/github.com/moby/moby/client/build_prune.go
generated
vendored
24
vendor/github.com/moby/moby/client/build_prune.go
generated
vendored
@ -8,7 +8,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
@ -18,11 +17,17 @@ type BuildCachePruneOptions struct {
|
||||
ReservedSpace int64
|
||||
MaxUsedSpace int64
|
||||
MinFreeSpace int64
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
// BuildCachePruneResult holds the result from the BuildCachePrune method.
|
||||
type BuildCachePruneResult struct {
|
||||
Report build.CachePruneReport
|
||||
}
|
||||
|
||||
// BuildCachePrune requests the daemon to delete unused cache data.
|
||||
func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) {
|
||||
func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (BuildCachePruneResult, error) {
|
||||
var out BuildCachePruneResult
|
||||
query := url.Values{}
|
||||
if opts.All {
|
||||
query.Set("all", "1")
|
||||
@ -43,23 +48,20 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOpti
|
||||
if opts.MinFreeSpace != 0 {
|
||||
query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace)))
|
||||
}
|
||||
f, err := filters.ToJSON(opts.Filters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("prune could not marshal filters option: %w", err)
|
||||
}
|
||||
query.Set("filters", f)
|
||||
opts.Filters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.post(ctx, "/build/prune", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return BuildCachePruneResult{}, err
|
||||
}
|
||||
|
||||
report := build.CachePruneReport{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&report); err != nil {
|
||||
return nil, fmt.Errorf("error retrieving disk usage: %w", err)
|
||||
return BuildCachePruneResult{}, fmt.Errorf("error retrieving disk usage: %w", err)
|
||||
}
|
||||
|
||||
return &report, nil
|
||||
out.Report = report
|
||||
return out, nil
|
||||
}
|
||||
|
||||
42
vendor/github.com/moby/moby/client/client.go
generated
vendored
42
vendor/github.com/moby/moby/client/client.go
generated
vendored
@ -54,6 +54,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
@ -99,12 +100,10 @@ const DummyHost = "api.moby.localhost"
|
||||
// This version may be lower than the version of the api library module used.
|
||||
const MaxAPIVersion = "1.52"
|
||||
|
||||
// fallbackAPIVersion is the version to fallback to if API-version negotiation
|
||||
// fails. This version is the highest version of the API before API-version
|
||||
// negotiation was introduced. If negotiation fails (or no API version was
|
||||
// included in the API response), we assume the API server uses the most
|
||||
// recent version before negotiation was introduced.
|
||||
const fallbackAPIVersion = "1.24"
|
||||
// fallbackAPIVersion is the version to fall back to if API-version negotiation
|
||||
// fails. API versions below this version are not supported by the client,
|
||||
// and not considered when negotiating.
|
||||
const fallbackAPIVersion = "1.44"
|
||||
|
||||
// Ensure that Client always implements APIClient.
|
||||
var _ APIClient = &Client{}
|
||||
@ -275,7 +274,7 @@ func (cli *Client) checkVersion(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli.negotiateAPIVersionPing(ping.APIVersion)
|
||||
return cli.negotiateAPIVersion(ping.APIVersion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -311,8 +310,7 @@ func (cli *Client) ClientVersion() string {
|
||||
// If the API server's ping response does not contain an API version, or if the
|
||||
// client did not get a successful ping response, it assumes it is connected with
|
||||
// an old daemon that does not support API version negotiation, in which case it
|
||||
// downgrades to the latest version of the API before version negotiation was
|
||||
// added (1.24).
|
||||
// downgrades to the lowest supported API version.
|
||||
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
if !cli.manualOverride {
|
||||
// Avoid concurrent modification of version-related fields
|
||||
@ -324,7 +322,8 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
|
||||
return
|
||||
}
|
||||
cli.negotiateAPIVersionPing(ping.APIVersion)
|
||||
// FIXME(thaJeztah): we should not swallow the error here, and instead returning it.
|
||||
_ = cli.negotiateAPIVersion(ping.APIVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,28 +336,30 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized
|
||||
// with a fixed version ([WithVersion]), no negotiation is performed.
|
||||
//
|
||||
// If the API server's ping response does not contain an API version, we assume
|
||||
// we are connected with an old daemon without API version negotiation support,
|
||||
// and downgrade to the latest version of the API before version negotiation was
|
||||
// added (1.24).
|
||||
// If the API server's ping response does not contain an API version, it falls
|
||||
// back to the oldest API version supported.
|
||||
func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
|
||||
if !cli.manualOverride {
|
||||
// Avoid concurrent modification of version-related fields
|
||||
cli.negotiateLock.Lock()
|
||||
defer cli.negotiateLock.Unlock()
|
||||
|
||||
cli.negotiateAPIVersionPing(pingResponse.APIVersion)
|
||||
// FIXME(thaJeztah): we should not swallow the error here, and instead returning it.
|
||||
_ = cli.negotiateAPIVersion(pingResponse.APIVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// negotiateAPIVersionPing queries the API and updates the version to match the
|
||||
// API version from the ping response.
|
||||
func (cli *Client) negotiateAPIVersionPing(pingVersion string) {
|
||||
// negotiateAPIVersion updates the version to match the API version from
|
||||
// the ping response. It falls back to the lowest version supported if the
|
||||
// API version is empty, or returns an error if the API version is lower than
|
||||
// the lowest supported API version, in which case the version is not modified.
|
||||
func (cli *Client) negotiateAPIVersion(pingVersion string) error {
|
||||
pingVersion = strings.TrimPrefix(pingVersion, "v")
|
||||
|
||||
// default to the latest version before versioning headers existed
|
||||
if pingVersion == "" {
|
||||
// TODO(thaJeztah): consider returning an error on empty value or not falling back; see https://github.com/moby/moby/pull/51119#discussion_r2413148487
|
||||
pingVersion = fallbackAPIVersion
|
||||
} else if versions.LessThan(pingVersion, fallbackAPIVersion) {
|
||||
return cerrdefs.ErrInvalidArgument.WithMessage(fmt.Sprintf("API version %s is not supported by this client: the minimum supported API version is %s", pingVersion, fallbackAPIVersion))
|
||||
}
|
||||
|
||||
// if the client is not initialized with a version, start with the latest supported version
|
||||
@ -376,6 +377,7 @@ func (cli *Client) negotiateAPIVersionPing(pingVersion string) {
|
||||
if cli.negotiateVersion {
|
||||
cli.negotiated.Store(true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DaemonHost returns the host address used by the client
|
||||
|
||||
18
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
18
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@ -6,10 +6,8 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/events"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
@ -90,7 +88,7 @@ type ContainerAPIClient interface {
|
||||
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
|
||||
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
|
||||
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error
|
||||
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
|
||||
ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error)
|
||||
}
|
||||
|
||||
type ExecAPIClient interface {
|
||||
@ -109,18 +107,18 @@ type DistributionAPIClient interface {
|
||||
// ImageAPIClient defines API client methods for the images
|
||||
type ImageAPIClient interface {
|
||||
ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResponse, error)
|
||||
BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error)
|
||||
BuildCancel(ctx context.Context, id string) error
|
||||
BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (BuildCachePruneResult, error)
|
||||
BuildCancel(ctx context.Context, id string, opts BuildCancelOptions) error
|
||||
ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error)
|
||||
ImageImport(ctx context.Context, source ImageImportSource, ref string, options ImageImportOptions) (io.ReadCloser, error)
|
||||
|
||||
ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error)
|
||||
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (io.ReadCloser, error)
|
||||
ImagePull(ctx context.Context, ref string, options ImagePullOptions) (ImagePullResponse, error)
|
||||
ImagePush(ctx context.Context, ref string, options ImagePushOptions) (io.ReadCloser, error)
|
||||
ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error)
|
||||
ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error)
|
||||
ImageTag(ctx context.Context, image, ref string) error
|
||||
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)
|
||||
ImagesPrune(ctx context.Context, pruneFilter Filters) (image.PruneReport, error)
|
||||
|
||||
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
|
||||
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
|
||||
@ -137,7 +135,7 @@ type NetworkAPIClient interface {
|
||||
NetworkInspectWithRaw(ctx context.Context, network string, options NetworkInspectOptions) (network.Inspect, []byte, error)
|
||||
NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error)
|
||||
NetworkRemove(ctx context.Context, network string) error
|
||||
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error)
|
||||
NetworksPrune(ctx context.Context, pruneFilter Filters) (network.PruneReport, error)
|
||||
}
|
||||
|
||||
// NodeAPIClient defines API client methods for the nodes
|
||||
@ -150,7 +148,7 @@ type NodeAPIClient interface {
|
||||
|
||||
// PluginAPIClient defines API client methods for the plugins
|
||||
type PluginAPIClient interface {
|
||||
PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error)
|
||||
PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error)
|
||||
PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error
|
||||
PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error
|
||||
PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error
|
||||
@ -202,7 +200,7 @@ type VolumeAPIClient interface {
|
||||
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
|
||||
VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error)
|
||||
VolumeRemove(ctx context.Context, volumeID string, force bool) error
|
||||
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error)
|
||||
VolumesPrune(ctx context.Context, pruneFilter Filters) (volume.PruneReport, error)
|
||||
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
|
||||
}
|
||||
|
||||
|
||||
11
vendor/github.com/moby/moby/client/config_list.go
generated
vendored
11
vendor/github.com/moby/moby/client/config_list.go
generated
vendored
@ -5,22 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// ConfigList returns the list of configs.
|
||||
func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.get(ctx, "/configs", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
65
vendor/github.com/moby/moby/client/container_create.go
generated
vendored
65
vendor/github.com/moby/moby/client/container_create.go
generated
vendored
@ -3,7 +3,6 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
@ -25,58 +24,28 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
||||
|
||||
var response container.CreateResponse
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
if err := cli.NewVersionError(ctx, "1.25", "stop timeout"); config.StopTimeout != nil && err != nil {
|
||||
return response, err
|
||||
}
|
||||
if err := cli.NewVersionError(ctx, "1.41", "specify container image platform"); platform != nil && err != nil {
|
||||
return response, err
|
||||
}
|
||||
if err := cli.NewVersionError(ctx, "1.44", "specify health-check start interval"); config.Healthcheck != nil && config.Healthcheck.StartInterval != 0 && err != nil {
|
||||
return response, err
|
||||
}
|
||||
if err := cli.NewVersionError(ctx, "1.44", "specify mac-address per network"); hasEndpointSpecificMacAddress(networkingConfig) && err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
if hostConfig != nil {
|
||||
if versions.LessThan(cli.ClientVersion(), "1.25") {
|
||||
// When using API 1.24 and under, the client is responsible for removing the container
|
||||
hostConfig.AutoRemove = false
|
||||
}
|
||||
if platform != nil && platform.OS == "linux" && versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
// When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
if versions.LessThan(cli.ClientVersion(), "1.44") {
|
||||
for _, m := range hostConfig.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
// ReadOnlyNonRecursive can be safely ignored when API < 1.44
|
||||
if m.BindOptions.ReadOnlyForceRecursive {
|
||||
return response, errors.New("bind-recursive=readonly requires API v1.44 or later")
|
||||
}
|
||||
if m.BindOptions.NonRecursive && versions.LessThan(cli.ClientVersion(), "1.40") {
|
||||
return response, errors.New("bind-recursive=disabled requires API v1.40 or later")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd)
|
||||
hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop)
|
||||
}
|
||||
|
||||
// Since API 1.44, the container-wide MacAddress is deprecated and triggers a WARNING if it's specified.
|
||||
if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.44") {
|
||||
config.MacAddress = "" //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
// FIXME(thaJeztah): remove this once we updated our (integration) tests;
|
||||
// some integration tests depend on this to test old API versions; see https://github.com/moby/moby/pull/51120#issuecomment-3376224865
|
||||
if config.MacAddress != "" { //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return response, err
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(cli.ClientVersion(), "1.44") {
|
||||
// Since API 1.44, the container-wide MacAddress is deprecated and triggers a WARNING if it's specified.
|
||||
//
|
||||
// FIXME(thaJeztah): remove the field from the API
|
||||
config.MacAddress = "" //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.
|
||||
}
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
|
||||
33
vendor/github.com/moby/moby/client/container_exec.go
generated
vendored
33
vendor/github.com/moby/moby/client/container_exec.go
generated
vendored
@ -6,7 +6,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// ExecCreateOptions is a small subset of the Config struct that holds the configuration
|
||||
@ -32,22 +31,6 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, containerID string,
|
||||
return container.ExecCreateResponse{}, err
|
||||
}
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return container.ExecCreateResponse{}, err
|
||||
}
|
||||
|
||||
if err := cli.NewVersionError(ctx, "1.25", "env"); len(options.Env) != 0 && err != nil {
|
||||
return container.ExecCreateResponse{}, err
|
||||
}
|
||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
options.ConsoleSize = nil
|
||||
}
|
||||
|
||||
req := container.ExecCreateRequest{
|
||||
User: options.User,
|
||||
Privileged: options.Privileged,
|
||||
@ -86,19 +69,6 @@ type ExecStartOptions struct {
|
||||
|
||||
// ContainerExecStart starts an exec process already created in the docker host.
|
||||
func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config ExecStartOptions) error {
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
config.ConsoleSize = nil
|
||||
}
|
||||
|
||||
req := container.ExecStartRequest{
|
||||
Detach: config.Detach,
|
||||
Tty: config.Tty,
|
||||
@ -133,9 +103,6 @@ type ExecAttachOptions = ExecStartOptions
|
||||
//
|
||||
// [stdcopy.StdCopy]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdCopy
|
||||
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config ExecAttachOptions) (HijackedResponse, error) {
|
||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
config.ConsoleSize = nil
|
||||
}
|
||||
req := container.ExecStartRequest{
|
||||
Detach: config.Detach,
|
||||
Tty: config.Tty,
|
||||
|
||||
11
vendor/github.com/moby/moby/client/container_list.go
generated
vendored
11
vendor/github.com/moby/moby/client/container_list.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
)
|
||||
|
||||
// ContainerListOptions holds parameters to list containers with.
|
||||
@ -18,7 +17,7 @@ type ContainerListOptions struct {
|
||||
Since string
|
||||
Before string
|
||||
Limit int
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
// ContainerList returns the list of containers in the docker host.
|
||||
@ -45,13 +44,7 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio
|
||||
query.Set("size", "1")
|
||||
}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.get(ctx, "/containers/json", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
10
vendor/github.com/moby/moby/client/container_prune.go
generated
vendored
10
vendor/github.com/moby/moby/client/container_prune.go
generated
vendored
@ -4,17 +4,15 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
)
|
||||
|
||||
// ContainersPrune requests the daemon to delete unused data
|
||||
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
|
||||
query, err := getFiltersQuery(pruneFilters)
|
||||
if err != nil {
|
||||
return container.PruneReport{}, err
|
||||
}
|
||||
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) {
|
||||
query := url.Values{}
|
||||
pruneFilters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.post(ctx, "/containers/prune", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
14
vendor/github.com/moby/moby/client/container_restart.go
generated
vendored
14
vendor/github.com/moby/moby/client/container_restart.go
generated
vendored
@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// ContainerRestart stops, and starts a container again.
|
||||
@ -22,17 +20,7 @@ func (cli *Client) ContainerRestart(ctx context.Context, containerID string, opt
|
||||
query.Set("t", strconv.Itoa(*options.Timeout))
|
||||
}
|
||||
if options.Signal != "" {
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
||||
query.Set("signal", options.Signal)
|
||||
}
|
||||
query.Set("signal", options.Signal)
|
||||
}
|
||||
resp, err := cli.post(ctx, "/containers/"+containerID+"/restart", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
14
vendor/github.com/moby/moby/client/container_stop.go
generated
vendored
14
vendor/github.com/moby/moby/client/container_stop.go
generated
vendored
@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// ContainerStopOptions holds the options to stop or restart a container.
|
||||
@ -44,17 +42,7 @@ func (cli *Client) ContainerStop(ctx context.Context, containerID string, option
|
||||
query.Set("t", strconv.Itoa(*options.Timeout))
|
||||
}
|
||||
if options.Signal != "" {
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
||||
query.Set("signal", options.Signal)
|
||||
}
|
||||
query.Set("signal", options.Signal)
|
||||
}
|
||||
resp, err := cli.post(ctx, "/containers/"+containerID+"/stop", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
14
vendor/github.com/moby/moby/client/container_wait.go
generated
vendored
14
vendor/github.com/moby/moby/client/container_wait.go
generated
vendored
@ -9,7 +9,6 @@ import (
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */
|
||||
@ -41,19 +40,6 @@ func (cli *Client) ContainerWait(ctx context.Context, containerID string, condit
|
||||
return resultC, errC
|
||||
}
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
errC <- err
|
||||
return resultC, errC
|
||||
}
|
||||
if versions.LessThan(cli.ClientVersion(), "1.30") {
|
||||
return cli.legacyContainerWait(ctx, containerID)
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
if condition != "" {
|
||||
query.Set("condition", string(condition))
|
||||
|
||||
46
vendor/github.com/moby/moby/client/filters.go
generated
vendored
Normal file
46
vendor/github.com/moby/moby/client/filters.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Filters describes a predicate for an API request.
|
||||
//
|
||||
// Each entry in the map is a filter term.
|
||||
// Each term is evaluated against the set of values.
|
||||
// A filter term is satisfied if any one of the values in the set is a match.
|
||||
// An item matches the filters when all terms are satisfied.
|
||||
//
|
||||
// Like all other map types in Go, the zero value is empty and read-only.
|
||||
type Filters map[string]map[string]bool
|
||||
|
||||
// Add appends values to the value-set of term.
|
||||
//
|
||||
// The receiver f is returned for chaining.
|
||||
//
|
||||
// f := make(Filters).Add("name", "foo", "bar").Add("status", "exited")
|
||||
func (f Filters) Add(term string, values ...string) Filters {
|
||||
if _, ok := f[term]; !ok {
|
||||
f[term] = make(map[string]bool)
|
||||
}
|
||||
for _, v := range values {
|
||||
f[term][v] = true
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// updateURLValues sets the "filters" key in values to the marshalled value of
|
||||
// f, replacing any existing values. When f is empty, any existing "filters" key
|
||||
// is removed.
|
||||
func (f Filters) updateURLValues(values url.Values) {
|
||||
if len(f) > 0 {
|
||||
b, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
panic(err) // Marshaling builtin types should never fail
|
||||
}
|
||||
values.Set("filters", string(b))
|
||||
} else {
|
||||
values.Del("filters")
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/moby/moby/client/hijack.go
generated
vendored
6
vendor/github.com/moby/moby/client/hijack.go
generated
vendored
@ -9,7 +9,6 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
@ -28,11 +27,6 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
|
||||
return HijackedResponse{}, err
|
||||
}
|
||||
|
||||
if versions.LessThan(cli.ClientVersion(), "1.42") {
|
||||
// Prior to 1.42, Content-Type is always set to raw-stream and not relevant
|
||||
mediaType = ""
|
||||
}
|
||||
|
||||
return NewHijackedResponse(conn, mediaType), nil
|
||||
}
|
||||
|
||||
|
||||
9
vendor/github.com/moby/moby/client/image_build.go
generated
vendored
9
vendor/github.com/moby/moby/client/image_build.go
generated
vendored
@ -42,7 +42,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options ImageBuildOptions) (url.Values, error) {
|
||||
func (cli *Client) imageBuildOptionsToQuery(_ context.Context, options ImageBuildOptions) (url.Values, error) {
|
||||
query := url.Values{}
|
||||
if len(options.Tags) > 0 {
|
||||
query["t"] = options.Tags
|
||||
@ -79,9 +79,7 @@ func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options ImageBu
|
||||
}
|
||||
|
||||
if options.Squash {
|
||||
if err := cli.NewVersionError(ctx, "1.25", "squash"); err != nil {
|
||||
return query, err
|
||||
}
|
||||
// TODO(thaJeztah): squash is experimental, and deprecated when using BuildKit?
|
||||
query.Set("squash", "1")
|
||||
}
|
||||
|
||||
@ -157,9 +155,6 @@ func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options ImageBu
|
||||
query.Set("session", options.SessionID)
|
||||
}
|
||||
if options.Platform != "" {
|
||||
if err := cli.NewVersionError(ctx, "1.32", "platform"); err != nil {
|
||||
return query, err
|
||||
}
|
||||
query.Set("platform", strings.ToLower(options.Platform))
|
||||
}
|
||||
if options.BuildID != "" {
|
||||
|
||||
35
vendor/github.com/moby/moby/client/image_list.go
generated
vendored
35
vendor/github.com/moby/moby/client/image_list.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
@ -19,32 +18,28 @@ import (
|
||||
func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]image.Summary, error) {
|
||||
var images []image.Summary
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return images, err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return images, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
if options.All {
|
||||
query.Set("all", "1")
|
||||
}
|
||||
if options.SharedSize && versions.GreaterThanOrEqualTo(cli.version, "1.42") {
|
||||
if options.SharedSize {
|
||||
query.Set("shared-size", "1")
|
||||
}
|
||||
if options.Manifests && versions.GreaterThanOrEqualTo(cli.version, "1.47") {
|
||||
query.Set("manifests", "1")
|
||||
if options.Manifests {
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return images, err
|
||||
}
|
||||
|
||||
if versions.GreaterThanOrEqualTo(cli.version, "1.47") {
|
||||
query.Set("manifests", "1")
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/images/json", query, nil)
|
||||
|
||||
4
vendor/github.com/moby/moby/client/image_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/image_list_opts.go
generated
vendored
@ -1,7 +1,5 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// ImageListOptions holds parameters to list images with.
|
||||
type ImageListOptions struct {
|
||||
// All controls whether all images in the graph are filtered, or just
|
||||
@ -9,7 +7,7 @@ type ImageListOptions struct {
|
||||
All bool
|
||||
|
||||
// Filters is a JSON-encoded set of filter arguments.
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
|
||||
// SharedSize indicates whether the shared size of images should be computed.
|
||||
SharedSize bool
|
||||
|
||||
10
vendor/github.com/moby/moby/client/image_prune.go
generated
vendored
10
vendor/github.com/moby/moby/client/image_prune.go
generated
vendored
@ -4,17 +4,15 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/image"
|
||||
)
|
||||
|
||||
// ImagesPrune requests the daemon to delete unused data
|
||||
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) {
|
||||
query, err := getFiltersQuery(pruneFilters)
|
||||
if err != nil {
|
||||
return image.PruneReport{}, err
|
||||
}
|
||||
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters Filters) (image.PruneReport, error) {
|
||||
query := url.Values{}
|
||||
pruneFilters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.post(ctx, "/images/prune", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
76
vendor/github.com/moby/moby/client/image_pull.go
generated
vendored
76
vendor/github.com/moby/moby/client/image_pull.go
generated
vendored
@ -2,19 +2,84 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"iter"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/client/pkg/jsonmessage"
|
||||
)
|
||||
|
||||
func newImagePullResponse(rc io.ReadCloser) ImagePullResponse {
|
||||
if rc == nil {
|
||||
panic("nil io.ReadCloser")
|
||||
}
|
||||
return ImagePullResponse{
|
||||
rc: rc,
|
||||
close: sync.OnceValue(rc.Close),
|
||||
}
|
||||
}
|
||||
|
||||
type ImagePullResponse struct {
|
||||
rc io.ReadCloser
|
||||
close func() error
|
||||
}
|
||||
|
||||
// Read implements io.ReadCloser
|
||||
func (r ImagePullResponse) Read(p []byte) (n int, err error) {
|
||||
if r.rc == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return r.rc.Read(p)
|
||||
}
|
||||
|
||||
// Close implements io.ReadCloser
|
||||
func (r ImagePullResponse) Close() error {
|
||||
if r.close == nil {
|
||||
return nil
|
||||
}
|
||||
return r.close()
|
||||
}
|
||||
|
||||
// JSONMessages decodes the response stream as a sequence of JSONMessages.
|
||||
// if stream ends or context is cancelled, the underlying [io.Reader] is closed.
|
||||
func (r ImagePullResponse) JSONMessages(ctx context.Context) iter.Seq2[jsonmessage.JSONMessage, error] {
|
||||
context.AfterFunc(ctx, func() {
|
||||
_ = r.Close()
|
||||
})
|
||||
dec := json.NewDecoder(r)
|
||||
return func(yield func(jsonmessage.JSONMessage, error) bool) {
|
||||
defer r.Close()
|
||||
for {
|
||||
var jm jsonmessage.JSONMessage
|
||||
err := dec.Decode(&jm)
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
yield(jm, ctx.Err())
|
||||
return
|
||||
}
|
||||
if !yield(jm, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ImagePull requests the docker host to pull an image from a remote registry.
|
||||
// It executes the privileged function if the operation is unauthorized
|
||||
// and it tries one more time.
|
||||
// It's up to the caller to handle the [io.ReadCloser] and close it.
|
||||
func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePullOptions) (io.ReadCloser, error) {
|
||||
// Callers can use [ImagePullResponse.JSONMessages] to monitor pull progress as
|
||||
// a sequence of JSONMessages, [ImagePullResponse.Close] does not need to be
|
||||
// called in this case. Or, use the [io.Reader] interface and call
|
||||
// [ImagePullResponse.Close] after processing.
|
||||
func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePullOptions) (ImagePullResponse, error) {
|
||||
// FIXME(vdemeester): there is currently used in a few way in docker/docker
|
||||
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
|
||||
// - if in trusted content, ref is used to pass the reference name, and tag for the digest
|
||||
@ -23,7 +88,7 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePu
|
||||
|
||||
ref, err := reference.ParseNormalizedNamed(refStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ImagePullResponse{}, err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
@ -40,9 +105,10 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePu
|
||||
resp, err = cli.tryImageCreate(ctx, query, options.PrivilegeFunc)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ImagePullResponse{}, err
|
||||
}
|
||||
return resp.Body, nil
|
||||
|
||||
return newImagePullResponse(resp.Body), nil
|
||||
}
|
||||
|
||||
// getAPITagFromNamedRef returns a tag from the specified reference.
|
||||
|
||||
4
vendor/github.com/moby/moby/client/image_pull_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/image_pull_opts.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
package client
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// ImagePullOptions holds information to pull images.
|
||||
type ImagePullOptions struct {
|
||||
|
||||
9
vendor/github.com/moby/moby/client/image_search.go
generated
vendored
9
vendor/github.com/moby/moby/client/image_search.go
generated
vendored
@ -8,7 +8,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
)
|
||||
|
||||
@ -22,13 +21,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSe
|
||||
query.Set("limit", strconv.Itoa(options.Limit))
|
||||
}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
4
vendor/github.com/moby/moby/client/image_search_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/image_search_opts.go
generated
vendored
@ -2,8 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
)
|
||||
|
||||
// ImageSearchOptions holds parameters to search images with.
|
||||
@ -17,6 +15,6 @@ type ImageSearchOptions struct {
|
||||
//
|
||||
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
|
||||
PrivilegeFunc func(context.Context) (string, error)
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
Limit int
|
||||
}
|
||||
|
||||
50
vendor/github.com/moby/moby/client/internal/json-stream.go
generated
vendored
Normal file
50
vendor/github.com/moby/moby/client/internal/json-stream.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"slices"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
)
|
||||
|
||||
const rs = 0x1E
|
||||
|
||||
type DecoderFn func(v any) error
|
||||
|
||||
// NewJSONStreamDecoder builds adequate DecoderFn to read json records formatted with specified content-type
|
||||
func NewJSONStreamDecoder(r io.Reader, contentType string) DecoderFn {
|
||||
switch contentType {
|
||||
case types.MediaTypeJSONSequence:
|
||||
return json.NewDecoder(NewRSFilterReader(r)).Decode
|
||||
case types.MediaTypeJSON, types.MediaTypeNDJSON:
|
||||
fallthrough
|
||||
default:
|
||||
return json.NewDecoder(r).Decode
|
||||
}
|
||||
}
|
||||
|
||||
// RSFilterReader wraps an io.Reader and filters out ASCII RS characters
|
||||
type RSFilterReader struct {
|
||||
reader io.Reader
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
// NewRSFilterReader creates a new RSFilterReader that filters out RS characters
|
||||
func NewRSFilterReader(r io.Reader) *RSFilterReader {
|
||||
return &RSFilterReader{
|
||||
reader: r,
|
||||
buffer: make([]byte, 4096), // Internal buffer for reading chunks
|
||||
}
|
||||
}
|
||||
|
||||
// Read implements the io.Reader interface, filtering out RS characters
|
||||
func (r *RSFilterReader) Read(p []byte) (n int, err error) {
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
n, err = r.reader.Read(p)
|
||||
filtered := slices.DeleteFunc(p[:n], func(b byte) bool { return b == rs })
|
||||
return len(filtered), err
|
||||
}
|
||||
33
vendor/github.com/moby/moby/client/network_create.go
generated
vendored
33
vendor/github.com/moby/moby/client/network_create.go
generated
vendored
@ -5,21 +5,11 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
)
|
||||
|
||||
// NetworkCreate creates a new network in the docker host.
|
||||
func (cli *Client) NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (network.CreateResponse, error) {
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return network.CreateResponse{}, err
|
||||
}
|
||||
|
||||
networkCreateRequest := network.CreateRequest{
|
||||
req := network.CreateRequest{
|
||||
Name: name,
|
||||
Driver: options.Driver,
|
||||
Scope: options.Scope,
|
||||
@ -35,27 +25,6 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options Netwo
|
||||
Labels: options.Labels,
|
||||
}
|
||||
|
||||
var req any
|
||||
if versions.LessThan(cli.version, "1.44") {
|
||||
// CheckDuplicate is removed in API v1.44, and no longer used by
|
||||
// daemons supporting that API version (v25.0.0-beta.1 and up)
|
||||
// regardless of the API version used, but it must be set to true
|
||||
// when sent to older daemons.
|
||||
//
|
||||
// TODO(thaJeztah) remove this once daemon versions v24.0 and lower are no
|
||||
// longer expected to be used (when Mirantis Container Runtime v23
|
||||
// is EOL); https://github.com/moby/moby/blob/v2.0.0-beta.0/project/BRANCHES-AND-TAGS.md
|
||||
req = struct {
|
||||
network.CreateRequest
|
||||
CheckDuplicate bool
|
||||
}{
|
||||
CreateRequest: networkCreateRequest,
|
||||
CheckDuplicate: true,
|
||||
}
|
||||
} else {
|
||||
req = networkCreateRequest
|
||||
}
|
||||
|
||||
resp, err := cli.post(ctx, "/networks/create", nil, req, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
9
vendor/github.com/moby/moby/client/network_list.go
generated
vendored
9
vendor/github.com/moby/moby/client/network_list.go
generated
vendored
@ -5,20 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
)
|
||||
|
||||
// NetworkList returns the list of networks configured in the docker host.
|
||||
func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) {
|
||||
query := url.Values{}
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
var networkResources []network.Summary
|
||||
resp, err := cli.get(ctx, "/networks", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
4
vendor/github.com/moby/moby/client/network_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/network_list_opts.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// NetworkListOptions holds parameters to filter the list of networks with.
|
||||
type NetworkListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
10
vendor/github.com/moby/moby/client/network_prune.go
generated
vendored
10
vendor/github.com/moby/moby/client/network_prune.go
generated
vendored
@ -4,17 +4,15 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
)
|
||||
|
||||
// NetworksPrune requests the daemon to delete unused networks
|
||||
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) {
|
||||
query, err := getFiltersQuery(pruneFilters)
|
||||
if err != nil {
|
||||
return network.PruneReport{}, err
|
||||
}
|
||||
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters Filters) (network.PruneReport, error) {
|
||||
query := url.Values{}
|
||||
pruneFilters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.post(ctx, "/networks/prune", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
12
vendor/github.com/moby/moby/client/node_list.go
generated
vendored
12
vendor/github.com/moby/moby/client/node_list.go
generated
vendored
@ -5,23 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeList returns the list of nodes.
|
||||
func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
|
||||
options.Filters.updateURLValues(query)
|
||||
resp, err := cli.get(ctx, "/nodes", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
44
vendor/github.com/moby/moby/client/pkg/jsonmessage/jsonmessage.go
generated
vendored
44
vendor/github.com/moby/moby/client/pkg/jsonmessage/jsonmessage.go
generated
vendored
@ -2,8 +2,10 @@ package jsonmessage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -187,9 +189,32 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type JSONMessagesStream iter.Seq2[JSONMessage, error]
|
||||
|
||||
// DisplayJSONMessagesStream reads a JSON message stream from in, and writes
|
||||
// each [JSONMessage] to out. It returns an error if an invalid JSONMessage
|
||||
// is received, or if a JSONMessage containers a non-zero [JSONMessage.Error].
|
||||
// each [JSONMessage] to out.
|
||||
// see DisplayJSONMessages for details
|
||||
func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error {
|
||||
var dec = json.NewDecoder(in)
|
||||
var f JSONMessagesStream = func(yield func(JSONMessage, error) bool) {
|
||||
for {
|
||||
var jm JSONMessage
|
||||
err := dec.Decode(&jm)
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if !yield(jm, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DisplayJSONMessages(f, out, terminalFd, isTerminal, auxCallback)
|
||||
}
|
||||
|
||||
// DisplayJSONMessages writes each [JSONMessage] from stream to out.
|
||||
// It returns an error if an invalid JSONMessage is received, or if
|
||||
// a JSONMessage containers a non-zero [JSONMessage.Error].
|
||||
//
|
||||
// Presentation of the JSONMessage depends on whether a terminal is attached,
|
||||
// and on the terminal width. Progress bars ([JSONProgress]) are suppressed
|
||||
@ -203,19 +228,12 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
||||
// - auxCallback allows handling the [JSONMessage.Aux] field. It is
|
||||
// called if a JSONMessage contains an Aux field, in which case
|
||||
// DisplayJSONMessagesStream does not present the JSONMessage.
|
||||
func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error {
|
||||
var (
|
||||
dec = json.NewDecoder(in)
|
||||
ids = make(map[string]uint)
|
||||
)
|
||||
func DisplayJSONMessages(messages JSONMessagesStream, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error {
|
||||
var ids = make(map[string]uint)
|
||||
|
||||
for {
|
||||
for jm, err := range messages {
|
||||
var diff uint
|
||||
var jm JSONMessage
|
||||
if err := dec.Decode(&jm); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
11
vendor/github.com/moby/moby/client/plugin_list.go
generated
vendored
11
vendor/github.com/moby/moby/client/plugin_list.go
generated
vendored
@ -5,22 +5,15 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/plugin"
|
||||
)
|
||||
|
||||
// PluginList returns the installed plugins
|
||||
func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) {
|
||||
func (cli *Client) PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error) {
|
||||
var plugins plugin.ListResponse
|
||||
query := url.Values{}
|
||||
|
||||
if filter.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(filter)
|
||||
if err != nil {
|
||||
return plugins, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
filter.updateURLValues(query)
|
||||
resp, err := cli.get(ctx, "/plugins", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
5
vendor/github.com/moby/moby/client/request.go
generated
vendored
5
vendor/github.com/moby/moby/client/request.go
generated
vendored
@ -303,9 +303,8 @@ func checkResponseErr(serverResp *http.Response) (retErr error) {
|
||||
daemonErr = errors.New(strings.TrimSpace(errorResponse.Message))
|
||||
}
|
||||
} else {
|
||||
// Fall back to returning the response as-is for API versions < 1.24
|
||||
// that didn't support JSON error responses, and for situations
|
||||
// where a plain text error is returned. This branch may also catch
|
||||
// Fall back to returning the response as-is for situations where a
|
||||
// plain text error is returned. This branch may also catch
|
||||
// situations where a proxy is involved, returning a HTML response.
|
||||
daemonErr = errors.New(strings.TrimSpace(string(body)))
|
||||
}
|
||||
|
||||
11
vendor/github.com/moby/moby/client/secret_list.go
generated
vendored
11
vendor/github.com/moby/moby/client/secret_list.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
@ -13,15 +12,7 @@ import (
|
||||
func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
|
||||
options.Filters.updateURLValues(query)
|
||||
resp, err := cli.get(ctx, "/secrets", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
4
vendor/github.com/moby/moby/client/secret_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/secret_list_opts.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// SecretListOptions holds parameters to list secrets
|
||||
type SecretListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
27
vendor/github.com/moby/moby/client/service_create.go
generated
vendored
27
vendor/github.com/moby/moby/client/service_create.go
generated
vendored
@ -11,7 +11,6 @@ import (
|
||||
"github.com/distribution/reference"
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
@ -19,21 +18,12 @@ import (
|
||||
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options ServiceCreateOptions) (swarm.ServiceCreateResponse, error) {
|
||||
var response swarm.ServiceCreateResponse
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
|
||||
if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
|
||||
service.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{}
|
||||
}
|
||||
|
||||
if err := validateServiceSpec(service, cli.version); err != nil {
|
||||
if err := validateServiceSpec(service); err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
@ -172,7 +162,7 @@ func digestWarning(image string) string {
|
||||
return fmt.Sprintf("image %s could not be accessed on a registry to record\nits digest. Each node will access %s independently,\npossibly leading to different nodes running different\nversions of the image.\n", image, image)
|
||||
}
|
||||
|
||||
func validateServiceSpec(s swarm.ServiceSpec, apiVersion string) error {
|
||||
func validateServiceSpec(s swarm.ServiceSpec) error {
|
||||
if s.TaskTemplate.ContainerSpec != nil && s.TaskTemplate.PluginSpec != nil {
|
||||
return errors.New("must not specify both a container spec and a plugin spec in the task template")
|
||||
}
|
||||
@ -182,18 +172,5 @@ func validateServiceSpec(s swarm.ServiceSpec, apiVersion string) error {
|
||||
if s.TaskTemplate.ContainerSpec != nil && (s.TaskTemplate.Runtime != "" && s.TaskTemplate.Runtime != swarm.RuntimeContainer) {
|
||||
return errors.New("mismatched runtime with container spec")
|
||||
}
|
||||
if s.TaskTemplate.ContainerSpec != nil && apiVersion != "" && versions.LessThan(apiVersion, "1.44") {
|
||||
for _, m := range s.TaskTemplate.ContainerSpec.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
if m.BindOptions.NonRecursive && versions.LessThan(apiVersion, "1.40") {
|
||||
return errors.New("bind-recursive=disabled requires API v1.40 or later")
|
||||
}
|
||||
// ReadOnlyNonRecursive can be safely ignored when API < 1.44
|
||||
if m.BindOptions.ReadOnlyForceRecursive && versions.LessThan(apiVersion, "1.44") {
|
||||
return errors.New("bind-recursive=readonly requires API v1.44 or later")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/moby/moby/client/service_list.go
generated
vendored
10
vendor/github.com/moby/moby/client/service_list.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
@ -13,14 +12,7 @@ import (
|
||||
func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
if options.Status {
|
||||
query.Set("status", "true")
|
||||
|
||||
10
vendor/github.com/moby/moby/client/service_update.go
generated
vendored
10
vendor/github.com/moby/moby/client/service_update.go
generated
vendored
@ -20,15 +20,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
|
||||
return swarm.ServiceUpdateResponse{}, err
|
||||
}
|
||||
|
||||
// Make sure we negotiated (if the client is configured to do so),
|
||||
// as code below contains API-version specific handling of options.
|
||||
//
|
||||
// Normally, version-negotiation (if enabled) would not happen until
|
||||
// the API request is made.
|
||||
if err := cli.checkVersion(ctx); err != nil {
|
||||
return swarm.ServiceUpdateResponse{}, err
|
||||
}
|
||||
if err := validateServiceSpec(service, cli.version); err != nil {
|
||||
if err := validateServiceSpec(service); err != nil {
|
||||
return swarm.ServiceUpdateResponse{}, err
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/moby/moby/client/swarm_config_list_options.go
generated
vendored
4
vendor/github.com/moby/moby/client/swarm_config_list_options.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// ConfigListOptions holds parameters to list configs
|
||||
type ConfigListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
4
vendor/github.com/moby/moby/client/swarm_node_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/swarm_node_list_opts.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
4
vendor/github.com/moby/moby/client/swarm_service_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/swarm_service_list_opts.go
generated
vendored
@ -1,10 +1,8 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// ServiceListOptions holds parameters to list services with.
|
||||
type ServiceListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
|
||||
// Status indicates whether the server should include the service task
|
||||
// count of running and desired tasks.
|
||||
|
||||
4
vendor/github.com/moby/moby/client/swarm_task_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/swarm_task_list_opts.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// TaskListOptions holds parameters to list tasks with.
|
||||
type TaskListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
25
vendor/github.com/moby/moby/client/system_events.go
generated
vendored
25
vendor/github.com/moby/moby/client/system_events.go
generated
vendored
@ -2,12 +2,13 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/events"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/client/internal"
|
||||
"github.com/moby/moby/client/internal/timestamp"
|
||||
)
|
||||
|
||||
@ -15,7 +16,7 @@ import (
|
||||
type EventsListOptions struct {
|
||||
Since string
|
||||
Until string
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
// Events returns a stream of events in the daemon. It's up to the caller to close the stream
|
||||
@ -37,7 +38,10 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) (<-cha
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/events", query, nil)
|
||||
headers := http.Header{}
|
||||
headers.Add("Accept", types.MediaTypeJSONSequence)
|
||||
headers.Add("Accept", types.MediaTypeNDJSON)
|
||||
resp, err := cli.get(ctx, "/events", query, headers)
|
||||
if err != nil {
|
||||
close(started)
|
||||
errs <- err
|
||||
@ -45,7 +49,8 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) (<-cha
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
decoder := internal.NewJSONStreamDecoder(resp.Body, contentType)
|
||||
|
||||
close(started)
|
||||
for {
|
||||
@ -55,7 +60,7 @@ func (cli *Client) Events(ctx context.Context, options EventsListOptions) (<-cha
|
||||
return
|
||||
default:
|
||||
var event events.Message
|
||||
if err := decoder.Decode(&event); err != nil {
|
||||
if err := decoder(&event); err != nil {
|
||||
errs <- err
|
||||
return
|
||||
}
|
||||
@ -94,13 +99,7 @@ func buildEventsQueryParams(options EventsListOptions) (url.Values, error) {
|
||||
query.Set("until", ts)
|
||||
}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
10
vendor/github.com/moby/moby/client/task_list.go
generated
vendored
10
vendor/github.com/moby/moby/client/task_list.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
@ -13,14 +12,7 @@ import (
|
||||
func (cli *Client) TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.get(ctx, "/tasks", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
16
vendor/github.com/moby/moby/client/utils.go
generated
vendored
16
vendor/github.com/moby/moby/client/utils.go
generated
vendored
@ -3,11 +3,9 @@ package client
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@ -28,20 +26,6 @@ func trimID(objType, id string) (string, error) {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// getFiltersQuery returns a url query with "filters" query term, based on the
|
||||
// filters provided.
|
||||
func getFiltersQuery(f filters.Args) (url.Values, error) {
|
||||
query := url.Values{}
|
||||
if f.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(f)
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// encodePlatforms marshals the given platform(s) to JSON format, to
|
||||
// be used for query-parameters for filtering / selecting platforms.
|
||||
func encodePlatforms(platform ...ocispec.Platform) ([]string, error) {
|
||||
|
||||
9
vendor/github.com/moby/moby/client/volume_list.go
generated
vendored
9
vendor/github.com/moby/moby/client/volume_list.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
@ -13,13 +12,7 @@ import (
|
||||
func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) {
|
||||
query := url.Values{}
|
||||
|
||||
if options.Filters.Len() > 0 {
|
||||
filterJSON, err := filters.ToJSON(options.Filters)
|
||||
if err != nil {
|
||||
return volume.ListResponse{}, err
|
||||
}
|
||||
query.Set("filters", filterJSON)
|
||||
}
|
||||
options.Filters.updateURLValues(query)
|
||||
resp, err := cli.get(ctx, "/volumes", query, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
|
||||
4
vendor/github.com/moby/moby/client/volume_list_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/volume_list_opts.go
generated
vendored
@ -1,8 +1,6 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/filters"
|
||||
|
||||
// VolumeListOptions holds parameters to list volumes.
|
||||
type VolumeListOptions struct {
|
||||
Filters filters.Args
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
10
vendor/github.com/moby/moby/client/volume_prune.go
generated
vendored
10
vendor/github.com/moby/moby/client/volume_prune.go
generated
vendored
@ -4,17 +4,15 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumesPrune requests the daemon to delete unused data
|
||||
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) {
|
||||
query, err := getFiltersQuery(pruneFilters)
|
||||
if err != nil {
|
||||
return volume.PruneReport{}, err
|
||||
}
|
||||
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters Filters) (volume.PruneReport, error) {
|
||||
query := url.Values{}
|
||||
pruneFilters.updateURLValues(query)
|
||||
|
||||
resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
|
||||
Reference in New Issue
Block a user