endpoint.go 31 KB

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