endpoint.go 29 KB

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