endpoint.go 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
  2. //go:build go1.19
  3. package libnetwork
  4. import (
  5. "context"
  6. "encoding/json"
  7. "fmt"
  8. "net"
  9. "sync"
  10. "github.com/containerd/log"
  11. "github.com/docker/docker/internal/sliceutil"
  12. "github.com/docker/docker/libnetwork/datastore"
  13. "github.com/docker/docker/libnetwork/ipamapi"
  14. "github.com/docker/docker/libnetwork/netlabel"
  15. "github.com/docker/docker/libnetwork/options"
  16. "github.com/docker/docker/libnetwork/scope"
  17. "github.com/docker/docker/libnetwork/types"
  18. )
  19. // ByNetworkType sorts a [Endpoint] slice based on the network-type
  20. // they're attached to. It implements [sort.Interface] and can be used
  21. // with [sort.Stable] or [sort.Sort]. It is used by [Sandbox.ResolveName]
  22. // when resolving names in swarm mode. In swarm mode, services with exposed
  23. // ports are connected to user overlay network, ingress network, and local
  24. // ("docker_gwbridge") networks. Name resolution should prioritize returning
  25. // the VIP/IPs on user overlay network over ingress and local networks.
  26. //
  27. // ByNetworkType re-orders the endpoints based on the network-type they
  28. // are attached to:
  29. //
  30. // 1. dynamic networks (user overlay networks)
  31. // 2. ingress network(s)
  32. // 3. local networks ("docker_gwbridge")
  33. type ByNetworkType []*Endpoint
  34. func (ep ByNetworkType) Len() int { return len(ep) }
  35. func (ep ByNetworkType) Swap(i, j int) { ep[i], ep[j] = ep[j], ep[i] }
  36. func (ep ByNetworkType) Less(i, j int) bool {
  37. return getNetworkType(ep[i].getNetwork()) < getNetworkType(ep[j].getNetwork())
  38. }
  39. // Define the order in which resolution should happen if an endpoint is
  40. // attached to multiple network-types. It is used by [ByNetworkType].
  41. const (
  42. typeDynamic = iota
  43. typeIngress
  44. typeLocal
  45. )
  46. func getNetworkType(nw *Network) int {
  47. switch {
  48. case nw.ingress:
  49. return typeIngress
  50. case nw.dynamic:
  51. return typeDynamic
  52. default:
  53. return typeLocal
  54. }
  55. }
  56. // EndpointOption is an option setter function type used to pass various options to Network
  57. // and Endpoint interfaces methods. The various setter functions of type EndpointOption are
  58. // provided by libnetwork, they look like <Create|Join|Leave>Option[...](...)
  59. type EndpointOption func(ep *Endpoint)
  60. // Endpoint represents a logical connection between a network and a sandbox.
  61. type Endpoint struct {
  62. name string
  63. id string
  64. network *Network
  65. iface *EndpointInterface
  66. joinInfo *endpointJoinInfo
  67. sandboxID string
  68. exposedPorts []types.TransportPort
  69. // dnsNames holds all the non-fully qualified DNS names associated to this endpoint. Order matters: first entry
  70. // will be used for the PTR records associated to the endpoint's IPv4 and IPv6 addresses.
  71. dnsNames []string
  72. disableResolution bool
  73. generic map[string]interface{}
  74. prefAddress net.IP
  75. prefAddressV6 net.IP
  76. ipamOptions map[string]string
  77. aliases map[string]string
  78. svcID string
  79. svcName string
  80. virtualIP net.IP
  81. svcAliases []string
  82. ingressPorts []*PortConfig
  83. dbIndex uint64
  84. dbExists bool
  85. serviceEnabled bool
  86. loadBalancer bool
  87. mu sync.Mutex
  88. }
  89. func (ep *Endpoint) MarshalJSON() ([]byte, error) {
  90. ep.mu.Lock()
  91. defer ep.mu.Unlock()
  92. epMap := make(map[string]interface{})
  93. epMap["name"] = ep.name
  94. epMap["id"] = ep.id
  95. epMap["ep_iface"] = ep.iface
  96. epMap["joinInfo"] = ep.joinInfo
  97. epMap["exposed_ports"] = ep.exposedPorts
  98. if ep.generic != nil {
  99. epMap["generic"] = ep.generic
  100. }
  101. epMap["sandbox"] = ep.sandboxID
  102. epMap["dnsNames"] = ep.dnsNames
  103. epMap["disableResolution"] = ep.disableResolution
  104. epMap["svcName"] = ep.svcName
  105. epMap["svcID"] = ep.svcID
  106. epMap["virtualIP"] = ep.virtualIP.String()
  107. epMap["ingressPorts"] = ep.ingressPorts
  108. epMap["svcAliases"] = ep.svcAliases
  109. epMap["loadBalancer"] = ep.loadBalancer
  110. return json.Marshal(epMap)
  111. }
  112. func (ep *Endpoint) UnmarshalJSON(b []byte) (err error) {
  113. ep.mu.Lock()
  114. defer ep.mu.Unlock()
  115. var epMap map[string]interface{}
  116. if err := json.Unmarshal(b, &epMap); err != nil {
  117. return err
  118. }
  119. ep.name = epMap["name"].(string)
  120. ep.id = epMap["id"].(string)
  121. // TODO(cpuguy83): So yeah, this isn't checking any errors anywhere.
  122. // Seems like we should be checking errors even because of memory related issues that can arise.
  123. // Alas it seems like given the nature of this data we could introduce problems if we start checking these errors.
  124. //
  125. // If anyone ever comes here and figures out one way or another if we can/should be checking these errors and it turns out we can't... then please document *why*
  126. ib, _ := json.Marshal(epMap["ep_iface"])
  127. json.Unmarshal(ib, &ep.iface) //nolint:errcheck
  128. jb, _ := json.Marshal(epMap["joinInfo"])
  129. json.Unmarshal(jb, &ep.joinInfo) //nolint:errcheck
  130. tb, _ := json.Marshal(epMap["exposed_ports"])
  131. var tPorts []types.TransportPort
  132. json.Unmarshal(tb, &tPorts) //nolint:errcheck
  133. ep.exposedPorts = tPorts
  134. cb, _ := json.Marshal(epMap["sandbox"])
  135. json.Unmarshal(cb, &ep.sandboxID) //nolint:errcheck
  136. if v, ok := epMap["generic"]; ok {
  137. ep.generic = v.(map[string]interface{})
  138. if opt, ok := ep.generic[netlabel.PortMap]; ok {
  139. pblist := []types.PortBinding{}
  140. for i := 0; i < len(opt.([]interface{})); i++ {
  141. pb := types.PortBinding{}
  142. tmp := opt.([]interface{})[i].(map[string]interface{})
  143. bytes, err := json.Marshal(tmp)
  144. if err != nil {
  145. log.G(context.TODO()).Error(err)
  146. break
  147. }
  148. err = json.Unmarshal(bytes, &pb)
  149. if err != nil {
  150. log.G(context.TODO()).Error(err)
  151. break
  152. }
  153. pblist = append(pblist, pb)
  154. }
  155. ep.generic[netlabel.PortMap] = pblist
  156. }
  157. if opt, ok := ep.generic[netlabel.ExposedPorts]; ok {
  158. tplist := []types.TransportPort{}
  159. for i := 0; i < len(opt.([]interface{})); i++ {
  160. tp := types.TransportPort{}
  161. tmp := opt.([]interface{})[i].(map[string]interface{})
  162. bytes, err := json.Marshal(tmp)
  163. if err != nil {
  164. log.G(context.TODO()).Error(err)
  165. break
  166. }
  167. err = json.Unmarshal(bytes, &tp)
  168. if err != nil {
  169. log.G(context.TODO()).Error(err)
  170. break
  171. }
  172. tplist = append(tplist, tp)
  173. }
  174. ep.generic[netlabel.ExposedPorts] = tplist
  175. }
  176. }
  177. var anonymous bool
  178. if v, ok := epMap["anonymous"]; ok {
  179. anonymous = v.(bool)
  180. }
  181. if v, ok := epMap["disableResolution"]; ok {
  182. ep.disableResolution = v.(bool)
  183. }
  184. if sn, ok := epMap["svcName"]; ok {
  185. ep.svcName = sn.(string)
  186. }
  187. if si, ok := epMap["svcID"]; ok {
  188. ep.svcID = si.(string)
  189. }
  190. if vip, ok := epMap["virtualIP"]; ok {
  191. ep.virtualIP = net.ParseIP(vip.(string))
  192. }
  193. if v, ok := epMap["loadBalancer"]; ok {
  194. ep.loadBalancer = v.(bool)
  195. }
  196. sal, _ := json.Marshal(epMap["svcAliases"])
  197. var svcAliases []string
  198. json.Unmarshal(sal, &svcAliases) //nolint:errcheck
  199. ep.svcAliases = svcAliases
  200. pc, _ := json.Marshal(epMap["ingressPorts"])
  201. var ingressPorts []*PortConfig
  202. json.Unmarshal(pc, &ingressPorts) //nolint:errcheck
  203. ep.ingressPorts = ingressPorts
  204. ma, _ := json.Marshal(epMap["myAliases"])
  205. var myAliases []string
  206. json.Unmarshal(ma, &myAliases) //nolint:errcheck
  207. _, hasDNSNames := epMap["dnsNames"]
  208. dn, _ := json.Marshal(epMap["dnsNames"])
  209. var dnsNames []string
  210. json.Unmarshal(dn, &dnsNames)
  211. ep.dnsNames = dnsNames
  212. // TODO(aker): remove this migration code in v27
  213. if !hasDNSNames {
  214. // The field dnsNames was introduced in v25.0. If we don't have it, the on-disk state was written by an older
  215. // daemon, thus we need to populate dnsNames based off of myAliases and anonymous values.
  216. if !anonymous {
  217. myAliases = append([]string{ep.name}, myAliases...)
  218. }
  219. ep.dnsNames = sliceutil.Dedup(myAliases)
  220. }
  221. return nil
  222. }
  223. func (ep *Endpoint) New() datastore.KVObject {
  224. return &Endpoint{network: ep.getNetwork()}
  225. }
  226. func (ep *Endpoint) CopyTo(o datastore.KVObject) error {
  227. ep.mu.Lock()
  228. defer ep.mu.Unlock()
  229. dstEp := o.(*Endpoint)
  230. dstEp.name = ep.name
  231. dstEp.id = ep.id
  232. dstEp.sandboxID = ep.sandboxID
  233. dstEp.dbIndex = ep.dbIndex
  234. dstEp.dbExists = ep.dbExists
  235. dstEp.disableResolution = ep.disableResolution
  236. dstEp.svcName = ep.svcName
  237. dstEp.svcID = ep.svcID
  238. dstEp.virtualIP = ep.virtualIP
  239. dstEp.loadBalancer = ep.loadBalancer
  240. dstEp.svcAliases = make([]string, len(ep.svcAliases))
  241. copy(dstEp.svcAliases, ep.svcAliases)
  242. dstEp.ingressPorts = make([]*PortConfig, len(ep.ingressPorts))
  243. copy(dstEp.ingressPorts, ep.ingressPorts)
  244. if ep.iface != nil {
  245. dstEp.iface = &EndpointInterface{}
  246. if err := ep.iface.CopyTo(dstEp.iface); err != nil {
  247. return err
  248. }
  249. }
  250. if ep.joinInfo != nil {
  251. dstEp.joinInfo = &endpointJoinInfo{}
  252. if err := ep.joinInfo.CopyTo(dstEp.joinInfo); err != nil {
  253. return err
  254. }
  255. }
  256. dstEp.exposedPorts = make([]types.TransportPort, len(ep.exposedPorts))
  257. copy(dstEp.exposedPorts, ep.exposedPorts)
  258. dstEp.dnsNames = make([]string, len(ep.dnsNames))
  259. copy(dstEp.dnsNames, ep.dnsNames)
  260. dstEp.generic = options.Generic{}
  261. for k, v := range ep.generic {
  262. dstEp.generic[k] = v
  263. }
  264. return nil
  265. }
  266. // ID returns the system-generated id for this endpoint.
  267. func (ep *Endpoint) ID() string {
  268. ep.mu.Lock()
  269. defer ep.mu.Unlock()
  270. return ep.id
  271. }
  272. // Name returns the name of this endpoint.
  273. func (ep *Endpoint) Name() string {
  274. ep.mu.Lock()
  275. defer ep.mu.Unlock()
  276. return ep.name
  277. }
  278. // Network returns the name of the network to which this endpoint is attached.
  279. func (ep *Endpoint) Network() string {
  280. if ep.network == nil {
  281. return ""
  282. }
  283. return ep.network.name
  284. }
  285. // getDNSNames returns a copy of the DNS names associated to this endpoint. The first entry is the one used for PTR
  286. // records.
  287. func (ep *Endpoint) getDNSNames() []string {
  288. ep.mu.Lock()
  289. defer ep.mu.Unlock()
  290. dnsNames := make([]string, len(ep.dnsNames))
  291. copy(dnsNames, ep.dnsNames)
  292. return dnsNames
  293. }
  294. // isServiceEnabled check if service is enabled on the endpoint
  295. func (ep *Endpoint) isServiceEnabled() bool {
  296. ep.mu.Lock()
  297. defer ep.mu.Unlock()
  298. return ep.serviceEnabled
  299. }
  300. // enableService sets service enabled on the endpoint
  301. func (ep *Endpoint) enableService() {
  302. ep.mu.Lock()
  303. defer ep.mu.Unlock()
  304. ep.serviceEnabled = true
  305. }
  306. // disableService disables service on the endpoint
  307. func (ep *Endpoint) disableService() {
  308. ep.mu.Lock()
  309. defer ep.mu.Unlock()
  310. ep.serviceEnabled = false
  311. }
  312. func (ep *Endpoint) needResolver() bool {
  313. ep.mu.Lock()
  314. defer ep.mu.Unlock()
  315. return !ep.disableResolution
  316. }
  317. // endpoint Key structure : endpoint/network-id/endpoint-id
  318. func (ep *Endpoint) Key() []string {
  319. if ep.network == nil {
  320. return nil
  321. }
  322. return []string{datastore.EndpointKeyPrefix, ep.network.id, ep.id}
  323. }
  324. func (ep *Endpoint) KeyPrefix() []string {
  325. if ep.network == nil {
  326. return nil
  327. }
  328. return []string{datastore.EndpointKeyPrefix, ep.network.id}
  329. }
  330. func (ep *Endpoint) Value() []byte {
  331. b, err := json.Marshal(ep)
  332. if err != nil {
  333. return nil
  334. }
  335. return b
  336. }
  337. func (ep *Endpoint) SetValue(value []byte) error {
  338. return json.Unmarshal(value, ep)
  339. }
  340. func (ep *Endpoint) Index() uint64 {
  341. ep.mu.Lock()
  342. defer ep.mu.Unlock()
  343. return ep.dbIndex
  344. }
  345. func (ep *Endpoint) SetIndex(index uint64) {
  346. ep.mu.Lock()
  347. defer ep.mu.Unlock()
  348. ep.dbIndex = index
  349. ep.dbExists = true
  350. }
  351. func (ep *Endpoint) Exists() bool {
  352. ep.mu.Lock()
  353. defer ep.mu.Unlock()
  354. return ep.dbExists
  355. }
  356. func (ep *Endpoint) Skip() bool {
  357. return ep.getNetwork().Skip()
  358. }
  359. func (ep *Endpoint) processOptions(options ...EndpointOption) {
  360. ep.mu.Lock()
  361. defer ep.mu.Unlock()
  362. for _, opt := range options {
  363. if opt != nil {
  364. opt(ep)
  365. }
  366. }
  367. }
  368. func (ep *Endpoint) getNetwork() *Network {
  369. ep.mu.Lock()
  370. defer ep.mu.Unlock()
  371. return ep.network
  372. }
  373. func (ep *Endpoint) getNetworkFromStore() (*Network, error) {
  374. if ep.network == nil {
  375. return nil, fmt.Errorf("invalid network object in endpoint %s", ep.Name())
  376. }
  377. return ep.network.getController().getNetworkFromStore(ep.network.id)
  378. }
  379. // Join joins the sandbox to the endpoint and populates into the sandbox
  380. // the network resources allocated for the endpoint.
  381. func (ep *Endpoint) Join(sb *Sandbox, options ...EndpointOption) error {
  382. if sb == nil || sb.ID() == "" || sb.Key() == "" {
  383. return types.InvalidParameterErrorf("invalid Sandbox passed to endpoint join: %v", sb)
  384. }
  385. sb.joinLeaveStart()
  386. defer sb.joinLeaveEnd()
  387. return ep.sbJoin(sb, options...)
  388. }
  389. func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) {
  390. n, err := ep.getNetworkFromStore()
  391. if err != nil {
  392. return fmt.Errorf("failed to get network from store during join: %v", err)
  393. }
  394. ep, err = n.getEndpointFromStore(ep.ID())
  395. if err != nil {
  396. return fmt.Errorf("failed to get endpoint from store during join: %v", err)
  397. }
  398. ep.mu.Lock()
  399. if ep.sandboxID != "" {
  400. ep.mu.Unlock()
  401. return types.ForbiddenErrorf("another container is attached to the same network endpoint")
  402. }
  403. ep.network = n
  404. ep.sandboxID = sb.ID()
  405. ep.joinInfo = &endpointJoinInfo{}
  406. epid := ep.id
  407. ep.mu.Unlock()
  408. defer func() {
  409. if err != nil {
  410. ep.mu.Lock()
  411. ep.sandboxID = ""
  412. ep.mu.Unlock()
  413. }
  414. }()
  415. nid := n.ID()
  416. ep.processOptions(options...)
  417. d, err := n.driver(true)
  418. if err != nil {
  419. return fmt.Errorf("failed to get driver during join: %v", err)
  420. }
  421. err = d.Join(nid, epid, sb.Key(), ep, sb.Labels())
  422. if err != nil {
  423. return err
  424. }
  425. defer func() {
  426. if err != nil {
  427. if e := d.Leave(nid, epid); e != nil {
  428. log.G(context.TODO()).Warnf("driver leave failed while rolling back join: %v", e)
  429. }
  430. }
  431. }()
  432. if !n.getController().isAgent() {
  433. if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
  434. n.updateSvcRecord(ep, true)
  435. }
  436. }
  437. if err := sb.updateHostsFile(ep.getEtcHostsAddrs()); err != nil {
  438. return err
  439. }
  440. if err = sb.updateDNS(n.enableIPv6); err != nil {
  441. return err
  442. }
  443. // Current endpoint providing external connectivity for the sandbox
  444. extEp := sb.getGatewayEndpoint()
  445. sb.addEndpoint(ep)
  446. defer func() {
  447. if err != nil {
  448. sb.removeEndpoint(ep)
  449. }
  450. }()
  451. if err = sb.populateNetworkResources(ep); err != nil {
  452. return err
  453. }
  454. if err = n.getController().updateToStore(ep); err != nil {
  455. return err
  456. }
  457. if err = ep.addDriverInfoToCluster(); err != nil {
  458. return err
  459. }
  460. defer func() {
  461. if err != nil {
  462. if e := ep.deleteDriverInfoFromCluster(); e != nil {
  463. log.G(context.TODO()).Errorf("Could not delete endpoint state for endpoint %s from cluster on join failure: %v", ep.Name(), e)
  464. }
  465. }
  466. }()
  467. // Load balancing endpoints should never have a default gateway nor
  468. // should they alter the status of a network's default gateway
  469. if ep.loadBalancer && !sb.ingress {
  470. return nil
  471. }
  472. if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
  473. return sb.setupDefaultGW()
  474. }
  475. moveExtConn := sb.getGatewayEndpoint() != extEp
  476. if moveExtConn {
  477. if extEp != nil {
  478. log.G(context.TODO()).Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
  479. extN, err := extEp.getNetworkFromStore()
  480. if err != nil {
  481. return fmt.Errorf("failed to get network from store for revoking external connectivity during join: %v", err)
  482. }
  483. extD, err := extN.driver(true)
  484. if err != nil {
  485. return fmt.Errorf("failed to get driver for revoking external connectivity during join: %v", err)
  486. }
  487. if err = extD.RevokeExternalConnectivity(extEp.network.ID(), extEp.ID()); err != nil {
  488. return types.InternalErrorf(
  489. "driver failed revoking external connectivity on endpoint %s (%s): %v",
  490. extEp.Name(), extEp.ID(), err)
  491. }
  492. defer func() {
  493. if err != nil {
  494. if e := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil {
  495. log.G(context.TODO()).Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
  496. extEp.Name(), extEp.ID(), e)
  497. }
  498. }
  499. }()
  500. }
  501. if !n.internal {
  502. log.G(context.TODO()).Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
  503. if err = d.ProgramExternalConnectivity(n.ID(), ep.ID(), sb.Labels()); err != nil {
  504. return types.InternalErrorf(
  505. "driver failed programming external connectivity on endpoint %s (%s): %v",
  506. ep.Name(), ep.ID(), err)
  507. }
  508. }
  509. }
  510. if !sb.needDefaultGW() {
  511. if e := sb.clearDefaultGW(); e != nil {
  512. log.G(context.TODO()).Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
  513. sb.ID(), sb.ContainerID(), e)
  514. }
  515. }
  516. return nil
  517. }
  518. func (ep *Endpoint) rename(name string) error {
  519. ep.mu.Lock()
  520. ep.name = name
  521. ep.mu.Unlock()
  522. // Update the store with the updated name
  523. if err := ep.getNetwork().getController().updateToStore(ep); err != nil {
  524. return err
  525. }
  526. return nil
  527. }
  528. func (ep *Endpoint) UpdateDNSNames(dnsNames []string) error {
  529. nw := ep.getNetwork()
  530. c := nw.getController()
  531. sb, ok := ep.getSandbox()
  532. if !ok {
  533. log.G(context.TODO()).WithFields(log.Fields{
  534. "sandboxID": ep.sandboxID,
  535. "endpointID": ep.ID(),
  536. }).Warn("DNSNames update aborted, sandbox is not present anymore")
  537. return nil
  538. }
  539. if c.isAgent() {
  540. if err := ep.deleteServiceInfoFromCluster(sb, true, "UpdateDNSNames"); err != nil {
  541. return types.InternalErrorf("could not delete service state for endpoint %s from cluster on UpdateDNSNames: %v", ep.Name(), err)
  542. }
  543. ep.dnsNames = dnsNames
  544. if err := ep.addServiceInfoToCluster(sb); err != nil {
  545. return types.InternalErrorf("could not add service state for endpoint %s to cluster on UpdateDNSNames: %v", ep.Name(), err)
  546. }
  547. } else {
  548. nw.updateSvcRecord(ep, false)
  549. ep.dnsNames = dnsNames
  550. nw.updateSvcRecord(ep, true)
  551. }
  552. // Update the store with the updated name
  553. if err := c.updateToStore(ep); err != nil {
  554. return err
  555. }
  556. return nil
  557. }
  558. func (ep *Endpoint) hasInterface(iName string) bool {
  559. ep.mu.Lock()
  560. defer ep.mu.Unlock()
  561. return ep.iface != nil && ep.iface.srcName == iName
  562. }
  563. // Leave detaches the network resources populated in the sandbox.
  564. func (ep *Endpoint) Leave(sb *Sandbox) error {
  565. if sb == nil || sb.ID() == "" || sb.Key() == "" {
  566. return types.InvalidParameterErrorf("invalid Sandbox passed to endpoint leave: %v", sb)
  567. }
  568. sb.joinLeaveStart()
  569. defer sb.joinLeaveEnd()
  570. return ep.sbLeave(sb, false)
  571. }
  572. func (ep *Endpoint) sbLeave(sb *Sandbox, force bool) error {
  573. n, err := ep.getNetworkFromStore()
  574. if err != nil {
  575. return fmt.Errorf("failed to get network from store during leave: %v", err)
  576. }
  577. ep, err = n.getEndpointFromStore(ep.ID())
  578. if err != nil {
  579. return fmt.Errorf("failed to get endpoint from store during leave: %v", err)
  580. }
  581. ep.mu.Lock()
  582. sid := ep.sandboxID
  583. ep.mu.Unlock()
  584. if sid == "" {
  585. return types.ForbiddenErrorf("cannot leave endpoint with no attached sandbox")
  586. }
  587. if sid != sb.ID() {
  588. return types.ForbiddenErrorf("unexpected sandbox ID in leave request. Expected %s. Got %s", ep.sandboxID, sb.ID())
  589. }
  590. d, err := n.driver(!force)
  591. if err != nil {
  592. return fmt.Errorf("failed to get driver during endpoint leave: %v", err)
  593. }
  594. ep.mu.Lock()
  595. ep.sandboxID = ""
  596. ep.network = n
  597. ep.mu.Unlock()
  598. // Current endpoint providing external connectivity to the sandbox
  599. extEp := sb.getGatewayEndpoint()
  600. moveExtConn := extEp != nil && (extEp.ID() == ep.ID())
  601. if d != nil {
  602. if moveExtConn {
  603. log.G(context.TODO()).Debugf("Revoking external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
  604. if err := d.RevokeExternalConnectivity(n.id, ep.id); err != nil {
  605. log.G(context.TODO()).Warnf("driver failed revoking external connectivity on endpoint %s (%s): %v",
  606. ep.Name(), ep.ID(), err)
  607. }
  608. }
  609. if err := d.Leave(n.id, ep.id); err != nil {
  610. if _, ok := err.(types.MaskableError); !ok {
  611. log.G(context.TODO()).Warnf("driver error disconnecting container %s : %v", ep.name, err)
  612. }
  613. }
  614. }
  615. if err := ep.deleteServiceInfoFromCluster(sb, true, "sbLeave"); err != nil {
  616. log.G(context.TODO()).Warnf("Failed to clean up service info on container %s disconnect: %v", ep.name, err)
  617. }
  618. if err := sb.clearNetworkResources(ep); err != nil {
  619. log.G(context.TODO()).Warnf("Failed to clean up network resources on container %s disconnect: %v", ep.name, err)
  620. }
  621. // Update the store about the sandbox detach only after we
  622. // have completed sb.clearNetworkresources above to avoid
  623. // spurious logs when cleaning up the sandbox when the daemon
  624. // ungracefully exits and restarts before completing sandbox
  625. // detach but after store has been updated.
  626. if err := n.getController().updateToStore(ep); err != nil {
  627. return err
  628. }
  629. if e := ep.deleteDriverInfoFromCluster(); e != nil {
  630. log.G(context.TODO()).Errorf("Failed to delete endpoint state for endpoint %s from cluster: %v", ep.Name(), e)
  631. }
  632. sb.deleteHostsEntries(n.getSvcRecords(ep))
  633. if !sb.inDelete && sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
  634. return sb.setupDefaultGW()
  635. }
  636. // New endpoint providing external connectivity for the sandbox
  637. extEp = sb.getGatewayEndpoint()
  638. if moveExtConn && extEp != nil {
  639. log.G(context.TODO()).Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
  640. extN, err := extEp.getNetworkFromStore()
  641. if err != nil {
  642. return fmt.Errorf("failed to get network from store for programming external connectivity during leave: %v", err)
  643. }
  644. extD, err := extN.driver(true)
  645. if err != nil {
  646. return fmt.Errorf("failed to get driver for programming external connectivity during leave: %v", err)
  647. }
  648. if err := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); err != nil {
  649. log.G(context.TODO()).Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
  650. extEp.Name(), extEp.ID(), err)
  651. }
  652. }
  653. if !sb.needDefaultGW() {
  654. if err := sb.clearDefaultGW(); err != nil {
  655. log.G(context.TODO()).Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
  656. sb.ID(), sb.ContainerID(), err)
  657. }
  658. }
  659. return nil
  660. }
  661. // Delete deletes and detaches this endpoint from the network.
  662. func (ep *Endpoint) Delete(force bool) error {
  663. var err error
  664. n, err := ep.getNetworkFromStore()
  665. if err != nil {
  666. return fmt.Errorf("failed to get network during Delete: %v", err)
  667. }
  668. ep, err = n.getEndpointFromStore(ep.ID())
  669. if err != nil {
  670. return fmt.Errorf("failed to get endpoint from store during Delete: %v", err)
  671. }
  672. ep.mu.Lock()
  673. epid := ep.id
  674. name := ep.name
  675. sbid := ep.sandboxID
  676. ep.mu.Unlock()
  677. sb, _ := n.getController().SandboxByID(sbid)
  678. if sb != nil && !force {
  679. return &ActiveContainerError{name: name, id: epid}
  680. }
  681. if sb != nil {
  682. if e := ep.sbLeave(sb, force); e != nil {
  683. log.G(context.TODO()).Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
  684. }
  685. }
  686. if err = n.getController().deleteFromStore(ep); err != nil {
  687. return err
  688. }
  689. defer func() {
  690. if err != nil && !force {
  691. ep.dbExists = false
  692. if e := n.getController().updateToStore(ep); e != nil {
  693. log.G(context.TODO()).Warnf("failed to recreate endpoint in store %s : %v", name, e)
  694. }
  695. }
  696. }()
  697. if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
  698. n.updateSvcRecord(ep, false)
  699. }
  700. if err = ep.deleteEndpoint(force); err != nil && !force {
  701. return err
  702. }
  703. ep.releaseAddress()
  704. if err := n.getEpCnt().DecEndpointCnt(); err != nil {
  705. log.G(context.TODO()).Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err)
  706. }
  707. return nil
  708. }
  709. func (ep *Endpoint) deleteEndpoint(force bool) error {
  710. ep.mu.Lock()
  711. n := ep.network
  712. name := ep.name
  713. epid := ep.id
  714. ep.mu.Unlock()
  715. driver, err := n.driver(!force)
  716. if err != nil {
  717. return fmt.Errorf("failed to delete endpoint: %v", err)
  718. }
  719. if driver == nil {
  720. return nil
  721. }
  722. if err := driver.DeleteEndpoint(n.id, epid); err != nil {
  723. if _, ok := err.(types.ForbiddenError); ok {
  724. return err
  725. }
  726. if _, ok := err.(types.MaskableError); !ok {
  727. log.G(context.TODO()).Warnf("driver error deleting endpoint %s : %v", name, err)
  728. }
  729. }
  730. return nil
  731. }
  732. func (ep *Endpoint) getSandbox() (*Sandbox, bool) {
  733. c := ep.network.getController()
  734. ep.mu.Lock()
  735. sid := ep.sandboxID
  736. ep.mu.Unlock()
  737. c.mu.Lock()
  738. ps, ok := c.sandboxes[sid]
  739. c.mu.Unlock()
  740. return ps, ok
  741. }
  742. // Return a list of this endpoint's addresses to add to '/etc/hosts'.
  743. func (ep *Endpoint) getEtcHostsAddrs() []string {
  744. ep.mu.Lock()
  745. defer ep.mu.Unlock()
  746. // Do not update hosts file with internal network's endpoint IP
  747. if n := ep.network; n == nil || n.ingress || n.Name() == libnGWNetwork {
  748. return nil
  749. }
  750. var addresses []string
  751. if ep.iface.addr != nil {
  752. addresses = append(addresses, ep.iface.addr.IP.String())
  753. }
  754. if ep.iface.addrv6 != nil {
  755. addresses = append(addresses, ep.iface.addrv6.IP.String())
  756. }
  757. return addresses
  758. }
  759. // EndpointOptionGeneric function returns an option setter for a Generic option defined
  760. // in a Dictionary of Key-Value pair
  761. func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
  762. return func(ep *Endpoint) {
  763. for k, v := range generic {
  764. ep.generic[k] = v
  765. }
  766. }
  767. }
  768. var (
  769. linkLocalMask = net.CIDRMask(16, 32)
  770. linkLocalMaskIPv6 = net.CIDRMask(64, 128)
  771. )
  772. // CreateOptionIpam function returns an option setter for the ipam configuration for this endpoint
  773. func CreateOptionIpam(ipV4, ipV6 net.IP, llIPs []net.IP, ipamOptions map[string]string) EndpointOption {
  774. return func(ep *Endpoint) {
  775. ep.prefAddress = ipV4
  776. ep.prefAddressV6 = ipV6
  777. if len(llIPs) != 0 {
  778. for _, ip := range llIPs {
  779. nw := &net.IPNet{IP: ip, Mask: linkLocalMask}
  780. if ip.To4() == nil {
  781. nw.Mask = linkLocalMaskIPv6
  782. }
  783. ep.iface.llAddrs = append(ep.iface.llAddrs, nw)
  784. }
  785. }
  786. ep.ipamOptions = ipamOptions
  787. }
  788. }
  789. // CreateOptionExposedPorts function returns an option setter for the container exposed
  790. // ports option to be passed to [Network.CreateEndpoint] method.
  791. func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption {
  792. return func(ep *Endpoint) {
  793. // Defensive copy
  794. eps := make([]types.TransportPort, len(exposedPorts))
  795. copy(eps, exposedPorts)
  796. // Store endpoint label and in generic because driver needs it
  797. ep.exposedPorts = eps
  798. ep.generic[netlabel.ExposedPorts] = eps
  799. }
  800. }
  801. // CreateOptionPortMapping function returns an option setter for the mapping
  802. // ports option to be passed to [Network.CreateEndpoint] method.
  803. func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
  804. return func(ep *Endpoint) {
  805. // Store a copy of the bindings as generic data to pass to the driver
  806. pbs := make([]types.PortBinding, len(portBindings))
  807. copy(pbs, portBindings)
  808. ep.generic[netlabel.PortMap] = pbs
  809. }
  810. }
  811. // CreateOptionDNS function returns an option setter for dns entry option to
  812. // be passed to container Create method.
  813. func CreateOptionDNS(dns []string) EndpointOption {
  814. return func(ep *Endpoint) {
  815. ep.generic[netlabel.DNSServers] = dns
  816. }
  817. }
  818. // CreateOptionDNSNames specifies the list of (non fully qualified) DNS names associated to an endpoint. These will be
  819. // used to populate the embedded DNS server. Order matters: first name will be used to generate PTR records.
  820. func CreateOptionDNSNames(names []string) EndpointOption {
  821. return func(ep *Endpoint) {
  822. ep.dnsNames = names
  823. }
  824. }
  825. // CreateOptionDisableResolution function returns an option setter to indicate
  826. // this endpoint doesn't want embedded DNS server functionality
  827. func CreateOptionDisableResolution() EndpointOption {
  828. return func(ep *Endpoint) {
  829. ep.disableResolution = true
  830. }
  831. }
  832. // CreateOptionAlias function returns an option setter for setting endpoint alias
  833. func CreateOptionAlias(name string, alias string) EndpointOption {
  834. return func(ep *Endpoint) {
  835. if ep.aliases == nil {
  836. ep.aliases = make(map[string]string)
  837. }
  838. ep.aliases[alias] = name
  839. }
  840. }
  841. // CreateOptionService function returns an option setter for setting service binding configuration
  842. func CreateOptionService(name, id string, vip net.IP, ingressPorts []*PortConfig, aliases []string) EndpointOption {
  843. return func(ep *Endpoint) {
  844. ep.svcName = name
  845. ep.svcID = id
  846. ep.virtualIP = vip
  847. ep.ingressPorts = ingressPorts
  848. ep.svcAliases = aliases
  849. }
  850. }
  851. // CreateOptionLoadBalancer function returns an option setter for denoting the endpoint is a load balancer for a network
  852. func CreateOptionLoadBalancer() EndpointOption {
  853. return func(ep *Endpoint) {
  854. ep.loadBalancer = true
  855. }
  856. }
  857. // JoinOptionPriority function returns an option setter for priority option to
  858. // be passed to the endpoint.Join() method.
  859. func JoinOptionPriority(prio int) EndpointOption {
  860. return func(ep *Endpoint) {
  861. // ep lock already acquired
  862. c := ep.network.getController()
  863. c.mu.Lock()
  864. sb, ok := c.sandboxes[ep.sandboxID]
  865. c.mu.Unlock()
  866. if !ok {
  867. log.G(context.TODO()).Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
  868. return
  869. }
  870. sb.epPriority[ep.id] = prio
  871. }
  872. }
  873. func (ep *Endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool) error {
  874. var err error
  875. n := ep.getNetwork()
  876. if n.hasSpecialDriver() {
  877. return nil
  878. }
  879. log.G(context.TODO()).Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  880. if assignIPv4 {
  881. if err = ep.assignAddressVersion(4, ipam); err != nil {
  882. return err
  883. }
  884. }
  885. if assignIPv6 {
  886. err = ep.assignAddressVersion(6, ipam)
  887. }
  888. return err
  889. }
  890. func (ep *Endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
  891. var (
  892. poolID *string
  893. address **net.IPNet
  894. prefAdd net.IP
  895. progAdd net.IP
  896. )
  897. n := ep.getNetwork()
  898. switch ipVer {
  899. case 4:
  900. poolID = &ep.iface.v4PoolID
  901. address = &ep.iface.addr
  902. prefAdd = ep.prefAddress
  903. case 6:
  904. poolID = &ep.iface.v6PoolID
  905. address = &ep.iface.addrv6
  906. prefAdd = ep.prefAddressV6
  907. default:
  908. return types.InternalErrorf("incorrect ip version number passed: %d", ipVer)
  909. }
  910. ipInfo := n.getIPInfo(ipVer)
  911. // ipv6 address is not mandatory
  912. if len(ipInfo) == 0 && ipVer == 6 {
  913. return nil
  914. }
  915. // The address to program may be chosen by the user or by the network driver in one specific
  916. // case to support backward compatibility with `docker daemon --fixed-cidrv6` use case
  917. if prefAdd != nil {
  918. progAdd = prefAdd
  919. } else if *address != nil {
  920. progAdd = (*address).IP
  921. }
  922. for _, d := range ipInfo {
  923. if progAdd != nil && !d.Pool.Contains(progAdd) {
  924. continue
  925. }
  926. addr, _, err := ipam.RequestAddress(d.PoolID, progAdd, ep.ipamOptions)
  927. if err == nil {
  928. ep.mu.Lock()
  929. *address = addr
  930. *poolID = d.PoolID
  931. ep.mu.Unlock()
  932. return nil
  933. }
  934. if err != ipamapi.ErrNoAvailableIPs || progAdd != nil {
  935. return err
  936. }
  937. }
  938. if progAdd != nil {
  939. return types.InvalidParameterErrorf("invalid address %s: It does not belong to any of this network's subnets", prefAdd)
  940. }
  941. return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
  942. }
  943. func (ep *Endpoint) releaseAddress() {
  944. n := ep.getNetwork()
  945. if n.hasSpecialDriver() {
  946. return
  947. }
  948. log.G(context.TODO()).Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  949. ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
  950. if err != nil {
  951. log.G(context.TODO()).Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
  952. return
  953. }
  954. if ep.iface.addr != nil {
  955. if err := ipam.ReleaseAddress(ep.iface.v4PoolID, ep.iface.addr.IP); err != nil {
  956. log.G(context.TODO()).Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
  957. }
  958. }
  959. if ep.iface.addrv6 != nil {
  960. if err := ipam.ReleaseAddress(ep.iface.v6PoolID, ep.iface.addrv6.IP); err != nil {
  961. log.G(context.TODO()).Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
  962. }
  963. }
  964. }
  965. func (c *Controller) cleanupLocalEndpoints() error {
  966. // Get used endpoints
  967. eps := make(map[string]interface{})
  968. for _, sb := range c.sandboxes {
  969. for _, ep := range sb.endpoints {
  970. eps[ep.id] = true
  971. }
  972. }
  973. nl, err := c.getNetworks()
  974. if err != nil {
  975. return fmt.Errorf("could not get list of networks: %v", err)
  976. }
  977. for _, n := range nl {
  978. if n.ConfigOnly() {
  979. continue
  980. }
  981. epl, err := n.getEndpointsFromStore()
  982. if err != nil {
  983. log.G(context.TODO()).Warnf("Could not get list of endpoints in network %s during endpoint cleanup: %v", n.name, err)
  984. continue
  985. }
  986. for _, ep := range epl {
  987. if _, ok := eps[ep.id]; ok {
  988. continue
  989. }
  990. log.G(context.TODO()).Infof("Removing stale endpoint %s (%s)", ep.name, ep.id)
  991. if err := ep.Delete(true); err != nil {
  992. log.G(context.TODO()).Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
  993. }
  994. }
  995. epl, err = n.getEndpointsFromStore()
  996. if err != nil {
  997. log.G(context.TODO()).Warnf("Could not get list of endpoints in network %s for count update: %v", n.name, err)
  998. continue
  999. }
  1000. epCnt := n.getEpCnt().EndpointCnt()
  1001. if epCnt != uint64(len(epl)) {
  1002. log.G(context.TODO()).Infof("Fixing inconsistent endpoint_cnt for network %s. Expected=%d, Actual=%d", n.name, len(epl), epCnt)
  1003. if err := n.getEpCnt().setCnt(uint64(len(epl))); err != nil {
  1004. log.G(context.TODO()).WithField("network", n.name).WithError(err).Warn("Error while fixing inconsistent endpoint_cnt for network")
  1005. }
  1006. }
  1007. }
  1008. return nil
  1009. }