2018-02-05 16:05:59 -05:00
|
|
|
package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"
|
2015-05-08 14:59:38 -07:00
|
|
|
|
|
|
|
import (
|
2022-03-03 17:32:53 -05:00
|
|
|
"errors"
|
2017-05-23 10:22:32 -04:00
|
|
|
|
2019-11-25 13:39:25 +01:00
|
|
|
"github.com/Microsoft/hcsshim/osversion"
|
2022-03-03 17:32:53 -05:00
|
|
|
"golang.org/x/sys/windows"
|
2018-02-28 14:54:21 -08:00
|
|
|
"golang.org/x/sys/windows/registry"
|
2015-05-08 14:59:38 -07:00
|
|
|
)
|
|
|
|
|
2022-03-03 17:32:53 -05:00
|
|
|
// VER_NT_WORKSTATION, see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
|
|
|
|
const verNTWorkstation = 0x00000001 // VER_NT_WORKSTATION
|
|
|
|
|
2015-07-25 10:35:07 +02:00
|
|
|
// GetOperatingSystem gets the name of the current operating system.
|
2015-05-08 14:59:38 -07:00
|
|
|
func GetOperatingSystem() (string, error) {
|
2022-03-03 17:32:53 -05:00
|
|
|
osversion := windows.RtlGetVersion() // Always succeeds.
|
|
|
|
rel := windowsOSRelease{
|
|
|
|
IsServer: osversion.ProductType != verNTWorkstation,
|
|
|
|
Build: osversion.BuildNumber,
|
|
|
|
}
|
2019-05-30 09:51:41 -07:00
|
|
|
|
2022-03-03 17:32:53 -05:00
|
|
|
// Make a best-effort attempt to retrieve the display version and
|
|
|
|
// Update Build Revision by querying undocumented registry values.
|
|
|
|
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
|
|
|
if err == nil {
|
|
|
|
defer key.Close()
|
|
|
|
if ver, err := getFirstStringValue(key,
|
|
|
|
"DisplayVersion", /* Windows 20H2 and above */
|
|
|
|
"ReleaseId", /* Windows 2009 and below */
|
|
|
|
); err == nil {
|
|
|
|
rel.DisplayVersion = ver
|
2019-05-30 09:51:41 -07:00
|
|
|
}
|
2022-03-03 17:32:53 -05:00
|
|
|
if ubr, _, err := key.GetIntegerValue("UBR"); err == nil {
|
|
|
|
rel.UBR = ubr
|
2019-05-30 09:51:41 -07:00
|
|
|
}
|
2018-02-28 14:54:21 -08:00
|
|
|
}
|
|
|
|
|
2022-03-03 17:32:53 -05:00
|
|
|
return rel.String(), nil
|
2019-05-30 09:51:41 -07:00
|
|
|
}
|
2018-02-28 14:54:21 -08:00
|
|
|
|
2022-03-03 17:32:53 -05:00
|
|
|
func getFirstStringValue(key registry.Key, names ...string) (string, error) {
|
|
|
|
for _, n := range names {
|
|
|
|
val, _, err := key.GetStringValue(n)
|
|
|
|
if err != nil {
|
|
|
|
if !errors.Is(err, registry.ErrNotExist) {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return val, nil
|
2015-05-08 14:59:38 -07:00
|
|
|
}
|
2022-03-03 17:32:53 -05:00
|
|
|
return "", registry.ErrNotExist
|
2019-05-30 09:51:41 -07:00
|
|
|
}
|
2015-05-08 14:59:38 -07:00
|
|
|
|
2019-05-30 09:51:41 -07:00
|
|
|
// GetOperatingSystemVersion gets the version of the current operating system, as a string.
|
|
|
|
func GetOperatingSystemVersion() (string, error) {
|
2022-02-17 18:25:38 +01:00
|
|
|
return osversion.Get().ToString(), nil
|
2015-05-08 14:59:38 -07:00
|
|
|
}
|
|
|
|
|
2015-07-25 10:35:07 +02:00
|
|
|
// IsContainerized returns true if we are running inside a container.
|
|
|
|
// No-op on Windows, always returns false.
|
2015-05-08 14:59:38 -07:00
|
|
|
func IsContainerized() (bool, error) {
|
|
|
|
return false, nil
|
|
|
|
}
|
2022-03-16 00:41:30 +01:00
|
|
|
|
|
|
|
// IsWindowsClient returns true if the SKU is client. It returns false on
|
|
|
|
// Windows server.
|
|
|
|
func IsWindowsClient() bool {
|
|
|
|
return windows.RtlGetVersion().ProductType == verNTWorkstation
|
|
|
|
}
|