1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #43254 from thaJeztah/windows_rs5_minimum

Windows: require Windows Server RS5 / ltsc2019 (build 17763) as minimum
This commit is contained in:
Sebastiaan van Stijn 2022-02-19 00:35:45 +01:00 committed by GitHub
commit dc8fb8f03b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 147 additions and 287 deletions

View file

@ -12,7 +12,6 @@ import (
"time" "time"
"unsafe" "unsafe"
"github.com/Microsoft/hcsshim/osversion"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
@ -167,19 +166,11 @@ func registerService() error {
} }
defer m.Disconnect() defer m.Disconnect()
depends := []string{}
// This dependency is required on build 14393 (RS1)
// it is added to the platform in newer builds
if osversion.Build() == osversion.RS1 {
depends = append(depends, "ConDrv")
}
c := mgr.Config{ c := mgr.Config{
ServiceType: windows.SERVICE_WIN32_OWN_PROCESS, ServiceType: windows.SERVICE_WIN32_OWN_PROCESS,
StartType: mgr.StartAutomatic, StartType: mgr.StartAutomatic,
ErrorControl: mgr.ErrorNormal, ErrorControl: mgr.ErrorNormal,
Dependencies: depends, Dependencies: []string{},
DisplayName: "Docker Engine", DisplayName: "Docker Engine",
} }

View file

@ -118,15 +118,6 @@ func verifyPlatformContainerResources(resources *containertypes.Resources, isHyp
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()) 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())
} }
if resources.NanoCPUs > 0 && isHyperv && osversion.Build() < osversion.RS3 {
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)
}
}
if len(resources.BlkioDeviceReadBps) > 0 { if len(resources.BlkioDeviceReadBps) > 0 {
return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadBps") return warnings, fmt.Errorf("invalid option: Windows does not support BlkioDeviceReadBps")
} }
@ -187,19 +178,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
if hostConfig == nil { if hostConfig == nil {
return nil, nil return nil, nil
} }
hyperv := daemon.runAsHyperVContainer(hostConfig) return verifyPlatformContainerResources(&hostConfig.Resources, daemon.runAsHyperVContainer(hostConfig))
// On RS5, we allow (but don't strictly support) process isolation on Client SKUs.
// Prior to RS5, we don't allow process isolation on Client SKUs.
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping Microsoft folks if there are concerns or PRs to change this.
if !hyperv && system.IsWindowsClient() && osversion.Build() < osversion.RS5 {
return warnings, fmt.Errorf("Windows client operating systems earlier than version 1809 can only run Hyper-V containers")
}
w, err := verifyPlatformContainerResources(&hostConfig.Resources, hyperv)
warnings = append(warnings, w...)
return warnings, err
} }
// verifyDaemonSettings performs validation of daemon config struct // verifyDaemonSettings performs validation of daemon config struct
@ -211,11 +190,8 @@ func verifyDaemonSettings(config *config.Config) error {
func checkSystem() error { func checkSystem() error {
// Validate the OS version. Note that dockerd.exe must be manifested for this // Validate the OS version. Note that dockerd.exe must be manifested for this
// call to return the correct version. // call to return the correct version.
if osversion.Get().MajorVersion < 10 { if osversion.Get().MajorVersion < 10 || osversion.Build() < osversion.RS5 {
return fmt.Errorf("This version of Windows does not support the docker daemon") return fmt.Errorf("this version of Windows does not support the docker daemon (Windows build %d or higher is required)", osversion.RS5)
}
if osversion.Build() < osversion.RS1 {
return fmt.Errorf("The docker daemon requires build 14393 or later of Windows Server 2016 or Windows 10")
} }
vmcompute := windows.NewLazySystemDLL("vmcompute.dll") vmcompute := windows.NewLazySystemDLL("vmcompute.dll")
@ -574,13 +550,13 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
// setDefaultIsolation determine the default isolation mode for the // setDefaultIsolation determine the default isolation mode for the
// daemon to run in. This is only applicable on Windows // daemon to run in. This is only applicable on Windows
func (daemon *Daemon) setDefaultIsolation() error { func (daemon *Daemon) setDefaultIsolation() error {
daemon.defaultIsolation = containertypes.Isolation("process")
// On client SKUs, default to Hyper-V. @engine maintainers. This // On client SKUs, default to Hyper-V. @engine maintainers. This
// should not be removed. Ping Microsoft folks is there are PRs to // should not be removed. Ping Microsoft folks is there are PRs to
// to change this. // to change this.
if system.IsWindowsClient() { if system.IsWindowsClient() {
daemon.defaultIsolation = containertypes.Isolation("hyperv") daemon.defaultIsolation = containertypes.IsolationHyperV
} else {
daemon.defaultIsolation = containertypes.IsolationProcess
} }
for _, option := range daemon.configStore.ExecOptions { for _, option := range daemon.configStore.ExecOptions {
key, val, err := parsers.ParseKeyValueOpt(option) key, val, err := parsers.ParseKeyValueOpt(option)
@ -595,16 +571,10 @@ func (daemon *Daemon) setDefaultIsolation() error {
return fmt.Errorf("Invalid exec-opt value for 'isolation':'%s'", val) return fmt.Errorf("Invalid exec-opt value for 'isolation':'%s'", val)
} }
if containertypes.Isolation(val).IsHyperV() { if containertypes.Isolation(val).IsHyperV() {
daemon.defaultIsolation = containertypes.Isolation("hyperv") daemon.defaultIsolation = containertypes.IsolationHyperV
} }
if containertypes.Isolation(val).IsProcess() { if containertypes.Isolation(val).IsProcess() {
if system.IsWindowsClient() && osversion.Build() < osversion.RS5 { daemon.defaultIsolation = containertypes.IsolationProcess
// On RS5, we allow (but don't strictly support) process isolation on Client SKUs.
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping Microsoft folks if there are concerns or PRs to change this.
return fmt.Errorf("Windows client operating systems earlier than version 1809 can only run Hyper-V containers")
}
daemon.defaultIsolation = containertypes.Isolation("process")
} }
default: default:
return fmt.Errorf("Unrecognised exec-opt '%s'\n", key) return fmt.Errorf("Unrecognised exec-opt '%s'\n", key)

View file

@ -253,14 +253,11 @@ func operatingSystem() (operatingSystem string) {
} else { } else {
operatingSystem = s operatingSystem = s
} }
// Don't do containerized check on Windows if inContainer, err := operatingsystem.IsContainerized(); err != nil {
if runtime.GOOS != "windows" { logrus.Errorf("Could not determine if daemon is containerized: %v", err)
if inContainer, err := operatingsystem.IsContainerized(); err != nil { operatingSystem += " (error determining if containerized)"
logrus.Errorf("Could not determine if daemon is containerized: %v", err) } else if inContainer {
operatingSystem += " (error determining if containerized)" operatingSystem += " (containerized)"
} else if inContainer {
operatingSystem += " (containerized)"
}
} }
return operatingSystem return operatingSystem

View file

@ -7,7 +7,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/Microsoft/hcsshim/osversion"
containertypes "github.com/docker/docker/api/types/container" containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container" "github.com/docker/docker/container"
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
@ -260,9 +259,6 @@ func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.S
if isHyperV { if isHyperV {
return errors.New("device assignment is not supported for HyperV containers") return errors.New("device assignment is not supported for HyperV containers")
} }
if osversion.Build() < osversion.RS5 {
return errors.New("device assignment requires Windows builds RS5 (17763+) or later")
}
for _, deviceMapping := range c.HostConfig.Devices { for _, deviceMapping := range c.HostConfig.Devices {
srcParts := strings.SplitN(deviceMapping.PathOnHost, "/", 2) srcParts := strings.SplitN(deviceMapping.PathOnHost, "/", 2)
if len(srcParts) != 2 { if len(srcParts) != 2 {

View file

@ -12,7 +12,6 @@ import (
"testing" "testing"
winio "github.com/Microsoft/go-winio" winio "github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/osversion"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
@ -22,8 +21,6 @@ import (
) )
func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) { func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) {
testRequires(c, testEnv.IsLocalDaemon, DaemonIsWindowsAtLeastBuild(osversion.RS3)) // Named pipe support was added in RS3
// Create a host pipe to map into the container // Create a host pipe to map into the container
hostPipeName := fmt.Sprintf(`\\.\pipe\docker-cli-test-pipe-%x`, rand.Uint64()) hostPipeName := fmt.Sprintf(`\\.\pipe\docker-cli-test-pipe-%x`, rand.Uint64())
pc := &winio.PipeConfig{ pc := &winio.PipeConfig{

View file

@ -4,18 +4,14 @@ import (
"context" "context"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"runtime"
"strconv"
"strings" "strings"
"testing" "testing"
"github.com/Microsoft/hcsshim/osversion"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/cli/build" "github.com/docker/docker/integration-cli/cli/build"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/testutil/request" "github.com/docker/docker/testutil/request"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
) )
@ -59,17 +55,6 @@ func (s *DockerSuite) TestAPIImagesFilter(c *testing.T) {
} }
func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *testing.T) { func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *testing.T) {
if runtime.GOOS == "windows" {
// Note we parse kernel.GetKernelVersion rather than osversion.Build()
// as test binaries aren't manifested, so would otherwise report build 9200.
v, err := kernel.GetKernelVersion()
assert.NilError(c, err)
buildNumber, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0])
if buildNumber <= osversion.RS3 {
c.Skip("Temporarily disabled on RS3 and older because they are too slow. See #39909")
}
}
testRequires(c, Network) testRequires(c, Network)
buildImageSuccessfully(c, "saveandload", build.WithDockerfile("FROM busybox\nENV FOO bar")) buildImageSuccessfully(c, "saveandload", build.WithDockerfile("FROM busybox\nENV FOO bar"))
id := getIDByName(c, "saveandload") id := getIDByName(c, "saveandload")
@ -141,17 +126,6 @@ func (s *DockerSuite) TestAPIImagesHistory(c *testing.T) {
} }
func (s *DockerSuite) TestAPIImagesImportBadSrc(c *testing.T) { func (s *DockerSuite) TestAPIImagesImportBadSrc(c *testing.T) {
if runtime.GOOS == "windows" {
// Note we parse kernel.GetKernelVersion rather than osversion.Build()
// as test binaries aren't manifested, so would otherwise report build 9200.
v, err := kernel.GetKernelVersion()
assert.NilError(c, err)
buildNumber, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0])
if buildNumber == osversion.RS3 {
c.Skip("Temporarily disabled on RS3 builds")
}
}
testRequires(c, Network, testEnv.IsLocalDaemon) testRequires(c, Network, testEnv.IsLocalDaemon)
server := httptest.NewServer(http.NewServeMux()) server := httptest.NewServer(http.NewServeMux())

View file

@ -303,7 +303,7 @@ func (s *DockerSuite) TestCreateWithWorkdir(c *testing.T) {
// Windows does not create the workdir until the container is started // Windows does not create the workdir until the container is started
if testEnv.OSType == "windows" { if testEnv.OSType == "windows" {
dockerCmd(c, "start", name) dockerCmd(c, "start", name)
if IsolationIsHyperv() { if testEnv.DaemonInfo.Isolation.IsHyperV() {
// Hyper-V isolated containers do not allow file-operations on a // Hyper-V isolated containers do not allow file-operations on a
// running container. This test currently uses `docker cp` to verify // running container. This test currently uses `docker cp` to verify
// that the WORKDIR was automatically created, which cannot be done // that the WORKDIR was automatically created, which cannot be done

View file

@ -171,7 +171,7 @@ func (s *DockerSuite) TestRestartContainerSuccess(c *testing.T) {
// such that it assumes there is a host process to kill. In Hyper-V // such that it assumes there is a host process to kill. In Hyper-V
// containers, the process is inside the utility VM, not on the host. // containers, the process is inside the utility VM, not on the host.
if DaemonIsWindows() { if DaemonIsWindows() {
testRequires(c, IsolationIsProcess) testRequires(c, testEnv.DaemonInfo.Isolation.IsProcess)
} }
out := runSleepingContainer(c, "-d", "--restart=always") out := runSleepingContainer(c, "-d", "--restart=always")
@ -247,7 +247,7 @@ func (s *DockerSuite) TestRestartPolicyAfterRestart(c *testing.T) {
// such that it assumes there is a host process to kill. In Hyper-V // such that it assumes there is a host process to kill. In Hyper-V
// containers, the process is inside the utility VM, not on the host. // containers, the process is inside the utility VM, not on the host.
if DaemonIsWindows() { if DaemonIsWindows() {
testRequires(c, IsolationIsProcess) testRequires(c, testEnv.DaemonInfo.Isolation.IsProcess)
} }
out := runSleepingContainer(c, "-d", "--restart=always") out := runSleepingContainer(c, "-d", "--restart=always")

View file

@ -22,7 +22,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/Microsoft/hcsshim/osversion"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/cli/build" "github.com/docker/docker/integration-cli/cli/build"
@ -1877,11 +1876,6 @@ func (s *DockerSuite) TestRunBindMounts(c *testing.T) {
testRequires(c, DaemonIsLinux, NotUserNamespace) testRequires(c, DaemonIsLinux, NotUserNamespace)
} }
if testEnv.OSType == "windows" {
// Disabled prior to RS5 due to how volumes are mapped
testRequires(c, DaemonIsWindowsAtLeastBuild(osversion.RS5))
}
prefix, _ := getPrefixAndSlashFromDaemonPlatform() prefix, _ := getPrefixAndSlashFromDaemonPlatform()
tmpDir, err := os.MkdirTemp("", "docker-test-container") tmpDir, err := os.MkdirTemp("", "docker-test-container")
@ -4105,7 +4099,7 @@ func (s *DockerSuite) TestRunWindowsWithCPUPercent(c *testing.T) {
} }
func (s *DockerSuite) TestRunProcessIsolationWithCPUCountCPUSharesAndCPUPercent(c *testing.T) { func (s *DockerSuite) TestRunProcessIsolationWithCPUCountCPUSharesAndCPUPercent(c *testing.T) {
testRequires(c, IsolationIsProcess) testRequires(c, DaemonIsWindows, testEnv.DaemonInfo.Isolation.IsProcess)
out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing") out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing")
assert.Assert(c, strings.Contains(strings.TrimSpace(out), "WARNING: Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded")) assert.Assert(c, strings.Contains(strings.TrimSpace(out), "WARNING: Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded"))
@ -4122,7 +4116,7 @@ func (s *DockerSuite) TestRunProcessIsolationWithCPUCountCPUSharesAndCPUPercent(
} }
func (s *DockerSuite) TestRunHypervIsolationWithCPUCountCPUSharesAndCPUPercent(c *testing.T) { func (s *DockerSuite) TestRunHypervIsolationWithCPUCountCPUSharesAndCPUPercent(c *testing.T) {
testRequires(c, IsolationIsHyperv) testRequires(c, DaemonIsWindows, testEnv.DaemonInfo.Isolation.IsHyperV)
out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing") out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing")
assert.Assert(c, strings.Contains(strings.TrimSpace(out), "testing")) assert.Assert(c, strings.Contains(strings.TrimSpace(out), "testing"))
@ -4413,7 +4407,7 @@ func (s *DockerSuite) TestRunAddDeviceCgroupRule(c *testing.T) {
// Verifies that running as local system is operating correctly on Windows // Verifies that running as local system is operating correctly on Windows
func (s *DockerSuite) TestWindowsRunAsSystem(c *testing.T) { func (s *DockerSuite) TestWindowsRunAsSystem(c *testing.T) {
testRequires(c, DaemonIsWindowsAtLeastBuild(osversion.RS3)) testRequires(c, DaemonIsWindows)
out, _ := dockerCmd(c, "run", "--net=none", `--user=nt authority\system`, "--hostname=XYZZY", minimalBaseImage(), "cmd", "/c", `@echo %USERNAME%`) out, _ := dockerCmd(c, "run", "--net=none", `--user=nt authority\system`, "--hostname=XYZZY", minimalBaseImage(), "cmd", "/c", `@echo %USERNAME%`)
assert.Equal(c, strings.TrimSpace(out), "XYZZY$") assert.Equal(c, strings.TrimSpace(out), "XYZZY$")
} }

View file

@ -2,15 +2,11 @@ package main
import ( import (
"fmt" "fmt"
"runtime"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/Microsoft/hcsshim/osversion"
"github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/pkg/parsers/kernel"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/icmd" "gotest.tools/v3/icmd"
) )
@ -190,18 +186,6 @@ func (s *DockerSuite) TestStartAttachWithRename(c *testing.T) {
} }
func (s *DockerSuite) TestStartReturnCorrectExitCode(c *testing.T) { func (s *DockerSuite) TestStartReturnCorrectExitCode(c *testing.T) {
// Note we parse kernel.GetKernelVersion rather than system.GetOSVersion
// as test binaries aren't manifested, so would otherwise report the wrong
// build number.
if runtime.GOOS == "windows" {
v, err := kernel.GetKernelVersion()
assert.NilError(c, err)
build, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0])
if build < osversion.RS3 {
c.Skip("FLAKY on Windows RS1, see #38521")
}
}
dockerCmd(c, "create", "--restart=on-failure:2", "--name", "withRestart", "busybox", "sh", "-c", "exit 11") dockerCmd(c, "create", "--restart=on-failure:2", "--name", "withRestart", "busybox", "sh", "-c", "exit 11")
dockerCmd(c, "create", "--rm", "--name", "withRm", "busybox", "sh", "-c", "exit 12") dockerCmd(c, "create", "--rm", "--name", "withRm", "busybox", "sh", "-c", "exit 12")

View file

@ -6,7 +6,6 @@ import (
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -27,17 +26,6 @@ func DaemonIsWindows() bool {
return testEnv.OSType == "windows" return testEnv.OSType == "windows"
} }
func DaemonIsWindowsAtLeastBuild(buildNumber int) func() bool {
return func() bool {
if testEnv.OSType != "windows" {
return false
}
version := testEnv.DaemonInfo.KernelVersion
numVersion, _ := strconv.Atoi(strings.Split(version, " ")[1])
return numVersion >= buildNumber
}
}
func DaemonIsLinux() bool { func DaemonIsLinux() bool {
return testEnv.OSType == "linux" return testEnv.OSType == "linux"
} }
@ -154,23 +142,11 @@ func UserNamespaceInKernel() bool {
func IsPausable() bool { func IsPausable() bool {
if testEnv.OSType == "windows" { if testEnv.OSType == "windows" {
return testEnv.DaemonInfo.Isolation == "hyperv" return testEnv.DaemonInfo.Isolation.IsHyperV()
} }
return true return true
} }
func IsolationIs(expectedIsolation string) bool {
return testEnv.OSType == "windows" && string(testEnv.DaemonInfo.Isolation) == expectedIsolation
}
func IsolationIsHyperv() bool {
return IsolationIs("hyperv")
}
func IsolationIsProcess() bool {
return IsolationIs("process")
}
// RegistryHosting returns whether the host can host a registry (v2) or not // RegistryHosting returns whether the host can host a registry (v2) or not
func RegistryHosting() bool { func RegistryHosting() bool {
// for now registry binary is built only if we're running inside // for now registry binary is built only if we're running inside

View file

@ -16,7 +16,6 @@ import (
"time" "time"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/osversion"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/cio" "github.com/containerd/containerd/cio"
containerderrdefs "github.com/containerd/containerd/errdefs" containerderrdefs "github.com/containerd/containerd/errdefs"
@ -305,9 +304,6 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
} }
} }
configuration.MappedDirectories = mds configuration.MappedDirectories = mds
if len(mps) > 0 && osversion.Build() < osversion.RS3 {
return errors.New("named pipe mounts are not supported on this version of Windows")
}
configuration.MappedPipes = mps configuration.MappedPipes = mps
if len(spec.Windows.Devices) > 0 { if len(spec.Windows.Devices) > 0 {
@ -315,9 +311,6 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
if configuration.HvPartition { if configuration.HvPartition {
return errors.New("device assignment is not supported for HyperV containers") return errors.New("device assignment is not supported for HyperV containers")
} }
if osversion.Build() < osversion.RS5 {
return errors.New("device assignment requires Windows builds RS5 (17763+) or later")
}
for _, d := range spec.Windows.Devices { for _, d := range spec.Windows.Devices {
configuration.AssignedDevices = append(configuration.AssignedDevices, hcsshim.AssignedDevice{InterfaceClassGUID: d.ID}) configuration.AssignedDevices = append(configuration.AssignedDevices, hcsshim.AssignedDevice{InterfaceClassGUID: d.ID})
} }

View file

@ -155,43 +155,41 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy) hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
if osversion.Build() > 16236 { natPolicy, err := json.Marshal(hcsshim.PaPolicy{
natPolicy, err := json.Marshal(hcsshim.PaPolicy{ Type: "OutBoundNAT",
Type: "OutBoundNAT", })
})
if err != nil { if err != nil {
return err return err
}
hnsEndpoint.Policies = append(hnsEndpoint.Policies, natPolicy)
epConnectivity, err := windows.ParseEndpointConnectivity(epOptions)
if err != nil {
return err
}
ep.portMapping = epConnectivity.PortBindings
ep.portMapping, err = windows.AllocatePorts(n.portMapper, ep.portMapping, ep.addr.IP)
if err != nil {
return err
}
defer func() {
if err != nil {
windows.ReleasePorts(n.portMapper, ep.portMapping)
}
}()
pbPolicy, err := windows.ConvertPortBindings(ep.portMapping)
if err != nil {
return err
}
hnsEndpoint.Policies = append(hnsEndpoint.Policies, pbPolicy...)
ep.disablegateway = true
} }
hnsEndpoint.Policies = append(hnsEndpoint.Policies, natPolicy)
epConnectivity, err := windows.ParseEndpointConnectivity(epOptions)
if err != nil {
return err
}
ep.portMapping = epConnectivity.PortBindings
ep.portMapping, err = windows.AllocatePorts(n.portMapper, ep.portMapping, ep.addr.IP)
if err != nil {
return err
}
defer func() {
if err != nil {
windows.ReleasePorts(n.portMapper, ep.portMapping)
}
}()
pbPolicy, err := windows.ConvertPortBindings(ep.portMapping)
if err != nil {
return err
}
hnsEndpoint.Policies = append(hnsEndpoint.Policies, pbPolicy...)
ep.disablegateway = true
configurationb, err := json.Marshal(hnsEndpoint) configurationb, err := json.Marshal(hnsEndpoint)
if err != nil { if err != nil {
return err return err

View file

@ -21,7 +21,6 @@ import (
"sync" "sync"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/osversion"
"github.com/docker/docker/libnetwork/datastore" "github.com/docker/docker/libnetwork/datastore"
"github.com/docker/docker/libnetwork/discoverapi" "github.com/docker/docker/libnetwork/discoverapi"
"github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/driverapi"
@ -218,9 +217,6 @@ func (d *driver) parseNetworkOptions(id string, genericOptions map[string]string
} }
config.VSID = uint(vsid) config.VSID = uint(vsid)
case EnableOutboundNat: case EnableOutboundNat:
if osversion.Build() <= 16236 {
return nil, fmt.Errorf("Invalid network option. OutboundNat is not supported on this OS version")
}
b, err := strconv.ParseBool(value) b, err := strconv.ParseBool(value)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -4,7 +4,6 @@ import (
"net" "net"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/osversion"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -23,98 +22,96 @@ func (n *network) addLBBackend(ip net.IP, lb *loadBalancer) {
vip := lb.vip vip := lb.vip
ingressPorts := lb.service.ingressPorts ingressPorts := lb.service.ingressPorts
if osversion.Build() > 16236 { lb.Lock()
lb.Lock() defer lb.Unlock()
defer lb.Unlock() //find the load balancer IP for the network.
//find the load balancer IP for the network. var sourceVIP string
var sourceVIP string for _, e := range n.Endpoints() {
for _, e := range n.Endpoints() { epInfo := e.Info()
epInfo := e.Info() if epInfo == nil {
if epInfo == nil { continue
continue
}
if epInfo.LoadBalancer() {
sourceVIP = epInfo.Iface().Address().IP.String()
break
}
} }
if epInfo.LoadBalancer() {
if sourceVIP == "" { sourceVIP = epInfo.Iface().Address().IP.String()
logrus.Errorf("Failed to find load balancer IP for network %s", n.Name()) break
return
} }
}
var endpoints []hcsshim.HNSEndpoint if sourceVIP == "" {
logrus.Errorf("Failed to find load balancer IP for network %s", n.Name())
return
}
for eid, be := range lb.backEnds { var endpoints []hcsshim.HNSEndpoint
if be.disabled {
continue
}
//Call HNS to get back ID (GUID) corresponding to the endpoint.
hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid)
if err != nil {
logrus.Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err)
return
}
endpoints = append(endpoints, *hnsEndpoint) for eid, be := range lb.backEnds {
if be.disabled {
continue
} }
//Call HNS to get back ID (GUID) corresponding to the endpoint.
if policies, ok := lbPolicylistMap[lb]; ok { hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid)
if policies.ilb != nil {
policies.ilb.Delete()
policies.ilb = nil
}
if policies.elb != nil {
policies.elb.Delete()
policies.elb = nil
}
delete(lbPolicylistMap, lb)
}
ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0)
if err != nil { if err != nil {
logrus.Errorf("Failed to add ILB policy for service %s (%s) with endpoints %v using load balancer IP %s on network %s: %v", logrus.Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err)
lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err)
return return
} }
lbPolicylistMap[lb] = &policyLists{ endpoints = append(endpoints, *hnsEndpoint)
ilb: ilbPolicy, }
if policies, ok := lbPolicylistMap[lb]; ok {
if policies.ilb != nil {
policies.ilb.Delete()
policies.ilb = nil
} }
publishedPorts := make(map[uint32]uint32) if policies.elb != nil {
policies.elb.Delete()
policies.elb = nil
}
delete(lbPolicylistMap, lb)
}
for i, port := range ingressPorts { ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0)
protocol := uint16(6) if err != nil {
logrus.Errorf("Failed to add ILB policy for service %s (%s) with endpoints %v using load balancer IP %s on network %s: %v",
lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err)
return
}
// Skip already published port lbPolicylistMap[lb] = &policyLists{
if publishedPorts[port.PublishedPort] == port.TargetPort { ilb: ilbPolicy,
continue }
publishedPorts := make(map[uint32]uint32)
for i, port := range ingressPorts {
protocol := uint16(6)
// Skip already published port
if publishedPorts[port.PublishedPort] == port.TargetPort {
continue
}
if port.Protocol == ProtocolUDP {
protocol = 17
}
// check if already has udp matching to add wild card publishing
for j := i + 1; j < len(ingressPorts); j++ {
if ingressPorts[j].TargetPort == port.TargetPort &&
ingressPorts[j].PublishedPort == port.PublishedPort {
protocol = 0
} }
}
if port.Protocol == ProtocolUDP { publishedPorts[port.PublishedPort] = port.TargetPort
protocol = 17
}
// check if already has udp matching to add wild card publishing lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort))
for j := i + 1; j < len(ingressPorts); j++ { if err != nil {
if ingressPorts[j].TargetPort == port.TargetPort && logrus.Errorf("Failed to add ELB policy for service %s (ip:%s target port:%v published port:%v) with endpoints %v using load balancer IP %s on network %s: %v",
ingressPorts[j].PublishedPort == port.PublishedPort { lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err)
protocol = 0 return
}
}
publishedPorts[port.PublishedPort] = port.TargetPort
lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort))
if err != nil {
logrus.Errorf("Failed to add ELB policy for service %s (ip:%s target port:%v published port:%v) with endpoints %v using load balancer IP %s on network %s: %v",
lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err)
return
}
} }
} }
} }
@ -124,30 +121,28 @@ func (n *network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullR
return return
} }
if osversion.Build() > 16236 { if numEnabledBackends(lb) > 0 {
if numEnabledBackends(lb) > 0 { // Reprogram HNS (actually VFP) with the existing backends.
//Reprogram HNS (actually VFP) with the existing backends. n.addLBBackend(ip, lb)
n.addLBBackend(ip, lb) } else {
} else { lb.Lock()
lb.Lock() defer lb.Unlock()
defer lb.Unlock() logrus.Debugf("No more backends for service %s (ip:%s). Removing all policies", lb.service.name, lb.vip.String())
logrus.Debugf("No more backends for service %s (ip:%s). Removing all policies", lb.service.name, lb.vip.String())
if policyLists, ok := lbPolicylistMap[lb]; ok { if policyLists, ok := lbPolicylistMap[lb]; ok {
if policyLists.ilb != nil { if policyLists.ilb != nil {
policyLists.ilb.Delete() policyLists.ilb.Delete()
policyLists.ilb = nil policyLists.ilb = nil
}
if policyLists.elb != nil {
policyLists.elb.Delete()
policyLists.elb = nil
}
delete(lbPolicylistMap, lb)
} else {
logrus.Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String())
} }
if policyLists.elb != nil {
policyLists.elb.Delete()
policyLists.elb = nil
}
delete(lbPolicylistMap, lb)
} else {
logrus.Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String())
} }
} }
} }

View file

@ -52,8 +52,7 @@ func withCurrentVersionRegistryKey(f func(registry.Key) (string, error)) (string
// GetOperatingSystemVersion gets the version of the current operating system, as a string. // GetOperatingSystemVersion gets the version of the current operating system, as a string.
func GetOperatingSystemVersion() (string, error) { func GetOperatingSystemVersion() (string, error) {
version := osversion.Get() return osversion.Get().ToString(), nil
return fmt.Sprintf("%d.%d.%d", version.MajorVersion, version.MinorVersion, version.Build), nil
} }
// IsContainerized returns true if we are running inside a container. // IsContainerized returns true if we are running inside a container.