Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
15a76f3b9b | ||
|
a3110d4623 |
2
actors/.gitignore
vendored
@@ -6,5 +6,3 @@ udsactor*.changes
|
|||||||
/udsactor_1.7.0.dsc
|
/udsactor_1.7.0.dsc
|
||||||
/udsactor_1.7.0.tar.xz
|
/udsactor_1.7.0.tar.xz
|
||||||
/udsactor*.rpm
|
/udsactor*.rpm
|
||||||
/udsactor_2.1.0_amd64.buildinfo
|
|
||||||
linux/debian/files
|
|
||||||
|
@@ -1,9 +1,3 @@
|
|||||||
udsactor (2.1.0) stable; urgency=medium
|
|
||||||
|
|
||||||
* Fixes for 2.1.0 release
|
|
||||||
|
|
||||||
-- Adolfo Gómez García <agomez@virtualcable.es> Tue, 19 Jan 2017 08:00:22 +0200
|
|
||||||
|
|
||||||
udsactor (2.0.0) stable; urgency=medium
|
udsactor (2.0.0) stable; urgency=medium
|
||||||
|
|
||||||
* Upgrade for 2.0.0
|
* Upgrade for 2.0.0
|
||||||
|
3
actors/linux/debian/files
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
udsactor-nx_2.0.0_all.deb x11 optional
|
||||||
|
udsactor-xrdp_2.0.0_all.deb x11 optional
|
||||||
|
udsactor_2.0.0_all.deb admin optional
|
@@ -5,7 +5,6 @@
|
|||||||
set -e
|
set -e
|
||||||
case "$1" in
|
case "$1" in
|
||||||
configure)
|
configure)
|
||||||
/usr/bin/python2.7 -m compileall /usr/share/UDSActor > /dev/nul 2>&1
|
|
||||||
# If new "fresh" install or if configuration file has disappeared...
|
# If new "fresh" install or if configuration file has disappeared...
|
||||||
if [ "$2" = "" ] || [ ! -f /etc/udsactor/udsactor.cfg ]; then
|
if [ "$2" = "" ] || [ ! -f /etc/udsactor/udsactor.cfg ]; then
|
||||||
db_get udsactor/host
|
db_get udsactor/host
|
||||||
|
@@ -8,5 +8,5 @@ Type=Application
|
|||||||
NoDisplay=true
|
NoDisplay=true
|
||||||
X-KDE-autostart-after=panel
|
X-KDE-autostart-after=panel
|
||||||
X-KDE-StartupNotify=false
|
X-KDE-StartupNotify=false
|
||||||
X-DBUS-StartupType=None
|
X-DBUS-StartupType=Unique
|
||||||
X-KDE-UniqueApplet=false
|
X-KDE-UniqueApplet=true
|
||||||
|
@@ -51,8 +51,6 @@ from udsactor import VERSION
|
|||||||
|
|
||||||
trayIcon = None
|
trayIcon = None
|
||||||
|
|
||||||
doLogoff = False
|
|
||||||
|
|
||||||
|
|
||||||
def sigTerm(sigNo, stackFrame):
|
def sigTerm(sigNo, stackFrame):
|
||||||
if trayIcon:
|
if trayIcon:
|
||||||
@@ -255,7 +253,7 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
|
|||||||
|
|
||||||
if remainingTime <= 0:
|
if remainingTime <= 0:
|
||||||
logger.info('User has been idle for too long, notifying Broker that service can be reclaimed')
|
logger.info('User has been idle for too long, notifying Broker that service can be reclaimed')
|
||||||
self.quit(logoff=True)
|
self.quit()
|
||||||
|
|
||||||
def displayMessage(self, message):
|
def displayMessage(self, message):
|
||||||
logger.debug('Displaying message')
|
logger.debug('Displaying message')
|
||||||
@@ -292,8 +290,7 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
|
|||||||
def about(self):
|
def about(self):
|
||||||
self.aboutDlg.exec_()
|
self.aboutDlg.exec_()
|
||||||
|
|
||||||
def quit(self, logoff=False):
|
def quit(self):
|
||||||
global doLogoff
|
|
||||||
logger.debug('Quit invoked')
|
logger.debug('Quit invoked')
|
||||||
if self.stopped is False:
|
if self.stopped is False:
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
@@ -306,7 +303,10 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
|
|||||||
# May we have lost connection with server, simply exit in that case
|
# May we have lost connection with server, simply exit in that case
|
||||||
pass
|
pass
|
||||||
|
|
||||||
doLogoff = logoff
|
try:
|
||||||
|
operations.loggoff() # Invoke log off
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
self.app.quit()
|
self.app.quit()
|
||||||
|
|
||||||
@@ -339,12 +339,4 @@ if __name__ == '__main__':
|
|||||||
logger.debug('Exiting')
|
logger.debug('Exiting')
|
||||||
trayIcon.quit()
|
trayIcon.quit()
|
||||||
|
|
||||||
if doLogoff:
|
|
||||||
try:
|
|
||||||
time.sleep(1)
|
|
||||||
operations.loggoff() # Invoke log off
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
sys.exit(res)
|
sys.exit(res)
|
||||||
|
@@ -34,7 +34,7 @@ from __future__ import unicode_literals
|
|||||||
# On centos, old six release does not includes byte2int, nor six.PY2
|
# On centos, old six release does not includes byte2int, nor six.PY2
|
||||||
import six
|
import six
|
||||||
|
|
||||||
VERSION = '2.1.0'
|
VERSION = '2.0.0'
|
||||||
|
|
||||||
__title__ = 'udsactor'
|
__title__ = 'udsactor'
|
||||||
__version__ = VERSION
|
__version__ = VERSION
|
||||||
|
@@ -196,22 +196,13 @@ class HTTPServerThread(threading.Thread):
|
|||||||
|
|
||||||
self.initiateServer(address)
|
self.initiateServer(address)
|
||||||
|
|
||||||
def getPort(self):
|
|
||||||
return self.address[1]
|
|
||||||
|
|
||||||
def getIp(self):
|
|
||||||
return self.address[0]
|
|
||||||
|
|
||||||
def initiateServer(self, address):
|
def initiateServer(self, address):
|
||||||
self.address = (address[0], address[1]) # Copy address & keep it for future reference...
|
self.server = socketserver.TCPServer(address, HTTPServerHandler)
|
||||||
|
|
||||||
addr = ('0.0.0.0', address[1]) # Adapt to listen on 0.0.0.0
|
|
||||||
|
|
||||||
self.server = socketserver.TCPServer(addr, HTTPServerHandler)
|
|
||||||
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.certFile, server_side=True)
|
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.certFile, server_side=True)
|
||||||
|
|
||||||
def getServerUrl(self):
|
def getServerUrl(self):
|
||||||
return 'https://{}:{}/{}'.format(self.getIp(), self.getPort(), HTTPServerHandler.uuid)
|
return 'https://{}:{}/{}'.format(self.server.server_address[0], self.server.server_address[1], HTTPServerHandler.uuid)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
logger.debug('Stopping REST Service')
|
logger.debug('Stopping REST Service')
|
||||||
@@ -220,14 +211,11 @@ class HTTPServerThread(threading.Thread):
|
|||||||
def restart(self, address=None):
|
def restart(self, address=None):
|
||||||
|
|
||||||
if address is None:
|
if address is None:
|
||||||
# address = self.server.server_address
|
address = self.server.server_address
|
||||||
address = self.address
|
|
||||||
|
|
||||||
self.address = (address[0], self.address[1]) # Copy address & keep it for future reference, port is never changed once assigned on init
|
self.stop()
|
||||||
|
|
||||||
# Listening on 0.0.0.0, does not need to restart listener..
|
self.initiateServer(address)
|
||||||
# self.stop()
|
|
||||||
# self.initiateServer(address)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.server.serve_forever()
|
self.server.serve_forever()
|
||||||
|
@@ -36,8 +36,6 @@ import sys
|
|||||||
import six
|
import six
|
||||||
import traceback
|
import traceback
|
||||||
import pickle
|
import pickle
|
||||||
import errno
|
|
||||||
import time
|
|
||||||
|
|
||||||
from udsactor.utils import toUnicode
|
from udsactor.utils import toUnicode
|
||||||
from udsactor.log import logger
|
from udsactor.log import logger
|
||||||
@@ -409,11 +407,8 @@ class ClientIPC(threading.Thread):
|
|||||||
self.messageReceived()
|
self.messageReceived()
|
||||||
|
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.errno == errno.EINTR:
|
|
||||||
time.sleep(1) #
|
|
||||||
continue # Ignore interrupted system call
|
|
||||||
logger.error('Communication with server got an error: {}'.format(toUnicode(e.strerror)))
|
logger.error('Communication with server got an error: {}'.format(toUnicode(e.strerror)))
|
||||||
# self.running = False
|
self.running = False
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
tb = traceback.format_exc()
|
tb = traceback.format_exc()
|
||||||
|
@@ -36,7 +36,6 @@ from udsactor import operations
|
|||||||
from udsactor.service import CommonService
|
from udsactor.service import CommonService
|
||||||
from udsactor.service import initCfg
|
from udsactor.service import initCfg
|
||||||
from udsactor.service import IPC_PORT
|
from udsactor.service import IPC_PORT
|
||||||
|
|
||||||
from udsactor import ipc
|
from udsactor import ipc
|
||||||
|
|
||||||
from udsactor.log import logger
|
from udsactor.log import logger
|
||||||
@@ -45,23 +44,15 @@ from udsactor.linux.daemon import Daemon
|
|||||||
from udsactor.linux import renamer
|
from udsactor.linux import renamer
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import time
|
||||||
import stat
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
POST_CMD = '/etc/udsactor/post'
|
|
||||||
PRECONNECT_CMD = '/etc/udsactor/pre'
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from prctl import set_proctitle # @UnresolvedImport
|
from prctl import set_proctitle
|
||||||
except Exception: # Platform may not include prctl, so in case it's not available, we let the "name" as is
|
except Exception: # 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, CommonService):
|
||||||
rebootMachineAfterOp = False
|
|
||||||
|
|
||||||
def __init__(self, args=None):
|
def __init__(self, args=None):
|
||||||
Daemon.__init__(self, '/var/run/udsa.pid')
|
Daemon.__init__(self, '/var/run/udsa.pid')
|
||||||
CommonService.__init__(self)
|
CommonService.__init__(self)
|
||||||
@@ -71,12 +62,6 @@ class UDSActorSvc(Daemon, CommonService):
|
|||||||
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
|
||||||
'''
|
'''
|
||||||
hostName = operations.getComputerName()
|
|
||||||
|
|
||||||
if hostName.lower() == name.lower():
|
|
||||||
logger.info('Computer name is already {}'.format(hostName))
|
|
||||||
self.setReady()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Check for password change request for an user
|
# Check for password change request for an user
|
||||||
if user is not None:
|
if user is not None:
|
||||||
@@ -90,48 +75,13 @@ class UDSActorSvc(Daemon, CommonService):
|
|||||||
'Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(user, unicode(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)
|
||||||
|
self.setReady()
|
||||||
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(self, name, domain, ou, account, password):
|
||||||
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:
|
|
||||||
|
|
||||||
if os.path.isfile(PRECONNECT_CMD):
|
|
||||||
if (os.stat(PRECONNECT_CMD).st_mode & stat.S_IXUSR) != 0:
|
|
||||||
subprocess.call([PRECONNECT_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 as e:
|
|
||||||
# Ignore output of execution command
|
|
||||||
logger.error('Executing preconnect command give')
|
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
cfg = initCfg() # Gets a local copy of config to get "reboot"
|
initCfg()
|
||||||
|
|
||||||
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')
|
||||||
@@ -156,21 +106,6 @@ class UDSActorSvc(Daemon, CommonService):
|
|||||||
logger.debug('Reboot has been requested, stopping service')
|
logger.debug('Reboot has been requested, stopping service')
|
||||||
return
|
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()
|
self.initIPC()
|
||||||
|
|
||||||
# *********************
|
# *********************
|
||||||
|
@@ -122,7 +122,7 @@ def getComputerName():
|
|||||||
def getNetworkInfo():
|
def getNetworkInfo():
|
||||||
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 ip.startswith('169.254') is False: # Skips local interfaces & interfaces with no dhcp IPs
|
if mac != '00:00:00:00:00:00': # Skips local interfaces
|
||||||
yield utils.Bunch(name=ifname, mac=mac, ip=ip)
|
yield utils.Bunch(name=ifname, mac=mac, ip=ip)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -78,11 +78,3 @@ def writeConfig(data):
|
|||||||
cfg.write(f)
|
cfg.write(f)
|
||||||
|
|
||||||
os.chmod(CONFIGFILE, 0o0600)
|
os.chmod(CONFIGFILE, 0o0600)
|
||||||
|
|
||||||
def useOldJoinSystem():
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Right now, we do not really need an application to be run on "startup" as could ocur with windows
|
|
||||||
def runApplication():
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
@@ -70,8 +70,6 @@ def initCfg():
|
|||||||
cfg = None
|
cfg = None
|
||||||
break
|
break
|
||||||
|
|
||||||
return cfg
|
|
||||||
|
|
||||||
|
|
||||||
class CommonService(object):
|
class CommonService(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -86,23 +84,6 @@ class CommonService(object):
|
|||||||
def reboot(self):
|
def reboot(self):
|
||||||
self.rebootRequested = True
|
self.rebootRequested = True
|
||||||
|
|
||||||
def execute(self, cmd, section):
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import stat
|
|
||||||
|
|
||||||
if os.path.isfile(cmd):
|
|
||||||
if (os.stat(cmd).st_mode & stat.S_IXUSR) != 0:
|
|
||||||
subprocess.call([cmd, ])
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.info('{} file exists but it it is not executable (needs execution permission by admin/root)'.format(section))
|
|
||||||
else:
|
|
||||||
logger.info('{} file not found & not executed'.format(section))
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def setReady(self):
|
def setReady(self):
|
||||||
self.api.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()])
|
self.api.setReady([(v.mac, v.ip) for v in operations.getNetworkInfo()])
|
||||||
|
|
||||||
@@ -155,13 +136,6 @@ class CommonService(object):
|
|||||||
# Wait a bit before next check
|
# Wait a bit before next check
|
||||||
self.doWait(5000)
|
self.doWait(5000)
|
||||||
|
|
||||||
# Now try to run the "runonce" element
|
|
||||||
runOnce = store.runApplication()
|
|
||||||
if runOnce is not None:
|
|
||||||
if self.execute(runOnce, 'RunOnce') is True:
|
|
||||||
# operations.reboot()
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Broker connection is initialized, now get information about what to
|
# Broker connection is initialized, now get information about what to
|
||||||
# do
|
# do
|
||||||
counter = 0
|
counter = 0
|
||||||
@@ -236,7 +210,7 @@ class CommonService(object):
|
|||||||
self.knownIps = dict(((v.mac, v.ip) for v in netInfo))
|
self.knownIps = dict(((v.mac, v.ip) for v in netInfo))
|
||||||
|
|
||||||
# And notify new listening address to broker
|
# And notify new listening address to broker
|
||||||
address = (self.knownIps[self.api.mac], self.httpServer.getPort())
|
address = (self.knownIps[self.api.mac], random.randrange(43900, 44000))
|
||||||
# And new listening address
|
# And new listening address
|
||||||
self.httpServer.restart(address)
|
self.httpServer.restart(address)
|
||||||
# sends notification
|
# sends notification
|
||||||
|
@@ -40,11 +40,9 @@ import win32event # @UnresolvedImport, pylint: disable=import-error
|
|||||||
import win32com.client # @UnresolvedImport, @UnusedImport, pylint: disable=import-error
|
import win32com.client # @UnresolvedImport, @UnusedImport, pylint: disable=import-error
|
||||||
import pythoncom # @UnresolvedImport, pylint: disable=import-error
|
import pythoncom # @UnresolvedImport, pylint: disable=import-error
|
||||||
import servicemanager # @UnresolvedImport, pylint: disable=import-error
|
import servicemanager # @UnresolvedImport, pylint: disable=import-error
|
||||||
import subprocess
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from udsactor import operations
|
from udsactor import operations
|
||||||
from udsactor import store
|
|
||||||
from udsactor.service import CommonService
|
from udsactor.service import CommonService
|
||||||
from udsactor.service import initCfg
|
from udsactor.service import initCfg
|
||||||
|
|
||||||
@@ -57,8 +55,6 @@ from .SENS import SENSGUID_PUBLISHER
|
|||||||
from .SENS import PROGID_EventSubscription
|
from .SENS import PROGID_EventSubscription
|
||||||
from .SENS import PROGID_EventSystem
|
from .SENS import PROGID_EventSystem
|
||||||
|
|
||||||
POST_CMD = 'c:\\windows\\post-uds.bat'
|
|
||||||
|
|
||||||
|
|
||||||
class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
||||||
'''
|
'''
|
||||||
@@ -117,7 +113,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
|||||||
|
|
||||||
operations.renameComputer(name)
|
operations.renameComputer(name)
|
||||||
# Reboot just after renaming
|
# Reboot just after renaming
|
||||||
logger.info('Rebooting computer to activate new name {}'.format(name))
|
logger.info('Rebooting computer got activate new name {}'.format(name))
|
||||||
self.reboot()
|
self.reboot()
|
||||||
|
|
||||||
def oneStepJoin(self, name, domain, ou, account, password):
|
def oneStepJoin(self, name, domain, ou, account, password):
|
||||||
@@ -162,15 +158,12 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
|||||||
ver = ver[0] * 10 + ver[1]
|
ver = ver[0] * 10 + ver[1]
|
||||||
logger.debug('Starting joining domain {} with name {} (detected operating version: {})'.format(
|
logger.debug('Starting joining domain {} with name {} (detected operating version: {})'.format(
|
||||||
domain, name, ver))
|
domain, name, ver))
|
||||||
# If file c:\compat.bin exists, joind domain in two steps instead one
|
|
||||||
|
|
||||||
# Accepts one step joinDomain, also remember XP is no more supported by
|
# 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
|
# microsoft, but this also must works with it because will do a "multi
|
||||||
# step" join
|
# step" join
|
||||||
if ver >= 60 and store.useOldJoinSystem() is False:
|
if ver >= 60:
|
||||||
self.oneStepJoin(name, domain, ou, account, password)
|
self.oneStepJoin(name, domain, ou, account, password)
|
||||||
else:
|
else:
|
||||||
logger.info('Using multiple step join because configuration requests to do so')
|
|
||||||
self.multiStepJoin(name, domain, ou, account, password)
|
self.multiStepJoin(name, domain, ou, account, password)
|
||||||
|
|
||||||
def preConnect(self, user, protocol):
|
def preConnect(self, user, protocol):
|
||||||
@@ -299,17 +292,6 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
|
|||||||
|
|
||||||
logger.debug('Registered SENS, running main loop')
|
logger.debug('Registered SENS, running main loop')
|
||||||
|
|
||||||
# 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')
|
|
||||||
|
|
||||||
# *********************
|
# *********************
|
||||||
# * Main Service loop *
|
# * Main Service loop *
|
||||||
# *********************
|
# *********************
|
||||||
|
@@ -82,6 +82,7 @@ def readConfig():
|
|||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def writeConfig(data, fixPermissions=True):
|
def writeConfig(data, fixPermissions=True):
|
||||||
try:
|
try:
|
||||||
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
key = wreg.OpenKey(baseKey, path, 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
||||||
@@ -92,32 +93,3 @@ def writeConfig(data, fixPermissions=True):
|
|||||||
|
|
||||||
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(cPickle.dumps(data))) # @UndefinedVariable
|
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, encoder(cPickle.dumps(data))) # @UndefinedVariable
|
||||||
wreg.CloseKey(key) # @UndefinedVariable
|
wreg.CloseKey(key) # @UndefinedVariable
|
||||||
|
|
||||||
def useOldJoinSystem():
|
|
||||||
try:
|
|
||||||
key = wreg.OpenKey(baseKey, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_QUERY_VALUE) # @UndefinedVariable
|
|
||||||
try:
|
|
||||||
data, _ = wreg.QueryValueEx(key, 'join') # @UndefinedVariable
|
|
||||||
except Exception:
|
|
||||||
data = ''
|
|
||||||
wreg.CloseKey(key) # @UndefinedVariable
|
|
||||||
except:
|
|
||||||
data = ''
|
|
||||||
|
|
||||||
return data == 'old'
|
|
||||||
|
|
||||||
# Gives the oportunity to run an application ONE TIME (because, the registry key "run" will be deleted after read)
|
|
||||||
def runApplication():
|
|
||||||
try:
|
|
||||||
key = wreg.OpenKey(baseKey, 'Software\\UDSEnterpriseActor', 0, wreg.KEY_ALL_ACCESS) # @UndefinedVariable
|
|
||||||
try:
|
|
||||||
data, _ = wreg.QueryValueEx(key, 'run') # @UndefinedVariable
|
|
||||||
wreg.DeleteValue(key, 'run') # @UndefinedVariable
|
|
||||||
except Exception:
|
|
||||||
data = None
|
|
||||||
wreg.CloseKey(key) # @UndefinedVariable
|
|
||||||
except:
|
|
||||||
data = None
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
@@ -1,2 +0,0 @@
|
|||||||
udsclient_2.1.0_all.deb admin optional
|
|
||||||
udsclient_2.1.0_amd64.buildinfo admin optional
|
|
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
VERSION=`cat ../../../VERSION`
|
VERSION=`cat ../../VERSION`
|
||||||
RELEASE=1
|
RELEASE=1
|
||||||
# Debian based
|
# Debian based
|
||||||
dpkg-buildpackage -b
|
dpkg-buildpackage -b
|
@@ -1,9 +1,3 @@
|
|||||||
udsclient (2.1.0) stable; urgency=medium
|
|
||||||
|
|
||||||
* Updated release
|
|
||||||
|
|
||||||
-- Adolfo Gómez García <agomez@virtualcable.es> Sun, 23 Oct 2016 21:12:23 +0200
|
|
||||||
|
|
||||||
udsclient (2.0.0) stable; urgency=medium
|
udsclient (2.0.0) stable; urgency=medium
|
||||||
|
|
||||||
* Release upgrade
|
* Release upgrade
|
1
client/linux/debian/files
Normal file
@@ -0,0 +1 @@
|
|||||||
|
udsclient_2.0.0_all.deb admin optional
|
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
# Copyright (c) 2014 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,
|
||||||
@@ -281,7 +281,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Setup REST api endpoint
|
# Setup REST api endpoint
|
||||||
RestRequest.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
|
RestRequest.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
|
||||||
logger.debug('Setting request URL to {}'.format(RestRequest.restApiUrl))
|
logger.debug('Setting requert URL to {}'.format(RestRequest.restApiUrl))
|
||||||
# RestRequest.restApiUrl = 'https://172.27.0.1/rest/client'
|
# RestRequest.restApiUrl = 'https://172.27.0.1/rest/client'
|
||||||
|
|
||||||
try:
|
try:
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
@@ -34,7 +34,7 @@ from __future__ import unicode_literals
|
|||||||
# On centos, old six release does not includes byte2int, nor six.PY2
|
# On centos, old six release does not includes byte2int, nor six.PY2
|
||||||
import six
|
import six
|
||||||
|
|
||||||
VERSION = '2.1.0'
|
VERSION = '2.0.0'
|
||||||
|
|
||||||
__title__ = 'udclient'
|
__title__ = 'udclient'
|
||||||
__version__ = VERSION
|
__version__ = VERSION
|
@@ -33,17 +33,10 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
if sys.platform.startswith('linux'):
|
|
||||||
from os.path import expanduser
|
|
||||||
logFile = expanduser('~/udsclient.log')
|
|
||||||
else:
|
|
||||||
logFile = os.path.join(tempfile.gettempdir(), b'udsclient.log')
|
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
filename=logFile,
|
filename=os.path.join(tempfile.gettempdir(), b'udsclient.log'),
|
||||||
filemode='a',
|
filemode='a',
|
||||||
format='%(levelname)s %(asctime)s %(message)s',
|
format='%(levelname)s %(asctime)s %(message)s',
|
||||||
level=logging.DEBUG
|
level=logging.DEBUG
|
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
# Copyright (c) 2015 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,
|
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
# Copyright (c) 2015 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,
|
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>UDSClient-Thin</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.python.pydev.PyDevBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.python.pydev.pythonNature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
|
||||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
|
||||||
<path>/${PROJECT_DIR_NAME}/src</path>
|
|
||||||
</pydev_pathproperty>
|
|
||||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
|
||||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
|
||||||
</pydev_project>
|
|
@@ -1,158 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from uds import ui
|
|
||||||
from uds.rest import RestRequest, RetryException
|
|
||||||
from uds.forward import forward
|
|
||||||
from uds import VERSION
|
|
||||||
from uds.log import logger # @UnresolvedImport
|
|
||||||
from uds import tools
|
|
||||||
|
|
||||||
import six
|
|
||||||
import sys
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
|
|
||||||
def approveHost(host):
|
|
||||||
from os.path import expanduser
|
|
||||||
hostsFile = expanduser('~/.udsclient.hosts')
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(hostsFile, 'r') as f:
|
|
||||||
approvedHosts = f.read().splitlines()
|
|
||||||
except Exception:
|
|
||||||
approvedHosts = []
|
|
||||||
|
|
||||||
host = host.lower()
|
|
||||||
|
|
||||||
if host in approvedHosts:
|
|
||||||
return True
|
|
||||||
|
|
||||||
errorString = 'The server {} must be approved:\n'.format(host)
|
|
||||||
errorString += 'Only approve UDS servers that you trust to avoid security issues.'
|
|
||||||
|
|
||||||
approved = ui.question("ACCESS Warning", errorString)
|
|
||||||
|
|
||||||
if approved:
|
|
||||||
approvedHosts.append(host)
|
|
||||||
logger.debug('Host was approved, saving to approvedHosts file')
|
|
||||||
try:
|
|
||||||
with open(hostsFile, 'w') as f:
|
|
||||||
f.write('\n'.join(approvedHosts))
|
|
||||||
except Exception:
|
|
||||||
logger.warn('Got exception writing to {}'.format(hostsFile))
|
|
||||||
|
|
||||||
return approved
|
|
||||||
|
|
||||||
|
|
||||||
def getWithRetry(rest, url, params=None):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
res = rest.get(url, params)
|
|
||||||
return res
|
|
||||||
except RetryException as e:
|
|
||||||
if ui.question('Service not available', 'Error {}.\nPlease, wait a minute and press "OK" to retry, or "CANCEL" to abort'.format(e)) is True:
|
|
||||||
continue
|
|
||||||
raise Exception('Cancelled by user')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
logger.debug('Initializing connector')
|
|
||||||
|
|
||||||
if six.PY3 is False:
|
|
||||||
logger.debug('Fixing threaded execution of commands')
|
|
||||||
import threading
|
|
||||||
threading._DummyThread._Thread__stop = lambda x: 42
|
|
||||||
|
|
||||||
# First parameter must be url
|
|
||||||
try:
|
|
||||||
uri = sys.argv[1]
|
|
||||||
|
|
||||||
if uri == '--test':
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
logger.debug('URI: {}'.format(uri))
|
|
||||||
if uri[:6] != 'uds://' and uri[:7] != 'udss://':
|
|
||||||
raise Exception()
|
|
||||||
|
|
||||||
ssl = uri[3] == 's'
|
|
||||||
host, ticket, scrambler = uri.split('//')[1].split('/')
|
|
||||||
logger.debug('ssl: {}, host:{}, ticket:{}, scrambler:{}'.format(ssl, host, ticket, scrambler))
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
logger.debug('Detected execution without valid URI, exiting')
|
|
||||||
ui.message('UDS Client', 'UDS Client Version {}'.format(VERSION))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
rest = RestRequest(host, ssl)
|
|
||||||
logger.debug('Setting request URL to {}'.format(rest.restApiUrl))
|
|
||||||
|
|
||||||
# Main requests part
|
|
||||||
# First, get version
|
|
||||||
try:
|
|
||||||
res = getWithRetry(rest, '')
|
|
||||||
|
|
||||||
logger.debug('Got information {}'.format(res))
|
|
||||||
|
|
||||||
if res['requiredVersion'] > VERSION:
|
|
||||||
ui.message("New UDS Client available", "A new uds version is needed in order to access this version of UDS.\nPlease, download and install it")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
res = getWithRetry(rest, '/{}/{}'.format(ticket, scrambler), params={'hostname': tools.getHostName(), 'version': VERSION})
|
|
||||||
|
|
||||||
script = res.decode('base64').decode('bz2')
|
|
||||||
|
|
||||||
logger.debug('Script: {}'.format(script))
|
|
||||||
|
|
||||||
six.exec_(script, globals(), {'parent': None})
|
|
||||||
except Exception as e:
|
|
||||||
error = 'ERROR: {}'.format(e)
|
|
||||||
logger.error(error)
|
|
||||||
ui.message('Error', error)
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
# Finalize
|
|
||||||
try:
|
|
||||||
tools.waitForTasks()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
tools.unlinkFiles()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
tools.execBeforeExit()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
@@ -1 +0,0 @@
|
|||||||
../../../full/src/uds/__init__.py
|
|
@@ -1 +0,0 @@
|
|||||||
../../../full/src/uds/forward.py
|
|
@@ -1 +0,0 @@
|
|||||||
../../../full/src/uds/log.py
|
|
@@ -1 +0,0 @@
|
|||||||
../../../full/src/uds/osDetector.py
|
|
@@ -1,86 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2015 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from . import VERSION
|
|
||||||
|
|
||||||
import json
|
|
||||||
import six
|
|
||||||
import osDetector
|
|
||||||
|
|
||||||
|
|
||||||
from .log import logger
|
|
||||||
|
|
||||||
class RetryException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class RestRequest(object):
|
|
||||||
|
|
||||||
restApiUrl = ''
|
|
||||||
|
|
||||||
def __init__(self, host, ssl=True): # parent not used
|
|
||||||
super(RestRequest, self).__init__()
|
|
||||||
|
|
||||||
self.host = host
|
|
||||||
self.ssl = ssl
|
|
||||||
self.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
|
|
||||||
|
|
||||||
def get(self, url, params=None):
|
|
||||||
url = self.restApiUrl + url
|
|
||||||
if params is not None:
|
|
||||||
url += '?' + '&'.join('{}={}'.format(k, six.moves.urllib.parse.quote(six.text_type(v).encode('utf8'))) for k, v in params.iteritems()) # @UndefinedVariable
|
|
||||||
|
|
||||||
logger.debug('Requesting {}'.format(url))
|
|
||||||
|
|
||||||
try:
|
|
||||||
r = requests.get(url, headers={'Content-type': 'application/json', 'User-Agent': osDetector.getOs() + " - UDS Connector " + VERSION })
|
|
||||||
except requests.exceptions.ConnectionError as e:
|
|
||||||
raise Exception('Error connecting to UDS Server at {}'.format(self.restApiUrl[0:-11]))
|
|
||||||
|
|
||||||
if r.ok:
|
|
||||||
logger.debug('Request was OK. {}'.format(r.text))
|
|
||||||
data = json.loads(r.text)
|
|
||||||
if not 'error' in data:
|
|
||||||
return data['result']
|
|
||||||
# Has error
|
|
||||||
if data.get('retryable', '0') == '1':
|
|
||||||
raise RetryException(data['error'])
|
|
||||||
|
|
||||||
raise Exception(data['error'])
|
|
||||||
else:
|
|
||||||
logger.error('Error requesting {}: {}, {}'.format(url, r.code. r.text))
|
|
||||||
raise Exception('Error {}: {}'.format(r.code, r.text))
|
|
||||||
|
|
||||||
return data
|
|
@@ -1 +0,0 @@
|
|||||||
../../../full/src/uds/tools.py
|
|
@@ -1,44 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
try:
|
|
||||||
import gtkui as theUI
|
|
||||||
except Exception:
|
|
||||||
import consoleui as theUI # @Reimport
|
|
||||||
|
|
||||||
def message(title, message):
|
|
||||||
theUI.message(title, message)
|
|
||||||
|
|
||||||
def question(title, message):
|
|
||||||
return theUI.question(title, message)
|
|
||||||
|
|
@@ -1,58 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import random
|
|
||||||
import os
|
|
||||||
import tempfile
|
|
||||||
import string
|
|
||||||
import webbrowser
|
|
||||||
|
|
||||||
TEMPLATE = '''<html>
|
|
||||||
<head>
|
|
||||||
<title>{title}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>{title}</h1>
|
|
||||||
<p>{message}<P>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'''
|
|
||||||
|
|
||||||
def _htmlFilename():
|
|
||||||
return os.path.join(tempfile.gettempdir(), ''.join([random.choice(string.ascii_lowercase) for i in range(22)]) + '.html')
|
|
||||||
|
|
||||||
def message(title, message):
|
|
||||||
filename = _htmlFilename()
|
|
||||||
with open(filename, 'w') as f:
|
|
||||||
f.write(TEMPLATE.format(title=title, message=message))
|
|
||||||
|
|
||||||
webbrowser.open('file://' + filename, new=0, autoraise=False)
|
|
@@ -1,49 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from uds.log import logger
|
|
||||||
|
|
||||||
counter = 0
|
|
||||||
|
|
||||||
def message(title, message):
|
|
||||||
sys.stderr.write("** {} **\n {}\n".format(title, message))
|
|
||||||
|
|
||||||
def question(title, message):
|
|
||||||
global counter
|
|
||||||
if counter > 100: # 5 minutes
|
|
||||||
return False
|
|
||||||
counter += 1
|
|
||||||
sys.stderr.write("** {} **\n{}\nReturning YES in 3 seconds. (counter is {})\n".format(title, message, counter))
|
|
||||||
time.sleep(3) # Wait 3 seconds before returning
|
|
||||||
return True
|
|
@@ -1,143 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017 Virtual Cable S.L.
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
# are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
|
||||||
# and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
|
||||||
# may be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
# 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: Adolfo Gómez, dkmaster at dkmon dot com
|
|
||||||
'''
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import pygtk
|
|
||||||
pygtk.require('2.0')
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
LINE_LEN = 65
|
|
||||||
|
|
||||||
class Dialog():
|
|
||||||
def __init__(self, title, message, timeout=-1, withCancel=True):
|
|
||||||
self.title = title
|
|
||||||
self.message = message
|
|
||||||
self.timeout = timeout
|
|
||||||
self.withCancel = withCancel
|
|
||||||
|
|
||||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
||||||
self.window.set_position(gtk.WIN_POS_CENTER)
|
|
||||||
# self.window.set_size_request(320, 200)
|
|
||||||
self.window.set_title(self.title)
|
|
||||||
self.create_widgets()
|
|
||||||
self.connect_signals()
|
|
||||||
self.window.show_all()
|
|
||||||
|
|
||||||
self.window.connect("destroy", self.destroy)
|
|
||||||
|
|
||||||
# Setup "auto OK" timer
|
|
||||||
if timeout != -1:
|
|
||||||
self.timerId = gobject.timeout_add(self.timeout * 1000, self.callback_timer)
|
|
||||||
else:
|
|
||||||
self.timerId = -1
|
|
||||||
|
|
||||||
self.result = False
|
|
||||||
|
|
||||||
gtk.main()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def adapted_message(self):
|
|
||||||
msg = ''
|
|
||||||
for l in re.sub(r'<p[^>]*>', '', self.message).replace('</p>', '\n').split('\n'):
|
|
||||||
words = []
|
|
||||||
length = 0
|
|
||||||
for word in l.split(' '):
|
|
||||||
if length + len(word) >= LINE_LEN:
|
|
||||||
msg += ' '.join(words) + '\n'
|
|
||||||
words = []
|
|
||||||
length = 0
|
|
||||||
length += len(word) + 1
|
|
||||||
words.append(word)
|
|
||||||
msg += ' '.join(words) + '\n'
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def create_widgets(self):
|
|
||||||
self.vbox = gtk.VBox(spacing=10)
|
|
||||||
self.vbox.set_size_request(490, -1)
|
|
||||||
|
|
||||||
self.messageLabel = gtk.Label()
|
|
||||||
# Fix message markup
|
|
||||||
# self.message = re.sub(r'<p[^>]*>', '<span font_weight="bold">', self.message).replace('</p>', '</span>\n' )
|
|
||||||
|
|
||||||
# Set as simple markup
|
|
||||||
self.messageLabel.set_markup('\n' + self.adapted_message + '\n')
|
|
||||||
self.messageLabel.set_alignment(xalign=0.5, yalign=1)
|
|
||||||
|
|
||||||
self.hbox = gtk.HBox(spacing=10)
|
|
||||||
self.button_ok = gtk.Button("OK")
|
|
||||||
self.hbox.pack_start(self.button_ok)
|
|
||||||
|
|
||||||
if self.withCancel:
|
|
||||||
self.button_cancel = gtk.Button("Cancel")
|
|
||||||
self.hbox.pack_start(self.button_cancel)
|
|
||||||
|
|
||||||
self.vbox.pack_start(self.messageLabel)
|
|
||||||
self.vbox.pack_start(self.hbox)
|
|
||||||
|
|
||||||
self.window.add(self.vbox)
|
|
||||||
|
|
||||||
def connect_signals(self):
|
|
||||||
self.button_ok.connect("clicked", self.callback_ok)
|
|
||||||
if self.withCancel:
|
|
||||||
self.button_cancel.connect("clicked", self.callback_cancel)
|
|
||||||
|
|
||||||
def destroy(self, widget, data=None):
|
|
||||||
self.setResult(False)
|
|
||||||
|
|
||||||
def setResult(self, val):
|
|
||||||
if self.timerId != -1:
|
|
||||||
gobject.source_remove(self.timerId)
|
|
||||||
self.timerId = -1
|
|
||||||
|
|
||||||
self.result = val
|
|
||||||
self.window.hide()
|
|
||||||
gtk.main_quit()
|
|
||||||
|
|
||||||
|
|
||||||
def callback_ok(self, widget, callback_data=None):
|
|
||||||
self.setResult(True)
|
|
||||||
|
|
||||||
def callback_cancel(self, widget, callback_data=None):
|
|
||||||
self.setResult(False)
|
|
||||||
|
|
||||||
def callback_timer(self):
|
|
||||||
self.setResult(True)
|
|
||||||
|
|
||||||
def message(title, message):
|
|
||||||
Dialog(title, message, withCancel=False)
|
|
||||||
|
|
||||||
def question(title, message):
|
|
||||||
dlg = Dialog(title, message, timeout=30, withCancel=True)
|
|
||||||
return dlg.result
|
|
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
cd /lib/UDSClient
|
|
||||||
exec python UDSClient.pyc $@
|
|
@@ -1,11 +0,0 @@
|
|||||||
Steps:
|
|
||||||
1.- If building from repository, full copy (recursive) the "src" folder of "udsclient/thin" inside the "udsclient" folder. If building from the .tar.gz, simply ignor4e this step
|
|
||||||
2.- Copy the folder "udsclient" to /build/packages inside the thinstation build environment
|
|
||||||
3.- enter the chroot of thinstation
|
|
||||||
4.- go to the udsclient folder (/build/packages/udsclient)
|
|
||||||
5.- Execute "build.sh"
|
|
||||||
6.- Edit the file /build/build.conf, and add this line:
|
|
||||||
package udsclient
|
|
||||||
7.- Execute the build process
|
|
||||||
|
|
||||||
Ready!!!
|
|
2
client/thin/thinstation/udsclient/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
lib
|
|
||||||
src
|
|
@@ -1,11 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Name=UDSClient
|
|
||||||
Comment=UDS Helper
|
|
||||||
Keywords=uds;client;vdi;
|
|
||||||
Exec=/bin/udsclient %u
|
|
||||||
Icon=help-browser
|
|
||||||
StartupNotify=true
|
|
||||||
Terminal=false
|
|
||||||
Type=Application
|
|
||||||
Categories=Utility;
|
|
||||||
MimeType=x-scheme-handler/uds;x-scheme-handler/udss;
|
|
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
cd /lib/UDSClient
|
|
||||||
exec python UDSClient.pyc $@
|
|
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
pip install paramiko requests six
|
|
||||||
rm -rf lib
|
|
||||||
mkdir -p lib/python2.7/site-packages
|
|
||||||
for a in requests paramiko pyasn1 cryptography packaging idna asn1crypto six enum ipaddress cffi ; do cp -r /usr/lib/python2.7/site-packages/$a* lib/python2.7/site-packages/; done
|
|
||||||
cp src/udsclient bin
|
|
||||||
chmod 755 bin/udsclient
|
|
||||||
mkdir lib/UDSClient
|
|
||||||
cp src/UDSClient.py lib/UDSClient
|
|
||||||
chmod 755 lib/UDSClient/UDSClient.py
|
|
||||||
cp -r src/uds lib/UDSClient
|
|
||||||
mkdir lib/applications
|
|
||||||
cp UDSClient.desktop lib/applications
|
|
@@ -1,5 +0,0 @@
|
|||||||
base
|
|
||||||
#add your own dependancies to this file, base should always be included.
|
|
||||||
python
|
|
||||||
pygtk
|
|
||||||
freerdp
|
|
@@ -1,15 +0,0 @@
|
|||||||
In here you place the commands to start your application if using the scripts
|
|
||||||
|
|
||||||
/etc/thinstation.packages
|
|
||||||
or /etc/thinstation.console
|
|
||||||
|
|
||||||
see examples for for information
|
|
||||||
|
|
||||||
|
|
||||||
possible types are
|
|
||||||
|
|
||||||
example.global (this is always needed)
|
|
||||||
example.menu
|
|
||||||
example.console
|
|
||||||
example.window
|
|
||||||
example.fullscreen
|
|
@@ -1 +0,0 @@
|
|||||||
CMD_FULLSCREEN="example -FULLSCREEN"
|
|
@@ -1 +0,0 @@
|
|||||||
CMD_GLOBAL="example -startapp"
|
|
@@ -1 +0,0 @@
|
|||||||
Place a 0 length file in here as the same name as the package if your application is a Console App
|
|
@@ -1,34 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
|
|
||||||
. /etc/thinstation.global
|
|
||||||
|
|
||||||
# note you can replace this package with a symlink to /etc/thinstation.packages
|
|
||||||
# for GUI apps, or /etc/thinstation.console for console apps
|
|
||||||
# if you do then you will need to create a seperate initilization script for
|
|
||||||
# any other parameters which need to be started at bootup
|
|
||||||
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
init)
|
|
||||||
if ! pkg_initialized $PACKAGE; then
|
|
||||||
|
|
||||||
# Your startup instructions go here
|
|
||||||
|
|
||||||
pkg_set_init_flag $PACKAGE
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
console)
|
|
||||||
;;
|
|
||||||
window)
|
|
||||||
;;
|
|
||||||
fullscreen)
|
|
||||||
;;
|
|
||||||
help)
|
|
||||||
echo "Usage: $0 init"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
@@ -1 +0,0 @@
|
|||||||
/etc/init.d/your_start_up_script
|
|
13
guacamole-tunnel/.gitignore
vendored
@@ -1,13 +0,0 @@
|
|||||||
# Backup files
|
|
||||||
*~
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
src/main/webapp/META-INF/
|
|
||||||
src/main/webapp/generated/
|
|
||||||
target/
|
|
||||||
|
|
||||||
# IDE-specific configuration
|
|
||||||
nb-configuration.xml
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
|
|
@@ -7,7 +7,7 @@
|
|||||||
<groupId>org.openuds.server</groupId>
|
<groupId>org.openuds.server</groupId>
|
||||||
<artifactId>transport</artifactId>
|
<artifactId>transport</artifactId>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
<version>2.5.0</version>
|
<version>2.0.0</version>
|
||||||
<name>Guacamole Transport</name>
|
<name>Guacamole Transport</name>
|
||||||
<url>https://github.com/dkmstr/openuds</url>
|
<url>https://github.com/dkmstr/openuds</url>
|
||||||
|
|
||||||
@@ -81,14 +81,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.guacamole</groupId>
|
<groupId>org.apache.guacamole</groupId>
|
||||||
<artifactId>guacamole-common</artifactId>
|
<artifactId>guacamole-common</artifactId>
|
||||||
<version>0.9.10-incubating</version>
|
<version>0.9.9-incubating</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Guacamole JavaScript library -->
|
<!-- Guacamole JavaScript library -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.guacamole</groupId>
|
<groupId>org.apache.guacamole</groupId>
|
||||||
<artifactId>guacamole-common-js</artifactId>
|
<artifactId>guacamole-common-js</artifactId>
|
||||||
<version>0.9.12-incubating</version>
|
<version>0.9.9-incubating</version>
|
||||||
<type>zip</type>
|
<type>zip</type>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Copyright (C) 2017 Glyptodon, Inc.
|
Copyright (C) 2013 Glyptodon LLC
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -147,12 +147,30 @@
|
|||||||
|
|
||||||
<!-- guacamole-default-webapp scripts -->
|
<!-- guacamole-default-webapp scripts -->
|
||||||
<script type="text/javascript" src="scripts/session.js"></script>
|
<script type="text/javascript" src="scripts/session.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/history.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/service.js"></script>
|
||||||
<script type="text/javascript" src="scripts/guac-ui.js"></script>
|
<script type="text/javascript" src="scripts/guac-ui.js"></script>
|
||||||
<script type="text/javascript" src="scripts/client-ui.js"></script>
|
<script type="text/javascript" src="scripts/client-ui.js"></script>
|
||||||
|
|
||||||
<!-- Init -->
|
<!-- Init -->
|
||||||
<script type="text/javascript"> /* <![CDATA[ */
|
<script type="text/javascript"> /* <![CDATA[ */
|
||||||
|
|
||||||
|
/*function getQueryParams(qs) {
|
||||||
|
qs = qs.split("+").join(" ");
|
||||||
|
|
||||||
|
var params = {}, tokens,
|
||||||
|
re = /[?&]?([^=]+)=([^&]*)/g;
|
||||||
|
|
||||||
|
while (tokens = re.exec(qs)) {
|
||||||
|
params[decodeURIComponent(tokens[1])]
|
||||||
|
= decodeURIComponent(tokens[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.query = getQueryParams(document.location.search);*/
|
||||||
|
|
||||||
// Adapted to 1.5
|
// Adapted to 1.5
|
||||||
function getQueryParams(qs) {
|
function getQueryParams(qs) {
|
||||||
qs = qs.split("+").join(" ");
|
qs = qs.split("+").join(" ");
|
||||||
@@ -169,11 +187,16 @@
|
|||||||
|
|
||||||
window.query = getQueryParams(document.location.href);
|
window.query = getQueryParams(document.location.href);
|
||||||
|
|
||||||
|
// Sanity check Guacamole JavaScript API version
|
||||||
|
// if (Guacamole.API_VERSION !== "0.9.1")
|
||||||
|
// GuacUI.Client.showStatus("Clear Your Cache", "An older version of Guacamole has been cached by your browser. Please clear your browser's cache and try again.");
|
||||||
|
|
||||||
// Start connect after control returns from onload (allow browser
|
// Start connect after control returns from onload (allow browser
|
||||||
// to consider the page loaded).
|
// to consider the page loaded).
|
||||||
window.onload = function() {
|
//else
|
||||||
window.setTimeout(GuacUI.Client.connect, 10);
|
window.onload = function() {
|
||||||
};
|
window.setTimeout(GuacUI.Client.connect, 10);
|
||||||
|
};
|
||||||
|
|
||||||
/* ]]> */ </script>
|
/* ]]> */ </script>
|
||||||
|
|
||||||
|
1505
guacamole-tunnel/src/main/webapp/scripts/admin-ui.js
Normal file
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 Glyptodon, Inc.
|
* Copyright (C) 2013 Glyptodon LLC
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -746,6 +746,48 @@ GuacUI.Client.Pinch = function(element) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flattens the attached Guacamole.Client, storing the result within the
|
||||||
|
* connection history.
|
||||||
|
*/
|
||||||
|
GuacUI.Client.updateThumbnail = function() {
|
||||||
|
|
||||||
|
var guac = GuacUI.Client.attachedClient;
|
||||||
|
if (!guac)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Do not create empty thumbnails
|
||||||
|
if (guac.getDisplay().getWidth() <= 0 || guac.getDisplay().getHeight() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get screenshot
|
||||||
|
var canvas = guac.getDisplay().flatten();
|
||||||
|
|
||||||
|
// Calculate scale of thumbnail (max 320x240, max zoom 100%)
|
||||||
|
var scale = Math.min(
|
||||||
|
320 / canvas.width,
|
||||||
|
240 / canvas.height,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create thumbnail canvas
|
||||||
|
var thumbnail = document.createElement("canvas");
|
||||||
|
thumbnail.width = canvas.width*scale;
|
||||||
|
thumbnail.height = canvas.height*scale;
|
||||||
|
|
||||||
|
// Scale screenshot to thumbnail
|
||||||
|
var context = thumbnail.getContext("2d");
|
||||||
|
context.drawImage(canvas,
|
||||||
|
0, 0, canvas.width, canvas.height,
|
||||||
|
0, 0, thumbnail.width, thumbnail.height
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save thumbnail to history
|
||||||
|
var id = decodeURIComponent(window.location.search.substring(4));
|
||||||
|
GuacamoleHistory.update(id, thumbnail.toDataURL());
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current display scale to the given value, where 1 is 100% (1:1
|
* Sets the current display scale to the given value, where 1 is 100% (1:1
|
||||||
* pixel ratio). Out-of-range values will be clamped in-range.
|
* pixel ratio). Out-of-range values will be clamped in-range.
|
||||||
@@ -1546,11 +1588,15 @@ GuacUI.Client.attach = function(guac) {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disconnect on close
|
* Disconnect and update thumbnail on close
|
||||||
*/
|
*/
|
||||||
window.onunload = function() {
|
window.onunload = function() {
|
||||||
|
|
||||||
|
GuacUI.Client.updateThumbnail();
|
||||||
|
|
||||||
if (GuacUI.Client.attachedClient)
|
if (GuacUI.Client.attachedClient)
|
||||||
GuacUI.Client.attachedClient.disconnect();
|
GuacUI.Client.attachedClient.disconnect();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|