Merge pull request #36442 from rallytime/merge-2016.3

[2016.3] Merge forward from 2015.8 to 2016.3
This commit is contained in:
Nicole Thomas 2016-09-20 17:16:30 -06:00 committed by GitHub
commit c8e15dcdca
4 changed files with 137 additions and 20 deletions

View File

@ -36,6 +36,8 @@ _supported_dists += ('arch', 'mageia', 'meego', 'vmware', 'bluewhite64',
import salt.log
import salt.utils
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
# of the modules are loaded and are generally available for any usage.
@ -866,6 +868,10 @@ def _windows_platform_data():
Use the platform module for as much as we can.
'''
# Provides:
# kernelrelease
# osversion
# osrelease
# osservicepack
# osmanufacturer
# manufacturer
# productname
@ -876,6 +882,7 @@ def _windows_platform_data():
# windowsdomain
# motherboard.productname
# motherboard.serialnumber
# virtual
if not HAS_WMI:
return {}
@ -884,7 +891,7 @@ def _windows_platform_data():
wmi_c = wmi.WMI()
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx
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]
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394077(v=vs.85).aspx
biosinfo = wmi_c.Win32_BIOS()[0]
@ -892,9 +899,8 @@ def _windows_platform_data():
timeinfo = wmi_c.Win32_TimeZone()[0]
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394072(v=vs.85).aspx
motherboard = {}
motherboard['product'] = None
motherboard['serial'] = None
motherboard = {'product': None,
'serial': None}
try:
motherboardinfo = wmi_c.Win32_BaseBoard()[0]
motherboard['product'] = motherboardinfo.Product
@ -902,13 +908,40 @@ def _windows_platform_data():
except IndexError:
log.debug('Motherboard info not available on this system')
# the name of the OS comes with a bunch of other data about the install
# location. For example:
# 'Microsoft Windows Server 2008 R2 Standard |C:\\Windows|\\Device\\Harddisk0\\Partition2'
(osfullname, _) = osinfo.Name.split('|', 1)
osfullname = osfullname.strip()
os_release = platform.release()
info = salt.utils.win_osinfo.get_os_version_info()
# Starting with Python 2.7.12 and 3.5.2 the `platform.uname()` function
# 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 = {
'kernelrelease': osinfo.Version,
'osversion': osinfo.Version,
'osrelease': os_release,
'osservicepack': service_pack,
'osmanufacturer': osinfo.Manufacturer,
'manufacturer': systeminfo.Manufacturer,
'productname': systeminfo.Model,
@ -916,12 +949,12 @@ def _windows_platform_data():
# 'PhoenixBIOS 4.0 Release 6.0 '
'biosversion': biosinfo.Name.strip(),
'serialnumber': biosinfo.SerialNumber,
'osfullname': osfullname,
'osfullname': osinfo.Caption,
'timezone': timeinfo.Description,
'windowsdomain': systeminfo.Domain,
'motherboard': {
'productname': motherboard['product'],
'serialnumber': motherboard['serial']
'serialnumber': motherboard['serial'],
}
}
@ -1146,10 +1179,6 @@ def os_data():
grains['os_family'] = 'proxy'
grains['osfullname'] = 'proxy'
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_family'] = 'Windows'
grains.update(_memdata(grains))

View File

@ -140,8 +140,11 @@ def _strip_exc(exc):
return re.sub(r'^Command [\'"].+[\'"] failed: ', '', exc.strerror)
def _uptodate(ret, target, comments=None):
def _uptodate(ret, target, comments=None, local_changes=False):
ret['comment'] = 'Repository {0} is up-to-date'.format(target)
if local_changes:
ret['comment'] += ', but with local changes. Set \'force_reset\' to ' \
'True to purge local changes.'
if comments:
# Shouldn't be making any changes if the repo was up to date, but
# report on them so we are alerted to potential problems with our
@ -773,6 +776,30 @@ def latest(name,
)
local_changes = False
if local_changes and revs_match:
if force_reset:
msg = (
'{0} is up-to-date, but with local changes. Since '
'\'force_reset\' is enabled, these local changes '
'would be reset.'.format(target)
)
if __opts__['test']:
ret['changes']['forced update'] = True
if comments:
msg += _format_comments(comments)
return _neutral_test(ret, msg)
log.debug(msg.replace('would', 'will'))
else:
log.debug(
'%s up-to-date, but with local changes. Since '
'\'force_reset\' is disabled, no changes will be '
'made.', target
)
return _uptodate(ret,
target,
_format_comments(comments),
local_changes)
if remote_rev_type == 'sha1' \
and base_rev is not None \
and base_rev.startswith(remote_rev):
@ -866,7 +893,7 @@ def latest(name,
has_remote_rev = True
# If fast_forward is not boolean, then we don't know if this will
# be a fast forward or not, because a fetch is requirde.
# be a fast forward or not, because a fetch is required.
fast_forward = None if not local_changes else False
if has_remote_rev:

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

View File

@ -175,16 +175,21 @@ class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
# Make sure that we now have uncommitted changes
self.assertTrue(self.run_function('git.diff', [name, 'HEAD']))
# Re-run state with force_reset=False, this should fail
# Re-run state with force_reset=False
ret = self.run_state(
'git.latest',
name='https://{0}/saltstack/salt-test-repo.git'.format(self.__domain),
target=name,
force_reset=False
)
self.assertSaltFalseReturn(ret)
self.assertSaltTrueReturn(ret)
self.assertEqual(
ret[next(iter(ret))]['comment'],
('Repository {0} is up-to-date, but with local changes. Set '
'\'force_reset\' to True to purge local changes.'.format(name))
)
# Now run the state with force_reset=True, this should succeed
# Now run the state with force_reset=True
ret = self.run_state(
'git.latest',
name='https://{0}/saltstack/salt-test-repo.git'.format(self.__domain),