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
} |