github.com/moby/docker@v26.1.3+incompatible/libnetwork/drivers/windows/windows_store.go (about) 1 //go:build windows 2 3 package windows 4 5 import ( 6 "context" 7 "encoding/json" 8 "fmt" 9 "net" 10 11 "github.com/containerd/log" 12 "github.com/docker/docker/libnetwork/datastore" 13 "github.com/docker/docker/libnetwork/netlabel" 14 "github.com/docker/docker/libnetwork/types" 15 ) 16 17 const ( 18 windowsPrefix = "windows" 19 windowsEndpointPrefix = "windows-endpoint" 20 ) 21 22 func (d *driver) initStore(option map[string]interface{}) error { 23 if data, ok := option[netlabel.LocalKVClient]; ok { 24 var ok bool 25 d.store, ok = data.(*datastore.Store) 26 if !ok { 27 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 28 } 29 30 err := d.populateNetworks() 31 if err != nil { 32 return err 33 } 34 35 err = d.populateEndpoints() 36 if err != nil { 37 return err 38 } 39 } 40 41 return nil 42 } 43 44 func (d *driver) populateNetworks() error { 45 kvol, err := d.store.List(&networkConfiguration{Type: d.name}) 46 if err != nil && err != datastore.ErrKeyNotFound { 47 return fmt.Errorf("failed to get windows network configurations from store: %v", err) 48 } 49 50 // It's normal for network configuration state to be empty. Just return. 51 if err == datastore.ErrKeyNotFound { 52 return nil 53 } 54 55 for _, kvo := range kvol { 56 ncfg := kvo.(*networkConfiguration) 57 if ncfg.Type != d.name { 58 continue 59 } 60 d.createNetwork(ncfg) 61 log.G(context.TODO()).Debugf("Network %v (%.7s) restored", d.name, ncfg.ID) 62 } 63 64 return nil 65 } 66 67 func (d *driver) populateEndpoints() error { 68 kvol, err := d.store.List(&hnsEndpoint{Type: d.name}) 69 if err != nil && err != datastore.ErrKeyNotFound { 70 return fmt.Errorf("failed to get endpoints from store: %v", err) 71 } 72 73 if err == datastore.ErrKeyNotFound { 74 return nil 75 } 76 77 for _, kvo := range kvol { 78 ep := kvo.(*hnsEndpoint) 79 if ep.Type != d.name { 80 continue 81 } 82 n, ok := d.networks[ep.nid] 83 if !ok { 84 log.G(context.TODO()).Debugf("Network (%.7s) not found for restored endpoint (%.7s)", ep.nid, ep.id) 85 log.G(context.TODO()).Debugf("Deleting stale endpoint (%.7s) from store", ep.id) 86 if err := d.storeDelete(ep); err != nil { 87 log.G(context.TODO()).Debugf("Failed to delete stale endpoint (%.7s) from store", ep.id) 88 } 89 continue 90 } 91 n.endpoints[ep.id] = ep 92 log.G(context.TODO()).Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid) 93 } 94 95 return nil 96 } 97 98 func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 99 if d.store == nil { 100 log.G(context.TODO()).Warnf("store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 101 return nil 102 } 103 104 if err := d.store.PutObjectAtomic(kvObject); err != nil { 105 return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err) 106 } 107 108 return nil 109 } 110 111 func (d *driver) storeDelete(kvObject datastore.KVObject) error { 112 if d.store == nil { 113 log.G(context.TODO()).Debugf("store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 114 return nil 115 } 116 117 return d.store.DeleteObject(kvObject) 118 } 119 120 func (ncfg *networkConfiguration) MarshalJSON() ([]byte, error) { 121 nMap := make(map[string]interface{}) 122 123 nMap["ID"] = ncfg.ID 124 nMap["Type"] = ncfg.Type 125 nMap["Name"] = ncfg.Name 126 nMap["HnsID"] = ncfg.HnsID 127 nMap["VLAN"] = ncfg.VLAN 128 nMap["VSID"] = ncfg.VSID 129 nMap["DNSServers"] = ncfg.DNSServers 130 nMap["DNSSuffix"] = ncfg.DNSSuffix 131 nMap["SourceMac"] = ncfg.SourceMac 132 nMap["NetworkAdapterName"] = ncfg.NetworkAdapterName 133 134 return json.Marshal(nMap) 135 } 136 137 func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { 138 var ( 139 err error 140 nMap map[string]interface{} 141 ) 142 143 if err = json.Unmarshal(b, &nMap); err != nil { 144 return err 145 } 146 147 ncfg.ID = nMap["ID"].(string) 148 ncfg.Type = nMap["Type"].(string) 149 ncfg.Name = nMap["Name"].(string) 150 ncfg.HnsID = nMap["HnsID"].(string) 151 ncfg.VLAN = uint(nMap["VLAN"].(float64)) 152 ncfg.VSID = uint(nMap["VSID"].(float64)) 153 ncfg.DNSServers = nMap["DNSServers"].(string) 154 ncfg.DNSSuffix = nMap["DNSSuffix"].(string) 155 ncfg.SourceMac = nMap["SourceMac"].(string) 156 ncfg.NetworkAdapterName = nMap["NetworkAdapterName"].(string) 157 return nil 158 } 159 160 func (ncfg *networkConfiguration) Key() []string { 161 return []string{windowsPrefix + ncfg.Type, ncfg.ID} 162 } 163 164 func (ncfg *networkConfiguration) KeyPrefix() []string { 165 return []string{windowsPrefix + ncfg.Type} 166 } 167 168 func (ncfg *networkConfiguration) Value() []byte { 169 b, err := json.Marshal(ncfg) 170 if err != nil { 171 return nil 172 } 173 return b 174 } 175 176 func (ncfg *networkConfiguration) SetValue(value []byte) error { 177 return json.Unmarshal(value, ncfg) 178 } 179 180 func (ncfg *networkConfiguration) Index() uint64 { 181 return ncfg.dbIndex 182 } 183 184 func (ncfg *networkConfiguration) SetIndex(index uint64) { 185 ncfg.dbIndex = index 186 ncfg.dbExists = true 187 } 188 189 func (ncfg *networkConfiguration) Exists() bool { 190 return ncfg.dbExists 191 } 192 193 func (ncfg *networkConfiguration) Skip() bool { 194 return false 195 } 196 197 func (ncfg *networkConfiguration) New() datastore.KVObject { 198 return &networkConfiguration{Type: ncfg.Type} 199 } 200 201 func (ncfg *networkConfiguration) CopyTo(o datastore.KVObject) error { 202 dstNcfg := o.(*networkConfiguration) 203 *dstNcfg = *ncfg 204 return nil 205 } 206 207 func (ep *hnsEndpoint) MarshalJSON() ([]byte, error) { 208 epMap := make(map[string]interface{}) 209 epMap["id"] = ep.id 210 epMap["nid"] = ep.nid 211 epMap["Type"] = ep.Type 212 epMap["profileID"] = ep.profileID 213 epMap["MacAddress"] = ep.macAddress.String() 214 if ep.addr.IP != nil { 215 epMap["Addr"] = ep.addr.String() 216 } 217 if ep.gateway != nil { 218 epMap["gateway"] = ep.gateway.String() 219 } 220 epMap["epOption"] = ep.epOption 221 epMap["epConnectivity"] = ep.epConnectivity 222 epMap["PortMapping"] = ep.portMapping 223 224 return json.Marshal(epMap) 225 } 226 227 func (ep *hnsEndpoint) UnmarshalJSON(b []byte) error { 228 var ( 229 err error 230 epMap map[string]interface{} 231 ) 232 233 if err = json.Unmarshal(b, &epMap); err != nil { 234 return fmt.Errorf("Failed to unmarshal to endpoint: %v", err) 235 } 236 if v, ok := epMap["MacAddress"]; ok { 237 if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil { 238 return types.InternalErrorf("failed to decode endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 239 } 240 } 241 if v, ok := epMap["Addr"]; ok { 242 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 243 log.G(context.TODO()).Warnf("failed to decode endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 244 } 245 } 246 if v, ok := epMap["gateway"]; ok { 247 ep.gateway = net.ParseIP(v.(string)) 248 } 249 ep.id = epMap["id"].(string) 250 ep.Type = epMap["Type"].(string) 251 ep.nid = epMap["nid"].(string) 252 ep.profileID = epMap["profileID"].(string) 253 d, _ := json.Marshal(epMap["epOption"]) 254 if err := json.Unmarshal(d, &ep.epOption); err != nil { 255 log.G(context.TODO()).Warnf("Failed to decode endpoint container config %v", err) 256 } 257 d, _ = json.Marshal(epMap["epConnectivity"]) 258 if err := json.Unmarshal(d, &ep.epConnectivity); err != nil { 259 log.G(context.TODO()).Warnf("Failed to decode endpoint external connectivity configuration %v", err) 260 } 261 d, _ = json.Marshal(epMap["PortMapping"]) 262 if err := json.Unmarshal(d, &ep.portMapping); err != nil { 263 log.G(context.TODO()).Warnf("Failed to decode endpoint port mapping %v", err) 264 } 265 266 return nil 267 } 268 269 func (ep *hnsEndpoint) Key() []string { 270 return []string{windowsEndpointPrefix + ep.Type, ep.id} 271 } 272 273 func (ep *hnsEndpoint) KeyPrefix() []string { 274 return []string{windowsEndpointPrefix + ep.Type} 275 } 276 277 func (ep *hnsEndpoint) Value() []byte { 278 b, err := json.Marshal(ep) 279 if err != nil { 280 return nil 281 } 282 return b 283 } 284 285 func (ep *hnsEndpoint) SetValue(value []byte) error { 286 return json.Unmarshal(value, ep) 287 } 288 289 func (ep *hnsEndpoint) Index() uint64 { 290 return ep.dbIndex 291 } 292 293 func (ep *hnsEndpoint) SetIndex(index uint64) { 294 ep.dbIndex = index 295 ep.dbExists = true 296 } 297 298 func (ep *hnsEndpoint) Exists() bool { 299 return ep.dbExists 300 } 301 302 func (ep *hnsEndpoint) Skip() bool { 303 return false 304 } 305 306 func (ep *hnsEndpoint) New() datastore.KVObject { 307 return &hnsEndpoint{Type: ep.Type} 308 } 309 310 func (ep *hnsEndpoint) CopyTo(o datastore.KVObject) error { 311 dstEp := o.(*hnsEndpoint) 312 *dstEp = *ep 313 return nil 314 }