package libnetwork import ( "context" "errors" "fmt" "github.com/containerd/log" "github.com/moby/moby/v2/daemon/libnetwork/datastore" "github.com/moby/moby/v2/daemon/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) } } } }