forked from shaba/openuds
Merge remote-tracking branch 'origin/v2.2'
This commit is contained in:
commit
83ad9141a8
@ -38,8 +38,7 @@ from .OVirtJobs import OVirtDeferredRemoval
|
||||
import pickle
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-03-22'
|
||||
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -185,6 +184,13 @@ class OVirtLinkedDeployment(UserDeployment):
|
||||
self.cache.put('ready', '1')
|
||||
return State.FINISHED
|
||||
|
||||
def reset(self):
|
||||
'''
|
||||
o oVirt, reset operation just shutdowns it until v3 support is removed
|
||||
'''
|
||||
if self._vmid != '':
|
||||
self.service().stopMachine(self._vmid)
|
||||
|
||||
def getConsoleConnection(self):
|
||||
return self.service().getConsoleConnection(self._vmid)
|
||||
|
||||
|
@ -41,7 +41,7 @@ from uds.core.ui import gui
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-11-07'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -88,6 +88,7 @@ class OVirtLinkedService(Service):
|
||||
# : If true, the system can't do an automatic assignation of a deployed user
|
||||
# : service from this service
|
||||
mustAssignManually = False
|
||||
canReset = True
|
||||
|
||||
# : Types of publications (preparated data for deploys)
|
||||
# : In our case, we do no need a publication, so this is None
|
||||
|
@ -39,8 +39,7 @@ from . import on
|
||||
import pickle
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-03-27'
|
||||
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -181,6 +180,10 @@ class LiveDeployment(UserDeployment):
|
||||
self.cache.put('ready', '1')
|
||||
return State.FINISHED
|
||||
|
||||
def reset(self):
|
||||
if self._vmid != '':
|
||||
self.service().resetMachine(self._vmid)
|
||||
|
||||
def getConsoleConnection(self):
|
||||
return self.service().getConsoleConnection(self._vmid)
|
||||
|
||||
|
@ -81,6 +81,7 @@ class LiveService(Service):
|
||||
# : If true, the system can't do an automatic assignation of a deployed user
|
||||
# : service from this service
|
||||
mustAssignManually = False
|
||||
canReset = True
|
||||
|
||||
# : Types of publications (preparated data for deploys)
|
||||
# : In our case, we do no need a publication, so this is None
|
||||
@ -111,7 +112,7 @@ class LiveService(Service):
|
||||
label=_('Machine Names'),
|
||||
rdonly=False,
|
||||
order=111,
|
||||
tooltip='Base name for clones from this machine',
|
||||
tooltip=_('Base name for clones from this machine'),
|
||||
tab=_('Machine'),
|
||||
required=True
|
||||
)
|
||||
@ -255,6 +256,9 @@ class LiveService(Service):
|
||||
"""
|
||||
return self.parent().suspendMachine(machineId)
|
||||
|
||||
def resetMachine(self, machineId):
|
||||
return self.parent().resetMachine(machineId)
|
||||
|
||||
def removeMachine(self, machineId):
|
||||
"""
|
||||
Tries to delete a machine. No check is done, it is simply requested to OpenNebula
|
||||
|
@ -43,17 +43,17 @@ from defusedxml import minidom
|
||||
from .LiveService import LiveService
|
||||
from . import on
|
||||
|
||||
|
||||
import logging
|
||||
import six
|
||||
|
||||
# Python bindings for OpenNebula
|
||||
# import oca
|
||||
|
||||
__updated__ = '2017-03-28'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Provider(ServiceProvider):
|
||||
"""
|
||||
This class represents the sample services provider
|
||||
@ -125,7 +125,6 @@ class Provider(ServiceProvider):
|
||||
def endpoint(self):
|
||||
return 'http{}://{}:{}/RPC2'.format('s' if self.ssl.isTrue() else '', self.host.value, self.port.value)
|
||||
|
||||
|
||||
@property
|
||||
def api(self):
|
||||
if self._api is None:
|
||||
@ -194,7 +193,6 @@ class Provider(ServiceProvider):
|
||||
"""
|
||||
return on.vm.getMachineSubstate(self.api, machineId)
|
||||
|
||||
|
||||
def startMachine(self, machineId):
|
||||
"""
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenNebula.
|
||||
@ -207,6 +205,7 @@ class Provider(ServiceProvider):
|
||||
Returns:
|
||||
"""
|
||||
on.vm.startMachine(self.api, machineId)
|
||||
return True
|
||||
|
||||
def stopMachine(self, machineId):
|
||||
"""
|
||||
@ -218,6 +217,7 @@ class Provider(ServiceProvider):
|
||||
Returns:
|
||||
"""
|
||||
on.vm.stopMachine(self.api, machineId)
|
||||
return True
|
||||
|
||||
def suspendMachine(self, machineId):
|
||||
"""
|
||||
@ -229,6 +229,13 @@ class Provider(ServiceProvider):
|
||||
Returns:
|
||||
"""
|
||||
on.vm.suspendMachine(self.api, machineId)
|
||||
return True
|
||||
|
||||
def resetMachine(self, machineId):
|
||||
'''
|
||||
Resets a machine (hard-reboot)
|
||||
'''
|
||||
on.vm.resetMachine(self.api, machineId)
|
||||
|
||||
def removeMachine(self, machineId):
|
||||
"""
|
||||
@ -240,6 +247,7 @@ class Provider(ServiceProvider):
|
||||
Returns:
|
||||
"""
|
||||
on.vm.removeMachine(self.api, machineId)
|
||||
return True
|
||||
|
||||
def getNetInfo(self, machineId, networkId=None):
|
||||
"""
|
||||
@ -263,7 +271,6 @@ class Provider(ServiceProvider):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def test(env, data):
|
||||
"""
|
||||
|
@ -27,9 +27,9 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
'''
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
'''
|
||||
|
||||
import logging
|
||||
import six
|
||||
@ -39,13 +39,13 @@ from defusedxml import minidom
|
||||
# Python bindings for OpenNebula
|
||||
from .common import VmState
|
||||
|
||||
__updated__ = '2017-03-28'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getMachineState(api, machineId):
|
||||
"""
|
||||
'''
|
||||
Returns the state of the machine
|
||||
This method do not uses cache at all (it always tries to get machine state from OpenNebula server)
|
||||
|
||||
@ -54,32 +54,32 @@ def getMachineState(api, machineId):
|
||||
|
||||
Returns:
|
||||
one of the on.VmState Values
|
||||
"""
|
||||
'''
|
||||
try:
|
||||
# vm = oca.VirtualMachine.new_with_id(api, int(machineId))
|
||||
# vm.info()
|
||||
# return vm.state
|
||||
return api.getVMState(machineId)
|
||||
except Exception as e:
|
||||
logger.error('Error obtaining machine state for {} on opennebula: {}'.format(machineId, e))
|
||||
logger.error('Error obtaining machine state for {} on OpenNebula: {}'.format(machineId, e))
|
||||
|
||||
return VmState.UNKNOWN
|
||||
|
||||
|
||||
def getMachineSubstate(api, machineId):
|
||||
"""
|
||||
'''
|
||||
Returns the lcm_state
|
||||
"""
|
||||
'''
|
||||
try:
|
||||
return api.getVMSubState(machineId)
|
||||
except Exception as e:
|
||||
logger.error('Error obtaining machine state for {} on opennebula: {}'.format(machineId, e))
|
||||
logger.error('Error obtaining machine state for {} on OpenNebula: {}'.format(machineId, e))
|
||||
|
||||
return VmState.UNKNOWN
|
||||
|
||||
|
||||
def startMachine(api, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenNebula.
|
||||
|
||||
This start also "resume" suspended/paused machines
|
||||
@ -88,63 +88,78 @@ def startMachine(api, machineId):
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
'''
|
||||
try:
|
||||
# vm = oca.VirtualMachine.new_with_id(api, int(machineId))
|
||||
# vm.resume()
|
||||
api.VMAction(machineId, 'resume')
|
||||
except Exception as e:
|
||||
# logger.error('Error obtaining machine state for {} on opennebula: {}'.format(machineId, e))
|
||||
# MAybe the machine is already running. If we get error here, simply ignore it for now...
|
||||
pass
|
||||
|
||||
def stopMachine(api, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenNebula
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
'''
|
||||
try:
|
||||
# vm = oca.VirtualMachine.new_with_id(api, int(machineId))
|
||||
# vm.poweroff_hard()
|
||||
api.VMAction(machineId, 'poweroff-hard')
|
||||
except Exception as e:
|
||||
logger.error('Error obtaining machine state for {} on opennebula: {}'.format(machineId, e))
|
||||
logger.error('Error powering off {} on OpenNebula: {}'.format(machineId, e))
|
||||
|
||||
|
||||
def suspendMachine(api, machineId):
|
||||
"""
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenNebula
|
||||
'''
|
||||
Tries to suspend a machine. No check is done, it is simply requested to OpenNebula
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
startMachine(api, machineId)
|
||||
'''
|
||||
try:
|
||||
api.VMAction(machineId, 'suspend')
|
||||
except Exception as e:
|
||||
logger.error('Error suspending {} on OpenNebula: {}'.format(machineId, e))
|
||||
|
||||
|
||||
def resetMachine(api, machineId):
|
||||
'''
|
||||
Tries to suspend a machine. No check is done, it is simply requested to OpenNebula
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
'''
|
||||
try:
|
||||
api.VMAction(machineId, 'reboot-hard')
|
||||
except Exception as e:
|
||||
logger.error('Error reseting {} on OpenNebula: {}'.format(machineId, e))
|
||||
|
||||
|
||||
def removeMachine(api, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to delete a machine. No check is done, it is simply requested to OpenNebula
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
'''
|
||||
try:
|
||||
# vm = oca.VirtualMachine.new_with_id(api, int(machineId))
|
||||
# vm.delete()
|
||||
api.deleteVM(machineId)
|
||||
except Exception as e:
|
||||
logger.exception('Error removing machine {} on opennebula: {}'.format(machineId, e))
|
||||
raise 'Error removing machine {} on opennebula: {}'.format(machineId, e)
|
||||
logger.exception('Error removing machine {} on OpenNebula: {}'.format(machineId, e))
|
||||
raise 'Error removing machine {} on OpenNebula: {}'.format(machineId, e)
|
||||
|
||||
|
||||
def enumerateMachines(api):
|
||||
"""
|
||||
'''
|
||||
Obtains the list of machines inside OpenNebula.
|
||||
Machines starting with UDS are filtered out
|
||||
|
||||
@ -157,14 +172,14 @@ def enumerateMachines(api):
|
||||
'name'
|
||||
'id'
|
||||
'cluster_id'
|
||||
"""
|
||||
'''
|
||||
return api.enumVMs()
|
||||
|
||||
|
||||
def getNetInfo(api, machineId, networkId=None):
|
||||
"""
|
||||
'''
|
||||
Changes the mac address of first nic of the machine to the one specified
|
||||
"""
|
||||
'''
|
||||
# md = minidom.parseString(api.call('vm.info', int(machineId)))
|
||||
md = minidom.parseString(api.VMInfo(machineId)[1])
|
||||
node = md
|
||||
@ -187,16 +202,15 @@ def getNetInfo(api, machineId, networkId=None):
|
||||
except Exception:
|
||||
ip = ''
|
||||
|
||||
return node.getElementsByTagName('MAC')[0].childNodes[0].data, ip
|
||||
return (node.getElementsByTagName('MAC')[0].childNodes[0].data, ip)
|
||||
except Exception:
|
||||
raise Exception('No network interface found on template. Please, add a network and republish.')
|
||||
|
||||
|
||||
def getDisplayConnection(api, machineId):
|
||||
"""
|
||||
'''
|
||||
If machine is not running or there is not a display, will return NONE
|
||||
SPICE connections should check that 'type' is 'SPICE'
|
||||
"""
|
||||
'''
|
||||
md = minidom.parseString(api.VMInfo(machineId)[1])
|
||||
try:
|
||||
graphics = md.getElementsByTagName('GRAPHICS')[0]
|
||||
@ -219,8 +233,6 @@ def getDisplayConnection(api, machineId):
|
||||
except Exception:
|
||||
return None # No SPICE connection
|
||||
|
||||
|
||||
|
||||
# Sample NIC Content (there will be as much as nics)
|
||||
# <NIC>
|
||||
# <BRIDGE><![CDATA[br0]]></BRIDGE>
|
||||
@ -235,5 +247,3 @@ def getDisplayConnection(api, machineId):
|
||||
# <VLAN><![CDATA[NO]]></VLAN>
|
||||
# </NIC>
|
||||
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ from . import openStack
|
||||
import pickle
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-11-21'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -190,6 +190,10 @@ class LiveDeployment(UserDeployment):
|
||||
self.cache.put('ready', '1')
|
||||
return State.FINISHED
|
||||
|
||||
def reset(self):
|
||||
if self._vmid != '':
|
||||
self.service().resetMachine(self._vmid)
|
||||
|
||||
def getConsoleConnection(self):
|
||||
return self.service().getConsoleConnection(self._vmid)
|
||||
|
||||
|
@ -27,9 +27,9 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
'''
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
'''
|
||||
from django.utils.translation import ugettext_noop as _, ugettext
|
||||
from uds.core.transports import protocols
|
||||
from uds.core.services import Service, types as serviceTypes
|
||||
@ -42,15 +42,15 @@ from uds.core.ui import gui
|
||||
import six
|
||||
import logging
|
||||
|
||||
__updated__ = '2017-05-16'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LiveService(Service):
|
||||
"""
|
||||
'''
|
||||
OpenStack Live 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)
|
||||
@ -85,6 +85,7 @@ class LiveService(Service):
|
||||
# : If true, the system can't do an automatic assignation of a deployed user
|
||||
# : service from this service
|
||||
mustAssignManually = False
|
||||
canReset = True
|
||||
|
||||
# : Types of publications (preparated data for deploys)
|
||||
# : In our case, we do no need a publication, so this is None
|
||||
@ -143,12 +144,12 @@ class LiveService(Service):
|
||||
ev = gui.HiddenField(value=None) # We need to keep the env so we can instantiate the Provider
|
||||
|
||||
def initialize(self, values):
|
||||
"""
|
||||
'''
|
||||
We check here form values to see if they are valid.
|
||||
|
||||
Note that we check them through FROM variables, that already has been
|
||||
initialized by __init__ method of base class, before invoking this.
|
||||
"""
|
||||
'''
|
||||
if values is not None:
|
||||
length = int(self.lenName.value)
|
||||
if len(self.baseName.value) + length > 15:
|
||||
@ -161,11 +162,10 @@ class LiveService(Service):
|
||||
|
||||
self._api = None
|
||||
|
||||
|
||||
def initGui(self):
|
||||
"""
|
||||
'''
|
||||
Loads required values inside
|
||||
"""
|
||||
'''
|
||||
api = self.parent().api()
|
||||
regions = [gui.choiceItem(r['id'], r['id']) for r in api.listRegions()]
|
||||
self.region.setValues(regions)
|
||||
@ -198,13 +198,13 @@ class LiveService(Service):
|
||||
return self.api.createVolumeSnapshot(self.volume.value, templateName, description)
|
||||
|
||||
def getTemplate(self, snapshotId):
|
||||
"""
|
||||
'''
|
||||
Checks current state of a template (an snapshot)
|
||||
"""
|
||||
'''
|
||||
return self.api.getSnapshot(snapshotId)
|
||||
|
||||
def deployFromTemplate(self, name, snapshotId):
|
||||
"""
|
||||
'''
|
||||
Deploys a virtual machine on selected cluster from selected template
|
||||
|
||||
Args:
|
||||
@ -214,7 +214,7 @@ class LiveService(Service):
|
||||
|
||||
Returns:
|
||||
Id of the machine being created form template
|
||||
"""
|
||||
'''
|
||||
logger.debug('Deploying from template {0} machine {1}'.format(snapshotId, name))
|
||||
# self.datastoreHasSpace()
|
||||
return self.api.createServerFromSnapshot(snapshotId=snapshotId,
|
||||
@ -225,13 +225,13 @@ class LiveService(Service):
|
||||
securityGroupsIdsList=self.securityGroups.value)['id']
|
||||
|
||||
def removeTemplate(self, templateId):
|
||||
"""
|
||||
'''
|
||||
invokes removeTemplate from parent provider
|
||||
"""
|
||||
'''
|
||||
self.api.deleteSnapshot(templateId)
|
||||
|
||||
def getMachineState(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Invokes getServer from openstack client
|
||||
|
||||
Args:
|
||||
@ -256,11 +256,11 @@ class LiveService(Service):
|
||||
STOPPED. The server is powered off and the disk image still persists.
|
||||
SUSPENDED. The server is suspended, either by request or necessity. This status appears for only the XenServer/XCP, KVM, and ESXi hypervisors. Administrative users can suspend an instance if it is infrequently used or to perform system maintenance. When you suspend an instance, its VM state is stored on disk, all memory is written to disk, and the virtual machine is stopped. Suspending an instance is similar to placing a device in hibernation; memory and vCPUs become available to create other instances.
|
||||
VERIFY_RESIZE. System is awaiting confirmation that the server is operational after a move or resize.
|
||||
"""
|
||||
'''
|
||||
return self.api.getServer(machineId)['status']
|
||||
|
||||
def startMachine(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenStack.
|
||||
|
||||
This start also "resume" suspended/paused machines
|
||||
@ -269,70 +269,80 @@ class LiveService(Service):
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
return self.api.startServer(machineId)
|
||||
'''
|
||||
self.api.startServer(machineId)
|
||||
|
||||
def stopMachine(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to stop a machine. No check is done, it is simply requested to OpenStack
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
return self.api.stopServer(machineId)
|
||||
'''
|
||||
self.api.stopServer(machineId)
|
||||
|
||||
def resetMachine(self, machineId):
|
||||
'''
|
||||
Tries to stop a machine. No check is done, it is simply requested to OpenStack
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
'''
|
||||
self.api.resetServer(machineId)
|
||||
|
||||
def suspendMachine(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to suspend a machine. No check is done, it is simply requested to OpenStack
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
return self.api.suspendServer(machineId)
|
||||
'''
|
||||
self.api.suspendServer(machineId)
|
||||
|
||||
def resumeMachine(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to start a machine. No check is done, it is simply requested to OpenStack
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
return self.api.suspendServer(machineId)
|
||||
|
||||
'''
|
||||
self.api.resumeServer(machineId)
|
||||
|
||||
def removeMachine(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Tries to delete a machine. No check is done, it is simply requested to OpenStack
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
"""
|
||||
return self.api.deleteServer(machineId)
|
||||
'''
|
||||
self.api.deleteServer(machineId)
|
||||
|
||||
def getNetInfo(self, machineId):
|
||||
"""
|
||||
'''
|
||||
Gets the mac address of first nic of the machine
|
||||
"""
|
||||
'''
|
||||
net = self.api.getServer(machineId)['addresses']
|
||||
vals = six.next(six.itervalues(net))[0] # Returns "any" mac address of any interface. We just need only one interface info
|
||||
return vals['OS-EXT-IPS-MAC:mac_addr'].upper(), vals['addr']
|
||||
return (vals['OS-EXT-IPS-MAC:mac_addr'].upper(), vals['addr'])
|
||||
|
||||
def getBaseName(self):
|
||||
"""
|
||||
'''
|
||||
Returns the base name
|
||||
"""
|
||||
'''
|
||||
return self.baseName.value
|
||||
|
||||
def getLenName(self):
|
||||
"""
|
||||
'''
|
||||
Returns the length of numbers part
|
||||
"""
|
||||
'''
|
||||
return int(self.lenName.value)
|
||||
|
@ -39,7 +39,7 @@ import json
|
||||
import dateutil.parser
|
||||
import six
|
||||
|
||||
__updated__ = '2018-03-02'
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -519,6 +519,17 @@ class Client(object):
|
||||
|
||||
ensureResponseIsValid(r, 'Resuming server')
|
||||
|
||||
@authProjectRequired
|
||||
def resetServer(self, serverId):
|
||||
r = requests.post(self._getEndpointFor('compute') + '/servers/{server_id}/action'.format(server_id=serverId),
|
||||
data='{"reboot":{"type":"HARD"}}',
|
||||
headers=self._requestHeaders(),
|
||||
verify=VERIFY_SSL,
|
||||
timeout=self._timeout)
|
||||
|
||||
# Ignore response for this...
|
||||
# ensureResponseIsValid(r, 'Reseting server')
|
||||
|
||||
def testConnection(self):
|
||||
# First, ensure requested api is supported
|
||||
# We need api version 3.2 or greater
|
||||
|
@ -197,6 +197,10 @@ class XenLinkedDeployment(UserDeployment):
|
||||
|
||||
return State.FINISHED
|
||||
|
||||
def reset(self):
|
||||
if self._vmid != '':
|
||||
self.service().resetVM(self._vmid) # Reset in sync
|
||||
|
||||
def notifyReadyFromOsManager(self, data):
|
||||
# Here we will check for suspending the VM (when full ready)
|
||||
logger.debug('Checking if cache 2 for {0}'.format(self._name))
|
||||
|
@ -88,6 +88,7 @@ class XenLinkedService(Service):
|
||||
# : If true, the system can't do an automatic assignation of a deployed user
|
||||
# : service from this service
|
||||
mustAssignManually = False
|
||||
canReset = True
|
||||
|
||||
# : Types of publications (preparated data for deploys)
|
||||
# : In our case, we do no need a publication, so this is None
|
||||
@ -97,7 +98,6 @@ class XenLinkedService(Service):
|
||||
|
||||
servicesTypeProvided = (serviceTypes.VDI,)
|
||||
|
||||
|
||||
# Now the form part
|
||||
datastore = gui.ChoiceField(
|
||||
label=_("Storage SR"),
|
||||
@ -216,12 +216,9 @@ class XenLinkedService(Service):
|
||||
self.datastore.setValues(storages_list)
|
||||
self.network.setValues(network_list)
|
||||
|
||||
|
||||
|
||||
def checkTaskFinished(self, task):
|
||||
return self.parent().checkTaskFinished(task)
|
||||
|
||||
|
||||
def datastoreHasSpace(self):
|
||||
# Get storages for that datacenter
|
||||
logger.debug('Checking datastore space for {0}'.format(self.datastore.value))
|
||||
@ -237,7 +234,6 @@ class XenLinkedService(Service):
|
||||
"""
|
||||
return name
|
||||
|
||||
|
||||
def startDeployTemplate(self, name, comments):
|
||||
"""
|
||||
Invokes makeTemplate from parent provider, completing params
|
||||
@ -325,6 +321,17 @@ class XenLinkedService(Service):
|
||||
"""
|
||||
return self.parent().stopVM(machineId, async)
|
||||
|
||||
def resetVM(self, machineId, async=True):
|
||||
'''
|
||||
Tries to stop a machine. No check is done, it is simply requested to Xen
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
'''
|
||||
return self.parent().resetVM(machineId, async)
|
||||
|
||||
def canSuspendVM(self, machineId):
|
||||
"""
|
||||
The machine can be suspended only when "suspend" is in their operations list (mush have xentools installed)
|
||||
@ -359,7 +366,6 @@ class XenLinkedService(Service):
|
||||
"""
|
||||
return self.parent().suspendVM(machineId, async)
|
||||
|
||||
|
||||
def removeVM(self, machineId):
|
||||
"""
|
||||
Tries to delete a machine. No check is done, it is simply requested to Xen
|
||||
|
@ -49,8 +49,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2017-03-06'
|
||||
|
||||
__updated__ = '2018-03-16'
|
||||
|
||||
CACHE_TIME_FOR_SERVER = 1800
|
||||
|
||||
@ -318,6 +317,17 @@ class Provider(ServiceProvider):
|
||||
"""
|
||||
return self.__getApi().stopVM(machineId, async)
|
||||
|
||||
def resetVM(self, machineId, async=True):
|
||||
'''
|
||||
Tries to start a machine. No check is done, it is simply requested to XenServer
|
||||
|
||||
Args:
|
||||
machineId: Id of the machine
|
||||
|
||||
Returns:
|
||||
'''
|
||||
return self.__getApi().resetVM(machineId, async)
|
||||
|
||||
def canSuspendVM(self, machineId):
|
||||
"""
|
||||
The machine can be suspended only when "suspend" is in their operations list (mush have xentools installed)
|
||||
|
@ -88,6 +88,7 @@ class XenFailure(XenAPI.Failure, XenFault):
|
||||
|
||||
|
||||
class XenException(XenFault):
|
||||
|
||||
def __init__(self, message):
|
||||
XenFault.__init__(self, message)
|
||||
logger.debug('Exception create: {0}'.format(message))
|
||||
@ -101,6 +102,7 @@ class XenPowerState(object):
|
||||
|
||||
|
||||
class XenServer(object):
|
||||
|
||||
def __init__(self, host, port, username, password, useSSL=False, verifySSL=False):
|
||||
self._originalHost = self._host = host
|
||||
self._port = six.text_type(port)
|
||||
@ -331,6 +333,14 @@ class XenServer(object):
|
||||
return self.Async.VM.hard_shutdown(vmId)
|
||||
return self.VM.hard_shutdown(vmId)
|
||||
|
||||
def resetVM(self, vmId, async=True):
|
||||
vmState = self.getVMPowerState(vmId)
|
||||
if vmState in (XenPowerState.suspended, XenPowerState.halted):
|
||||
return None # Already powered off
|
||||
if async:
|
||||
return self.Async.VM.hard_reboot(vmId)
|
||||
return self.VM.hard_reboot(vmId)
|
||||
|
||||
def canSuspendVM(self, vmId):
|
||||
operations = self.VM.get_allowed_operations(vmId)
|
||||
logger.debug('Operations: {}'.format(operations))
|
||||
|
@ -42,7 +42,7 @@
|
||||
<img {% if ser.name != ser.visual_name %}class="with-tooltip" data-content="{{ser.name|capfirst}}"{% endif %} class="se-agranda" src="{% url "uds.web.views.serviceImage" idImage=ser.imageId %}" />
|
||||
</div>
|
||||
<span {% if ser.show_transports and numTransports > 1 %} style="width: 130px;"{% endif %}>{{ ser.visual_name|capfirst|truncatechars:16 }}</span>
|
||||
{% if ser.show_transports and numTransports > 1 or ser.allow_users_remove %}
|
||||
{% if ser.show_transports and numTransports > 1 or ser.allow_users_remove or ser.allow_users_reset %}
|
||||
<span class="gear">
|
||||
{% if ser.show_transports and numTransports > 1 %}
|
||||
<span class="connection fa fa-gear"> </span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user