endpoint.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. package libnetwork
  2. import (
  3. "container/heap"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "strings"
  8. "sync"
  9. "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. logrus.Error(err)
  121. break
  122. }
  123. err = json.Unmarshal(bytes, &pb)
  124. if err != nil {
  125. logrus.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. logrus.Error(err)
  140. break
  141. }
  142. err = json.Unmarshal(bytes, &tp)
  143. if err != nil {
  144. logrus.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) (err error) {
  351. n, err := ep.getNetworkFromStore()
  352. if err != nil {
  353. return fmt.Errorf("failed to get network from store during join: %v", err)
  354. }
  355. ep, err = n.getEndpointFromStore(ep.ID())
  356. if err != nil {
  357. return fmt.Errorf("failed to get endpoint from store during join: %v", err)
  358. }
  359. ep.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 get driver during join: %v", err)
  381. }
  382. err = d.Join(nid, epid, sb.Key(), ep, sb.Labels())
  383. if err != nil {
  384. return err
  385. }
  386. defer func() {
  387. if err != nil {
  388. if e := d.Leave(nid, epid); e != nil {
  389. logrus.Warnf("driver leave failed while rolling back join: %v", e)
  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. // Current endpoint providing external connectivity for the sandbox
  410. extEp := sb.getGatewayEndpoint()
  411. sb.Lock()
  412. heap.Push(&sb.endpoints, ep)
  413. sb.Unlock()
  414. defer func() {
  415. if err != nil {
  416. sb.removeEndpoint(ep)
  417. }
  418. }()
  419. if err = sb.populateNetworkResources(ep); err != nil {
  420. return err
  421. }
  422. if err = n.getController().updateToStore(ep); err != nil {
  423. return err
  424. }
  425. if err = ep.addDriverInfoToCluster(); err != nil {
  426. return err
  427. }
  428. defer func() {
  429. if err != nil {
  430. if e := ep.deleteDriverInfoFromCluster(); e != nil {
  431. logrus.Errorf("Could not delete endpoint state for endpoint %s from cluster on join failure: %v", ep.Name(), e)
  432. }
  433. }
  434. }()
  435. if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
  436. return sb.setupDefaultGW()
  437. }
  438. moveExtConn := sb.getGatewayEndpoint() != extEp
  439. if moveExtConn {
  440. if extEp != nil {
  441. logrus.Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
  442. extN, err := extEp.getNetworkFromStore()
  443. if err != nil {
  444. return fmt.Errorf("failed to get network from store for revoking external connectivity during join: %v", err)
  445. }
  446. extD, err := extN.driver(true)
  447. if err != nil {
  448. return fmt.Errorf("failed to get driver for revoking external connectivity during join: %v", err)
  449. }
  450. if err = extD.RevokeExternalConnectivity(extEp.network.ID(), extEp.ID()); err != nil {
  451. return types.InternalErrorf(
  452. "driver failed revoking external connectivity on endpoint %s (%s): %v",
  453. extEp.Name(), extEp.ID(), err)
  454. }
  455. defer func() {
  456. if err != nil {
  457. if e := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil {
  458. logrus.Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v",
  459. extEp.Name(), extEp.ID(), e)
  460. }
  461. }
  462. }()
  463. }
  464. if !n.internal {
  465. logrus.Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
  466. if err = d.ProgramExternalConnectivity(n.ID(), ep.ID(), sb.Labels()); err != nil {
  467. return types.InternalErrorf(
  468. "driver failed programming external connectivity on endpoint %s (%s): %v",
  469. ep.Name(), ep.ID(), err)
  470. }
  471. }
  472. }
  473. if !sb.needDefaultGW() {
  474. if e := sb.clearDefaultGW(); e != nil {
  475. logrus.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
  476. sb.ID(), sb.ContainerID(), e)
  477. }
  478. }
  479. return nil
  480. }
  481. func doUpdateHostsFile(n *network, sb *sandbox) bool {
  482. return !n.ingress && n.Name() != libnGWNetwork
  483. }
  484. func (ep *endpoint) rename(name string) error {
  485. var (
  486. err error
  487. netWatch *netWatch
  488. ok bool
  489. )
  490. n := ep.getNetwork()
  491. if n == nil {
  492. return fmt.Errorf("network not connected for ep %q", ep.name)
  493. }
  494. c := n.getController()
  495. if c.isAgent() {
  496. if err = ep.deleteServiceInfoFromCluster(); err != nil {
  497. return types.InternalErrorf("Could not delete service state for endpoint %s from cluster on rename: %v", ep.Name(), err)
  498. }
  499. } else {
  500. c.Lock()
  501. netWatch, ok = c.nmap[n.ID()]
  502. c.Unlock()
  503. if !ok {
  504. return fmt.Errorf("watch null for network %q", n.Name())
  505. }
  506. n.updateSvcRecord(ep, c.getLocalEps(netWatch), false)
  507. }
  508. oldName := ep.name
  509. oldAnonymous := ep.anonymous
  510. ep.name = name
  511. ep.anonymous = false
  512. if c.isAgent() {
  513. if err = ep.addServiceInfoToCluster(); err != nil {
  514. return types.InternalErrorf("Could not add service state for endpoint %s to cluster on rename: %v", ep.Name(), err)
  515. }
  516. defer func() {
  517. if err != nil {
  518. ep.deleteServiceInfoFromCluster()
  519. ep.name = oldName
  520. ep.anonymous = oldAnonymous
  521. ep.addServiceInfoToCluster()
  522. }
  523. }()
  524. } else {
  525. n.updateSvcRecord(ep, c.getLocalEps(netWatch), true)
  526. defer func() {
  527. if err != nil {
  528. n.updateSvcRecord(ep, c.getLocalEps(netWatch), false)
  529. ep.name = oldName
  530. ep.anonymous = oldAnonymous
  531. n.updateSvcRecord(ep, c.getLocalEps(netWatch), true)
  532. }
  533. }()
  534. }
  535. // Update the store with the updated name
  536. if err = c.updateToStore(ep); err != nil {
  537. return err
  538. }
  539. // After the name change do a dummy endpoint count update to
  540. // trigger the service record update in the peer nodes
  541. // Ignore the error because updateStore fail for EpCnt is a
  542. // benign error. Besides there is no meaningful recovery that
  543. // we can do. When the cluster recovers subsequent EpCnt update
  544. // will force the peers to get the correct EP name.
  545. n.getEpCnt().updateStore()
  546. return err
  547. }
  548. func (ep *endpoint) hasInterface(iName string) bool {
  549. ep.Lock()
  550. defer ep.Unlock()
  551. return ep.iface != nil && ep.iface.srcName == iName
  552. }
  553. func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
  554. if sbox == nil || sbox.ID() == "" || sbox.Key() == "" {
  555. return types.BadRequestErrorf("invalid Sandbox passed to endpoint leave: %v", sbox)
  556. }
  557. sb, ok := sbox.(*sandbox)
  558. if !ok {
  559. return types.BadRequestErrorf("not a valid Sandbox interface")
  560. }
  561. sb.joinLeaveStart()
  562. defer sb.joinLeaveEnd()
  563. return ep.sbLeave(sb, false, options...)
  564. }
  565. func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) error {
  566. n, err := ep.getNetworkFromStore()
  567. if err != nil {
  568. return fmt.Errorf("failed to get network from store during leave: %v", err)
  569. }
  570. ep, err = n.getEndpointFromStore(ep.ID())
  571. if err != nil {
  572. return fmt.Errorf("failed to get endpoint from store during leave: %v", err)
  573. }
  574. ep.Lock()
  575. sid := ep.sandboxID
  576. ep.Unlock()
  577. if sid == "" {
  578. return types.ForbiddenErrorf("cannot leave endpoint with no attached sandbox")
  579. }
  580. if sid != sb.ID() {
  581. return types.ForbiddenErrorf("unexpected sandbox ID in leave request. Expected %s. Got %s", ep.sandboxID, sb.ID())
  582. }
  583. ep.processOptions(options...)
  584. d, err := n.driver(!force)
  585. if err != nil {
  586. return fmt.Errorf("failed to get driver during endpoint leave: %v", err)
  587. }
  588. ep.Lock()
  589. ep.sandboxID = ""
  590. ep.network = n
  591. ep.Unlock()
  592. // Current endpoint providing external connectivity to the sandbox
  593. extEp := sb.getGatewayEndpoint()
  594. moveExtConn := extEp != nil && (extEp.ID() == ep.ID())
  595. if d != nil {
  596. if moveExtConn {
  597. logrus.Debugf("Revoking external connectivity on endpoint %s (%s)", ep.Name(), ep.ID())
  598. if err := d.RevokeExternalConnectivity(n.id, ep.id); err != nil {
  599. logrus.Warnf("driver failed revoking external connectivity on endpoint %s (%s): %v",
  600. ep.Name(), ep.ID(), err)
  601. }
  602. }
  603. if err := d.Leave(n.id, ep.id); err != nil {
  604. if _, ok := err.(types.MaskableError); !ok {
  605. logrus.Warnf("driver error disconnecting container %s : %v", ep.name, err)
  606. }
  607. }
  608. }
  609. if err := sb.clearNetworkResources(ep); err != nil {
  610. logrus.Warnf("Could not cleanup network resources on container %s disconnect: %v", ep.name, err)
  611. }
  612. // Update the store about the sandbox detach only after we
  613. // have completed sb.clearNetworkresources above to avoid
  614. // spurious logs when cleaning up the sandbox when the daemon
  615. // ungracefully exits and restarts before completing sandbox
  616. // detach but after store has been updated.
  617. if err := n.getController().updateToStore(ep); err != nil {
  618. return err
  619. }
  620. if e := ep.deleteServiceInfoFromCluster(); e != nil {
  621. logrus.Errorf("Could not delete service state for endpoint %s from cluster: %v", ep.Name(), e)
  622. }
  623. if e := ep.deleteDriverInfoFromCluster(); e != nil {
  624. logrus.Errorf("Could not delete endpoint state for endpoint %s from cluster: %v", ep.Name(), e)
  625. }
  626. sb.deleteHostsEntries(n.getSvcRecords(ep))
  627. if !sb.inDelete && sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
  628. return sb.setupDefaultGW()
  629. }
  630. // New endpoint providing external connectivity for the sandbox
  631. extEp = sb.getGatewayEndpoint()
  632. if moveExtConn && extEp != nil {
  633. logrus.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID())
  634. extN, err := extEp.getNetworkFromStore()
  635. if err != nil {
  636. return fmt.Errorf("failed to get network from store for programming external connectivity during leave: %v", err)
  637. }
  638. extD, err := extN.driver(true)
  639. if err != nil {
  640. return fmt.Errorf("failed to get driver for programming external connectivity during leave: %v", err)
  641. }
  642. if err := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); err != nil {
  643. logrus.Warnf("driver failed programming external connectivity on endpoint %s: (%s) %v",
  644. extEp.Name(), extEp.ID(), err)
  645. }
  646. }
  647. if !sb.needDefaultGW() {
  648. if err := sb.clearDefaultGW(); err != nil {
  649. logrus.Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v",
  650. sb.ID(), sb.ContainerID(), err)
  651. }
  652. }
  653. return nil
  654. }
  655. func (ep *endpoint) Delete(force bool) error {
  656. var err error
  657. n, err := ep.getNetworkFromStore()
  658. if err != nil {
  659. return fmt.Errorf("failed to get network during Delete: %v", err)
  660. }
  661. ep, err = n.getEndpointFromStore(ep.ID())
  662. if err != nil {
  663. return fmt.Errorf("failed to get endpoint from store during Delete: %v", err)
  664. }
  665. ep.Lock()
  666. epid := ep.id
  667. name := ep.name
  668. sbid := ep.sandboxID
  669. ep.Unlock()
  670. sb, _ := n.getController().SandboxByID(sbid)
  671. if sb != nil && !force {
  672. return &ActiveContainerError{name: name, id: epid}
  673. }
  674. if sb != nil {
  675. if e := ep.sbLeave(sb.(*sandbox), force); e != nil {
  676. logrus.Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
  677. }
  678. }
  679. if err = n.getController().deleteFromStore(ep); err != nil {
  680. return err
  681. }
  682. defer func() {
  683. if err != nil && !force {
  684. ep.dbExists = false
  685. if e := n.getController().updateToStore(ep); e != nil {
  686. logrus.Warnf("failed to recreate endpoint in store %s : %v", name, e)
  687. }
  688. }
  689. }()
  690. // unwatch for service records
  691. n.getController().unWatchSvcRecord(ep)
  692. if err = ep.deleteEndpoint(force); err != nil && !force {
  693. return err
  694. }
  695. ep.releaseAddress()
  696. if err := n.getEpCnt().DecEndpointCnt(); err != nil {
  697. logrus.Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err)
  698. }
  699. return nil
  700. }
  701. func (ep *endpoint) deleteEndpoint(force bool) error {
  702. ep.Lock()
  703. n := ep.network
  704. name := ep.name
  705. epid := ep.id
  706. ep.Unlock()
  707. driver, err := n.driver(!force)
  708. if err != nil {
  709. return fmt.Errorf("failed to delete endpoint: %v", err)
  710. }
  711. if driver == nil {
  712. return nil
  713. }
  714. if err := driver.DeleteEndpoint(n.id, epid); err != nil {
  715. if _, ok := err.(types.ForbiddenError); ok {
  716. return err
  717. }
  718. if _, ok := err.(types.MaskableError); !ok {
  719. logrus.Warnf("driver error deleting endpoint %s : %v", name, err)
  720. }
  721. }
  722. return nil
  723. }
  724. func (ep *endpoint) getSandbox() (*sandbox, bool) {
  725. c := ep.network.getController()
  726. ep.Lock()
  727. sid := ep.sandboxID
  728. ep.Unlock()
  729. c.Lock()
  730. ps, ok := c.sandboxes[sid]
  731. c.Unlock()
  732. return ps, ok
  733. }
  734. func (ep *endpoint) getFirstInterfaceAddress() net.IP {
  735. ep.Lock()
  736. defer ep.Unlock()
  737. if ep.iface.addr != nil {
  738. return ep.iface.addr.IP
  739. }
  740. return nil
  741. }
  742. // EndpointOptionGeneric function returns an option setter for a Generic option defined
  743. // in a Dictionary of Key-Value pair
  744. func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
  745. return func(ep *endpoint) {
  746. for k, v := range generic {
  747. ep.generic[k] = v
  748. }
  749. }
  750. }
  751. var (
  752. linkLocalMask = net.CIDRMask(16, 32)
  753. linkLocalMaskIPv6 = net.CIDRMask(64, 128)
  754. )
  755. // CreateOptionIpam function returns an option setter for the ipam configuration for this endpoint
  756. func CreateOptionIpam(ipV4, ipV6 net.IP, llIPs []net.IP, ipamOptions map[string]string) EndpointOption {
  757. return func(ep *endpoint) {
  758. ep.prefAddress = ipV4
  759. ep.prefAddressV6 = ipV6
  760. if len(llIPs) != 0 {
  761. for _, ip := range llIPs {
  762. nw := &net.IPNet{IP: ip, Mask: linkLocalMask}
  763. if ip.To4() == nil {
  764. nw.Mask = linkLocalMaskIPv6
  765. }
  766. ep.iface.llAddrs = append(ep.iface.llAddrs, nw)
  767. }
  768. }
  769. ep.ipamOptions = ipamOptions
  770. }
  771. }
  772. // CreateOptionExposedPorts function returns an option setter for the container exposed
  773. // ports option to be passed to network.CreateEndpoint() method.
  774. func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption {
  775. return func(ep *endpoint) {
  776. // Defensive copy
  777. eps := make([]types.TransportPort, len(exposedPorts))
  778. copy(eps, exposedPorts)
  779. // Store endpoint label and in generic because driver needs it
  780. ep.exposedPorts = eps
  781. ep.generic[netlabel.ExposedPorts] = eps
  782. }
  783. }
  784. // CreateOptionPortMapping function returns an option setter for the mapping
  785. // ports option to be passed to network.CreateEndpoint() method.
  786. func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
  787. return func(ep *endpoint) {
  788. // Store a copy of the bindings as generic data to pass to the driver
  789. pbs := make([]types.PortBinding, len(portBindings))
  790. copy(pbs, portBindings)
  791. ep.generic[netlabel.PortMap] = pbs
  792. }
  793. }
  794. // CreateOptionDNS function returns an option setter for dns entry option to
  795. // be passed to container Create method.
  796. func CreateOptionDNS(dns []string) EndpointOption {
  797. return func(ep *endpoint) {
  798. ep.generic[netlabel.DNSServers] = dns
  799. }
  800. }
  801. // CreateOptionAnonymous function returns an option setter for setting
  802. // this endpoint as anonymous
  803. func CreateOptionAnonymous() EndpointOption {
  804. return func(ep *endpoint) {
  805. ep.anonymous = true
  806. }
  807. }
  808. // CreateOptionDisableResolution function returns an option setter to indicate
  809. // this endpoint doesn't want embedded DNS server functionality
  810. func CreateOptionDisableResolution() EndpointOption {
  811. return func(ep *endpoint) {
  812. ep.disableResolution = true
  813. }
  814. }
  815. //CreateOptionAlias function returns an option setter for setting endpoint alias
  816. func CreateOptionAlias(name string, alias string) EndpointOption {
  817. return func(ep *endpoint) {
  818. if ep.aliases == nil {
  819. ep.aliases = make(map[string]string)
  820. }
  821. ep.aliases[alias] = name
  822. }
  823. }
  824. // CreateOptionService function returns an option setter for setting service binding configuration
  825. func CreateOptionService(name, id string, vip net.IP, ingressPorts []*PortConfig, aliases []string) EndpointOption {
  826. return func(ep *endpoint) {
  827. ep.svcName = name
  828. ep.svcID = id
  829. ep.virtualIP = vip
  830. ep.ingressPorts = ingressPorts
  831. ep.svcAliases = aliases
  832. }
  833. }
  834. //CreateOptionMyAlias function returns an option setter for setting endpoint's self alias
  835. func CreateOptionMyAlias(alias string) EndpointOption {
  836. return func(ep *endpoint) {
  837. ep.myAliases = append(ep.myAliases, alias)
  838. }
  839. }
  840. // JoinOptionPriority function returns an option setter for priority option to
  841. // be passed to the endpoint.Join() method.
  842. func JoinOptionPriority(ep Endpoint, prio int) EndpointOption {
  843. return func(ep *endpoint) {
  844. // ep lock already acquired
  845. c := ep.network.getController()
  846. c.Lock()
  847. sb, ok := c.sandboxes[ep.sandboxID]
  848. c.Unlock()
  849. if !ok {
  850. logrus.Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
  851. return
  852. }
  853. sb.epPriority[ep.id] = prio
  854. }
  855. }
  856. func (ep *endpoint) DataScope() string {
  857. return ep.getNetwork().DataScope()
  858. }
  859. func (ep *endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool) error {
  860. var err error
  861. n := ep.getNetwork()
  862. if n.hasSpecialDriver() {
  863. return nil
  864. }
  865. logrus.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  866. if assignIPv4 {
  867. if err = ep.assignAddressVersion(4, ipam); err != nil {
  868. return err
  869. }
  870. }
  871. if assignIPv6 {
  872. err = ep.assignAddressVersion(6, ipam)
  873. }
  874. return err
  875. }
  876. func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
  877. var (
  878. poolID *string
  879. address **net.IPNet
  880. prefAdd net.IP
  881. progAdd net.IP
  882. )
  883. n := ep.getNetwork()
  884. switch ipVer {
  885. case 4:
  886. poolID = &ep.iface.v4PoolID
  887. address = &ep.iface.addr
  888. prefAdd = ep.prefAddress
  889. case 6:
  890. poolID = &ep.iface.v6PoolID
  891. address = &ep.iface.addrv6
  892. prefAdd = ep.prefAddressV6
  893. default:
  894. return types.InternalErrorf("incorrect ip version number passed: %d", ipVer)
  895. }
  896. ipInfo := n.getIPInfo(ipVer)
  897. // ipv6 address is not mandatory
  898. if len(ipInfo) == 0 && ipVer == 6 {
  899. return nil
  900. }
  901. // The address to program may be chosen by the user or by the network driver in one specific
  902. // case to support backward compatibility with `docker daemon --fixed-cidrv6` use case
  903. if prefAdd != nil {
  904. progAdd = prefAdd
  905. } else if *address != nil {
  906. progAdd = (*address).IP
  907. }
  908. for _, d := range ipInfo {
  909. if progAdd != nil && !d.Pool.Contains(progAdd) {
  910. continue
  911. }
  912. addr, _, err := ipam.RequestAddress(d.PoolID, progAdd, ep.ipamOptions)
  913. if err == nil {
  914. ep.Lock()
  915. *address = addr
  916. *poolID = d.PoolID
  917. ep.Unlock()
  918. return nil
  919. }
  920. if err != ipamapi.ErrNoAvailableIPs || progAdd != nil {
  921. return err
  922. }
  923. }
  924. if progAdd != nil {
  925. return types.BadRequestErrorf("Invalid address %s: It does not belong to any of this network's subnets", prefAdd)
  926. }
  927. return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
  928. }
  929. func (ep *endpoint) releaseAddress() {
  930. n := ep.getNetwork()
  931. if n.hasSpecialDriver() {
  932. return
  933. }
  934. logrus.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  935. ipam, _, err := n.getController().getIPAMDriver(n.ipamType)
  936. if err != nil {
  937. logrus.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
  938. return
  939. }
  940. if ep.iface.addr != nil {
  941. if err := ipam.ReleaseAddress(ep.iface.v4PoolID, ep.iface.addr.IP); err != nil {
  942. logrus.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
  943. }
  944. }
  945. if ep.iface.addrv6 != nil && ep.iface.addrv6.IP.IsGlobalUnicast() {
  946. if err := ipam.ReleaseAddress(ep.iface.v6PoolID, ep.iface.addrv6.IP); err != nil {
  947. logrus.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
  948. }
  949. }
  950. }
  951. func (c *controller) cleanupLocalEndpoints() {
  952. // Get used endpoints
  953. eps := make(map[string]interface{})
  954. for _, sb := range c.sandboxes {
  955. for _, ep := range sb.endpoints {
  956. eps[ep.id] = true
  957. }
  958. }
  959. nl, err := c.getNetworksForScope(datastore.LocalScope)
  960. if err != nil {
  961. logrus.Warnf("Could not get list of networks during endpoint cleanup: %v", err)
  962. return
  963. }
  964. for _, n := range nl {
  965. if n.ConfigOnly() {
  966. continue
  967. }
  968. epl, err := n.getEndpointsFromStore()
  969. if err != nil {
  970. logrus.Warnf("Could not get list of endpoints in network %s during endpoint cleanup: %v", n.name, err)
  971. continue
  972. }
  973. for _, ep := range epl {
  974. if _, ok := eps[ep.id]; ok {
  975. continue
  976. }
  977. logrus.Infof("Removing stale endpoint %s (%s)", ep.name, ep.id)
  978. if err := ep.Delete(true); err != nil {
  979. logrus.Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
  980. }
  981. }
  982. epl, err = n.getEndpointsFromStore()
  983. if err != nil {
  984. logrus.Warnf("Could not get list of endpoints in network %s for count update: %v", n.name, err)
  985. continue
  986. }
  987. epCnt := n.getEpCnt().EndpointCnt()
  988. if epCnt != uint64(len(epl)) {
  989. logrus.Infof("Fixing inconsistent endpoint_cnt for network %s. Expected=%d, Actual=%d", n.name, len(epl), epCnt)
  990. n.getEpCnt().setCnt(uint64(len(epl)))
  991. }
  992. }
  993. }