endpoint.go 31 KB

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