diff --git a/go.mod b/go.mod index cc3d6092a7..1c95133161 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 github.com/container-storage-interface/spec v1.2.0 github.com/docker/distribution v2.8.2+incompatible - github.com/docker/docker v24.0.0-rc.2.0.20230630161949-75ee002347f8+incompatible // master (v25.0.0-dev) + github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible // master (v25.0.0-dev) github.com/docker/go-connections v0.4.0 github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c github.com/docker/go-metrics v0.0.1 diff --git a/go.sum b/go.sum index bcd70a8043..ccbd619349 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.0-rc.2.0.20230630161949-75ee002347f8+incompatible h1:3OTkzTHbQj93/CJInJrkpgiKz+8THR9Y9lp/i5Jb/JE= -github.com/docker/docker v24.0.0-rc.2.0.20230630161949-75ee002347f8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible h1:XccikgvtGCEZE9ZQoaEApdx9ZvruGYakfi2tw4d/vUg= +github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= diff --git a/manager/allocator/cnmallocator/drivers_darwin.go b/manager/allocator/cnmallocator/drivers_darwin.go index e7d3dbe710..ac4152db22 100644 --- a/manager/allocator/cnmallocator/drivers_darwin.go +++ b/manager/allocator/cnmallocator/drivers_darwin.go @@ -1,14 +1,13 @@ package cnmallocator import ( + "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/drivers/overlay/ovmanager" - "github.com/docker/docker/libnetwork/drivers/remote" "github.com/moby/swarmkit/v2/manager/allocator/networkallocator" ) -var initializers = []initializer{ - {remote.Init, "remote"}, - {ovmanager.Init, "overlay"}, +var initializers = map[string]func(driverapi.Registerer) error{ + "overlay": ovmanager.Register, } // PredefinedNetworks returns the list of predefined network structures diff --git a/manager/allocator/cnmallocator/drivers_ipam.go b/manager/allocator/cnmallocator/drivers_ipam.go index 1b9617d31e..61b8614e2e 100644 --- a/manager/allocator/cnmallocator/drivers_ipam.go +++ b/manager/allocator/cnmallocator/drivers_ipam.go @@ -4,16 +4,14 @@ import ( "strconv" "strings" - "github.com/docker/docker/libnetwork/drvregistry" "github.com/docker/docker/libnetwork/ipamapi" builtinIpam "github.com/docker/docker/libnetwork/ipams/builtin" nullIpam "github.com/docker/docker/libnetwork/ipams/null" - remoteIpam "github.com/docker/docker/libnetwork/ipams/remote" "github.com/docker/docker/libnetwork/ipamutils" "github.com/sirupsen/logrus" ) -func initIPAMDrivers(r *drvregistry.DrvRegistry, netConfig *NetworkConfig) error { +func initIPAMDrivers(r ipamapi.Registerer, netConfig *NetworkConfig) error { var addressPool []*ipamutils.NetworkToSplit var str strings.Builder str.WriteString("Subnetlist - ") @@ -40,12 +38,11 @@ func initIPAMDrivers(r *drvregistry.DrvRegistry, netConfig *NetworkConfig) error logrus.Infof("Swarm initialized global default address pool to: " + str.String()) } - for _, fn := range [](func(ipamapi.Callback, interface{}, interface{}) error){ - builtinIpam.Init, - remoteIpam.Init, - nullIpam.Init, + for _, fn := range [](func(ipamapi.Registerer) error){ + builtinIpam.Register, + nullIpam.Register, } { - if err := fn(r, nil, nil); err != nil { + if err := fn(r); err != nil { return err } } diff --git a/manager/allocator/cnmallocator/drivers_network_linux.go b/manager/allocator/cnmallocator/drivers_network_linux.go index 5ae9196977..34268bfe60 100644 --- a/manager/allocator/cnmallocator/drivers_network_linux.go +++ b/manager/allocator/cnmallocator/drivers_network_linux.go @@ -1,22 +1,21 @@ package cnmallocator import ( + "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/drivers/bridge/brmanager" "github.com/docker/docker/libnetwork/drivers/host" "github.com/docker/docker/libnetwork/drivers/ipvlan/ivmanager" "github.com/docker/docker/libnetwork/drivers/macvlan/mvmanager" "github.com/docker/docker/libnetwork/drivers/overlay/ovmanager" - "github.com/docker/docker/libnetwork/drivers/remote" "github.com/moby/swarmkit/v2/manager/allocator/networkallocator" ) -var initializers = []initializer{ - {remote.Init, "remote"}, - {ovmanager.Init, "overlay"}, - {mvmanager.Init, "macvlan"}, - {brmanager.Init, "bridge"}, - {ivmanager.Init, "ipvlan"}, - {host.Init, "host"}, +var initializers = map[string]func(driverapi.Registerer) error{ + "overlay": ovmanager.Register, + "macvlan": mvmanager.Register, + "bridge": brmanager.Register, + "ipvlan": ivmanager.Register, + "host": host.Register, } // PredefinedNetworks returns the list of predefined network structures diff --git a/manager/allocator/cnmallocator/drivers_network_windows.go b/manager/allocator/cnmallocator/drivers_network_windows.go index abc6c44aac..7d4724a6d2 100644 --- a/manager/allocator/cnmallocator/drivers_network_windows.go +++ b/manager/allocator/cnmallocator/drivers_network_windows.go @@ -1,17 +1,16 @@ package cnmallocator import ( + "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/drivers/overlay/ovmanager" - "github.com/docker/docker/libnetwork/drivers/remote" "github.com/moby/swarmkit/v2/manager/allocator/networkallocator" ) -var initializers = []initializer{ - {remote.Init, "remote"}, - {ovmanager.Init, "overlay"}, - {StubManagerInit("internal"), "internal"}, - {StubManagerInit("l2bridge"), "l2bridge"}, - {StubManagerInit("nat"), "nat"}, +var initializers = map[string]func(driverapi.Registerer) error{ + "overlay": ovmanager.Register, + "internal": stubManager("internal"), + "l2bridge": stubManager("l2bridge"), + "nat": stubManager("nat"), } // PredefinedNetworks returns the list of predefined network structures @@ -20,3 +19,9 @@ func PredefinedNetworks() []networkallocator.PredefinedNetworkData { {Name: "nat", Driver: "nat"}, } } + +func stubManager(ntype string) func(driverapi.Registerer) error { + return func(r driverapi.Registerer) error { + return RegisterManager(r, ntype) + } +} diff --git a/manager/allocator/cnmallocator/manager.go b/manager/allocator/cnmallocator/manager.go index bfc0e9a7af..985f30e1f9 100644 --- a/manager/allocator/cnmallocator/manager.go +++ b/manager/allocator/cnmallocator/manager.go @@ -11,19 +11,12 @@ type manager struct { networkType string } -func StubManagerInit(networkType string) func(dc driverapi.DriverCallback, config map[string]interface{}) error { - return func(dc driverapi.DriverCallback, config map[string]interface{}) error { - return RegisterManager(dc, networkType) - } -} - -// Register registers a new instance of the manager driver for networkType with r. -func RegisterManager(r driverapi.DriverCallback, networkType string) error { - c := driverapi.Capability{ +// RegisterManager registers a new instance of the manager driver for networkType with r. +func RegisterManager(r driverapi.Registerer, networkType string) error { + return r.RegisterDriver(networkType, &manager{networkType: networkType}, driverapi.Capability{ DataScope: datastore.LocalScope, ConnectivityScope: datastore.LocalScope, - } - return r.RegisterDriver(networkType, &manager{networkType: networkType}, c) + }) } func (d *manager) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { diff --git a/manager/allocator/cnmallocator/networkallocator.go b/manager/allocator/cnmallocator/networkallocator.go index 9aae338fa2..ee9ae9b1c1 100644 --- a/manager/allocator/cnmallocator/networkallocator.go +++ b/manager/allocator/cnmallocator/networkallocator.go @@ -8,8 +8,10 @@ import ( "github.com/docker/docker/libnetwork/datastore" "github.com/docker/docker/libnetwork/driverapi" + "github.com/docker/docker/libnetwork/drivers/remote" "github.com/docker/docker/libnetwork/drvregistry" "github.com/docker/docker/libnetwork/ipamapi" + remoteipam "github.com/docker/docker/libnetwork/ipams/remote" "github.com/docker/docker/libnetwork/netlabel" "github.com/docker/docker/pkg/plugingetter" "github.com/moby/swarmkit/v2/api" @@ -30,9 +32,14 @@ const ( // like managing network and IPAM drivers and also creating and // deleting networks and the associated resources. type cnmNetworkAllocator struct { - // The driver register which manages all internal and external - // IPAM and network drivers. - drvRegistry *drvregistry.DrvRegistry + // The plugin getter instance used to get network and IPAM driver plugins. + pg plugingetter.PluginGetter + + // The driver registry for all internal and external IPAM drivers. + ipamRegistry drvregistry.IPAMs + + // The driver registry for all internal and external network drivers. + networkRegistry drvregistry.Networks // The port allocator instance for allocating node ports portAllocator *portAllocator @@ -81,11 +88,6 @@ type networkDriver struct { capability *driverapi.Capability } -type initializer struct { - fn drvregistry.InitFunc - ntype string -} - // NetworkConfig is used to store network related cluster config in the Manager. type NetworkConfig struct { // DefaultAddrPool specifies default subnet pool for global scope networks @@ -106,22 +108,24 @@ func New(pg plugingetter.PluginGetter, netConfig *NetworkConfig) (networkallocat services: make(map[string]struct{}), tasks: make(map[string]struct{}), nodes: make(map[string]map[string]struct{}), + pg: pg, } - // There are no driver configurations and notification - // functions as of now. - reg, err := drvregistry.New(nil, nil, nil, nil, pg) - if err != nil { - return nil, err + for ntype, i := range initializers { + if err := i(&na.networkRegistry); err != nil { + return nil, fmt.Errorf("failed to register %q network driver: %w", ntype, err) + } } - - if err := initializeDrivers(reg); err != nil { - return nil, err + if err := remote.Register(&na.networkRegistry, pg); err != nil { + return nil, fmt.Errorf("failed to initialize network driver plugins: %w", err) } - if err = initIPAMDrivers(reg, netConfig); err != nil { + if err := initIPAMDrivers(&na.ipamRegistry, netConfig); err != nil { return nil, err } + if err := remoteipam.Register(&na.ipamRegistry, pg); err != nil { + return nil, fmt.Errorf("failed to initialize IPAM driver plugins: %w", err) + } pa, err := newPortAllocator() if err != nil { @@ -129,7 +133,6 @@ func New(pg plugingetter.PluginGetter, netConfig *NetworkConfig) (networkallocat } na.portAllocator = pa - na.drvRegistry = reg return na, nil } @@ -816,28 +819,27 @@ func (na *cnmNetworkAllocator) resolveDriver(n *api.Network) (*networkDriver, er dName = n.Spec.DriverConfig.Name } - d, drvcap := na.drvRegistry.Driver(dName) + d, drvcap := na.networkRegistry.Driver(dName) if d == nil { err := na.loadDriver(dName) if err != nil { return nil, err } - d, drvcap = na.drvRegistry.Driver(dName) + d, drvcap = na.networkRegistry.Driver(dName) if d == nil { return nil, fmt.Errorf("could not resolve network driver %s", dName) } } - return &networkDriver{driver: d, capability: drvcap, name: dName}, nil + return &networkDriver{driver: d, capability: &drvcap, name: dName}, nil } func (na *cnmNetworkAllocator) loadDriver(name string) error { - pg := na.drvRegistry.GetPluginGetter() - if pg == nil { + if na.pg == nil { return errors.New("plugin store is uninitialized") } - _, err := pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup) + _, err := na.pg.Get(name, driverapi.NetworkPluginEndpointType, plugingetter.Lookup) return err } @@ -853,7 +855,7 @@ func (na *cnmNetworkAllocator) resolveIPAM(n *api.Network) (ipamapi.Ipam, string dOptions = n.Spec.IPAM.Driver.Options } - ipam, _ := na.drvRegistry.IPAM(dName) + ipam, _ := na.ipamRegistry.IPAM(dName) if ipam == nil { return nil, "", nil, fmt.Errorf("could not resolve IPAM driver %s", dName) } @@ -893,7 +895,7 @@ func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string, // We don't support user defined address spaces yet so just // retrieve default address space names for the driver. - _, asName, err := na.drvRegistry.IPAMDefaultAddressSpaces(dName) + _, asName, err := ipam.GetDefaultAddressSpaces() if err != nil { return nil, err } @@ -978,15 +980,6 @@ func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string, return pools, nil } -func initializeDrivers(reg *drvregistry.DrvRegistry) error { - for _, i := range initializers { - if err := reg.AddDriver(i.ntype, i.fn, nil); err != nil { - return err - } - } - return nil -} - func serviceNetworks(s *api.Service) []*api.NetworkAttachmentConfig { // Always prefer NetworkAttachmentConfig in the TaskSpec if len(s.Spec.Task.Networks) == 0 && len(s.Spec.Networks) != 0 { @@ -1011,12 +1004,8 @@ func (na *cnmNetworkAllocator) IsVIPOnIngressNetwork(vip *api.Endpoint_VirtualIP // IsBuiltInDriver returns whether the passed driver is an internal network driver func IsBuiltInDriver(name string) bool { n := strings.ToLower(name) - for _, d := range initializers { - if n == d.ntype { - return true - } - } - return false + _, ok := initializers[n] + return ok } // setIPAMSerialAlloc sets the ipam allocation method to serial diff --git a/manager/allocator/cnmallocator/networkallocator_test.go b/manager/allocator/cnmallocator/networkallocator_test.go index 5b0f028c2f..0d2c306860 100644 --- a/manager/allocator/cnmallocator/networkallocator_test.go +++ b/manager/allocator/cnmallocator/networkallocator_test.go @@ -982,7 +982,7 @@ func TestCorrectlyPassIPAMOptions(t *testing.T) { na := newNetworkAllocator(t) ipamDriver := &mockIpam{} - err = na.(*cnmNetworkAllocator).drvRegistry.RegisterIpamDriver("mockipam", ipamDriver) + err = na.(*cnmNetworkAllocator).ipamRegistry.RegisterIpamDriver("mockipam", ipamDriver) assert.NoError(t, err) n := &api.Network{ diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index f761a30708..0ad0b1c076 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -804,6 +804,12 @@ definitions: 1000000 (1 ms). 0 means inherit. type: "integer" format: "int64" + StartInterval: + description: | + The time to wait between checks in nanoseconds during the start period. + It should be 0 or at least 1000000 (1 ms). 0 means inherit. + type: "integer" + format: "int64" Health: description: | @@ -5161,42 +5167,8 @@ definitions: ServerVersion: description: | Version string of the daemon. - - > **Note**: the [standalone Swarm API](https://docs.docker.com/swarm/swarm-api/) - > returns the Swarm version instead of the daemon version, for example - > `swarm/1.2.8`. - type: "string" - example: "17.06.0-ce" - ClusterStore: - description: | - URL of the distributed storage backend. - - - The storage backend is used for multihost networking (to store - network and endpoint information) and by the node discovery mechanism. - -


- - > **Deprecated**: This field is only propagated when using standalone Swarm - > mode, and overlay networking using an external k/v store. Overlay - > networks with Swarm mode enabled use the built-in raft store, and - > this field will be empty. type: "string" - example: "consul://consul.corp.example.com:8600/some/path" - ClusterAdvertise: - description: | - The network endpoint that the Engine advertises for the purpose of - node discovery. ClusterAdvertise is a `host:port` combination on which - the daemon is reachable by other hosts. - -


- - > **Deprecated**: This field is only propagated when using standalone Swarm - > mode, and overlay networking using an external k/v store. Overlay - > networks with Swarm mode enabled use the built-in raft store, and - > this field will be empty. - type: "string" - example: "node5.corp.example.com:8000" + example: "24.0.2" Runtimes: description: | List of [OCI compliant](https://github.com/opencontainers/runtime-spec) @@ -10391,6 +10363,12 @@ paths: default if omitted. required: true type: "string" + - name: "force" + in: "query" + description: | + Force disable a plugin even if still in use. + required: false + type: "boolean" tags: ["Plugin"] /plugins/{name}/upgrade: post: diff --git a/vendor/github.com/docker/docker/api/types/container/config.go b/vendor/github.com/docker/docker/api/types/container/config.go index 077583e66c..8776dfbf36 100644 --- a/vendor/github.com/docker/docker/api/types/container/config.go +++ b/vendor/github.com/docker/docker/api/types/container/config.go @@ -44,9 +44,10 @@ type HealthConfig struct { Test []string `json:",omitempty"` // Zero means to inherit. Durations are expressed as integer nanoseconds. - Interval time.Duration `json:",omitempty"` // Interval is the time to wait between checks. - Timeout time.Duration `json:",omitempty"` // Timeout is the time to wait before considering the check to have hung. - StartPeriod time.Duration `json:",omitempty"` // The start period for the container to initialize before the retries starts to count down. + Interval time.Duration `json:",omitempty"` // Interval is the time to wait between checks. + Timeout time.Duration `json:",omitempty"` // Timeout is the time to wait before considering the check to have hung. + StartPeriod time.Duration `json:",omitempty"` // The start period for the container to initialize before the retries starts to count down. + StartInterval time.Duration `json:",omitempty"` // The interval to attempt healthchecks at during the start period // Retries is the number of consecutive failures needed to consider a container as unhealthy. // Zero means inherit. diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index 60bc14c1aa..02cc394bc8 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -307,6 +307,9 @@ type Info struct { ProductLicense string `json:",omitempty"` DefaultAddressPools []NetworkAddressPool `json:",omitempty"` + // Legacy API fields for older API versions. + legacyFields + // Warnings contains a slice of warnings that occurred while collecting // system information. These warnings are intended to be informational // messages for the user, and are not intended to be parsed / used for @@ -314,6 +317,10 @@ type Info struct { Warnings []string } +type legacyFields struct { + ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions. +} + // KeyValue holds a key/value pair type KeyValue struct { Key, Value string diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index 193a2bb562..14a2127d88 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -29,6 +29,9 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil { return response, err } + if err := cli.NewVersionError("1.44", "specify health-check start interval"); config != nil && config.Healthcheck != nil && config.Healthcheck.StartInterval != 0 && err != nil { + return response, err + } if hostConfig != nil { if versions.LessThan(cli.ClientVersion(), "1.25") { diff --git a/vendor/github.com/docker/docker/libnetwork/bitmap/sequence.go b/vendor/github.com/docker/docker/libnetwork/bitmap/sequence.go index 9dc11384e9..2644c5d354 100644 --- a/vendor/github.com/docker/docker/libnetwork/bitmap/sequence.go +++ b/vendor/github.com/docker/docker/libnetwork/bitmap/sequence.go @@ -47,7 +47,7 @@ type Bitmap struct { noCopy noCopy } -// NewHandle returns a new Bitmap n bits long. +// NewHandle returns a new Bitmap of ordinals in the interval [0, n). func New(n uint64) *Bitmap { return &Bitmap{ bits: n, @@ -176,7 +176,7 @@ func (s *sequence) fromByteArray(data []byte) error { return nil } -// SetAnyInRange sets the first unset bit in the range [start, end) and returns +// SetAnyInRange sets the first unset bit in the range [start, end] and returns // the ordinal of the set bit. // // When serial=true, the bitmap is scanned starting from the ordinal following diff --git a/vendor/github.com/docker/docker/libnetwork/bitseq/sequence.go b/vendor/github.com/docker/docker/libnetwork/bitseq/sequence.go deleted file mode 100644 index b78dae0492..0000000000 --- a/vendor/github.com/docker/docker/libnetwork/bitseq/sequence.go +++ /dev/null @@ -1,213 +0,0 @@ -// Package bitseq provides a structure and utilities for representing a long -// bitmask which is persisted in a datastore. It is backed by [bitmap.Bitmap] -// which operates directly on the encoded representation, without uncompressing. -package bitseq - -import ( - "encoding/json" - "fmt" - "sync" - - "github.com/docker/docker/libnetwork/bitmap" - "github.com/docker/docker/libnetwork/datastore" - "github.com/docker/docker/libnetwork/types" -) - -var ( - // ErrNoBitAvailable is returned when no more bits are available to set - ErrNoBitAvailable = bitmap.ErrNoBitAvailable - // ErrBitAllocated is returned when the specific bit requested is already set - ErrBitAllocated = bitmap.ErrBitAllocated -) - -// Handle contains the sequence representing the bitmask and its identifier -type Handle struct { - app string - id string - dbIndex uint64 - dbExists bool - store datastore.DataStore - bm *bitmap.Bitmap - mu sync.Mutex -} - -// NewHandle returns a thread-safe instance of the bitmask handler -func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64) (*Handle, error) { - h := &Handle{ - bm: bitmap.New(numElements), - app: app, - id: id, - store: ds, - } - - if h.store == nil { - return h, nil - } - - // Get the initial status from the ds if present. - if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound { - return nil, err - } - - // If the handle is not in store, write it. - if !h.Exists() { - if err := h.writeToStore(); err != nil { - return nil, fmt.Errorf("failed to write bitsequence to store: %v", err) - } - } - - return h, nil -} - -func (h *Handle) getCopy() *Handle { - return &Handle{ - bm: bitmap.Copy(h.bm), - app: h.app, - id: h.id, - dbIndex: h.dbIndex, - dbExists: h.dbExists, - store: h.store, - } -} - -// SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal -func (h *Handle) SetAnyInRange(start, end uint64, serial bool) (uint64, error) { - return h.apply(func(b *bitmap.Bitmap) (uint64, error) { return b.SetAnyInRange(start, end, serial) }) -} - -// SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal -func (h *Handle) SetAny(serial bool) (uint64, error) { - return h.apply(func(b *bitmap.Bitmap) (uint64, error) { return b.SetAny(serial) }) -} - -// Set atomically sets the corresponding bit in the sequence -func (h *Handle) Set(ordinal uint64) error { - _, err := h.apply(func(b *bitmap.Bitmap) (uint64, error) { return 0, b.Set(ordinal) }) - return err -} - -// Unset atomically unsets the corresponding bit in the sequence -func (h *Handle) Unset(ordinal uint64) error { - _, err := h.apply(func(b *bitmap.Bitmap) (uint64, error) { return 0, b.Unset(ordinal) }) - return err -} - -// IsSet atomically checks if the ordinal bit is set. In case ordinal -// is outside of the bit sequence limits, false is returned. -func (h *Handle) IsSet(ordinal uint64) bool { - h.mu.Lock() - defer h.mu.Unlock() - return h.bm.IsSet(ordinal) -} - -// set/reset the bit -func (h *Handle) apply(op func(*bitmap.Bitmap) (uint64, error)) (uint64, error) { - for { - var store datastore.DataStore - h.mu.Lock() - store = h.store - if store != nil { - h.mu.Unlock() // The lock is acquired in the GetObject - if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound { - return 0, err - } - h.mu.Lock() // Acquire the lock back - } - - // Create a private copy of h and work on it - nh := h.getCopy() - - ret, err := op(nh.bm) - if err != nil { - h.mu.Unlock() - return ret, err - } - - if h.store != nil { - h.mu.Unlock() - // Attempt to write private copy to store - if err := nh.writeToStore(); err != nil { - if _, ok := err.(types.RetryError); !ok { - return ret, fmt.Errorf("internal failure while setting the bit: %v", err) - } - // Retry - continue - } - h.mu.Lock() - } - - // Previous atomic push was successful. Save private copy to local copy - h.bm = nh.bm - h.dbExists = nh.dbExists - h.dbIndex = nh.dbIndex - h.mu.Unlock() - return ret, nil - } -} - -// Destroy removes from the datastore the data belonging to this handle -func (h *Handle) Destroy() error { - for { - if err := h.deleteFromStore(); err != nil { - if _, ok := err.(types.RetryError); !ok { - return fmt.Errorf("internal failure while destroying the sequence: %v", err) - } - // Fetch latest - if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil { - if err == datastore.ErrKeyNotFound { // already removed - return nil - } - return fmt.Errorf("failed to fetch from store when destroying the sequence: %v", err) - } - continue - } - return nil - } -} - -// Bits returns the length of the bit sequence -func (h *Handle) Bits() uint64 { - h.mu.Lock() - defer h.mu.Unlock() - return h.bm.Bits() -} - -// Unselected returns the number of bits which are not selected -func (h *Handle) Unselected() uint64 { - h.mu.Lock() - defer h.mu.Unlock() - return h.bm.Unselected() -} - -func (h *Handle) String() string { - h.mu.Lock() - defer h.mu.Unlock() - return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, %s", - h.app, h.id, h.dbIndex, h.bm) -} - -type jsonMessage struct { - ID string `json:"id"` - Sequence *bitmap.Bitmap `json:"sequence"` -} - -// MarshalJSON encodes h into a JSON message. -func (h *Handle) MarshalJSON() ([]byte, error) { - h.mu.Lock() - defer h.mu.Unlock() - m := jsonMessage{ID: h.id, Sequence: h.bm} - return json.Marshal(m) -} - -// UnmarshalJSON decodes a JSON message into h. -func (h *Handle) UnmarshalJSON(data []byte) error { - var m jsonMessage - if err := json.Unmarshal(data, &m); err != nil { - return err - } - - h.mu.Lock() - defer h.mu.Unlock() - h.id, h.bm = m.ID, m.Sequence - return nil -} diff --git a/vendor/github.com/docker/docker/libnetwork/bitseq/store.go b/vendor/github.com/docker/docker/libnetwork/bitseq/store.go deleted file mode 100644 index edcee5e5be..0000000000 --- a/vendor/github.com/docker/docker/libnetwork/bitseq/store.go +++ /dev/null @@ -1,128 +0,0 @@ -package bitseq - -import ( - "encoding/json" - - "github.com/docker/docker/libnetwork/bitmap" - "github.com/docker/docker/libnetwork/datastore" - "github.com/docker/docker/libnetwork/types" -) - -// Key provides the Key to be used in KV Store -func (h *Handle) Key() []string { - h.mu.Lock() - defer h.mu.Unlock() - return []string{h.app, h.id} -} - -// KeyPrefix returns the immediate parent key that can be used for tree walk -func (h *Handle) KeyPrefix() []string { - h.mu.Lock() - defer h.mu.Unlock() - return []string{h.app} -} - -// Value marshals the data to be stored in the KV store -func (h *Handle) Value() []byte { - b, err := json.Marshal(h) - if err != nil { - return nil - } - return b -} - -// SetValue unmarshals the data from the KV store -func (h *Handle) SetValue(value []byte) error { - return json.Unmarshal(value, h) -} - -// Index returns the latest DB Index as seen by this object -func (h *Handle) Index() uint64 { - h.mu.Lock() - defer h.mu.Unlock() - return h.dbIndex -} - -// SetIndex method allows the datastore to store the latest DB Index into this object -func (h *Handle) SetIndex(index uint64) { - h.mu.Lock() - h.dbIndex = index - h.dbExists = true - h.mu.Unlock() -} - -// Exists method is true if this object has been stored in the DB. -func (h *Handle) Exists() bool { - h.mu.Lock() - defer h.mu.Unlock() - return h.dbExists -} - -// New method returns a handle based on the receiver handle -func (h *Handle) New() datastore.KVObject { - h.mu.Lock() - defer h.mu.Unlock() - - return &Handle{ - app: h.app, - store: h.store, - } -} - -// CopyTo deep copies the handle into the passed destination object -func (h *Handle) CopyTo(o datastore.KVObject) error { - h.mu.Lock() - defer h.mu.Unlock() - - dstH := o.(*Handle) - if h == dstH { - return nil - } - dstH.mu.Lock() - defer dstH.mu.Unlock() - dstH.bm = bitmap.Copy(h.bm) - dstH.app = h.app - dstH.id = h.id - dstH.dbIndex = h.dbIndex - dstH.dbExists = h.dbExists - dstH.store = h.store - - return nil -} - -// Skip provides a way for a KV Object to avoid persisting it in the KV Store -func (h *Handle) Skip() bool { - return false -} - -// DataScope method returns the storage scope of the datastore -func (h *Handle) DataScope() string { - h.mu.Lock() - defer h.mu.Unlock() - - return h.store.Scope() -} - -func (h *Handle) writeToStore() error { - h.mu.Lock() - store := h.store - h.mu.Unlock() - if store == nil { - return nil - } - err := store.PutObjectAtomic(h) - if err == datastore.ErrKeyModified { - return types.RetryErrorf("failed to perform atomic write (%v). Retry might fix the error", err) - } - return err -} - -func (h *Handle) deleteFromStore() error { - h.mu.Lock() - store := h.store - h.mu.Unlock() - if store == nil { - return nil - } - return store.DeleteObjectAtomic(h) -} diff --git a/vendor/github.com/docker/docker/libnetwork/datastore/cache.go b/vendor/github.com/docker/docker/libnetwork/datastore/cache.go index f001fc8138..61bc67e8ac 100644 --- a/vendor/github.com/docker/docker/libnetwork/datastore/cache.go +++ b/vendor/github.com/docker/docker/libnetwork/datastore/cache.go @@ -138,7 +138,7 @@ func (c *cache) del(kvObject KVObject, atomic bool) error { return nil } -func (c *cache) get(key string, kvObject KVObject) error { +func (c *cache) get(kvObject KVObject) error { kmap, err := c.kmap(kvObject) if err != nil { return err diff --git a/vendor/github.com/docker/docker/libnetwork/datastore/datastore.go b/vendor/github.com/docker/docker/libnetwork/datastore/datastore.go index b7963f04d6..f1456616b0 100644 --- a/vendor/github.com/docker/docker/libnetwork/datastore/datastore.go +++ b/vendor/github.com/docker/docker/libnetwork/datastore/datastore.go @@ -2,7 +2,6 @@ package datastore import ( "fmt" - "log" "reflect" "strings" "sync" @@ -17,24 +16,10 @@ import ( type DataStore interface { // GetObject gets data from datastore and unmarshals to the specified object GetObject(key string, o KVObject) error - // PutObject adds a new Record based on an object into the datastore - PutObject(kvObject KVObject) error // PutObjectAtomic provides an atomic add and update operation for a Record PutObjectAtomic(kvObject KVObject) error - // DeleteObject deletes a record - DeleteObject(kvObject KVObject) error // DeleteObjectAtomic performs an atomic delete operation DeleteObjectAtomic(kvObject KVObject) error - // DeleteTree deletes a record - DeleteTree(kvObject KVObject) error - // Watchable returns whether the store is watchable or not - Watchable() bool - // Watch for changes on a KVObject - Watch(kvObject KVObject, stopCh <-chan struct{}) (<-chan KVObject, error) - // RestartWatch retriggers stopped Watches - RestartWatch() - // Active returns if the store is active - Active() bool // List returns of a list of KVObjects belonging to the parent // key. The caller must pass a KVObject of the same type as // the objects that need to be listed @@ -56,13 +41,10 @@ var ( ) type datastore struct { - scope string - store store.Store - cache *cache - watchCh chan struct{} - active bool - sequential bool - sync.Mutex + mu sync.Mutex + scope string + store store.Store + cache *cache } // KVObject is Key/Value interface used by objects to be part of the DataStore @@ -210,7 +192,7 @@ func newClient(kv string, addr string, config *store.Config) (DataStore, error) return nil, err } - ds := &datastore{scope: LocalScope, store: s, active: true, watchCh: make(chan struct{}), sequential: true} + ds := &datastore{scope: LocalScope, store: s} ds.cache = newCache(ds) return ds, nil @@ -261,91 +243,6 @@ func (ds *datastore) Scope() string { return ds.scope } -func (ds *datastore) Active() bool { - return ds.active -} - -func (ds *datastore) Watchable() bool { - return ds.scope != LocalScope -} - -func (ds *datastore) Watch(kvObject KVObject, stopCh <-chan struct{}) (<-chan KVObject, error) { - sCh := make(chan struct{}) - - ctor, ok := kvObject.(KVConstructor) - if !ok { - return nil, fmt.Errorf("error watching object type %T, object does not implement KVConstructor interface", kvObject) - } - - kvpCh, err := ds.store.Watch(Key(kvObject.Key()...), sCh) - if err != nil { - return nil, err - } - - kvoCh := make(chan KVObject) - - go func() { - retry_watch: - var err error - - // Make sure to get a new instance of watch channel - ds.Lock() - watchCh := ds.watchCh - ds.Unlock() - - loop: - for { - select { - case <-stopCh: - close(sCh) - return - case kvPair := <-kvpCh: - // If the backend KV store gets reset libkv's go routine - // for the watch can exit resulting in a nil value in - // channel. - if kvPair == nil { - ds.Lock() - ds.active = false - ds.Unlock() - break loop - } - - dstO := ctor.New() - - if err = dstO.SetValue(kvPair.Value); err != nil { - log.Printf("Could not unmarshal kvpair value = %s", string(kvPair.Value)) - break - } - - dstO.SetIndex(kvPair.LastIndex) - kvoCh <- dstO - } - } - - // Wait on watch channel for a re-trigger when datastore becomes active - <-watchCh - - kvpCh, err = ds.store.Watch(Key(kvObject.Key()...), sCh) - if err != nil { - log.Printf("Could not watch the key %s in store: %v", Key(kvObject.Key()...), err) - } - - goto retry_watch - }() - - return kvoCh, nil -} - -func (ds *datastore) RestartWatch() { - ds.Lock() - defer ds.Unlock() - - ds.active = true - watchCh := ds.watchCh - ds.watchCh = make(chan struct{}) - close(watchCh) -} - func (ds *datastore) KVStore() store.Store { return ds.store } @@ -357,10 +254,8 @@ func (ds *datastore) PutObjectAtomic(kvObject KVObject) error { pair *store.KVPair err error ) - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } + ds.mu.Lock() + defer ds.mu.Unlock() if kvObject == nil { return types.BadRequestErrorf("invalid KV Object : nil") @@ -382,7 +277,7 @@ func (ds *datastore) PutObjectAtomic(kvObject KVObject) error { previous = nil } - _, pair, err = ds.store.AtomicPut(Key(kvObject.Key()...), kvObjValue, previous, nil) + pair, err = ds.store.AtomicPut(Key(kvObject.Key()...), kvObjValue, previous) if err != nil { if err == store.ErrKeyExists { return ErrKeyModified @@ -402,53 +297,13 @@ add_cache: return nil } -// PutObject adds a new Record based on an object into the datastore -func (ds *datastore) PutObject(kvObject KVObject) error { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } - - if kvObject == nil { - return types.BadRequestErrorf("invalid KV Object : nil") - } - - if kvObject.Skip() { - goto add_cache - } - - if err := ds.putObjectWithKey(kvObject, kvObject.Key()...); err != nil { - return err - } - -add_cache: - if ds.cache != nil { - // If persistent store is skipped, sequencing needs to - // happen in cache. - return ds.cache.add(kvObject, kvObject.Skip()) - } - - return nil -} - -func (ds *datastore) putObjectWithKey(kvObject KVObject, key ...string) error { - kvObjValue := kvObject.Value() - - if kvObjValue == nil { - return types.BadRequestErrorf("invalid KV Object with a nil Value for key %s", Key(kvObject.Key()...)) - } - return ds.store.Put(Key(key...), kvObjValue, nil) -} - // GetObject returns a record matching the key func (ds *datastore) GetObject(key string, o KVObject) error { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } + ds.mu.Lock() + defer ds.mu.Unlock() if ds.cache != nil { - return ds.cache.get(key, o) + return ds.cache.get(o) } kvPair, err := ds.store.Get(key) @@ -474,14 +329,12 @@ func (ds *datastore) ensureParent(parent string) error { if exists { return nil } - return ds.store.Put(parent, []byte{}, &store.WriteOptions{IsDir: true}) + return ds.store.Put(parent, []byte{}) } func (ds *datastore) List(key string, kvObject KVObject) ([]KVObject, error) { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } + ds.mu.Lock() + defer ds.mu.Unlock() if ds.cache != nil { return ds.cache.list(kvObject) @@ -535,10 +388,8 @@ func (ds *datastore) iterateKVPairsFromStore(key string, kvObject KVObject, call } func (ds *datastore) Map(key string, kvObject KVObject) (map[string]KVObject, error) { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } + ds.mu.Lock() + defer ds.mu.Unlock() kvol := make(map[string]KVObject) cb := func(key string, val KVObject) { @@ -552,33 +403,10 @@ func (ds *datastore) Map(key string, kvObject KVObject) (map[string]KVObject, er return kvol, nil } -// DeleteObject unconditionally deletes a record from the store -func (ds *datastore) DeleteObject(kvObject KVObject) error { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } - - // cleanup the cache first - if ds.cache != nil { - // If persistent store is skipped, sequencing needs to - // happen in cache. - ds.cache.del(kvObject, kvObject.Skip()) - } - - if kvObject.Skip() { - return nil - } - - return ds.store.Delete(Key(kvObject.Key()...)) -} - // DeleteObjectAtomic performs atomic delete on a record func (ds *datastore) DeleteObjectAtomic(kvObject KVObject) error { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } + ds.mu.Lock() + defer ds.mu.Unlock() if kvObject == nil { return types.BadRequestErrorf("invalid KV Object : nil") @@ -590,7 +418,7 @@ func (ds *datastore) DeleteObjectAtomic(kvObject KVObject) error { goto del_cache } - if _, err := ds.store.AtomicDelete(Key(kvObject.Key()...), previous); err != nil { + if err := ds.store.AtomicDelete(Key(kvObject.Key()...), previous); err != nil { if err == store.ErrKeyExists { return ErrKeyModified } @@ -607,24 +435,3 @@ del_cache: return nil } - -// DeleteTree unconditionally deletes a record from the store -func (ds *datastore) DeleteTree(kvObject KVObject) error { - if ds.sequential { - ds.Lock() - defer ds.Unlock() - } - - // cleanup the cache first - if ds.cache != nil { - // If persistent store is skipped, sequencing needs to - // happen in cache. - ds.cache.del(kvObject, kvObject.Skip()) - } - - if kvObject.Skip() { - return nil - } - - return ds.store.DeleteTree(Key(kvObject.KeyPrefix()...)) -} diff --git a/vendor/github.com/docker/docker/libnetwork/datastore/mock_store.go b/vendor/github.com/docker/docker/libnetwork/datastore/mock_store.go index d6a513815f..9e7a0bb84b 100644 --- a/vendor/github.com/docker/docker/libnetwork/datastore/mock_store.go +++ b/vendor/github.com/docker/docker/libnetwork/datastore/mock_store.go @@ -38,7 +38,7 @@ func (s *MockStore) Get(key string) (*store.KVPair, error) { } // Put a value at "key" -func (s *MockStore) Put(key string, value []byte, options *store.WriteOptions) error { +func (s *MockStore) Put(key string, value []byte) error { mData := s.db[key] if mData == nil { mData = &MockData{value, 0} @@ -48,12 +48,6 @@ func (s *MockStore) Put(key string, value []byte, options *store.WriteOptions) e return nil } -// Delete a value at "key" -func (s *MockStore) Delete(key string) error { - delete(s.db, key) - return nil -} - // Exists checks that the key exists inside the store func (s *MockStore) Exists(key string) (bool, error) { _, ok := s.db[key] @@ -65,59 +59,38 @@ func (s *MockStore) List(prefix string) ([]*store.KVPair, error) { return nil, ErrNotImplemented } -// DeleteTree deletes a range of values at "directory" -func (s *MockStore) DeleteTree(prefix string) error { - delete(s.db, prefix) - return nil -} - -// Watch a single key for modifications -func (s *MockStore) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { - return nil, ErrNotImplemented -} - -// WatchTree triggers a watch on a range of values at "directory" -func (s *MockStore) WatchTree(prefix string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { - return nil, ErrNotImplemented -} - -// NewLock exposed -func (s *MockStore) NewLock(key string, options *store.LockOptions) (store.Locker, error) { - return nil, ErrNotImplemented -} - // AtomicPut put a value at "key" if the key has not been // modified in the meantime, throws an error if this is the case -func (s *MockStore) AtomicPut(key string, newValue []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) { +func (s *MockStore) AtomicPut(key string, newValue []byte, previous *store.KVPair) (*store.KVPair, error) { mData := s.db[key] if previous == nil { if mData != nil { - return false, nil, types.BadRequestErrorf("atomic put failed because key exists") + return nil, types.BadRequestErrorf("atomic put failed because key exists") } // Else OK. } else { if mData == nil { - return false, nil, types.BadRequestErrorf("atomic put failed because key exists") + return nil, types.BadRequestErrorf("atomic put failed because key exists") } if mData != nil && mData.Index != previous.LastIndex { - return false, nil, types.BadRequestErrorf("atomic put failed due to mismatched Index") + return nil, types.BadRequestErrorf("atomic put failed due to mismatched Index") } // Else OK. } - err := s.Put(key, newValue, nil) - if err != nil { - return false, nil, err + if err := s.Put(key, newValue); err != nil { + return nil, err } - return true, &store.KVPair{Key: key, Value: newValue, LastIndex: s.db[key].Index}, nil + return &store.KVPair{Key: key, Value: newValue, LastIndex: s.db[key].Index}, nil } // AtomicDelete deletes a value at "key" if the key has not // been modified in the meantime, throws an error if this is the case -func (s *MockStore) AtomicDelete(key string, previous *store.KVPair) (bool, error) { +func (s *MockStore) AtomicDelete(key string, previous *store.KVPair) error { mData := s.db[key] if mData != nil && mData.Index != previous.LastIndex { - return false, types.BadRequestErrorf("atomic delete failed due to mismatched Index") + return types.BadRequestErrorf("atomic delete failed due to mismatched Index") } - return true, s.Delete(key) + delete(s.db, key) + return nil } // Close closes the client connection diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/bridge/brmanager/brmanager.go b/vendor/github.com/docker/docker/libnetwork/drivers/bridge/brmanager/brmanager.go index 22922d8253..e90d6febf6 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/bridge/brmanager/brmanager.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/bridge/brmanager/brmanager.go @@ -15,11 +15,11 @@ type driver struct{} // // Deprecated: use [Register]. func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error { - return Register(dc, nil) + return Register(dc) } // Register registers a new instance of the bridge manager driver with r. -func Register(r driverapi.Registerer, _ map[string]interface{}) error { +func Register(r driverapi.Registerer) error { return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{ DataScope: datastore.LocalScope, ConnectivityScope: datastore.LocalScope, diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/host/host.go b/vendor/github.com/docker/docker/libnetwork/drivers/host/host.go index 9eb596ce14..ee9adbc4d8 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/host/host.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/host/host.go @@ -9,7 +9,7 @@ import ( "github.com/docker/docker/libnetwork/types" ) -const networkType = "host" +const NetworkType = "host" type driver struct { network string @@ -20,11 +20,11 @@ type driver struct { // // Deprecated: use [Register]. func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error { - return Register(dc, nil) + return Register(dc) } -func Register(r driverapi.Registerer, _ map[string]interface{}) error { - return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{ +func Register(r driverapi.Registerer) error { + return r.RegisterDriver(NetworkType, &driver{}, driverapi.Capability{ DataScope: datastore.LocalScope, ConnectivityScope: datastore.LocalScope, }) @@ -50,7 +50,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d defer d.Unlock() if d.network != "" { - return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", networkType) + return types.ForbiddenErrorf("only one instance of \"%s\" network is allowed", NetworkType) } d.network = id @@ -59,7 +59,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d } func (d *driver) DeleteNetwork(nid string) error { - return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", networkType) + return types.ForbiddenErrorf("network of type \"%s\" cannot be deleted", NetworkType) } func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error { @@ -93,7 +93,7 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error { } func (d *driver) Type() string { - return networkType + return NetworkType } func (d *driver) IsBuiltIn() bool { diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go b/vendor/github.com/docker/docker/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go index e7e5a285d2..d3d841ecb3 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go @@ -15,11 +15,11 @@ type driver struct{} // // Deprecated: use [Register]. func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error { - return Register(dc, nil) + return Register(dc) } // Register registers a new instance of the ipvlan manager driver. -func Register(r driverapi.Registerer, _ map[string]interface{}) error { +func Register(r driverapi.Registerer) error { return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{ DataScope: datastore.LocalScope, ConnectivityScope: datastore.GlobalScope, diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/macvlan/mvmanager/mvmanager.go b/vendor/github.com/docker/docker/libnetwork/drivers/macvlan/mvmanager/mvmanager.go index ba69cd933f..b490c6769e 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/macvlan/mvmanager/mvmanager.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/macvlan/mvmanager/mvmanager.go @@ -15,11 +15,11 @@ type driver struct{} // // Deprecated: use [Register]. func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error { - return Register(dc, nil) + return Register(dc) } // Register registers a new instance of the macvlan manager driver. -func Register(r driverapi.Registerer, _ map[string]interface{}) error { +func Register(r driverapi.Registerer) error { return r.RegisterDriver(networkType, &driver{}, driverapi.Capability{ DataScope: datastore.LocalScope, ConnectivityScope: datastore.GlobalScope, diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/overlay/overlayutils/utils.go b/vendor/github.com/docker/docker/libnetwork/drivers/overlay/overlayutils/utils.go index 2d7674a535..2ce3c237dc 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/overlay/overlayutils/utils.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/overlay/overlayutils/utils.go @@ -3,6 +3,8 @@ package overlayutils import ( "fmt" + "strconv" + "strings" "sync" ) @@ -40,3 +42,23 @@ func VXLANUDPPort() uint32 { defer mutex.RUnlock() return vxlanUDPPort } + +// AppendVNIList appends the VNI values encoded as a CSV string to slice. +func AppendVNIList(vnis []uint32, csv string) ([]uint32, error) { + for { + var ( + vniStr string + found bool + ) + vniStr, csv, found = strings.Cut(csv, ",") + vni, err := strconv.Atoi(vniStr) + if err != nil { + return vnis, fmt.Errorf("invalid vxlan id value %q passed", vniStr) + } + + vnis = append(vnis, uint32(vni)) + if !found { + return vnis, nil + } + } +} diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go b/vendor/github.com/docker/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go index 41b05eb95e..256de20207 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go @@ -5,30 +5,33 @@ import ( "fmt" "net" "strconv" - "strings" "sync" "github.com/containerd/containerd/log" + "github.com/docker/docker/libnetwork/bitmap" "github.com/docker/docker/libnetwork/datastore" "github.com/docker/docker/libnetwork/discoverapi" "github.com/docker/docker/libnetwork/driverapi" - "github.com/docker/docker/libnetwork/idm" + "github.com/docker/docker/libnetwork/drivers/overlay/overlayutils" "github.com/docker/docker/libnetwork/netlabel" "github.com/docker/docker/libnetwork/types" ) const ( - networkType = "overlay" + networkType = "overlay" + // The lowest VNI value to auto-assign. Windows does not support VXLAN IDs + // which overlap the range of 802.1Q VLAN IDs [0, 4095]. vxlanIDStart = 4096 - vxlanIDEnd = (1 << 24) - 1 + // The largest VNI value permitted by RFC 7348. + vxlanIDEnd = (1 << 24) - 1 ) type networkTable map[string]*network type driver struct { + mu sync.Mutex networks networkTable - vxlanIdm *idm.Idm - sync.Mutex + vxlanIdm *bitmap.Bitmap } type subnet struct { @@ -41,34 +44,30 @@ type network struct { id string driver *driver subnets []*subnet - sync.Mutex } // Init registers a new instance of the overlay driver. // // Deprecated: use [Register]. func Init(dc driverapi.DriverCallback, _ map[string]interface{}) error { - return Register(dc, nil) + return Register(dc) } // Register registers a new instance of the overlay driver. -func Register(r driverapi.Registerer, _ map[string]interface{}) error { - var err error - d := &driver{ - networks: networkTable{}, - } - - d.vxlanIdm, err = idm.New(nil, "vxlan-id", 0, vxlanIDEnd) - if err != nil { - return fmt.Errorf("failed to initialize vxlan id manager: %v", err) - } - - return r.RegisterDriver(networkType, d, driverapi.Capability{ +func Register(r driverapi.Registerer) error { + return r.RegisterDriver(networkType, newDriver(), driverapi.Capability{ DataScope: datastore.GlobalScope, ConnectivityScope: datastore.GlobalScope, }) } +func newDriver() *driver { + return &driver{ + networks: networkTable{}, + vxlanIdm: bitmap.New(vxlanIDEnd + 1), // The full range of valid vxlan IDs: [0, 2^24). + } +} + func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { if id == "" { return nil, fmt.Errorf("invalid network id for overlay network") @@ -89,33 +88,40 @@ func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, for key, val := range option { if key == netlabel.OverlayVxlanIDList { log.G(context.TODO()).Debugf("overlay network option: %s", val) - valStrList := strings.Split(val, ",") - for _, idStr := range valStrList { - vni, err := strconv.Atoi(idStr) - if err != nil { - return nil, fmt.Errorf("invalid vxlan id value %q passed", idStr) - } - - vxlanIDList = append(vxlanIDList, uint32(vni)) + var err error + vxlanIDList, err = overlayutils.AppendVNIList(vxlanIDList, val) + if err != nil { + return nil, err } } else { opts[key] = val } } + d.mu.Lock() + defer d.mu.Unlock() for i, ipd := range ipV4Data { s := &subnet{ subnetIP: ipd.Pool, gwIP: ipd.Gateway, } - if len(vxlanIDList) > i { + if len(vxlanIDList) > i { // The VNI for this subnet was specified in the network options. s.vni = vxlanIDList[i] - } - - if err := n.obtainVxlanID(s); err != nil { - n.releaseVxlanID() - return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err) + err := d.vxlanIdm.Set(uint64(s.vni)) // Mark VNI as in-use. + if err != nil { + // The VNI is already in use by another subnet/network. + n.releaseVxlanID() + return nil, fmt.Errorf("could not assign vxlan id %v to pool %s: %v", s.vni, s.subnetIP, err) + } + } else { + // Allocate an available VNI for the subnet, outside the range of 802.1Q VLAN IDs. + vni, err := d.vxlanIdm.SetAnyInRange(vxlanIDStart, vxlanIDEnd, true) + if err != nil { + n.releaseVxlanID() + return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err) + } + s.vni = uint32(vni) } n.subnets = append(n.subnets, s) @@ -127,8 +133,6 @@ func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, } opts[netlabel.OverlayVxlanIDList] = val - d.Lock() - defer d.Unlock() if _, ok := d.networks[id]; ok { n.releaseVxlanID() return nil, fmt.Errorf("network %s already exists", id) @@ -143,8 +147,8 @@ func (d *driver) NetworkFree(id string) error { return fmt.Errorf("invalid network id passed while freeing overlay network") } - d.Lock() - defer d.Unlock() + d.mu.Lock() + defer d.mu.Unlock() n, ok := d.networks[id] if !ok { @@ -159,43 +163,11 @@ func (d *driver) NetworkFree(id string) error { return nil } -func (n *network) obtainVxlanID(s *subnet) error { - var ( - err error - vni uint64 - ) - - n.Lock() - vni = uint64(s.vni) - n.Unlock() - - if vni == 0 { - vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd, true) - if err != nil { - return err - } - - n.Lock() - s.vni = uint32(vni) - n.Unlock() - return nil - } - - return n.driver.vxlanIdm.GetSpecificID(vni) -} - func (n *network) releaseVxlanID() { - n.Lock() - vnis := make([]uint32, 0, len(n.subnets)) for _, s := range n.subnets { - vnis = append(vnis, s.vni) + n.driver.vxlanIdm.Unset(uint64(s.vni)) s.vni = 0 } - n.Unlock() - - for _, vni := range vnis { - n.driver.vxlanIdm.Release(uint64(vni)) - } } func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error { diff --git a/vendor/github.com/docker/docker/libnetwork/drivers/remote/driver.go b/vendor/github.com/docker/docker/libnetwork/drivers/remote/driver.go index 19e641a13c..5147c0ee17 100644 --- a/vendor/github.com/docker/docker/libnetwork/drivers/remote/driver.go +++ b/vendor/github.com/docker/docker/libnetwork/drivers/remote/driver.go @@ -246,11 +246,11 @@ func errorWithRollback(msg string, err error) error { } func (d *driver) DeleteEndpoint(nid, eid string) error { - delete := &api.DeleteEndpointRequest{ + deleteRequest := &api.DeleteEndpointRequest{ NetworkID: nid, EndpointID: eid, } - return d.call("DeleteEndpoint", delete, &api.DeleteEndpointResponse{}) + return d.call("DeleteEndpoint", deleteRequest, &api.DeleteEndpointResponse{}) } func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) { diff --git a/vendor/github.com/docker/docker/libnetwork/idm/idm.go b/vendor/github.com/docker/docker/libnetwork/idm/idm.go deleted file mode 100644 index 49d16037a9..0000000000 --- a/vendor/github.com/docker/docker/libnetwork/idm/idm.go +++ /dev/null @@ -1,76 +0,0 @@ -// Package idm manages reservation/release of numerical ids from a configured set of contiguous ids -package idm - -import ( - "errors" - "fmt" - - "github.com/docker/docker/libnetwork/bitseq" - "github.com/docker/docker/libnetwork/datastore" -) - -// Idm manages the reservation/release of numerical ids from a contiguous set -type Idm struct { - start uint64 - end uint64 - handle *bitseq.Handle -} - -// New returns an instance of id manager for a [start,end] set of numerical ids -func New(ds datastore.DataStore, id string, start, end uint64) (*Idm, error) { - if id == "" { - return nil, errors.New("Invalid id") - } - if end <= start { - return nil, fmt.Errorf("Invalid set range: [%d, %d]", start, end) - } - - h, err := bitseq.NewHandle("idm", ds, id, 1+end-start) - if err != nil { - return nil, fmt.Errorf("failed to initialize bit sequence handler: %s", err.Error()) - } - - return &Idm{start: start, end: end, handle: h}, nil -} - -// GetID returns the first available id in the set -func (i *Idm) GetID(serial bool) (uint64, error) { - if i.handle == nil { - return 0, errors.New("ID set is not initialized") - } - ordinal, err := i.handle.SetAny(serial) - return i.start + ordinal, err -} - -// GetSpecificID tries to reserve the specified id -func (i *Idm) GetSpecificID(id uint64) error { - if i.handle == nil { - return errors.New("ID set is not initialized") - } - - if id < i.start || id > i.end { - return errors.New("Requested id does not belong to the set") - } - - return i.handle.Set(id - i.start) -} - -// GetIDInRange returns the first available id in the set within a [start,end] range -func (i *Idm) GetIDInRange(start, end uint64, serial bool) (uint64, error) { - if i.handle == nil { - return 0, errors.New("ID set is not initialized") - } - - if start < i.start || end > i.end { - return 0, errors.New("Requested range does not belong to the set") - } - - ordinal, err := i.handle.SetAnyInRange(start-i.start, end-i.start, serial) - - return i.start + ordinal, err -} - -// Release releases the specified id -func (i *Idm) Release(id uint64) { - i.handle.Unset(id - i.start) -} diff --git a/vendor/github.com/docker/docker/libnetwork/internal/kvstore/kvstore.go b/vendor/github.com/docker/docker/libnetwork/internal/kvstore/kvstore.go index bc7a24f462..e8b61046ad 100644 --- a/vendor/github.com/docker/docker/libnetwork/internal/kvstore/kvstore.go +++ b/vendor/github.com/docker/docker/libnetwork/internal/kvstore/kvstore.go @@ -1,7 +1,6 @@ package kvstore import ( - "crypto/tls" "errors" "time" ) @@ -15,8 +14,6 @@ const BOLTDB Backend = "boltdb" var ( // ErrBackendNotSupported is thrown when the backend k/v store is not supported by libkv ErrBackendNotSupported = errors.New("Backend storage not supported yet, please choose one of") - // ErrCallNotSupported is thrown when a method is not implemented/supported by the current backend - ErrCallNotSupported = errors.New("The current call is not supported with this backend") // ErrKeyModified is thrown during an atomic operation if the index does not match the one in the store ErrKeyModified = errors.New("Unable to complete atomic operation, key modified") // ErrKeyNotFound is thrown when the key is not found in the store during a Get operation @@ -29,21 +26,9 @@ var ( // Config contains the options for a storage client type Config struct { - ClientTLS *ClientTLSConfig - TLS *tls.Config ConnectionTimeout time.Duration Bucket string PersistConnection bool - Username string - Password string -} - -// ClientTLSConfig contains data for a Client TLS configuration in the form -// the etcd client wants it. Eventually we'll adapt it for ZK and Consul. -type ClientTLSConfig struct { - CertFile string - KeyFile string - CACertFile string } // Store represents the backend K/V storage @@ -52,41 +37,23 @@ type ClientTLSConfig struct { // backend for libkv type Store interface { // Put a value at the specified key - Put(key string, value []byte, options *WriteOptions) error + Put(key string, value []byte) error // Get a value given its key Get(key string) (*KVPair, error) - // Delete the value at the specified key - Delete(key string) error - - // Verify if a Key exists in the store + // Exists verifies if a Key exists in the store. Exists(key string) (bool, error) - // Watch for changes on a key - Watch(key string, stopCh <-chan struct{}) (<-chan *KVPair, error) - - // WatchTree watches for changes on child nodes under - // a given directory - WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*KVPair, error) - - // NewLock creates a lock for a given key. - // The returned Locker is not held and must be acquired - // with `.Lock`. The Value is optional. - NewLock(key string, options *LockOptions) (Locker, error) - // List the content of a given prefix List(directory string) ([]*KVPair, error) - // DeleteTree deletes a range of keys under a given directory - DeleteTree(directory string) error - - // Atomic CAS operation on a single value. + // AtomicPut performs an atomic CAS operation on a single value. // Pass previous = nil to create a new key. - AtomicPut(key string, value []byte, previous *KVPair, options *WriteOptions) (bool, *KVPair, error) + AtomicPut(key string, value []byte, previous *KVPair) (*KVPair, error) - // Atomic delete of a single value - AtomicDelete(key string, previous *KVPair) (bool, error) + // AtomicDelete performs an atomic delete of a single value. + AtomicDelete(key string, previous *KVPair) error // Close the store connection Close() @@ -98,23 +65,3 @@ type KVPair struct { Value []byte LastIndex uint64 } - -// WriteOptions contains optional request parameters -type WriteOptions struct { - IsDir bool - TTL time.Duration -} - -// LockOptions contains optional request parameters -type LockOptions struct { - Value []byte // Optional, value to associate with the lock - TTL time.Duration // Optional, expiration ttl associated with the lock - RenewLock chan struct{} // Optional, chan used to control and stop the session ttl renewal for the lock -} - -// Locker provides locking mechanism on top of the store. -// Similar to `sync.Lock` except it may return errors. -type Locker interface { - Lock(stopChan chan struct{}) (<-chan struct{}, error) - Unlock() error -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0c908dccd3..a5c6d12f39 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -48,7 +48,7 @@ github.com/davecgh/go-spew/spew ## explicit github.com/docker/distribution/digestset github.com/docker/distribution/reference -# github.com/docker/docker v24.0.0-rc.2.0.20230630161949-75ee002347f8+incompatible +# github.com/docker/docker v24.0.0-rc.2.0.20230706181717-98d3da79ef9c+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -69,7 +69,6 @@ github.com/docker/docker/api/types/volume github.com/docker/docker/client github.com/docker/docker/errdefs github.com/docker/docker/libnetwork/bitmap -github.com/docker/docker/libnetwork/bitseq github.com/docker/docker/libnetwork/datastore github.com/docker/docker/libnetwork/discoverapi github.com/docker/docker/libnetwork/driverapi @@ -82,7 +81,6 @@ github.com/docker/docker/libnetwork/drivers/overlay/ovmanager github.com/docker/docker/libnetwork/drivers/remote github.com/docker/docker/libnetwork/drivers/remote/api github.com/docker/docker/libnetwork/drvregistry -github.com/docker/docker/libnetwork/idm github.com/docker/docker/libnetwork/internal/kvstore github.com/docker/docker/libnetwork/ipam github.com/docker/docker/libnetwork/ipamapi