Skip to content

Commit faa680d

Browse files
committed
Update
1 parent 030a7e6 commit faa680d

12 files changed

Lines changed: 447 additions & 129 deletions

File tree

backend/insert_vm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
if __name__ == "__main__":
66
xml_template = None
7+
xml_template_2 = None
78
with get_session() as session:
89
xml_template = session.exec(select(VirtualMachineXmlTemplate).where(VirtualMachineXmlTemplate.name == "Basic VM")).first()
10+
xml_template_2 = session.exec(select(VirtualMachineXmlTemplate).where(VirtualMachineXmlTemplate.name == "Basic VM USB2")).first()
911

1012
ovmf_path = None
1113
with get_session() as session:
@@ -74,7 +76,7 @@
7476
memory_min=1*1024*1024*1024,
7577
memory_max=1*1024*1024*1024,
7678
video_type=VirtualMachineBasicVideoTypes.QXL,
77-
xml_template=xml_template
79+
xml_template=xml_template_2
7880
)
7981

8082
with get_session() as session:

backend/insert_vm_templates.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def insert_vm_templates():
1515
<os>
1616
<type arch='x86_64' machine='{%machine_type%}'>hvm</type>
1717
{%loader%}
18+
<bootmenu enable="yes"/>
1819
</os>
1920
<features>
2021
<acpi/>
@@ -44,6 +45,60 @@ def insert_vm_templates():
4445
{%graphics%}
4546
{%video%}
4647
</devices>
48+
</domain>""")
49+
50+
xml_template_2 = VirtualMachineXmlTemplate(
51+
name="Basic VM USB2",
52+
description="Basic VM with USB2",
53+
content=
54+
"""<domain type='kvm'>
55+
<name>{%name%}</name>
56+
<memory unit='B'>{%memory_max%}</memory>
57+
<currentMemory unit='B'>{%memory_min%}</currentMemory>
58+
<vcpu placement='static' current='{%vcpu_current%}'>{%vcpu%}</vcpu>
59+
<os>
60+
<type arch='x86_64' machine='{%machine_type%}'>hvm</type>
61+
{%loader%}
62+
<bootmenu enable="yes"/>
63+
</os>
64+
<features>
65+
<acpi/>
66+
<apic/>
67+
<hyperv mode='custom'>
68+
<relaxed state='on'/>
69+
<vapic state='on'/>
70+
<spinlocks state='on' retries='8191'/>
71+
</hyperv>
72+
<vmport state='off'/>
73+
</features>
74+
<cpu mode='{%cpu_model%}' check='partial'/>
75+
<clock offset='utc'/>
76+
<on_poweroff>destroy</on_poweroff>
77+
<on_reboot>restart</on_reboot>
78+
<on_crash>destroy</on_crash>
79+
<devices>
80+
<emulator>{%qemu_path%}</emulator>
81+
{%devices_disk_file%}
82+
{%devices_network%}
83+
<controller type='pci' index='0' model='pcie-root'/>
84+
<controller type="usb" index="0" model="ich9-ehci1"/>
85+
<controller type="usb" index="0" model="ich9-uhci1">
86+
<master startport="0"/>
87+
</controller>
88+
<controller type="usb" index="0" model="ich9-uhci2">
89+
<master startport="2"/>
90+
</controller>
91+
<controller type="usb" index="0" model="ich9-uhci3">
92+
<master startport="4"/>
93+
</controller>
94+
<input type='tablet' bus='usb'>
95+
<address type='usb' bus='0' port='1'/>
96+
</input>
97+
<input type='mouse' bus='ps2'/>
98+
<input type='keyboard' bus='ps2'/>
99+
{%graphics%}
100+
{%video%}
101+
</devices>
47102
</domain>""")
48103

49104
# OVMF_path is the OVMF path in the database with name "OVMF"
@@ -70,7 +125,7 @@ def insert_vm_templates():
70125
ovmf_path=ovmf_path,
71126
memory_min=2*1024*1024*1024,
72127
memory_max=4*1024*1024*1024,
73-
video_type=VirtualMachineBasicVideoTypes.VIRTIO,
128+
video_type=VirtualMachineBasicVideoTypes.QXL,
74129
vdisk_required=True,
75130
vdisk_type=VirtualMachineBasicVDiskTypes.QCOW2,
76131
vdisk_bus_type=VirtualMachineBasicDiskBusTypes.SATA,
@@ -82,9 +137,39 @@ def insert_vm_templates():
82137
xml_template=xml_template
83138
)
84139

140+
vm_template_2 = VirtualMachineBasicTemplate(
141+
name="Windows 7",
142+
description="Windows 7",
143+
cpu_model="host-passthrough",
144+
vcpu=2,
145+
vcpu_current=2,
146+
vcpu_custom_topology=False,
147+
vcpu_custom_topology_sockets=None,
148+
vcpu_custom_topology_dies=None,
149+
vcpu_custom_topology_cores=None,
150+
vcpu_custom_topology_threads=None,
151+
machine_type="pc-q35-7.2",
152+
bios_type=VirtualMachineBasicBiosTypes.OVMF,
153+
ovmf_path=ovmf_path,
154+
memory_min=2*1024*1024*1024,
155+
memory_max=4*1024*1024*1024,
156+
video_type=VirtualMachineBasicVideoTypes.QXL,
157+
vdisk_required=True,
158+
vdisk_type=VirtualMachineBasicVDiskTypes.QCOW2,
159+
vdisk_bus_type=VirtualMachineBasicDiskBusTypes.SATA,
160+
vdisk_min_size=40*1024*1024*1024,
161+
network_interface_required=True,
162+
network_interface_type=VirtualMachineBasicNetworkTypes.E1000,
163+
cdrom_required=True,
164+
cdrom_bus_type=VirtualMachineBasicDiskBusTypes.SATA,
165+
xml_template=xml_template_2
166+
)
167+
85168
with get_session() as session:
86169
session.add(xml_template)
170+
session.add(xml_template_2)
87171
session.add(vm_template)
172+
session.add(vm_template_2)
88173
session.commit()
89174

90175
if __name__ == "__main__":
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
class VmManagerException(Exception):
1+
class VmException(Exception):
22
def __init__(self, message):
33
self.message = message
44
super().__init__(self.message)

backend/vm_manager/routes.py

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from .VmManagerException import VmManagerException
1+
from .VmException import VmException
22
from fastapi import APIRouter, Depends, HTTPException
33
from auth_manager.auth import check_auth
44
from db.database import get_session
55
from sqlmodel import select
6-
from .vmbasic import VirtualMachineBasic, VirtualMachineBasicTemplate, OvmfPath, VirtualMachineBasicConfig, VirtualMachineXmlTemplate, VirtualMachineDeviceDiskFile, VirtualMachineDeviceNetwork, VirtualMachineDeviceDiskBlock
6+
from .vmbasic import VirtualMachineBasic, VirtualMachineBasicTemplate, OvmfPath, VirtualMachineBasicLibvirtConfig, VirtualMachineXmlTemplate, VirtualMachineDeviceDiskFile, VirtualMachineDeviceNetwork, VirtualMachineDeviceDiskBlock, get_vm_networks
77

88
router = APIRouter()
99

@@ -34,13 +34,17 @@ async def api_vm_xml_template_get(xml_template_id: int, username: str = Depends(
3434
if xml_template is None:
3535
raise HTTPException(status_code=404, detail="XML Template not found")
3636
return xml_template
37-
37+
38+
@router.get("/networks")
39+
async def api_vm_networks_get(username: str = Depends(check_auth)):
40+
return get_vm_networks()
41+
3842
@router.get("/")
3943
async def api_vm_get(username: str = Depends(check_auth)):
4044
with get_session() as session:
4145
vms = session.exec(select(VirtualMachineBasic)).all()
4246

43-
vms = [VirtualMachineBasicConfig(vm).to_dict() for vm in vms]
47+
vms = [VirtualMachineBasicLibvirtConfig(vm).to_dict() for vm in vms]
4448
return vms
4549

4650
@router.get("/{vm_id}")
@@ -49,7 +53,7 @@ async def api_vm_get_id(vm_id: int, username: str = Depends(check_auth)):
4953
vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
5054
if vm is None:
5155
raise HTTPException(status_code=404, detail="VM not found")
52-
return VirtualMachineBasicConfig(vm).to_dict()
56+
return VirtualMachineBasicLibvirtConfig(vm).to_dict()
5357

5458
@router.delete("/{vm_id}")
5559
async def api_vm_delete(vm_id: int, username: str = Depends(check_auth)):
@@ -58,20 +62,45 @@ async def api_vm_delete(vm_id: int, username: str = Depends(check_auth)):
5862
if vm is None:
5963
raise HTTPException(status_code=404, detail="VM not found")
6064
try:
61-
VirtualMachineBasicConfig(vm).remove()
65+
VirtualMachineBasicLibvirtConfig(vm).remove()
6266
except Exception as e:
6367
raise HTTPException(status_code=500, detail=str(e))
6468
session.delete(vm)
6569
session.commit()
6670

71+
@router.put("/{vm_id}")
72+
async def api_vm_update(vm_id: int, vm: VirtualMachineBasic, username: str = Depends(check_auth)):
73+
with get_session() as session:
74+
old_vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
75+
if old_vm is None:
76+
raise HTTPException(status_code=404, detail="VM not found")
77+
old_vm.name = vm.name
78+
old_vm.autostart = vm.autostart
79+
old_vm.cpu_model = vm.cpu_model
80+
old_vm.vcpu = vm.vcpu
81+
old_vm.vcpu_current = vm.vcpu_current
82+
old_vm.vcpu_custom_topology = vm.vcpu_custom_topology
83+
old_vm.vcpu_custom_topology_sockets = vm.vcpu_custom_topology_sockets
84+
old_vm.vcpu_custom_topology_dies = vm.vcpu_custom_topology_dies
85+
old_vm.vcpu_custom_topology_cores = vm.vcpu_custom_topology_cores
86+
old_vm.vcpu_custom_topology_threads = vm.vcpu_custom_topology_threads
87+
old_vm.memory_min = vm.memory_min
88+
old_vm.memory_max = vm.memory_max
89+
old_vm.video_type = vm.video_type
90+
session.commit()
91+
return
92+
6793
@router.post("/{vm_id}/start")
6894
async def api_vm_start(vm_id: int, username: str = Depends(check_auth)):
6995
with get_session() as session:
7096
vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
7197
if vm is None:
7298
raise HTTPException(status_code=404, detail="VM not found")
7399
print(f"Starting VM {vm_id}")
74-
VirtualMachineBasicConfig(vm).start()
100+
try:
101+
VirtualMachineBasicLibvirtConfig(vm).start()
102+
except VmException as e:
103+
raise HTTPException(status_code=500, detail=str(e))
75104
return
76105

77106
@router.post("/{vm_id}/shutdown")
@@ -81,7 +110,7 @@ async def api_vm_shutdown(vm_id: int, username: str = Depends(check_auth)):
81110
if vm is None:
82111
raise HTTPException(status_code=404, detail="VM not found")
83112
print(f"Shutting down VM {vm_id}")
84-
VirtualMachineBasicConfig(vm).shutdown()
113+
VirtualMachineBasicLibvirtConfig(vm).shutdown()
85114
return
86115

87116
@router.post("/{vm_id}/forcestop")
@@ -91,7 +120,7 @@ async def api_vm_forcestop(vm_id: int, username: str = Depends(check_auth)):
91120
if vm is None:
92121
raise HTTPException(status_code=404, detail="VM not found")
93122
print(f"Force stopping VM {vm_id}")
94-
VirtualMachineBasicConfig(vm).forcestop()
123+
VirtualMachineBasicLibvirtConfig(vm).forcestop()
95124
return
96125

97126
@router.post("/{vm_id}/reset")
@@ -101,10 +130,9 @@ async def api_vm_reset(vm_id: int, username: str = Depends(check_auth)):
101130
if vm is None:
102131
raise HTTPException(status_code=404, detail="VM not found")
103132
print(f"Resetting VM {vm_id}")
104-
VirtualMachineBasicConfig(vm).reset()
133+
VirtualMachineBasicLibvirtConfig(vm).reset()
105134
return
106135

107-
# /devices actions
108136
@router.delete("/{vm_id}/devices/network/{device_id}")
109137
async def api_vm_delete_device_network(vm_id: int, device_id: int, username: str = Depends(check_auth)):
110138
with get_session() as session:
@@ -114,6 +142,19 @@ async def api_vm_delete_device_network(vm_id: int, device_id: int, username: str
114142
session.delete(network_device)
115143
session.commit()
116144

145+
@router.post("/{vm_id}/devices/network")
146+
async def api_vm_add_device_network(vm_id: int, device: VirtualMachineDeviceNetwork, username: str = Depends(check_auth)):
147+
print(f"Adding network device {device}")
148+
with get_session() as session:
149+
vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
150+
if vm is None:
151+
raise HTTPException(status_code=404, detail="VM not found")
152+
device.vm = vm
153+
session.add(device)
154+
session.commit()
155+
return device
156+
return
157+
117158
@router.delete("/{vm_id}/devices/disk-file/{device_id}")
118159
async def api_vm_delete_device_disk_file(vm_id: int, device_id: int, username: str = Depends(check_auth)):
119160
with get_session() as session:
@@ -123,6 +164,19 @@ async def api_vm_delete_device_disk_file(vm_id: int, device_id: int, username: s
123164
session.delete(disk_device_file)
124165
session.commit()
125166

167+
@router.post("/{vm_id}/devices/disk-file")
168+
async def api_vm_add_device_disk_file(vm_id: int, device: VirtualMachineDeviceDiskFile, username: str = Depends(check_auth)):
169+
print(f"Adding disk device {device}")
170+
with get_session() as session:
171+
vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
172+
if vm is None:
173+
raise HTTPException(status_code=404, detail="VM not found")
174+
device.vm = vm
175+
session.add(device)
176+
session.commit()
177+
return device
178+
return
179+
126180
@router.delete("/{vm_id}/devices/disk-block/{device_id}")
127181
async def api_vm_delete_device_disk_block(vm_id: int, device_id: int, username: str = Depends(check_auth)):
128182
with get_session() as session:
@@ -132,18 +186,15 @@ async def api_vm_delete_device_disk_block(vm_id: int, device_id: int, username:
132186
session.delete(disk_device_block)
133187
session.commit()
134188

135-
@router.post("/{vm_id}/devices/network")
136-
async def api_vm_add_device_network(vm_id: int, device: VirtualMachineDeviceNetwork, username: str = Depends(check_auth)):
137-
print(f"Adding network device {device}")
138-
# with get_session() as session:
139-
# vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
140-
# if vm is None:
141-
# raise HTTPException(status_code=404, detail="VM not found")
142-
# device.vm = vm
143-
# session.add(device)
144-
# session.commit()
145-
# return device
189+
@router.post("/{vm_id}/devices/disk-block")
190+
async def api_vm_add_device_disk_block(vm_id: int, device: VirtualMachineDeviceDiskBlock, username: str = Depends(check_auth)):
191+
print(f"Adding disk device {device}")
192+
with get_session() as session:
193+
vm = session.exec(select(VirtualMachineBasic).where(VirtualMachineBasic.id == vm_id)).first()
194+
if vm is None:
195+
raise HTTPException(status_code=404, detail="VM not found")
196+
device.vm = vm
197+
session.add(device)
198+
session.commit()
199+
return device
146200
return
147-
148-
149-

0 commit comments

Comments
 (0)