diff --git a/server/src/uds/services/Xen/service.py b/server/src/uds/services/Xen/service.py index 826cda053..24dc3c4ec 100644 --- a/server/src/uds/services/Xen/service.py +++ b/server/src/uds/services/Xen/service.py @@ -187,18 +187,17 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho # Here we have to use "default values", cause values aren't used at form initialization # This is that value is always '', so if we want to change something, we have to do it # at defValue + GB: typing.Final[int] = 1024**3 with self.provider().get_connection() as api: machines_list = [gui.choice_item(m.opaque_ref, m.name) for m in api.list_vms()] - storages_list: list[types.ui.ChoiceItem] = [] - for storage in api.list_srs(): - space, free = ( - storage.physical_size / 1024, - (storage.physical_size - storage.physical_utilisation) / 1024, - ) - storages_list.append( - gui.choice_item(storage.opaque_ref, f'{storage.name} ({space:.2f} Gb/{free:.2f} Gb)') + storages_list: list[types.ui.ChoiceItem] = [ + gui.choice_item( + storage.opaque_ref, + f'{storage.name} ({storage.physical_size/GB:.2f} Gb/{storage.free_space/GB:.2f} Gb)', ) + for storage in api.list_srs() + ] network_list = [gui.choice_item(net.opaque_ref, net.name) for net in api.list_networks()] self.machine.set_choices(machines_list) @@ -225,7 +224,7 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho Xen Seems to allow all kind of names, but let's sanitize a bit """ return re.sub(r'([^a-zA-Z0-9_ .-]+)', r'_', name) - + def find_duplicates(self, name: str, mac: str) -> collections.abc.Iterable[str]: """ Checks if a machine with the same name or mac exists @@ -244,9 +243,7 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho with self.provider().get_connection() as api: vms = api.list_vms() return [ - vm.opaque_ref - for vm in vms - if vm.name == name + vm.opaque_ref for vm in vms if vm.name == name ] # Only check for name, mac is harder to get, so by now, we only check for name def start_deploy_of_template(self, name: str, comments: str) -> str: @@ -313,20 +310,26 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho vm_opaque_ref, mac_info={'network': self.network.value, 'mac': mac}, memory=self.memory.value ) - def get_ip(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> str: + def get_ip( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> str: """ Returns the ip of the machine If cannot be obtained, MUST raise an exception """ return '' # No ip will be get, UDS will assign one (from actor) - def get_mac(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> str: + def get_mac( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> str: """ For """ return self.mac_generator().get(self.provider().get_macs_range()) - def is_running(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> bool: + def is_running( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> bool: """ Returns if the machine is ready and running """ @@ -336,7 +339,9 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho return True return False - def start(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None: + def start( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> None: """ Starts the machine Can return a task, or None if no task is returned @@ -344,7 +349,9 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho with self.provider().get_connection() as api: api.start_vm(vmid) - def stop(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None: + def stop( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> None: """ Stops the machine Can return a task, or None if no task is returned @@ -352,7 +359,9 @@ class XenLinkedService(DynamicService): # pylint: disable=too-many-public-metho with self.provider().get_connection() as api: api.stop_vm(vmid) - def shutdown(self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str) -> None: + def shutdown( + self, caller_instance: typing.Optional['DynamicUserService | DynamicPublication'], vmid: str + ) -> None: with self.provider().get_connection() as api: api.shutdown_vm(vmid) diff --git a/server/src/uds/services/Xen/xen/client.py b/server/src/uds/services/Xen/xen/client.py index cc0101f7a..4be52aff8 100644 --- a/server/src/uds/services/Xen/xen/client.py +++ b/server/src/uds/services/Xen/xen/client.py @@ -525,8 +525,8 @@ class XenClient: # pylint: disable=too-many-public-methods if memory: logger.debug('Setting up memory to %s MB', memory) # Convert memory to MB - memory = memory * 1024 * 1024 - self.VM.set_memory_limits(vm_opaque_ref, memory, memory, memory, memory) + memory_mb = str(int(memory) * 1024 * 1024) + self.VM.set_memory_limits(vm_opaque_ref, memory_mb, memory_mb, memory_mb, memory_mb) @cached(prefix='xen_folders', timeout=consts.cache.LONG_CACHE_TIMEOUT, key_helper=cache_key_helper) @exceptions.catched diff --git a/server/src/uds/services/Xen/xen/types.py b/server/src/uds/services/Xen/xen/types.py index 9e50e7cd2..714a2c716 100644 --- a/server/src/uds/services/Xen/xen/types.py +++ b/server/src/uds/services/Xen/xen/types.py @@ -307,6 +307,14 @@ class StorageInfo: type: str # Type of the storage content_type: str # Content type of the storage shared: bool # Shared storage + + @property + def free_space(self) -> int: + """ + Returns the free space in the storage in bytes + """ + return self.physical_size - self.physical_utilisation + @staticmethod def from_dict(data: dict[str, typing.Any], opaque_ref: str) -> 'StorageInfo':