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  }