forked from shaba/openuds
Fixed opennebula provider for python 3.7 && updated setting to nonpersistant (moved to end of image clone process)
This commit is contained in:
parent
7d66d92f85
commit
54110f5425
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,16 +30,16 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import pickle
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from uds.core.services import UserDeployment
|
||||
from uds.core.util.State import State
|
||||
from uds.core.util import log
|
||||
|
||||
from . import on
|
||||
|
||||
import pickle
|
||||
import logging
|
||||
|
||||
__updated__ = '2019-02-07'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -47,7 +47,6 @@ opCreate, opStart, opSuspend, opRemove, opWait, opError, opFinish, opRetry = ran
|
||||
|
||||
NO_MORE_NAMES = 'NO-NAME-ERROR'
|
||||
|
||||
|
||||
class LiveDeployment(UserDeployment):
|
||||
"""
|
||||
This class generates the user consumable elements of the service tree.
|
||||
@ -59,10 +58,18 @@ class LiveDeployment(UserDeployment):
|
||||
The logic for managing ovirt deployments (user machines in this case) is here.
|
||||
|
||||
"""
|
||||
|
||||
# : Recheck every six seconds by default (for task methods)
|
||||
suggestedTime = 6
|
||||
|
||||
#
|
||||
_name = ''
|
||||
_ip = ''
|
||||
_mac = ''
|
||||
_vmid = ''
|
||||
_reason = ''
|
||||
_queue: typing.List[int] = []
|
||||
|
||||
|
||||
def initialize(self):
|
||||
self._name = ''
|
||||
self._ip = ''
|
||||
@ -86,11 +93,11 @@ class LiveDeployment(UserDeployment):
|
||||
pickle.dumps(self._queue, protocol=0)
|
||||
])
|
||||
|
||||
def unmarshal(self, str_):
|
||||
def unmarshal(self, data):
|
||||
"""
|
||||
Does nothing here also, all data are keeped at environment storage
|
||||
"""
|
||||
vals = str_.split(b'\1')
|
||||
vals = data.split(b'\1')
|
||||
if vals[0] == b'v1':
|
||||
self._name = vals[1].decode('utf8')
|
||||
self._ip = vals[2].decode('utf8')
|
||||
@ -139,7 +146,7 @@ class LiveDeployment(UserDeployment):
|
||||
:note: This IP is the IP of the "consumed service", so the transport can
|
||||
access it.
|
||||
"""
|
||||
logger.debug('Setting IP to {}'.format(ip))
|
||||
logger.debug('Setting IP to %s', ip)
|
||||
self._ip = ip
|
||||
|
||||
def getUniqueId(self):
|
||||
@ -204,7 +211,7 @@ class LiveDeployment(UserDeployment):
|
||||
|
||||
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))
|
||||
logger.debug('Checking if cache 2 for %s', self._name)
|
||||
if self.__getCurrentOp() == opWait:
|
||||
logger.debug('Machine is ready. Moving to level 2')
|
||||
self.__popCurrentOp() # Remove current state
|
||||
@ -235,7 +242,7 @@ class LiveDeployment(UserDeployment):
|
||||
self._queue = [opCreate, opStart, opWait, opSuspend, opFinish]
|
||||
|
||||
def __checkMachineState(self, chkState):
|
||||
logger.debug('Checking that state of machine {} ({}) is {}'.format(self._vmid, self._name, chkState))
|
||||
logger.debug('Checking that state of machine %s (%s) is %s', self._vmid, self._name, chkState)
|
||||
state = self.service().getMachineState(self._vmid)
|
||||
|
||||
# If we want to check an state and machine does not exists (except in case that we whant to check this)
|
||||
@ -254,13 +261,13 @@ class LiveDeployment(UserDeployment):
|
||||
return ret
|
||||
|
||||
def __getCurrentOp(self):
|
||||
if len(self._queue) == 0:
|
||||
if not self._queue:
|
||||
return opFinish
|
||||
|
||||
return self._queue[0]
|
||||
|
||||
def __popCurrentOp(self):
|
||||
if len(self._queue) == 0:
|
||||
if not self._queue:
|
||||
return opFinish
|
||||
|
||||
res = self._queue.pop(0)
|
||||
@ -279,14 +286,14 @@ class LiveDeployment(UserDeployment):
|
||||
Returns:
|
||||
State.ERROR, so we can do "return self.__error(reason)"
|
||||
"""
|
||||
logger.debug('Setting error state, reason: {0}'.format(reason))
|
||||
logger.debug('Setting error state, reason: %s', reason)
|
||||
self.doLog(log.ERROR, reason)
|
||||
|
||||
if self._vmid != '': # Powers off & delete it
|
||||
try:
|
||||
self.service().removeMachine(self._vmid)
|
||||
except:
|
||||
logger.debug('Can\t set machine state to stopped')
|
||||
except Exception:
|
||||
logger.debug('Can\'t set machine state to stopped')
|
||||
|
||||
self._queue = [opError]
|
||||
self._reason = str(reason)
|
||||
@ -371,7 +378,7 @@ class LiveDeployment(UserDeployment):
|
||||
if state == on.VmState.ACTIVE: # @UndefinedVariable
|
||||
subState = self.service().getMachineSubstate(self._vmid)
|
||||
if subState < 3: # Less than running
|
||||
logger.info('Must wait before remove: {}'.format(subState))
|
||||
logger.info('Must wait before remove: %s', subState)
|
||||
self.__pushFrontOp(opRetry)
|
||||
return
|
||||
|
||||
@ -457,7 +464,6 @@ class LiveDeployment(UserDeployment):
|
||||
(No matter wether it is for cache or for an user)
|
||||
"""
|
||||
self.__debug('finish')
|
||||
pass
|
||||
|
||||
def moveToCache(self, newLevel):
|
||||
"""
|
||||
@ -529,8 +535,8 @@ class LiveDeployment(UserDeployment):
|
||||
}.get(op, '????')
|
||||
|
||||
def __debug(self, txt):
|
||||
logger.debug('_name {0}: {1}'.format(txt, self._name))
|
||||
logger.debug('_ip {0}: {1}'.format(txt, self._ip))
|
||||
logger.debug('_mac {0}: {1}'.format(txt, self._mac))
|
||||
logger.debug('_vmid {0}: {1}'.format(txt, self._vmid))
|
||||
logger.debug('Queue at {0}: {1}'.format(txt, [LiveDeployment.__op2str(op) for op in self._queue]))
|
||||
logger.debug('_name %s: %s', txt, self._name)
|
||||
logger.debug('_ip %s: %s', txt, self._ip)
|
||||
logger.debug('_mac %s: %s', txt, self._mac)
|
||||
logger.debug('_vmid %s: %s', txt, self._vmid)
|
||||
logger.debug('Queue at %s: %s', txt, [LiveDeployment.__op2str(op) for op in self._queue])
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,16 +30,11 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from uds.core.services import Publication
|
||||
from uds.core.util.State import State
|
||||
|
||||
import six
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2019-02-07'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -51,6 +46,11 @@ class LivePublication(Publication):
|
||||
|
||||
suggestedTime = 2 # : Suggested recheck time if publication is unfinished in seconds
|
||||
|
||||
_name = ''
|
||||
_reason = ''
|
||||
_templateId = ''
|
||||
_state = ''
|
||||
|
||||
def initialize(self):
|
||||
"""
|
||||
This method will be invoked by default __init__ of base class, so it gives
|
||||
@ -76,7 +76,7 @@ class LivePublication(Publication):
|
||||
"""
|
||||
deserializes the data and loads it inside instance.
|
||||
"""
|
||||
logger.debug('Data: {0}'.format(data))
|
||||
logger.debug('Data: %s', data)
|
||||
vals = data.decode('utf8').split('\t')
|
||||
if vals[0] == 'v1':
|
||||
self._name, self._reason, self._templateId, self._state = vals[1:]
|
||||
@ -93,7 +93,7 @@ class LivePublication(Publication):
|
||||
self._templateId = self.service().makeTemplate(self._name)
|
||||
except Exception as e:
|
||||
self._state = 'error'
|
||||
self._reason = six.text_type(e)
|
||||
self._reason = str(e)
|
||||
return State.ERROR
|
||||
|
||||
return State.RUNNING
|
||||
@ -109,7 +109,7 @@ class LivePublication(Publication):
|
||||
self._state = 'ok'
|
||||
except Exception as e:
|
||||
self._state = 'error'
|
||||
self._reason = six.text_type(e)
|
||||
self._reason = str(e)
|
||||
|
||||
if self._state == 'error':
|
||||
return State.ERROR
|
||||
@ -124,7 +124,6 @@ class LivePublication(Publication):
|
||||
"""
|
||||
In our case, finish does nothing
|
||||
"""
|
||||
pass
|
||||
|
||||
def reasonOfError(self):
|
||||
"""
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,17 +30,16 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from django.utils.translation import ugettext_noop as _, ugettext
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core.transports import protocols
|
||||
from uds.core.services import Service, types as serviceTypes
|
||||
from uds.core.ui import gui
|
||||
|
||||
from .LivePublication import LivePublication
|
||||
from .LiveDeployment import LiveDeployment
|
||||
|
||||
from uds.core.ui import gui
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2018-08-20'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -186,7 +185,7 @@ class LiveService(Service):
|
||||
Returns:
|
||||
Id of the machine being created form template
|
||||
"""
|
||||
logger.debug('Deploying from template {0} machine {1}'.format(templateId, name))
|
||||
logger.debug('Deploying from template %s machine %s', templateId, name)
|
||||
# self.datastoreHasSpace()
|
||||
return self.parent().deployFromTemplate(name, templateId)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,29 +28,18 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
Created on Jun 22, 2012
|
||||
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core.services import ServiceProvider
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util import validators
|
||||
from defusedxml import minidom
|
||||
|
||||
from .LiveService import LiveService
|
||||
from . import on
|
||||
|
||||
import logging
|
||||
import six
|
||||
|
||||
# Python bindings for OpenNebula
|
||||
# import oca
|
||||
|
||||
__updated__ = '2018-08-20'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -119,7 +108,7 @@ class Provider(ServiceProvider):
|
||||
|
||||
if values is not None:
|
||||
self.timeout.value = validators.validateTimeout(self.timeout.value, returnAsInteger=False)
|
||||
logger.debug('Endpoint: {}'.format(self.endpoint))
|
||||
logger.debug('Endpoint: %s', self.endpoint)
|
||||
|
||||
@property
|
||||
def endpoint(self):
|
||||
@ -130,7 +119,7 @@ class Provider(ServiceProvider):
|
||||
if self._api is None:
|
||||
self._api = on.OpenNebulaClient(self.username.value, self.password.value, self.endpoint)
|
||||
|
||||
logger.debug('Api: {}'.format(self._api))
|
||||
logger.debug('Api: %s', self._api)
|
||||
return self._api
|
||||
|
||||
def resetApi(self):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,16 +32,16 @@
|
||||
"""
|
||||
|
||||
# pylint: disable=maybe-no-member
|
||||
|
||||
import six
|
||||
import types
|
||||
import xmlrpc.client
|
||||
|
||||
from uds.core.util import xml2dict
|
||||
|
||||
from . import storage
|
||||
from . import template
|
||||
from . import vm
|
||||
# Import submodules
|
||||
from .common import *
|
||||
import types
|
||||
|
||||
__updated__ = '2017-03-28'
|
||||
|
||||
@ -72,14 +72,14 @@ def checkResult(lst, parseResult=True):
|
||||
raise Exception('OpenNebula error {}: "{}"'.format(lst[2], lst[1]))
|
||||
if parseResult:
|
||||
return xml2dict.parse(lst[1])
|
||||
else:
|
||||
return lst[1]
|
||||
|
||||
return lst[1]
|
||||
|
||||
|
||||
def asList(element):
|
||||
if isinstance(element, (tuple, list)):
|
||||
return element
|
||||
return element,
|
||||
return (element,)
|
||||
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
@ -95,7 +95,7 @@ class OpenNebulaClient(object):
|
||||
def sessionString(self):
|
||||
return '{}:{}'.format(self.username, self.password)
|
||||
|
||||
@property
|
||||
@property # type: ignore
|
||||
@ensureConnected
|
||||
def version(self):
|
||||
if self.cachedVersion is None:
|
||||
@ -108,11 +108,11 @@ class OpenNebulaClient(object):
|
||||
if self.connection is not None:
|
||||
return
|
||||
|
||||
self.connection = six.moves.xmlrpc_client.ServerProxy(self.endpoint) # @UndefinedVariable
|
||||
self.connection = xmlrpc.client.ServerProxy(self.endpoint) # @UndefinedVariable
|
||||
|
||||
@ensureConnected
|
||||
def enumStorage(self, storageType=0):
|
||||
storageType = six.text_type(storageType) # Ensure it is an string
|
||||
storageType = str(storageType) # Ensure it is an string
|
||||
# Invoke datastore pools info, no parameters except connection string
|
||||
result = self.connection.one.datastorepool.info(self.sessionString)
|
||||
result = checkResult(result)
|
||||
@ -129,8 +129,7 @@ class OpenNebulaClient(object):
|
||||
3.- When the next parameter is >= -1 this is the Range start ID. Can be -1. For smaller values this is the offset used for pagination.
|
||||
4.- For values >= -1 this is the Range end ID. Can be -1 to get until the last ID. For values < -1 this is the page size used for pagination.
|
||||
"""
|
||||
result = self.connection.one.templatepool.info(self.sessionString, -1, -1, -1)
|
||||
result = checkResult(result)
|
||||
result = checkResult(self.connection.one.templatepool.info(self.sessionString, -1, -1, -1))
|
||||
for ds in asList(result['VMTEMPLATE_POOL']['VMTEMPLATE']):
|
||||
try:
|
||||
yield(ds['ID'], ds['NAME'], ds['TEMPLATE']['MEMORY'])
|
||||
@ -182,7 +181,7 @@ class OpenNebulaClient(object):
|
||||
return checkResult(result, parseResult=False)
|
||||
|
||||
@ensureConnected
|
||||
def updateTemplate(self, templateId, template, updateType=0):
|
||||
def updateTemplate(self, templateId, templateData, updateType=0):
|
||||
"""
|
||||
Updates the template with the templateXml
|
||||
1.- Session string
|
||||
@ -190,7 +189,7 @@ class OpenNebulaClient(object):
|
||||
3.- The new template contents. Syntax can be the usual attribute=value or XML.
|
||||
4.- Update type. 0 replace the whole template, 1 merge with the existing one
|
||||
"""
|
||||
result = self.connection.one.template.update(self.sessionString, int(templateId), template, int(updateType))
|
||||
result = self.connection.one.template.update(self.sessionString, int(templateId), templateData, int(updateType))
|
||||
return checkResult(result, parseResult=False)
|
||||
|
||||
@ensureConnected
|
||||
@ -208,6 +207,7 @@ class OpenNebulaClient(object):
|
||||
@ensureConnected
|
||||
def deleteTemplate(self, templateId):
|
||||
"""
|
||||
Deletes the template (not images)
|
||||
"""
|
||||
result = self.connection.one.template.delete(self.sessionString, int(templateId))
|
||||
return checkResult(result, parseResult=False)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -37,8 +37,6 @@ import re
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-02-09'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
module = sys.modules[__name__]
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,8 +34,6 @@
|
||||
import logging
|
||||
|
||||
|
||||
__updated__ = '2016-07-11'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def enumerateDatastores(api, datastoreType=0):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,17 +32,14 @@
|
||||
"""
|
||||
|
||||
import logging
|
||||
import six
|
||||
|
||||
from defusedxml import minidom
|
||||
# Python bindings for OpenNebula
|
||||
from .common import sanitizeName
|
||||
|
||||
__updated__ = '2017-05-05'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getTemplates(api, force=False):
|
||||
|
||||
for t in api.enumTemplates():
|
||||
@ -76,13 +73,13 @@ def create(api, fromTemplateId, name, toDataStore):
|
||||
|
||||
info = api.templateInfo(templateId)[1]
|
||||
template = minidom.parseString(info).getElementsByTagName('TEMPLATE')[0]
|
||||
logger.debug('XML: {}'.format(template.toxml()))
|
||||
logger.debug('XML: %s', template.toxml())
|
||||
|
||||
counter = 0
|
||||
for dsk in template.getElementsByTagName('DISK'):
|
||||
counter += 1
|
||||
imgIds = dsk.getElementsByTagName('IMAGE_ID')
|
||||
if len(imgIds) == 0:
|
||||
if not imgIds:
|
||||
fromId = False
|
||||
try:
|
||||
node = dsk.getElementsByTagName('IMAGE')[0].childNodes[0]
|
||||
@ -99,19 +96,17 @@ def create(api, fromTemplateId, name, toDataStore):
|
||||
node = imgIds[0].childNodes[0]
|
||||
imgId = node.data
|
||||
|
||||
logger.debug('Found {} for cloning'.format(imgId))
|
||||
logger.debug('Found %s for cloning', imgId)
|
||||
|
||||
# if api.imageInfo(imgId)[0]['IMAGE']['STATE'] != '1':
|
||||
# raise Exception('The base machines images are not in READY state')
|
||||
|
||||
# Now clone the image
|
||||
imgName = sanitizeName(name + ' DSK ' + six.text_type(counter))
|
||||
imgName = sanitizeName(name + ' DSK ' + str(counter))
|
||||
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
|
||||
if fromId is True:
|
||||
node.data = six.text_type(newId)
|
||||
node.data = str(newId)
|
||||
else:
|
||||
node.data = imgName
|
||||
|
||||
@ -119,9 +114,9 @@ def create(api, fromTemplateId, name, toDataStore):
|
||||
# api.call('template.update', templateId, template.toxml())
|
||||
api.updateTemplate(templateId, template.toxml())
|
||||
|
||||
return six.text_type(templateId)
|
||||
return str(templateId)
|
||||
except Exception as e:
|
||||
logger.exception('Creating template on OpenNebula: {}'.format(e))
|
||||
logger.exception('Creating template on OpenNebula')
|
||||
try:
|
||||
api.deleteTemplate(templateId) # Try to remove created template in case of fail
|
||||
except Exception:
|
||||
@ -143,11 +138,11 @@ def remove(api, templateId):
|
||||
|
||||
info = api.templateInfo(templateId)[1]
|
||||
template = minidom.parseString(info).getElementsByTagName('TEMPLATE')[0]
|
||||
logger.debug('XML: {}'.format(template.toxml()))
|
||||
logger.debug('XML: %s', template.toxml())
|
||||
|
||||
for dsk in template.getElementsByTagName('DISK'):
|
||||
imgIds = dsk.getElementsByTagName('IMAGE_ID')
|
||||
if len(imgIds) == 0:
|
||||
if not imgIds:
|
||||
try:
|
||||
node = dsk.getElementsByTagName('IMAGE')[0].childNodes[0]
|
||||
except IndexError:
|
||||
@ -157,17 +152,16 @@ def remove(api, templateId):
|
||||
node = imgIds[0].childNodes[0]
|
||||
imgId = node.data
|
||||
|
||||
logger.debug('Found {} for cloning'.format(imgId))
|
||||
logger.debug('Found %s for cloning', imgId)
|
||||
|
||||
# Now delete the image
|
||||
api.deleteImage(imgId) # api.call('image.delete', int(imgId))
|
||||
|
||||
except:
|
||||
logger.exception('Exception cloning image')
|
||||
except Exception:
|
||||
logger.exception('Removing image')
|
||||
|
||||
api.deleteTemplate(templateId) # api.call('template.delete', int(templateId))
|
||||
except Exception as e:
|
||||
logger.error('Removing template on OpenNebula: {}'.format(e))
|
||||
except Exception:
|
||||
logger.error('Removing template on OpenNebula')
|
||||
|
||||
def deployFrom(api, templateId, name):
|
||||
"""
|
||||
@ -182,7 +176,7 @@ def deployFrom(api, templateId, name):
|
||||
Id of the machine being created form template
|
||||
"""
|
||||
vmId = api.instantiateTemplate(templateId, name, False, '', False) # api.call('template.instantiate', int(templateId), name, False, '')
|
||||
return six.text_type(vmId)
|
||||
return str(vmId)
|
||||
|
||||
def checkPublished(api, templateId):
|
||||
"""
|
||||
@ -193,11 +187,11 @@ def checkPublished(api, templateId):
|
||||
|
||||
info = api.templateInfo(templateId)[1]
|
||||
template = minidom.parseString(info).getElementsByTagName('TEMPLATE')[0]
|
||||
logger.debug('XML: {}'.format(template.toxml()))
|
||||
logger.debug('XML: %s', template.toxml())
|
||||
|
||||
for dsk in template.getElementsByTagName('DISK'):
|
||||
imgIds = dsk.getElementsByTagName('IMAGE_ID')
|
||||
if len(imgIds) == 0:
|
||||
if not imgIds:
|
||||
try:
|
||||
node = dsk.getElementsByTagName('IMAGE')[0].childNodes[0]
|
||||
except IndexError:
|
||||
@ -207,13 +201,16 @@ def checkPublished(api, templateId):
|
||||
node = imgIds[0].childNodes[0]
|
||||
imgId = node.data
|
||||
|
||||
logger.debug('Found {} for checking'.format(imgId))
|
||||
logger.debug('Found %s for checking', imgId)
|
||||
|
||||
state = api.imageInfo(imgId)[0]['IMAGE']['STATE']
|
||||
if state in ('0', '4'):
|
||||
return False
|
||||
elif state != '1': # If error is not READY
|
||||
if 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)')
|
||||
# Ensure image is non persistent. This may be invoked more than once, but idoes not matters
|
||||
api.makePersistentImage(imgId, False)
|
||||
|
||||
except Exception:
|
||||
logger.exception('Exception checking published')
|
||||
raise
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,14 +32,12 @@
|
||||
'''
|
||||
|
||||
import logging
|
||||
import six
|
||||
# import oca
|
||||
|
||||
from defusedxml import minidom
|
||||
# Python bindings for OpenNebula
|
||||
from .common import VmState
|
||||
|
||||
__updated__ = '2018-08-20'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -61,7 +59,7 @@ def getMachineState(api, machineId):
|
||||
# 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 %s on OpenNebula: %s', machineId, e)
|
||||
|
||||
return VmState.UNKNOWN
|
||||
|
||||
@ -73,7 +71,7 @@ def getMachineSubstate(api, machineId):
|
||||
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 substate for %s on OpenNebula: %s', machineId, e)
|
||||
|
||||
return VmState.UNKNOWN
|
||||
|
||||
@ -91,7 +89,7 @@ def startMachine(api, machineId):
|
||||
'''
|
||||
try:
|
||||
api.VMAction(machineId, 'resume')
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
# MAybe the machine is already running. If we get error here, simply ignore it for now...
|
||||
pass
|
||||
|
||||
@ -108,7 +106,7 @@ def stopMachine(api, machineId):
|
||||
try:
|
||||
api.VMAction(machineId, 'poweroff-hard')
|
||||
except Exception as e:
|
||||
logger.error('Error powering off {} on OpenNebula: {}'.format(machineId, e))
|
||||
logger.error('Error powering off %s on OpenNebula: %s', machineId, e)
|
||||
|
||||
|
||||
def suspendMachine(api, machineId):
|
||||
@ -123,7 +121,7 @@ def suspendMachine(api, machineId):
|
||||
try:
|
||||
api.VMAction(machineId, 'suspend')
|
||||
except Exception as e:
|
||||
logger.error('Error suspending {} on OpenNebula: {}'.format(machineId, e))
|
||||
logger.error('Error suspending %s on OpenNebula: %s', machineId, e)
|
||||
|
||||
|
||||
def resetMachine(api, machineId):
|
||||
@ -138,7 +136,7 @@ def resetMachine(api, machineId):
|
||||
try:
|
||||
api.VMAction(machineId, 'reboot-hard')
|
||||
except Exception as e:
|
||||
logger.error('Error reseting {} on OpenNebula: {}'.format(machineId, e))
|
||||
logger.error('Error reseting %s on OpenNebula: %s', machineId, e)
|
||||
|
||||
|
||||
def removeMachine(api, machineId):
|
||||
@ -155,8 +153,9 @@ def removeMachine(api, machineId):
|
||||
# vm.delete()
|
||||
api.deleteVM(machineId)
|
||||
except Exception as e:
|
||||
logger.exception('Error removing machine {} on OpenNebula: {}'.format(machineId, e))
|
||||
raise Exception('Error removing machine {} on OpenNebula: {}'.format(machineId, e))
|
||||
err = 'Error removing machine {} on OpenNebula: {}'.format(machineId, e)
|
||||
logger.exception(err)
|
||||
raise Exception(err)
|
||||
|
||||
|
||||
def enumerateMachines(api):
|
||||
@ -248,4 +247,3 @@ def getDisplayConnection(api, machineId):
|
||||
# <NIC_ID><![CDATA[2]]></NIC_ID>
|
||||
# <VLAN><![CDATA[NO]]></VLAN>
|
||||
# </NIC>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user