diff --git a/server/src/uds/services/Sample/deployment_one.py b/server/src/uds/services/Sample/deployment_one.py
index 6d328ce2..2fb12140 100644
--- a/server/src/uds/services/Sample/deployment_one.py
+++ b/server/src/uds/services/Sample/deployment_one.py
@@ -118,7 +118,9 @@ class SampleUserDeploymentOne(services.UserDeployment):
"""
name: str = typing.cast(str, self.storage.readData('name'))
if name is None:
- name = self.nameGenerator().get(self.service().getBaseName() + '-' + self.service().getColour(), 3)
+ name = self.nameGenerator().get(
+ self.service().getBaseName() + '-' + self.service().getColour(), 3
+ )
# Store value for persistence
self.storage.saveData('name', name)
@@ -269,7 +271,10 @@ class SampleUserDeploymentOne(services.UserDeployment):
destroying, and cancel will simply invoke destroy
"""
import random
- countStr: typing.Optional[str] = typing.cast(str, self.storage.readData('count'))
+
+ countStr: typing.Optional[str] = typing.cast(
+ str, self.storage.readData('count')
+ )
count: int = 0
if countStr:
count = int(countStr) + 1
diff --git a/server/src/uds/services/Sample/deployment_two.py b/server/src/uds/services/Sample/deployment_two.py
index bdc2b890..9d8d79f6 100644
--- a/server/src/uds/services/Sample/deployment_two.py
+++ b/server/src/uds/services/Sample/deployment_two.py
@@ -119,8 +119,9 @@ class SampleUserDeploymentTwo(services.UserDeployment):
beside the values, so we can, at a later stage, treat with old
data for current modules.
"""
- data = '\t'.join(['v1', self._name, self._ip, self._mac, self._error,
- str(self._count)])
+ data = '\t'.join(
+ ['v1', self._name, self._ip, self._mac, self._error, str(self._count)]
+ )
return codecs.encode(data.encode(), encoding='zip') # type: ignore
def unmarshal(self, data: bytes) -> None:
diff --git a/server/src/uds/services/Sample/provider.py b/server/src/uds/services/Sample/provider.py
index 3074fbe3..769719c0 100644
--- a/server/src/uds/services/Sample/provider.py
+++ b/server/src/uds/services/Sample/provider.py
@@ -66,6 +66,7 @@ class Provider(services.ServiceProvider):
we MUST register it at package __init__.
"""
+
# : What kind of services we offer, this are classes inherited from Service
offers = [ServiceOne, ServiceTwo]
# : Name to show the administrator. This string will be translated BEFORE
@@ -107,7 +108,7 @@ class Provider(services.ServiceProvider):
label=_('Your pet\'s name'),
tooltip=_('If you like, write the name of your pet'),
requred=False,
- defvalue='Tux' # : This will not get translated
+ defvalue='Tux', # : This will not get translated
)
# : Age of Methuselah (matusalén in spanish)
# : in Spain there is a well-known to say that something is very old,
@@ -118,7 +119,7 @@ class Provider(services.ServiceProvider):
label=_('Age of Methuselah'),
tooltip=_('If you know it, please, tell me!!!'),
required=True, # : Numeric fields have always a value, so this not really needed
- defvalue='4500'
+ defvalue='4500',
)
# : Is Methuselah istill alive?
@@ -126,7 +127,7 @@ class Provider(services.ServiceProvider):
order=4,
label=_('Is Methuselah still alive?'),
tooltip=_('If you fail, this will not get saved :-)'),
- defvalue=gui.TRUE # : By default, at new item, check this
+ defvalue=gui.TRUE, # : By default, at new item, check this
)
methText = gui.TextField(
@@ -136,7 +137,7 @@ class Provider(services.ServiceProvider):
label=_('Text area'),
tooltip=_('This is a text area'),
requred=False,
- defvalue='Write\nsomething' # : This will not get translated
+ defvalue='Write\nsomething', # : This will not get translated
)
# There is more fields type, but not here the best place to cover it
@@ -154,7 +155,9 @@ class Provider(services.ServiceProvider):
# values are only passed from administration client. Internals
# instantiations are always empty.
if values and self.methAlive.isTrue():
- raise services.ServiceProvider.ValidationException(_('Methuselah is not alive!!! :-)'))
+ raise services.ServiceProvider.ValidationException(
+ _('Methuselah is not alive!!! :-)')
+ )
# Marshal and unmarshal are defaults ones, also enought
@@ -162,7 +165,9 @@ class Provider(services.ServiceProvider):
# base class so we don't have to mess with all those things...
@staticmethod
- def test(env: 'Environment', data: typing.Dict[str, str]) -> typing.List[typing.Any]:
+ def test(
+ env: 'Environment', data: typing.Dict[str, str]
+ ) -> typing.List[typing.Any]:
"""
Create your test method here so the admin can push the "check" button
and this gets executed.
@@ -186,7 +191,11 @@ class Provider(services.ServiceProvider):
try:
# We instantiate the provider, but this may fail...
instance = Provider(env, data)
- logger.debug('Methuselah has %s years and is %s :-)', instance.methAge.value, instance.methAlive.value)
+ logger.debug(
+ 'Methuselah has %s years and is %s :-)',
+ instance.methAge.value,
+ instance.methAlive.value,
+ )
except services.ServiceProvider.ValidationException as e:
# If we say that meth is alive, instantiation will
return [False, str(e)]
diff --git a/server/src/uds/services/Sample/publication.py b/server/src/uds/services/Sample/publication.py
index 36542757..43847776 100644
--- a/server/src/uds/services/Sample/publication.py
+++ b/server/src/uds/services/Sample/publication.py
@@ -84,7 +84,9 @@ class SamplePublication(services.Publication):
it's expressed in seconds, (i.e. "suggestedTime = 10")
"""
- suggestedTime = 5 # : Suggested recheck time if publication is unfinished in seconds
+ suggestedTime = (
+ 5 # : Suggested recheck time if publication is unfinished in seconds
+ )
_name: str = ''
_reason: str = ''
_number: int = -1
@@ -217,7 +219,9 @@ class SamplePublication(services.Publication):
Returned value, if any, is ignored
"""
# Make simply a random string
- self._name = ''.join(random.SystemRandom().choices(string.ascii_uppercase + string.digits, k=10))
+ self._name = ''.join(
+ random.SystemRandom().choices(string.ascii_uppercase + string.digits, k=10)
+ )
def reasonOfError(self) -> str:
"""
diff --git a/server/src/uds/services/Sample/service.py b/server/src/uds/services/Sample/service.py
index b62e38d9..56a9b1ee 100644
--- a/server/src/uds/services/Sample/service.py
+++ b/server/src/uds/services/Sample/service.py
@@ -49,6 +49,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
+
class ServiceOne(services.Service):
"""
Basic service, the first part (variables) include the description of the service.
@@ -71,6 +72,7 @@ class ServiceOne(services.Service):
information.
"""
+
# : 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)
@@ -130,9 +132,9 @@ class ServiceOne(services.Service):
gui.choiceItem('red', 'Red'),
gui.choiceItem('green', 'Green'),
gui.choiceItem('blue', 'Blue'),
- gui.choiceItem('nonsense', 'Blagenta')
+ gui.choiceItem('nonsense', 'Blagenta'),
],
- defvalue='1' # Default value is the ID of the choicefield
+ defvalue='1', # Default value is the ID of the choicefield
)
passw = gui.PasswordField(
@@ -140,7 +142,7 @@ class ServiceOne(services.Service):
label=_('Password'),
tooltip=_('Password for testing purposes'),
required=True,
- defvalue='1234' # : Default password are nonsense?? :-)
+ defvalue='1234', # : Default password are nonsense?? :-)
)
baseName = gui.TextField(
@@ -149,7 +151,7 @@ class ServiceOne(services.Service):
tooltip=_('Base name for this user services'),
# In this case, the choice can have none value selected by default
required=True,
- defvalue='' # Default value is the ID of the choicefield
+ defvalue='', # Default value is the ID of the choicefield
)
def initialize(self, values: 'Module.ValuesType') -> None:
@@ -165,13 +167,13 @@ class ServiceOne(services.Service):
# so we only need to validate params if values is not None
if values:
if self.colour.value == 'nonsense':
- raise services.Service.ValidationException('The selected colour is invalid!!!')
-
+ raise services.Service.ValidationException(
+ 'The selected colour is invalid!!!'
+ )
# Services itself are non testeable right now, so we don't even have
# to provide one!!!
-
# Congratulations!!!, the needed part of your first simple service is done!
# Now you can go to administration panel, and check it
#
@@ -200,6 +202,7 @@ class ServiceTwo(services.Service):
"""
Just a second service, no comments here (almost same that ServiceOne
"""
+
typeName = _('Sample Service Two')
typeType = 'SampleService2'
typeDescription = _('Sample (and dummy) service ONE+ONE')
@@ -222,7 +225,6 @@ class ServiceTwo(services.Service):
# : Types of deploys (services in cache and/or assigned to users)
deployedType = SampleUserDeploymentTwo
-
# Gui, we will use here the EditableList field
names = gui.EditableList(label=_('List of names'))
diff --git a/server/src/uds/services/Xen/deployment.py b/server/src/uds/services/Xen/deployment.py
index f069805b..d6f232a2 100644
--- a/server/src/uds/services/Xen/deployment.py
+++ b/server/src/uds/services/Xen/deployment.py
@@ -48,7 +48,20 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
-opCreate, opStart, opStop, opSuspend, opRemove, opWait, opError, opFinish, opRetry, opConfigure, opProvision, opWaitSuspend = range(12)
+(
+ opCreate,
+ opStart,
+ opStop,
+ opSuspend,
+ opRemove,
+ opWait,
+ opError,
+ opFinish,
+ opRetry,
+ opConfigure,
+ opProvision,
+ opWaitSuspend,
+) = range(12)
NO_MORE_NAMES = 'NO-NAME-ERROR'
@@ -80,16 +93,18 @@ class XenLinkedDeployment(UserDeployment):
# Serializable needed methods
def marshal(self) -> bytes:
- return b'\1'.join([
- b'v1',
- self._name.encode('utf8'),
- self._ip.encode('utf8'),
- self._mac.encode('utf8'),
- self._vmid.encode('utf8'),
- self._reason.encode('utf8'),
- pickle.dumps(self._queue, protocol=0),
- self._task.encode('utf8')
- ])
+ return b'\1'.join(
+ [
+ b'v1',
+ self._name.encode('utf8'),
+ self._ip.encode('utf8'),
+ self._mac.encode('utf8'),
+ self._vmid.encode('utf8'),
+ self._reason.encode('utf8'),
+ pickle.dumps(self._queue, protocol=0),
+ self._task.encode('utf8'),
+ ]
+ )
def unmarshal(self, data: bytes) -> None:
vals = data.split(b'\1')
@@ -106,7 +121,9 @@ class XenLinkedDeployment(UserDeployment):
def getName(self) -> str:
if not self._name:
try:
- self._name = self.nameGenerator().get(self.service().getBaseName(), self.service().getLenName())
+ self._name = self.nameGenerator().get(
+ self.service().getBaseName(), self.service().getLenName()
+ )
except KeyError:
return NO_MORE_NAMES
return self._name
@@ -168,7 +185,16 @@ class XenLinkedDeployment(UserDeployment):
if forLevel2 is False:
self._queue = [opCreate, opConfigure, opProvision, opStart, opFinish]
else:
- self._queue = [opCreate, opConfigure, opProvision, opStart, opWait, opWaitSuspend, opSuspend, opFinish]
+ self._queue = [
+ opCreate,
+ opConfigure,
+ opProvision,
+ opStart,
+ opWait,
+ opWaitSuspend,
+ opSuspend,
+ opFinish,
+ ]
def __getCurrentOp(self) -> int:
if len(self._queue) == 0:
@@ -196,7 +222,11 @@ class XenLinkedDeployment(UserDeployment):
if self._vmid != '': # Powers off and delete VM
try:
state = self.service().getVMPowerState(self._vmid)
- if state in (XenPowerState.running, XenPowerState.paused, XenPowerState.suspended):
+ if state in (
+ XenPowerState.running,
+ XenPowerState.paused,
+ XenPowerState.suspended,
+ ):
self.service().stopVM(self._vmid, False) # In sync mode
self.service().removeVM(self._vmid)
except Exception:
@@ -226,14 +256,16 @@ class XenLinkedDeployment(UserDeployment):
opWait: self.__wait,
opRemove: self.__remove,
opConfigure: self.__configure,
- opProvision: self.__provision
+ opProvision: self.__provision,
}
try:
execFnc: typing.Optional[typing.Callable[[], str]] = fncs.get(op, None)
if execFnc is None:
- return self.__error('Unknown operation found at execution queue ({0})'.format(op))
+ return self.__error(
+ 'Unknown operation found at execution queue ({0})'.format(op)
+ )
execFnc()
@@ -265,9 +297,13 @@ class XenLinkedDeployment(UserDeployment):
templateId = self.publication().getTemplateId()
name = self.getName()
if name == NO_MORE_NAMES:
- raise Exception('No more names available for this service. (Increase digits for this service to fix)')
+ raise Exception(
+ 'No more names available for this service. (Increase digits for this service to fix)'
+ )
- name = 'UDS service ' + self.service().sanitizeVmName(name) # oVirt don't let us to create machines with more than 15 chars!!!
+ name = 'UDS service ' + self.service().sanitizeVmName(
+ name
+ ) # oVirt don't let us to create machines with more than 15 chars!!!
comments = 'UDS Linked clone'
self._task = self.service().startDeployFromTemplate(name, comments, templateId)
@@ -282,7 +318,7 @@ class XenLinkedDeployment(UserDeployment):
"""
state = self.service().getVMPowerState(self._vmid)
- if state not in(XenPowerState.halted, XenPowerState.suspended):
+ if state not in (XenPowerState.halted, XenPowerState.suspended):
self.__pushFrontOp(opStop)
self.__executeQueue()
else:
@@ -348,7 +384,9 @@ class XenLinkedDeployment(UserDeployment):
"""
Makes machine usable on Xen
"""
- self.service().provisionVM(self._vmid, False) # Let's try this in "sync" mode, this must be fast enough
+ self.service().provisionVM(
+ self._vmid, False
+ ) # Let's try this in "sync" mode, this must be fast enough
return State.RUNNING
@@ -434,14 +472,16 @@ class XenLinkedDeployment(UserDeployment):
opSuspend: self.__checkSuspend,
opRemove: self.__checkRemoved,
opConfigure: self.__checkConfigure,
- opProvision: self.__checkProvision
+ opProvision: self.__checkProvision,
}
try:
chkFnc: typing.Optional[typing.Callable[[], str]] = fncs.get(op, None)
if chkFnc is None:
- return self.__error('Unknown operation found at check queue ({})'.format(op))
+ return self.__error(
+ 'Unknown operation found at check queue ({})'.format(op)
+ )
state = chkFnc()
if state == State.FINISHED:
@@ -503,8 +543,16 @@ class XenLinkedDeployment(UserDeployment):
opFinish: 'finish',
opRetry: 'retry',
opConfigure: 'configuring',
- opProvision: 'provisioning'
+ opProvision: 'provisioning',
}.get(op, '????')
def __debug(self, txt: str) -> None:
- logger.debug('State at %s: name: %s, ip: %s, mac: %s, vmid:%s, queue: %s', txt, self._name, self._ip, self._mac, self._vmid, [XenLinkedDeployment.__op2str(op) for op in self._queue])
+ logger.debug(
+ 'State at %s: name: %s, ip: %s, mac: %s, vmid:%s, queue: %s',
+ txt,
+ self._name,
+ self._ip,
+ self._mac,
+ self._vmid,
+ [XenLinkedDeployment.__op2str(op) for op in self._queue],
+ )
diff --git a/server/src/uds/services/Xen/publication.py b/server/src/uds/services/Xen/publication.py
index 26510a64..f091934e 100644
--- a/server/src/uds/services/Xen/publication.py
+++ b/server/src/uds/services/Xen/publication.py
@@ -45,7 +45,9 @@ logger = logging.getLogger(__name__)
class XenPublication(Publication):
- suggestedTime = 20 # : Suggested recheck time if publication is unfinished in seconds
+ suggestedTime = (
+ 20 # : Suggested recheck time if publication is unfinished in seconds
+ )
_name: str = ''
_reason: str = ''
@@ -61,23 +63,44 @@ class XenPublication(Publication):
"""
returns data from an instance of Sample Publication serialized
"""
- return '\t'.join(['v1', self._name, self._reason, self._destroyAfter, self._templateId, self._state, self._task]).encode('utf8')
+ return '\t'.join(
+ [
+ 'v1',
+ self._name,
+ self._reason,
+ self._destroyAfter,
+ self._templateId,
+ self._state,
+ self._task,
+ ]
+ ).encode('utf8')
def unmarshal(self, data: bytes) -> None:
"""
deserializes the data and loads it inside instance.
"""
- #logger.debug('Data: {0}'.format(data))
+ # logger.debug('Data: {0}'.format(data))
vals = data.decode('utf8').split('\t')
if vals[0] == 'v1':
- self._name, self._reason, self._destroyAfter, self._templateId, self._state, self._task = vals[1:]
+ (
+ self._name,
+ self._reason,
+ self._destroyAfter,
+ self._templateId,
+ self._state,
+ self._task,
+ ) = vals[1:]
def publish(self) -> str:
"""
Realizes the publication of the service
"""
- self._name = self.service().sanitizeVmName('UDS Pub ' + self.dsName() + "-" + str(self.revision()))
- comments = _('UDS pub for {0} at {1}').format(self.dsName(), str(datetime.now()).split('.')[0])
+ self._name = self.service().sanitizeVmName(
+ 'UDS Pub ' + self.dsName() + "-" + str(self.revision())
+ )
+ comments = _('UDS pub for {0} at {1}').format(
+ self.dsName(), str(datetime.now()).split('.')[0]
+ )
self._reason = '' # No error, no reason for it
self._destroyAfter = 'f'
self._state = 'ok'
diff --git a/server/src/uds/services/Xen/service.py b/server/src/uds/services/Xen/service.py
index 48f450be..545df345 100644
--- a/server/src/uds/services/Xen/service.py
+++ b/server/src/uds/services/Xen/service.py
@@ -54,6 +54,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
"""
+
# : 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)
@@ -78,15 +79,13 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
usesCache = True
# : Tooltip shown to user when this item is pointed at admin interface, none
# : because we don't use it
- cacheTooltip = _(
- 'Number of desired machines to keep running waiting for a user')
+ cacheTooltip = _('Number of desired machines to keep running waiting for a user')
# : If we need to generate a "Level 2" cache for this service (i.e., L1
# : could be running machines and L2 suspended machines)
usesCache_L2 = True
# : Tooltip shown to user when this item is pointed at admin interface, None
# : also because we don't use it
- cacheTooltip_L2 = _(
- 'Number of desired machines to keep suspended waiting for use')
+ cacheTooltip_L2 = _('Number of desired machines to keep suspended waiting for use')
# : If the service needs a s.o. manager (managers are related to agents
# : provided by services itselfs, i.e. virtual machines with actors)
@@ -109,8 +108,10 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
label=_("Storage SR"),
rdonly=False,
order=100,
- tooltip=_('Storage where to publish and put incrementals (only shared storages are supported)'),
- required=True
+ tooltip=_(
+ 'Storage where to publish and put incrementals (only shared storages are supported)'
+ ),
+ required=True,
)
minSpaceGB = gui.NumericField(
@@ -119,7 +120,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
defvalue='32',
order=101,
tooltip=_('Minimal free space in GB'),
- required=True
+ required=True,
)
machine = gui.ChoiceField(
@@ -127,7 +128,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
order=110,
tooltip=_('Service base machine'),
tab=_('Machine'),
- required=True
+ required=True,
)
network = gui.ChoiceField(
@@ -136,17 +137,18 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
order=111,
tooltip=_('Network used for virtual machines'),
tab=_('Machine'),
- required=True
+ required=True,
)
memory = gui.NumericField(
label=_("Memory (Mb)"),
- length=4, defvalue=512,
+ length=4,
+ defvalue=512,
rdonly=False,
order=112,
tooltip=_('Memory assigned to machines'),
tab=_('Machine'),
- required=True
+ required=True,
)
shadow = gui.NumericField(
@@ -157,7 +159,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
order=113,
tooltip=_('Shadow memory multiplier (use with care)'),
tab=_('Machine'),
- required=True
+ required=True,
)
baseName = gui.TextField(
@@ -166,7 +168,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
order=114,
tooltip=_('Base name for clones from this machine'),
tab=_('Machine'),
- required=True
+ required=True,
)
lenName = gui.NumericField(
@@ -176,7 +178,7 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
order=115,
tooltip=_('Size of numeric part for the names of these machines'),
tab=_('Machine'),
- required=True
+ required=True,
)
def initialize(self, values):
@@ -191,7 +193,8 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
if int(self.memory.value) < 256:
raise Service.ValidationException(
- _('The minimum allowed memory is 256 Mb'))
+ _('The minimum allowed memory is 256 Mb')
+ )
def parent(self) -> 'XenProvider':
return typing.cast('XenProvider', super().parent())
@@ -201,14 +204,27 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
# This is that value is always '', so if we want to change something, we have to do it
# at defValue
- machines_list = [gui.choiceItem(m['id'], m['name']) for m in self.parent().getMachines()]
+ machines_list = [
+ gui.choiceItem(m['id'], m['name']) for m in self.parent().getMachines()
+ ]
storages_list = []
for storage in self.parent().getStorages():
- space, free = storage['size'] / 1024, (storage['size'] - storage['used']) / 1024
- storages_list.append(gui.choiceItem(storage['id'], "%s (%4.2f Gb/%4.2f Gb)" % (storage['name'], space, free)))
+ space, free = (
+ storage['size'] / 1024,
+ (storage['size'] - storage['used']) / 1024,
+ )
+ storages_list.append(
+ gui.choiceItem(
+ storage['id'],
+ "%s (%4.2f Gb/%4.2f Gb)" % (storage['name'], space, free),
+ )
+ )
- network_list = [gui.choiceItem(net['id'], net['name']) for net in self.parent().getNetworks()]
+ network_list = [
+ gui.choiceItem(net['id'], net['name'])
+ for net in self.parent().getNetworks()
+ ]
self.machine.setValues(machines_list)
self.datastore.setValues(storages_list)
@@ -223,7 +239,11 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
logger.debug('Checking datastore space for %s: %s', self.datastore.value, info)
availableGB = (info['size'] - info['used']) / 1024
if availableGB < self.minSpaceGB.num():
- raise Exception('Not enough free space available: (Needs at least {} GB and there is only {} GB '.format(self.minSpaceGB.num(), availableGB))
+ raise Exception(
+ 'Not enough free space available: (Needs at least {} GB and there is only {} GB '.format(
+ self.minSpaceGB.num(), availableGB
+ )
+ )
def sanitizeVmName(self, name: str) -> str:
"""
@@ -245,12 +265,18 @@ class XenLinkedService(Service): # pylint: disable=too-many-public-methods
Raises an exception if operation fails.
"""
- logger.debug('Starting deploy of template from machine %s on datastore %s', self.machine.value, self.datastore.value)
+ logger.debug(
+ 'Starting deploy of template from machine %s on datastore %s',
+ self.machine.value,
+ self.datastore.value,
+ )
# Checks datastore available space, raises exeception in no min available
self.datastoreHasSpace()
- return self.parent().cloneForTemplate(name, comments, self.machine.value, self.datastore.value)
+ return self.parent().cloneForTemplate(
+ name, comments, self.machine.value, self.datastore.value
+ )
def convertToTemplate(self, machineId: str) -> None:
"""
diff --git a/server/src/uds/services/Xen/xen_client/XenAPI.py b/server/src/uds/services/Xen/xen_client/XenAPI.py
index 23848889..65351bb5 100644
--- a/server/src/uds/services/Xen/xen_client/XenAPI.py
+++ b/server/src/uds/services/Xen/xen_client/XenAPI.py
@@ -69,8 +69,10 @@ translation = gettext.translation('xen-xm', fallback=True)
API_VERSION_1_1 = '1.1'
API_VERSION_1_2 = '1.2'
+
class Failure(Exception):
details: typing.List[typing.Any]
+
def __init__(self, details: typing.List[typing.Any]):
super().__init__()
self.details = details
@@ -87,19 +89,24 @@ class Failure(Exception):
# dict([(str(i), self.details[i]) for i in range(len(self.details))])
return {str(i): d for i, d in enumerate(self.details)}
+
# Just a "constant" that we use to decide whether to retry the RPC
_RECONNECT_AND_RETRY = object()
+
class UDSHTTPConnection(httplib.HTTPConnection):
- """HTTPConnection subclass to allow HTTP over Unix domain sockets. """
+ """HTTPConnection subclass to allow HTTP over Unix domain sockets."""
+
def connect(self):
path = self.host.replace("_", "/")
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(path)
+
class UDSHTTP(httplib.HTTPConnection):
_connection_class = UDSHTTPConnection
+
class UDSTransport(xmlrpclib.Transport):
_use_datetime: bool
_extra_headers: typing.List[typing.Tuple[str, str]]
@@ -117,11 +124,14 @@ class UDSTransport(xmlrpclib.Transport):
def make_connection(self, host: str) -> httplib.HTTPConnection: # type: ignore # In our case, host is always an string
return UDSHTTPConnection(host)
- def send_request(self, connection, handler, request_body, debug): # pylint: disable=arguments-differ
+ def send_request(
+ self, connection, handler, request_body, debug
+ ): # pylint: disable=arguments-differ
connection.putrequest("POST", handler)
for key, value in self._extra_headers:
connection.putheader(key, value)
+
class Session(xmlrpclib.ServerProxy):
"""A server proxy and session manager for communicating with xapi using
the Xen-API.
@@ -134,25 +144,40 @@ class Session(xmlrpclib.ServerProxy):
session.xenapi.session.logout()
"""
- def __init__(self, uri, transport=None, encoding=None, verbose=0,
- allow_none=1, ignore_ssl=False):
+ def __init__(
+ self,
+ uri,
+ transport=None,
+ encoding=None,
+ verbose=0,
+ allow_none=1,
+ ignore_ssl=False,
+ ):
# Fix for CA-172901 (+ Python 2.4 compatibility)
# Fix for context=ctx ( < Python 2.7.9 compatibility)
- if not (sys.version_info[0] <= 2 and sys.version_info[1] <= 7 and sys.version_info[2] <= 9) and ignore_ssl:
+ if (
+ not (
+ sys.version_info[0] <= 2
+ and sys.version_info[1] <= 7
+ and sys.version_info[2] <= 9
+ )
+ and ignore_ssl
+ ):
ctx = ssl._create_unverified_context()
- xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
- verbose, allow_none, context=ctx)
+ xmlrpclib.ServerProxy.__init__(
+ self, uri, transport, encoding, verbose, allow_none, context=ctx
+ )
else:
- xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
- verbose, allow_none)
+ xmlrpclib.ServerProxy.__init__(
+ self, uri, transport, encoding, verbose, allow_none
+ )
self.transport = transport
self._session = None
self.last_login_method = None
self.last_login_params = None
self.API_version = API_VERSION_1_1
-
def xenapi_request(self, methodname, params):
if methodname.startswith('login'):
self._login(methodname, params)
@@ -168,22 +193,20 @@ class Session(xmlrpclib.ServerProxy):
if result is _RECONNECT_AND_RETRY:
retry_count += 1
if self.last_login_method:
- self._login(self.last_login_method,
- self.last_login_params)
+ self._login(self.last_login_method, self.last_login_params)
else:
raise xmlrpclib.Fault(401, 'You must log in')
else:
return result
raise xmlrpclib.Fault(
- 500, 'Tried 3 times to get a valid session, but failed')
+ 500, 'Tried 3 times to get a valid session, but failed'
+ )
def _login(self, method, params):
try:
- result = _parse_result(
- getattr(self, 'session.%s' % method)(*params))
+ result = _parse_result(getattr(self, 'session.%s' % method)(*params))
if result is _RECONNECT_AND_RETRY:
- raise xmlrpclib.Fault(
- 500, 'Received SESSION_INVALID when logging in')
+ raise xmlrpclib.Fault(500, 'Received SESSION_INVALID when logging in')
self._session = result
self.last_login_method = method
self.last_login_params = params
@@ -195,7 +218,7 @@ class Session(xmlrpclib.ServerProxy):
def _logout(self):
try:
- if self.last_login_method.startswith("slave_local"):
+ if self.last_login_method.startswith("slave_local"): # type: ignore
return _parse_result(self.session.local_logout(self._session)) # type: ignore
else:
return _parse_result(self.session.logout(self._session)) # type: ignore
@@ -210,7 +233,7 @@ class Session(xmlrpclib.ServerProxy):
host = self.xenapi.pool.get_master(pool)
major = self.xenapi.host.get_API_version_major(host)
minor = self.xenapi.host.get_API_version_minor(host)
- return "%s.%s"%(major, minor)
+ return "%s.%s" % (major, minor)
def __getattr__(self, name):
if name == 'handle':
@@ -224,12 +247,16 @@ class Session(xmlrpclib.ServerProxy):
else:
return xmlrpclib.ServerProxy.__getattr__(self, name)
+
def xapi_local():
return Session("http://_var_lib_xcp_xapi/", transport=UDSTransport())
+
def _parse_result(result):
if not isinstance(result, dict) or 'Status' not in result:
- raise xmlrpclib.Fault(500, 'Missing Status in response from server: {}'.format(result))
+ raise xmlrpclib.Fault(
+ 500, 'Missing Status in response from server: {}'.format(result)
+ )
if result['Status'] == 'Success':
if 'Value' in result:
return result['Value']
@@ -258,7 +285,9 @@ class _Dispatcher:
if self.__name is None:
return _Dispatcher(self.__API_version, self.__send, name)
else:
- return _Dispatcher(self.__API_version, self.__send, "%s.%s" % (self.__name, name))
+ return _Dispatcher(
+ self.__API_version, self.__send, "%s.%s" % (self.__name, name)
+ )
def __call__(self, *args):
return self.__send(self.__name, args)
diff --git a/server/src/uds/services/Xen/xen_client/__init__.py b/server/src/uds/services/Xen/xen_client/__init__.py
index a5a04987..6c87843d 100644
--- a/server/src/uds/services/Xen/xen_client/__init__.py
+++ b/server/src/uds/services/Xen/xen_client/__init__.py
@@ -38,6 +38,7 @@ logger = logging.getLogger(__name__)
TAG_TEMPLATE = "uds-template"
TAG_MACHINE = "uds-machine"
+
class XenFault(Exception):
pass
@@ -113,7 +114,16 @@ class XenServer: # pylint: disable=too-many-public-methods
_poolName: str
_apiVersion: str
- def __init__(self, host: str, host_backup: str, port: int, username: str, password: str, useSSL: bool = False, verifySSL: bool = False):
+ def __init__(
+ self,
+ host: str,
+ host_backup: str,
+ port: int,
+ username: str,
+ password: str,
+ useSSL: bool = False,
+ verifySSL: bool = False,
+ ):
self._originalHost = self._host = host
self._host_backup = host_backup or ''
self._port = str(port)
@@ -186,7 +196,11 @@ class XenServer: # pylint: disable=too-many-public-methods
self._poolName = str(self.getPoolName())
except XenAPI.Failure as e: # XenAPI.Failure: ['HOST_IS_SLAVE', '172.27.0.29'] indicates that this host is an slave of 172.27.0.29, connect to it...
if switchToMaster and e.details[0] == 'HOST_IS_SLAVE':
- logger.info('%s is an Slave, connecting to master at %s', self._host, e.details[1])
+ logger.info(
+ '%s is an Slave, connecting to master at %s',
+ self._host,
+ e.details[1],
+ )
self._host = e.details[1]
self.login()
else:
@@ -246,7 +260,11 @@ class XenServer: # pylint: disable=too-many-public-methods
status = 'failure'
# Removes if present
- if result and not isinstance(result, XenFailure) and result.startswith(''):
+ if (
+ result
+ and not isinstance(result, XenFailure)
+ and result.startswith('')
+ ):
result = result[7:-8]
if destroyTask:
@@ -255,14 +273,18 @@ class XenServer: # pylint: disable=too-many-public-methods
except Exception as e:
logger.warning('Destroy task %s returned error %s', task, str(e))
- return {'result': result, 'progress': progress, 'status':str(status)}
+ return {'result': result, 'progress': progress, 'status': str(status)}
def getSRs(self) -> typing.Iterable[typing.MutableMapping[str, typing.Any]]:
for srId in self.SR.get_all():
# Only valid SR shared, non iso
name_label = self.SR.get_name_label(srId)
# Skip non valid...
- if self.SR.get_content_type(srId) == 'iso' or self.SR.get_shared(srId) is False or name_label == '':
+ if (
+ self.SR.get_content_type(srId) == 'iso'
+ or self.SR.get_shared(srId) is False
+ or name_label == ''
+ ):
continue
valid = True
@@ -276,7 +298,7 @@ class XenServer: # pylint: disable=too-many-public-methods
'id': srId,
'name': name_label,
'size': XenServer.toMb(self.SR.get_physical_size(srId)),
- 'used': XenServer.toMb(self.SR.get_physical_utilisation(srId))
+ 'used': XenServer.toMb(self.SR.get_physical_utilisation(srId)),
}
def getSRInfo(self, srId: str) -> typing.MutableMapping[str, typing.Any]:
@@ -284,22 +306,24 @@ class XenServer: # pylint: disable=too-many-public-methods
'id': srId,
'name': self.SR.get_name_label(srId),
'size': XenServer.toMb(self.SR.get_physical_size(srId)),
- 'used': XenServer.toMb(self.SR.get_physical_utilisation(srId))
+ 'used': XenServer.toMb(self.SR.get_physical_utilisation(srId)),
}
def getNetworks(self) -> typing.Iterable[typing.MutableMapping[str, typing.Any]]:
for netId in self.network.get_all():
- if self.network.get_other_config(netId).get('is_host_internal_management_network', False) is False:
+ if (
+ self.network.get_other_config(netId).get(
+ 'is_host_internal_management_network', False
+ )
+ is False
+ ):
yield {
'id': netId,
'name': self.network.get_name_label(netId),
}
def getNetworkInfo(self, netId: str) -> typing.MutableMapping[str, typing.Any]:
- return {
- 'id': netId,
- 'name': self.network.get_name_label(netId)
- }
+ return {'id': netId, 'name': self.network.get_name_label(netId)}
def getVMs(self) -> typing.Iterable[typing.MutableMapping[str, typing.Any]]:
try:
@@ -308,8 +332,7 @@ class XenServer: # pylint: disable=too-many-public-methods
# if self.VM.get_is_a_template(vm): # Sample set_tags, easy..
# self.VM.set_tags(vm, ['template'])
# continue
- if self.VM.get_is_control_domain(vm) or \
- self.VM.get_is_a_template(vm):
+ if self.VM.get_is_control_domain(vm) or self.VM.get_is_a_template(vm):
continue
yield {'id': vm, 'name': self.VM.get_name_label(vm)}
@@ -382,7 +405,9 @@ class XenServer: # pylint: disable=too-many-public-methods
return self.Async.VM.resume(vmId, False, False)
return self.VM.resume(vmId, False, False)
- def cloneVM(self, vmId: str, targetName: str, targetSR: typing.Optional[str] = None) -> str:
+ def cloneVM(
+ self, vmId: str, targetName: str, targetSR: typing.Optional[str] = None
+ ) -> str:
"""
If targetSR is NONE:
Clones the specified VM, making a new VM.
@@ -402,11 +427,15 @@ class XenServer: # pylint: disable=too-many-public-methods
try:
if targetSR:
if 'copy' not in operations:
- raise XenException('Copy is not supported for this machine (maybe it\'s powered on?)')
+ raise XenException(
+ 'Copy is not supported for this machine (maybe it\'s powered on?)'
+ )
task = self.Async.VM.copy(vmId, targetName, targetSR)
else:
if 'clone' not in operations:
- raise XenException('Clone is not supported for this machine (maybe it\'s powered on?)')
+ raise XenException(
+ 'Clone is not supported for this machine (maybe it\'s powered on?)'
+ )
task = self.Async.VM.clone(vmId, targetName)
return task
except XenAPI.Failure as e:
@@ -490,7 +519,9 @@ class XenServer: # pylint: disable=too-many-public-methods
operations = self.VM.get_allowed_operations(vmId)
logger.debug('Allowed operations: %s', operations)
if 'make_into_template' not in operations:
- raise XenException('Convert in template is not supported for this machine')
+ raise XenException(
+ 'Convert in template is not supported for this machine'
+ )
self.VM.set_is_a_template(vmId, True)
# Apply that is an "UDS Template" taggint it
diff --git a/server/src/uds/services/__init__.py b/server/src/uds/services/__init__.py
index 574786e2..f0cd4750 100644
--- a/server/src/uds/services/__init__.py
+++ b/server/src/uds/services/__init__.py
@@ -63,7 +63,7 @@ def __init__():
for _, name, _ in pkgutil.iter_modules([pkgpath]):
# __import__('uds.services.' + name, globals(), locals(), [])
importlib.import_module('.' + name, __name__) # import module
-
+
importlib.invalidate_caches()
for p in [services.ServiceProvider]: