forked from shaba/openuds
udsactor/linux/renamer/common.py
This commit is contained in:
parent
2c8963ba5f
commit
4cdbe5abae
3
actor/deps.txt
Normal file
3
actor/deps.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Linux:
|
||||||
|
python3-prctl (recommended, but not required in fact)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import signal
|
||||||
import stat
|
import typing
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from udsactor import operations
|
from . import operations
|
||||||
|
from . import renamer
|
||||||
|
from . import daemon
|
||||||
|
|
||||||
from udsactor.service import CommonService
|
from ..log import logger
|
||||||
from udsactor.service import initCfg
|
from ..service import CommonService
|
||||||
from udsactor.service import IPC_PORT
|
|
||||||
|
|
||||||
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:
|
try:
|
||||||
from prctl import set_proctitle # @UnresolvedImport
|
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(_):
|
def set_proctitle(_):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UDSActorSvc(Daemon, CommonService):
|
class UDSActorSvc(daemon.Daemon, CommonService):
|
||||||
rebootMachineAfterOp = False
|
def __init__(self, args=None) -> None:
|
||||||
|
daemon.Daemon.__init__(self, '/var/run/udsactor.pid')
|
||||||
def __init__(self, args=None):
|
|
||||||
Daemon.__init__(self, '/var/run/udsa.pid')
|
|
||||||
CommonService.__init__(self)
|
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
|
Renames the computer, and optionally sets a password for an user
|
||||||
before this
|
before this
|
||||||
@ -75,103 +76,40 @@ class UDSActorSvc(Daemon, CommonService):
|
|||||||
|
|
||||||
if hostName.lower() == name.lower():
|
if hostName.lower() == name.lower():
|
||||||
logger.info('Computer name is already {}'.format(hostName))
|
logger.info('Computer name is already {}'.format(hostName))
|
||||||
self.setReady()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check for password change request for an user
|
# Check for password change request for an user
|
||||||
if user is not None:
|
if userName and oldPassword and newPassword:
|
||||||
logger.info('Setting password for user {}'.format(user))
|
logger.info('Setting password for user {}'.format(userName))
|
||||||
try:
|
try:
|
||||||
operations.changeUserPassword(user, oldPassword, newPassword)
|
operations.changeUserPassword(userName, oldPassword, newPassword)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# We stop here without even renaming computer, because the
|
# We stop here without even renaming computer, because the
|
||||||
# process has failed
|
# process has failed
|
||||||
raise Exception(
|
raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, e))
|
||||||
'Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(user, unicode(e)))
|
|
||||||
|
|
||||||
renamer.rename(name)
|
renamer.rename(name)
|
||||||
|
|
||||||
if self.rebootMachineAfterOp is False:
|
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||||
self.setReady()
|
self,
|
||||||
else:
|
name: str,
|
||||||
logger.info('Rebooting computer to activate new name {}'.format(name))
|
domain: str,
|
||||||
self.reboot()
|
ou: str,
|
||||||
|
account: str,
|
||||||
def joinDomain(self, name, domain, ou, account, password):
|
password: str
|
||||||
|
) -> None:
|
||||||
logger.fatal('Join domain is not supported on linux platforms right now')
|
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):
|
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')
|
logger.debug('Running Daemon')
|
||||||
set_proctitle('UDSActorDaemon')
|
set_proctitle('UDSActorDaemon')
|
||||||
|
|
||||||
# Linux daemon will continue running unless something is requested to
|
# Linux daemon will continue running unless something is requested to
|
||||||
while True:
|
if not self.initialize():
|
||||||
brokerConnected = self.interactWithBroker()
|
return # Stop daemon if initializes told to do so
|
||||||
if brokerConnected is False:
|
|
||||||
logger.debug('Interact with broker returned false, stopping service after a while')
|
|
||||||
return
|
|
||||||
elif brokerConnected is True:
|
|
||||||
break
|
|
||||||
|
|
||||||
# If brokerConnected returns None, repeat the cycle
|
# Initialization is done, set machine to ready for UDS, communicate urls, etc...
|
||||||
self.doWait(16000) # Wait for a looong while
|
self.setReady()
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
# *********************
|
# *********************
|
||||||
# * Main Service loop *
|
# * Main Service loop *
|
||||||
@ -186,9 +124,6 @@ class UDSActorSvc(Daemon, CommonService):
|
|||||||
# In milliseconds, will break
|
# In milliseconds, will break
|
||||||
self.doWait(1000)
|
self.doWait(1000)
|
||||||
|
|
||||||
self.endIPC()
|
|
||||||
self.endAPI()
|
|
||||||
|
|
||||||
self.notifyStop()
|
self.notifyStop()
|
||||||
|
|
||||||
|
|
||||||
@ -202,31 +137,31 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
|
||||||
logger.debug('Running client udsactor')
|
logger.debug('Running client udsactor')
|
||||||
client = None
|
# client = None
|
||||||
try:
|
# try:
|
||||||
client = ipc.ClientIPC(IPC_PORT)
|
# client = ipc.ClientIPC(IPC_PORT)
|
||||||
if 'login' == sys.argv[1]:
|
# if 'login' == sys.argv[1]:
|
||||||
client.sendLogin(sys.argv[2])
|
# client.sendLogin(sys.argv[2])
|
||||||
sys.exit(0)
|
# sys.exit(0)
|
||||||
elif 'logout' == sys.argv[1]:
|
# elif 'logout' == sys.argv[1]:
|
||||||
client.sendLogout(sys.argv[2])
|
# client.sendLogout(sys.argv[2])
|
||||||
sys.exit(0)
|
# sys.exit(0)
|
||||||
else:
|
# else:
|
||||||
usage()
|
# usage()
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.error(e)
|
# logger.error(e)
|
||||||
elif len(sys.argv) != 2:
|
elif len(sys.argv) != 2:
|
||||||
usage()
|
usage()
|
||||||
|
|
||||||
logger.debug('Executing actor')
|
logger.debug('Executing actor')
|
||||||
daemon = UDSActorSvc()
|
daemonSvr = UDSActorSvc()
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
if 'start' == sys.argv[1]:
|
if sys.argv[1] == 'start':
|
||||||
daemon.start()
|
daemonSvr.start()
|
||||||
elif 'stop' == sys.argv[1]:
|
elif sys.argv[1] == 'stop':
|
||||||
daemon.stop()
|
daemonSvr.stop()
|
||||||
elif 'restart' == sys.argv[1]:
|
elif sys.argv[1] == 'restart':
|
||||||
daemon.restart()
|
daemonSvr.restart()
|
||||||
else:
|
else:
|
||||||
usage()
|
usage()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014-2018 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
# 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.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
'''
|
'''
|
||||||
@author: : http://www.jejik.com/authors/sander_marechal/
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import atexit
|
import atexit
|
||||||
from udsactor.log import logger
|
|
||||||
|
|
||||||
from signal import SIGTERM
|
from signal import SIGTERM
|
||||||
|
|
||||||
|
from udsactor.log import logger
|
||||||
|
|
||||||
|
|
||||||
class Daemon:
|
class Daemon:
|
||||||
"""
|
"""
|
||||||
@ -47,13 +44,13 @@ class Daemon:
|
|||||||
Usage: subclass the Daemon class and override the run() method
|
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.stdin = stdin
|
||||||
self.stdout = stdout
|
self.stdout = stdout
|
||||||
self.stderr = stderr
|
self.stderr = stderr
|
||||||
self.pidfile = pidfile
|
self.pidfile = pidfile
|
||||||
|
|
||||||
def daemonize(self):
|
def daemonize(self) -> None:
|
||||||
"""
|
"""
|
||||||
do the UNIX double-fork magic, see Stevens' "Advanced
|
do the UNIX double-fork magic, see Stevens' "Advanced
|
||||||
Programming in the UNIX Environment" for details (ISBN 0201563177)
|
Programming in the UNIX Environment" for details (ISBN 0201563177)
|
||||||
@ -96,33 +93,26 @@ class Daemon:
|
|||||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
# write pidfile
|
# write pidfile
|
||||||
atexit.register(self.delpid)
|
atexit.register(self.removePidFile)
|
||||||
pid = str(os.getpid())
|
pidStr = str(os.getpid())
|
||||||
with open(self.pidfile, 'w+') as f:
|
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:
|
try:
|
||||||
os.remove(self.pidfile)
|
os.remove(self.pidfile)
|
||||||
except Exception:
|
except Exception:
|
||||||
# Not found/not permissions or whatever...
|
# Not found/not permissions or whatever, ignore it
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def start(self):
|
def start(self) -> None:
|
||||||
"""
|
"""
|
||||||
Start the daemon
|
Start the daemon
|
||||||
"""
|
"""
|
||||||
logger.debug('Starting daemon')
|
logger.debug('Starting daemon')
|
||||||
# Check for a pidfile to see if the daemon already runs
|
# Check for a pidfile to see if the daemon already runs
|
||||||
try:
|
if os.path.exists(self.pidfile):
|
||||||
pf = open(self.pidfile, 'r')
|
message = "pidfile {} already exist. Daemon already running?\n".format(self.pidfile)
|
||||||
pid = int(pf.read().strip())
|
|
||||||
pf.close()
|
|
||||||
except IOError:
|
|
||||||
pid = None
|
|
||||||
|
|
||||||
if pid:
|
|
||||||
message = "pidfile {} already exist. Daemon already running?\n".format(pid)
|
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
sys.stderr.write(message)
|
sys.stderr.write(message)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -134,10 +124,9 @@ class Daemon:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error('Exception running process: {}'.format(e))
|
logger.error('Exception running process: {}'.format(e))
|
||||||
|
|
||||||
if os.path.exists(self.pidfile):
|
self.removePidFile()
|
||||||
os.remove(self.pidfile)
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self) -> None:
|
||||||
"""
|
"""
|
||||||
Stop the daemon
|
Stop the daemon
|
||||||
"""
|
"""
|
||||||
@ -147,9 +136,6 @@ class Daemon:
|
|||||||
pid = int(pf.read().strip())
|
pid = int(pf.read().strip())
|
||||||
pf.close()
|
pf.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
pid = None
|
|
||||||
|
|
||||||
if pid is None:
|
|
||||||
message = "pidfile {} does not exist. Daemon not running?\n".format(self.pidfile)
|
message = "pidfile {} does not exist. Daemon not running?\n".format(self.pidfile)
|
||||||
logger.info(message)
|
logger.info(message)
|
||||||
# sys.stderr.write(message)
|
# sys.stderr.write(message)
|
||||||
@ -165,10 +151,10 @@ class Daemon:
|
|||||||
if os.path.exists(self.pidfile):
|
if os.path.exists(self.pidfile):
|
||||||
os.remove(self.pidfile)
|
os.remove(self.pidfile)
|
||||||
else:
|
else:
|
||||||
sys.stderr.write(err)
|
sys.stderr.write('Error: {}'.format(err))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def restart(self):
|
def restart(self) -> None:
|
||||||
"""
|
"""
|
||||||
Restart the daemon
|
Restart the daemon
|
||||||
"""
|
"""
|
||||||
@ -176,8 +162,7 @@ class Daemon:
|
|||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
# Overridables
|
# 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
|
override this to provide your own daemon
|
||||||
daemonized by start() or restart().
|
|
||||||
"""
|
"""
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import six
|
import logging
|
||||||
|
import typing
|
||||||
|
|
||||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
# 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
|
class LocalLogger: # pylint: disable=too-few-public-methods
|
||||||
linux = False
|
linux = False
|
||||||
windows = True
|
windows = True
|
||||||
|
|
||||||
def __init__(self):
|
logger: typing.Optional[logging.Logger]
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
# tempdir is different for "user application" and "service"
|
# tempdir is different for "user application" and "service"
|
||||||
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
|
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
|
||||||
# Try to open logger at /var/log path
|
# 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), ....
|
# our loglevels are 10000 (other), 20000 (debug), ....
|
||||||
# logging levels are 10 (debug), 20 (info)
|
# logging levels are 10 (debug), 20 (info)
|
||||||
# OTHER = logging.NOTSET
|
# OTHER = logging.NOTSET
|
||||||
self.logger.log(int(level / 1000) - 10, message)
|
if self.logger:
|
||||||
|
self.logger.log(int(level / 1000) - 10, message)
|
||||||
|
@ -29,8 +29,9 @@
|
|||||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
import socket
|
import configparser
|
||||||
import platform
|
import platform
|
||||||
|
import socket
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import ctypes
|
import ctypes
|
||||||
@ -109,30 +110,30 @@ def _getIpAndMac(ifname: str) -> typing.Tuple[typing.Optional[str], typing.Optio
|
|||||||
def checkPermissions() -> bool:
|
def checkPermissions() -> bool:
|
||||||
return os.getuid() == 0
|
return os.getuid() == 0
|
||||||
|
|
||||||
|
|
||||||
def getComputerName() -> str:
|
def getComputerName() -> str:
|
||||||
'''
|
'''
|
||||||
Returns computer name, with no domain
|
Returns computer name, with no domain
|
||||||
'''
|
'''
|
||||||
return socket.gethostname().split('.')[0]
|
return socket.gethostname().split('.')[0]
|
||||||
|
|
||||||
|
|
||||||
def getNetworkInfo() -> typing.Iterable[types.InterfaceInfoType]:
|
def getNetworkInfo() -> typing.Iterable[types.InterfaceInfoType]:
|
||||||
for ifname in _getInterfaces():
|
for ifname in _getInterfaces():
|
||||||
ip, mac = _getIpAndMac(ifname)
|
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
|
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)
|
yield types.InterfaceInfoType(name=ifname, mac=mac, ip=ip)
|
||||||
|
|
||||||
|
|
||||||
def getDomainName() -> str:
|
def getDomainName() -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def getLinuxVersion() -> str:
|
def getLinuxOs() -> str:
|
||||||
import distro
|
try:
|
||||||
|
with open('/etc/os-release', 'r') as f:
|
||||||
lv = distro.linux_distribution()
|
data = f.read()
|
||||||
return lv[0] + ', ' + lv[1]
|
cfg = configparser.ConfigParser()
|
||||||
|
cfg.read_string('[os]\n' + data)
|
||||||
|
return cfg['os'].get('id', 'unknown')
|
||||||
|
except Exception:
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
def reboot(flags: int = 0):
|
def reboot(flags: int = 0):
|
||||||
'''
|
'''
|
||||||
@ -216,7 +217,7 @@ def getIdleDuration() -> float:
|
|||||||
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssInfo)
|
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)
|
# 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 3600 * 100 * 1000 # If screen saver is active, return a high enough value
|
||||||
|
|
||||||
return xssInfo.contents.idle / 1000.0
|
return xssInfo.contents.idle / 1000.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
from __future__ import unicode_literals
|
from .common import rename
|
||||||
|
|
||||||
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()
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@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
|
import os
|
||||||
|
|
||||||
|
from .common import renamers
|
||||||
|
from ...log import logger
|
||||||
|
|
||||||
def rename(newName):
|
|
||||||
|
def rename(newName: str) -> bool:
|
||||||
'''
|
'''
|
||||||
Debian renamer
|
Debian renamer
|
||||||
Expects new host name on newName
|
Expects new host name on newName
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@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
|
import os
|
||||||
|
|
||||||
|
from .common import renamers
|
||||||
|
from ...log import logger
|
||||||
|
|
||||||
def rename(newName):
|
|
||||||
|
def rename(newName: str) -> bool:
|
||||||
'''
|
'''
|
||||||
RH, Centos, Fedora Renamer
|
RH, Centos, Fedora Renamer
|
||||||
Expects new host name on newName
|
Expects new host name on newName
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@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
|
import os
|
||||||
|
|
||||||
|
from .common import renamers
|
||||||
|
from ...log import logger
|
||||||
|
|
||||||
def rename(newName):
|
|
||||||
|
def rename(newName: str) -> bool:
|
||||||
'''
|
'''
|
||||||
RH, Centos, Fedora Renamer
|
RH, Centos, Fedora Renamer
|
||||||
Expects new host name on newName
|
Expects new host name on newName
|
||||||
|
@ -98,5 +98,5 @@ def writeConfig(config: types.ActorConfigurationType) -> None:
|
|||||||
os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root
|
os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root
|
||||||
|
|
||||||
|
|
||||||
def useOldJoinSystem():
|
def useOldJoinSystem() -> bool:
|
||||||
return False
|
return False
|
||||||
|
@ -36,15 +36,15 @@ import sys
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
from udsactor.windows.log import LocalLogger # @UnusedImport
|
from .windows.log import LocalLogger # @UnusedImport
|
||||||
else:
|
else:
|
||||||
from udsactor.linux.log import LocalLogger # @Reimport
|
from .linux.log import LocalLogger # @Reimport
|
||||||
|
|
||||||
# Valid logging levels, from UDS Broker (uds.core.utils.log)
|
# 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 six.moves.xrange(6)) # @UndefinedVariable
|
||||||
|
|
||||||
|
|
||||||
class Logger(object):
|
class Logger:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.logLevel = INFO
|
self.logLevel = INFO
|
||||||
|
@ -193,7 +193,7 @@ class REST:
|
|||||||
os = r['os']
|
os = r['os']
|
||||||
return types.InitializationResultType(
|
return types.InitializationResultType(
|
||||||
own_token=r['own_token'],
|
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'],
|
max_idle=r['max_idle'],
|
||||||
os=types.ActorOsConfigurationType(
|
os=types.ActorOsConfigurationType(
|
||||||
action=os['action'],
|
action=os['action'],
|
||||||
@ -203,11 +203,11 @@ class REST:
|
|||||||
new_password=os.get('new_password'),
|
new_password=os.get('new_password'),
|
||||||
ad=os.get('ad'),
|
ad=os.get('ad'),
|
||||||
ou=os.get('ou')
|
ou=os.get('ou')
|
||||||
)
|
) if r['os'] else None
|
||||||
)
|
)
|
||||||
except requests.ConnectionError as e:
|
except requests.ConnectionError as e:
|
||||||
raise RESTConnectionError(str(e))
|
raise RESTConnectionError(str(e))
|
||||||
except Exception:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
raise RESTError(result.content)
|
raise RESTError(result.content)
|
||||||
|
@ -208,7 +208,7 @@ class CommonService:
|
|||||||
def rename( # pylint: disable=unused-argument
|
def rename( # pylint: disable=unused-argument
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
user: typing.Optional[str] = None,
|
userName: typing.Optional[str] = None,
|
||||||
oldPassword: typing.Optional[str] = None,
|
oldPassword: typing.Optional[str] = None,
|
||||||
newPassword: typing.Optional[str] = None
|
newPassword: typing.Optional[str] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -216,7 +216,7 @@ class CommonService:
|
|||||||
Invoked when broker requests a rename action
|
Invoked when broker requests a rename action
|
||||||
default does nothing
|
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
|
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
|
||||||
self,
|
self,
|
||||||
@ -230,14 +230,11 @@ class CommonService:
|
|||||||
Invoked when broker requests a "domain" action
|
Invoked when broker requests a "domain" action
|
||||||
default does nothing
|
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
|
# Methods that CAN BE overriden by actors
|
||||||
# ****************************************
|
# ****************************************
|
||||||
def notifyLocal(self) -> None:
|
|
||||||
self.setReady()
|
|
||||||
|
|
||||||
def doWait(self, miliseconds: int) -> None:
|
def doWait(self, miliseconds: int) -> None:
|
||||||
'''
|
'''
|
||||||
Invoked to wait a bit
|
Invoked to wait a bit
|
||||||
@ -254,8 +251,11 @@ class CommonService:
|
|||||||
def preConnect(self, user: str, protocol: str) -> str: # pylint: disable=unused-argument
|
def preConnect(self, user: str, protocol: str) -> str: # pylint: disable=unused-argument
|
||||||
'''
|
'''
|
||||||
Invoked when received a PRE Connection request via REST
|
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'
|
return 'ok'
|
||||||
|
|
||||||
def onLogout(self, user: str) -> None:
|
def onLogout(self, user: str) -> None:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014 Virtual Cable S.L.
|
# Copyright (c) 2014-2019 Virtual Cable S.L.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
# 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
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
'''
|
'''
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
@ -263,6 +263,9 @@ class ActorV2IpChange(ActorV2Action):
|
|||||||
name = 'ipchange'
|
name = 'ipchange'
|
||||||
|
|
||||||
def post(self):
|
def post(self):
|
||||||
|
"""
|
||||||
|
Records the ip change, and also fix notifyComms url
|
||||||
|
"""
|
||||||
logger.debug('Args: %s, Params: %s', self._args, self._params)
|
logger.debug('Args: %s, Params: %s', self._args, self._params)
|
||||||
return actorResult('ok')
|
return actorResult('ok')
|
||||||
|
|
||||||
|
@ -489,8 +489,10 @@ class UserService(UUIDModel): # pylint: disable=too-many-public-methods
|
|||||||
return self.deployed_service.testServer(host, port, timeout)
|
return self.deployed_service.testServer(host, port, timeout)
|
||||||
|
|
||||||
def __str__(self):
|
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,
|
return "User service {}, unique_id {}, cache_level {}, user {}, name {}, state {}:{}".format(
|
||||||
State.toString(self.state), State.toString(self.os_state))
|
self.name, self.unique_id, self.cache_level, self.user, self.friendly_name,
|
||||||
|
State.toString(self.state), State.toString(self.os_state)
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def beforeDelete(sender, **kwargs):
|
def beforeDelete(sender, **kwargs):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user