1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-12 04:58:34 +03:00

Fixed invalid node and redundant info on Proxmox. Also added empty result if an vm does not supports spice

This commit is contained in:
Adolfo Gómez García 2024-10-02 00:48:32 +02:00
parent 33d3b5d14a
commit e2ec608ead
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
7 changed files with 40 additions and 37 deletions

View File

@ -208,9 +208,8 @@ DEF_UPID: prox_types.ExecResult = prox_types.ExecResult(
DEF_VM_CREATION_RESULT: prox_types.VmCreationResult = prox_types.VmCreationResult(
node=DEF_NODES[0].name,
vmid=DEF_VMS_INFO[0].id,
upid=DEF_UPID,
exec_result=DEF_UPID,
)

View File

@ -62,7 +62,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
hagroup: str = ''
def setUp(self) -> None:
v = vars.get_vars('proxmox')
v = vars.get_vars('proxmox_cluster')
if not v:
self.skipTest('No proxmox vars')
@ -113,10 +113,10 @@ class TestProxmoxClient(UDSTransactionTestCase):
# if it exists when we try to create a new one, we will simply try to get another one
self.fail(f'Could not get a new vmid!!: last tried {vmid}')
def _wait_for_task(self, node: str, upid: str, timeout: int = 16) -> None:
def _wait_for_task(self, exec_result: prox_types.ExecResult, timeout: int = 16) -> None:
while timeout > 0:
timeout -= 1
task_info = self.pclient.get_task_info(node, upid)
task_info = self.pclient.get_task_info(exec_result.node, exec_result.upid)
if task_info.is_running():
time.sleep(1)
else:
@ -148,7 +148,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
must_have_vgpus=must_have_vgpus,
)
# Wait for the task to finish
self._wait_for_task(res.node, res.upid.upid)
self._wait_for_task(res.exec_result)
yield self.pclient.get_vm_info(res.vmid)
finally:
if res:
@ -158,7 +158,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
vminfo = self.pclient.get_vm_info(res.vmid)
if vminfo.status == prox_types.VMStatus.RUNNING:
exec_result = self.pclient.stop_vm(res.vmid)
self._wait_for_task(exec_result.node, exec_result.upid)
self._wait_for_task(exec_result)
except prox_exceptions.ProxmoxError:
pass
self.pclient.delete_vm(res.vmid)
@ -291,7 +291,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
with self._create_test_vm() as vm:
# Create snapshot for the vm
task = self.pclient.create_snapshot(vm.id, name='test-snapshot')
self._wait_for_task(task.node, task.upid)
self._wait_for_task(task)
snapshots = self.pclient.list_snapshots(vm.id)
self.assertIsInstance(snapshots, list)
# should have TWO snapshots, the one created by us and "current"
@ -304,11 +304,11 @@ class TestProxmoxClient(UDSTransactionTestCase):
# Restore the snapshot
task = self.pclient.restore_snapshot(vm.id, name='test-snapshot')
self._wait_for_task(task.node, task.upid)
self._wait_for_task(task)
# Delete the snapshot
task = self.pclient.delete_snapshot(vm.id, name='test-snapshot')
self._wait_for_task(task.node, task.upid)
self._wait_for_task(task)
snapshots = self.pclient.list_snapshots(vm.id)
self.assertTrue(len(snapshots) == 1)
@ -368,23 +368,23 @@ class TestProxmoxClient(UDSTransactionTestCase):
def test_start_stop_vm(self) -> None:
with self._create_test_vm() as vm:
task_info = self.pclient.start_vm(vm.id)
self._wait_for_task(task_info.node, task_info.upid)
self._wait_for_task(task_info)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.RUNNING)
task_info = self.pclient.stop_vm(vm.id)
self._wait_for_task(task_info.node, task_info.upid)
self._wait_for_task(task_info)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.STOPPED)
def test_shutdown_vm(self) -> None:
with self._create_test_vm() as vm:
task_info = self.pclient.start_vm(vm.id)
self._wait_for_task(task_info.node, task_info.upid)
self._wait_for_task(task_info)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.RUNNING)
start_time = time.time()
# The VM has no SO, so it will not shutdown gracefully but in 2 seconds will be stopped
task_info = self.pclient.shutdown_vm(vm.id, timeout=2)
self._wait_for_task(task_info.node, task_info.upid)
self._wait_for_task(task_info)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.STOPPED)
end_time = time.time()
self.assertGreaterEqual(end_time - start_time, 2)
@ -392,21 +392,21 @@ class TestProxmoxClient(UDSTransactionTestCase):
def test_suspend_resume_vm(self) -> None:
with self._create_test_vm() as vm:
result = self.pclient.start_vm(vm.id)
self._wait_for_task(result.node, result.upid)
self._wait_for_task(result)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.RUNNING)
result = self.pclient.suspend_vm(vm.id)
self._wait_for_task(result.node, result.upid)
self._wait_for_task(result)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.STOPPED)
result = self.pclient.resume_vm(vm.id)
self._wait_for_task(result.node, result.upid)
self._wait_for_task(result)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.RUNNING)
def test_convert_vm_to_template_and_clone(self) -> None:
with self._create_test_vm() as vm:
result = self.pclient.convert_vm_to_template(vm.id)
self._wait_for_task(result.node, result.upid)
self._wait_for_task(result)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).template)
with self._create_test_vm(vmid=vm.id, as_linked_clone=True):
@ -453,7 +453,7 @@ class TestProxmoxClient(UDSTransactionTestCase):
# Create an vm and start it
with self._create_test_vm() as vm:
result = self.pclient.start_vm(vm.id)
self._wait_for_task(result.node, result.upid)
self._wait_for_task(result)
self.assertTrue(self.pclient.get_vm_info(vm.id, force=True).status == prox_types.VMStatus.RUNNING)
# Get the console connection

View File

@ -92,6 +92,10 @@ class ConsoleConnectionInfo:
proxy: str = ''
monitors: int = 0
@staticmethod
def null() -> 'ConsoleConnectionInfo':
return ConsoleConnectionInfo(type='', address='') # All other values are default
@dataclasses.dataclass
class ConnectionData:
@ -282,4 +286,3 @@ class UserServiceInfo:
ip: typing.Optional[str]
userservice: 'models.UserService'
transport: 'models.Transport'

View File

@ -191,7 +191,7 @@ class ProxmoxUserserviceLinked(DynamicUserService):
comments = 'UDS Linked clone'
task_result = self.service().clone_vm(name, comments, template_id)
self._store_task(task_result.upid)
self._store_task(task_result.exec_result)
self._vmid = str(task_result.vmid)
def op_create_checker(self) -> types.states.TaskState:

View File

@ -440,9 +440,8 @@ class ProxmoxClient:
)
return types.VmCreationResult(
node=src_node,
vmid=new_vmid,
result=result,
exec_result=result,
)
@cached('hagrps', consts.CACHE_DURATION, key_helper=caching_key_helper)
@ -820,17 +819,20 @@ class ProxmoxClient:
Gets the connetion info for the specified machine
"""
node = node or self.get_vm_info(vmid).node
res: dict[str, typing.Any] = self.do_post(f'nodes/{node}/qemu/{vmid}/spiceproxy', node=node)['data']
return core_types.services.ConsoleConnectionInfo(
type=res['type'],
proxy=res['proxy'],
address=res['host'],
port=res.get('port', None),
secure_port=res['tls-port'],
cert_subject=res['host-subject'],
ticket=core_types.services.ConsoleConnectionTicket(value=res['password']),
ca=res.get('ca', None),
)
try:
res: dict[str, typing.Any] = self.do_post(f'nodes/{node}/qemu/{vmid}/spiceproxy', node=node)['data']
return core_types.services.ConsoleConnectionInfo(
type=res['type'],
proxy=res['proxy'],
address=res['host'],
port=res.get('port', None),
secure_port=res['tls-port'],
cert_subject=res['host-subject'],
ticket=core_types.services.ConsoleConnectionTicket(value=res['password']),
ca=res.get('ca', None),
)
except Exception: # Does not have spice or something went wrong
return core_types.services.ConsoleConnectionInfo.null()
# Sample data:
# 'data': {'proxy': 'http://pvealone.dkmon.com:3128',
# 'release-cursor': 'Ctrl+Alt+R',

View File

@ -407,9 +407,8 @@ class VMConfiguration:
@dataclasses.dataclass
class VmCreationResult:
node: str
vmid: int
upid: ExecResult
exec_result: ExecResult
@dataclasses.dataclass

View File

@ -100,7 +100,7 @@ class ProxmoxPublication(DynamicPublication, autoserializable.AutoSerializable):
# Name is generated on op_initialize by DynamicPublication
task = self.service().clone_vm(self._name, self.generate_annotation())
self._vmid = str(task.vmid)
self._task = ','.join((task.upid.node, task.upid.upid))
self._task = ','.join((task.exec_result.node, task.exec_result.upid))
def op_create_checker(self) -> types.states.TaskState:
node, upid = self._task.split(',')