Merge pull request #39370 from twangboy/gate_win_utils

Gate win_osinfo and winservice
This commit is contained in:
Mike Place 2017-02-17 16:53:58 -07:00 committed by GitHub
commit e4c71683d9
3 changed files with 104 additions and 69 deletions

View file

@ -5,17 +5,33 @@ from __future__ import absolute_import
import sys
# Import salt libs
from salt.utils.winservice import Service, instart
from salt.utils.winservice import service, instart
import salt
import salt.defaults.exitcodes
# Import third party libs
import win32serviceutil
import win32service
import winerror
try:
import win32serviceutil
import win32service
import winerror
HAS_WIN32 = True
except ImportError:
HAS_WIN32 = False
class MinionService(Service):
# Although utils are often directly imported, it is also possible to use the
# loader.
def __virtual__():
'''
Only load if Win32 Libraries are installed
'''
if not HAS_WIN32:
return False, 'This utility requires pywin32'
return 'saltminionservice'
class MinionService(service(False)):
def start(self):
self.runflag = True

View file

@ -29,40 +29,42 @@ def __virtual__():
return 'win_osinfo'
class OSVERSIONINFO(ctypes.Structure):
_fields_ = (('dwOSVersionInfoSize', DWORD),
('dwMajorVersion', DWORD),
('dwMinorVersion', DWORD),
('dwBuildNumber', DWORD),
('dwPlatformId', DWORD),
('szCSDVersion', WCHAR * 128))
def os_version_info_ex():
'''
Helper function to return the results of the GetVersionExW Windows API call.
It is a ctypes Structure that contains Windows OS Version information.
def __init__(self, *args, **kwds):
super(OSVERSIONINFO, self).__init__(*args, **kwds)
self.dwOSVersionInfoSize = ctypes.sizeof(self)
kernel32.GetVersionExW(ctypes.byref(self))
Returns:
class: An instance of a class containing version info
'''
if not HAS_WIN32:
return
class OSVersionInfo(ctypes.Structure):
_fields_ = (('dwOSVersionInfoSize', DWORD),
('dwMajorVersion', DWORD),
('dwMinorVersion', DWORD),
('dwBuildNumber', DWORD),
('dwPlatformId', DWORD),
('szCSDVersion', WCHAR * 128))
class OSVERSIONINFOEX(OSVERSIONINFO):
_fields_ = (('wServicePackMajor', WORD),
('wServicePackMinor', WORD),
('wSuiteMask', WORD),
('wProductType', BYTE),
('wReserved', BYTE))
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
if HAS_WIN32:
kernel32.GetVersionExW.errcheck = errcheck_bool
kernel32.GetVersionExW.argtypes = (ctypes.POINTER(OSVERSIONINFO),)
return OSVersionInfoEx()
def get_os_version_info():
info = OSVERSIONINFOEX()
info = os_version_info_ex()
ret = {'MajorVersion': info.dwMajorVersion,
'MinorVersion': info.dwMinorVersion,
'BuildNumber': info.dwBuildNumber,

View file

@ -30,52 +30,69 @@ def __virtual__():
return 'winservice'
class Service(win32serviceutil.ServiceFramework):
def service(instantiated=True):
'''
Helper function to return an instance of the ServiceFramework class
_svc_name_ = '_unNamed'
_svc_display_name_ = '_Service Template'
Args:
instantiated (bool): True to return an instantiated object, False to
return the object definition. Use False if inherited by another
class. Default is True.
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
Returns:
class: An instance of the ServiceFramework class
'''
if not HAS_WIN32:
return
def log(self, msg):
import servicemanager
servicemanager.LogInfoMsg(str(msg))
class Service(win32serviceutil.ServiceFramework):
def sleep(self, sec):
win32api.Sleep(sec * 1000, True)
_svc_name_ = '_unNamed'
_svc_display_name_ = '_Service Template'
def SvcDoRun(self): # pylint: disable=C0103
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('start')
self.start()
self.log('wait')
win32event.WaitForSingleObject(self.stop_event,
win32event.INFINITE)
self.log('done')
except Exception as err:
self.log('Exception: {0}'.format(err))
self.SvcStop()
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self): # pylint: disable=C0103
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.log('stopping')
self.stop()
self.log('stopped')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def log(self, msg):
import servicemanager
servicemanager.LogInfoMsg(str(msg))
# to be overridden
def start(self):
pass
def sleep(self, sec):
win32api.Sleep(sec * 1000, True)
# to be overridden
def stop(self):
pass
def SvcDoRun(self): # pylint: disable=C0103
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('start')
self.start()
self.log('wait')
win32event.WaitForSingleObject(self.stop_event,
win32event.INFINITE)
self.log('done')
except Exception as err:
self.log('Exception: {0}'.format(err))
self.SvcStop()
def SvcStop(self): # pylint: disable=C0103
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.log('stopping')
self.stop()
self.log('stopped')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
# to be overridden
def start(self):
pass
# to be overridden
def stop(self):
pass
return Service() if instantiated else Service
def instart(cls, name, display_name=None, stay_alive=True):