endpoint.go 32 KB

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