1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-10-14 15:33:43 +03:00

20 Commits
v3.0t ... v2.2

Author SHA1 Message Date
Adolfo Gómez García
1a18ff1d5e Changed "/multimedia" for "/video" 2020-06-17 10:16:48 +02:00
Adolfo Gómez García
56553a70a1 minor fixes for 2.2 version 2020-05-26 21:29:39 +02:00
Adolfo Gómez García
2c10e9445b fixed actor log level 2020-05-15 13:56:02 +02:00
Adolfo Gómez García
4ca387c370 Fixed log level for actor 2020-05-15 12:34:59 +02:00
Adolfo Gómez García
67eb4332b7 fixed logger.info issue 2020-05-13 13:47:12 +02:00
Adolfo Gómez García
a6077a61b4 fixed x2go app closing too early 2020-05-13 13:32:16 +02:00
Adolfo Gómez García
dc42433b86 fixed operations getidle for linux 2020-05-12 14:20:35 +02:00
Adolfo Gómez García
f67730cfad fixed Publication manager error on full persistent services 2020-04-20 10:18:45 +02:00
Adolfo Gómez García
8b8135ea98 Fixed xen SR error 2020-04-16 10:10:59 +02:00
Adolfo Gómez García
07c304cecb small fix on REST (visual) 2020-03-19 13:52:10 +01:00
Adolfo Gómez García
a3dd038e79 Testing clients 2020-03-04 15:24:17 +01:00
Adolfo Gómez García
f3522ae154 Updating udsclient 2020-03-04 15:17:43 +01:00
Adolfo Gómez García
67feb4aefa Fixed operations for getidle 2019-12-04 15:00:10 +01:00
Adolfo Gómez García
5953a67d3a Fixed support for deathkey on UDS 2019-10-14 09:21:27 +02:00
Adolfo Gómez García
c6f3c87b93 Fixed fastlinks for owner. Thanks to Daniel Torregosa for the fix :) 2019-09-11 11:10:01 +02:00
Adolfo Gómez García
eb270d883e Fixed OpenNebula "weird". We were defining "VmState" Module, and after that, redefining by importing common. Removed initial definition 2019-08-16 11:12:41 +02:00
Adolfo Gómez García
5ddd2519b0 fix for OpenNebula 2019-08-01 14:43:17 +02:00
Adolfo Gómez García
e5574fe2ba fix for newer opennebula settiong image to "non persistent" on publication clone 2019-07-25 11:47:46 +02:00
Adolfo Gómez García
4b9b386f14 fixed authorize of x2go for python2/3 compat 2019-07-10 11:30:04 +02:00
Adolfo Gómez García
8a61986dad fixed httpserver for python3 compat 2019-07-09 13:25:50 +02:00
36 changed files with 268 additions and 202 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@
*_enterprise.* *_enterprise.*
.settings/ .settings/
.ipynb_checkpoints .ipynb_checkpoints
.mypy_cache
# Debian buildings # Debian buildings
*.debhelper* *.debhelper*

View File

@@ -2,8 +2,7 @@
# Resource object code # Resource object code
# #
# Created: Mon Apr 27 22:05:02 2015 # Created by: The Resource Compiler for PyQt4 (Qt v4.8.7)
# by: The Resource Compiler for PyQt (Qt v4.8.6)
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@@ -2,8 +2,7 @@
# Form implementation generated from reading ui file 'about-dialog.ui' # Form implementation generated from reading ui file 'about-dialog.ui'
# #
# Created: Mon Apr 27 22:05:02 2015 # Created by: PyQt4 UI code generator 4.12.1
# by: PyQt4 UI code generator 4.11.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@@ -34,8 +33,8 @@ class Ui_UDSAboutDialog(object):
UDSAboutDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) UDSAboutDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
UDSAboutDialog.setModal(True) UDSAboutDialog.setModal(True)
self.vboxlayout = QtGui.QVBoxLayout(UDSAboutDialog) self.vboxlayout = QtGui.QVBoxLayout(UDSAboutDialog)
self.vboxlayout.setSpacing(9)
self.vboxlayout.setMargin(9) self.vboxlayout.setMargin(9)
self.vboxlayout.setSpacing(9)
self.vboxlayout.setObjectName(_fromUtf8("vboxlayout")) self.vboxlayout.setObjectName(_fromUtf8("vboxlayout"))
self.LogoLabel = QtGui.QLabel(UDSAboutDialog) self.LogoLabel = QtGui.QLabel(UDSAboutDialog)
self.LogoLabel.setObjectName(_fromUtf8("LogoLabel")) self.LogoLabel.setObjectName(_fromUtf8("LogoLabel"))
@@ -55,8 +54,8 @@ class Ui_UDSAboutDialog(object):
self.aboutTab = QtGui.QWidget() self.aboutTab = QtGui.QWidget()
self.aboutTab.setObjectName(_fromUtf8("aboutTab")) self.aboutTab.setObjectName(_fromUtf8("aboutTab"))
self.vboxlayout1 = QtGui.QVBoxLayout(self.aboutTab) self.vboxlayout1 = QtGui.QVBoxLayout(self.aboutTab)
self.vboxlayout1.setSpacing(6)
self.vboxlayout1.setMargin(9) self.vboxlayout1.setMargin(9)
self.vboxlayout1.setSpacing(6)
self.vboxlayout1.setObjectName(_fromUtf8("vboxlayout1")) self.vboxlayout1.setObjectName(_fromUtf8("vboxlayout1"))
self.aboutBrowser = QtGui.QTextBrowser(self.aboutTab) self.aboutBrowser = QtGui.QTextBrowser(self.aboutTab)
self.aboutBrowser.setOpenExternalLinks(True) self.aboutBrowser.setOpenExternalLinks(True)
@@ -66,8 +65,8 @@ class Ui_UDSAboutDialog(object):
self.authorsTab = QtGui.QWidget() self.authorsTab = QtGui.QWidget()
self.authorsTab.setObjectName(_fromUtf8("authorsTab")) self.authorsTab.setObjectName(_fromUtf8("authorsTab"))
self.vboxlayout2 = QtGui.QVBoxLayout(self.authorsTab) self.vboxlayout2 = QtGui.QVBoxLayout(self.authorsTab)
self.vboxlayout2.setSpacing(6)
self.vboxlayout2.setMargin(9) self.vboxlayout2.setMargin(9)
self.vboxlayout2.setSpacing(6)
self.vboxlayout2.setObjectName(_fromUtf8("vboxlayout2")) self.vboxlayout2.setObjectName(_fromUtf8("vboxlayout2"))
self.authorsBrowser = QtGui.QTextBrowser(self.authorsTab) self.authorsBrowser = QtGui.QTextBrowser(self.authorsTab)
self.authorsBrowser.setOpenExternalLinks(True) self.authorsBrowser.setOpenExternalLinks(True)
@@ -77,8 +76,8 @@ class Ui_UDSAboutDialog(object):
self.licenseTab = QtGui.QWidget() self.licenseTab = QtGui.QWidget()
self.licenseTab.setObjectName(_fromUtf8("licenseTab")) self.licenseTab.setObjectName(_fromUtf8("licenseTab"))
self.vboxlayout3 = QtGui.QVBoxLayout(self.licenseTab) self.vboxlayout3 = QtGui.QVBoxLayout(self.licenseTab)
self.vboxlayout3.setSpacing(6)
self.vboxlayout3.setMargin(9) self.vboxlayout3.setMargin(9)
self.vboxlayout3.setSpacing(6)
self.vboxlayout3.setObjectName(_fromUtf8("vboxlayout3")) self.vboxlayout3.setObjectName(_fromUtf8("vboxlayout3"))
self.licenseBrowser = QtGui.QTextBrowser(self.licenseTab) self.licenseBrowser = QtGui.QTextBrowser(self.licenseTab)
self.licenseBrowser.setObjectName(_fromUtf8("licenseBrowser")) self.licenseBrowser.setObjectName(_fromUtf8("licenseBrowser"))
@@ -92,7 +91,7 @@ class Ui_UDSAboutDialog(object):
self.vboxlayout.addWidget(self.buttonBox) self.vboxlayout.addWidget(self.buttonBox)
self.retranslateUi(UDSAboutDialog) self.retranslateUi(UDSAboutDialog)
self.tabWidget.setCurrentIndex(0) self.tabWidget.setCurrentIndex(2)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("clicked(QAbstractButton*)")), UDSAboutDialog.closeDialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("clicked(QAbstractButton*)")), UDSAboutDialog.closeDialog)
QtCore.QMetaObject.connectSlotsByName(UDSAboutDialog) QtCore.QMetaObject.connectSlotsByName(UDSAboutDialog)
@@ -106,7 +105,7 @@ class Ui_UDSAboutDialog(object):
"p, li { white-space: pre-wrap; }\n" "p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" "</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\';\"><br /></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\';\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\'; font-weight:600;\">(c) 2014, Virtual Cable S.L.U.</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'Sans Serif\'; font-weight:600;\">(c) 2012-2016, Virtual Cable S.L.U.</span></p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-style:italic;\"><br /></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'Sans Serif\'; font-style:italic;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.udsenterprise.com\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.udsenterprise.com</span></a></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.udsenterprise.com\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.udsenterprise.com</span></a></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.openuds.org\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.openuds.org</span></a></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.openuds.org\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt; text-decoration: underline; color:#0000ff;\">http://www.openuds.org</span></a></p>\n"
@@ -122,7 +121,7 @@ class Ui_UDSAboutDialog(object):
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n" "p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n" "</style></head><body style=\" font-family:\'Verdana\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">Copyright (c) 2014 Virtual Cable S.L.</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">Copyright (c) 2012-2016 Virtual Cable S.L.</span></p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">All rights reserved.</span></p>\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:8pt;\">All rights reserved.</span></p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n" "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><br /></p>\n"

View File

@@ -2,8 +2,7 @@
# Form implementation generated from reading ui file 'message-dialog.ui' # Form implementation generated from reading ui file 'message-dialog.ui'
# #
# Created: Mon Apr 27 22:05:02 2015 # Created by: PyQt4 UI code generator 4.12.1
# by: PyQt4 UI code generator 4.11.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@@ -121,7 +121,7 @@
<x>20</x> <x>20</x>
<y>20</y> <y>20</y>
<width>361</width> <width>361</width>
<height>131</height> <height>166</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@@ -205,7 +205,7 @@
<item row="3" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="logLevelComboBox"> <widget class="QComboBox" name="logLevelComboBox">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>3</number>
</property> </property>
<property name="frame"> <property name="frame">
<bool>true</bool> <bool>true</bool>
@@ -220,6 +220,11 @@
<string notr="true">INFO</string> <string notr="true">INFO</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>WARN</string>
</property>
</item>
<item> <item>
<property name="text"> <property name="text">
<string notr="true">ERROR</string> <string notr="true">ERROR</string>

View File

@@ -2,8 +2,7 @@
# Form implementation generated from reading ui file 'setup-dialog.ui' # Form implementation generated from reading ui file 'setup-dialog.ui'
# #
# Created: Mon Apr 27 22:05:03 2015 # Created by: PyQt4 UI code generator 4.12.1
# by: PyQt4 UI code generator 4.11.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@@ -63,7 +62,7 @@ class Ui_UdsActorSetupDialog(object):
self.cancelButton.setSizePolicy(sizePolicy) self.cancelButton.setSizePolicy(sizePolicy)
self.cancelButton.setObjectName(_fromUtf8("cancelButton")) self.cancelButton.setObjectName(_fromUtf8("cancelButton"))
self.layoutWidget = QtGui.QWidget(UdsActorSetupDialog) self.layoutWidget = QtGui.QWidget(UdsActorSetupDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 361, 131)) self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 361, 166))
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
self.formLayout = QtGui.QFormLayout(self.layoutWidget) self.formLayout = QtGui.QFormLayout(self.layoutWidget)
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
@@ -102,13 +101,14 @@ class Ui_UdsActorSetupDialog(object):
self.logLevelComboBox.addItem(_fromUtf8("")) self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(1, _fromUtf8("INFO")) self.logLevelComboBox.setItemText(1, _fromUtf8("INFO"))
self.logLevelComboBox.addItem(_fromUtf8("")) self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(2, _fromUtf8("ERROR"))
self.logLevelComboBox.addItem(_fromUtf8("")) self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(3, _fromUtf8("FATAL")) self.logLevelComboBox.setItemText(3, _fromUtf8("ERROR"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(4, _fromUtf8("FATAL"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.logLevelComboBox) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.logLevelComboBox)
self.retranslateUi(UdsActorSetupDialog) self.retranslateUi(UdsActorSetupDialog)
self.logLevelComboBox.setCurrentIndex(1) self.logLevelComboBox.setCurrentIndex(3)
QtCore.QObject.connect(self.host, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged) QtCore.QObject.connect(self.host, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.masterKey, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged) QtCore.QObject.connect(self.masterKey, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.cancelAndDiscard) QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.cancelAndDiscard)
@@ -139,6 +139,7 @@ class Ui_UdsActorSetupDialog(object):
self.useSSl.setItemText(0, _translate("UdsActorSetupDialog", "Do not use SSL", None)) self.useSSl.setItemText(0, _translate("UdsActorSetupDialog", "Do not use SSL", None))
self.useSSl.setItemText(1, _translate("UdsActorSetupDialog", "Use SSL", None)) self.useSSl.setItemText(1, _translate("UdsActorSetupDialog", "Use SSL", None))
self.logLevelLabel.setText(_translate("UdsActorSetupDialog", "Log Level", None)) self.logLevelLabel.setText(_translate("UdsActorSetupDialog", "Log Level", None))
self.logLevelComboBox.setItemText(2, _translate("UdsActorSetupDialog", "WARN", None))
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -116,8 +116,8 @@ class HTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
try: try:
HTTPServerHandler.lock.acquire() HTTPServerHandler.lock.acquire()
length = int(self.headers.getheader('content-length')) length = int(self.headers.get('content-length'))
content = self.rfile.read(length) content = self.rfile.read(length).decode('utf8')
logger.debug('length: {}, content >>{}<<'.format(length, content)) logger.debug('length: {}, content >>{}<<'.format(length, content))
params = json.loads(content) params = json.loads(content)
@@ -181,7 +181,7 @@ class HTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
logger.error('HTTP ' + fmt % args) logger.error('HTTP ' + fmt % args)
def log_message(self, fmt, *args): def log_message(self, fmt, *args):
logger.info('HTTP ' + fmt % args) logger.debug('HTTP ' + fmt % args)
class HTTPServerThread(threading.Thread): class HTTPServerThread(threading.Thread):

View File

@@ -132,7 +132,7 @@ class ClientProcessor(threading.Thread):
if b == b'': if b == b'':
# Client disconnected # Client disconnected
self.running = False self.running = False
self.processRequest(REQ_LOGOUT, 'CLIENT_CONNECTION_LOST') # self.processRequest(REQ_LOGOUT, 'CLIENT_CONNECTION_LOST')
break break
buf = six.byte2int(b) # Empty buffer, this is set as non-blocking buf = six.byte2int(b) # Empty buffer, this is set as non-blocking
if state is None: if state is None:

View File

@@ -232,7 +232,7 @@ def getIdleDuration():
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), info) xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), info)
# 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 info.contents.state != 0 and 'centos' not in platform.linux_distribution()[0].lower().strip(): if info.contents.state == 1:
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 info.contents.idle / 1000.0 return info.contents.idle / 1000.0

View File

@@ -219,7 +219,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
logger.info('PRECONNECT file not found & not executed') logger.info('PRECONNECT file not found & not executed')
except Exception as e: except Exception as e:
# Ignore output of execution command # Ignore output of execution command
logger.error('Executing preconnect command give') logger.error('Executing preconnect command give {}'.format(e))
return 'ok' return 'ok'

View File

@@ -215,8 +215,9 @@ def getIdleDuration():
return 0 return 0
# if lastInputInfo.dwTime > 1000000000: # Value toooo high, nonsense... # if lastInputInfo.dwTime > 1000000000: # Value toooo high, nonsense...
# return 0 # return 0
millis = ctypes.windll.kernel32.GetTickCount() - lastInputInfo.dwTime # @UndefinedVariable current = ctypes.c_uint(ctypes.windll.kernel32.GetTickCount())
if millis < 0 or millis > 1000000000: millis = current.value - lastInputInfo.dwTime # @UndefinedVariable
if millis < 0:
return 0 return 0
return millis / 1000.0 return millis / 1000.0
except Exception as e: except Exception as e:

View File

@@ -162,6 +162,7 @@ class UDSClient(QtGui.QMainWindow):
QtCore.QTimer.singleShot(1000, self.getVersion) QtCore.QTimer.singleShot(1000, self.getVersion)
except Exception as e: except Exception as e:
logger.exception('Version')
self.showError(e) self.showError(e)
@@ -210,7 +211,7 @@ class UDSClient(QtGui.QMainWindow):
# if QtGui.QMessageBox.warning(None, 'ACCESS Warning', errorString, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) == QtGui.QMessageBox.No: # if QtGui.QMessageBox.warning(None, 'ACCESS Warning', errorString, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) == QtGui.QMessageBox.No:
# raise Exception('Server not approved. Access denied.') # raise Exception('Server not approved. Access denied.')
logger.debug('Script: {}'.format(script))
six.exec_(script, globals(), {'parent': self, 'sp': params}) six.exec_(script, globals(), {'parent': self, 'sp': params})
except RetryException as e: except RetryException as e:
@@ -219,7 +220,7 @@ class UDSClient(QtGui.QMainWindow):
QtCore.QTimer.singleShot(10000, self.getTransportData) QtCore.QTimer.singleShot(10000, self.getTransportData)
except Exception as e: except Exception as e:
#logger.exception('Got exception executing script:') logger.exception('Got exception executing script:')
self.showError(e) self.showError(e)
def endScript(self): def endScript(self):

View File

@@ -46,7 +46,7 @@ logging.basicConfig(
filename=logFile, filename=logFile,
filemode='a', filemode='a',
format='%(levelname)s %(asctime)s %(message)s', format='%(levelname)s %(asctime)s %(message)s',
level=logging.INFO level=logging.DEBUG
) )
logger = logging.getLogger('udsclient') logger = logging.getLogger('udsclient')

View File

@@ -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.14</version> <version>1.0.0</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.14</version> <version>1.0.0</version>
<type>zip</type> <type>zip</type>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>

View File

@@ -263,7 +263,7 @@ GuacUI.Client = {
"min_zoom" : 1, "min_zoom" : 1,
"max_zoom" : 3, "max_zoom" : 3,
"connectionName" : "Guacamole", "connectionName" : "UDS Remote Connection",
"attachedClient" : null, "attachedClient" : null,
/* Mouse emulation */ /* Mouse emulation */
@@ -1433,7 +1433,11 @@ GuacUI.Client.attach = function(guac) {
* Route document-level keyboard events to the client. * Route document-level keyboard events to the client.
*/ */
var sink = new Guacamole.InputSink();
document.body.appendChild(sink.getElement());
var keyboard = new Guacamole.Keyboard(document); var keyboard = new Guacamole.Keyboard(document);
keyboard.listenTo(sink.getElement());
var show_keyboard_gesture_possible = true; var show_keyboard_gesture_possible = true;
function __send_key(pressed, keysym) { function __send_key(pressed, keysym) {

View File

@@ -78,7 +78,7 @@ class Dispatcher(View):
content_type = None content_type = None
cls = None cls = None
while len(path) > 0: while path:
# .json, .xml, ... will break path recursion # .json, .xml, ... will break path recursion
if path[0].find('.') != -1: if path[0].find('.') != -1:
content_type = path[0].split('.')[1] content_type = path[0].split('.')[1]
@@ -92,7 +92,7 @@ class Dispatcher(View):
break break
full_path = '/'.join(full_path) full_path = '/'.join(full_path)
logger.debug("REST request: {} ({})".format(full_path, content_type)) logger.debug('REST request: %s (%s)', full_path, content_type)
# Here, service points to the path # Here, service points to the path
cls = service[''] cls = service['']

View File

@@ -92,6 +92,10 @@ class ServicesPools(ModelHandler):
custom_methods = [('setFallbackAccess', True), ('actionsList', True)] custom_methods = [('setFallbackAccess', True), ('actionsList', True)]
def getItems(self, *args, **kwargs):
return super(ServicesPools, self).getItems(overview=kwargs.get('overview', True), prefetch=['service', 'service__provider', 'servicesPoolGroup', 'image', 'tags'])
# return super(ServicesPools, self).getItems(overview)
def item_as_dict(self, item): def item_as_dict(self, item):
summary = 'summarize' in self._params summary = 'summarize' in self._params
# if item does not have an associated service, hide it (the case, for example, for a removed service) # if item does not have an associated service, hide it (the case, for example, for a removed service)
@@ -162,106 +166,106 @@ class ServicesPools(ModelHandler):
g = self.addDefaultFields([], ['name', 'short_name', 'comments', 'tags']) g = self.addDefaultFields([], ['name', 'short_name', 'comments', 'tags'])
for f in [{ for f in [{
'name': 'service_id', 'name': 'service_id',
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.provider.name + '\\' + v.name) for v in Service.objects.all()]), 'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.provider.name + '\\' + v.name) for v in Service.objects.all()]),
'label': ugettext('Base service'), 'label': ugettext('Base service'),
'tooltip': ugettext('Service used as base of this service pool'), 'tooltip': ugettext('Service used as base of this service pool'),
'type': gui.InputField.CHOICE_TYPE, 'type': gui.InputField.CHOICE_TYPE,
'rdonly': True, 'rdonly': True,
'order': 100, # Ensueres is At end 'order': 100, # Ensueres is At end
}, { }, {
'name': 'osmanager_id', 'name': 'osmanager_id',
'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.name) for v in OSManager.objects.all()]), 'values': [gui.choiceItem(-1, '')] + gui.sortedChoices([gui.choiceItem(v.uuid, v.name) for v in OSManager.objects.all()]),
'label': ugettext('OS Manager'), 'label': ugettext('OS Manager'),
'tooltip': ugettext('OS Manager used as base of this service pool'), 'tooltip': ugettext('OS Manager used as base of this service pool'),
'type': gui.InputField.CHOICE_TYPE, 'type': gui.InputField.CHOICE_TYPE,
'rdonly': True, 'rdonly': True,
'order': 101, 'order': 101,
}, { }, {
'name': 'show_transports', 'name': 'show_transports',
'value': True, 'value': True,
'label': ugettext('Show transports'), 'label': ugettext('Show transports'),
'tooltip': ugettext('If active, alternative transports for user will be shown'), 'tooltip': ugettext('If active, alternative transports for user will be shown'),
'type': gui.InputField.CHECKBOX_TYPE, 'type': gui.InputField.CHECKBOX_TYPE,
'order': 110, 'order': 110,
'tab': ugettext('Advanced'), 'tab': ugettext('Advanced'),
}, { }, {
'name': 'allow_users_remove', 'name': 'allow_users_remove',
'value': False, 'value': False,
'label': ugettext('Allow removal by users'), 'label': ugettext('Allow removal by users'),
'tooltip': ugettext('If active, the user will be allowed to remove the service "manually". Be careful with this, because the user will have the "power" to delete it\'s own service'), 'tooltip': ugettext('If active, the user will be allowed to remove the service "manually". Be careful with this, because the user will have the "power" to delete it\'s own service'),
'type': gui.InputField.CHECKBOX_TYPE, 'type': gui.InputField.CHECKBOX_TYPE,
'order': 111, 'order': 111,
'tab': ugettext('Advanced'), 'tab': ugettext('Advanced'),
}, { }, {
'name': 'allow_users_reset', 'name': 'allow_users_reset',
'value': False, 'value': False,
'label': ugettext('Allow reset by users'), 'label': ugettext('Allow reset by users'),
'tooltip': ugettext('If active, the user will be allowed to reset the service'), 'tooltip': ugettext('If active, the user will be allowed to reset the service'),
'type': gui.InputField.CHECKBOX_TYPE, 'type': gui.InputField.CHECKBOX_TYPE,
'order': 112, 'order': 112,
'tab': ugettext('Advanced'), 'tab': ugettext('Advanced'),
}, { }, {
'name': 'ignores_unused', 'name': 'ignores_unused',
'value': False, 'value': False,
'label': ugettext('Ignores unused'), 'label': ugettext('Ignores unused'),
'tooltip': ugettext('If the option is enabled, UDS will not attempt to detect and remove the user services assigned but not in use.'), 'tooltip': ugettext('If the option is enabled, UDS will not attempt to detect and remove the user services assigned but not in use.'),
'type': gui.InputField.CHECKBOX_TYPE, 'type': gui.InputField.CHECKBOX_TYPE,
'order': 113, 'order': 113,
'tab': ugettext('Advanced'), 'tab': ugettext('Advanced'),
}, { }, {
'name': 'image_id', 'name': 'image_id',
'values': [gui.choiceImage(-1, '--------', DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in Image.objects.all()]), 'values': [gui.choiceImage(-1, '--------', DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in Image.objects.all()]),
'label': ugettext('Associated Image'), 'label': ugettext('Associated Image'),
'tooltip': ugettext('Image assocciated with this service'), 'tooltip': ugettext('Image assocciated with this service'),
'type': gui.InputField.IMAGECHOICE_TYPE, 'type': gui.InputField.IMAGECHOICE_TYPE,
'order': 120, 'order': 120,
'tab': ugettext('Display'), 'tab': ugettext('Display'),
}, { }, {
'name': 'servicesPoolGroup_id', 'name': 'servicesPoolGroup_id',
'values': [gui.choiceImage(-1, _('Default'), DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in ServicesPoolGroup.objects.all()]), 'values': [gui.choiceImage(-1, _('Default'), DEFAULT_THUMB_BASE64)] + gui.sortedChoices([gui.choiceImage(v.uuid, v.name, v.thumb64) for v in ServicesPoolGroup.objects.all()]),
'label': ugettext('Pool group'), 'label': ugettext('Pool group'),
'tooltip': ugettext('Pool group for this pool (for pool classify on display)'), 'tooltip': ugettext('Pool group for this pool (for pool classify on display)'),
'type': gui.InputField.IMAGECHOICE_TYPE, 'type': gui.InputField.IMAGECHOICE_TYPE,
'order': 121, 'order': 121,
'tab': ugettext('Display'), 'tab': ugettext('Display'),
}, { }, {
'name': 'initial_srvs', 'name': 'initial_srvs',
'value': '0', 'value': '0',
'minValue': '0', 'minValue': '0',
'label': ugettext('Initial available services'), 'label': ugettext('Initial available services'),
'tooltip': ugettext('Services created initially for this service pool'), 'tooltip': ugettext('Services created initially for this service pool'),
'type': gui.InputField.NUMERIC_TYPE, 'type': gui.InputField.NUMERIC_TYPE,
'order': 130, 'order': 130,
'tab': ugettext('Availability'), 'tab': ugettext('Availability'),
}, { }, {
'name': 'cache_l1_srvs', 'name': 'cache_l1_srvs',
'value': '0', 'value': '0',
'minValue': '0', 'minValue': '0',
'label': ugettext('Services to keep in cache'), 'label': ugettext('Services to keep in cache'),
'tooltip': ugettext('Services kept in cache for improved user service assignation'), 'tooltip': ugettext('Services kept in cache for improved user service assignation'),
'type': gui.InputField.NUMERIC_TYPE, 'type': gui.InputField.NUMERIC_TYPE,
'order': 131, 'order': 131,
'tab': ugettext('Availability'), 'tab': ugettext('Availability'),
}, { }, {
'name': 'cache_l2_srvs', 'name': 'cache_l2_srvs',
'value': '0', 'value': '0',
'minValue': '0', 'minValue': '0',
'label': ugettext('Services to keep in L2 cache'), 'label': ugettext('Services to keep in L2 cache'),
'tooltip': ugettext('Services kept in cache of level2 for improved service generation'), 'tooltip': ugettext('Services kept in cache of level2 for improved service generation'),
'type': gui.InputField.NUMERIC_TYPE, 'type': gui.InputField.NUMERIC_TYPE,
'order': 132, 'order': 132,
'tab': ugettext('Availability'), 'tab': ugettext('Availability'),
}, { }, {
'name': 'max_srvs', 'name': 'max_srvs',
'value': '0', 'value': '0',
'minValue': '1', 'minValue': '1',
'label': ugettext('Maximum number of services to provide'), 'label': ugettext('Maximum number of services to provide'),
'tooltip': ugettext('Maximum number of service (assigned and L1 cache) that can be created for this service'), 'tooltip': ugettext('Maximum number of service (assigned and L1 cache) that can be created for this service'),
'type': gui.InputField.NUMERIC_TYPE, 'type': gui.InputField.NUMERIC_TYPE,
'order': 133, 'order': 133,
'tab': ugettext('Availability'), 'tab': ugettext('Availability'),
}]: }]:
self.addField(g, f) self.addField(g, f)
return g return g

View File

@@ -732,8 +732,28 @@ class ModelHandler(BaseModelHandler):
return method() return method()
def getItems(self, overview=True, *args, **kwargs): def getItems(self, *args, **kwargs):
for item in self.model.objects.filter(*args, **kwargs): if 'overview' in kwargs:
overview = kwargs['overview']
del kwargs['overview']
else:
overview = False
if 'prefetch' in kwargs:
prefetch = kwargs['prefetch']
logger.debug('Prefetching %s', prefetch)
del kwargs['prefetch']
else:
prefetch = []
if 'query' in kwargs:
query = kwargs['query']
del kwargs['query']
else:
logger.debug('Args: %s, kwargs: %s', args, kwargs)
query = self.model.objects.filter(*args, **kwargs).prefetch_related(*prefetch)
for item in query:
try: try:
if permissions.checkPermissions(self._user, item, permissions.PERMISSION_READ) is False: if permissions.checkPermissions(self._user, item, permissions.PERMISSION_READ) is False:
continue continue

View File

@@ -140,9 +140,9 @@ class PublicationFinishChecker(DelayedTask):
if doPublicationCleanup: if doPublicationCleanup:
pc = PublicationOldMachinesCleaner(old.id) pc = PublicationOldMachinesCleaner(old.id)
pc.register(GlobalConfig.SESSION_EXPIRE_TIME.getInt(True) * 3600, 'pclean-' + str(old.id), True) pc.register(GlobalConfig.SESSION_EXPIRE_TIME.getInt(True) * 3600, 'pclean-' + str(old.id), True)
servicePoolPub.deployed_service.markOldUserServicesAsRemovables(servicePoolPub)
servicePoolPub.setState(State.USABLE) servicePoolPub.setState(State.USABLE)
servicePoolPub.deployed_service.markOldUserServicesAsRemovables(servicePoolPub)
elif State.isRemoving(prevState): elif State.isRemoving(prevState):
servicePoolPub.setState(State.REMOVED) servicePoolPub.setState(State.REMOVED)
else: # State is canceling else: # State is canceling

View File

@@ -72,9 +72,9 @@ class StateUpdater(object):
def run(self, state): def run(self, state):
executor = { executor = {
State.RUNNING: self.running, State.RUNNING: self.running,
State.ERROR: self.error, State.ERROR: self.error,
State.FINISHED: self.finish State.FINISHED: self.finish
}.get(state, self.error) }.get(state, self.error)
logger.debug('Running updater with state {} and executor {}'.format(State.toString(state), executor)) logger.debug('Running updater with state {} and executor {}'.format(State.toString(state), executor))

View File

@@ -115,7 +115,8 @@ class CalendarAction(UUIDModel):
self.service_pool.save() self.service_pool.save()
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.next_execution = calendar.CalendarChecker(self.calendar).nextEvent(checkFrom=self.last_execution, startEvent=self.at_start, offset=self.offset) lastExecution = self.last_execution or getSqlDatetime()
self.next_execution = calendar.CalendarChecker(self.calendar).nextEvent(checkFrom=lastExecution-self.offset, startEvent=self.at_start) + self.offset
return UUIDModel.save(self, *args, **kwargs) return UUIDModel.save(self, *args, **kwargs)

View File

@@ -107,12 +107,15 @@ class WinDomainOsManager(WindowsOsManager):
_str = '' _str = ''
try: try:
uri = "%s://%s:%d" % ('ldap', server[0], server[1]) uri = "%s://%s" % ('ldaps', server[0])
logger.debug('URI: {0}'.format(uri)) logger.debug('URI: {0}'.format(uri))
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # Disable certificate check ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # Disable certificate check
l = ldap.initialize(uri=uri) l = ldap.initialize(uri=uri)
l.set_option(ldap.OPT_REFERRALS, 0) l.set_option(ldap.OPT_REFERRALS, 0)
# l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
# l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
# l.set_option( ldap.OPT_X_TLS_DEMAND, True )
l.network_timeout = l.timeout = 5 l.network_timeout = l.timeout = 5
l.protocol_version = ldap.VERSION3 l.protocol_version = ldap.VERSION3

View File

@@ -150,6 +150,7 @@ class UsageByPool(StatsReport):
total = i.stamp - stamp total = i.stamp - stamp
data.append({ data.append({
'name': i.fld4, 'name': i.fld4,
'origin': i.fld2.split(':')[0], # Gets also origin
'date': datetime.datetime.fromtimestamp(stamp), 'date': datetime.datetime.fromtimestamp(stamp),
'time': total 'time': total
}) })
@@ -186,9 +187,9 @@ class UsageByPoolCSV(UsageByPool):
reportData, poolName = self.getData() reportData, poolName = self.getData()
writer.writerow([ugettext('Date'), ugettext('User'), ugettext('Seconds')]) writer.writerow([ugettext('Date'), ugettext('User'), ugettext('Seconds'), ugettext('Origin')])
for v in reportData: for v in reportData:
writer.writerow([v['date'], v['name'], v['time']]) writer.writerow([v['date'], v['name'], v['time'], v['origin']])
return output.getvalue() return output.getvalue()

View File

@@ -49,12 +49,8 @@ logger = logging.getLogger(__name__)
module = sys.modules[__name__] module = sys.modules[__name__]
VmState = imp.new_module('VmState')
ImageState = imp.new_module('ImageState') ImageState = imp.new_module('ImageState')
for i in enumerate(['INIT', 'PENDING', 'HOLD', 'ACTIVE', 'STOPPED', 'SUSPENDED', 'DONE', 'FAILED', 'POWEROFF', 'UNDEPLOYED']):
setattr(VmState, i[1], i[0])
for i in enumerate(['INIT', 'READY', 'USED', 'DISABLED', 'LOCKED', 'ERROR', 'CLONE', 'DELETE', 'USED_PERS', 'LOCKED_USED', 'LOCKED_USED_PERS']): for i in enumerate(['INIT', 'READY', 'USED', 'DISABLED', 'LOCKED', 'ERROR', 'CLONE', 'DELETE', 'USED_PERS', 'LOCKED_USED', 'LOCKED_USED_PERS']):
setattr(ImageState, i[1], i[0]) setattr(ImageState, i[1], i[0])

View File

@@ -101,12 +101,12 @@ def create(api, fromTemplateId, name, toDataStore):
# if api.imageInfo(imgId)[0]['IMAGE']['STATE'] != '1': # if api.imageInfo(imgId)[0]['IMAGE']['STATE'] != '1':
# raise Exception('The base machines images are not in READY state') # raise Exception('The base machines images are not in READY state')
# Ensure base Image persistence is set to "False"
# api.makePersistentImage(imgId, False)
# Now clone the image # Now clone the image
imgName = sanitizeName(name + ' DSK ' + six.text_type(counter)) imgName = sanitizeName(name + ' DSK ' + six.text_type(counter))
newId = api.cloneImage(imgId, imgName, toDataStore) # api.call('image.clone', int(imgId), imgName, int(toDataStore)) newId = api.cloneImage(imgId, imgName, toDataStore) # api.call('image.clone', int(imgId), imgName, int(toDataStore))
# Ensure image is non persistent
api.makePersistentImage(newId, False)
# Now Store id/name # Now Store id/name
if fromId is True: if fromId is True:
node.data = six.text_type(newId) node.data = six.text_type(newId)
@@ -207,12 +207,15 @@ def checkPublished(api, templateId):
logger.debug('Found {} for checking'.format(imgId)) logger.debug('Found {} for checking'.format(imgId))
state = api.imageInfo(imgId)[0]['IMAGE']['STATE'] state = api.imageInfo(imgId)[0]['IMAGE']['STATE']
if state in ('0', '4'): if state in ('0', '4', '6'):
return False return False
elif state != '1': # If error is not READY elif state != '1': # If error is not READY
raise Exception('Error publishing. Image is in an invalid state. (Check it and delete it if not needed anymore)') raise Exception('Error publishing. Image is in an invalid state. (Check it and delete it if not needed anymore)')
# Ensure image is non persistent, do not ask first because this is a simple request and normally templates has only 1 image.
api.makePersistentImage(imgId, False)
except Exception: except Exception:
logger.exception('Exception checking published') logger.exception('Exception checking published')
raise raise
return True return True

View File

@@ -97,20 +97,20 @@ class LiveService(Service):
servicesTypeProvided = (serviceTypes.VDI,) servicesTypeProvided = (serviceTypes.VDI,)
# Now the form part # Now the form part
region = gui.ChoiceField(label=_('Region'), order=1, tooltip=_('Service region'), required=True, rdonly=True) #region = gui.ChoiceField(label=_('Region'), order=1, tooltip=_('Service region'), required=True, rdonly=True)
project = gui.ChoiceField(label=_('Project'), order=2, #project = gui.ChoiceField(label=_('Project'), order=2,
fills={ # fills={
'callbackName' : 'osFillResources', # 'callbackName' : 'osFillResources',
'function' : helpers.getResources, # 'function' : helpers.getResources,
'parameters' : ['ov', 'ev', 'project', 'region', 'legacy'] # 'parameters' : ['ov', 'ev', 'project', 'region', 'legacy']
}, # },
tooltip=_('Project for this service'), required=True, rdonly=True # tooltip=_('Project for this service'), required=True, rdonly=True
) #)
availabilityZone = gui.ChoiceField(label=_('Availability Zones'), order=3, availabilityZone = gui.ChoiceField(label=_('Availability Zones'), order=3,
fills={ fills={
'callbackName' : 'osFillVolumees', 'callbackName' : 'osFillVolumees',
'function' : helpers.getVolumes, 'function' : helpers.getVolumes,
'parameters' : ['ov', 'ev', 'project', 'region', 'availabilityZone', 'legacy'] 'parameters' : ['ov', 'ev', 'availabilityZone', 'legacy']
}, },
tooltip=_('Service availability zones'), required=True, rdonly=True tooltip=_('Service availability zones'), required=True, rdonly=True
) )
@@ -168,11 +168,17 @@ class LiveService(Service):
Loads required values inside Loads required values inside
''' '''
api = self.parent().api() api = self.parent().api()
regions = [gui.choiceItem(r['id'], r['id']) for r in api.listRegions()] #regions = [gui.choiceItem(r['id'], r['id']) for r in api.listRegions()]
self.region.setValues(regions) #self.region.setValues(regions)
tenants = [gui.choiceItem(t['id'], t['name']) for t in api.listProjects()] #tenants = [gui.choiceItem(t['id'], t['name']) for t in api.listProjects()]
self.project.setValues(tenants) #self.project.setValues(tenants)
self.availabilityZone.setValues([gui.choiceItem(z, z) for z in api.listAvailabilityZones()])
self.network.setValues([gui.choiceItem(z['id'], z['name']) for z in api.listNetworks()])
self.flavor.setValues([gui.choiceItem(z['id'], z['name']) for z in api.listFlavors()])
self.securityGroups.setValues([gui.choiceItem(z['id'], z['name']) for z in api.listSecurityGroups()])
# volumeTypes = [gui.choiceItem('-', _('None'))] + [gui.choiceItem(t['id'], t['name']) for t in api.listVolumeTypes()]
# So we can instantiate parent to get API # So we can instantiate parent to get API
logger.debug(self.parent().serialize()) logger.debug(self.parent().serialize())
@@ -184,7 +190,7 @@ class LiveService(Service):
@property @property
def api(self): def api(self):
if self._api is None: if self._api is None:
self._api = self.parent().api(projectId=self.project.value, region=self.region.value) self._api = self.parent().api()
return self._api return self._api

View File

@@ -109,8 +109,8 @@ class Provider(ServiceProvider):
timeout = gui.NumericField(length=3, label=_('Timeout'), defvalue='10', minValue=1, maxValue=128, order=99, tooltip=_('Timeout in seconds of connection to OpenStack'), required=True, tab=gui.ADVANCED_TAB) timeout = gui.NumericField(length=3, label=_('Timeout'), defvalue='10', minValue=1, maxValue=128, order=99, tooltip=_('Timeout in seconds of connection to OpenStack'), required=True, tab=gui.ADVANCED_TAB)
# tenant = gui.TextField(length=64, label=_('Project'), order=6, tooltip=_('Project (tenant) for this provider'), required=True, defvalue='') tenant = gui.TextField(length=64, label=_('Project'), order=6, tooltip=_('Project (tenant) for this provider'), required=True, defvalue='')
# region = gui.TextField(length=64, label=_('Region'), order=7, tooltip=_('Region for this provider'), required=True, defvalue='RegionOne') region = gui.TextField(length=64, label=_('Region'), order=7, tooltip=_('Region for this provider'), required=True, defvalue='eu-de')
legacy = False legacy = False
@@ -127,6 +127,8 @@ class Provider(ServiceProvider):
self.timeout.value = validators.validateTimeout(self.timeout.value, returnAsInteger=False) self.timeout.value = validators.validateTimeout(self.timeout.value, returnAsInteger=False)
def api(self, projectId=None, region=None): def api(self, projectId=None, region=None):
projectId = projectId or self.tenant.value
region = region or self.region.value
return openStack.Client(self.endpoint.value, -1, return openStack.Client(self.endpoint.value, -1,
self.domain.value, self.username.value, self.password.value, self.domain.value, self.username.value, self.password.value,
legacyVersion=False, legacyVersion=False,

View File

@@ -30,7 +30,7 @@ def getResources(parameters):
provider = Provider(env) provider = Provider(env)
provider.unserialize(parameters['ov']) provider.unserialize(parameters['ov'])
api = provider.api(parameters['project'], parameters['region']) api = provider.api()
zones = [gui.choiceItem(z, z) for z in api.listAvailabilityZones()] zones = [gui.choiceItem(z, z) for z in api.listAvailabilityZones()]
networks = [gui.choiceItem(z['id'], z['name']) for z in api.listNetworks()] networks = [gui.choiceItem(z['id'], z['name']) for z in api.listNetworks()]
@@ -63,7 +63,7 @@ def getVolumes(parameters):
provider = Provider(env) provider = Provider(env)
provider.unserialize(parameters['ov']) provider.unserialize(parameters['ov'])
api = provider.api(parameters['project'], parameters['region']) api = provider.api()
volumes = [gui.choiceItem(v['id'], v['name']) for v in api.listVolumes() if v['name'] != '' and v['availability_zone'] == parameters['availabilityZone']] volumes = [gui.choiceItem(v['id'], v['name']) for v in api.listVolumes() if v['name'] != '' and v['availability_zone'] == parameters['availabilityZone']]

View File

@@ -73,6 +73,7 @@ def getRecurringUrlJson(url, headers, key, params=None, errMsg=None, timeout=10)
counter += 1 counter += 1
logger.debug('Requesting url #{}: {} / {}'.format(counter, url, params)) logger.debug('Requesting url #{}: {} / {}'.format(counter, url, params))
r = requests.get(url, params=params, headers=headers, verify=VERIFY_SSL, timeout=timeout) r = requests.get(url, params=params, headers=headers, verify=VERIFY_SSL, timeout=timeout)
logger.debug('Response: %s', r.content)
ensureResponseIsValid(r, errMsg) ensureResponseIsValid(r, errMsg)
@@ -212,6 +213,8 @@ class Client(object):
if self._projectId is not None: if self._projectId is not None:
self._catalog = token['catalog'] self._catalog = token['catalog']
# logger.debug(self._catalog)
def ensureAuthenticated(self): def ensureAuthenticated(self):
if self._authenticated is False or self._projectId != self._authenticatedProjectId: if self._authenticated is False or self._projectId != self._authenticatedProjectId:
self.authPassword() self.authPassword()
@@ -474,13 +477,20 @@ class Client(object):
@authProjectRequired @authProjectRequired
def deleteServer(self, serverId): def deleteServer(self, serverId):
r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId), r = requests.delete(
data='{"forceDelete": null}', self._getEndpointFor('compute') + '/servers/{server_id}'.format(server_id=serverId),
headers=self._requestHeaders(), headers=self._requestHeaders(),
verify=VERIFY_SSL, verify=VERIFY_SSL,
timeout=self._timeout) timeout=self._timeout
)
ensureResponseIsValid(r, 'Cannot start server (probably server does not exists).') # r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId),
# data='{"forceDelete": null}',
# headers=self._requestHeaders(),
# verify=VERIFY_SSL,
# timeout=self._timeout)
ensureResponseIsValid(r, 'Cannot delete server (probably server does not exists).')
# This does not returns anything # This does not returns anything
@@ -570,7 +580,7 @@ class Client(object):
logger.exception('Authenticating') logger.exception('Authenticating')
raise Exception(_('Authentication error')) raise Exception(_('Authentication error'))
except Exception: # Not json except Exception: # Not json
# logger.exception('xx') logger.exception('xx')
raise Exception('Invalid endpoint (maybe invalid version selected?)') raise Exception('Invalid endpoint (maybe invalid version selected?)')
raise Exception(_('Openstack does not support identity API 3.2 or newer. This OpenStack server is not compatible with UDS.')) raise Exception(_('Openstack does not support identity API 3.2 or newer. This OpenStack server is not compatible with UDS.'))

View File

@@ -252,15 +252,13 @@ class XenServer(object):
if v not in allowed_ops: if v not in allowed_ops:
valid = False valid = False
if not valid: if valid:
return yield {
'id': srId,
yield { 'name': name_label,
'id': srId, 'size': XenServer.toMb(self.SR.get_physical_size(srId)),
'name': name_label, 'used': XenServer.toMb(self.SR.get_physical_utilisation(srId))
'size': XenServer.toMb(self.SR.get_physical_size(srId)), }
'used': XenServer.toMb(self.SR.get_physical_utilisation(srId))
}
def getSRInfo(self, srId): def getSRInfo(self, srId):
return { return {

View File

@@ -226,7 +226,7 @@ gui.providers.link = (event) ->
onData: (data) -> onData: (data) ->
$.each data, (index, value) -> $.each data, (index, value) ->
value.owner = gui.fastLink(value.owner.replace /@/, '<span class="text-danger">@</span>', "#{value.owner_info.auth_id},u#{value.owner_info.user_id}", 'gui.providers.fastLink', 'goAuthLink') value.owner = gui.fastLink(value.owner.replace(/@/, '<span class="text-danger">@</span>'), "#{value.owner_info.auth_id},u#{value.owner_info.user_id}", 'gui.providers.fastLink', 'goAuthLink')
value.pool = gui.fastLink(value.pool, value.pool_id, 'gui.providers.fastLink', 'goPoolLink') value.pool = gui.fastLink(value.pool, value.pool_id, 'gui.providers.fastLink', 'goPoolLink')
buttons: [ buttons: [

View File

@@ -417,8 +417,7 @@ gui.servicesPools.link = (event) ->
value.in_use = gettext('Yes') value.in_use = gettext('Yes')
else else
value.in_use = gettext('No') value.in_use = gettext('No')
value.owner = gui.fastLink(value.owner.replace /@/, '<span class="text-danger">@</span>', "#{value.owner_info.auth_id},u#{value.owner_info.user_id}", 'gui.servicesPools.fastLink', 'goAuthLink') value.owner = gui.fastLink(value.owner.replace(/@/, '<span class="text-danger">@</span>'), "#{value.owner_info.auth_id},u#{value.owner_info.user_id}", 'gui.servicesPools.fastLink', 'goAuthLink')
return return
onRefresh: () -> onRefresh: () ->

View File

@@ -111,13 +111,11 @@ class RDPFile(object):
if self.alsa: if self.alsa:
params.append('/sound:sys:alsa,format:1,quality:high') params.append('/sound:sys:alsa,format:1,quality:high')
params.append('/microphone:sys:alsa') params.append('/microphone:sys:alsa')
if self.multimedia:
params.append('/multimedia:sys:alsa')
else: else:
params.append('/sound') params.append('/sound')
params.append('/microphone') params.append('/microphone')
if self.multimedia: if self.multimedia:
params.append('/multimedia') params.append('/video')
if self.redirectDrives != 'false': if self.redirectDrives != 'false':
params.append('/drive:media,/media') params.append('/drive:media,/media')

View File

@@ -29,7 +29,7 @@ def updateAuthorizedKeys(user, pubKey):
sshFolder = '{}/.ssh'.format(home) sshFolder = '{}/.ssh'.format(home)
if not os.path.exists(sshFolder): if not os.path.exists(sshFolder):
try: try:
os.makedirs(sshFolder, 0700) os.makedirs(sshFolder, 0o700)
os.chown(sshFolder, uid, -1) os.chown(sshFolder, uid, -1)
except OSError as e: except OSError as e:
if e.errno != errno.EEXIST: if e.errno != errno.EEXIST:
@@ -53,7 +53,7 @@ def updateAuthorizedKeys(user, pubKey):
# Ensure access is correct # Ensure access is correct
os.chown(authorizedKeys, uid, -1) os.chown(authorizedKeys, uid, -1)
os.chmod(authorizedKeys, 0600) os.chmod(authorizedKeys, 0o600)
# Done # Done

View File

@@ -191,12 +191,20 @@ def ticketAuth(request, ticketId):
request.session['ticket'] = '1' # Store that user access is done using ticket request.session['ticket'] = '1' # Store that user access is done using ticket
logger.debug("Service & transport: {}, {}".format(servicePool, transport)) logger.debug("Service & transport: {}, {}".format(servicePool, transport))
for v in DeployedService.objects.all(): # for v in DeployedService.objects.all():
logger.debug("{} {}".format(v.uuid, v.name)) # logger.debug("{} {}".format(v.uuid, v.name))
# Check if servicePool is part of the ticket # Check if servicePool is part of the ticket
if servicePool is not None: if servicePool is not None:
# If service pool is in there, also is transport # If service pool is in there, also is transport
# Deferred update transport
servicePoolDb = DeployedService.objects.get(uuid=servicePool)
for t in servicePoolDb.transports.order_by('priority'):
typeTrans = t.getType()
if t.validForIp(request.ip) and typeTrans.supportsOs(request.os['OS']) and t.validForOs(request.os['OS']):
transport = t.uuid
break
res = userServiceManager().getService(request.user, request.ip, 'F' + servicePool, transport, False) res = userServiceManager().getService(request.user, request.ip, 'F' + servicePool, transport, False)
_x, userService, _x, transport, _x = res _x, userService, _x, transport, _x = res

View File

@@ -191,10 +191,17 @@ def index(request):
else: else:
tbrt = '' tbrt = ''
left = ''
# try:
# if svr.max_srvs > 0:
# left = ' (max {})'.format(svr.max_srvs - svr.assignedUserServices().filter(UserServiceManager.getStateFilter()).count())
# except Exception:
# logger.exception('Error')
services.append({ services.append({
'id': 'F' + svr.uuid, 'id': 'F' + svr.uuid,
'name': svr.name, 'name': svr.name + left,
'visual_name': svr.visual_name, 'visual_name': svr.visual_name + left,
'description': svr.comments, 'description': svr.comments,
'group': group, 'group': group,
'transports': trans, 'transports': trans,