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 }