mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-05 09:17:54 +03:00
Updating new UDS Actor
This commit is contained in:
parent
e76df6349d
commit
2c8963ba5f
@ -77,6 +77,8 @@ class UDSConfigDialog(QDialog):
|
||||
def browse(self, lineEdit: 'QLineEdit', caption: str) -> None:
|
||||
name = QFileDialog.getOpenFileName(parent=self, caption=caption, directory=os.path.dirname(lineEdit.text()))[0]
|
||||
if name:
|
||||
if ' ' in name:
|
||||
name = '"' + name + '"'
|
||||
lineEdit.setText(os.path.normpath(name))
|
||||
|
||||
def browsePreconnect(self) -> None:
|
||||
|
@ -193,7 +193,7 @@ class REST:
|
||||
os = r['os']
|
||||
return types.InitializationResultType(
|
||||
own_token=r['own_token'],
|
||||
unique_id=r['unique_id'],
|
||||
unique_id=r['unique_id'].lower(),
|
||||
max_idle=r['max_idle'],
|
||||
os=types.ActorOsConfigurationType(
|
||||
action=os['action'],
|
||||
|
@ -67,28 +67,19 @@ class CommonService:
|
||||
_interfaces: typing.List[types.InterfaceInfoType]
|
||||
|
||||
@staticmethod
|
||||
def execute(cmdLine: str, section: str):
|
||||
cmd = shlex.split(cmdLine, posix=False)
|
||||
def execute(cmdLine: str, section: str) -> bool:
|
||||
try:
|
||||
res = subprocess.check_call(cmdLine)
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing: {} - {} - {}'.format(section, cmdLine, e))
|
||||
return False
|
||||
logger.info('Result of executing cmd for {} was {}'.format(section, res))
|
||||
return True
|
||||
|
||||
if os.path.isfile(cmd[0]):
|
||||
if (os.stat(cmd[0]).st_mode & stat.S_IXUSR) != 0:
|
||||
try:
|
||||
res = subprocess.check_call(cmd)
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing: {} - {}'.format(cmdLine, e))
|
||||
return False
|
||||
logger.info('Result of executing cmd was {}'.format(res))
|
||||
return True
|
||||
logger.error('{} file exists but it it is not executable (needs execution permission by admin/root)'.format(section))
|
||||
else:
|
||||
logger.error('{} file not found & not executed'.format(section))
|
||||
|
||||
return False
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
self._cfg = platform.store.readConfig()
|
||||
self._interfaces = []
|
||||
self._api = rest.REST(self._cfg.host, self._cfg.validateCert)
|
||||
self._api = rest.REST(self._cfg.host, self._cfg.validateCertificate)
|
||||
|
||||
socket.setdefaulttimeout(20)
|
||||
|
||||
@ -96,18 +87,34 @@ class CommonService:
|
||||
self._rebootRequested = True
|
||||
|
||||
def setReady(self) -> None:
|
||||
# First, if postconfig is available, execute it and disable it
|
||||
if self._cfg.post_command:
|
||||
self.execute(self._cfg.post_command, 'postConfig')
|
||||
self._cfg = self._cfg._replace(post_command=None)
|
||||
platform.store.writeConfig(self._cfg)
|
||||
|
||||
if self._cfg.own_token and self._interfaces:
|
||||
self._api.ready(self._cfg.own_token, self._interfaces)
|
||||
# Cleans sensible data
|
||||
if self._cfg.config:
|
||||
self._cfg._replace(config=self._cfg.config._replace(os=None), data=None)
|
||||
platform.store.writeConfig(self._cfg)
|
||||
if self._cfg.config:
|
||||
self._cfg = self._cfg._replace(config=self._cfg.config._replace(os=None), data=None)
|
||||
platform.store.writeConfig(self._cfg)
|
||||
|
||||
def configureMachine(self) -> bool:
|
||||
# Retry configurations, config in case of error 10 times
|
||||
counter = 1
|
||||
while counter < 10 and self._isAlive:
|
||||
counter += 1
|
||||
# First, if runonce is present, honor it and remove it from config
|
||||
# Return values is "True" for keep service (or daemon) running, False if Stop it.
|
||||
if self._cfg.runonce_command:
|
||||
runOnce = self._cfg.runonce_command
|
||||
self._cfg = self._cfg._replace(runonce_command=None)
|
||||
platform.store.writeConfig(self._cfg)
|
||||
if self.execute(runOnce, "runOnce"):
|
||||
# If runonce is present, will not do anythin more
|
||||
# So we have to ensure that, when runonce command is finished, reboots the machine.
|
||||
# That is, the COMMAND itself has to restart the machine!
|
||||
return False # If the command fails, continue with the rest of the operations...
|
||||
|
||||
# Retry configuration while not stop service, config in case of error 10 times
|
||||
while self._isAlive:
|
||||
try:
|
||||
if self._cfg.config and self._cfg.config.os:
|
||||
osData = self._cfg.config.os
|
||||
@ -121,10 +128,10 @@ class CommonService:
|
||||
platform.operations.reboot()
|
||||
except Exception as e:
|
||||
logger.error('Exception on reboot: {}'.format(e))
|
||||
return False # Stops service
|
||||
return False # Stops service if reboot was requested ofc
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error('Got exception operationg machine: {}'.format(e))
|
||||
logger.error('Got exception operating machine: {}'.format(e))
|
||||
self.doWait(5000)
|
||||
|
||||
return True
|
||||
@ -169,29 +176,28 @@ class CommonService:
|
||||
except rest.RESTError as e: # Invalid key?
|
||||
logger.error('Error validating with broker. (Invalid token?): {}'.format(e))
|
||||
|
||||
self.configureMachine()
|
||||
|
||||
return True
|
||||
return self.configureMachine()
|
||||
|
||||
def checkIpsChanged(self):
|
||||
if not self._cfg.own_token or not self._cfg.config or not self._cfg.config.unique_id:
|
||||
# Not enouth data do check
|
||||
return
|
||||
|
||||
unique_id = self._cfg.config.unique_id
|
||||
def locateMac(interfaces: typing.Iterable[types.InterfaceInfoType]) -> typing.Optional[types.InterfaceInfoType]:
|
||||
try:
|
||||
return next(x for x in interfaces if x.mac.lower() == self._cfg.config.unique_id.lower())
|
||||
return next(x for x in interfaces if x.mac.lower() == unique_id)
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
try:
|
||||
oldIp = locateMac(self._interfaces)
|
||||
newIp = locateMac(platform.operations.getNetworkInfo())
|
||||
if not newIp:
|
||||
old: types.InterfaceInfoType = locateMac(self._interfaces)
|
||||
new: types.InterfaceInfoType = locateMac(platform.operations.getNetworkInfo())
|
||||
if not new:
|
||||
raise Exception('No ip currently available for {}'.format(self._cfg.config.unique_id))
|
||||
if oldIp != newIp:
|
||||
self._api.notifyIpChange(self._cfg.own_token, newIp)
|
||||
logger.info('Ip changed from {} to {}. Notified to UDS'.format(oldIp, newIp))
|
||||
if old.ip != new.ip:
|
||||
self._api.notifyIpChange(self._cfg.own_token, new.ip)
|
||||
logger.info('Ip changed from {} to {}. Notified to UDS'.format(old.ip, new.ip))
|
||||
except Exception as e:
|
||||
# No ip changed, log exception for info
|
||||
logger.warn('Checking ips faield: {}'.format(e))
|
||||
@ -199,45 +205,58 @@ class CommonService:
|
||||
# ***************************************************
|
||||
# Methods that ARE overriden by linux & windows Actor
|
||||
# ***************************************************
|
||||
def rename(self, name: str, user: typing.Optional[str] = None, oldPassword: typing.Optional[str] = None, newPassword: typing.Optional[str] = None):
|
||||
def rename( # pylint: disable=unused-argument
|
||||
self,
|
||||
name: str,
|
||||
user: typing.Optional[str] = None,
|
||||
oldPassword: typing.Optional[str] = None,
|
||||
newPassword: typing.Optional[str] = None
|
||||
) -> None:
|
||||
'''
|
||||
Invoked when broker requests a rename action
|
||||
MUST BE OVERRIDEN
|
||||
default does nothing
|
||||
'''
|
||||
raise NotImplementedError('Method renamed has not been implemented!')
|
||||
logger.info('Base renamed invoked: {}'.format(name))
|
||||
|
||||
def joinDomain(self, name: str, domain: str, ou: str, account: str, password: str):
|
||||
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||
self,
|
||||
name: str,
|
||||
domain: str,
|
||||
ou: str,
|
||||
account: str,
|
||||
password: str
|
||||
) -> None:
|
||||
'''
|
||||
Invoked when broker requests a "domain" action
|
||||
MUST BE OVERRIDEN
|
||||
default does nothing
|
||||
'''
|
||||
raise NotImplementedError('Method renamed has not been implemented!')
|
||||
logger.info('Base join invode: {} on {}, {}'.format(name, domain, ou))
|
||||
|
||||
# ****************************************
|
||||
# Methods that CAN BE overriden by actors
|
||||
# ****************************************
|
||||
def notifyLocal(self):
|
||||
def notifyLocal(self) -> None:
|
||||
self.setReady()
|
||||
|
||||
def doWait(self, miliseconds):
|
||||
def doWait(self, miliseconds: int) -> None:
|
||||
'''
|
||||
Invoked to wait a bit
|
||||
CAN be OVERRIDEN
|
||||
'''
|
||||
time.sleep(float(miliseconds) / 1000)
|
||||
|
||||
def notifyStop(self):
|
||||
def notifyStop(self) -> None:
|
||||
'''
|
||||
Overriden to log stop
|
||||
'''
|
||||
logger.info('Service is being stopped')
|
||||
|
||||
def preConnect(self, user: str, protocol: str):
|
||||
def preConnect(self, user: str, protocol: str) -> str: # pylint: disable=unused-argument
|
||||
'''
|
||||
Invoked when received a PRE Connection request via REST
|
||||
'''
|
||||
logger.debug('Pre-connect does nothing')
|
||||
return 'ok'
|
||||
|
||||
def onLogout(self, user: str):
|
||||
def onLogout(self, user: str) -> None:
|
||||
logger.debug('On logout invoked for {}'.format(user))
|
||||
|
Loading…
Reference in New Issue
Block a user