Merge pull request #36379 from twangboy/windows_grains

Fix windows osrelease grain
This commit is contained in:
Mike Place 2016-09-20 22:09:39 +09:00 committed by GitHub
commit 266dd7c00a
2 changed files with 101 additions and 16 deletions

View File

@ -33,6 +33,8 @@ _supported_dists += ('arch', 'mageia', 'meego', 'vmware', 'bluewhite64',
import salt.log import salt.log
import salt.utils import salt.utils
import salt.utils.network import salt.utils.network
if salt.utils.is_windows():
import salt.utils.win_osinfo
# Solve the Chicken and egg problem where grains need to run before any # Solve the Chicken and egg problem where grains need to run before any
# of the modules are loaded and are generally available for any usage. # of the modules are loaded and are generally available for any usage.
@ -821,6 +823,10 @@ def _windows_platform_data():
Use the platform module for as much as we can. Use the platform module for as much as we can.
''' '''
# Provides: # Provides:
# kernelrelease
# osversion
# osrelease
# osservicepack
# osmanufacturer # osmanufacturer
# manufacturer # manufacturer
# productname # productname
@ -831,6 +837,7 @@ def _windows_platform_data():
# windowsdomain # windowsdomain
# motherboard.productname # motherboard.productname
# motherboard.serialnumber # motherboard.serialnumber
# virtual
if not HAS_WMI: if not HAS_WMI:
return {} return {}
@ -839,7 +846,7 @@ def _windows_platform_data():
wmi_c = wmi.WMI() wmi_c = wmi.WMI()
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx # http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx
systeminfo = wmi_c.Win32_ComputerSystem()[0] systeminfo = wmi_c.Win32_ComputerSystem()[0]
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394239%28v=vs.85%29.aspx # https://msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx
osinfo = wmi_c.Win32_OperatingSystem()[0] osinfo = wmi_c.Win32_OperatingSystem()[0]
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394077(v=vs.85).aspx # http://msdn.microsoft.com/en-us/library/windows/desktop/aa394077(v=vs.85).aspx
biosinfo = wmi_c.Win32_BIOS()[0] biosinfo = wmi_c.Win32_BIOS()[0]
@ -847,23 +854,49 @@ def _windows_platform_data():
timeinfo = wmi_c.Win32_TimeZone()[0] timeinfo = wmi_c.Win32_TimeZone()[0]
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394072(v=vs.85).aspx # http://msdn.microsoft.com/en-us/library/windows/desktop/aa394072(v=vs.85).aspx
motherboard = {} motherboard = {'product': None,
motherboard['product'] = None 'serial': None}
motherboard['serial'] = None
try: try:
motherboardinfo = wmi_c.Win32_BaseBoard()[0] motherboardinfo = wmi_c.Win32_BaseBoard()[0]
motherboard['product'] = motherboardinfo.Product motherboard['product'] = motherboardinfo.Product
motherboard['serial'] = motherboardinfo.SerialNumber motherboard['serial'] = motherboardinfo.SerialNumber
except IndexError: except IndexError:
log.debug('Motherboard info not available on this sytem') log.debug('Motherboard info not available on this system')
# the name of the OS comes with a bunch of other data about the install os_release = platform.release()
# location. For example: info = salt.utils.win_osinfo.get_os_version_info()
# 'Microsoft Windows Server 2008 R2 Standard |C:\\Windows|\\Device\\Harddisk0\\Partition2'
(osfullname, _) = osinfo.Name.split('|', 1) # Starting with Python 2.7.12 and 3.5.2 the `platform.uname()` function
osfullname = osfullname.strip() # started reporting the Desktop version instead of the Server version on
# Server versions of Windows, so we need to look those up
# Check for Python >=2.7.12 or >=3.5.2
ver = pythonversion()['pythonversion']
if ((six.PY2 and
salt.utils.compare_versions(ver, '>=', [2, 7, 12, 'final', 0]))
or
(six.PY3 and
salt.utils.compare_versions(ver, '>=', [3, 5, 2, 'final', 0]))):
# (Product Type 1 is Desktop, Everything else is Server)
if info['ProductType'] > 1:
server = {'Vista': '2008Server',
'7': '2008ServerR2',
'8': '2012Server',
'8.1': '2012ServerR2',
'10': '2016Server'}
os_release = server.get(os_release,
'Grain not found. Update lookup table '
'in the `_windows_platform_data` '
'function in `grains\\core.py`')
service_pack = None
if info['ServicePackMajor'] > 0:
service_pack = ''.join(['SP', str(info['ServicePackMajor'])])
grains = { grains = {
'kernelrelease': osinfo.Version,
'osversion': osinfo.Version,
'osrelease': os_release,
'osservicepack': service_pack,
'osmanufacturer': osinfo.Manufacturer, 'osmanufacturer': osinfo.Manufacturer,
'manufacturer': systeminfo.Manufacturer, 'manufacturer': systeminfo.Manufacturer,
'productname': systeminfo.Model, 'productname': systeminfo.Model,
@ -871,12 +904,12 @@ def _windows_platform_data():
# 'PhoenixBIOS 4.0 Release 6.0 ' # 'PhoenixBIOS 4.0 Release 6.0 '
'biosversion': biosinfo.Name.strip(), 'biosversion': biosinfo.Name.strip(),
'serialnumber': biosinfo.SerialNumber, 'serialnumber': biosinfo.SerialNumber,
'osfullname': osfullname, 'osfullname': osinfo.Caption,
'timezone': timeinfo.Description, 'timezone': timeinfo.Description,
'windowsdomain': systeminfo.Domain, 'windowsdomain': systeminfo.Domain,
'motherboard': { 'motherboard': {
'productname': motherboard['product'], 'productname': motherboard['product'],
'serialnumber': motherboard['serial'] 'serialnumber': motherboard['serial'],
} }
} }
@ -1067,10 +1100,6 @@ def os_data():
grains['os'] = 'proxy' grains['os'] = 'proxy'
grains['os_family'] = 'proxy' grains['os_family'] = 'proxy'
elif salt.utils.is_windows(): elif salt.utils.is_windows():
with salt.utils.winapi.Com():
wmi_c = wmi.WMI()
grains['osrelease'] = grains['kernelrelease']
grains['osversion'] = grains['kernelrelease'] = wmi_c.Win32_OperatingSystem()[0].Version
grains['os'] = 'Windows' grains['os'] = 'Windows'
grains['os_family'] = 'Windows' grains['os_family'] = 'Windows'
grains.update(_memdata(grains)) grains.update(_memdata(grains))

56
salt/utils/win_osinfo.py Normal file
View File

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
'''
Get Versioning information from Windows
'''
# http://stackoverflow.com/questions/32300004/python-ctypes-getting-0-with-getversionex-function
from __future__ import absolute_import
import ctypes
from ctypes.wintypes import BYTE, WORD, DWORD, WCHAR
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
class OSVERSIONINFO(ctypes.Structure):
_fields_ = (('dwOSVersionInfoSize', DWORD),
('dwMajorVersion', DWORD),
('dwMinorVersion', DWORD),
('dwBuildNumber', DWORD),
('dwPlatformId', DWORD),
('szCSDVersion', WCHAR * 128))
def __init__(self, *args, **kwds):
super(OSVERSIONINFO, self).__init__(*args, **kwds)
self.dwOSVersionInfoSize = ctypes.sizeof(self)
kernel32.GetVersionExW(ctypes.byref(self))
class OSVERSIONINFOEX(OSVERSIONINFO):
_fields_ = (('wServicePackMajor', WORD),
('wServicePackMinor', WORD),
('wSuiteMask', WORD),
('wProductType', BYTE),
('wReserved', BYTE))
def errcheck_bool(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.GetVersionExW.errcheck = errcheck_bool
kernel32.GetVersionExW.argtypes = (ctypes.POINTER(OSVERSIONINFO),)
def get_os_version_info():
info = OSVERSIONINFOEX()
ret = {'MajorVersion': info.dwMajorVersion,
'MinorVersion': info.dwMinorVersion,
'BuildNumber': info.dwBuildNumber,
'PlatformID': info.dwPlatformId,
'ServicePackMajor': info.wServicePackMajor,
'ServicePackMinor': info.wServicePackMinor,
'SuiteMask': info.wSuiteMask,
'ProductType': info.wProductType}
return ret