| package libnetwork |
| |
| import ( |
| "context" |
| "errors" |
| "fmt" |
| |
| "github.com/containerd/log" |
| "github.com/docker/docker/libnetwork/datastore" |
| "github.com/docker/docker/libnetwork/scope" |
| "go.opentelemetry.io/otel" |
| ) |
| |
| func (c *Controller) getNetworkFromStore(nid string) (*Network, error) { |
| for _, n := range c.getNetworksFromStore(context.TODO()) { |
| if n.id == nid { |
| return n, nil |
| } |
| } |
| return nil, ErrNoSuchNetwork(nid) |
| } |
| |
| func (c *Controller) getNetworks() ([]*Network, error) { |
| var nl []*Network |
| |
| kvol, err := c.store.List(&Network{ctrlr: c}) |
| if err != nil && !errors.Is(err, datastore.ErrKeyNotFound) { |
| return nil, fmt.Errorf("failed to get networks: %w", err) |
| } |
| |
| for _, kvo := range kvol { |
| n := kvo.(*Network) |
| n.ctrlr = c |
| c.cacheNetwork(n) |
| if n.scope == "" { |
| n.scope = scope.Local |
| } |
| nl = append(nl, n) |
| } |
| |
| return nl, nil |
| } |
| |
| func (c *Controller) getNetworksFromStore(ctx context.Context) []*Network { // FIXME: unify with c.getNetworks() |
| var nl []*Network |
| |
| kvol, err := c.store.List(&Network{ctrlr: c}) |
| if err != nil { |
| if !errors.Is(err, datastore.ErrKeyNotFound) { |
| log.G(ctx).Debugf("failed to get networks from store: %v", err) |
| } |
| return nil |
| } |
| |
| for _, kvo := range kvol { |
| n := kvo.(*Network) |
| n.mu.Lock() |
| n.ctrlr = c |
| if n.scope == "" { |
| n.scope = scope.Local |
| } |
| n.mu.Unlock() |
| nl = append(nl, n) |
| } |
| |
| return nl |
| } |
| |
| func (n *Network) getEndpointFromStore(eid string) (*Endpoint, error) { |
| ep := &Endpoint{id: eid, network: n} |
| err := n.ctrlr.store.GetObject(ep) |
| if err != nil { |
| return nil, fmt.Errorf("could not find endpoint %s: %w", eid, err) |
| } |
| n.ctrlr.cacheEndpoint(ep) |
| return ep, nil |
| } |
| |
| func (n *Network) getEndpointsFromStore() ([]*Endpoint, error) { |
| var epl []*Endpoint |
| |
| kvol, err := n.getController().store.List(&Endpoint{network: n}) |
| if err != nil { |
| if !errors.Is(err, datastore.ErrKeyNotFound) { |
| return nil, fmt.Errorf("failed to get endpoints for network %s: %w", |
| n.Name(), err) |
| } |
| return nil, nil |
| } |
| |
| for _, kvo := range kvol { |
| ep := kvo.(*Endpoint) |
| epl = append(epl, ep) |
| n.ctrlr.cacheEndpoint(ep) |
| } |
| |
| return epl, nil |
| } |
| |
| func (c *Controller) updateToStore(ctx context.Context, kvObject datastore.KVObject) error { |
| ctx, span := otel.Tracer("").Start(ctx, "libnetwork.Controller.updateToStore") |
| defer span.End() |
| |
| if err := c.store.PutObjectAtomic(kvObject); err != nil { |
| if errors.Is(err, datastore.ErrKeyModified) { |
| return err |
| } |
| return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err) |
| } |
| |
| return nil |
| } |
| |
| func (c *Controller) deleteFromStore(kvObject datastore.KVObject) error { |
| retry: |
| if err := c.store.DeleteObjectAtomic(kvObject); err != nil { |
| if errors.Is(err, datastore.ErrKeyModified) { |
| if err := c.store.GetObject(kvObject); err != nil { |
| return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) |
| } |
| log.G(context.TODO()).Warnf("Error (%v) deleting object %v, retrying....", err, kvObject.Key()) |
| goto retry |
| } |
| return err |
| } |
| |
| return nil |
| } |
| |
| func (c *Controller) networkCleanup() { |
| for _, n := range c.getNetworksFromStore(context.TODO()) { |
| if n.inDelete { |
| log.G(context.TODO()).Infof("Removing stale network %s (%s)", n.Name(), n.ID()) |
| if err := n.delete(true, true); err != nil { |
| log.G(context.TODO()).Debugf("Error while removing stale network: %v", err) |
| } |
| } |
| } |
| } |