123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- package daemon
- import (
- "fmt"
- "path/filepath"
- "sort"
- "strconv"
- containertypes "github.com/docker/docker/api/types/container"
- "github.com/docker/docker/container"
- "github.com/docker/docker/oci"
- "github.com/docker/libnetwork"
- "github.com/opencontainers/runtime-spec/specs-go"
- )
- func setResources(s *specs.Spec, r containertypes.Resources) error {
- mem := getMemoryResources(r)
- s.Solaris.CappedMemory = &mem
- capCPU := getCPUResources(r)
- s.Solaris.CappedCPU = &capCPU
- return nil
- }
- func setUser(s *specs.Spec, c *container.Container) error {
- uid, gid, additionalGids, err := getUser(c, c.Config.User)
- if err != nil {
- return err
- }
- s.Process.User.UID = uid
- s.Process.User.GID = gid
- s.Process.User.AdditionalGids = additionalGids
- return nil
- }
- func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) {
- return 0, 0, nil, nil
- }
- func (daemon *Daemon) getRunzAnet(ep libnetwork.Endpoint) (specs.Anet, error) {
- var (
- linkName string
- lowerLink string
- defRouter string
- )
- epInfo := ep.Info()
- if epInfo == nil {
- return specs.Anet{}, fmt.Errorf("invalid endpoint")
- }
- nw, err := daemon.GetNetworkByName(ep.Network())
- if err != nil {
- return specs.Anet{}, fmt.Errorf("Failed to get network %s: %v", ep.Network(), err)
- }
- // Evaluate default router, linkname and lowerlink for interface endpoint
- switch nw.Type() {
- case "bridge":
- defRouter = epInfo.Gateway().String()
- linkName = "net0" // Should always be net0 for a container
- // TODO We construct lowerlink here exactly as done for solaris bridge
- // initialization. Need modular code to reuse.
- options := nw.Info().DriverOptions()
- nwName := options["com.docker.network.bridge.name"]
- lastChar := nwName[len(nwName)-1:]
- if _, err = strconv.Atoi(lastChar); err != nil {
- lowerLink = nwName + "_0"
- } else {
- lowerLink = nwName
- }
- case "overlay":
- defRouter = ""
- linkName = "net1"
- // TODO Follows generateVxlanName() in solaris overlay.
- id := nw.ID()
- if len(nw.ID()) > 12 {
- id = nw.ID()[:12]
- }
- lowerLink = "vx_" + id + "_0"
- }
- runzanet := specs.Anet{
- Linkname: linkName,
- Lowerlink: lowerLink,
- Allowedaddr: epInfo.Iface().Address().String(),
- Configallowedaddr: "true",
- Defrouter: defRouter,
- Linkprotection: "mac-nospoof, ip-nospoof",
- Macaddress: epInfo.Iface().MacAddress().String(),
- }
- return runzanet, nil
- }
- func (daemon *Daemon) setNetworkInterface(s *specs.Spec, c *container.Container) error {
- var anets []specs.Anet
- sb, err := daemon.netController.SandboxByID(c.NetworkSettings.SandboxID)
- if err != nil {
- return fmt.Errorf("Could not obtain sandbox for container")
- }
- // Populate interfaces required for each endpoint
- for _, ep := range sb.Endpoints() {
- runzanet, err := daemon.getRunzAnet(ep)
- if err != nil {
- return fmt.Errorf("Failed to get interface information for endpoint %d: %v", ep.ID(), err)
- }
- anets = append(anets, runzanet)
- }
- s.Solaris.Anet = anets
- if anets != nil {
- s.Solaris.Milestone = "svc:/milestone/container:default"
- }
- return nil
- }
- func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) error {
- linkedEnv, err := daemon.setupLinkedContainers(c)
- if err != nil {
- return err
- }
- s.Root = specs.Root{
- Path: filepath.Dir(c.BaseFS),
- Readonly: c.HostConfig.ReadonlyRootfs,
- }
- rootUID, rootGID := daemon.GetRemappedUIDGID()
- if err := c.SetupWorkingDirectory(rootUID, rootGID); err != nil {
- return err
- }
- cwd := c.Config.WorkingDir
- s.Process.Args = append([]string{c.Path}, c.Args...)
- s.Process.Cwd = cwd
- s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
- s.Process.Terminal = c.Config.Tty
- s.Hostname = c.FullHostname()
- return nil
- }
- func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
- s := oci.DefaultSpec()
- if err := daemon.populateCommonSpec(&s, c); err != nil {
- return nil, err
- }
- if err := setResources(&s, c.HostConfig.Resources); err != nil {
- return nil, fmt.Errorf("runtime spec resources: %v", err)
- }
- if err := setUser(&s, c); err != nil {
- return nil, fmt.Errorf("spec user: %v", err)
- }
- if err := daemon.setNetworkInterface(&s, c); err != nil {
- return nil, err
- }
- if err := daemon.setupIpcDirs(c); err != nil {
- return nil, err
- }
- ms, err := daemon.setupMounts(c)
- if err != nil {
- return nil, err
- }
- ms = append(ms, c.IpcMounts()...)
- tmpfsMounts, err := c.TmpfsMounts()
- if err != nil {
- return nil, err
- }
- ms = append(ms, tmpfsMounts...)
- sort.Sort(mounts(ms))
- return (*specs.Spec)(&s), nil
- }
- // mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
- // It will do nothing on non-Linux platform
- func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
- return
- }
|