oci_solaris.go 4.7 KB

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