-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stop relying on ReleaseId/DisplayVersion registry keys #191
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
from .DockerUtils import DockerUtils | ||
from pkg_resources import parse_version | ||
import platform, sys | ||
from typing import Optional | ||
|
||
if platform.system() == 'Windows': | ||
import winreg | ||
|
@@ -10,18 +11,22 @@ class WindowsUtils(object): | |
# The oldest Windows build we support | ||
_minimumRequiredBuild = 17763 | ||
|
||
# The latest Windows build version we recognise as a non-Insider build | ||
_latestReleaseBuild = 19042 | ||
# This lookup table is based on the list of valid tags from <https://hub.docker.com/r/microsoft/windowsservercore/> | ||
# and list of build-to-release mapping from https://docs.microsoft.com/en-us/windows/release-health/release-information | ||
_knownTagsByBuildNumber = { | ||
17763: 'ltsc2019', | ||
18362: '1903', | ||
18363: '1909', | ||
19041: '2004', | ||
19042: '20H2', | ||
19043: '21H1', | ||
} | ||
|
||
# The list of Windows Server Core base image tags that we recognise, in ascending version number order | ||
_validTags = ['ltsc2019', '1903', '1909', '2004', '20H2'] | ||
_knownTags = list(_knownTagsByBuildNumber.values()) | ||
|
||
# The list of Windows Server and Windows 10 host OS releases that are blacklisted due to critical bugs | ||
# (See: <https://unrealcontainers.com/docs/concepts/windows-containers>) | ||
_blacklistedReleases = ['1903', '1909'] | ||
|
||
# The list of Windows Server Core container image releases that are unsupported due to having reached EOL | ||
_eolReleases = ['1903', '1909'] | ||
_blacklistedHosts = [18362, 18363] | ||
|
||
@staticmethod | ||
def _getVersionRegKey(subkey : str) -> str: | ||
|
@@ -54,25 +59,21 @@ def systemString() -> str: | |
''' | ||
Generates a verbose human-readable version string for the Windows host system | ||
''' | ||
return '{} Version {} (Build {}.{})'.format( | ||
return '{} (Build {}.{})'.format( | ||
WindowsUtils._getVersionRegKey('ProductName'), | ||
WindowsUtils.getWindowsRelease(), | ||
WindowsUtils.getWindowsBuild(), | ||
WindowsUtils._getVersionRegKey('UBR') | ||
) | ||
|
||
@staticmethod | ||
def getWindowsRelease() -> str: | ||
def getHostBaseTag() -> Optional[str]: | ||
''' | ||
Determines the Windows 10 / Windows Server release (1607, 1709, 1803, etc.) of the Windows host system | ||
Retrieves the tag for the Windows Server Core base image matching the host Windows system | ||
''' | ||
try: | ||
# Starting with Windows 20H2 (also known as 2009), Microsoft stopped updating ReleaseId | ||
# and instead updates DisplayVersion | ||
return WindowsUtils._getVersionRegKey('DisplayVersion') | ||
except FileNotFoundError: | ||
# Fallback to ReleaseId for pre-20H2 releases that didn't have DisplayVersion | ||
return WindowsUtils._getVersionRegKey('ReleaseId') | ||
|
||
hostBuild = WindowsUtils.getWindowsBuild() | ||
|
||
return WindowsUtils._knownTagsByBuildNumber.get(hostBuild) | ||
|
||
@staticmethod | ||
def getWindowsBuild() -> int: | ||
|
@@ -82,23 +83,14 @@ def getWindowsBuild() -> int: | |
return sys.getwindowsversion().build | ||
|
||
@staticmethod | ||
def isBlacklistedWindowsVersion(release=None): | ||
def isBlacklistedWindowsHost() -> bool: | ||
''' | ||
Determines if the specified Windows release is one with bugs that make it unsuitable for use | ||
Determines if host Windows version is one with bugs that make it unsuitable for use | ||
(defaults to checking the host OS release if one is not specified) | ||
''' | ||
dockerVersion = parse_version(DockerUtils.version()['Version']) | ||
release = WindowsUtils.getWindowsRelease() if release is None else release | ||
return release in WindowsUtils._blacklistedReleases and dockerVersion < parse_version('19.03.6') | ||
|
||
@staticmethod | ||
def isEndOfLifeWindowsVersion(release=None): | ||
''' | ||
Determines if the specified Windows release is one that has reached End Of Life (EOL) | ||
(defaults to checking the host OS release if one is not specified) | ||
''' | ||
release = WindowsUtils.getWindowsRelease() if release is None else release | ||
return release in WindowsUtils._eolReleases | ||
build = WindowsUtils.getWindowsBuild() | ||
return build in WindowsUtils._blacklistedHosts and dockerVersion < parse_version('19.03.6') | ||
|
||
@staticmethod | ||
def isWindowsServer() -> bool: | ||
|
@@ -108,28 +100,6 @@ def isWindowsServer() -> bool: | |
# TODO: Replace this with something more reliable | ||
return 'Windows Server' in WindowsUtils._getVersionRegKey('ProductName') | ||
|
||
@staticmethod | ||
def isInsiderPreview() -> bool: | ||
''' | ||
Determines if the Windows host system is a Windows Insider preview build | ||
''' | ||
return WindowsUtils.getWindowsBuild() > WindowsUtils._latestReleaseBuild | ||
|
||
@staticmethod | ||
def getReleaseBaseTag(release: str) -> str: | ||
''' | ||
Retrieves the tag for the Windows Server Core base image matching the specified Windows 10 / Windows Server release | ||
''' | ||
|
||
# For Windows Insider preview builds, build the latest release tag | ||
if WindowsUtils.isInsiderPreview(): | ||
return WindowsUtils._validTags[-1] | ||
|
||
# This lookup table is based on the list of valid tags from <https://hub.docker.com/r/microsoft/windowsservercore/> | ||
return { | ||
'1809': 'ltsc2019', | ||
}.get(release, release) | ||
|
||
@staticmethod | ||
def getDllSrcImage(basetag: str) -> str: | ||
''' | ||
|
@@ -142,22 +112,18 @@ def getDllSrcImage(basetag: str) -> str: | |
return f'mcr.microsoft.com/windows:{tag}' | ||
|
||
@staticmethod | ||
def getValidBaseTags() -> [str]: | ||
''' | ||
Returns the list of valid tags for the Windows Server Core base image, in ascending chronological release order | ||
''' | ||
return WindowsUtils._validTags | ||
|
||
@staticmethod | ||
def isValidBaseTag(tag: str) -> bool: | ||
def getKnownBaseTags() -> [str]: | ||
''' | ||
Determines if the specified tag is a valid Windows Server Core base image tag | ||
Returns the list of known tags for the Windows Server Core base image, in ascending chronological release order | ||
''' | ||
return tag in WindowsUtils._validTags | ||
return WindowsUtils._knownTags | ||
|
||
@staticmethod | ||
def isNewerBaseTag(older: str, newer: str) -> bool: | ||
def isNewerBaseTag(older: str, newer: str) -> Optional[bool]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking nit-pick: I'm reasonably unfond of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dunno, these both look equally ugly to me :D I'd actually make a enum { Newer, Older, Unknown } but don't think it will improve anything at all given that we're in Python that |
||
''' | ||
Determines if the base tag `newer` is chronologically newer than the base tag `older` | ||
''' | ||
return WindowsUtils._validTags.index(newer) > WindowsUtils._validTags.index(older) | ||
try: | ||
return WindowsUtils._knownTags.index(newer) > WindowsUtils._knownTags.index(older) | ||
except ValueError: | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Windows 10 2004 hits EOL in December, and 20H2 EOLs in May next year. So if we just disappear them entirely, then we lose support for any Windows Client platforms.
I'd keep the EOL support around until we either decide to drop Windows 10 process isolation support once there's no supported base images available, or something changes on the MS side, or some other intervening idea occurs.
Better to say "Yes, we recognise this, it's EOL, are you sure you want to continue" when we can recognise a version.
Also, these two versions are only blacklisted for Docker versions before 19.03.6, so this change actually promotes them from EOL warning with user-override to "supported", i.e. silently accepted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trick is that they're blacklisted as a host and EOL as a target. We silently allow building supported versions on EOL hosts even before this commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, agreed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good point. I'm fine with not complaining about using an EOL host to build a supported target.
I'm ambivalent about complaining when we try to use an EOL target; I'd lean towards keeping the warning around based on the calculated base tag (i.e. after applying the user's specified base tag), but that isn't really comprehensive or reliable (e.g., basetag
1909-KB4574727-amd64
would not be recognised), so I don't mind if we drop it now.My personal use-cases are 100% process-isolation-based (and Windows Server LTSC-based 95% of the time), so I haven't had any value from the EOL warning myself.
I'd be interested to know if @adamrehn has any concerns about dropping this (or use-cases where it prevents a bad outcome), but if not, then I'm happy to resolve this thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ue4-docker doesn't support building targets that are not hardcoded in valid tags list at all. #166 wanted to change that, but kinda failed.
I thought about 20H2 again. I very doubt that anyone would want to build ue4-docker images for it after it gets EOLed. If they're on a newer host, they would need to use Hyper-V isolation. And if you use Hyper-V isolation, why not just use a supported target version? Alternatively, they still run EOLed 20H2 on their host. Well, if you use EOLed Windows, also use EOLed version of ue4-docker that has 20H2 support, no?