github.com/moby/docker@v26.1.3+incompatible/libnetwork/store.go (about) 1 package libnetwork 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/containerd/log" 9 "github.com/docker/docker/libnetwork/datastore" 10 "github.com/docker/docker/libnetwork/scope" 11 ) 12 13 func (c *Controller) initStores() error { 14 if c.cfg == nil { 15 return nil 16 } 17 var err error 18 c.store, err = datastore.New(c.cfg.Scope) 19 if err != nil { 20 return err 21 } 22 23 return nil 24 } 25 26 func (c *Controller) closeStores() { 27 if store := c.store; store != nil { 28 store.Close() 29 } 30 } 31 32 func (c *Controller) getStore() *datastore.Store { 33 return c.store 34 } 35 36 func (c *Controller) getNetworkFromStore(nid string) (*Network, error) { 37 for _, n := range c.getNetworksFromStore(context.TODO()) { 38 if n.id == nid { 39 return n, nil 40 } 41 } 42 return nil, ErrNoSuchNetwork(nid) 43 } 44 45 func (c *Controller) getNetworks() ([]*Network, error) { 46 var nl []*Network 47 48 store := c.getStore() 49 if store == nil { 50 return nil, nil 51 } 52 53 kvol, err := store.List(&Network{ctrlr: c}) 54 if err != nil && err != datastore.ErrKeyNotFound { 55 return nil, fmt.Errorf("failed to get networks: %w", err) 56 } 57 58 for _, kvo := range kvol { 59 n := kvo.(*Network) 60 n.ctrlr = c 61 62 ec := &endpointCnt{n: n} 63 err = store.GetObject(ec) 64 if err != nil && !n.inDelete { 65 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) 66 continue 67 } 68 69 n.epCnt = ec 70 if n.scope == "" { 71 n.scope = scope.Local 72 } 73 nl = append(nl, n) 74 } 75 76 return nl, nil 77 } 78 79 func (c *Controller) getNetworksFromStore(ctx context.Context) []*Network { // FIXME: unify with c.getNetworks() 80 var nl []*Network 81 82 store := c.getStore() 83 kvol, err := store.List(&Network{ctrlr: c}) 84 if err != nil { 85 if err != datastore.ErrKeyNotFound { 86 log.G(ctx).Debugf("failed to get networks from store: %v", err) 87 } 88 return nil 89 } 90 91 kvep, err := store.Map(datastore.Key(epCntKeyPrefix), &endpointCnt{}) 92 if err != nil && err != datastore.ErrKeyNotFound { 93 log.G(ctx).Warnf("failed to get endpoint_count map from store: %v", err) 94 } 95 96 for _, kvo := range kvol { 97 n := kvo.(*Network) 98 n.mu.Lock() 99 n.ctrlr = c 100 ec := &endpointCnt{n: n} 101 // Trim the leading & trailing "/" to make it consistent across all stores 102 if val, ok := kvep[strings.Trim(datastore.Key(ec.Key()...), "/")]; ok { 103 ec = val.(*endpointCnt) 104 ec.n = n 105 n.epCnt = ec 106 } 107 if n.scope == "" { 108 n.scope = scope.Local 109 } 110 n.mu.Unlock() 111 nl = append(nl, n) 112 } 113 114 return nl 115 } 116 117 func (n *Network) getEndpointFromStore(eid string) (*Endpoint, error) { 118 store := n.ctrlr.getStore() 119 ep := &Endpoint{id: eid, network: n} 120 err := store.GetObject(ep) 121 if err != nil { 122 return nil, fmt.Errorf("could not find endpoint %s: %w", eid, err) 123 } 124 return ep, nil 125 } 126 127 func (n *Network) getEndpointsFromStore() ([]*Endpoint, error) { 128 var epl []*Endpoint 129 130 store := n.getController().getStore() 131 kvol, err := store.List(&Endpoint{network: n}) 132 if err != nil { 133 if err != datastore.ErrKeyNotFound { 134 return nil, fmt.Errorf("failed to get endpoints for network %s: %w", 135 n.Name(), err) 136 } 137 return nil, nil 138 } 139 140 for _, kvo := range kvol { 141 ep := kvo.(*Endpoint) 142 epl = append(epl, ep) 143 } 144 145 return epl, nil 146 } 147 148 func (c *Controller) updateToStore(kvObject datastore.KVObject) error { 149 cs := c.getStore() 150 if cs == nil { 151 return fmt.Errorf("datastore is not initialized") 152 } 153 154 if err := cs.PutObjectAtomic(kvObject); err != nil { 155 if err == datastore.ErrKeyModified { 156 return err 157 } 158 return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err) 159 } 160 161 return nil 162 } 163 164 func (c *Controller) deleteFromStore(kvObject datastore.KVObject) error { 165 cs := c.getStore() 166 if cs == nil { 167 return fmt.Errorf("datastore is not initialized") 168 } 169 170 retry: 171 if err := cs.DeleteObjectAtomic(kvObject); err != nil { 172 if err == datastore.ErrKeyModified { 173 if err := cs.GetObject(kvObject); err != nil { 174 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 175 } 176 log.G(context.TODO()).Warnf("Error (%v) deleting object %v, retrying....", err, kvObject.Key()) 177 goto retry 178 } 179 return err 180 } 181 182 return nil 183 } 184 185 func (c *Controller) networkCleanup() { 186 for _, n := range c.getNetworksFromStore(context.TODO()) { 187 if n.inDelete { 188 log.G(context.TODO()).Infof("Removing stale network %s (%s)", n.Name(), n.ID()) 189 if err := n.delete(true, true); err != nil { 190 log.G(context.TODO()).Debugf("Error while removing stale network: %v", err) 191 } 192 } 193 } 194 }