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