endpoint.go 31 KB

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