mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-05 09:17:54 +03:00
Actor v3
This commit is contained in:
parent
6f3f573f61
commit
e5b4fb393f
@ -149,8 +149,13 @@ def loggoff() -> None:
|
||||
# subprocess.call(['/usr/bin/systemctl', 'reboot', '-i'])
|
||||
|
||||
|
||||
def renameComputer(newName: str) -> None:
|
||||
def renameComputer(newName: str) -> bool:
|
||||
'''
|
||||
Changes the computer name
|
||||
Returns True if reboot needed
|
||||
'''
|
||||
rename(newName)
|
||||
return False
|
||||
|
||||
|
||||
def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False):
|
||||
|
@ -33,7 +33,6 @@ import signal
|
||||
import typing
|
||||
|
||||
from . import operations
|
||||
from . import renamer
|
||||
from . import daemon
|
||||
|
||||
from ..log import logger
|
||||
@ -59,37 +58,6 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
def markForExit(self, signum, frame) -> None:
|
||||
self._isAlive = False
|
||||
|
||||
def rename( # pylint: disable=unused-argument
|
||||
self,
|
||||
name: str,
|
||||
userName: typing.Optional[str] = None,
|
||||
oldPassword: typing.Optional[str] = None,
|
||||
newPassword: typing.Optional[str] = None
|
||||
) -> None:
|
||||
'''
|
||||
Renames the computer, and optionally sets a password for an user
|
||||
before this
|
||||
'''
|
||||
hostName = operations.getComputerName()
|
||||
|
||||
if hostName.lower() == name.lower():
|
||||
logger.info('Computer name is already {}'.format(hostName))
|
||||
return
|
||||
|
||||
logger.debug('Data: {}'.format((name, userName, oldPassword, newPassword)))
|
||||
|
||||
# Check for password change request for an user
|
||||
if userName and oldPassword and newPassword:
|
||||
logger.info('Setting password for user {}'.format(userName))
|
||||
try:
|
||||
operations.changeUserPassword(userName, oldPassword, newPassword)
|
||||
except Exception as e:
|
||||
# We stop here without even renaming computer, because the
|
||||
# process has failed
|
||||
raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, e))
|
||||
|
||||
renamer.rename(name)
|
||||
|
||||
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||
self,
|
||||
name: str,
|
||||
@ -106,6 +74,7 @@ class UDSActorSvc(daemon.Daemon, CommonService):
|
||||
|
||||
# Linux daemon will continue running unless something is requested to
|
||||
if not self.initialize():
|
||||
self.notifyStop()
|
||||
return # Stop daemon if initializes told to do so
|
||||
|
||||
logger.debug('Initialized, setting ready')
|
||||
|
@ -202,9 +202,6 @@ class CommonService:
|
||||
# No ip changed, log exception for info
|
||||
logger.warn('Checking ips faield: {}'.format(e))
|
||||
|
||||
# ***************************************************
|
||||
# Methods that ARE overriden by linux & windows Actor
|
||||
# ***************************************************
|
||||
def rename( # pylint: disable=unused-argument
|
||||
self,
|
||||
name: str,
|
||||
@ -216,8 +213,28 @@ class CommonService:
|
||||
Invoked when broker requests a rename action
|
||||
default does nothing
|
||||
'''
|
||||
logger.info('Base renamed invoked: {}, {}'.format(name, userName))
|
||||
hostName = platform.operations.getComputerName()
|
||||
|
||||
if hostName.lower() == name.lower():
|
||||
logger.info('Computer name is already {}'.format(hostName))
|
||||
return
|
||||
|
||||
# Check for password change request for an user
|
||||
if userName and newPassword:
|
||||
logger.info('Setting password for user {}'.format(userName))
|
||||
try:
|
||||
platform.operations.changeUserPassword(userName, oldPassword or '', newPassword)
|
||||
except Exception as e:
|
||||
raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, str(e)))
|
||||
|
||||
if platform.operations.renameComputer(name):
|
||||
# Reboot just after renaming
|
||||
logger.info('Rebooting computer to activate new name {}'.format(name))
|
||||
self.reboot()
|
||||
|
||||
# ******************************************************
|
||||
# Methods that can be overriden by linux & windows Actor
|
||||
# ******************************************************
|
||||
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||
self,
|
||||
name: str,
|
||||
@ -248,7 +265,7 @@ class CommonService:
|
||||
'''
|
||||
logger.info('Service is being stopped')
|
||||
|
||||
def preConnect(self, user: str, protocol: str) -> str: # pylint: disable=unused-argument
|
||||
def preConnect(self, userName: str, protocol: str) -> str: # pylint: disable=unused-argument
|
||||
'''
|
||||
Invoked when received a PRE Connection request via REST
|
||||
Base preconnect executes the preconnect command
|
||||
@ -258,5 +275,5 @@ class CommonService:
|
||||
|
||||
return 'ok'
|
||||
|
||||
def onLogout(self, user: str) -> None:
|
||||
logger.debug('On logout invoked for {}'.format(user))
|
||||
def onLogout(self, userName: str) -> None:
|
||||
logger.debug('On logout invoked for {}'.format(userName))
|
||||
|
@ -86,7 +86,7 @@ def getDomainName() -> str:
|
||||
|
||||
return domain
|
||||
|
||||
def getWindowsVersion() -> str:
|
||||
def getWindowsVersion() -> typing.Tuple[int, int, int, int, str]:
|
||||
return win32api.GetVersionEx()
|
||||
|
||||
EWX_LOGOFF = 0x00000000
|
||||
@ -106,7 +106,11 @@ def reboot(flags: int = EWX_FORCEIFHUNG | EWX_REBOOT) -> None:
|
||||
def loggoff() -> None:
|
||||
win32api.ExitWindowsEx(EWX_LOGOFF)
|
||||
|
||||
def renameComputer(newName: str) -> None:
|
||||
def renameComputer(newName: str) -> bool:
|
||||
'''
|
||||
Changes the computer name
|
||||
Returns True if reboot needed
|
||||
'''
|
||||
# Needs admin privileges to work
|
||||
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0: # @UndefinedVariable
|
||||
# win32api.FormatMessage -> returns error string
|
||||
@ -115,6 +119,7 @@ def renameComputer(newName: str) -> None:
|
||||
error = getErrorMessage()
|
||||
computerName = win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
|
||||
raise Exception('Error renaming computer from {} to {}: {}'.format(computerName, newName, error))
|
||||
return True
|
||||
|
||||
NETSETUP_JOIN_DOMAIN = 0x00000001
|
||||
NETSETUP_ACCT_CREATE = 0x00000002
|
||||
@ -171,16 +176,18 @@ def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneSt
|
||||
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain, account, ', under OU {}'.format(ou) if ou is not None else '', res, error))
|
||||
|
||||
def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
|
||||
lpUser = LPCWSTR(user)
|
||||
lpOldPassword = LPCWSTR(oldPassword)
|
||||
lpNewPassword = LPCWSTR(newPassword)
|
||||
# lpUser = LPCWSTR(user)
|
||||
# lpOldPassword = LPCWSTR(oldPassword)
|
||||
# lpNewPassword = LPCWSTR(newPassword)
|
||||
|
||||
res = ctypes.windll.netapi32.NetUserChangePassword(None, lpUser, lpOldPassword, lpNewPassword)
|
||||
# res = ctypes.windll.netapi32.NetUserChangePassword(None, lpUser, lpOldPassword, lpNewPassword)
|
||||
# Try to set new password "a las bravas", ignoring old one. This will not work with domain users
|
||||
res = win32net.NetUserSetInfo(None, user, 1003, {'password': newPassword})
|
||||
|
||||
if res != 0:
|
||||
# Log the error, and raise exception to parent
|
||||
error = getErrorMessage(res)
|
||||
raise Exception('Error changing password for user {}: {} {}'.format(lpUser.value, res, error))
|
||||
raise Exception('Error changing password for user {}: {} {}'.format(user, res, error))
|
||||
|
||||
class LASTINPUTINFO(ctypes.Structure): # pylint: disable=too-few-public-methods
|
||||
_fields_ = [
|
||||
|
@ -33,6 +33,7 @@ import struct
|
||||
import subprocess
|
||||
import os
|
||||
import stat
|
||||
import typing
|
||||
|
||||
import win32serviceutil
|
||||
import win32service
|
||||
@ -43,12 +44,11 @@ import win32com.client
|
||||
import pythoncom
|
||||
import servicemanager
|
||||
|
||||
from udsactor import operations
|
||||
from udsactor import store
|
||||
from udsactor.service import CommonService
|
||||
from udsactor.service import initCfg
|
||||
from . import operations
|
||||
from . import store
|
||||
from ..service import CommonService
|
||||
|
||||
from udsactor.log import logger
|
||||
from ..log import logger
|
||||
|
||||
from .SENS import SensLogon
|
||||
from .SENS import logevent
|
||||
@ -57,70 +57,44 @@ from .SENS import SENSGUID_PUBLISHER
|
||||
from .SENS import PROGID_EventSubscription
|
||||
from .SENS import PROGID_EventSystem
|
||||
|
||||
POST_CMD = 'c:\\windows\\post-uds.bat'
|
||||
|
||||
REMOTE_USERS_SID = 'S-1-5-32-555' # Well nown sid for remote desktop users
|
||||
|
||||
class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
'''
|
||||
This class represents a Windows Service for managing actor interactions
|
||||
with UDS Broker and Machine
|
||||
'''
|
||||
# ServiceeFramework related
|
||||
_svc_name_ = "UDSActorNG"
|
||||
_svc_display_name_ = "UDS Actor Service"
|
||||
_svc_description_ = "UDS Actor Management Service"
|
||||
# 'System Event Notification' is the SENS service
|
||||
_svc_deps_ = ['EventLog', 'SENS']
|
||||
|
||||
_user: typing.Optional[str]
|
||||
_hWaitStop: typing.Any
|
||||
|
||||
def __init__(self, args):
|
||||
win32serviceutil.ServiceFramework.__init__(self, args)
|
||||
CommonService.__init__(self)
|
||||
self.hWaitStop = win32event.CreateEvent(None, 1, 0, None)
|
||||
|
||||
self._hWaitStop = win32event.CreateEvent(None, 1, 0, None)
|
||||
self._user = None
|
||||
|
||||
def SvcStop(self):
|
||||
def SvcStop(self) -> None:
|
||||
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
|
||||
self.isAlive = False
|
||||
self._isAlive = False
|
||||
win32event.SetEvent(self.hWaitStop)
|
||||
|
||||
SvcShutdown = SvcStop
|
||||
|
||||
def notifyStop(self):
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STOPPED,
|
||||
(self._svc_name_, ''))
|
||||
def notifyStop(self) -> None:
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STOPPED, (self._svc_name_, ''))
|
||||
|
||||
def doWait(self, miliseconds):
|
||||
def doWait(self, miliseconds: int) -> None:
|
||||
win32event.WaitForSingleObject(self.hWaitStop, miliseconds)
|
||||
|
||||
def rename(self, name, user=None, oldPassword=None, newPassword=None):
|
||||
'''
|
||||
Renames the computer, and optionally sets a password for an user
|
||||
before this
|
||||
'''
|
||||
hostName = operations.getComputerName()
|
||||
|
||||
if hostName.lower() == name.lower():
|
||||
logger.info('Computer name is now {}'.format(hostName))
|
||||
self.setReady()
|
||||
return
|
||||
|
||||
# Check for password change request for an user
|
||||
if user is not None:
|
||||
logger.info('Setting password for user {}'.format(user))
|
||||
try:
|
||||
operations.changeUserPassword(user, oldPassword, newPassword)
|
||||
except Exception as e:
|
||||
# We stop here without even renaming computer, because the
|
||||
# process has failed
|
||||
raise Exception(
|
||||
'Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(user, str(e)))
|
||||
|
||||
operations.renameComputer(name)
|
||||
# Reboot just after renaming
|
||||
logger.info('Rebooting computer to activate new name {}'.format(name))
|
||||
self.reboot()
|
||||
|
||||
def oneStepJoin(self, name, domain, ou, account, password):
|
||||
def oneStepJoin(self, name: str, domain: str, ou: str, account: str, password: str) -> None:
|
||||
'''
|
||||
Ejecutes the join domain in exactly one step
|
||||
'''
|
||||
@ -129,176 +103,126 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
# name will not change
|
||||
if currName.lower() == name.lower():
|
||||
self.multiStepJoin(name, domain, ou, account, password)
|
||||
else:
|
||||
operations.renameComputer(name)
|
||||
logger.debug('Computer renamed to {} without reboot'.format(name))
|
||||
operations.joinDomain(
|
||||
domain, ou, account, password, executeInOneStep=True)
|
||||
logger.debug(
|
||||
'Requested join domain {} without errors'.format(domain))
|
||||
self.reboot()
|
||||
return
|
||||
|
||||
def multiStepJoin(self, name, domain, ou, account, password):
|
||||
operations.renameComputer(name)
|
||||
logger.debug('Computer renamed to {} without reboot'.format(name))
|
||||
operations.joinDomain(domain, ou, account, password, executeInOneStep=True)
|
||||
logger.debug('Requested join domain {} without errors'.format(domain))
|
||||
self.reboot()
|
||||
|
||||
def multiStepJoin(self, name: str, domain: str, ou: str, account: str, password: str) -> None:
|
||||
currName = operations.getComputerName()
|
||||
if currName.lower() == name.lower():
|
||||
currDomain = operations.getDomainName()
|
||||
if currDomain is not None:
|
||||
if currDomain:
|
||||
# logger.debug('Name: "{}" vs "{}", Domain: "{}" vs "{}"'.format(currName.lower(), name.lower(), currDomain.lower(), domain.lower()))
|
||||
logger.info('Machine {} is part of domain {}'.format(name, domain))
|
||||
self.setReady()
|
||||
else:
|
||||
operations.joinDomain(
|
||||
domain, ou, account, password, executeInOneStep=False)
|
||||
operations.joinDomain(domain, ou, account, password, executeInOneStep=False)
|
||||
self.reboot()
|
||||
else:
|
||||
operations.renameComputer(name)
|
||||
logger.info(
|
||||
'Rebooting computer got activate new name {}'.format(name))
|
||||
logger.info('Rebooting computer got activate new name {}'.format(name))
|
||||
self.reboot()
|
||||
|
||||
def joinDomain(self, name, domain, ou, account, password):
|
||||
ver = operations.getWindowsVersion()
|
||||
ver = ver[0] * 10 + ver[1]
|
||||
logger.debug('Starting joining domain {} with name {} (detected operating version: {})'.format(
|
||||
domain, name, ver))
|
||||
# If file c:\compat.bin exists, joind domain in two steps instead one
|
||||
|
||||
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||
self,
|
||||
name: str,
|
||||
domain: str,
|
||||
ou: str,
|
||||
account: str,
|
||||
password: str
|
||||
) -> None:
|
||||
versionData = operations.getWindowsVersion()
|
||||
versionInt = versionData[0] * 10 + versionData[1]
|
||||
logger.debug('Starting joining domain {} with name {} (detected operating version: {})'.format(domain, name, versionData))
|
||||
# Accepts one step joinDomain, also remember XP is no more supported by
|
||||
# microsoft, but this also must works with it because will do a "multi
|
||||
# step" join
|
||||
if ver >= 60 and store.useOldJoinSystem() is False:
|
||||
if versionInt >= 60 and not store.useOldJoinSystem():
|
||||
self.oneStepJoin(name, domain, ou, account, password)
|
||||
else:
|
||||
logger.info('Using multiple step join because configuration requests to do so')
|
||||
self.multiStepJoin(name, domain, ou, account, password)
|
||||
|
||||
def preConnect(self, user, protocol):
|
||||
def preConnect(self, userName: str, protocol: str) -> str:
|
||||
logger.debug('Pre connect invoked')
|
||||
if protocol != 'rdp': # If connection is not using rdp, skip adding user
|
||||
return 'ok'
|
||||
# Well known SSID for Remote Desktop Users
|
||||
REMOTE_USERS_SID = 'S-1-5-32-555'
|
||||
|
||||
p = win32security.GetBinarySid(REMOTE_USERS_SID)
|
||||
groupName = win32security.LookupAccountSid(None, p)[0]
|
||||
if protocol == 'rdp': # If connection is not using rdp, skip adding user
|
||||
# Well known SSID for Remote Desktop Users
|
||||
groupName = win32security.LookupAccountSid(None, win32security.GetBinarySid(REMOTE_USERS_SID))[0]
|
||||
|
||||
useraAlreadyInGroup = False
|
||||
resumeHandle = 0
|
||||
while True:
|
||||
users, _, resumeHandle = win32net.NetLocalGroupGetMembers(None, groupName, 1, resumeHandle, 32768)
|
||||
if user.lower() in [u['name'].lower() for u in users]:
|
||||
useraAlreadyInGroup = True
|
||||
break
|
||||
if resumeHandle == 0:
|
||||
break
|
||||
useraAlreadyInGroup = False
|
||||
resumeHandle = 0
|
||||
while True:
|
||||
users, _, resumeHandle = win32net.NetLocalGroupGetMembers(None, groupName, 1, resumeHandle, 32768)
|
||||
if userName.lower() in [u['name'].lower() for u in users]:
|
||||
useraAlreadyInGroup = True
|
||||
break
|
||||
if resumeHandle == 0:
|
||||
break
|
||||
|
||||
if useraAlreadyInGroup is False:
|
||||
logger.debug('User not in group, adding it')
|
||||
self._user = user
|
||||
try:
|
||||
userSSID = win32security.LookupAccountName(None, user)[0]
|
||||
win32net.NetLocalGroupAddMembers(None, groupName, 0, [{'sid': userSSID}])
|
||||
except Exception as e:
|
||||
logger.error('Exception adding user to Remote Desktop Users: {}'.format(e))
|
||||
else:
|
||||
self._user = None
|
||||
logger.debug('User {} already in group'.format(user))
|
||||
|
||||
# Now try to run pre connect command
|
||||
try:
|
||||
pre_cmd = store.preApplication()
|
||||
if os.path.isfile(pre_cmd):
|
||||
if (os.stat(pre_cmd).st_mode & stat.S_IXUSR) != 0:
|
||||
subprocess.call([pre_cmd, user, protocol])
|
||||
else:
|
||||
logger.info('PRECONNECT file exists but it it is not executable (needs execution permission by root)')
|
||||
if not useraAlreadyInGroup:
|
||||
logger.debug('User not in group, adding it')
|
||||
self._user = userName
|
||||
try:
|
||||
userSSID = win32security.LookupAccountName(None, userName)[0]
|
||||
win32net.NetLocalGroupAddMembers(None, groupName, 0, [{'sid': userSSID}])
|
||||
except Exception as e:
|
||||
logger.error('Exception adding user to Remote Desktop Users: {}'.format(e))
|
||||
else:
|
||||
logger.info('PRECONNECT file not found & not executed')
|
||||
except Exception as e:
|
||||
# Ignore output of execution command
|
||||
logger.error('Executing preconnect command give')
|
||||
self._user = None
|
||||
logger.debug('User {} already in group'.format(userName))
|
||||
|
||||
return 'ok'
|
||||
return super().preConnect(userName, protocol)
|
||||
|
||||
def ovLogon(self, username, password):
|
||||
def ovLogon(self, username: str, password: str) -> str:
|
||||
"""
|
||||
Logon on oVirt agent
|
||||
currently not used.
|
||||
"""
|
||||
# Compose packet for ov
|
||||
ub = username.encode('utf8')
|
||||
up = username.encode('utf8')
|
||||
packet = struct.pack('!I', len(ub)) + ub + struct.pack('!I', len(up)) + up
|
||||
usernameBytes = username.encode()
|
||||
passwordBytes = username.encode()
|
||||
packet = struct.pack('!I', len(usernameBytes)) + usernameBytes + struct.pack('!I', len(passwordBytes)) + passwordBytes
|
||||
# Send packet with username/password to ov pipe
|
||||
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
|
||||
return 'done'
|
||||
|
||||
def onLogout(self, user):
|
||||
def onLogout(self, userName) -> None:
|
||||
logger.debug('Windows onLogout invoked: {}, {}'.format(user, self._user))
|
||||
try:
|
||||
REMOTE_USERS_SID = 'S-1-5-32-555'
|
||||
p = win32security.GetBinarySid(REMOTE_USERS_SID)
|
||||
groupName = win32security.LookupAccountSid(None, p)[0]
|
||||
except Exception:
|
||||
logger.error('Exception getting Windows Group')
|
||||
return
|
||||
|
||||
if self._user is not None:
|
||||
if self._user:
|
||||
try:
|
||||
win32net.NetLocalGroupDelMembers(None, groupName, [self._user])
|
||||
except Exception as e:
|
||||
logger.error('Exception removing user from Remote Desktop Users: {}'.format(e))
|
||||
|
||||
def SvcDoRun(self): # pylint: disable=too-many-statements, too-many-branches
|
||||
def SvcDoRun(self) -> None: # pylint: disable=too-many-statements, too-many-branches
|
||||
'''
|
||||
Main service loop
|
||||
'''
|
||||
try:
|
||||
initCfg()
|
||||
logger.debug('running SvcDoRun')
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ''))
|
||||
|
||||
logger.debug('running SvcDoRun')
|
||||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
|
||||
servicemanager.PYS_SERVICE_STARTED,
|
||||
(self._svc_name_, ''))
|
||||
# call the CoInitialize to allow the registration to run in an other
|
||||
# thread
|
||||
logger.debug('Initializing com...')
|
||||
|
||||
pythoncom.CoInitialize()
|
||||
|
||||
# call the CoInitialize to allow the registration to run in an other
|
||||
# thread
|
||||
logger.debug('Initializing com...')
|
||||
pythoncom.CoInitialize()
|
||||
|
||||
# ********************************************************
|
||||
# * Ask brokers what to do before proceding to main loop *
|
||||
# ********************************************************
|
||||
while True:
|
||||
brokerConnected = self.interactWithBroker()
|
||||
if brokerConnected is False:
|
||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
||||
self.notifyStop()
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
||||
return
|
||||
elif brokerConnected is True:
|
||||
break
|
||||
|
||||
# If brokerConnected returns None, repeat the cycle
|
||||
self.doWait(16000) # Wait for a looong while
|
||||
|
||||
if self.interactWithBroker() is False:
|
||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
||||
self.notifyStop()
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
||||
return
|
||||
|
||||
if self.isAlive is False:
|
||||
logger.debug('The service is not alive after broker interaction, stopping it')
|
||||
self.notifyStop()
|
||||
return
|
||||
|
||||
if self.rebootRequested is True:
|
||||
logger.debug('Reboot has been requested, stopping service')
|
||||
self.notifyStop()
|
||||
return
|
||||
|
||||
self.initIPC()
|
||||
except Exception: # Any init exception wil be caught, service must be then restarted
|
||||
logger.exception()
|
||||
logger.debug('Exiting service with failure status')
|
||||
os._exit(-1) # pylint: disable=protected-access
|
||||
if not self.initialize():
|
||||
self.notifyStop()
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
||||
return # Stop daemon if initializes told to do so
|
||||
|
||||
# ********************************
|
||||
# * Registers SENS subscriptions *
|
||||
@ -319,18 +243,11 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
|
||||
event_system.Store(PROGID_EventSubscription, event_subscription)
|
||||
|
||||
logger.debug('Registered SENS, running main loop')
|
||||
logger.debug('Registered SENS')
|
||||
logger.debug('Initialized, setting ready')
|
||||
|
||||
# Execute script in c:\\windows\\post-uds.bat after interacting with broker, if no reboot is requested ofc
|
||||
# This will be executed only when machine gets "ready"
|
||||
try:
|
||||
if os.path.isfile(POST_CMD):
|
||||
subprocess.call([POST_CMD, ])
|
||||
else:
|
||||
logger.info('POST file not found & not executed')
|
||||
except Exception as e:
|
||||
# Ignore output of execution command
|
||||
logger.error('Executing post command give')
|
||||
# Initialization is done, set machine to ready for UDS, communicate urls, etc...
|
||||
self.setReady()
|
||||
|
||||
# *********************
|
||||
# * Main Service loop *
|
||||
@ -338,17 +255,15 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
# Counter used to check ip changes only once every 10 seconds, for
|
||||
# example
|
||||
counter = 0
|
||||
while self.isAlive:
|
||||
while self._isAlive:
|
||||
counter += 1
|
||||
# Process SENS messages, This will be a bit asyncronous (1 second
|
||||
# delay)
|
||||
# Process SENS messages, This will be a bit asyncronous (1 second delay)
|
||||
pythoncom.PumpWaitingMessages()
|
||||
if counter >= 15: # Once every 15 seconds
|
||||
|
||||
if counter >= 10: # Once every 15 seconds
|
||||
counter = 0
|
||||
try:
|
||||
self.checkIpsChanged()
|
||||
except Exception as e:
|
||||
logger.error('Error checking ip change: {}'.format(e))
|
||||
self.checkIpsChanged()
|
||||
|
||||
# In milliseconds, will break
|
||||
win32event.WaitForSingleObject(self.hWaitStop, 1000)
|
||||
|
||||
@ -357,10 +272,6 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||
# *******************************************
|
||||
# * Remove SENS subscription before exiting *
|
||||
# *******************************************
|
||||
event_system.Remove(
|
||||
PROGID_EventSubscription, "SubscriptionID == " + subscription_guid)
|
||||
|
||||
self.endIPC() # Ends IPC servers
|
||||
self.endAPI() # And deinitializes REST api if needed
|
||||
event_system.Remove(PROGID_EventSubscription, "SubscriptionID == " + subscription_guid)
|
||||
|
||||
self.notifyStop()
|
||||
|
Loading…
Reference in New Issue
Block a user