endpoint.go 32 KB

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