8fb0ca2c |
package daemon
import ( |
ddae20c0 |
"context" |
8fb0ca2c |
"fmt" |
26517a01 |
"path/filepath" |
4352da78 |
"strings" |
8fb0ca2c |
|
e8026d8a |
"github.com/Microsoft/hcsshim" |
91e197d6 |
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container" |
6bb0d181 |
"github.com/docker/docker/container" |
db63f937 |
"github.com/docker/docker/daemon/config" |
4352da78 |
"github.com/docker/docker/image" |
7a7357da |
"github.com/docker/docker/pkg/containerfs" |
8e71b1e2 |
"github.com/docker/docker/pkg/fileutils" |
557c7cb8 |
"github.com/docker/docker/pkg/idtools" |
94d70d83 |
"github.com/docker/docker/pkg/parsers" |
340e5233 |
"github.com/docker/docker/pkg/platform" |
8df20663 |
"github.com/docker/docker/pkg/sysinfo" |
805dd0ee |
"github.com/docker/docker/pkg/system" |
8df20663 |
"github.com/docker/docker/runconfig" |
8fb0ca2c |
"github.com/docker/libnetwork" |
ed364b69 |
nwconfig "github.com/docker/libnetwork/config" |
ed8ccc30 |
"github.com/docker/libnetwork/datastore" |
e8026d8a |
winlibnetwork "github.com/docker/libnetwork/drivers/windows"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options" |
1edcc635 |
"github.com/pkg/errors" |
1009e6a4 |
"github.com/sirupsen/logrus" |
000366f1 |
"golang.org/x/sys/windows" |
1edcc635 |
"golang.org/x/sys/windows/svc/mgr" |
8fb0ca2c |
)
|
10d30c64 |
const ( |
4e15420b |
defaultNetworkSpace = "172.16.0.0/12"
platformSupported = true
windowsMinCPUShares = 1
windowsMaxCPUShares = 10000
windowsMinCPUPercent = 1
windowsMaxCPUPercent = 100 |
10d30c64 |
) |
e0ec0cc1 |
|
26517a01 |
// Windows has no concept of an execution state directory. So use config.Root here.
func getPluginExecRoot(root string) string {
return filepath.Join(root, "plugins")
}
|
d7fda019 |
func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
return parseSecurityOpt(container, hostConfig)
}
|
7ac4232e |
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error { |
8fb0ca2c |
return nil
}
|
7a7357da |
func (daemon *Daemon) getLayerInit() func(containerfs.ContainerFS) error { |
2508ca00 |
return nil
}
|
8fb0ca2c |
func checkKernel() error {
return nil
}
|
ca89c329 |
func (daemon *Daemon) getCgroupDriver() string {
return ""
}
|
3fea79bf |
// adaptContainerSettings is called during container creation to modify any
// settings necessary in the HostConfig structure. |
7ac4232e |
func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error { |
608b3db5 |
if hostConfig == nil { |
4089b4e4 |
return nil |
608b3db5 |
}
|
4089b4e4 |
return nil |
7e0dfbf4 |
}
|
4e15420b |
func verifyContainerResources(resources *containertypes.Resources, isHyperv bool) ([]string, error) { |
ea8c6908 |
warnings := []string{} |
9d87e6e0 |
fixMemorySwappiness(resources) |
4e15420b |
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
}
} |
ea8c6908 |
}
|
0ed00b36 |
if resources.CPUShares < 0 || resources.CPUShares > windowsMaxCPUShares {
return warnings, fmt.Errorf("range of CPUShares is from %d to %d", windowsMinCPUShares, windowsMaxCPUShares)
}
if resources.CPUPercent < 0 || resources.CPUPercent > windowsMaxCPUPercent {
return warnings, fmt.Errorf("range of CPUPercent is from %d to %d", windowsMinCPUPercent, windowsMaxCPUPercent)
}
if resources.CPUCount < 0 {
return warnings, fmt.Errorf("invalid CPUCount: CPUCount cannot be negative") |
846baf1f |
}
|
0ed00b36 |
if resources.NanoCPUs > 0 && resources.CPUPercent > 0 {
return warnings, fmt.Errorf("conflicting options: Nano CPUs and CPU Percent cannot both be set")
} |
846baf1f |
if resources.NanoCPUs > 0 && resources.CPUShares > 0 { |
0ed00b36 |
return warnings, fmt.Errorf("conflicting options: Nano CPUs and CPU Shares cannot both be set") |
846baf1f |
} |
d22ac2f3 |
// The precision we could get is 0.01, because on Windows we have to convert to CPUPercent.
// We don't set the lower limit here and it is up to the underlying platform (e.g., Windows) to return an error. |
846baf1f |
if resources.NanoCPUs < 0 || resources.NanoCPUs > int64(sysinfo.NumCPU())*1e9 { |
d22ac2f3 |
return warnings, fmt.Errorf("range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", sysinfo.NumCPU(), sysinfo.NumCPU()) |
846baf1f |
}
|
3b5af0a2 |
osv := system.GetOSVersion()
if resources.NanoCPUs > 0 && isHyperv && osv.Build < 16175 {
leftoverNanoCPUs := resources.NanoCPUs % 1e9
if leftoverNanoCPUs != 0 && resources.NanoCPUs > 1e9 {
resources.NanoCPUs = ((resources.NanoCPUs + 1e9/2) / 1e9) * 1e9
warningString := fmt.Sprintf("Your current OS version does not support Hyper-V containers with NanoCPUs greater than 1000000000 but not divisible by 1000000000. NanoCPUs rounded to %d", resources.NanoCPUs)
warnings = append(warnings, warningString)
logrus.Warn(warningString)
}
}
|
0ed00b36 |
if len(resources.BlkioDeviceReadBps) > 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadBps")
}
if len(resources.BlkioDeviceReadIOps) > 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadIOps")
}
if len(resources.BlkioDeviceWriteBps) > 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceWriteBps")
}
if len(resources.BlkioDeviceWriteIOps) > 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceWriteIOps")
} |
8df20663 |
if resources.BlkioWeight > 0 { |
0ed00b36 |
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioWeight") |
8df20663 |
}
if len(resources.BlkioWeightDevice) > 0 { |
0ed00b36 |
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioWeightDevice") |
8df20663 |
} |
0ed00b36 |
if resources.CgroupParent != "" {
return warnings, fmt.Errorf("invalid option: Windows does not support CgroupParent") |
8df20663 |
} |
0ed00b36 |
if resources.CPUPeriod != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support CPUPeriod") |
8df20663 |
} |
0ed00b36 |
if resources.CpusetCpus != "" {
return warnings, fmt.Errorf("invalid option: Windows does not support CpusetCpus") |
8df20663 |
} |
0ed00b36 |
if resources.CpusetMems != "" {
return warnings, fmt.Errorf("invalid option: Windows does not support CpusetMems")
}
if resources.KernelMemory != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support KernelMemory")
}
if resources.MemoryReservation != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support MemoryReservation")
}
if resources.MemorySwap != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support MemorySwap")
} |
9d87e6e0 |
if resources.MemorySwappiness != nil { |
0ed00b36 |
return warnings, fmt.Errorf("invalid option: Windows does not support MemorySwappiness")
}
if resources.OomKillDisable != nil && *resources.OomKillDisable {
return warnings, fmt.Errorf("invalid option: Windows does not support OomKillDisable")
}
if resources.PidsLimit != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support PidsLimit")
}
if len(resources.Ulimits) != 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support Ulimits") |
8df20663 |
} |
ea8c6908 |
return warnings, nil
}
|
3fea79bf |
// verifyPlatformContainerSettings performs platform-specific validation of the
// hostconfig and config structures. |
8ae6f6ac |
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { |
ea8c6908 |
warnings := []string{}
|
6b4ad8d6 |
hyperv := daemon.runAsHyperVContainer(hostConfig) |
75f7f2a8 |
if !hyperv && system.IsWindowsClient() && !system.IsIoTCore() { |
6b4ad8d6 |
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this.
return warnings, fmt.Errorf("Windows client operating systems only support Hyper-V containers")
}
w, err := verifyContainerResources(&hostConfig.Resources, hyperv) |
ea8c6908 |
warnings = append(warnings, w...) |
3a425180 |
return warnings, err |
8fb0ca2c |
}
|
5ce5a8e9 |
// verifyDaemonSettings performs validation of daemon config struct |
db63f937 |
func verifyDaemonSettings(config *config.Config) error { |
8fb0ca2c |
return nil
}
|
62a75fca |
// checkSystem validates platform-specific requirements |
8fb0ca2c |
func checkSystem() error {
// Validate the OS version. Note that docker.exe must be manifested for this
// call to return the correct version. |
194eaa5c |
osv := system.GetOSVersion() |
805dd0ee |
if osv.MajorVersion < 10 { |
8fb0ca2c |
return fmt.Errorf("This version of Windows does not support the docker daemon")
} |
cc4e17cb |
if osv.Build < 14393 {
return fmt.Errorf("The docker daemon requires build 14393 or later of Windows Server 2016 or Windows 10") |
122568b3 |
} |
000366f1 |
vmcompute := windows.NewLazySystemDLL("vmcompute.dll")
if vmcompute.Load() != nil { |
31405b55 |
return fmt.Errorf("failed to load vmcompute.dll, ensure that the Containers feature is installed") |
000366f1 |
} |
e128a656 |
|
1edcc635 |
// Ensure that the required Host Network Service and vmcompute services
// are running. Docker will fail in unexpected ways if this is not present.
var requiredServices = []string{"hns", "vmcompute"}
if err := ensureServicesInstalled(requiredServices); err != nil {
return errors.Wrap(err, "a required service is not installed, ensure the Containers feature is installed")
}
return nil
}
func ensureServicesInstalled(services []string) error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
for _, service := range services {
s, err := m.OpenService(service)
if err != nil {
return errors.Wrapf(err, "failed to open service %s", service)
}
s.Close()
} |
6eed7f0c |
return nil |
8fb0ca2c |
}
// configureKernelSecuritySupport configures and validate security support for the kernel |
ce8e529e |
func configureKernelSecuritySupport(config *config.Config, driverName string) error { |
8fb0ca2c |
return nil
}
|
140a7434 |
// configureMaxThreads sets the Go runtime max threads threshold |
db63f937 |
func configureMaxThreads(config *config.Config) error { |
140a7434 |
return nil
}
|
db63f937 |
func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { |
a00940f0 |
netOptions, err := daemon.networkOptions(config, nil, nil) |
e8026d8a |
if err != nil {
return nil, err
}
controller, err := libnetwork.New(netOptions...)
if err != nil {
return nil, fmt.Errorf("error obtaining controller instance: %v", err)
}
hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "")
if err != nil {
return nil, err
}
// Remove networks not present in HNS
for _, v := range controller.Networks() {
options := v.Info().DriverOptions()
hnsid := options[winlibnetwork.HNSID]
found := false
for _, v := range hnsresponse {
if v.Id == hnsid {
found = true
break
}
}
if !found { |
ed8ccc30 |
// global networks should not be deleted by local HNS
if v.Info().Scope() != datastore.GlobalScope {
err = v.Delete()
if err != nil {
logrus.Errorf("Error occurred when removing network %v", err)
} |
e8026d8a |
}
}
}
|
6eb2b903 |
_, err = controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(false)) |
e8026d8a |
if err != nil {
return nil, err
}
|
aad25801 |
defaultNetworkExists := false
if network, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil {
options := network.Info().DriverOptions()
for _, v := range hnsresponse {
if options[winlibnetwork.HNSID] == v.Id {
defaultNetworkExists = true
break
}
}
}
|
e8026d8a |
// discover and add HNS networks to windows
// network that exist are removed and added again
for _, v := range hnsresponse { |
b91fd26b |
if strings.ToLower(v.Type) == "private" {
continue // workaround for HNS reporting unsupported networks
} |
e8026d8a |
var n libnetwork.Network
s := func(current libnetwork.Network) bool {
options := current.Info().DriverOptions()
if options[winlibnetwork.HNSID] == v.Id {
n = current
return true
}
return false
}
controller.WalkNetworks(s) |
cef1578a |
drvOptions := make(map[string]string)
|
e8026d8a |
if n != nil { |
ed8ccc30 |
// global networks should not be deleted by local HNS
if n.Info().Scope() == datastore.GlobalScope {
continue
} |
e8026d8a |
v.Name = n.Name() |
aad25801 |
// This will not cause network delete from HNS as the network
// is not yet populated in the libnetwork windows driver |
cef1578a |
// restore option if it existed before
drvOptions = n.Info().DriverOptions() |
e8026d8a |
n.Delete()
}
netOption := map[string]string{
winlibnetwork.NetworkName: v.Name,
winlibnetwork.HNSID: v.Id,
}
|
cef1578a |
// add persisted driver options
for k, v := range drvOptions {
if k != winlibnetwork.NetworkName && k != winlibnetwork.HNSID {
netOption[k] = v
}
}
|
e8026d8a |
v4Conf := []*libnetwork.IpamConf{}
for _, subnet := range v.Subnets {
ipamV4Conf := libnetwork.IpamConf{}
ipamV4Conf.PreferredPool = subnet.AddressPrefix
ipamV4Conf.Gateway = subnet.GatewayAddress
v4Conf = append(v4Conf, &ipamV4Conf)
}
name := v.Name |
aad25801 |
// If there is no nat network create one from the first NAT network |
e6962481 |
// encountered if it doesn't already exist
if !defaultNetworkExists &&
runconfig.DefaultDaemonNetworkMode() == containertypes.NetworkMode(strings.ToLower(v.Type)) &&
n == nil { |
e8026d8a |
name = runconfig.DefaultDaemonNetworkMode().NetworkName() |
aad25801 |
defaultNetworkExists = true |
e8026d8a |
}
v6Conf := []*libnetwork.IpamConf{} |
6eb2b903 |
_, err := controller.NewNetwork(strings.ToLower(v.Type), name, "", |
e8026d8a |
libnetwork.NetworkOptionGeneric(options.Generic{
netlabel.GenericData: netOption,
}),
libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
)
if err != nil {
logrus.Errorf("Error occurred when creating network %v", err)
}
}
if !config.DisableBridge {
// Initialize default driver "bridge"
if err := initBridgeDriver(controller, config); err != nil {
return nil, err
}
}
return controller, nil |
8fb0ca2c |
}
|
db63f937 |
func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error { |
e8026d8a |
if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil {
return nil |
e0ec0cc1 |
} |
e8026d8a |
netOption := map[string]string{
winlibnetwork.NetworkName: runconfig.DefaultDaemonNetworkMode().NetworkName(),
}
|
aad25801 |
var ipamOption libnetwork.NetworkOption
var subnetPrefix string
|
db63f937 |
if config.BridgeConfig.FixedCIDR != "" {
subnetPrefix = config.BridgeConfig.FixedCIDR |
e8026d8a |
} else { |
aad25801 |
// TP5 doesn't support properly detecting subnet
osv := system.GetOSVersion()
if osv.Build < 14360 {
subnetPrefix = defaultNetworkSpace
} |
e8026d8a |
}
|
aad25801 |
if subnetPrefix != "" {
ipamV4Conf := libnetwork.IpamConf{}
ipamV4Conf.PreferredPool = subnetPrefix
v4Conf := []*libnetwork.IpamConf{&ipamV4Conf}
v6Conf := []*libnetwork.IpamConf{}
ipamOption = libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil)
} |
e8026d8a |
|
6eb2b903 |
_, err := controller.NewNetwork(string(runconfig.DefaultDaemonNetworkMode()), runconfig.DefaultDaemonNetworkMode().NetworkName(), "", |
e8026d8a |
libnetwork.NetworkOptionGeneric(options.Generic{
netlabel.GenericData: netOption,
}), |
aad25801 |
ipamOption, |
e8026d8a |
)
if err != nil {
return fmt.Errorf("Error creating default network: %v", err)
} |
aad25801 |
|
e8026d8a |
return nil |
8fb0ca2c |
} |
c5e6a4b3 |
|
abd72d40 |
// registerLinks sets up links between containers and writes the |
b2771b44 |
// configuration out for persistence. As of Windows TP4, links are not supported. |
7ac4232e |
func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error { |
c5e6a4b3 |
return nil
} |
47c56e43 |
|
94d70d83 |
func (daemon *Daemon) cleanupMountsByID(in string) error {
return nil
}
|
c8291f71 |
func (daemon *Daemon) cleanupMounts() error {
return nil
} |
3a497650 |
|
09cd96c5 |
func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
return &idtools.IDMappings{}, nil |
557c7cb8 |
}
|
09cd96c5 |
func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error { |
557c7cb8 |
config.Root = rootDir
// Create the root directory if it doesn't exists |
516010e9 |
if err := system.MkdirAllWithACL(config.Root, 0, system.SddlAdministratorsLocalSystem); err != nil { |
557c7cb8 |
return err
}
return nil
}
|
4461bc45 |
// runasHyperVContainer returns true if we are going to run as a Hyper-V container |
4e15420b |
func (daemon *Daemon) runAsHyperVContainer(hostConfig *containertypes.HostConfig) bool {
if hostConfig.Isolation.IsDefault() { |
94d70d83 |
// Container is set to use the default, so take the default from the daemon configuration |
4461bc45 |
return daemon.defaultIsolation.IsHyperV() |
94d70d83 |
}
|
4461bc45 |
// Container is requesting an isolation mode. Honour it. |
4e15420b |
return hostConfig.Isolation.IsHyperV() |
4461bc45 |
}
// conditionalMountOnStart is a platform specific helper function during the
// container start to call mount.
func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error { |
0380fbff |
// Bail out now for Linux containers. We cannot mount the containers filesystem on the
// host as it is a non-Windows filesystem.
if system.LCOWSupported() && container.OS != "windows" { |
f8aa7005 |
return nil
}
|
0380fbff |
// We do not mount if a Hyper-V container as it needs to be mounted inside the
// utility VM, not the host. |
4e15420b |
if !daemon.runAsHyperVContainer(container.HostConfig) { |
4461bc45 |
return daemon.Mount(container) |
3a497650 |
}
return nil
}
// conditionalUnmountOnCleanup is a platform specific helper function called
// during the cleanup of a container to unmount. |
94d70d83 |
func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error { |
f8aa7005 |
// Bail out now for Linux containers |
0380fbff |
if system.LCOWSupported() && container.OS != "windows" { |
f8aa7005 |
return nil
}
|
3a497650 |
// We do not unmount if a Hyper-V container |
4e15420b |
if !daemon.runAsHyperVContainer(container.HostConfig) { |
94d70d83 |
return daemon.Unmount(container) |
4352da78 |
} |
94d70d83 |
return nil |
4352da78 |
}
|
db63f937 |
func driverOptions(config *config.Config) []nwconfig.Option { |
e8026d8a |
return []nwconfig.Option{} |
ed364b69 |
} |
94d70d83 |
func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { |
340e5233 |
if !c.IsRunning() { |
ebcb7d6b |
return nil, errNotRunning(c.ID) |
340e5233 |
}
// Obtain the stats from HCS via libcontainerd |
ddae20c0 |
stats, err := daemon.containerd.Stats(context.Background(), c.ID) |
340e5233 |
if err != nil { |
4a6cbf9b |
if strings.Contains(err.Error(), "container not found") { |
ebcb7d6b |
return nil, containerNotFound(c.ID) |
4a6cbf9b |
} |
340e5233 |
return nil, err
}
// Start with an empty structure
s := &types.StatsJSON{} |
ddae20c0 |
s.Stats.Read = stats.Read
s.Stats.NumProcs = platform.NumProcs() |
340e5233 |
|
ddae20c0 |
if stats.HCSStats != nil {
hcss := stats.HCSStats
// Populate the CPU/processor statistics
s.CPUStats = types.CPUStats{
CPUUsage: types.CPUUsage{
TotalUsage: hcss.Processor.TotalRuntime100ns,
UsageInKernelmode: hcss.Processor.RuntimeKernel100ns,
UsageInUsermode: hcss.Processor.RuntimeKernel100ns,
}, |
340e5233 |
}
|
ddae20c0 |
// Populate the memory statistics
s.MemoryStats = types.MemoryStats{
Commit: hcss.Memory.UsageCommitBytes,
CommitPeak: hcss.Memory.UsageCommitPeakBytes,
PrivateWorkingSet: hcss.Memory.UsagePrivateWorkingSetBytes,
} |
340e5233 |
|
ddae20c0 |
// Populate the storage statistics
s.StorageStats = types.StorageStats{
ReadCountNormalized: hcss.Storage.ReadCountNormalized,
ReadSizeBytes: hcss.Storage.ReadSizeBytes,
WriteCountNormalized: hcss.Storage.WriteCountNormalized,
WriteSizeBytes: hcss.Storage.WriteSizeBytes,
}
// Populate the network statistics
s.Networks = make(map[string]types.NetworkStats)
for _, nstats := range hcss.Network {
s.Networks[nstats.EndpointId] = types.NetworkStats{
RxBytes: nstats.BytesReceived,
RxPackets: nstats.PacketsReceived,
RxDropped: nstats.DroppedPacketsIncoming,
TxBytes: nstats.BytesSent,
TxPackets: nstats.PacketsSent,
TxDropped: nstats.DroppedPacketsOutgoing,
}
}
} |
340e5233 |
return s, nil |
94d70d83 |
}
// setDefaultIsolation determine the default isolation mode for the
// daemon to run in. This is only applicable on Windows
func (daemon *Daemon) setDefaultIsolation() error {
daemon.defaultIsolation = containertypes.Isolation("process") |
75f7f2a8 |
// On client SKUs, default to Hyper-V. Note that IoT reports as a client SKU
// but it should not be treated as such.
if system.IsWindowsClient() && !system.IsIoTCore() { |
ef2db56b |
daemon.defaultIsolation = containertypes.Isolation("hyperv")
} |
94d70d83 |
for _, option := range daemon.configStore.ExecOptions {
key, val, err := parsers.ParseKeyValueOpt(option)
if err != nil {
return err
}
key = strings.ToLower(key)
switch key {
case "isolation":
if !containertypes.Isolation(val).IsValid() {
return fmt.Errorf("Invalid exec-opt value for 'isolation':'%s'", val)
}
if containertypes.Isolation(val).IsHyperV() {
daemon.defaultIsolation = containertypes.Isolation("hyperv")
} |
ef2db56b |
if containertypes.Isolation(val).IsProcess() { |
75f7f2a8 |
if system.IsWindowsClient() && !system.IsIoTCore() { |
87ab13ad |
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this. |
ef2db56b |
return fmt.Errorf("Windows client operating systems only support Hyper-V containers")
}
daemon.defaultIsolation = containertypes.Isolation("process")
} |
94d70d83 |
default:
return fmt.Errorf("Unrecognised exec-opt '%s'\n", key)
}
}
logrus.Infof("Windows default isolation mode: %s", daemon.defaultIsolation)
return nil
} |
14dc4a71 |
func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
var layers []string
for _, l := range rootfs.DiffIDs {
layers = append(layers, l.String())
}
return types.RootFS{ |
f342b271 |
Type: rootfs.Type,
Layers: layers, |
14dc4a71 |
}
} |
a894aec8 |
|
db63f937 |
func setupDaemonProcess(config *config.Config) error { |
a894aec8 |
return nil
} |
dc712b92 |
// verifyVolumesInfo is a no-op on windows.
// This is called during daemon initialization to migrate volumes from pre-1.7.
// volumes were not supported on windows pre-1.7
func (daemon *Daemon) verifyVolumesInfo(container *container.Container) error {
return nil
} |
b237189e |
func (daemon *Daemon) setupSeccompProfile() error {
return nil
} |
8e71b1e2 |
func getRealPath(path string) (string, error) {
if system.IsIoTCore() {
// Due to https://github.com/golang/go/issues/20506, path expansion
// does not work correctly on the default IoT Core configuration.
// TODO @darrenstahlmsft remove this once golang/go/20506 is fixed
return path, nil
}
return fileutils.ReadSymlinkedDirectory(path)
} |
ddae20c0 |
func (daemon *Daemon) loadRuntimes() error {
return nil
}
func (daemon *Daemon) initRuntimes(_ map[string]types.Runtime) error {
return nil
} |