sandbox.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. package libnetwork
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net"
  7. "sort"
  8. "strings"
  9. "sync"
  10. "time"
  11. "github.com/containerd/containerd/log"
  12. "github.com/docker/docker/libnetwork/etchosts"
  13. "github.com/docker/docker/libnetwork/netlabel"
  14. "github.com/docker/docker/libnetwork/osl"
  15. "github.com/docker/docker/libnetwork/types"
  16. )
  17. // SandboxOption is an option setter function type used to pass various options to
  18. // NewNetContainer method. The various setter functions of type SandboxOption are
  19. // provided by libnetwork, they look like ContainerOptionXXXX(...)
  20. type SandboxOption func(sb *Sandbox)
  21. func (sb *Sandbox) processOptions(options ...SandboxOption) {
  22. for _, opt := range options {
  23. if opt != nil {
  24. opt(sb)
  25. }
  26. }
  27. }
  28. // Sandbox provides the control over the network container entity.
  29. // It is a one to one mapping with the container.
  30. type Sandbox struct {
  31. id string
  32. containerID string
  33. config containerConfig
  34. extDNS []extDNSEntry
  35. osSbox osl.Sandbox
  36. controller *Controller
  37. resolver *Resolver
  38. resolverOnce sync.Once
  39. endpoints []*Endpoint
  40. epPriority map[string]int
  41. populatedEndpoints map[string]struct{}
  42. joinLeaveDone chan struct{}
  43. dbIndex uint64
  44. dbExists bool
  45. isStub bool
  46. inDelete bool
  47. ingress bool
  48. ndotsSet bool
  49. oslTypes []osl.SandboxType // slice of properties of this sandbox
  50. loadBalancerNID string // NID that this SB is a load balancer for
  51. mu sync.Mutex
  52. // This mutex is used to serialize service related operation for an endpoint
  53. // The lock is here because the endpoint is saved into the store so is not unique
  54. service sync.Mutex
  55. }
  56. // These are the container configs used to customize container /etc/hosts file.
  57. type hostsPathConfig struct {
  58. hostName string
  59. domainName string
  60. hostsPath string
  61. originHostsPath string
  62. extraHosts []extraHost
  63. parentUpdates []parentUpdate
  64. }
  65. type parentUpdate struct {
  66. cid string
  67. name string
  68. ip string
  69. }
  70. type extraHost struct {
  71. name string
  72. IP string
  73. }
  74. // These are the container configs used to customize container /etc/resolv.conf file.
  75. type resolvConfPathConfig struct {
  76. resolvConfPath string
  77. originResolvConfPath string
  78. resolvConfHashFile string
  79. dnsList []string
  80. dnsSearchList []string
  81. dnsOptionsList []string
  82. }
  83. type containerConfig struct {
  84. hostsPathConfig
  85. resolvConfPathConfig
  86. generic map[string]interface{}
  87. useDefaultSandBox bool
  88. useExternalKey bool
  89. exposedPorts []types.TransportPort
  90. }
  91. const (
  92. resolverIPSandbox = "127.0.0.11"
  93. )
  94. // ID returns the ID of the sandbox.
  95. func (sb *Sandbox) ID() string {
  96. return sb.id
  97. }
  98. // ContainerID returns the container id associated to this sandbox.
  99. func (sb *Sandbox) ContainerID() string {
  100. return sb.containerID
  101. }
  102. // Key returns the sandbox's key.
  103. func (sb *Sandbox) Key() string {
  104. if sb.config.useDefaultSandBox {
  105. return osl.GenerateKey("default")
  106. }
  107. return osl.GenerateKey(sb.id)
  108. }
  109. // Labels returns the sandbox's labels.
  110. func (sb *Sandbox) Labels() map[string]interface{} {
  111. sb.mu.Lock()
  112. defer sb.mu.Unlock()
  113. opts := make(map[string]interface{}, len(sb.config.generic))
  114. for k, v := range sb.config.generic {
  115. opts[k] = v
  116. }
  117. return opts
  118. }
  119. // Statistics retrieves the interfaces' statistics for the sandbox.
  120. func (sb *Sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
  121. m := make(map[string]*types.InterfaceStatistics)
  122. sb.mu.Lock()
  123. osb := sb.osSbox
  124. sb.mu.Unlock()
  125. if osb == nil {
  126. return m, nil
  127. }
  128. var err error
  129. for _, i := range osb.Info().Interfaces() {
  130. if m[i.DstName()], err = i.Statistics(); err != nil {
  131. return m, err
  132. }
  133. }
  134. return m, nil
  135. }
  136. // Delete destroys this container after detaching it from all connected endpoints.
  137. func (sb *Sandbox) Delete() error {
  138. return sb.delete(false)
  139. }
  140. func (sb *Sandbox) delete(force bool) error {
  141. sb.mu.Lock()
  142. if sb.inDelete {
  143. sb.mu.Unlock()
  144. return types.ForbiddenErrorf("another sandbox delete in progress")
  145. }
  146. // Set the inDelete flag. This will ensure that we don't
  147. // update the store until we have completed all the endpoint
  148. // leaves and deletes. And when endpoint leaves and deletes
  149. // are completed then we can finally delete the sandbox object
  150. // altogether from the data store. If the daemon exits
  151. // ungracefully in the middle of a sandbox delete this way we
  152. // will have all the references to the endpoints in the
  153. // sandbox so that we can clean them up when we restart
  154. sb.inDelete = true
  155. sb.mu.Unlock()
  156. c := sb.controller
  157. // Detach from all endpoints
  158. retain := false
  159. for _, ep := range sb.Endpoints() {
  160. // gw network endpoint detach and removal are automatic
  161. if ep.endpointInGWNetwork() && !force {
  162. continue
  163. }
  164. // Retain the sanbdox if we can't obtain the network from store.
  165. if _, err := c.getNetworkFromStore(ep.getNetwork().ID()); err != nil {
  166. if c.isDistributedControl() {
  167. retain = true
  168. }
  169. log.G(context.TODO()).Warnf("Failed getting network for ep %s during sandbox %s delete: %v", ep.ID(), sb.ID(), err)
  170. continue
  171. }
  172. if !force {
  173. if err := ep.Leave(sb); err != nil {
  174. log.G(context.TODO()).Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
  175. }
  176. }
  177. if err := ep.Delete(force); err != nil {
  178. log.G(context.TODO()).Warnf("Failed deleting endpoint %s: %v\n", ep.ID(), err)
  179. }
  180. }
  181. if retain {
  182. sb.mu.Lock()
  183. sb.inDelete = false
  184. sb.mu.Unlock()
  185. return fmt.Errorf("could not cleanup all the endpoints in container %s / sandbox %s", sb.containerID, sb.id)
  186. }
  187. // Container is going away. Path cache in etchosts is most
  188. // likely not required any more. Drop it.
  189. etchosts.Drop(sb.config.hostsPath)
  190. if sb.resolver != nil {
  191. sb.resolver.Stop()
  192. }
  193. if sb.osSbox != nil && !sb.config.useDefaultSandBox {
  194. if err := sb.osSbox.Destroy(); err != nil {
  195. log.G(context.TODO()).WithError(err).Warn("error destroying network sandbox")
  196. }
  197. }
  198. if err := sb.storeDelete(); err != nil {
  199. log.G(context.TODO()).Warnf("Failed to delete sandbox %s from store: %v", sb.ID(), err)
  200. }
  201. c.mu.Lock()
  202. if sb.ingress {
  203. c.ingressSandbox = nil
  204. }
  205. delete(c.sandboxes, sb.ID())
  206. c.mu.Unlock()
  207. return nil
  208. }
  209. // Rename changes the name of all attached Endpoints.
  210. func (sb *Sandbox) Rename(name string) error {
  211. var err error
  212. for _, ep := range sb.Endpoints() {
  213. if ep.endpointInGWNetwork() {
  214. continue
  215. }
  216. oldName := ep.Name()
  217. lEp := ep
  218. if err = ep.rename(name); err != nil {
  219. break
  220. }
  221. defer func() {
  222. if err != nil {
  223. if err2 := lEp.rename(oldName); err2 != nil {
  224. log.G(context.TODO()).WithField("old", oldName).WithField("origError", err).WithError(err2).Error("error renaming sandbox")
  225. }
  226. }
  227. }()
  228. }
  229. return err
  230. }
  231. // Refresh leaves all the endpoints, resets and re-applies the options,
  232. // re-joins all the endpoints without destroying the osl sandbox
  233. func (sb *Sandbox) Refresh(options ...SandboxOption) error {
  234. // Store connected endpoints
  235. epList := sb.Endpoints()
  236. // Detach from all endpoints
  237. for _, ep := range epList {
  238. if err := ep.Leave(sb); err != nil {
  239. log.G(context.TODO()).Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
  240. }
  241. }
  242. // Re-apply options
  243. sb.config = containerConfig{}
  244. sb.processOptions(options...)
  245. // Setup discovery files
  246. if err := sb.setupResolutionFiles(); err != nil {
  247. return err
  248. }
  249. // Re-connect to all endpoints
  250. for _, ep := range epList {
  251. if err := ep.Join(sb); err != nil {
  252. log.G(context.TODO()).Warnf("Failed attach sandbox %s to endpoint %s: %v\n", sb.ID(), ep.ID(), err)
  253. }
  254. }
  255. return nil
  256. }
  257. func (sb *Sandbox) MarshalJSON() ([]byte, error) {
  258. sb.mu.Lock()
  259. defer sb.mu.Unlock()
  260. // We are just interested in the container ID. This can be expanded to include all of containerInfo if there is a need
  261. return json.Marshal(sb.id)
  262. }
  263. func (sb *Sandbox) UnmarshalJSON(b []byte) (err error) {
  264. sb.mu.Lock()
  265. defer sb.mu.Unlock()
  266. var id string
  267. if err := json.Unmarshal(b, &id); err != nil {
  268. return err
  269. }
  270. sb.id = id
  271. return nil
  272. }
  273. // Endpoints returns all the endpoints connected to the sandbox.
  274. func (sb *Sandbox) Endpoints() []*Endpoint {
  275. sb.mu.Lock()
  276. defer sb.mu.Unlock()
  277. eps := make([]*Endpoint, len(sb.endpoints))
  278. copy(eps, sb.endpoints)
  279. return eps
  280. }
  281. func (sb *Sandbox) addEndpoint(ep *Endpoint) {
  282. sb.mu.Lock()
  283. defer sb.mu.Unlock()
  284. l := len(sb.endpoints)
  285. i := sort.Search(l, func(j int) bool {
  286. return ep.Less(sb.endpoints[j])
  287. })
  288. sb.endpoints = append(sb.endpoints, nil)
  289. copy(sb.endpoints[i+1:], sb.endpoints[i:])
  290. sb.endpoints[i] = ep
  291. }
  292. func (sb *Sandbox) removeEndpoint(ep *Endpoint) {
  293. sb.mu.Lock()
  294. defer sb.mu.Unlock()
  295. sb.removeEndpointRaw(ep)
  296. }
  297. func (sb *Sandbox) removeEndpointRaw(ep *Endpoint) {
  298. for i, e := range sb.endpoints {
  299. if e == ep {
  300. sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...)
  301. return
  302. }
  303. }
  304. }
  305. func (sb *Sandbox) getEndpoint(id string) *Endpoint {
  306. sb.mu.Lock()
  307. defer sb.mu.Unlock()
  308. for _, ep := range sb.endpoints {
  309. if ep.id == id {
  310. return ep
  311. }
  312. }
  313. return nil
  314. }
  315. func (sb *Sandbox) updateGateway(ep *Endpoint) error {
  316. sb.mu.Lock()
  317. osSbox := sb.osSbox
  318. sb.mu.Unlock()
  319. if osSbox == nil {
  320. return nil
  321. }
  322. osSbox.UnsetGateway() //nolint:errcheck
  323. osSbox.UnsetGatewayIPv6() //nolint:errcheck
  324. if ep == nil {
  325. return nil
  326. }
  327. ep.mu.Lock()
  328. joinInfo := ep.joinInfo
  329. ep.mu.Unlock()
  330. if err := osSbox.SetGateway(joinInfo.gw); err != nil {
  331. return fmt.Errorf("failed to set gateway while updating gateway: %v", err)
  332. }
  333. if err := osSbox.SetGatewayIPv6(joinInfo.gw6); err != nil {
  334. return fmt.Errorf("failed to set IPv6 gateway while updating gateway: %v", err)
  335. }
  336. return nil
  337. }
  338. func (sb *Sandbox) HandleQueryResp(name string, ip net.IP) {
  339. for _, ep := range sb.Endpoints() {
  340. n := ep.getNetwork()
  341. n.HandleQueryResp(name, ip)
  342. }
  343. }
  344. func (sb *Sandbox) ResolveIP(ip string) string {
  345. var svc string
  346. log.G(context.TODO()).Debugf("IP To resolve %v", ip)
  347. for _, ep := range sb.Endpoints() {
  348. n := ep.getNetwork()
  349. svc = n.ResolveIP(ip)
  350. if len(svc) != 0 {
  351. return svc
  352. }
  353. }
  354. return svc
  355. }
  356. func (sb *Sandbox) ExecFunc(f func()) error {
  357. sb.mu.Lock()
  358. osSbox := sb.osSbox
  359. sb.mu.Unlock()
  360. if osSbox != nil {
  361. return osSbox.InvokeFunc(f)
  362. }
  363. return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID())
  364. }
  365. // ResolveService returns all the backend details about the containers or hosts
  366. // backing a service. Its purpose is to satisfy an SRV query.
  367. func (sb *Sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
  368. srv := []*net.SRV{}
  369. ip := []net.IP{}
  370. log.G(context.TODO()).Debugf("Service name To resolve: %v", name)
  371. // There are DNS implementations that allow SRV queries for names not in
  372. // the format defined by RFC 2782. Hence specific validations checks are
  373. // not done
  374. parts := strings.Split(name, ".")
  375. if len(parts) < 3 {
  376. return nil, nil
  377. }
  378. for _, ep := range sb.Endpoints() {
  379. n := ep.getNetwork()
  380. srv, ip = n.ResolveService(name)
  381. if len(srv) > 0 {
  382. break
  383. }
  384. }
  385. return srv, ip
  386. }
  387. func getDynamicNwEndpoints(epList []*Endpoint) []*Endpoint {
  388. eps := []*Endpoint{}
  389. for _, ep := range epList {
  390. n := ep.getNetwork()
  391. if n.dynamic && !n.ingress {
  392. eps = append(eps, ep)
  393. }
  394. }
  395. return eps
  396. }
  397. func getIngressNwEndpoint(epList []*Endpoint) *Endpoint {
  398. for _, ep := range epList {
  399. n := ep.getNetwork()
  400. if n.ingress {
  401. return ep
  402. }
  403. }
  404. return nil
  405. }
  406. func getLocalNwEndpoints(epList []*Endpoint) []*Endpoint {
  407. eps := []*Endpoint{}
  408. for _, ep := range epList {
  409. n := ep.getNetwork()
  410. if !n.dynamic && !n.ingress {
  411. eps = append(eps, ep)
  412. }
  413. }
  414. return eps
  415. }
  416. func (sb *Sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
  417. // Embedded server owns the docker network domain. Resolution should work
  418. // for both container_name and container_name.network_name
  419. // We allow '.' in service name and network name. For a name a.b.c.d the
  420. // following have to tried;
  421. // {a.b.c.d in the networks container is connected to}
  422. // {a.b.c in network d},
  423. // {a.b in network c.d},
  424. // {a in network b.c.d},
  425. log.G(context.TODO()).Debugf("Name To resolve: %v", name)
  426. name = strings.TrimSuffix(name, ".")
  427. reqName := []string{name}
  428. networkName := []string{""}
  429. if strings.Contains(name, ".") {
  430. var i int
  431. dup := name
  432. for {
  433. if i = strings.LastIndex(dup, "."); i == -1 {
  434. break
  435. }
  436. networkName = append(networkName, name[i+1:])
  437. reqName = append(reqName, name[:i])
  438. dup = dup[:i]
  439. }
  440. }
  441. epList := sb.Endpoints()
  442. // In swarm mode services with exposed ports are connected to user overlay
  443. // network, ingress network and docker_gwbridge network. Name resolution
  444. // should prioritize returning the VIP/IPs on user overlay network.
  445. newList := []*Endpoint{}
  446. if !sb.controller.isDistributedControl() {
  447. newList = append(newList, getDynamicNwEndpoints(epList)...)
  448. ingressEP := getIngressNwEndpoint(epList)
  449. if ingressEP != nil {
  450. newList = append(newList, ingressEP)
  451. }
  452. newList = append(newList, getLocalNwEndpoints(epList)...)
  453. epList = newList
  454. }
  455. for i := 0; i < len(reqName); i++ {
  456. // First check for local container alias
  457. ip, ipv6Miss := sb.resolveName(reqName[i], networkName[i], epList, true, ipType)
  458. if ip != nil {
  459. return ip, false
  460. }
  461. if ipv6Miss {
  462. return ip, ipv6Miss
  463. }
  464. // Resolve the actual container name
  465. ip, ipv6Miss = sb.resolveName(reqName[i], networkName[i], epList, false, ipType)
  466. if ip != nil {
  467. return ip, false
  468. }
  469. if ipv6Miss {
  470. return ip, ipv6Miss
  471. }
  472. }
  473. return nil, false
  474. }
  475. func (sb *Sandbox) resolveName(req string, networkName string, epList []*Endpoint, alias bool, ipType int) ([]net.IP, bool) {
  476. var ipv6Miss bool
  477. for _, ep := range epList {
  478. name := req
  479. n := ep.getNetwork()
  480. if networkName != "" && networkName != n.Name() {
  481. continue
  482. }
  483. if alias {
  484. if ep.aliases == nil {
  485. continue
  486. }
  487. var ok bool
  488. ep.mu.Lock()
  489. name, ok = ep.aliases[req]
  490. ep.mu.Unlock()
  491. if !ok {
  492. continue
  493. }
  494. } else {
  495. // If it is a regular lookup and if the requested name is an alias
  496. // don't perform a svc lookup for this endpoint.
  497. ep.mu.Lock()
  498. if _, ok := ep.aliases[req]; ok {
  499. ep.mu.Unlock()
  500. continue
  501. }
  502. ep.mu.Unlock()
  503. }
  504. ip, miss := n.ResolveName(name, ipType)
  505. if ip != nil {
  506. return ip, false
  507. }
  508. if miss {
  509. ipv6Miss = miss
  510. }
  511. }
  512. return nil, ipv6Miss
  513. }
  514. // SetKey updates the Sandbox Key.
  515. func (sb *Sandbox) SetKey(basePath string) error {
  516. start := time.Now()
  517. defer func() {
  518. log.G(context.TODO()).Debugf("sandbox set key processing took %s for container %s", time.Since(start), sb.ContainerID())
  519. }()
  520. if basePath == "" {
  521. return types.BadRequestErrorf("invalid sandbox key")
  522. }
  523. sb.mu.Lock()
  524. if sb.inDelete {
  525. sb.mu.Unlock()
  526. return types.ForbiddenErrorf("failed to SetKey: sandbox %q delete in progress", sb.id)
  527. }
  528. oldosSbox := sb.osSbox
  529. sb.mu.Unlock()
  530. if oldosSbox != nil {
  531. // If we already have an OS sandbox, release the network resources from that
  532. // and destroy the OS snab. We are moving into a new home further down. Note that none
  533. // of the network resources gets destroyed during the move.
  534. sb.releaseOSSbox()
  535. }
  536. osSbox, err := osl.GetSandboxForExternalKey(basePath, sb.Key())
  537. if err != nil {
  538. return err
  539. }
  540. sb.mu.Lock()
  541. sb.osSbox = osSbox
  542. sb.mu.Unlock()
  543. // If the resolver was setup before stop it and set it up in the
  544. // new osl sandbox.
  545. if oldosSbox != nil && sb.resolver != nil {
  546. sb.resolver.Stop()
  547. if err := sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0)); err == nil {
  548. if err := sb.resolver.Start(); err != nil {
  549. log.G(context.TODO()).Errorf("Resolver Start failed for container %s, %q", sb.ContainerID(), err)
  550. }
  551. } else {
  552. log.G(context.TODO()).Errorf("Resolver Setup Function failed for container %s, %q", sb.ContainerID(), err)
  553. }
  554. }
  555. for _, ep := range sb.Endpoints() {
  556. if err = sb.populateNetworkResources(ep); err != nil {
  557. return err
  558. }
  559. }
  560. return nil
  561. }
  562. // EnableService makes a managed container's service available by adding the
  563. // endpoint to the service load balancer and service discovery.
  564. func (sb *Sandbox) EnableService() (err error) {
  565. log.G(context.TODO()).Debugf("EnableService %s START", sb.containerID)
  566. defer func() {
  567. if err != nil {
  568. if err2 := sb.DisableService(); err2 != nil {
  569. log.G(context.TODO()).WithError(err2).WithField("origError", err).Error("Error while disabling service after original error")
  570. }
  571. }
  572. }()
  573. for _, ep := range sb.Endpoints() {
  574. if !ep.isServiceEnabled() {
  575. if err := ep.addServiceInfoToCluster(sb); err != nil {
  576. return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err)
  577. }
  578. ep.enableService()
  579. }
  580. }
  581. log.G(context.TODO()).Debugf("EnableService %s DONE", sb.containerID)
  582. return nil
  583. }
  584. // DisableService removes a managed container's endpoints from the load balancer
  585. // and service discovery.
  586. func (sb *Sandbox) DisableService() (err error) {
  587. log.G(context.TODO()).Debugf("DisableService %s START", sb.containerID)
  588. failedEps := []string{}
  589. defer func() {
  590. if len(failedEps) > 0 {
  591. err = fmt.Errorf("failed to disable service on sandbox:%s, for endpoints %s", sb.ID(), strings.Join(failedEps, ","))
  592. }
  593. }()
  594. for _, ep := range sb.Endpoints() {
  595. if ep.isServiceEnabled() {
  596. if err := ep.deleteServiceInfoFromCluster(sb, false, "DisableService"); err != nil {
  597. failedEps = append(failedEps, ep.Name())
  598. log.G(context.TODO()).Warnf("failed update state for endpoint %s into cluster: %v", ep.Name(), err)
  599. }
  600. ep.disableService()
  601. }
  602. }
  603. log.G(context.TODO()).Debugf("DisableService %s DONE", sb.containerID)
  604. return nil
  605. }
  606. func releaseOSSboxResources(osSbox osl.Sandbox, ep *Endpoint) {
  607. for _, i := range osSbox.Info().Interfaces() {
  608. // Only remove the interfaces owned by this endpoint from the sandbox.
  609. if ep.hasInterface(i.SrcName()) {
  610. if err := i.Remove(); err != nil {
  611. log.G(context.TODO()).Debugf("Remove interface %s failed: %v", i.SrcName(), err)
  612. }
  613. }
  614. }
  615. ep.mu.Lock()
  616. joinInfo := ep.joinInfo
  617. vip := ep.virtualIP
  618. lbModeIsDSR := ep.network.loadBalancerMode == loadBalancerModeDSR
  619. ep.mu.Unlock()
  620. if len(vip) > 0 && lbModeIsDSR {
  621. ipNet := &net.IPNet{IP: vip, Mask: net.CIDRMask(32, 32)}
  622. if err := osSbox.RemoveAliasIP(osSbox.GetLoopbackIfaceName(), ipNet); err != nil {
  623. log.G(context.TODO()).WithError(err).Debugf("failed to remove virtual ip %v to loopback", ipNet)
  624. }
  625. }
  626. if joinInfo == nil {
  627. return
  628. }
  629. // Remove non-interface routes.
  630. for _, r := range joinInfo.StaticRoutes {
  631. if err := osSbox.RemoveStaticRoute(r); err != nil {
  632. log.G(context.TODO()).Debugf("Remove route failed: %v", err)
  633. }
  634. }
  635. }
  636. func (sb *Sandbox) releaseOSSbox() {
  637. sb.mu.Lock()
  638. osSbox := sb.osSbox
  639. sb.osSbox = nil
  640. sb.mu.Unlock()
  641. if osSbox == nil {
  642. return
  643. }
  644. for _, ep := range sb.Endpoints() {
  645. releaseOSSboxResources(osSbox, ep)
  646. }
  647. if err := osSbox.Destroy(); err != nil {
  648. log.G(context.TODO()).WithError(err).Error("Error destroying os sandbox")
  649. }
  650. }
  651. func (sb *Sandbox) restoreOslSandbox() error {
  652. var routes []*types.StaticRoute
  653. // restore osl sandbox
  654. Ifaces := make(map[osl.Iface][]osl.IfaceOption)
  655. for _, ep := range sb.endpoints {
  656. ep.mu.Lock()
  657. joinInfo := ep.joinInfo
  658. i := ep.iface
  659. ep.mu.Unlock()
  660. if i == nil {
  661. log.G(context.TODO()).Errorf("error restoring endpoint %s for container %s", ep.Name(), sb.ContainerID())
  662. continue
  663. }
  664. ifaceOptions := []osl.IfaceOption{
  665. sb.osSbox.InterfaceOptions().Address(i.addr),
  666. sb.osSbox.InterfaceOptions().Routes(i.routes),
  667. }
  668. if i.addrv6 != nil && i.addrv6.IP.To16() != nil {
  669. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().AddressIPv6(i.addrv6))
  670. }
  671. if i.mac != nil {
  672. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
  673. }
  674. if len(i.llAddrs) != 0 {
  675. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
  676. }
  677. Ifaces[osl.Iface{SrcName: i.srcName, DstPrefix: i.dstPrefix}] = ifaceOptions
  678. if joinInfo != nil {
  679. routes = append(routes, joinInfo.StaticRoutes...)
  680. }
  681. if ep.needResolver() {
  682. sb.startResolver(true)
  683. }
  684. }
  685. gwep := sb.getGatewayEndpoint()
  686. if gwep == nil {
  687. return nil
  688. }
  689. // restore osl sandbox
  690. return sb.osSbox.Restore(Ifaces, routes, gwep.joinInfo.gw, gwep.joinInfo.gw6)
  691. }
  692. func (sb *Sandbox) populateNetworkResources(ep *Endpoint) error {
  693. sb.mu.Lock()
  694. if sb.osSbox == nil {
  695. sb.mu.Unlock()
  696. return nil
  697. }
  698. inDelete := sb.inDelete
  699. sb.mu.Unlock()
  700. ep.mu.Lock()
  701. joinInfo := ep.joinInfo
  702. i := ep.iface
  703. lbModeIsDSR := ep.network.loadBalancerMode == loadBalancerModeDSR
  704. ep.mu.Unlock()
  705. if ep.needResolver() {
  706. sb.startResolver(false)
  707. }
  708. if i != nil && i.srcName != "" {
  709. var ifaceOptions []osl.IfaceOption
  710. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().Address(i.addr), sb.osSbox.InterfaceOptions().Routes(i.routes))
  711. if i.addrv6 != nil && i.addrv6.IP.To16() != nil {
  712. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().AddressIPv6(i.addrv6))
  713. }
  714. if len(i.llAddrs) != 0 {
  715. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
  716. }
  717. if i.mac != nil {
  718. ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
  719. }
  720. if err := sb.osSbox.AddInterface(i.srcName, i.dstPrefix, ifaceOptions...); err != nil {
  721. return fmt.Errorf("failed to add interface %s to sandbox: %v", i.srcName, err)
  722. }
  723. if len(ep.virtualIP) > 0 && lbModeIsDSR {
  724. if sb.loadBalancerNID == "" {
  725. if err := sb.osSbox.DisableARPForVIP(i.srcName); err != nil {
  726. return fmt.Errorf("failed disable ARP for VIP: %v", err)
  727. }
  728. }
  729. ipNet := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
  730. if err := sb.osSbox.AddAliasIP(sb.osSbox.GetLoopbackIfaceName(), ipNet); err != nil {
  731. return fmt.Errorf("failed to add virtual ip %v to loopback: %v", ipNet, err)
  732. }
  733. }
  734. }
  735. if joinInfo != nil {
  736. // Set up non-interface routes.
  737. for _, r := range joinInfo.StaticRoutes {
  738. if err := sb.osSbox.AddStaticRoute(r); err != nil {
  739. return fmt.Errorf("failed to add static route %s: %v", r.Destination.String(), err)
  740. }
  741. }
  742. }
  743. if ep == sb.getGatewayEndpoint() {
  744. if err := sb.updateGateway(ep); err != nil {
  745. return err
  746. }
  747. }
  748. // Make sure to add the endpoint to the populated endpoint set
  749. // before populating loadbalancers.
  750. sb.mu.Lock()
  751. sb.populatedEndpoints[ep.ID()] = struct{}{}
  752. sb.mu.Unlock()
  753. // Populate load balancer only after updating all the other
  754. // information including gateway and other routes so that
  755. // loadbalancers are populated all the network state is in
  756. // place in the sandbox.
  757. sb.populateLoadBalancers(ep)
  758. // Only update the store if we did not come here as part of
  759. // sandbox delete. If we came here as part of delete then do
  760. // not bother updating the store. The sandbox object will be
  761. // deleted anyway
  762. if !inDelete {
  763. return sb.storeUpdate()
  764. }
  765. return nil
  766. }
  767. func (sb *Sandbox) clearNetworkResources(origEp *Endpoint) error {
  768. ep := sb.getEndpoint(origEp.id)
  769. if ep == nil {
  770. return fmt.Errorf("could not find the sandbox endpoint data for endpoint %s",
  771. origEp.id)
  772. }
  773. sb.mu.Lock()
  774. osSbox := sb.osSbox
  775. inDelete := sb.inDelete
  776. sb.mu.Unlock()
  777. if osSbox != nil {
  778. releaseOSSboxResources(osSbox, ep)
  779. }
  780. sb.mu.Lock()
  781. delete(sb.populatedEndpoints, ep.ID())
  782. if len(sb.endpoints) == 0 {
  783. // sb.endpoints should never be empty and this is unexpected error condition
  784. // We log an error message to note this down for debugging purposes.
  785. log.G(context.TODO()).Errorf("No endpoints in sandbox while trying to remove endpoint %s", ep.Name())
  786. sb.mu.Unlock()
  787. return nil
  788. }
  789. var (
  790. gwepBefore, gwepAfter *Endpoint
  791. index = -1
  792. )
  793. for i, e := range sb.endpoints {
  794. if e == ep {
  795. index = i
  796. }
  797. if len(e.Gateway()) > 0 && gwepBefore == nil {
  798. gwepBefore = e
  799. }
  800. if index != -1 && gwepBefore != nil {
  801. break
  802. }
  803. }
  804. if index == -1 {
  805. log.G(context.TODO()).Warnf("Endpoint %s has already been deleted", ep.Name())
  806. sb.mu.Unlock()
  807. return nil
  808. }
  809. sb.removeEndpointRaw(ep)
  810. for _, e := range sb.endpoints {
  811. if len(e.Gateway()) > 0 {
  812. gwepAfter = e
  813. break
  814. }
  815. }
  816. delete(sb.epPriority, ep.ID())
  817. sb.mu.Unlock()
  818. if gwepAfter != nil && gwepBefore != gwepAfter {
  819. if err := sb.updateGateway(gwepAfter); err != nil {
  820. return err
  821. }
  822. }
  823. // Only update the store if we did not come here as part of
  824. // sandbox delete. If we came here as part of delete then do
  825. // not bother updating the store. The sandbox object will be
  826. // deleted anyway
  827. if !inDelete {
  828. return sb.storeUpdate()
  829. }
  830. return nil
  831. }
  832. // joinLeaveStart waits to ensure there are no joins or leaves in progress and
  833. // marks this join/leave in progress without race
  834. func (sb *Sandbox) joinLeaveStart() {
  835. sb.mu.Lock()
  836. defer sb.mu.Unlock()
  837. for sb.joinLeaveDone != nil {
  838. joinLeaveDone := sb.joinLeaveDone
  839. sb.mu.Unlock()
  840. <-joinLeaveDone
  841. sb.mu.Lock()
  842. }
  843. sb.joinLeaveDone = make(chan struct{})
  844. }
  845. // joinLeaveEnd marks the end of this join/leave operation and
  846. // signals the same without race to other join and leave waiters
  847. func (sb *Sandbox) joinLeaveEnd() {
  848. sb.mu.Lock()
  849. defer sb.mu.Unlock()
  850. if sb.joinLeaveDone != nil {
  851. close(sb.joinLeaveDone)
  852. sb.joinLeaveDone = nil
  853. }
  854. }
  855. // OptionHostname function returns an option setter for hostname option to
  856. // be passed to NewSandbox method.
  857. func OptionHostname(name string) SandboxOption {
  858. return func(sb *Sandbox) {
  859. sb.config.hostName = name
  860. }
  861. }
  862. // OptionDomainname function returns an option setter for domainname option to
  863. // be passed to NewSandbox method.
  864. func OptionDomainname(name string) SandboxOption {
  865. return func(sb *Sandbox) {
  866. sb.config.domainName = name
  867. }
  868. }
  869. // OptionHostsPath function returns an option setter for hostspath option to
  870. // be passed to NewSandbox method.
  871. func OptionHostsPath(path string) SandboxOption {
  872. return func(sb *Sandbox) {
  873. sb.config.hostsPath = path
  874. }
  875. }
  876. // OptionOriginHostsPath function returns an option setter for origin hosts file path
  877. // to be passed to NewSandbox method.
  878. func OptionOriginHostsPath(path string) SandboxOption {
  879. return func(sb *Sandbox) {
  880. sb.config.originHostsPath = path
  881. }
  882. }
  883. // OptionExtraHost function returns an option setter for extra /etc/hosts options
  884. // which is a name and IP as strings.
  885. func OptionExtraHost(name string, IP string) SandboxOption {
  886. return func(sb *Sandbox) {
  887. sb.config.extraHosts = append(sb.config.extraHosts, extraHost{name: name, IP: IP})
  888. }
  889. }
  890. // OptionParentUpdate function returns an option setter for parent container
  891. // which needs to update the IP address for the linked container.
  892. func OptionParentUpdate(cid string, name, ip string) SandboxOption {
  893. return func(sb *Sandbox) {
  894. sb.config.parentUpdates = append(sb.config.parentUpdates, parentUpdate{cid: cid, name: name, ip: ip})
  895. }
  896. }
  897. // OptionResolvConfPath function returns an option setter for resolvconfpath option to
  898. // be passed to net container methods.
  899. func OptionResolvConfPath(path string) SandboxOption {
  900. return func(sb *Sandbox) {
  901. sb.config.resolvConfPath = path
  902. }
  903. }
  904. // OptionOriginResolvConfPath function returns an option setter to set the path to the
  905. // origin resolv.conf file to be passed to net container methods.
  906. func OptionOriginResolvConfPath(path string) SandboxOption {
  907. return func(sb *Sandbox) {
  908. sb.config.originResolvConfPath = path
  909. }
  910. }
  911. // OptionDNS function returns an option setter for dns entry option to
  912. // be passed to container Create method.
  913. func OptionDNS(dns string) SandboxOption {
  914. return func(sb *Sandbox) {
  915. sb.config.dnsList = append(sb.config.dnsList, dns)
  916. }
  917. }
  918. // OptionDNSSearch function returns an option setter for dns search entry option to
  919. // be passed to container Create method.
  920. func OptionDNSSearch(search string) SandboxOption {
  921. return func(sb *Sandbox) {
  922. sb.config.dnsSearchList = append(sb.config.dnsSearchList, search)
  923. }
  924. }
  925. // OptionDNSOptions function returns an option setter for dns options entry option to
  926. // be passed to container Create method.
  927. func OptionDNSOptions(options string) SandboxOption {
  928. return func(sb *Sandbox) {
  929. sb.config.dnsOptionsList = append(sb.config.dnsOptionsList, options)
  930. }
  931. }
  932. // OptionUseDefaultSandbox function returns an option setter for using default sandbox
  933. // (host namespace) to be passed to container Create method.
  934. func OptionUseDefaultSandbox() SandboxOption {
  935. return func(sb *Sandbox) {
  936. sb.config.useDefaultSandBox = true
  937. }
  938. }
  939. // OptionUseExternalKey function returns an option setter for using provided namespace
  940. // instead of creating one.
  941. func OptionUseExternalKey() SandboxOption {
  942. return func(sb *Sandbox) {
  943. sb.config.useExternalKey = true
  944. }
  945. }
  946. // OptionGeneric function returns an option setter for Generic configuration
  947. // that is not managed by libNetwork but can be used by the Drivers during the call to
  948. // net container creation method. Container Labels are a good example.
  949. func OptionGeneric(generic map[string]interface{}) SandboxOption {
  950. return func(sb *Sandbox) {
  951. if sb.config.generic == nil {
  952. sb.config.generic = make(map[string]interface{}, len(generic))
  953. }
  954. for k, v := range generic {
  955. sb.config.generic[k] = v
  956. }
  957. }
  958. }
  959. // OptionExposedPorts function returns an option setter for the container exposed
  960. // ports option to be passed to container Create method.
  961. func OptionExposedPorts(exposedPorts []types.TransportPort) SandboxOption {
  962. return func(sb *Sandbox) {
  963. if sb.config.generic == nil {
  964. sb.config.generic = make(map[string]interface{})
  965. }
  966. // Defensive copy
  967. eps := make([]types.TransportPort, len(exposedPorts))
  968. copy(eps, exposedPorts)
  969. // Store endpoint label and in generic because driver needs it
  970. sb.config.exposedPorts = eps
  971. sb.config.generic[netlabel.ExposedPorts] = eps
  972. }
  973. }
  974. // OptionPortMapping function returns an option setter for the mapping
  975. // ports option to be passed to container Create method.
  976. func OptionPortMapping(portBindings []types.PortBinding) SandboxOption {
  977. return func(sb *Sandbox) {
  978. if sb.config.generic == nil {
  979. sb.config.generic = make(map[string]interface{})
  980. }
  981. // Store a copy of the bindings as generic data to pass to the driver
  982. pbs := make([]types.PortBinding, len(portBindings))
  983. copy(pbs, portBindings)
  984. sb.config.generic[netlabel.PortMap] = pbs
  985. }
  986. }
  987. // OptionIngress function returns an option setter for marking a
  988. // sandbox as the controller's ingress sandbox.
  989. func OptionIngress() SandboxOption {
  990. return func(sb *Sandbox) {
  991. sb.ingress = true
  992. sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeIngress)
  993. }
  994. }
  995. // OptionLoadBalancer function returns an option setter for marking a
  996. // sandbox as a load balancer sandbox.
  997. func OptionLoadBalancer(nid string) SandboxOption {
  998. return func(sb *Sandbox) {
  999. sb.loadBalancerNID = nid
  1000. sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeLoadBalancer)
  1001. }
  1002. }
  1003. // <=> Returns true if a < b, false if a > b and advances to next level if a == b
  1004. // epi.prio <=> epj.prio # 2 < 1
  1005. // epi.gw <=> epj.gw # non-gw < gw
  1006. // epi.internal <=> epj.internal # non-internal < internal
  1007. // epi.joininfo <=> epj.joininfo # ipv6 < ipv4
  1008. // epi.name <=> epj.name # bar < foo
  1009. func (epi *Endpoint) Less(epj *Endpoint) bool {
  1010. var prioi, prioj int
  1011. sbi, _ := epi.getSandbox()
  1012. sbj, _ := epj.getSandbox()
  1013. // Prio defaults to 0
  1014. if sbi != nil {
  1015. prioi = sbi.epPriority[epi.ID()]
  1016. }
  1017. if sbj != nil {
  1018. prioj = sbj.epPriority[epj.ID()]
  1019. }
  1020. if prioi != prioj {
  1021. return prioi > prioj
  1022. }
  1023. gwi := epi.endpointInGWNetwork()
  1024. gwj := epj.endpointInGWNetwork()
  1025. if gwi != gwj {
  1026. return gwj
  1027. }
  1028. inti := epi.getNetwork().Internal()
  1029. intj := epj.getNetwork().Internal()
  1030. if inti != intj {
  1031. return intj
  1032. }
  1033. jii := 0
  1034. if epi.joinInfo != nil {
  1035. if epi.joinInfo.gw != nil {
  1036. jii = jii + 1
  1037. }
  1038. if epi.joinInfo.gw6 != nil {
  1039. jii = jii + 2
  1040. }
  1041. }
  1042. jij := 0
  1043. if epj.joinInfo != nil {
  1044. if epj.joinInfo.gw != nil {
  1045. jij = jij + 1
  1046. }
  1047. if epj.joinInfo.gw6 != nil {
  1048. jij = jij + 2
  1049. }
  1050. }
  1051. if jii != jij {
  1052. return jii > jij
  1053. }
  1054. return epi.network.Name() < epj.network.Name()
  1055. }
  1056. func (sb *Sandbox) NdotsSet() bool {
  1057. return sb.ndotsSet
  1058. }