From f78c755f12e23ab48decb2f087bc4c4dc5a90537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Mon, 6 Mar 2017 14:17:07 +0100 Subject: [PATCH] Several fixes for XenServer and L2 Cache... --- .../uds/services/Xen/XenLinkedDeployment.py | 21 ++++++++++++++++--- .../src/uds/services/Xen/XenLinkedService.py | 12 +++++++++++ server/src/uds/services/Xen/XenProvider.py | 12 +++++++++++ .../uds/services/Xen/xen_client/__init__.py | 11 ++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/server/src/uds/services/Xen/XenLinkedDeployment.py b/server/src/uds/services/Xen/XenLinkedDeployment.py index 19e00ef1..8edce115 100644 --- a/server/src/uds/services/Xen/XenLinkedDeployment.py +++ b/server/src/uds/services/Xen/XenLinkedDeployment.py @@ -42,7 +42,7 @@ import logging logger = logging.getLogger(__name__) -opCreate, opStart, opStop, opSuspend, opRemove, opWait, opError, opFinish, opRetry, opConfigure, opProvision = range(11) +opCreate, opStart, opStop, opSuspend, opRemove, opWait, opError, opFinish, opRetry, opConfigure, opProvision, opWaitSuspend = range(12) NO_MORE_NAMES = 'NO-NAME-ERROR' @@ -211,7 +211,7 @@ class XenLinkedDeployment(UserDeployment): if forLevel2 is False: self._queue = [opCreate, opConfigure, opProvision, opStart, opFinish] else: - self._queue = [opCreate, opConfigure, opProvision, opStart, opWait, opSuspend, opFinish] + self._queue = [opCreate, opConfigure, opProvision, opStart, opWait, opWaitSuspend, opSuspend, opFinish] def __getCurrentOp(self): if len(self._queue) == 0: @@ -247,7 +247,7 @@ class XenLinkedDeployment(UserDeployment): state = self.service().getVMPowerState(self._vmid) if state in (XenPowerState.running, XenPowerState.paused, XenPowerState.suspended): self.service().stopVM(self._vmid, False) # In sync mode - # TODO Remove machine + self.service().removeVM(self._vmid) except: logger.debug('Can\t set machine state to stopped') @@ -270,6 +270,7 @@ class XenLinkedDeployment(UserDeployment): opRetry: self.__retry, opStart: self.__startMachine, opStop: self.__stopMachine, + opWaitSuspend: self.__waitSuspend, opSuspend: self.__suspendMachine, opWait: self.__wait, opRemove: self.__remove, @@ -357,6 +358,12 @@ class XenLinkedDeployment(UserDeployment): else: self._task = '' + def __waitSuspend(self): + ''' + Before suspending, wait for machine to have the SUSPEND feature + ''' + self.task = '' + def __suspendMachine(self): ''' Suspends the machine @@ -408,6 +415,12 @@ class XenLinkedDeployment(UserDeployment): return State.FINISHED return State.RUNNING + def __checkWaitSuspend(self): + if self.service().canSuspendVM(self._vmid) is True: + return State.FINISHED + + return State.RUNNING + def __checkSuspend(self): ''' Check if the machine has suspended @@ -452,6 +465,7 @@ class XenLinkedDeployment(UserDeployment): opWait: self.__wait, opStart: self.__checkStart, opStop: self.__checkStop, + opWaitSuspend: self.__checkWaitSuspend, opSuspend: self.__checkSuspend, opRemove: self.__checkRemoved, opConfigure: self.__checkConfigure, @@ -570,6 +584,7 @@ class XenLinkedDeployment(UserDeployment): opCreate: 'create', opStart: 'start', opStop: 'stop', + opWaitSuspend: 'wait-suspend', opSuspend: 'suspend', opRemove: 'remove', opWait: 'wait', diff --git a/server/src/uds/services/Xen/XenLinkedService.py b/server/src/uds/services/Xen/XenLinkedService.py index 8f7c11a9..e8a911b1 100644 --- a/server/src/uds/services/Xen/XenLinkedService.py +++ b/server/src/uds/services/Xen/XenLinkedService.py @@ -325,6 +325,18 @@ class XenLinkedService(Service): ''' return self.parent().stopVM(machineId, async) + def canSuspendVM(self, machineId): + ''' + The machine can be suspended only when "suspend" is in their operations list (mush have xentools installed) + + Args: + machineId: Id of the machine + + Returns: + True if the machien can be suspended + ''' + return self.parent().canSuspendVM(machineId) + def suspendVM(self, machineId, async=True): ''' Tries to suspend a machine. No check is done, it is simply requested to Xen diff --git a/server/src/uds/services/Xen/XenProvider.py b/server/src/uds/services/Xen/XenProvider.py index da9cbb6e..4a6f907a 100644 --- a/server/src/uds/services/Xen/XenProvider.py +++ b/server/src/uds/services/Xen/XenProvider.py @@ -320,6 +320,18 @@ class Provider(ServiceProvider): ''' return self.__getApi().stopVM(machineId, async) + def canSuspendVM(self, machineId): + ''' + The machine can be suspended only when "suspend" is in their operations list (mush have xentools installed) + + Args: + machineId: Id of the machine + + Returns: + True if the machien can be suspended + ''' + return self.__getApi().canSuspendVM(machineId) + def suspendVM(self, machineId, async=True): ''' Tries to start a machine. No check is done, it is simply requested to XenServer diff --git a/server/src/uds/services/Xen/xen_client/__init__.py b/server/src/uds/services/Xen/xen_client/__init__.py index 39403bce..97904b8a 100644 --- a/server/src/uds/services/Xen/xen_client/__init__.py +++ b/server/src/uds/services/Xen/xen_client/__init__.py @@ -51,6 +51,7 @@ class XenFailure(XenAPI.Failure, XenFault): exHandleInvalid = 'HANDLE_INVALID' exHostIsSlave = 'HOST_IS_SLAVE' exSRError = 'SR_BACKEND_FAILURE_44' + exHandleInvalid = 'HANDLE_INVALID' def __init__(self, details=None): details = [] if details is None else details @@ -76,6 +77,7 @@ class XenFailure(XenAPI.Failure, XenFault): XenFailure.exHandleInvalid: 'Invalid handler', XenFailure.exHostIsSlave: 'The connected host is an slave, try to connect to {1}', XenFailure.exSRError: 'Error on SR: {2}', + XenFailure.exHandleInvalid: 'Invalid reference to {1}', } err = errList.get(self.details[0], 'Error {0}') @@ -315,6 +317,10 @@ class XenServer(object): vmState = self.getVMPowerState(vmId) if vmState == XenPowerState.running: return None # Already powered on + + if vmState == XenPowerState.suspended: + return self.resumeVM(vmId, async) + if async: return self.Async.VM.start(vmId, False, False) return self.VM.start(vmId, False, False) @@ -327,6 +333,11 @@ class XenServer(object): return self.Async.VM.hard_shutdown(vmId) return self.VM.hard_shutdown(vmId) + def canSuspendVM(self, vmId): + operations = self.VM.get_allowed_operations(vmId) + logger.debug('Operations: {}'.format(operations)) + return 'suspend' in operations + def suspendVM(self, vmId, async=True): vmState = self.getVMPowerState(vmId) if vmState == XenPowerState.suspended: