endpoint.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. package libnetwork
  2. import (
  3. "container/heap"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "strings"
  8. "sync"
  9. log "github.com/Sirupsen/logrus"
  10. "github.com/docker/libnetwork/datastore"
  11. "github.com/docker/libnetwork/ipamapi"
  12. "github.com/docker/libnetwork/netlabel"
  13. "github.com/docker/libnetwork/options"
  14. "github.com/docker/libnetwork/types"
  15. )
  16. // Endpoint represents a logical connection between a network and a sandbox.
  17. type Endpoint interface {
  18. // A system generated id for this endpoint.
  19. ID() string
  20. // Name returns the name of this endpoint.
  21. Name() string
  22. // Network returns the name of the network to which this endpoint is attached.
  23. Network() string
  24. // Join joins the sandbox to the endpoint and populates into the sandbox
  25. // the network resources allocated for the endpoint.
  26. Join(sandbox Sandbox, options ...EndpointOption) error
  27. // Leave detaches the network resources populated in the sandbox.
  28. Leave(sandbox Sandbox, options ...EndpointOption) error
  29. // Return certain operational data belonging to this endpoint
  30. Info() EndpointInfo
  31. // DriverInfo returns a collection of driver operational data related to this endpoint retrieved from the driver
  32. DriverInfo() (map[string]interface{}, error)
  33. // Delete and detaches this endpoint from the network.
  34. Delete() error
  35. }
  36. // EndpointOption is a option setter function type used to pass varios options to Network
  37. // and Endpoint interfaces methods. The various setter functions of type EndpointOption are
  38. // provided by libnetwork, they look like <Create|Join|Leave>Option[...](...)
  39. type EndpointOption func(ep *endpoint)
  40. type endpoint struct {
  41. name string
  42. id string
  43. network *network
  44. iface *endpointInterface
  45. joinInfo *endpointJoinInfo
  46. sandboxID string
  47. exposedPorts []types.TransportPort
  48. anonymous bool
  49. generic map[string]interface{}
  50. joinLeaveDone chan struct{}
  51. prefAddress net.IP
  52. ipamOptions map[string]string
  53. dbIndex uint64
  54. dbExists bool
  55. sync.Mutex
  56. }
  57. func (ep *endpoint) MarshalJSON() ([]byte, error) {
  58. ep.Lock()
  59. defer ep.Unlock()
  60. epMap := make(map[string]interface{})
  61. epMap["name"] = ep.name
  62. epMap["id"] = ep.id
  63. epMap["ep_iface"] = ep.iface
  64. epMap["exposed_ports"] = ep.exposedPorts
  65. if ep.generic != nil {
  66. epMap["generic"] = ep.generic
  67. }
  68. epMap["sandbox"] = ep.sandboxID
  69. epMap["anonymous"] = ep.anonymous
  70. return json.Marshal(epMap)
  71. }
  72. func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
  73. ep.Lock()
  74. defer ep.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. ib, _ := json.Marshal(epMap["ep_iface"])
  82. json.Unmarshal(ib, &ep.iface)
  83. tb, _ := json.Marshal(epMap["exposed_ports"])
  84. var tPorts []types.TransportPort
  85. json.Unmarshal(tb, &tPorts)
  86. ep.exposedPorts = tPorts
  87. cb, _ := json.Marshal(epMap["sandbox"])
  88. json.Unmarshal(cb, &ep.sandboxID)
  89. if v, ok := epMap["generic"]; ok {
  90. ep.generic = v.(map[string]interface{})
  91. if opt, ok := ep.generic[netlabel.PortMap]; ok {
  92. pblist := []types.PortBinding{}
  93. for i := 0; i < len(opt.([]interface{})); i++ {
  94. pb := types.PortBinding{}
  95. tmp := opt.([]interface{})[i].(map[string]interface{})
  96. bytes, err := json.Marshal(tmp)
  97. if err != nil {
  98. log.Error(err)
  99. break
  100. }
  101. err = json.Unmarshal(bytes, &pb)
  102. if err != nil {
  103. log.Error(err)
  104. break
  105. }
  106. pblist = append(pblist, pb)
  107. }
  108. ep.generic[netlabel.PortMap] = pblist
  109. }
  110. if opt, ok := ep.generic[netlabel.ExposedPorts]; ok {
  111. tplist := []types.TransportPort{}
  112. for i := 0; i < len(opt.([]interface{})); i++ {
  113. tp := types.TransportPort{}
  114. tmp := opt.([]interface{})[i].(map[string]interface{})
  115. bytes, err := json.Marshal(tmp)
  116. if err != nil {
  117. log.Error(err)
  118. break
  119. }
  120. err = json.Unmarshal(bytes, &tp)
  121. if err != nil {
  122. log.Error(err)
  123. break
  124. }
  125. tplist = append(tplist, tp)
  126. }
  127. ep.generic[netlabel.ExposedPorts] = tplist
  128. }
  129. }
  130. if v, ok := epMap["anonymous"]; ok {
  131. ep.anonymous = v.(bool)
  132. }
  133. return nil
  134. }
  135. func (ep *endpoint) New() datastore.KVObject {
  136. return &endpoint{network: ep.getNetwork()}
  137. }
  138. func (ep *endpoint) CopyTo(o datastore.KVObject) error {
  139. ep.Lock()
  140. defer ep.Unlock()
  141. dstEp := o.(*endpoint)
  142. dstEp.name = ep.name
  143. dstEp.id = ep.id
  144. dstEp.sandboxID = ep.sandboxID
  145. dstEp.dbIndex = ep.dbIndex
  146. dstEp.dbExists = ep.dbExists
  147. dstEp.anonymous = ep.anonymous
  148. if ep.iface != nil {
  149. dstEp.iface = &endpointInterface{}
  150. ep.iface.CopyTo(dstEp.iface)
  151. }
  152. dstEp.exposedPorts = make([]types.TransportPort, len(ep.exposedPorts))
  153. copy(dstEp.exposedPorts, ep.exposedPorts)
  154. dstEp.generic = options.Generic{}
  155. for k, v := range ep.generic {
  156. dstEp.generic[k] = v
  157. }
  158. return nil
  159. }
  160. func (ep *endpoint) ID() string {
  161. ep.Lock()
  162. defer ep.Unlock()
  163. return ep.id
  164. }
  165. func (ep *endpoint) Name() string {
  166. ep.Lock()
  167. defer ep.Unlock()
  168. return ep.name
  169. }
  170. func (ep *endpoint) Network() string {
  171. if ep.network == nil {
  172. return ""
  173. }
  174. return ep.network.name
  175. }
  176. func (ep *endpoint) isAnonymous() bool {
  177. ep.Lock()
  178. defer ep.Unlock()
  179. return ep.anonymous
  180. }
  181. // endpoint Key structure : endpoint/network-id/endpoint-id
  182. func (ep *endpoint) Key() []string {
  183. if ep.network == nil {
  184. return nil
  185. }
  186. return []string{datastore.EndpointKeyPrefix, ep.network.id, ep.id}
  187. }
  188. func (ep *endpoint) KeyPrefix() []string {
  189. if ep.network == nil {
  190. return nil
  191. }
  192. return []string{datastore.EndpointKeyPrefix, ep.network.id}
  193. }
  194. func (ep *endpoint) networkIDFromKey(key string) (string, error) {
  195. // endpoint Key structure : docker/libnetwork/endpoint/${network-id}/${endpoint-id}
  196. // it's an invalid key if the key doesn't have all the 5 key elements above
  197. keyElements := strings.Split(key, "/")
  198. if !strings.HasPrefix(key, datastore.Key(datastore.EndpointKeyPrefix)) || len(keyElements) < 5 {
  199. return "", fmt.Errorf("invalid endpoint key : %v", key)
  200. }
  201. // network-id is placed at index=3. pls refer to endpoint.Key() method
  202. return strings.Split(key, "/")[3], nil
  203. }
  204. func (ep *endpoint) Value() []byte {
  205. b, err := json.Marshal(ep)
  206. if err != nil {
  207. return nil
  208. }
  209. return b
  210. }
  211. func (ep *endpoint) SetValue(value []byte) error {
  212. return json.Unmarshal(value, ep)
  213. }
  214. func (ep *endpoint) Index() uint64 {
  215. ep.Lock()
  216. defer ep.Unlock()
  217. return ep.dbIndex
  218. }
  219. func (ep *endpoint) SetIndex(index uint64) {
  220. ep.Lock()
  221. defer ep.Unlock()
  222. ep.dbIndex = index
  223. ep.dbExists = true
  224. }
  225. func (ep *endpoint) Exists() bool {
  226. ep.Lock()
  227. defer ep.Unlock()
  228. return ep.dbExists
  229. }
  230. func (ep *endpoint) Skip() bool {
  231. return ep.getNetwork().Skip()
  232. }
  233. func (ep *endpoint) processOptions(options ...EndpointOption) {
  234. ep.Lock()
  235. defer ep.Unlock()
  236. for _, opt := range options {
  237. if opt != nil {
  238. opt(ep)
  239. }
  240. }
  241. }
  242. func (ep *endpoint) getNetwork() *network {
  243. ep.Lock()
  244. defer ep.Unlock()
  245. return ep.network
  246. }
  247. func (ep *endpoint) getNetworkFromStore() (*network, error) {
  248. if ep.network == nil {
  249. return nil, fmt.Errorf("invalid network object in endpoint %s", ep.Name())
  250. }
  251. return ep.network.ctrlr.getNetworkFromStore(ep.network.id)
  252. }
  253. func (ep *endpoint) Join(sbox Sandbox, options ...EndpointOption) error {
  254. if sbox == nil {
  255. return types.BadRequestErrorf("endpoint cannot be joined by nil container")
  256. }
  257. sb, ok := sbox.(*sandbox)
  258. if !ok {
  259. return types.BadRequestErrorf("not a valid Sandbox interface")
  260. }
  261. sb.joinLeaveStart()
  262. defer sb.joinLeaveEnd()
  263. return ep.sbJoin(sbox, options...)
  264. }
  265. func (ep *endpoint) sbJoin(sbox Sandbox, options ...EndpointOption) error {
  266. var err error
  267. sb, ok := sbox.(*sandbox)
  268. if !ok {
  269. return types.BadRequestErrorf("not a valid Sandbox interface")
  270. }
  271. network, err := ep.getNetworkFromStore()
  272. if err != nil {
  273. return fmt.Errorf("failed to get network from store during join: %v", err)
  274. }
  275. ep, err = network.getEndpointFromStore(ep.ID())
  276. if err != nil {
  277. return fmt.Errorf("failed to get endpoint from store during join: %v", err)
  278. }
  279. ep.Lock()
  280. if ep.sandboxID != "" {
  281. ep.Unlock()
  282. return types.ForbiddenErrorf("another container is attached to the same network endpoint")
  283. }
  284. ep.Unlock()
  285. ep.Lock()
  286. ep.network = network
  287. ep.sandboxID = sbox.ID()
  288. ep.joinInfo = &endpointJoinInfo{}
  289. epid := ep.id
  290. ep.Unlock()
  291. defer func() {
  292. if err != nil {
  293. ep.Lock()
  294. ep.sandboxID = ""
  295. ep.Unlock()
  296. }
  297. }()
  298. network.Lock()
  299. nid := network.id
  300. network.Unlock()
  301. ep.processOptions(options...)
  302. driver, err := network.driver()
  303. if err != nil {
  304. return fmt.Errorf("failed to join endpoint: %v", err)
  305. }
  306. err = driver.Join(nid, epid, sbox.Key(), ep, sbox.Labels())
  307. if err != nil {
  308. return err
  309. }
  310. defer func() {
  311. if err != nil {
  312. // Do not alter global err variable, it's needed by the previous defer
  313. if err := driver.Leave(nid, epid); err != nil {
  314. log.Warnf("driver leave failed while rolling back join: %v", err)
  315. }
  316. }
  317. }()
  318. // Watch for service records
  319. network.getController().watchSvcRecord(ep)
  320. address := ""
  321. if ip := ep.getFirstInterfaceAddress(); ip != nil {
  322. address = ip.String()
  323. }
  324. if err = sb.updateHostsFile(address, network.getSvcRecords(ep)); err != nil {
  325. return err
  326. }
  327. if err = sb.updateDNS(network.enableIPv6); err != nil {
  328. return err
  329. }
  330. if err = network.getController().updateToStore(ep); err != nil {
  331. return err
  332. }
  333. sb.Lock()
  334. heap.Push(&sb.endpoints, ep)
  335. sb.Unlock()
  336. defer func() {
  337. if err != nil {
  338. for i, e := range sb.getConnectedEndpoints() {
  339. if e == ep {
  340. sb.Lock()
  341. heap.Remove(&sb.endpoints, i)
  342. sb.Unlock()
  343. return
  344. }
  345. }
  346. }
  347. }()
  348. if err = sb.populateNetworkResources(ep); err != nil {
  349. return err
  350. }
  351. if sb.needDefaultGW() {
  352. return sb.setupDefaultGW(ep)
  353. }
  354. return sb.clearDefaultGW()
  355. }
  356. func (ep *endpoint) rename(name string) error {
  357. var err error
  358. n := ep.getNetwork()
  359. if n == nil {
  360. return fmt.Errorf("network not connected for ep %q", ep.name)
  361. }
  362. n.getController().Lock()
  363. netWatch, ok := n.getController().nmap[n.ID()]
  364. n.getController().Unlock()
  365. if !ok {
  366. return fmt.Errorf("watch null for network %q", n.Name())
  367. }
  368. n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), false)
  369. oldName := ep.name
  370. ep.name = name
  371. n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), true)
  372. defer func() {
  373. if err != nil {
  374. n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), false)
  375. ep.name = oldName
  376. n.updateSvcRecord(ep, n.getController().getLocalEps(netWatch), true)
  377. }
  378. }()
  379. // Update the store with the updated name
  380. if err = n.getController().updateToStore(ep); err != nil {
  381. return err
  382. }
  383. // After the name change do a dummy endpoint count update to
  384. // trigger the service record update in the peer nodes
  385. // Ignore the error because updateStore fail for EpCnt is a
  386. // benign error. Besides there is no meaningful recovery that
  387. // we can do. When the cluster recovers subsequent EpCnt update
  388. // will force the peers to get the correct EP name.
  389. n.getEpCnt().updateStore()
  390. return err
  391. }
  392. func (ep *endpoint) hasInterface(iName string) bool {
  393. ep.Lock()
  394. defer ep.Unlock()
  395. return ep.iface != nil && ep.iface.srcName == iName
  396. }
  397. func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
  398. if sbox == nil || sbox.ID() == "" || sbox.Key() == "" {
  399. return types.BadRequestErrorf("invalid Sandbox passed to enpoint leave: %v", sbox)
  400. }
  401. sb, ok := sbox.(*sandbox)
  402. if !ok {
  403. return types.BadRequestErrorf("not a valid Sandbox interface")
  404. }
  405. sb.joinLeaveStart()
  406. defer sb.joinLeaveEnd()
  407. return ep.sbLeave(sbox, options...)
  408. }
  409. func (ep *endpoint) sbLeave(sbox Sandbox, options ...EndpointOption) error {
  410. sb, ok := sbox.(*sandbox)
  411. if !ok {
  412. return types.BadRequestErrorf("not a valid Sandbox interface")
  413. }
  414. n, err := ep.getNetworkFromStore()
  415. if err != nil {
  416. return fmt.Errorf("failed to get network from store during leave: %v", err)
  417. }
  418. ep, err = n.getEndpointFromStore(ep.ID())
  419. if err != nil {
  420. return fmt.Errorf("failed to get endpoint from store during leave: %v", err)
  421. }
  422. ep.Lock()
  423. sid := ep.sandboxID
  424. ep.Unlock()
  425. if sid == "" {
  426. return types.ForbiddenErrorf("cannot leave endpoint with no attached sandbox")
  427. }
  428. if sid != sbox.ID() {
  429. return types.ForbiddenErrorf("unexpected sandbox ID in leave request. Expected %s. Got %s", ep.sandboxID, sbox.ID())
  430. }
  431. ep.processOptions(options...)
  432. d, err := n.driver()
  433. if err != nil {
  434. return fmt.Errorf("failed to leave endpoint: %v", err)
  435. }
  436. ep.Lock()
  437. ep.sandboxID = ""
  438. ep.network = n
  439. ep.Unlock()
  440. if err := d.Leave(n.id, ep.id); err != nil {
  441. if _, ok := err.(types.MaskableError); !ok {
  442. log.Warnf("driver error disconnecting container %s : %v", ep.name, err)
  443. }
  444. }
  445. if err := sb.clearNetworkResources(ep); err != nil {
  446. log.Warnf("Could not cleanup network resources on container %s disconnect: %v", ep.name, err)
  447. }
  448. // Update the store about the sandbox detach only after we
  449. // have completed sb.clearNetworkresources above to avoid
  450. // spurious logs when cleaning up the sandbox when the daemon
  451. // ungracefully exits and restarts before completing sandbox
  452. // detach but after store has been updated.
  453. if err := n.getController().updateToStore(ep); err != nil {
  454. return err
  455. }
  456. sb.deleteHostsEntries(n.getSvcRecords(ep))
  457. if !sb.inDelete && sb.needDefaultGW() {
  458. ep := sb.getEPwithoutGateway()
  459. if ep == nil {
  460. return fmt.Errorf("endpoint without GW expected, but not found")
  461. }
  462. return sb.setupDefaultGW(ep)
  463. }
  464. return sb.clearDefaultGW()
  465. }
  466. func (ep *endpoint) Delete() error {
  467. var err error
  468. n, err := ep.getNetworkFromStore()
  469. if err != nil {
  470. return fmt.Errorf("failed to get network during Delete: %v", err)
  471. }
  472. ep, err = n.getEndpointFromStore(ep.ID())
  473. if err != nil {
  474. return fmt.Errorf("failed to get endpoint from store during Delete: %v", err)
  475. }
  476. ep.Lock()
  477. epid := ep.id
  478. name := ep.name
  479. sb, _ := n.getController().SandboxByID(ep.sandboxID)
  480. if sb != nil {
  481. ep.Unlock()
  482. return &ActiveContainerError{name: name, id: epid}
  483. }
  484. ep.Unlock()
  485. if err = n.getController().deleteFromStore(ep); err != nil {
  486. return err
  487. }
  488. defer func() {
  489. if err != nil {
  490. ep.dbExists = false
  491. if e := n.getController().updateToStore(ep); e != nil {
  492. log.Warnf("failed to recreate endpoint in store %s : %v", name, e)
  493. }
  494. }
  495. }()
  496. if err = n.getEpCnt().DecEndpointCnt(); err != nil {
  497. return err
  498. }
  499. defer func() {
  500. if err != nil {
  501. if e := n.getEpCnt().IncEndpointCnt(); e != nil {
  502. log.Warnf("failed to update network %s : %v", n.name, e)
  503. }
  504. }
  505. }()
  506. // unwatch for service records
  507. n.getController().unWatchSvcRecord(ep)
  508. if err = ep.deleteEndpoint(); err != nil {
  509. return err
  510. }
  511. ep.releaseAddress()
  512. return nil
  513. }
  514. func (ep *endpoint) deleteEndpoint() error {
  515. ep.Lock()
  516. n := ep.network
  517. name := ep.name
  518. epid := ep.id
  519. ep.Unlock()
  520. driver, err := n.driver()
  521. if err != nil {
  522. return fmt.Errorf("failed to delete endpoint: %v", err)
  523. }
  524. if err := driver.DeleteEndpoint(n.id, epid); err != nil {
  525. if _, ok := err.(types.ForbiddenError); ok {
  526. return err
  527. }
  528. if _, ok := err.(types.MaskableError); !ok {
  529. log.Warnf("driver error deleting endpoint %s : %v", name, err)
  530. }
  531. }
  532. return nil
  533. }
  534. func (ep *endpoint) getSandbox() (*sandbox, bool) {
  535. ep.Lock()
  536. c := ep.network.getController()
  537. sid := ep.sandboxID
  538. ep.Unlock()
  539. c.Lock()
  540. ps, ok := c.sandboxes[sid]
  541. c.Unlock()
  542. return ps, ok
  543. }
  544. func (ep *endpoint) getFirstInterfaceAddress() net.IP {
  545. ep.Lock()
  546. defer ep.Unlock()
  547. if ep.iface.addr != nil {
  548. return ep.iface.addr.IP
  549. }
  550. return nil
  551. }
  552. // EndpointOptionGeneric function returns an option setter for a Generic option defined
  553. // in a Dictionary of Key-Value pair
  554. func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
  555. return func(ep *endpoint) {
  556. for k, v := range generic {
  557. ep.generic[k] = v
  558. }
  559. }
  560. }
  561. // CreateOptionIpam function returns an option setter for the ipam configuration for this endpoint
  562. func CreateOptionIpam(prefAddress net.IP, ipamOptions map[string]string) EndpointOption {
  563. return func(ep *endpoint) {
  564. ep.prefAddress = prefAddress
  565. ep.ipamOptions = ipamOptions
  566. }
  567. }
  568. // CreateOptionExposedPorts function returns an option setter for the container exposed
  569. // ports option to be passed to network.CreateEndpoint() method.
  570. func CreateOptionExposedPorts(exposedPorts []types.TransportPort) EndpointOption {
  571. return func(ep *endpoint) {
  572. // Defensive copy
  573. eps := make([]types.TransportPort, len(exposedPorts))
  574. copy(eps, exposedPorts)
  575. // Store endpoint label and in generic because driver needs it
  576. ep.exposedPorts = eps
  577. ep.generic[netlabel.ExposedPorts] = eps
  578. }
  579. }
  580. // CreateOptionPortMapping function returns an option setter for the mapping
  581. // ports option to be passed to network.CreateEndpoint() method.
  582. func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
  583. return func(ep *endpoint) {
  584. // Store a copy of the bindings as generic data to pass to the driver
  585. pbs := make([]types.PortBinding, len(portBindings))
  586. copy(pbs, portBindings)
  587. ep.generic[netlabel.PortMap] = pbs
  588. }
  589. }
  590. // CreateOptionAnonymous function returns an option setter for setting
  591. // this endpoint as anonymous
  592. func CreateOptionAnonymous() EndpointOption {
  593. return func(ep *endpoint) {
  594. ep.anonymous = true
  595. }
  596. }
  597. // JoinOptionPriority function returns an option setter for priority option to
  598. // be passed to the endpoint.Join() method.
  599. func JoinOptionPriority(ep Endpoint, prio int) EndpointOption {
  600. return func(ep *endpoint) {
  601. // ep lock already acquired
  602. c := ep.network.getController()
  603. c.Lock()
  604. sb, ok := c.sandboxes[ep.sandboxID]
  605. c.Unlock()
  606. if !ok {
  607. log.Errorf("Could not set endpoint priority value during Join to endpoint %s: No sandbox id present in endpoint", ep.id)
  608. return
  609. }
  610. sb.epPriority[ep.id] = prio
  611. }
  612. }
  613. func (ep *endpoint) DataScope() string {
  614. return ep.getNetwork().DataScope()
  615. }
  616. func (ep *endpoint) assignAddress(assignIPv4, assignIPv6 bool) error {
  617. var (
  618. ipam ipamapi.Ipam
  619. err error
  620. )
  621. n := ep.getNetwork()
  622. if n.Type() == "host" || n.Type() == "null" {
  623. return nil
  624. }
  625. log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  626. ipam, err = n.getController().getIpamDriver(n.ipamType)
  627. if err != nil {
  628. return err
  629. }
  630. if assignIPv4 {
  631. if err = ep.assignAddressVersion(4, ipam); err != nil {
  632. return err
  633. }
  634. }
  635. if assignIPv6 {
  636. err = ep.assignAddressVersion(6, ipam)
  637. }
  638. return err
  639. }
  640. func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
  641. var (
  642. poolID *string
  643. address **net.IPNet
  644. )
  645. n := ep.getNetwork()
  646. switch ipVer {
  647. case 4:
  648. poolID = &ep.iface.v4PoolID
  649. address = &ep.iface.addr
  650. case 6:
  651. poolID = &ep.iface.v6PoolID
  652. address = &ep.iface.addrv6
  653. default:
  654. return types.InternalErrorf("incorrect ip version number passed: %d", ipVer)
  655. }
  656. ipInfo := n.getIPInfo(ipVer)
  657. // ipv6 address is not mandatory
  658. if len(ipInfo) == 0 && ipVer == 6 {
  659. return nil
  660. }
  661. for _, d := range ipInfo {
  662. var prefIP net.IP
  663. if *address != nil {
  664. prefIP = (*address).IP
  665. }
  666. addr, _, err := ipam.RequestAddress(d.PoolID, prefIP, ep.ipamOptions)
  667. if err == nil {
  668. ep.Lock()
  669. *address = addr
  670. *poolID = d.PoolID
  671. ep.Unlock()
  672. return nil
  673. }
  674. if err != ipamapi.ErrNoAvailableIPs {
  675. return err
  676. }
  677. }
  678. return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
  679. }
  680. func (ep *endpoint) releaseAddress() {
  681. n := ep.getNetwork()
  682. if n.Type() == "host" || n.Type() == "null" {
  683. return
  684. }
  685. log.Debugf("Releasing addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
  686. ipam, err := n.getController().getIpamDriver(n.ipamType)
  687. if err != nil {
  688. log.Warnf("Failed to retrieve ipam driver to release interface address on delete of endpoint %s (%s): %v", ep.Name(), ep.ID(), err)
  689. return
  690. }
  691. if err := ipam.ReleaseAddress(ep.iface.v4PoolID, ep.iface.addr.IP); err != nil {
  692. log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addr.IP, ep.Name(), ep.ID(), err)
  693. }
  694. if ep.iface.addrv6 != nil && ep.iface.addrv6.IP.IsGlobalUnicast() {
  695. if err := ipam.ReleaseAddress(ep.iface.v6PoolID, ep.iface.addrv6.IP); err != nil {
  696. log.Warnf("Failed to release ip address %s on delete of endpoint %s (%s): %v", ep.iface.addrv6.IP, ep.Name(), ep.ID(), err)
  697. }
  698. }
  699. }
  700. func (c *controller) cleanupLocalEndpoints() {
  701. nl, err := c.getNetworksForScope(datastore.LocalScope)
  702. if err != nil {
  703. log.Warnf("Could not get list of networks during endpoint cleanup: %v", err)
  704. return
  705. }
  706. for _, n := range nl {
  707. epl, err := n.getEndpointsFromStore()
  708. if err != nil {
  709. log.Warnf("Could not get list of endpoints in network %s during endpoint cleanup: %v", n.name, err)
  710. continue
  711. }
  712. for _, ep := range epl {
  713. if err := ep.Delete(); err != nil {
  714. log.Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
  715. }
  716. }
  717. }
  718. }