oci_solaris.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package daemon
  2. import (
  3. "fmt"
  4. "sort"
  5. "strconv"
  6. containertypes "github.com/docker/docker/api/types/container"
  7. "github.com/docker/docker/container"
  8. "github.com/docker/docker/oci"
  9. "github.com/docker/libnetwork"
  10. "github.com/opencontainers/runtime-spec/specs-go"
  11. )
  12. func setResources(s *specs.Spec, r containertypes.Resources) error {
  13. mem := getMemoryResources(r)
  14. s.Solaris.CappedMemory = &mem
  15. capCPU := getCPUResources(r)
  16. s.Solaris.CappedCPU = &capCPU
  17. return nil
  18. }
  19. func setUser(s *specs.Spec, c *container.Container) error {
  20. uid, gid, additionalGids, err := getUser(c, c.Config.User)
  21. if err != nil {
  22. return err
  23. }
  24. s.Process.User.UID = uid
  25. s.Process.User.GID = gid
  26. s.Process.User.AdditionalGids = additionalGids
  27. return nil
  28. }
  29. func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) {
  30. return 0, 0, nil, nil
  31. }
  32. func (daemon *Daemon) getRunzAnet(ep libnetwork.Endpoint) (specs.Anet, error) {
  33. var (
  34. linkName string
  35. lowerLink string
  36. defRouter string
  37. )
  38. epInfo := ep.Info()
  39. if epInfo == nil {
  40. return specs.Anet{}, fmt.Errorf("invalid endpoint")
  41. }
  42. nw, err := daemon.GetNetworkByName(ep.Network())
  43. if err != nil {
  44. return specs.Anet{}, fmt.Errorf("Failed to get network %s: %v", ep.Network(), err)
  45. }
  46. // Evaluate default router, linkname and lowerlink for interface endpoint
  47. switch nw.Type() {
  48. case "bridge":
  49. defRouter = epInfo.Gateway().String()
  50. linkName = "net0" // Should always be net0 for a container
  51. // TODO We construct lowerlink here exactly as done for solaris bridge
  52. // initialization. Need modular code to reuse.
  53. options := nw.Info().DriverOptions()
  54. nwName := options["com.docker.network.bridge.name"]
  55. lastChar := nwName[len(nwName)-1:]
  56. if _, err = strconv.Atoi(lastChar); err != nil {
  57. lowerLink = nwName + "_0"
  58. } else {
  59. lowerLink = nwName
  60. }
  61. case "overlay":
  62. defRouter = ""
  63. linkName = "net1"
  64. // TODO Follows generateVxlanName() in solaris overlay.
  65. id := nw.ID()
  66. if len(nw.ID()) > 12 {
  67. id = nw.ID()[:12]
  68. }
  69. lowerLink = "vx_" + id + "_0"
  70. }
  71. runzanet := specs.Anet{
  72. Linkname: linkName,
  73. Lowerlink: lowerLink,
  74. Allowedaddr: epInfo.Iface().Address().String(),
  75. Configallowedaddr: "true",
  76. Defrouter: defRouter,
  77. Linkprotection: "mac-nospoof, ip-nospoof",
  78. Macaddress: epInfo.Iface().MacAddress().String(),
  79. }
  80. return runzanet, nil
  81. }
  82. func (daemon *Daemon) setNetworkInterface(s *specs.Spec, c *container.Container) error {
  83. var anets []specs.Anet
  84. sb, err := daemon.netController.SandboxByID(c.NetworkSettings.SandboxID)
  85. if err != nil {
  86. return fmt.Errorf("Could not obtain sandbox for container")
  87. }
  88. // Populate interfaces required for each endpoint
  89. for _, ep := range sb.Endpoints() {
  90. runzanet, err := daemon.getRunzAnet(ep)
  91. if err != nil {
  92. return fmt.Errorf("Failed to get interface information for endpoint %d: %v", ep.ID(), err)
  93. }
  94. anets = append(anets, runzanet)
  95. }
  96. s.Solaris.Anet = anets
  97. if anets != nil {
  98. s.Solaris.Milestone = "svc:/milestone/container:default"
  99. }
  100. return nil
  101. }
  102. func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) error {
  103. linkedEnv, err := daemon.setupLinkedContainers(c)
  104. if err != nil {
  105. return err
  106. }
  107. s.Root = specs.Root{
  108. Path: c.BaseFS.Dir(c.BaseFS.Path()),
  109. Readonly: c.HostConfig.ReadonlyRootfs,
  110. }
  111. if err := c.SetupWorkingDirectory(daemon.idMappings.RootPair()); err != nil {
  112. return err
  113. }
  114. cwd := c.Config.WorkingDir
  115. s.Process.Args = append([]string{c.Path}, c.Args...)
  116. s.Process.Cwd = cwd
  117. s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
  118. s.Process.Terminal = c.Config.Tty
  119. s.Hostname = c.FullHostname()
  120. return nil
  121. }
  122. func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
  123. s := oci.DefaultSpec()
  124. if err := daemon.populateCommonSpec(&s, c); err != nil {
  125. return nil, err
  126. }
  127. if err := setResources(&s, c.HostConfig.Resources); err != nil {
  128. return nil, fmt.Errorf("runtime spec resources: %v", err)
  129. }
  130. if err := setUser(&s, c); err != nil {
  131. return nil, fmt.Errorf("spec user: %v", err)
  132. }
  133. if err := daemon.setNetworkInterface(&s, c); err != nil {
  134. return nil, err
  135. }
  136. if err := daemon.setupIpcDirs(c); err != nil {
  137. return nil, err
  138. }
  139. ms, err := daemon.setupMounts(c)
  140. if err != nil {
  141. return nil, err
  142. }
  143. ms = append(ms, c.IpcMounts()...)
  144. tmpfsMounts, err := c.TmpfsMounts()
  145. if err != nil {
  146. return nil, err
  147. }
  148. ms = append(ms, tmpfsMounts...)
  149. sort.Sort(mounts(ms))
  150. return (*specs.Spec)(&s), nil
  151. }
  152. // mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
  153. // It will do nothing on non-Linux platform
  154. func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
  155. return
  156. }