github.com/gdevillele/moby@v1.13.0/daemon/oci_windows.go (about) 1 package daemon 2 3 import ( 4 "syscall" 5 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/docker/pkg/sysinfo" 10 "github.com/opencontainers/runtime-spec/specs-go" 11 ) 12 13 func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { 14 s := oci.DefaultSpec() 15 16 linkedEnv, err := daemon.setupLinkedContainers(c) 17 if err != nil { 18 return nil, err 19 } 20 21 // TODO Windows - this can be removed. Not used (UID/GID) 22 rootUID, rootGID := daemon.GetRemappedUIDGID() 23 if err := c.SetupWorkingDirectory(rootUID, rootGID); err != nil { 24 return nil, err 25 } 26 27 // In base spec 28 s.Hostname = c.FullHostname() 29 30 // In s.Mounts 31 mounts, err := daemon.setupMounts(c) 32 if err != nil { 33 return nil, err 34 } 35 for _, mount := range mounts { 36 m := specs.Mount{ 37 Source: mount.Source, 38 Destination: mount.Destination, 39 } 40 if !mount.Writable { 41 m.Options = append(m.Options, "ro") 42 } 43 s.Mounts = append(s.Mounts, m) 44 } 45 46 // In s.Process 47 s.Process.Args = append([]string{c.Path}, c.Args...) 48 if !c.Config.ArgsEscaped { 49 s.Process.Args = escapeArgs(s.Process.Args) 50 } 51 s.Process.Cwd = c.Config.WorkingDir 52 if len(s.Process.Cwd) == 0 { 53 // We default to C:\ to workaround the oddity of the case that the 54 // default directory for cmd running as LocalSystem (or 55 // ContainerAdministrator) is c:\windows\system32. Hence docker run 56 // <image> cmd will by default end in c:\windows\system32, rather 57 // than 'root' (/) on Linux. The oddity is that if you have a dockerfile 58 // which has no WORKDIR and has a COPY file ., . will be interpreted 59 // as c:\. Hence, setting it to default of c:\ makes for consistency. 60 s.Process.Cwd = `C:\` 61 } 62 s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv) 63 s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0] 64 s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1] 65 s.Process.Terminal = c.Config.Tty 66 s.Process.User.Username = c.Config.User 67 68 // In spec.Root. This is not set for Hyper-V containers 69 isHyperV := false 70 if c.HostConfig.Isolation.IsDefault() { 71 // Container using default isolation, so take the default from the daemon configuration 72 isHyperV = daemon.defaultIsolation.IsHyperV() 73 } else { 74 // Container may be requesting an explicit isolation mode. 75 isHyperV = c.HostConfig.Isolation.IsHyperV() 76 } 77 if !isHyperV { 78 s.Root.Path = c.BaseFS 79 } 80 s.Root.Readonly = false // Windows does not support a read-only root filesystem 81 82 // In s.Windows.Resources 83 // @darrenstahlmsft implement these resources 84 cpuShares := uint16(c.HostConfig.CPUShares) 85 cpuPercent := uint8(c.HostConfig.CPUPercent) 86 if c.HostConfig.NanoCPUs > 0 { 87 cpuPercent = uint8(c.HostConfig.NanoCPUs * 100 / int64(sysinfo.NumCPU()) / 1e9) 88 } 89 cpuCount := uint64(c.HostConfig.CPUCount) 90 memoryLimit := uint64(c.HostConfig.Memory) 91 s.Windows.Resources = &specs.WindowsResources{ 92 CPU: &specs.WindowsCPUResources{ 93 Percent: &cpuPercent, 94 Shares: &cpuShares, 95 Count: &cpuCount, 96 }, 97 Memory: &specs.WindowsMemoryResources{ 98 Limit: &memoryLimit, 99 //TODO Reservation: ..., 100 }, 101 Network: &specs.WindowsNetworkResources{ 102 //TODO Bandwidth: ..., 103 }, 104 Storage: &specs.WindowsStorageResources{ 105 Bps: &c.HostConfig.IOMaximumBandwidth, 106 Iops: &c.HostConfig.IOMaximumIOps, 107 }, 108 } 109 return (*specs.Spec)(&s), nil 110 } 111 112 func escapeArgs(args []string) []string { 113 escapedArgs := make([]string, len(args)) 114 for i, a := range args { 115 escapedArgs[i] = syscall.EscapeArg(a) 116 } 117 return escapedArgs 118 } 119 120 // mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig 121 // It will do nothing on non-Linux platform 122 func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) { 123 return 124 }