endpoint.go 31 KB

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