daemon/oci_windows.go
94d70d83
 package daemon
 
 import (
 	"syscall"
 
7d705a73
 	containertypes "github.com/docker/docker/api/types/container"
94d70d83
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/oci"
846baf1f
 	"github.com/docker/docker/pkg/sysinfo"
02309170
 	"github.com/opencontainers/runtime-spec/specs-go"
94d70d83
 )
 
02309170
 func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
94d70d83
 	s := oci.DefaultSpec()
 
 	linkedEnv, err := daemon.setupLinkedContainers(c)
 	if err != nil {
 		return nil, err
 	}
 
 	// TODO Windows - this can be removed. Not used (UID/GID)
 	rootUID, rootGID := daemon.GetRemappedUIDGID()
 	if err := c.SetupWorkingDirectory(rootUID, rootGID); err != nil {
 		return nil, err
 	}
 
 	// In base spec
 	s.Hostname = c.FullHostname()
 
 	// In s.Mounts
 	mounts, err := daemon.setupMounts(c)
 	if err != nil {
 		return nil, err
 	}
 	for _, mount := range mounts {
02309170
 		m := specs.Mount{
94d70d83
 			Source:      mount.Source,
 			Destination: mount.Destination,
bb585b9c
 		}
 		if !mount.Writable {
 			m.Options = append(m.Options, "ro")
 		}
 		s.Mounts = append(s.Mounts, m)
94d70d83
 	}
 
 	// In s.Process
6fa02397
 	s.Process.Args = append([]string{c.Path}, c.Args...)
 	if !c.Config.ArgsEscaped {
 		s.Process.Args = escapeArgs(s.Process.Args)
94d70d83
 	}
 	s.Process.Cwd = c.Config.WorkingDir
c2d18342
 	if len(s.Process.Cwd) == 0 {
 		// We default to C:\ to workaround the oddity of the case that the
 		// default directory for cmd running as LocalSystem (or
 		// ContainerAdministrator) is c:\windows\system32. Hence docker run
 		// <image> cmd will by default end in c:\windows\system32, rather
 		// than 'root' (/) on Linux. The oddity is that if you have a dockerfile
 		// which has no WORKDIR and has a COPY file ., . will be interpreted
 		// as c:\. Hence, setting it to default of c:\ makes for consistency.
 		s.Process.Cwd = `C:\`
 	}
e9814596
 	s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
6b74e2f0
 	s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0]
 	s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1]
94d70d83
 	s.Process.Terminal = c.Config.Tty
93f61b85
 	s.Process.User.Username = c.Config.User
94d70d83
 
8f76a1d0
 	// In spec.Root. This is not set for Hyper-V containers
 	isHyperV := false
 	if c.HostConfig.Isolation.IsDefault() {
 		// Container using default isolation, so take the default from the daemon configuration
 		isHyperV = daemon.defaultIsolation.IsHyperV()
 	} else {
 		// Container may be requesting an explicit isolation mode.
 		isHyperV = c.HostConfig.Isolation.IsHyperV()
 	}
 	if !isHyperV {
 		s.Root.Path = c.BaseFS
 	}
 	s.Root.Readonly = false // Windows does not support a read-only root filesystem
94d70d83
 
 	// In s.Windows.Resources
 	// @darrenstahlmsft implement these resources
02309170
 	cpuShares := uint16(c.HostConfig.CPUShares)
 	cpuPercent := uint8(c.HostConfig.CPUPercent)
846baf1f
 	if c.HostConfig.NanoCPUs > 0 {
 		cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9)
 	}
4e15420b
 	cpuCount := uint64(c.HostConfig.CPUCount)
02309170
 	memoryLimit := uint64(c.HostConfig.Memory)
 	s.Windows.Resources = &specs.WindowsResources{
 		CPU: &specs.WindowsCPUResources{
 			Percent: &cpuPercent,
ea8c6908
 			Shares:  &cpuShares,
4e15420b
 			Count:   &cpuCount,
94d70d83
 		},
02309170
 		Memory: &specs.WindowsMemoryResources{
 			Limit: &memoryLimit,
12fe27a4
 			//TODO Reservation: ...,
94d70d83
 		},
02309170
 		Network: &specs.WindowsNetworkResources{
94d70d83
 		//TODO Bandwidth: ...,
 		},
02309170
 		Storage: &specs.WindowsStorageResources{
8df20663
 			Bps:  &c.HostConfig.IOMaximumBandwidth,
 			Iops: &c.HostConfig.IOMaximumIOps,
94d70d83
 		},
 	}
02309170
 	return (*specs.Spec)(&s), nil
94d70d83
 }
 
 func escapeArgs(args []string) []string {
 	escapedArgs := make([]string, len(args))
 	for i, a := range args {
 		escapedArgs[i] = syscall.EscapeArg(a)
 	}
 	return escapedArgs
 }
7d705a73
 
 // 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
 }