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