2015-05-31 18:49:11 +00:00
|
|
|
package libnetwork
|
|
|
|
|
|
|
|
import (
|
2023-06-23 00:33:17 +00:00
|
|
|
"context"
|
2015-05-31 18:49:11 +00:00
|
|
|
"fmt"
|
2017-02-02 22:45:38 +00:00
|
|
|
"strings"
|
2015-05-31 18:49:11 +00:00
|
|
|
|
2023-09-13 15:41:45 +00:00
|
|
|
"github.com/containerd/log"
|
2021-05-28 00:15:56 +00:00
|
|
|
"github.com/docker/docker/libnetwork/datastore"
|
2023-11-09 22:48:01 +00:00
|
|
|
"github.com/docker/docker/libnetwork/scope"
|
2015-05-31 18:49:11 +00:00
|
|
|
)
|
|
|
|
|
2023-01-11 22:43:32 +00:00
|
|
|
func (c *Controller) initStores() error {
|
2015-10-05 11:21:15 +00:00
|
|
|
if c.cfg == nil {
|
|
|
|
return nil
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
2023-01-14 00:04:43 +00:00
|
|
|
var err error
|
2023-07-21 12:24:18 +00:00
|
|
|
c.store, err = datastore.New(c.cfg.Scope)
|
2023-01-13 23:38:46 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
|
2015-09-22 20:20:55 +00:00
|
|
|
return nil
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
|
|
|
|
2023-01-11 22:43:32 +00:00
|
|
|
func (c *Controller) closeStores() {
|
2023-01-14 00:04:43 +00:00
|
|
|
if store := c.store; store != nil {
|
2015-10-05 11:21:15 +00:00
|
|
|
store.Close()
|
2015-09-16 11:39:46 +00:00
|
|
|
}
|
2015-09-22 20:20:55 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 12:24:18 +00:00
|
|
|
func (c *Controller) getStore() *datastore.Store {
|
2023-01-14 00:04:43 +00:00
|
|
|
return c.store
|
2015-09-22 20:20:55 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 22:38:57 +00:00
|
|
|
func (c *Controller) getNetworkFromStore(nid string) (*Network, error) {
|
2023-09-10 00:05:05 +00:00
|
|
|
for _, n := range c.getNetworksFromStore(context.TODO()) {
|
2019-09-11 19:09:13 +00:00
|
|
|
if n.id == nid {
|
2019-09-24 08:56:30 +00:00
|
|
|
return n, nil
|
2015-10-12 05:28:26 +00:00
|
|
|
}
|
2015-09-16 11:39:46 +00:00
|
|
|
}
|
2020-05-22 07:22:36 +00:00
|
|
|
return nil, ErrNoSuchNetwork(nid)
|
2015-09-16 11:39:46 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 22:38:57 +00:00
|
|
|
func (c *Controller) getNetworks() ([]*Network, error) {
|
|
|
|
var nl []*Network
|
2015-10-19 20:20:23 +00:00
|
|
|
|
2023-01-14 00:04:43 +00:00
|
|
|
store := c.getStore()
|
2015-10-19 20:20:23 +00:00
|
|
|
if store == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
kvol, err := store.List(datastore.Key(datastore.NetworkKeyPrefix),
|
2023-07-21 22:38:57 +00:00
|
|
|
&Network{ctrlr: c})
|
2015-10-19 20:20:23 +00:00
|
|
|
if err != nil && err != datastore.ErrKeyNotFound {
|
2023-01-14 00:04:43 +00:00
|
|
|
return nil, fmt.Errorf("failed to get networks: %w", err)
|
2015-10-19 20:20:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, kvo := range kvol {
|
2023-07-21 22:38:57 +00:00
|
|
|
n := kvo.(*Network)
|
2015-10-19 20:20:23 +00:00
|
|
|
n.ctrlr = c
|
|
|
|
|
|
|
|
ec := &endpointCnt{n: n}
|
|
|
|
err = store.GetObject(datastore.Key(ec.Key()...), ec)
|
2016-03-05 10:00:31 +00:00
|
|
|
if err != nil && !n.inDelete {
|
2023-06-23 00:33:17 +00:00
|
|
|
log.G(context.TODO()).Warnf("Could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
|
2016-02-10 01:00:31 +00:00
|
|
|
continue
|
2015-10-19 20:20:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
n.epCnt = ec
|
2017-05-15 18:48:05 +00:00
|
|
|
if n.scope == "" {
|
2023-10-19 15:56:32 +00:00
|
|
|
n.scope = scope.Local
|
2017-05-15 18:48:05 +00:00
|
|
|
}
|
2015-10-19 20:20:23 +00:00
|
|
|
nl = append(nl, n)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nl, nil
|
|
|
|
}
|
|
|
|
|
2023-09-10 00:05:05 +00:00
|
|
|
func (c *Controller) getNetworksFromStore(ctx context.Context) []*Network { // FIXME: unify with c.getNetworks()
|
2023-07-21 22:38:57 +00:00
|
|
|
var nl []*Network
|
2015-10-05 11:21:15 +00:00
|
|
|
|
2023-01-14 00:04:43 +00:00
|
|
|
store := c.getStore()
|
2023-07-21 22:38:57 +00:00
|
|
|
kvol, err := store.List(datastore.Key(datastore.NetworkKeyPrefix), &Network{ctrlr: c})
|
2023-01-14 00:04:43 +00:00
|
|
|
if err != nil {
|
|
|
|
if err != datastore.ErrKeyNotFound {
|
2023-09-10 00:05:05 +00:00
|
|
|
log.G(ctx).Debugf("failed to get networks from store: %v", err)
|
2015-10-05 11:21:15 +00:00
|
|
|
}
|
2023-01-14 00:04:43 +00:00
|
|
|
return nil
|
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
|
2023-01-14 00:04:43 +00:00
|
|
|
kvep, err := store.Map(datastore.Key(epCntKeyPrefix), &endpointCnt{})
|
|
|
|
if err != nil && err != datastore.ErrKeyNotFound {
|
2023-09-10 00:05:05 +00:00
|
|
|
log.G(ctx).Warnf("failed to get endpoint_count map from store: %v", err)
|
2023-01-14 00:04:43 +00:00
|
|
|
}
|
2017-02-02 22:45:38 +00:00
|
|
|
|
2023-01-14 00:04:43 +00:00
|
|
|
for _, kvo := range kvol {
|
2023-07-21 22:38:57 +00:00
|
|
|
n := kvo.(*Network)
|
2023-01-14 00:04:43 +00:00
|
|
|
n.mu.Lock()
|
|
|
|
n.ctrlr = c
|
|
|
|
ec := &endpointCnt{n: n}
|
|
|
|
// Trim the leading & trailing "/" to make it consistent across all stores
|
|
|
|
if val, ok := kvep[strings.Trim(datastore.Key(ec.Key()...), "/")]; ok {
|
|
|
|
ec = val.(*endpointCnt)
|
|
|
|
ec.n = n
|
|
|
|
n.epCnt = ec
|
|
|
|
}
|
|
|
|
if n.scope == "" {
|
2023-10-19 15:56:32 +00:00
|
|
|
n.scope = scope.Local
|
2015-10-05 11:21:15 +00:00
|
|
|
}
|
2023-01-14 00:04:43 +00:00
|
|
|
n.mu.Unlock()
|
|
|
|
nl = append(nl, n)
|
2015-09-16 11:42:35 +00:00
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
|
2020-05-26 08:39:38 +00:00
|
|
|
return nl
|
2015-06-18 15:18:17 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 22:38:57 +00:00
|
|
|
func (n *Network) getEndpointFromStore(eid string) (*Endpoint, error) {
|
2023-01-14 00:04:43 +00:00
|
|
|
store := n.ctrlr.getStore()
|
|
|
|
ep := &Endpoint{id: eid, network: n}
|
|
|
|
err := store.GetObject(datastore.Key(ep.Key()...), ep)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not find endpoint %s: %w", eid, err)
|
2015-10-20 22:37:22 +00:00
|
|
|
}
|
2023-01-14 00:04:43 +00:00
|
|
|
return ep, nil
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
|
|
|
|
2023-07-21 22:38:57 +00:00
|
|
|
func (n *Network) getEndpointsFromStore() ([]*Endpoint, error) {
|
2023-01-12 01:42:24 +00:00
|
|
|
var epl []*Endpoint
|
2015-06-01 04:19:10 +00:00
|
|
|
|
2023-01-12 01:42:24 +00:00
|
|
|
tmp := Endpoint{network: n}
|
2023-01-14 00:04:43 +00:00
|
|
|
store := n.getController().getStore()
|
|
|
|
kvol, err := store.List(datastore.Key(tmp.KeyPrefix()...), &Endpoint{network: n})
|
|
|
|
if err != nil {
|
|
|
|
if err != datastore.ErrKeyNotFound {
|
2023-10-19 15:56:32 +00:00
|
|
|
return nil, fmt.Errorf("failed to get endpoints for network %s: %w",
|
|
|
|
n.Name(), err)
|
2015-10-05 11:21:15 +00:00
|
|
|
}
|
2023-01-14 00:04:43 +00:00
|
|
|
return nil, nil
|
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
|
2023-01-14 00:04:43 +00:00
|
|
|
for _, kvo := range kvol {
|
|
|
|
ep := kvo.(*Endpoint)
|
|
|
|
epl = append(epl, ep)
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
|
|
|
|
return epl, nil
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
|
|
|
|
2023-01-11 22:43:32 +00:00
|
|
|
func (c *Controller) updateToStore(kvObject datastore.KVObject) error {
|
2023-01-14 00:04:43 +00:00
|
|
|
cs := c.getStore()
|
2015-05-31 18:49:11 +00:00
|
|
|
if cs == nil {
|
2023-07-29 00:02:17 +00:00
|
|
|
return fmt.Errorf("datastore is not initialized")
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
|
|
|
|
2015-10-05 11:21:15 +00:00
|
|
|
if err := cs.PutObjectAtomic(kvObject); err != nil {
|
2015-10-10 02:31:44 +00:00
|
|
|
if err == datastore.ErrKeyModified {
|
|
|
|
return err
|
|
|
|
}
|
2015-10-05 11:21:15 +00:00
|
|
|
return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2015-05-31 18:49:11 +00:00
|
|
|
}
|
|
|
|
|
2023-01-11 22:43:32 +00:00
|
|
|
func (c *Controller) deleteFromStore(kvObject datastore.KVObject) error {
|
2023-01-14 00:04:43 +00:00
|
|
|
cs := c.getStore()
|
2015-06-01 16:43:24 +00:00
|
|
|
if cs == nil {
|
2023-07-29 00:02:17 +00:00
|
|
|
return fmt.Errorf("datastore is not initialized")
|
2015-06-01 16:43:24 +00:00
|
|
|
}
|
|
|
|
|
2015-10-05 11:21:15 +00:00
|
|
|
retry:
|
2015-09-16 11:42:35 +00:00
|
|
|
if err := cs.DeleteObjectAtomic(kvObject); err != nil {
|
2015-10-05 11:21:15 +00:00
|
|
|
if err == datastore.ErrKeyModified {
|
|
|
|
if err := cs.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil {
|
|
|
|
return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err)
|
|
|
|
}
|
2023-06-23 00:33:17 +00:00
|
|
|
log.G(context.TODO()).Warnf("Error (%v) deleting object %v, retrying....", err, kvObject.Key())
|
2015-10-05 11:21:15 +00:00
|
|
|
goto retry
|
|
|
|
}
|
2015-06-01 16:43:24 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-11 22:43:32 +00:00
|
|
|
func (c *Controller) networkCleanup() {
|
2023-09-10 00:05:05 +00:00
|
|
|
for _, n := range c.getNetworksFromStore(context.TODO()) {
|
2016-03-05 10:00:31 +00:00
|
|
|
if n.inDelete {
|
2023-06-23 00:33:17 +00:00
|
|
|
log.G(context.TODO()).Infof("Removing stale network %s (%s)", n.Name(), n.ID())
|
2018-04-09 22:08:39 +00:00
|
|
|
if err := n.delete(true, true); err != nil {
|
2023-06-23 00:33:17 +00:00
|
|
|
log.G(context.TODO()).Debugf("Error while removing stale network: %v", err)
|
2016-03-05 10:00:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|