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:
commit
dc8fb8f03b
16 changed files with 147 additions and 287 deletions
|
@ -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",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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$")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue