From ec7d3d39bdf5ec77f1aa5b15267a05b2dddc03ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Tue, 17 Jan 2017 11:17:55 +0100 Subject: [PATCH 1/3] Fixed a lot of things from javi --- server/src/uds/REST/methods/providers.py | 3 +- server/src/uds/REST/methods/services.py | 3 +- server/src/uds/REST/methods/system.py | 3 +- .../LinuxOsManager/LinuxOsManager.py | 2 +- .../WindowsOsManager/WinDomainOsManager.py | 2 +- .../WindowsOsManager/WindowsOsManager.py | 2 +- .../uds/services/OVirt/OVirtLinkedService.py | 82 ++++++++++-------- .../uds/services/OpenNebula/LiveService.py | 25 ++++-- .../src/uds/services/Xen/XenLinkedService.py | 83 +++++++++++++++---- 9 files changed, 145 insertions(+), 60 deletions(-) diff --git a/server/src/uds/REST/methods/providers.py b/server/src/uds/REST/methods/providers.py index a675d9306..0e87ab374 100644 --- a/server/src/uds/REST/methods/providers.py +++ b/server/src/uds/REST/methods/providers.py @@ -35,6 +35,7 @@ from __future__ import unicode_literals from django.utils.translation import ugettext, ugettext_lazy as _ from uds.models import Provider, Service, UserService from uds.core import services +from uds.core.util.State import State from uds.core.util import permissions from uds.core.util.model import processUuid @@ -87,7 +88,7 @@ class Providers(ModelHandler): 'name': provider.name, 'tags': [tag.vtag for tag in provider.tags.all()], 'services_count': provider.services.count(), - 'user_services_count': UserService.objects.filter(deployed_service__service__provider=provider).count(), + 'user_services_count': UserService.objects.filter(deployed_service__service__provider=provider).exclude(state__in=(State.REMOVED, State.ERROR)).count(), 'maintenance_mode': provider.maintenance_mode, 'offers': offers, 'type': type_.type(), diff --git a/server/src/uds/REST/methods/services.py b/server/src/uds/REST/methods/services.py index da2e780bd..7018dc7df 100644 --- a/server/src/uds/REST/methods/services.py +++ b/server/src/uds/REST/methods/services.py @@ -46,6 +46,7 @@ from uds.REST.model import DetailHandler from uds.REST import NotFound, ResponseError, RequestError from django.db import IntegrityError from uds.core.ui.images import DEFAULT_THUMB_BASE64 +from uds.core.util.State import State import logging @@ -92,7 +93,7 @@ class Services(DetailHandler): # pylint: disable=too-many-public-methods 'type': item.data_type, 'type_name': _(itemType.name()), 'deployed_services_count': item.deployedServices.count(), - 'user_services_count': UserService.objects.filter(deployed_service__service=item).count(), + 'user_services_count': UserService.objects.filter(deployed_service__service=item).exclude(state__in=(State.REMOVED, State.ERROR)).count(), 'maintenance_mode': item.provider.maintenance_mode, 'permission': perm } diff --git a/server/src/uds/REST/methods/system.py b/server/src/uds/REST/methods/system.py index 0e06e3651..245a41e8d 100644 --- a/server/src/uds/REST/methods/system.py +++ b/server/src/uds/REST/methods/system.py @@ -36,6 +36,7 @@ from uds.models import User, Service, UserService, DeployedService, getSqlDateti from uds.core.util.stats import counters from uds.core.util.Cache import Cache +from uds.core.util.State import State from uds.REST import Handler, RequestError, ResponseError import pickle from datetime import timedelta @@ -89,7 +90,7 @@ class System(Handler): if self._args[0] == 'overview': # System overview users = User.objects.count() services = Service.objects.count() - user_services = UserService.objects.count() + user_services = UserService.objects.exclude(state__in=(State.REMOVED, State.ERROR)).count() restrained_services_pools = len(DeployedService.getRestraineds()) return { 'users': users, diff --git a/server/src/uds/osmanagers/LinuxOsManager/LinuxOsManager.py b/server/src/uds/osmanagers/LinuxOsManager/LinuxOsManager.py index e527d610b..3e5df5d15 100644 --- a/server/src/uds/osmanagers/LinuxOsManager/LinuxOsManager.py +++ b/server/src/uds/osmanagers/LinuxOsManager/LinuxOsManager.py @@ -50,7 +50,7 @@ logger = logging.getLogger(__name__) class LinuxOsManager(osmanagers.OSManager): typeName = _('Linux OS Manager') typeType = 'LinuxManager' - typeDescription = _('Os Manager to control linux virtual machines (basically renames machine and notify state)') + typeDescription = _('Os Manager to control linux virtual machines') iconFile = 'losmanager.png' servicesType = (serviceTypes.VDI,) diff --git a/server/src/uds/osmanagers/WindowsOsManager/WinDomainOsManager.py b/server/src/uds/osmanagers/WindowsOsManager/WinDomainOsManager.py index ccee0f411..f29cde889 100644 --- a/server/src/uds/osmanagers/WindowsOsManager/WinDomainOsManager.py +++ b/server/src/uds/osmanagers/WindowsOsManager/WinDomainOsManager.py @@ -27,7 +27,7 @@ logger = logging.getLogger(__name__) class WinDomainOsManager(WindowsOsManager): typeName = _('Windows Domain OS Manager') typeType = 'WinDomainManager' - typeDescription = _('Os Manager to control windows machines with domain. (Basically renames machine)') + typeDescription = _('Os Manager to control windows machines with domain.') iconFile = 'wosmanager.png' # Apart form data from windows os manager, we need also domain and credentials diff --git a/server/src/uds/osmanagers/WindowsOsManager/WindowsOsManager.py b/server/src/uds/osmanagers/WindowsOsManager/WindowsOsManager.py index a162512fc..bda5e4caf 100644 --- a/server/src/uds/osmanagers/WindowsOsManager/WindowsOsManager.py +++ b/server/src/uds/osmanagers/WindowsOsManager/WindowsOsManager.py @@ -42,7 +42,7 @@ def scrambleMsg(data): class WindowsOsManager(osmanagers.OSManager): typeName = _('Windows Basic OS Manager') typeType = 'WindowsManager' - typeDescription = _('Os Manager to control windows machines without domain. (Basically renames machine)') + typeDescription = _('Os Manager to control windows machines without domain.') iconFile = 'wosmanager.png' servicesType = (serviceTypes.VDI,) diff --git a/server/src/uds/services/OVirt/OVirtLinkedService.py b/server/src/uds/services/OVirt/OVirtLinkedService.py index 1df03d9f6..827f4fcff 100644 --- a/server/src/uds/services/OVirt/OVirtLinkedService.py +++ b/server/src/uds/services/OVirt/OVirtLinkedService.py @@ -41,7 +41,7 @@ from uds.core.ui import gui import logging -__updated__ = '2016-09-11' +__updated__ = '2017-01-17' logger = logging.getLogger(__name__) @@ -99,8 +99,9 @@ class OVirtLinkedService(Service): servicesTypeProvided = (serviceTypes.VDI,) # Now the form part - machine = gui.ChoiceField(label=_("Base Machine"), order=1, tooltip=_('Service base machine'), required=True) - cluster = gui.ChoiceField(label=_("Cluster"), order=2, + cluster = gui.ChoiceField( + label=_("Cluster"), + order=100, fills={ 'callbackName': 'ovFillResourcesFromCluster', 'function': oVirtHelpers.getResources, @@ -112,7 +113,7 @@ class OVirtLinkedService(Service): datastore = gui.ChoiceField( label=_("Datastore Domain"), rdonly=False, - order=3, + order=101, tooltip=_('Datastore domain where to publish and put incrementals'), required=True ) @@ -121,18 +122,27 @@ class OVirtLinkedService(Service): length=3, label=_('Reserved Space'), defvalue='32', - order=4, + order=102, tooltip=_('Minimal free space in GB'), required=True ) + machine = gui.ChoiceField( + label=_("Base Machine"), + order=110, + tooltip=_('Service base machine'), + tab=_('Machine'), + required=True + ) + memory = gui.NumericField( label=_("Memory (Mb)"), length=4, defvalue=512, rdonly=False, - order=5, + order=111, tooltip=_('Memory assigned to machines'), + tab=_('Machine'), required=True ) @@ -141,16 +151,44 @@ class OVirtLinkedService(Service): length=4, defvalue=256, rdonly=False, - order=6, + order=112, tooltip=_('Physical memory guaranteed to machines'), + tab=_('Machine'), required=True ) + usb = gui.ChoiceField( + label=_('USB'), + rdonly=False, + order=113, + tooltip=_('Enable usb redirection for SPICE'), + values=[ + gui.choiceItem('disabled', 'disabled'), + gui.choiceItem('native', 'native'), + gui.choiceItem('legacy', 'legacy (deprecated)') + ], + tab=_('Machine'), + defvalue='1' # Default value is the ID of the choicefield + ) + + display = gui.ChoiceField( + label=_('Display'), + rdonly=False, + order=114, + tooltip=_('Display type (only for administration purposes)'), + values=[ + gui.choiceItem('spice', 'Spice'), + gui.choiceItem('vnc', 'Vnc') + ], + tab=_('Machine'), + defvalue='1' # Default value is the ID of the choicefield + ) baseName = gui.TextField( label=_('Machine Names'), rdonly=False, - order=6, + order=115, tooltip=('Base name for clones from this machine'), + tab=_('Machine'), required=True ) @@ -158,36 +196,12 @@ class OVirtLinkedService(Service): length=1, label=_('Name Length'), defvalue=5, - order=7, + order=116, tooltip=_('Size of numeric part for the names of these machines (between 3 and 6)'), + tab=_('Machine'), required=True ) - usb = gui.ChoiceField( - label=_('USB'), - rdonly=False, - order=9, - tooltip=_('Enable usb redirection for SPICE'), - values=[ - gui.choiceItem('disabled', 'disabled'), - gui.choiceItem('native', 'native'), - gui.choiceItem('legacy', 'legacy (deprecated)') - ], - defvalue='1' # Default value is the ID of the choicefield - ) - - display = gui.ChoiceField( - label=_('Display'), - rdonly=False, - order=9, - tooltip=_('Display type (only for administration purposes)'), - values=[ - gui.choiceItem('spice', 'Spice'), - gui.choiceItem('vnc', 'Vnc') - ], - defvalue='1' # Default value is the ID of the choicefield - ) - ov = gui.HiddenField(value=None) ev = gui.HiddenField(value=None) # We need to keep the env so we can instantiate the Provider diff --git a/server/src/uds/services/OpenNebula/LiveService.py b/server/src/uds/services/OpenNebula/LiveService.py index f66910641..05c0633ab 100644 --- a/server/src/uds/services/OpenNebula/LiveService.py +++ b/server/src/uds/services/OpenNebula/LiveService.py @@ -40,7 +40,7 @@ from uds.core.ui import gui import logging -__updated__ = '2016-11-23' +__updated__ = '2017-01-17' logger = logging.getLogger(__name__) @@ -92,14 +92,28 @@ class LiveService(Service): servicesTypeProvided = (serviceTypes.VDI,) # Now the form part - template = gui.ChoiceField(label=_("Base Template"), order=1, tooltip=_('Service base template'), required=True) - datastore = gui.ChoiceField(label=_("Datastore"), order=2, tooltip=_('Service clones datastore'), required=True) + datastore = gui.ChoiceField( + label=_("Datastore"), + order=100, + tooltip=_('Service clones datastore'), + required=True + ) + + template = gui.ChoiceField( + label=_("Base Template"), + order=110, + tooltip=_('Service base template'), + tab=_('Machine'), + required=True + ) + baseName = gui.TextField( label=_('Machine Names'), rdonly=False, - order=6, + order=111, tooltip=('Base name for clones from this machine'), + tab=_('Machine'), required=True ) @@ -107,8 +121,9 @@ class LiveService(Service): length=1, label=_('Name Length'), defvalue=5, - order=7, + order=112, tooltip=_('Size of numeric part for the names of these machines (between 3 and 6)'), + tab=_('Machine'), required=True ) diff --git a/server/src/uds/services/Xen/XenLinkedService.py b/server/src/uds/services/Xen/XenLinkedService.py index b1f82fe09..8f7c11a94 100644 --- a/server/src/uds/services/Xen/XenLinkedService.py +++ b/server/src/uds/services/Xen/XenLinkedService.py @@ -53,11 +53,11 @@ class XenLinkedService(Service): # : Name to show the administrator. This string will be translated BEFORE # : sending it to administration interface, so don't forget to # : mark it as _ (using ugettext_noop) - typeName = _('Xen Linked Clone (Experimental)') + typeName = _('Xen Linked Clone') # : Type used internally to identify this provider typeType = 'XenLinkedService' # : Description shown at administration interface for this provider - typeDescription = _('Xen Services based on templates (experimental)') + typeDescription = _('Xen Services based on templates') # : Icon file used as icon for this provider. This string will be translated # : BEFORE sending it to administration interface, so don't forget to # : mark it as _ (using ugettext_noop) @@ -99,26 +99,79 @@ class XenLinkedService(Service): # Now the form part - machine = gui.ChoiceField(label=_("Base Machine"), order=1, tooltip=_('Service base machine'), required=True) + datastore = gui.ChoiceField( + label=_("Storage SR"), + rdonly=False, + order=100, + tooltip=_('Storage where to publish and put incrementals'), + required=True + ) - datastore = gui.ChoiceField(label=_("Storage SR"), rdonly=False, order=3, - tooltip=_('Storage where to publish and put incrementals'), required=True) + minSpaceGB = gui.NumericField( + length=3, + label=_('Reserved Space'), + defvalue='32', + order=101, + tooltip=_('Minimal free space in GB'), + required=True + ) - network = gui.ChoiceField(label=_("Network"), rdonly=False, order=4, - tooltip=_('Network used for virtual machines'), required=True) + machine = gui.ChoiceField( + label=_("Base Machine"), + order=110, + tooltip=_('Service base machine'), + tab=_('Machine'), + required=True + ) - minSpaceGB = gui.NumericField(length=3, label=_('Reserved Space'), defvalue='32', order=5, tooltip=_('Minimal free space in GB'), required=True) + network = gui.ChoiceField( + label=_("Network"), + rdonly=False, + order=111, + tooltip=_('Network used for virtual machines'), + tab=_('Machine'), + required=True + ) - memory = gui.NumericField(label=_("Memory (Mb)"), length=4, defvalue=512, rdonly=False, order=6, - tooltip=_('Memory assigned to machines'), required=True) + memory = gui.NumericField( + label=_("Memory (Mb)"), + length=4, defvalue=512, + rdonly=False, + order=112, + tooltip=_('Memory assigned to machines'), + tab=_('Machine'), + required=True + ) - shadow = gui.NumericField(label=_("Shadow"), lengh=1, defvalue=4, rdonly=True, order=7, - tooltip=_('Shadow memory multiplier (memory overcommit)'), required=True) + shadow = gui.NumericField( + label=_("Shadow"), + length=1, + defvalue=4, + rdonly=False, + order=113, + tooltip=_('Shadow memory multiplier (memory overcommit)'), + tab=_('Machine'), + required=True + ) - baseName = gui.TextField(label=_('Machine Names'), rdonly=False, order=8, tooltip=('Base name for clones from this machine'), required=True) + baseName = gui.TextField( + label=_('Machine Names'), + rdonly=False, + order=114, + tooltip=('Base name for clones from this machine'), + tab=_('Machine'), + required=True + ) - lenName = gui.NumericField(length=1, label=_('Name Length'), defvalue=5, order=9, - tooltip=_('Length of numeric part for the names of this machines (beetwen 3 and 6'), required=True) + lenName = gui.NumericField( + length=1, + label=_('Name Length'), + defvalue=5, + order=115, + tooltip=_('Length of numeric part for the names of this machines (beetwen 3 and 6'), + tab=_('Machine'), + required=True + ) def initialize(self, values): ''' From 1d417c607581bd80c78bed6b2f27ae317e2730d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Thu, 19 Jan 2017 11:02:33 +0100 Subject: [PATCH 2/3] Removed pkill right now --- actors/.gitignore | 1 + actors/src/udsactor/linux/operations.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/actors/.gitignore b/actors/.gitignore index 3d772e261..df9471e2e 100644 --- a/actors/.gitignore +++ b/actors/.gitignore @@ -7,3 +7,4 @@ udsactor*.changes /udsactor_1.7.0.tar.xz /udsactor*.rpm /udsactor_2.1.0_amd64.buildinfo +linux/debian/files diff --git a/actors/src/udsactor/linux/operations.py b/actors/src/udsactor/linux/operations.py index 119e47d83..9441da895 100644 --- a/actors/src/udsactor/linux/operations.py +++ b/actors/src/udsactor/linux/operations.py @@ -156,7 +156,7 @@ def loggoff(): import threading threading._DummyThread._Thread__stop = lambda x: 42 - subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']]) + # subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']]) # subprocess.call(['/sbin/shutdown', 'now', '-r']) # subprocess.call(['/usr/bin/systemctl', 'reboot', '-i']) From c74045786042f9b18056d07e751e098aa8eb31d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Thu, 19 Jan 2017 12:46:22 +0100 Subject: [PATCH 3/3] Fixed doing "pkill" in correct session logout (only needs to do this on session timeout and persistent machines...) --- actors/linux/debian/changelog | 2 +- actors/linux/debian/udsactor.postinst | 1 + actors/src/UDSActorUser.py | 20 ++++++++++++++------ actors/src/udsactor/linux/operations.py | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/actors/linux/debian/changelog b/actors/linux/debian/changelog index 3ea9e0d1a..92aabdff9 100644 --- a/actors/linux/debian/changelog +++ b/actors/linux/debian/changelog @@ -2,7 +2,7 @@ udsactor (2.1.0) stable; urgency=medium * Fixes for 2.1.0 release - -- Adolfo Gómez García Tue, 11 Oct 2016 08:00:22 +0200 + -- Adolfo Gómez García Tue, 19 Jan 2017 08:00:22 +0200 udsactor (2.0.0) stable; urgency=medium diff --git a/actors/linux/debian/udsactor.postinst b/actors/linux/debian/udsactor.postinst index c846e7e49..c7e4a122c 100755 --- a/actors/linux/debian/udsactor.postinst +++ b/actors/linux/debian/udsactor.postinst @@ -5,6 +5,7 @@ set -e case "$1" in 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 [ "$2" = "" ] || [ ! -f /etc/udsactor/udsactor.cfg ]; then db_get udsactor/host diff --git a/actors/src/UDSActorUser.py b/actors/src/UDSActorUser.py index 6b50c84d8..b218fbd1b 100644 --- a/actors/src/UDSActorUser.py +++ b/actors/src/UDSActorUser.py @@ -51,6 +51,8 @@ from udsactor import VERSION trayIcon = None +doLogoff = False + def sigTerm(sigNo, stackFrame): if trayIcon: @@ -253,7 +255,7 @@ class UDSSystemTray(QtGui.QSystemTrayIcon): if remainingTime <= 0: logger.info('User has been idle for too long, notifying Broker that service can be reclaimed') - self.quit() + self.quit(logoff=True) def displayMessage(self, message): logger.debug('Displaying message') @@ -290,7 +292,8 @@ class UDSSystemTray(QtGui.QSystemTrayIcon): def about(self): self.aboutDlg.exec_() - def quit(self): + def quit(self, logoff=False): + global doLogoff logger.debug('Quit invoked') if self.stopped is False: self.stopped = True @@ -303,10 +306,7 @@ class UDSSystemTray(QtGui.QSystemTrayIcon): # May we have lost connection with server, simply exit in that case pass - try: - operations.loggoff() # Invoke log off - except Exception: - pass + doLogoff = logoff self.app.quit() @@ -339,4 +339,12 @@ if __name__ == '__main__': logger.debug('Exiting') trayIcon.quit() + if doLogoff: + try: + time.sleep(1) + operations.loggoff() # Invoke log off + except Exception: + pass + + sys.exit(res) diff --git a/actors/src/udsactor/linux/operations.py b/actors/src/udsactor/linux/operations.py index 9441da895..119e47d83 100644 --- a/actors/src/udsactor/linux/operations.py +++ b/actors/src/udsactor/linux/operations.py @@ -156,7 +156,7 @@ def loggoff(): import threading threading._DummyThread._Thread__stop = lambda x: 42 - # subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']]) + subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']]) # subprocess.call(['/sbin/shutdown', 'now', '-r']) # subprocess.call(['/usr/bin/systemctl', 'reboot', '-i'])