|
@@ -27,10 +27,13 @@ import (
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
- defaultNetworkSpace = "172.16.0.0/12"
|
|
|
- platformSupported = true
|
|
|
- windowsMinCPUShares = 1
|
|
|
- windowsMaxCPUShares = 10000
|
|
|
+ defaultNetworkSpace = "172.16.0.0/12"
|
|
|
+ platformSupported = true
|
|
|
+ windowsMinCPUShares = 1
|
|
|
+ windowsMaxCPUShares = 10000
|
|
|
+ windowsMinCPUPercent = 1
|
|
|
+ windowsMaxCPUPercent = 100
|
|
|
+ windowsMinCPUCount = 1
|
|
|
)
|
|
|
|
|
|
func getBlkioWeightDevices(config *containertypes.HostConfig) ([]blkiodev.WeightDevice, error) {
|
|
@@ -80,6 +83,15 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+ numCPU := int64(sysinfo.NumCPU())
|
|
|
+ if hostConfig.CPUCount < 0 {
|
|
|
+ logrus.Warnf("Changing requested CPUCount of %d to minimum allowed of %d", hostConfig.CPUCount, windowsMinCPUCount)
|
|
|
+ hostConfig.CPUCount = windowsMinCPUCount
|
|
|
+ } else if hostConfig.CPUCount > numCPU {
|
|
|
+ logrus.Warnf("Changing requested CPUCount of %d to current number of processors, %d", hostConfig.CPUCount, numCPU)
|
|
|
+ hostConfig.CPUCount = numCPU
|
|
|
+ }
|
|
|
+
|
|
|
if hostConfig.CPUShares < 0 {
|
|
|
logrus.Warnf("Changing requested CPUShares of %d to minimum allowed of %d", hostConfig.CPUShares, windowsMinCPUShares)
|
|
|
hostConfig.CPUShares = windowsMinCPUShares
|
|
@@ -88,19 +100,42 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
|
|
|
hostConfig.CPUShares = windowsMaxCPUShares
|
|
|
}
|
|
|
|
|
|
+ if hostConfig.CPUPercent < 0 {
|
|
|
+ logrus.Warnf("Changing requested CPUPercent of %d to minimum allowed of %d", hostConfig.CPUPercent, windowsMinCPUPercent)
|
|
|
+ hostConfig.CPUPercent = windowsMinCPUPercent
|
|
|
+ } else if hostConfig.CPUPercent > windowsMaxCPUPercent {
|
|
|
+ logrus.Warnf("Changing requested CPUPercent of %d to maximum allowed of %d", hostConfig.CPUPercent, windowsMaxCPUPercent)
|
|
|
+ hostConfig.CPUPercent = windowsMaxCPUPercent
|
|
|
+ }
|
|
|
+
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysinfo.SysInfo) ([]string, error) {
|
|
|
+func verifyContainerResources(resources *containertypes.Resources, isHyperv bool) ([]string, error) {
|
|
|
warnings := []string{}
|
|
|
|
|
|
- // cpu subsystem checks and adjustments
|
|
|
- if resources.CPUPercent < 0 || resources.CPUPercent > 100 {
|
|
|
- return warnings, fmt.Errorf("Range of CPU percent is from 1 to 100")
|
|
|
- }
|
|
|
-
|
|
|
- if resources.CPUPercent > 0 && resources.CPUShares > 0 {
|
|
|
- return warnings, fmt.Errorf("Conflicting options: CPU Shares and CPU Percent cannot both be set")
|
|
|
+ if !isHyperv {
|
|
|
+ // The processor resource controls are mutually exclusive on
|
|
|
+ // Windows Server Containers, the order of precedence is
|
|
|
+ // CPUCount first, then CPUShares, and CPUPercent last.
|
|
|
+ if resources.CPUCount > 0 {
|
|
|
+ if resources.CPUShares > 0 {
|
|
|
+ warnings = append(warnings, "Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded")
|
|
|
+ logrus.Warn("Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded")
|
|
|
+ resources.CPUShares = 0
|
|
|
+ }
|
|
|
+ if resources.CPUPercent > 0 {
|
|
|
+ warnings = append(warnings, "Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded")
|
|
|
+ logrus.Warn("Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded")
|
|
|
+ resources.CPUPercent = 0
|
|
|
+ }
|
|
|
+ } else if resources.CPUShares > 0 {
|
|
|
+ if resources.CPUPercent > 0 {
|
|
|
+ warnings = append(warnings, "Conflicting options: CPU shares takes priority over CPU percent on Windows Server Containers. CPU percent discarded")
|
|
|
+ logrus.Warn("Conflicting options: CPU shares takes priority over CPU percent on Windows Server Containers. CPU percent discarded")
|
|
|
+ resources.CPUPercent = 0
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if resources.NanoCPUs > 0 && resources.CPUPercent > 0 {
|
|
@@ -154,7 +189,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
|
|
|
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
|
|
|
warnings := []string{}
|
|
|
|
|
|
- w, err := verifyContainerResources(&hostConfig.Resources, nil)
|
|
|
+ w, err := verifyContainerResources(&hostConfig.Resources, daemon.runAsHyperVContainer(hostConfig))
|
|
|
warnings = append(warnings, w...)
|
|
|
if err != nil {
|
|
|
return warnings, err
|
|
@@ -388,14 +423,14 @@ func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error
|
|
|
}
|
|
|
|
|
|
// runasHyperVContainer returns true if we are going to run as a Hyper-V container
|
|
|
-func (daemon *Daemon) runAsHyperVContainer(container *container.Container) bool {
|
|
|
- if container.HostConfig.Isolation.IsDefault() {
|
|
|
+func (daemon *Daemon) runAsHyperVContainer(hostConfig *containertypes.HostConfig) bool {
|
|
|
+ if hostConfig.Isolation.IsDefault() {
|
|
|
// Container is set to use the default, so take the default from the daemon configuration
|
|
|
return daemon.defaultIsolation.IsHyperV()
|
|
|
}
|
|
|
|
|
|
// Container is requesting an isolation mode. Honour it.
|
|
|
- return container.HostConfig.Isolation.IsHyperV()
|
|
|
+ return hostConfig.Isolation.IsHyperV()
|
|
|
|
|
|
}
|
|
|
|
|
@@ -403,7 +438,7 @@ func (daemon *Daemon) runAsHyperVContainer(container *container.Container) bool
|
|
|
// container start to call mount.
|
|
|
func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error {
|
|
|
// We do not mount if a Hyper-V container
|
|
|
- if !daemon.runAsHyperVContainer(container) {
|
|
|
+ if !daemon.runAsHyperVContainer(container.HostConfig) {
|
|
|
return daemon.Mount(container)
|
|
|
}
|
|
|
return nil
|
|
@@ -413,7 +448,7 @@ func (daemon *Daemon) conditionalMountOnStart(container *container.Container) er
|
|
|
// during the cleanup of a container to unmount.
|
|
|
func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error {
|
|
|
// We do not unmount if a Hyper-V container
|
|
|
- if !daemon.runAsHyperVContainer(container) {
|
|
|
+ if !daemon.runAsHyperVContainer(container.HostConfig) {
|
|
|
return daemon.Unmount(container)
|
|
|
}
|
|
|
return nil
|