diff --git a/actor/deps.txt b/actor/deps.txt new file mode 100644 index 000000000..8696e6b39 --- /dev/null +++ b/actor/deps.txt @@ -0,0 +1,3 @@ +Linux: +python3-prctl (recommended, but not required in fact) + diff --git a/actor/src/udsactor/linux/UDSActorService.py b/actor/src/udsactor/linux/UDSActorService.py index 67c6a28c3..54847b82e 100644 --- a/actor/src/udsactor/linux/UDSActorService.py +++ b/actor/src/udsactor/linux/UDSActorService.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,44 +29,45 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals - import sys -import os -import stat -import subprocess +import signal +import typing -from udsactor import operations +from . import operations +from . import renamer +from . import daemon -from udsactor.service import CommonService -from udsactor.service import initCfg -from udsactor.service import IPC_PORT +from ..log import logger +from ..service import CommonService -from udsactor import ipc -from udsactor import store -from udsactor.log import logger - -from udsactor.linux.daemon import Daemon -from udsactor.linux import renamer - -POST_CMD = '/etc/udsactor/post' try: from prctl import set_proctitle # @UnresolvedImport -except Exception: # Platform may not include prctl, so in case it's not available, we let the "name" as is - +except ImportError: # Platform may not include prctl, so in case it's not available, we let the "name" as is def set_proctitle(_): pass -class UDSActorSvc(Daemon, CommonService): - rebootMachineAfterOp = False - - def __init__(self, args=None): - Daemon.__init__(self, '/var/run/udsa.pid') +class UDSActorSvc(daemon.Daemon, CommonService): + def __init__(self, args=None) -> None: + daemon.Daemon.__init__(self, '/var/run/udsactor.pid') CommonService.__init__(self) - def rename(self, name, user=None, oldPassword=None, newPassword=None): + signal.signal(signal.SIGINT, self.markForExit) + signal.signal(signal.SIGTERM, self.markForExit) + + + def markForExit(self, signum, frame): + 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 @@ -75,103 +76,40 @@ class UDSActorSvc(Daemon, CommonService): if hostName.lower() == name.lower(): logger.info('Computer name is already {}'.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)) + if userName and oldPassword and newPassword: + logger.info('Setting password for user {}'.format(userName)) try: - operations.changeUserPassword(user, oldPassword, newPassword) + 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(user, unicode(e))) + raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, e)) renamer.rename(name) - if self.rebootMachineAfterOp is False: - self.setReady() - else: - logger.info('Rebooting computer to activate new name {}'.format(name)) - self.reboot() - - def joinDomain(self, name, domain, ou, account, password): + def joinDomain( # pylint: disable=unused-argument, too-many-arguments + self, + name: str, + domain: str, + ou: str, + account: str, + password: str + ) -> None: logger.fatal('Join domain is not supported on linux platforms right now') - def preConnect(self, user, protocol): - ''' - Invoked when received a PRE Connection request via REST - ''' - # Execute script in /etc/udsactor/post after interacting with broker, if no reboot is requested ofc - # This will be executed only when machine gets "ready" - 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)') - else: - logger.info('PRECONNECT file not found & not executed') - except Exception: - # Ignore output of execution command - logger.error('Executing preconnect command give') - - return 'ok' - def run(self): - cfg = initCfg() # Gets a local copy of config to get "reboot" - - logger.debug('CFG: {}'.format(cfg)) - - if cfg is not None: - self.rebootMachineAfterOp = cfg.get('reboot', True) - else: - self.rebootMachineAfterOp = False - - logger.info('Reboot after is {}'.format(self.rebootMachineAfterOp)) - logger.debug('Running Daemon') set_proctitle('UDSActorDaemon') # Linux daemon will continue running unless something is requested to - while True: - brokerConnected = self.interactWithBroker() - if brokerConnected is False: - logger.debug('Interact with broker returned false, stopping service after a while') - return - elif brokerConnected is True: - break + if not self.initialize(): + return # Stop daemon if initializes told to do so - # If brokerConnected returns None, repeat the cycle - self.doWait(16000) # Wait for a looong while - - if self.isAlive is False: - logger.debug('The service is not alive after broker interaction, stopping it') - return - - if self.rebootRequested is True: - logger.debug('Reboot has been requested, stopping service') - return - - # Execute script in /etc/udsactor/post 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): - if (os.stat(POST_CMD).st_mode & stat.S_IXUSR) != 0: - subprocess.call([POST_CMD, ]) - else: - logger.info('POST file exists but it it is not executable (needs execution permission by root)') - else: - logger.info('POST file not found & not executed') - except Exception as e: - # Ignore output of execution command - logger.error('Executing post command give') - - self.initIPC() + # Initialization is done, set machine to ready for UDS, communicate urls, etc... + self.setReady() # ********************* # * Main Service loop * @@ -186,9 +124,6 @@ class UDSActorSvc(Daemon, CommonService): # In milliseconds, will break self.doWait(1000) - self.endIPC() - self.endAPI() - self.notifyStop() @@ -202,31 +137,31 @@ if __name__ == '__main__': if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'): logger.debug('Running client udsactor') - client = None - try: - client = ipc.ClientIPC(IPC_PORT) - if 'login' == sys.argv[1]: - client.sendLogin(sys.argv[2]) - sys.exit(0) - elif 'logout' == sys.argv[1]: - client.sendLogout(sys.argv[2]) - sys.exit(0) - else: - usage() - except Exception as e: - logger.error(e) + # client = None + # try: + # client = ipc.ClientIPC(IPC_PORT) + # if 'login' == sys.argv[1]: + # client.sendLogin(sys.argv[2]) + # sys.exit(0) + # elif 'logout' == sys.argv[1]: + # client.sendLogout(sys.argv[2]) + # sys.exit(0) + # else: + # usage() + # except Exception as e: + # logger.error(e) elif len(sys.argv) != 2: usage() logger.debug('Executing actor') - daemon = UDSActorSvc() + daemonSvr = UDSActorSvc() if len(sys.argv) == 2: - if 'start' == sys.argv[1]: - daemon.start() - elif 'stop' == sys.argv[1]: - daemon.stop() - elif 'restart' == sys.argv[1]: - daemon.restart() + if sys.argv[1] == 'start': + daemonSvr.start() + elif sys.argv[1] == 'stop': + daemonSvr.stop() + elif sys.argv[1] == 'restart': + daemonSvr.restart() else: usage() sys.exit(0) diff --git a/actor/src/udsactor/linux/__init__.py b/actor/src/udsactor/linux/__init__.py index 3a98c7807..4db3bd57b 100644 --- a/actor/src/udsactor/linux/__init__.py +++ b/actor/src/udsactor/linux/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,4 +29,3 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals diff --git a/actor/src/udsactor/linux/daemon.py b/actor/src/udsactor/linux/daemon.py index 1953b62a6..baad7d95c 100644 --- a/actor/src/udsactor/linux/daemon.py +++ b/actor/src/udsactor/linux/daemon.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014-2018 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,19 +26,16 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ''' -@author: : http://www.jejik.com/authors/sander_marechal/ -@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ +@author: Adolfo Gómez, dkmaster at dkmon dot com ''' - -from __future__ import unicode_literals import sys import os import time import atexit -from udsactor.log import logger - from signal import SIGTERM +from udsactor.log import logger + class Daemon: """ @@ -47,13 +44,13 @@ class Daemon: Usage: subclass the Daemon class and override the run() method """ - def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): + def __init__(self, pidfile: str, stdin: str = '/dev/null', stdout: str = '/dev/null', stderr: str = '/dev/null'): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile - def daemonize(self): + def daemonize(self) -> None: """ do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) @@ -96,33 +93,26 @@ class Daemon: os.dup2(se.fileno(), sys.stderr.fileno()) # write pidfile - atexit.register(self.delpid) - pid = str(os.getpid()) + atexit.register(self.removePidFile) + pidStr = str(os.getpid()) with open(self.pidfile, 'w+') as f: - f.write("{}\n".format(pid)) + f.write("{}\n".format(pidStr)) - def delpid(self): + def removePidFile(self) -> None: try: os.remove(self.pidfile) except Exception: - # Not found/not permissions or whatever... + # Not found/not permissions or whatever, ignore it pass - def start(self): + def start(self) -> None: """ Start the daemon """ logger.debug('Starting daemon') # Check for a pidfile to see if the daemon already runs - try: - pf = open(self.pidfile, 'r') - pid = int(pf.read().strip()) - pf.close() - except IOError: - pid = None - - if pid: - message = "pidfile {} already exist. Daemon already running?\n".format(pid) + if os.path.exists(self.pidfile): + message = "pidfile {} already exist. Daemon already running?\n".format(self.pidfile) logger.error(message) sys.stderr.write(message) sys.exit(1) @@ -134,10 +124,9 @@ class Daemon: except Exception as e: logger.error('Exception running process: {}'.format(e)) - if os.path.exists(self.pidfile): - os.remove(self.pidfile) + self.removePidFile() - def stop(self): + def stop(self) -> None: """ Stop the daemon """ @@ -147,9 +136,6 @@ class Daemon: pid = int(pf.read().strip()) pf.close() except IOError: - pid = None - - if pid is None: message = "pidfile {} does not exist. Daemon not running?\n".format(self.pidfile) logger.info(message) # sys.stderr.write(message) @@ -165,10 +151,10 @@ class Daemon: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: - sys.stderr.write(err) + sys.stderr.write('Error: {}'.format(err)) sys.exit(1) - def restart(self): + def restart(self) -> None: """ Restart the daemon """ @@ -176,8 +162,7 @@ class Daemon: self.start() # Overridables - def run(self): + def run(self) -> None: """ - You should override this method when you subclass Daemon. It will be called after the process has been - daemonized by start() or restart(). + override this to provide your own daemon """ diff --git a/actor/src/udsactor/linux/log.py b/actor/src/udsactor/linux/log.py index 7d6e2f7ad..8b818eb06 100644 --- a/actor/src/udsactor/linux/log.py +++ b/actor/src/udsactor/linux/log.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,20 +29,22 @@ @author: Adolfo Gómez, dkmaster at dkmon dot com ''' # pylint: disable=invalid-name -import logging import os import tempfile -import six +import logging +import typing # Valid logging levels, from UDS Broker (uds.core.utils.log) -OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable +OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in range(6)) # @UndefinedVariable class LocalLogger: # pylint: disable=too-few-public-methods linux = False windows = True - def __init__(self): + logger: typing.Optional[logging.Logger] + + def __init__(self) -> None: # tempdir is different for "user application" and "service" # service wil get c:\windows\temp, while user will get c:\users\XXX\temp # Try to open logger at /var/log path @@ -71,4 +73,5 @@ class LocalLogger: # pylint: disable=too-few-public-methods # our loglevels are 10000 (other), 20000 (debug), .... # logging levels are 10 (debug), 20 (info) # OTHER = logging.NOTSET - self.logger.log(int(level / 1000) - 10, message) + if self.logger: + self.logger.log(int(level / 1000) - 10, message) diff --git a/actor/src/udsactor/linux/operations.py b/actor/src/udsactor/linux/operations.py index e91c02c92..7c93f5e8b 100644 --- a/actor/src/udsactor/linux/operations.py +++ b/actor/src/udsactor/linux/operations.py @@ -29,8 +29,9 @@ @author: Adolfo Gómez, dkmaster at dkmon dot com ''' # pylint: disable=invalid-name -import socket +import configparser import platform +import socket import fcntl import os import ctypes @@ -109,30 +110,30 @@ def _getIpAndMac(ifname: str) -> typing.Tuple[typing.Optional[str], typing.Optio def checkPermissions() -> bool: return os.getuid() == 0 - def getComputerName() -> str: ''' Returns computer name, with no domain ''' return socket.gethostname().split('.')[0] - def getNetworkInfo() -> typing.Iterable[types.InterfaceInfoType]: for ifname in _getInterfaces(): ip, mac = _getIpAndMac(ifname) if mac != '00:00:00:00:00:00' and mac and ip and ip.startswith('169.254') is False: # Skips local interfaces & interfaces with no dhcp IPs yield types.InterfaceInfoType(name=ifname, mac=mac, ip=ip) - def getDomainName() -> str: return '' -def getLinuxVersion() -> str: - import distro - - lv = distro.linux_distribution() - return lv[0] + ', ' + lv[1] - +def getLinuxOs() -> str: + try: + with open('/etc/os-release', 'r') as f: + data = f.read() + cfg = configparser.ConfigParser() + cfg.read_string('[os]\n' + data) + return cfg['os'].get('id', 'unknown') + except Exception: + return 'unknown' def reboot(flags: int = 0): ''' @@ -216,7 +217,7 @@ def getIdleDuration() -> float: xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssInfo) # Centos seems to set state to 1?? (weird, but it's happening don't know why... will try this way) - if xssInfo.contents.state != 0 and 'centos' not in getLinuxVersion().lower().strip(): + if xssInfo.contents.state != 0 and 'centos' not in getLinuxOs().lower().strip(): return 3600 * 100 * 1000 # If screen saver is active, return a high enough value return xssInfo.contents.idle / 1000.0 diff --git a/actor/src/udsactor/linux/renamer/__init__.py b/actor/src/udsactor/linux/renamer/__init__.py index 54cd3c06f..27932c9c1 100644 --- a/actor/src/udsactor/linux/renamer/__init__.py +++ b/actor/src/udsactor/linux/renamer/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,33 +29,4 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals - -import platform -import os -import sys -import pkgutil - -from udsactor.log import logger - -renamers = {} - - -# Renamers now are for IPv4 only addresses -def rename(newName): - distribution = platform.linux_distribution()[0].lower().strip() - if distribution in renamers: - return renamers[distribution](newName) - - # Try Debian renamer, simplest one - logger.info('Renamer for platform "{0}" not found, tryin debian renamer'.format(distribution)) - return renamers['debian'](newName) - - -# Do load of packages -def _init(): - pkgpath = os.path.dirname(sys.modules[__name__].__file__) - for _, name, _ in pkgutil.iter_modules([pkgpath]): - __import__(__name__ + '.' + name, globals(), locals()) - -_init() \ No newline at end of file +from .common import rename diff --git a/actor/src/udsactor/linux/renamer/debian.py b/actor/src/udsactor/linux/renamer/debian.py index c1761656c..70711a03f 100644 --- a/actor/src/udsactor/linux/renamer/debian.py +++ b/actor/src/udsactor/linux/renamer/debian.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,15 +29,13 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals - -from udsactor.linux.renamer import renamers -from udsactor.log import logger - import os +from .common import renamers +from ...log import logger -def rename(newName): + +def rename(newName: str) -> bool: ''' Debian renamer Expects new host name on newName diff --git a/actor/src/udsactor/linux/renamer/opensuse.py b/actor/src/udsactor/linux/renamer/opensuse.py index d7826e009..9537afaee 100644 --- a/actor/src/udsactor/linux/renamer/opensuse.py +++ b/actor/src/udsactor/linux/renamer/opensuse.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -28,15 +28,13 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals - -from udsactor.linux.renamer import renamers -from udsactor.log import logger - import os +from .common import renamers +from ...log import logger -def rename(newName): + +def rename(newName: str) -> bool: ''' RH, Centos, Fedora Renamer Expects new host name on newName diff --git a/actor/src/udsactor/linux/renamer/redhat.py b/actor/src/udsactor/linux/renamer/redhat.py index 76a0dc9a2..1a8543f41 100644 --- a/actor/src/udsactor/linux/renamer/redhat.py +++ b/actor/src/udsactor/linux/renamer/redhat.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -28,15 +28,13 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals - -from udsactor.linux.renamer import renamers -from udsactor.log import logger - import os +from .common import renamers +from ...log import logger -def rename(newName): + +def rename(newName: str) -> bool: ''' RH, Centos, Fedora Renamer Expects new host name on newName diff --git a/actor/src/udsactor/linux/store.py b/actor/src/udsactor/linux/store.py index df9452d9b..515e751bd 100644 --- a/actor/src/udsactor/linux/store.py +++ b/actor/src/udsactor/linux/store.py @@ -98,5 +98,5 @@ def writeConfig(config: types.ActorConfigurationType) -> None: os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root -def useOldJoinSystem(): +def useOldJoinSystem() -> bool: return False diff --git a/actor/src/udsactor/log.py b/actor/src/udsactor/log.py index 55e6c9fba..716cdc01f 100644 --- a/actor/src/udsactor/log.py +++ b/actor/src/udsactor/log.py @@ -36,15 +36,15 @@ import sys import six if sys.platform == 'win32': - from udsactor.windows.log import LocalLogger # @UnusedImport + from .windows.log import LocalLogger # @UnusedImport else: - from udsactor.linux.log import LocalLogger # @Reimport + from .linux.log import LocalLogger # @Reimport # Valid logging levels, from UDS Broker (uds.core.utils.log) OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable -class Logger(object): +class Logger: def __init__(self): self.logLevel = INFO diff --git a/actor/src/udsactor/rest.py b/actor/src/udsactor/rest.py index ba0f26406..f4a0cdc9d 100644 --- a/actor/src/udsactor/rest.py +++ b/actor/src/udsactor/rest.py @@ -193,7 +193,7 @@ class REST: os = r['os'] return types.InitializationResultType( own_token=r['own_token'], - unique_id=r['unique_id'].lower(), + unique_id=r['unique_id'].lower() if r['unique_id'] else None, max_idle=r['max_idle'], os=types.ActorOsConfigurationType( action=os['action'], @@ -203,11 +203,11 @@ class REST: new_password=os.get('new_password'), ad=os.get('ad'), ou=os.get('ou') - ) + ) if r['os'] else None ) except requests.ConnectionError as e: raise RESTConnectionError(str(e)) - except Exception: + except Exception as e: pass raise RESTError(result.content) diff --git a/actor/src/udsactor/service.py b/actor/src/udsactor/service.py index 25ddc1243..5fef33dc8 100644 --- a/actor/src/udsactor/service.py +++ b/actor/src/udsactor/service.py @@ -208,7 +208,7 @@ class CommonService: def rename( # pylint: disable=unused-argument self, name: str, - user: typing.Optional[str] = None, + userName: typing.Optional[str] = None, oldPassword: typing.Optional[str] = None, newPassword: typing.Optional[str] = None ) -> None: @@ -216,7 +216,7 @@ class CommonService: Invoked when broker requests a rename action default does nothing ''' - logger.info('Base renamed invoked: {}'.format(name)) + logger.info('Base renamed invoked: {}, {}'.format(name, userName)) def joinDomain( # pylint: disable=unused-argument, too-many-arguments self, @@ -230,14 +230,11 @@ class CommonService: Invoked when broker requests a "domain" action default does nothing ''' - logger.info('Base join invode: {} on {}, {}'.format(name, domain, ou)) + logger.info('Base join invoked: {} on {}, {}'.format(name, domain, ou)) # **************************************** # Methods that CAN BE overriden by actors # **************************************** - def notifyLocal(self) -> None: - self.setReady() - def doWait(self, miliseconds: int) -> None: ''' Invoked to wait a bit @@ -254,8 +251,11 @@ class CommonService: def preConnect(self, user: str, protocol: str) -> str: # pylint: disable=unused-argument ''' Invoked when received a PRE Connection request via REST + Base preconnect executes the preconnect command ''' - logger.debug('Pre-connect does nothing') + if self._cfg.pre_command: + self.execute(self._cfg.pre_command, 'preConnect') + return 'ok' def onLogout(self, user: str) -> None: diff --git a/actor/src/udsactor/windows/__init__.py b/actor/src/udsactor/windows/__init__.py index 3a98c7807..4db3bd57b 100644 --- a/actor/src/udsactor/windows/__init__.py +++ b/actor/src/udsactor/windows/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2014 Virtual Cable S.L. +# Copyright (c) 2014-2019 Virtual Cable S.L. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -29,4 +29,3 @@ ''' @author: Adolfo Gómez, dkmaster at dkmon dot com ''' -from __future__ import unicode_literals diff --git a/server/src/uds/REST/methods/actor_v2.py b/server/src/uds/REST/methods/actor_v2.py index 46809bb4d..1e80728ce 100644 --- a/server/src/uds/REST/methods/actor_v2.py +++ b/server/src/uds/REST/methods/actor_v2.py @@ -165,7 +165,7 @@ class ActorV2Initiialize(ActorV2Action): * own_token: Optional[str] -> Personal uuid for the service (That, on service, will be used from now onwards). If None, there is no own_token * unique_id: Optional[str] -> If not None, unique id for the service * max_idle: Optional[int] -> If not None, max configured Idle for the vm - * os: Optional[dict] -> Data returned by os manager for setting up this service. + * os: Optional[dict] -> Data returned by os manager for setting up this service. On error, will return Empty (None) result, and error field Example: { @@ -263,6 +263,9 @@ class ActorV2IpChange(ActorV2Action): name = 'ipchange' def post(self): + """ + Records the ip change, and also fix notifyComms url + """ logger.debug('Args: %s, Params: %s', self._args, self._params) return actorResult('ok') diff --git a/server/src/uds/models/user_service.py b/server/src/uds/models/user_service.py index c07e63d15..a0197f88c 100644 --- a/server/src/uds/models/user_service.py +++ b/server/src/uds/models/user_service.py @@ -489,8 +489,10 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods return self.deployed_service.testServer(host, port, timeout) def __str__(self): - return "User service {0}, cache_level {1}, user {2}, name {3}, state {4}:{5}".format(self.name, self.cache_level, self.user, self.friendly_name, - State.toString(self.state), State.toString(self.os_state)) + return "User service {}, unique_id {}, cache_level {}, user {}, name {}, state {}:{}".format( + self.name, self.unique_id, self.cache_level, self.user, self.friendly_name, + State.toString(self.state), State.toString(self.os_state) + ) @staticmethod def beforeDelete(sender, **kwargs):