virtui-manager 1.1.5__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {virtui_manager-1.1.5.dist-info → virtui_manager-1.3.0.dist-info}/METADATA +1 -1
- virtui_manager-1.3.0.dist-info/RECORD +73 -0
- vmanager/constants.py +737 -108
- vmanager/dialog.css +24 -0
- vmanager/firmware_manager.py +4 -1
- vmanager/i18n.py +32 -0
- vmanager/libvirt_utils.py +132 -3
- vmanager/locales/de/LC_MESSAGES/virtui-manager.po +3012 -0
- vmanager/locales/fr/LC_MESSAGES/virtui-manager.mo +0 -0
- vmanager/locales/fr/LC_MESSAGES/virtui-manager.po +3124 -0
- vmanager/locales/it/LC_MESSAGES/virtui-manager.po +3012 -0
- vmanager/locales/virtui-manager.pot +3012 -0
- vmanager/modals/bulk_modals.py +13 -12
- vmanager/modals/cache_stats_modal.py +6 -5
- vmanager/modals/capabilities_modal.py +133 -0
- vmanager/modals/config_modal.py +25 -24
- vmanager/modals/cpu_mem_pc_modals.py +22 -21
- vmanager/modals/custom_migration_modal.py +10 -9
- vmanager/modals/disk_pool_modals.py +60 -59
- vmanager/modals/host_dashboard_modal.py +137 -0
- vmanager/modals/howto_disk_modal.py +13 -72
- vmanager/modals/howto_network_modal.py +13 -39
- vmanager/modals/howto_overlay_modal.py +13 -52
- vmanager/modals/howto_ssh_modal.py +12 -67
- vmanager/modals/howto_virtiofs_modal.py +13 -64
- vmanager/modals/input_modals.py +11 -10
- vmanager/modals/log_modal.py +2 -1
- vmanager/modals/migration_modals.py +20 -18
- vmanager/modals/network_modals.py +45 -36
- vmanager/modals/provisioning_modals.py +56 -56
- vmanager/modals/select_server_modals.py +8 -7
- vmanager/modals/selection_modals.py +7 -6
- vmanager/modals/server_modals.py +24 -23
- vmanager/modals/server_prefs_modals.py +103 -87
- vmanager/modals/utils_modals.py +10 -9
- vmanager/modals/virsh_modals.py +3 -2
- vmanager/modals/virtiofs_modals.py +6 -5
- vmanager/modals/vm_type_info_modal.py +2 -1
- vmanager/modals/vmanager_modals.py +19 -19
- vmanager/modals/vmcard_dialog.py +57 -57
- vmanager/modals/vmdetails_modals.py +115 -123
- vmanager/modals/xml_modals.py +3 -2
- vmanager/network_manager.py +4 -1
- vmanager/storage_manager.py +182 -42
- vmanager/utils.py +39 -6
- vmanager/vm_actions.py +28 -24
- vmanager/vm_queries.py +67 -25
- vmanager/vm_service.py +8 -5
- vmanager/vmanager.css +46 -0
- vmanager/vmanager.py +178 -112
- vmanager/vmcard.py +161 -159
- vmanager/webconsole_manager.py +21 -21
- virtui_manager-1.1.5.dist-info/RECORD +0 -65
- {virtui_manager-1.1.5.dist-info → virtui_manager-1.3.0.dist-info}/WHEEL +0 -0
- {virtui_manager-1.1.5.dist-info → virtui_manager-1.3.0.dist-info}/entry_points.txt +0 -0
- {virtui_manager-1.1.5.dist-info → virtui_manager-1.3.0.dist-info}/licenses/LICENSE +0 -0
- {virtui_manager-1.1.5.dist-info → virtui_manager-1.3.0.dist-info}/top_level.txt +0 -0
|
@@ -54,6 +54,7 @@ from ..libvirt_utils import (
|
|
|
54
54
|
get_host_usb_devices, get_host_pci_devices,
|
|
55
55
|
get_host_numa_nodes
|
|
56
56
|
)
|
|
57
|
+
from ..constants import ErrorMessages, SuccessMessages, WarningMessages, DialogMessages, ButtonLabels, StaticText
|
|
57
58
|
from .utils_modals import ConfirmationDialog, ProgressModal
|
|
58
59
|
from .cpu_mem_pc_modals import (
|
|
59
60
|
EditCpuModal, EditMemoryModal, SelectMachineTypeModal,
|
|
@@ -69,13 +70,6 @@ from .howto_virtiofs_modal import HowToVirtIOFSModal
|
|
|
69
70
|
from .network_modals import AddEditNetworkInterfaceModal
|
|
70
71
|
from .input_modals import AddInputDeviceModal, AddChannelModal
|
|
71
72
|
|
|
72
|
-
# Configure logging
|
|
73
|
-
logging.basicConfig(
|
|
74
|
-
filename=get_log_path(),
|
|
75
|
-
level=logging.INFO,
|
|
76
|
-
format='%(asctime)s - %(levelname)s - %(message)s'
|
|
77
|
-
)
|
|
78
|
-
|
|
79
73
|
BootDevice = namedtuple("BootDevice", ["type", "id", "description", "boot_order_idx"])
|
|
80
74
|
|
|
81
75
|
class VMDetailModal(ModalScreen):
|
|
@@ -147,7 +141,7 @@ class VMDetailModal(ModalScreen):
|
|
|
147
141
|
ui_update_callback()
|
|
148
142
|
return
|
|
149
143
|
except Exception as e:
|
|
150
|
-
self.app.show_error_message(
|
|
144
|
+
self.app.show_error_message(ErrorMessages.UNEXPECTED_ERROR_OCCURRED_TEMPLATE_XML.format(error=e))
|
|
151
145
|
return
|
|
152
146
|
|
|
153
147
|
progress = ProgressModal("Applying changes...")
|
|
@@ -236,7 +230,7 @@ class VMDetailModal(ModalScreen):
|
|
|
236
230
|
all_networks_info = list_networks(self.conn)
|
|
237
231
|
self.available_networks = [net['name'] for net in all_networks_info]
|
|
238
232
|
except (libvirt.libvirtError, Exception) as e:
|
|
239
|
-
self.app.show_error_message(
|
|
233
|
+
self.app.show_error_message(ErrorMessages.VM_DETAIL_COULD_NOT_LOAD_NETWORKS.format(error=e))
|
|
240
234
|
self.available_networks = []
|
|
241
235
|
|
|
242
236
|
try:
|
|
@@ -545,10 +539,10 @@ class VMDetailModal(ModalScreen):
|
|
|
545
539
|
try:
|
|
546
540
|
set_boot_info(self.domain, menu_enabled, new_boot_order)
|
|
547
541
|
self._invalidate_cache()
|
|
548
|
-
self.app.show_success_message(
|
|
542
|
+
self.app.show_success_message(SuccessMessages.BOOT_ORDER_SAVED_SUCCESSFULLY)
|
|
549
543
|
self.boot_order = new_boot_order
|
|
550
544
|
except libvirt.libvirtError as e:
|
|
551
|
-
self.app.show_error_message(
|
|
545
|
+
self.app.show_error_message(ErrorMessages.ERROR_SAVING_BOOT_ORDER_TEMPLATE.format(error=e))
|
|
552
546
|
|
|
553
547
|
|
|
554
548
|
def _get_bootable_devices(self) -> list[BootDevice]:
|
|
@@ -721,13 +715,13 @@ class VMDetailModal(ModalScreen):
|
|
|
721
715
|
try:
|
|
722
716
|
change_vm_network(self.domain, mac_address, new_network)
|
|
723
717
|
self._invalidate_cache()
|
|
724
|
-
self.app.show_success_message(
|
|
718
|
+
self.app.show_success_message(SuccessMessages.VM_NETWORK_INTERFACE_CHANGED_TEMPLATE.format(mac_address=mac_address, new_network=new_network))
|
|
725
719
|
for i in self.vm_info["networks"]:
|
|
726
720
|
if i["mac"] == mac_address:
|
|
727
721
|
i["network"] = new_network
|
|
728
722
|
break
|
|
729
723
|
except (libvirt.libvirtError, ValueError, Exception) as e:
|
|
730
|
-
self.app.show_error_message(
|
|
724
|
+
self.app.show_error_message(ErrorMessages.ERROR_UPDATING_NETWORK_TEMPLATE_SHORT.format(error=e))
|
|
731
725
|
event.control.value = original_network
|
|
732
726
|
|
|
733
727
|
self.available_networks = []
|
|
@@ -753,7 +747,7 @@ class VMDetailModal(ModalScreen):
|
|
|
753
747
|
self._run_bulk_operation(
|
|
754
748
|
targets,
|
|
755
749
|
operation,
|
|
756
|
-
|
|
750
|
+
SuccessMessages.VM_CPU_MODEL_SET_SUCCESS.format(new_cpu_model=new_cpu_model) + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
757
751
|
"Errors setting CPU model",
|
|
758
752
|
ui_update
|
|
759
753
|
)
|
|
@@ -783,7 +777,7 @@ class VMDetailModal(ModalScreen):
|
|
|
783
777
|
self.query_one("#firmware-path-label").update(msg_text)
|
|
784
778
|
self.vm_info['firmware']['path'] = new_uefi_path
|
|
785
779
|
|
|
786
|
-
msg_template =
|
|
780
|
+
msg_template = SuccessMessages.VM_UEFI_FILE_SET_SUCCESS.format(uefi_file_name=os.path.basename(new_uefi_path) if new_uefi_path else 'BIOS')
|
|
787
781
|
if self.is_bulk:
|
|
788
782
|
msg_template += " for {count} VMs ({names})"
|
|
789
783
|
|
|
@@ -838,7 +832,7 @@ class VMDetailModal(ModalScreen):
|
|
|
838
832
|
self._run_bulk_operation(
|
|
839
833
|
targets,
|
|
840
834
|
operation,
|
|
841
|
-
|
|
835
|
+
SuccessMessages.VM_VIDEO_MODEL_SET_SUCCESS.format(new_model=new_model) + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
842
836
|
"Errors setting video model",
|
|
843
837
|
ui_update
|
|
844
838
|
)
|
|
@@ -862,7 +856,7 @@ class VMDetailModal(ModalScreen):
|
|
|
862
856
|
self._run_bulk_operation(
|
|
863
857
|
targets,
|
|
864
858
|
operation,
|
|
865
|
-
|
|
859
|
+
SuccessMessages.VM_3D_ACCELERATION_SET_SUCCESS.format(state='enabled' if accel3d_enabled else 'disabled') + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
866
860
|
"Errors setting 3D acceleration",
|
|
867
861
|
ui_update
|
|
868
862
|
)
|
|
@@ -889,7 +883,7 @@ class VMDetailModal(ModalScreen):
|
|
|
889
883
|
self._run_bulk_operation(
|
|
890
884
|
targets,
|
|
891
885
|
operation,
|
|
892
|
-
|
|
886
|
+
SuccessMessages.VM_SOUND_MODEL_SET_SUCCESS.format(new_model=new_model) + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
893
887
|
"Errors setting sound model",
|
|
894
888
|
ui_update
|
|
895
889
|
)
|
|
@@ -900,7 +894,7 @@ class VMDetailModal(ModalScreen):
|
|
|
900
894
|
|
|
901
895
|
current_uefi_path = self.vm_info['firmware'].get('path')
|
|
902
896
|
if not current_uefi_path and event.value: # Trying to enable secure boot without a UEFI file
|
|
903
|
-
self.app.show_error_message(
|
|
897
|
+
self.app.show_error_message(ErrorMessages.CANNOT_ENABLE_SECURE_BOOT_WITHOUT_UEFI)
|
|
904
898
|
event.checkbox.value = not event.value # Revert checkbox
|
|
905
899
|
self._update_uefi_options() # Revert options
|
|
906
900
|
return
|
|
@@ -917,7 +911,7 @@ class VMDetailModal(ModalScreen):
|
|
|
917
911
|
self._run_bulk_operation(
|
|
918
912
|
targets,
|
|
919
913
|
operation,
|
|
920
|
-
|
|
914
|
+
SuccessMessages.VM_SECURE_BOOT_SET_SUCCESS.format(state='enabled' if event.value else 'disabled') + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
921
915
|
"Errors setting Secure Boot",
|
|
922
916
|
ui_update
|
|
923
917
|
)
|
|
@@ -940,7 +934,7 @@ class VMDetailModal(ModalScreen):
|
|
|
940
934
|
self._run_bulk_operation(
|
|
941
935
|
targets,
|
|
942
936
|
operation,
|
|
943
|
-
|
|
937
|
+
SuccessMessages.VM_SHARED_MEMORY_SET_SUCCESS.format(state='enabled' if event.value else 'disabled') + (" for {count} VMs ({names})" if self.is_bulk else ""),
|
|
944
938
|
"Errors setting shared memory",
|
|
945
939
|
ui_update
|
|
946
940
|
)
|
|
@@ -998,7 +992,7 @@ class VMDetailModal(ModalScreen):
|
|
|
998
992
|
@on(Button.Pressed, "#graphics-apply-btn")
|
|
999
993
|
def on_graphics_apply_button_pressed(self, event: Button.Pressed) -> None:
|
|
1000
994
|
if not self.is_vm_stopped:
|
|
1001
|
-
self.app.show_error_message(
|
|
995
|
+
self.app.show_error_message(ErrorMessages.GRAPHICS_VM_MUST_BE_STOPPED)
|
|
1002
996
|
return
|
|
1003
997
|
|
|
1004
998
|
original_graphics_type = self.original_graphics_info.get('type')
|
|
@@ -1054,7 +1048,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1054
1048
|
self._run_bulk_operation(
|
|
1055
1049
|
targets,
|
|
1056
1050
|
operation,
|
|
1057
|
-
|
|
1051
|
+
SuccessMessages.GRAPHICS_SETTINGS_APPLIED_SUCCESSFULLY + (" (Applied to {count} VMs ({names}))" if self.is_bulk else ""),
|
|
1058
1052
|
"Errors applying graphics settings",
|
|
1059
1053
|
ui_update
|
|
1060
1054
|
)
|
|
@@ -1080,16 +1074,16 @@ class VMDetailModal(ModalScreen):
|
|
|
1080
1074
|
self._run_bulk_operation(
|
|
1081
1075
|
targets,
|
|
1082
1076
|
removal_operation,
|
|
1083
|
-
|
|
1077
|
+
SuccessMessages.SPICE_DEVICES_REMOVED_SUCCESS + (" (from {count} VMs ({names}))" if self.is_bulk else ""),
|
|
1084
1078
|
"Error removing SPICE devices",
|
|
1085
1079
|
do_apply_graphics_settings
|
|
1086
1080
|
)
|
|
1087
1081
|
else:
|
|
1088
1082
|
do_apply_graphics_settings()
|
|
1089
1083
|
|
|
1090
|
-
msg =
|
|
1084
|
+
msg = ErrorMessages.SPICE_REMOVAL_CONFIRMATION_SINGLE
|
|
1091
1085
|
if self.is_bulk:
|
|
1092
|
-
msg =
|
|
1086
|
+
msg = ErrorMessages.SPICE_REMOVAL_CONFIRMATION_BULK
|
|
1093
1087
|
|
|
1094
1088
|
self.app.push_screen(
|
|
1095
1089
|
ConfirmationDialog(msg),
|
|
@@ -1102,12 +1096,12 @@ class VMDetailModal(ModalScreen):
|
|
|
1102
1096
|
@on(Button.Pressed, "#apply-rng-btn")
|
|
1103
1097
|
def on_rng_apply_button_pressed(self, event: Button.Pressed) -> None:
|
|
1104
1098
|
if not self.is_vm_stopped:
|
|
1105
|
-
self.app.show_error_message(
|
|
1099
|
+
self.app.show_error_message(ErrorMessages.RNG_VM_MUST_BE_STOPPED)
|
|
1106
1100
|
return
|
|
1107
1101
|
|
|
1108
1102
|
rng_device = self.query_one("#rng-host-device", Input).value
|
|
1109
1103
|
if not rng_device:
|
|
1110
|
-
self.app.show_error_message(
|
|
1104
|
+
self.app.show_error_message(ErrorMessages.RNG_DEVICE_PATH_EMPTY)
|
|
1111
1105
|
return
|
|
1112
1106
|
|
|
1113
1107
|
targets = self.selected_domains if self.is_bulk else [self.domain]
|
|
@@ -1118,7 +1112,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1118
1112
|
self._run_bulk_operation(
|
|
1119
1113
|
targets,
|
|
1120
1114
|
operation,
|
|
1121
|
-
|
|
1115
|
+
SuccessMessages.RNG_SETTINGS_APPLIED_SUCCESSFULLY.format(rng_device=rng_device) + (" (Applied to {count} VMs ({names}))" if self.is_bulk else ""),
|
|
1122
1116
|
"Error applying RNG settings"
|
|
1123
1117
|
)
|
|
1124
1118
|
|
|
@@ -1141,7 +1135,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1141
1135
|
@on(Button.Pressed, "#apply-tpm-btn")
|
|
1142
1136
|
def on_tpm_apply_button_pressed(self, event: Button.Pressed) -> None:
|
|
1143
1137
|
if not self.is_vm_stopped:
|
|
1144
|
-
self.app.show_error_message(
|
|
1138
|
+
self.app.show_error_message(ErrorMessages.TPM_VM_MUST_BE_STOPPED)
|
|
1145
1139
|
return
|
|
1146
1140
|
|
|
1147
1141
|
tpm_model = self.query_one("#tpm-model-select", Select).value
|
|
@@ -1152,7 +1146,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1152
1146
|
|
|
1153
1147
|
# Basic validation for passthrough
|
|
1154
1148
|
if tpm_type == 'passthrough' and not device_path:
|
|
1155
|
-
self.app.show_error_message(
|
|
1149
|
+
self.app.show_error_message(ErrorMessages.DEVICE_PATH_REQUIRED_FOR_PASSTHROUGH_TPM)
|
|
1156
1150
|
return
|
|
1157
1151
|
|
|
1158
1152
|
targets = self.selected_domains if self.is_bulk else [self.domain]
|
|
@@ -1179,14 +1173,13 @@ class VMDetailModal(ModalScreen):
|
|
|
1179
1173
|
self.tpm_info = get_vm_tpm_info(root) # Refresh info
|
|
1180
1174
|
self._update_tpm_ui()
|
|
1181
1175
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1176
|
+
self._run_bulk_operation(
|
|
1177
|
+
targets,
|
|
1178
|
+
operation,
|
|
1179
|
+
SuccessMessages.TPM_SETTINGS_APPLIED_SUCCESSFULLY + (" (Applied to {count} VMs ({names}))" if self.is_bulk else ""),
|
|
1180
|
+
"Error applying TPM settings",
|
|
1181
|
+
ui_update
|
|
1182
|
+
)
|
|
1190
1183
|
@on(ListView.Highlighted, "#available-devices-list")
|
|
1191
1184
|
def on_available_devices_list_highlighted(self, event: ListView.Highlighted) -> None:
|
|
1192
1185
|
if not self.is_vm_stopped:
|
|
@@ -1276,11 +1269,11 @@ class VMDetailModal(ModalScreen):
|
|
|
1276
1269
|
try:
|
|
1277
1270
|
attach_usb_device(self.domain, vendor_id, product_id)
|
|
1278
1271
|
self._invalidate_cache()
|
|
1279
|
-
self.app.show_success_message(
|
|
1272
|
+
self.app.show_success_message(SuccessMessages.USB_DEVICE_ATTACHED_TEMPLATE.format(description=device_to_attach['description']))
|
|
1280
1273
|
self.xml_desc = self.vm_service._get_domain_xml(self.domain)
|
|
1281
1274
|
self._populate_usb_lists()
|
|
1282
1275
|
except libvirt.libvirtError as e:
|
|
1283
|
-
self.app.show_error_message(
|
|
1276
|
+
self.app.show_error_message(ErrorMessages.ERROR_ATTACHING_USB_DEVICE_TEMPLATE.format(error=e))
|
|
1284
1277
|
|
|
1285
1278
|
@on(Button.Pressed, "#detach-usb-btn")
|
|
1286
1279
|
def on_detach_usb_button_pressed(self, event: Button.Pressed) -> None:
|
|
@@ -1292,11 +1285,11 @@ class VMDetailModal(ModalScreen):
|
|
|
1292
1285
|
try:
|
|
1293
1286
|
detach_usb_device(self.domain, vendor_id, product_id)
|
|
1294
1287
|
self._invalidate_cache()
|
|
1295
|
-
self.app.show_success_message(
|
|
1288
|
+
self.app.show_success_message(SuccessMessages.USB_DEVICE_DETACHED_TEMPLATE.format(description=device_to_detach['description']))
|
|
1296
1289
|
self.xml_desc = self.vm_service._get_domain_xml(self.domain)
|
|
1297
1290
|
self._populate_usb_lists()
|
|
1298
1291
|
except libvirt.libvirtError as e:
|
|
1299
|
-
self.app.show_error_message(
|
|
1292
|
+
self.app.show_error_message(ErrorMessages.ERROR_DETACHING_USB_DEVICE_TEMPLATE.format(error=e))
|
|
1300
1293
|
|
|
1301
1294
|
def _populate_pci_lists(self):
|
|
1302
1295
|
"""Populates the PCI device lists."""
|
|
@@ -1348,11 +1341,11 @@ class VMDetailModal(ModalScreen):
|
|
|
1348
1341
|
|
|
1349
1342
|
@on(Button.Pressed, "#attach-pci-btn")
|
|
1350
1343
|
def on_attach_pci_button_pressed(self, event: Button.Pressed) -> None:
|
|
1351
|
-
self.app.show_error_message(
|
|
1344
|
+
self.app.show_error_message(ErrorMessages.PCI_PASSTHROUGH_NOT_IMPLEMENTED)
|
|
1352
1345
|
|
|
1353
1346
|
@on(Button.Pressed, "#detach-pci-btn")
|
|
1354
1347
|
def on_detach_pci_button_pressed(self, event: Button.Pressed) -> None:
|
|
1355
|
-
self.app.show_error_message(
|
|
1348
|
+
self.app.show_error_message(ErrorMessages.PCI_PASSTHROUGH_NOT_IMPLEMENTED)
|
|
1356
1349
|
|
|
1357
1350
|
def _populate_serial_table(self):
|
|
1358
1351
|
"""Populates the serial devices table."""
|
|
@@ -1555,10 +1548,10 @@ class VMDetailModal(ModalScreen):
|
|
|
1555
1548
|
result["target_name"]
|
|
1556
1549
|
)
|
|
1557
1550
|
self._invalidate_cache()
|
|
1558
|
-
self.app.show_success_message(
|
|
1551
|
+
self.app.show_success_message(SuccessMessages.CHANNEL_ADDED_SUCCESSFULLY)
|
|
1559
1552
|
self._update_channel_table()
|
|
1560
1553
|
except libvirt.libvirtError as e:
|
|
1561
|
-
self.app.show_error_message(
|
|
1554
|
+
self.app.show_error_message(ErrorMessages.ERROR_ADDING_CHANNEL_TEMPLATE.format(error=e))
|
|
1562
1555
|
|
|
1563
1556
|
self.app.push_screen(AddChannelModal(), add_channel_callback)
|
|
1564
1557
|
|
|
@@ -1567,19 +1560,19 @@ class VMDetailModal(ModalScreen):
|
|
|
1567
1560
|
if self.selected_channel:
|
|
1568
1561
|
target_name = self.selected_channel.get('name')
|
|
1569
1562
|
if not target_name:
|
|
1570
|
-
self.app.show_error_message(
|
|
1563
|
+
self.app.show_error_message(ErrorMessages.ADD_CHANNEL_NO_TARGET_NAME)
|
|
1571
1564
|
return
|
|
1572
1565
|
|
|
1573
|
-
message =
|
|
1566
|
+
message = DialogMessages.CONFIRM_REMOVE_CHANNEL_TEMPLATE.format(target_name=target_name)
|
|
1574
1567
|
def on_confirm(confirmed: bool) -> None:
|
|
1575
1568
|
if confirmed:
|
|
1576
1569
|
try:
|
|
1577
1570
|
remove_vm_channel(self.domain, target_name)
|
|
1578
1571
|
self._invalidate_cache()
|
|
1579
|
-
self.app.show_success_message(
|
|
1572
|
+
self.app.show_success_message(SuccessMessages.CHANNEL_REMOVED_SUCCESSFULLY_TEMPLATE.format(target_name=target_name))
|
|
1580
1573
|
self._update_channel_table()
|
|
1581
1574
|
except libvirt.libvirtError as e:
|
|
1582
|
-
self.app.show_error_message(
|
|
1575
|
+
self.app.show_error_message(ErrorMessages.ERROR_REMOVING_CHANNEL_TEMPLATE.format(error=e))
|
|
1583
1576
|
self.app.push_screen(ConfirmationDialog(message), on_confirm)
|
|
1584
1577
|
|
|
1585
1578
|
def compose(self) -> ComposeResult:
|
|
@@ -1600,12 +1593,12 @@ class VMDetailModal(ModalScreen):
|
|
|
1600
1593
|
if not self.is_bulk:
|
|
1601
1594
|
yield Label(f"ID: {self.vm_info.get('internal_id', 'N/A')}", id="vm-details-uuid")
|
|
1602
1595
|
|
|
1603
|
-
yield Button(
|
|
1596
|
+
yield Button(ButtonLabels.OTHER_TABS, id="toggle-detail-button", classes="toggle-detail-button")
|
|
1604
1597
|
with TabbedContent(id="detail-vm"):
|
|
1605
1598
|
with TabPane("CPU", id="detail-cpu-tab"):
|
|
1606
1599
|
with Vertical(classes="info-details"):
|
|
1607
1600
|
yield Label(f"CPU: {self.vm_info.get('cpu', 'N/A')}", id="cpu-label", classes="tabd")
|
|
1608
|
-
yield Button(
|
|
1601
|
+
yield Button(ButtonLabels.EDIT, id="edit-cpu", classes="edit-detail-btn")
|
|
1609
1602
|
yield Static(classes="button-separator")
|
|
1610
1603
|
|
|
1611
1604
|
# CPU Model Selection
|
|
@@ -1636,7 +1629,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1636
1629
|
# CPU Tune
|
|
1637
1630
|
vcpupin_count = len(self.cputune_info.get('vcpupin', []))
|
|
1638
1631
|
yield Label(f"CPU Pinning: {vcpupin_count} rules", id="cputune-label", classes="tabd")
|
|
1639
|
-
yield Button(
|
|
1632
|
+
yield Button(ButtonLabels.EDIT_CPU_TUNE, id="edit-cputune", classes="edit-detail-btn", disabled=not self.is_vm_stopped)
|
|
1640
1633
|
|
|
1641
1634
|
yield Static(classes="button-separator")
|
|
1642
1635
|
|
|
@@ -1645,12 +1638,12 @@ class VMDetailModal(ModalScreen):
|
|
|
1645
1638
|
yield Label(f"NUMA Mode: {numa_mode}", id="numatune-label", classes="tabd")
|
|
1646
1639
|
|
|
1647
1640
|
numa_btn_disabled = not self.is_vm_stopped or self.host_numa_nodes <= 1
|
|
1648
|
-
yield Button(
|
|
1641
|
+
yield Button(ButtonLabels.EDIT_NUMA_TUNE, id="edit-numatune", classes="edit-detail-btn", disabled=numa_btn_disabled)
|
|
1649
1642
|
|
|
1650
1643
|
with TabPane("Mem", id="detail-mem-tab", ):
|
|
1651
1644
|
with Vertical(classes="info-details"):
|
|
1652
1645
|
yield Label(f"Memory: {self.vm_info.get('memory', 'N/A')} MB", id="memory-label", classes="tabd")
|
|
1653
|
-
yield Button(
|
|
1646
|
+
yield Button(ButtonLabels.EDIT, id="edit-memory", classes="edit-detail-btn")
|
|
1654
1647
|
yield Static(classes="button-separator")
|
|
1655
1648
|
yield Checkbox("Shared Memory", value=self.vm_info.get('shared_memory', False), id="shared-memory-checkbox", classes="shared-memory", disabled=not self.is_vm_stopped)
|
|
1656
1649
|
if not self.is_bulk:
|
|
@@ -1680,34 +1673,34 @@ class VMDetailModal(ModalScreen):
|
|
|
1680
1673
|
allow_blank=True,
|
|
1681
1674
|
)
|
|
1682
1675
|
yield Static(classes="button-separator")
|
|
1683
|
-
yield Button(
|
|
1676
|
+
yield Button(ButtonLabels.SWITCH_TO_BIOS, id="switch-to-bios", disabled=not self.is_vm_stopped)
|
|
1684
1677
|
else:
|
|
1685
|
-
yield Button(
|
|
1678
|
+
yield Button(ButtonLabels.SWITCH_TO_UEFI, id="switch-to-uefi", disabled=not self.is_vm_stopped)
|
|
1686
1679
|
|
|
1687
1680
|
|
|
1688
1681
|
if "machine_type" in self.vm_info:
|
|
1689
1682
|
yield Static(classes="button-separator")
|
|
1690
1683
|
yield Label(f"Machine Type: {self.vm_info['machine_type']}", id="machine-type-label", classes="tabd")
|
|
1691
|
-
yield Button(
|
|
1684
|
+
yield Button(ButtonLabels.EDIT, id="edit-machine-type", classes="edit-detail-btn", disabled=not self.is_vm_stopped)
|
|
1692
1685
|
|
|
1693
1686
|
|
|
1694
1687
|
with TabPane("Boot", id="detail-boot-tab"):
|
|
1695
1688
|
with Vertical():
|
|
1696
|
-
yield Checkbox(
|
|
1689
|
+
yield Checkbox(StaticText.ENABLE_BOOT_MENU, id="boot-menu-enable", disabled=not self.is_vm_stopped)
|
|
1697
1690
|
with Horizontal(classes="boot-manager"):
|
|
1698
1691
|
with Vertical(classes="boot-main-container"):
|
|
1699
|
-
yield Label(
|
|
1692
|
+
yield Label(StaticText.BOOT_ORDER)
|
|
1700
1693
|
yield ListView(id="boot-order-list", classes="boot-list-container")
|
|
1701
1694
|
with Vertical(classes="boot-buttons-container"):
|
|
1702
|
-
yield Label(
|
|
1703
|
-
yield Button(
|
|
1704
|
-
yield Button(
|
|
1705
|
-
yield Button(
|
|
1706
|
-
yield Button(
|
|
1695
|
+
yield Label(StaticText.EMPTY_LABEL)
|
|
1696
|
+
yield Button(ButtonLabels.BOOT_ADD, id="boot-add", disabled=not self.is_vm_stopped)
|
|
1697
|
+
yield Button(ButtonLabels.BOOT_REMOVE, id="boot-remove", disabled=not self.is_vm_stopped)
|
|
1698
|
+
yield Button(ButtonLabels.BOOT_UP, id="boot-up", disabled=not self.is_vm_stopped)
|
|
1699
|
+
yield Button(ButtonLabels.BOOT_DOWN, id="boot-down", disabled=not self.is_vm_stopped)
|
|
1707
1700
|
with Vertical(classes="boot-main-container"):
|
|
1708
|
-
yield Label(
|
|
1701
|
+
yield Label(StaticText.AVAILABLE_DEVICES)
|
|
1709
1702
|
yield ListView(id="available-devices-list", classes="boot-list-container")
|
|
1710
|
-
yield Button(
|
|
1703
|
+
yield Button(ButtonLabels.SAVE_BOOT_ORDER, id="save-boot-order", disabled=not self.is_vm_stopped, variant="primary")
|
|
1711
1704
|
|
|
1712
1705
|
with TabPane("Disks", id="detail-disk-tab"):
|
|
1713
1706
|
with ScrollableContainer(classes="info-details"):
|
|
@@ -1716,20 +1709,20 @@ class VMDetailModal(ModalScreen):
|
|
|
1716
1709
|
disks_info = self.vm_info.get("disks", [])
|
|
1717
1710
|
has_enabled_disks = any(d['status'] == 'enabled' for d in disks_info)
|
|
1718
1711
|
has_disabled_disks = any(d['status'] == 'disabled' for d in disks_info)
|
|
1719
|
-
remove_button = Button(
|
|
1720
|
-
disable_button = Button(
|
|
1721
|
-
enable_button = Button(
|
|
1712
|
+
remove_button = Button(ButtonLabels.REMOVE_DISK, id="detail_remove_disk", classes="detail-disks")
|
|
1713
|
+
disable_button = Button(ButtonLabels.DISABLE_DISK, id="detail_disable_disk", classes="detail-disks")
|
|
1714
|
+
enable_button = Button(ButtonLabels.ENABLE_DISK, id="detail_enable_disk", classes="detail-disks")
|
|
1722
1715
|
remove_button.display = has_enabled_disks
|
|
1723
1716
|
disable_button.display = has_enabled_disks
|
|
1724
1717
|
enable_button.display = has_disabled_disks
|
|
1725
1718
|
|
|
1726
1719
|
with Vertical(classes="button-details"):
|
|
1727
1720
|
with Horizontal():
|
|
1728
|
-
yield Button(
|
|
1729
|
-
yield Button(
|
|
1730
|
-
yield Button(
|
|
1721
|
+
yield Button(ButtonLabels.ADD_DISK, id="detail_add_disk", classes="detail-disks")
|
|
1722
|
+
yield Button(ButtonLabels.ATTACH_EXISTING_DISK, id="detail_attach_disk", classes="detail-disks")
|
|
1723
|
+
yield Button(ButtonLabels.EDIT_DISK, id="detail_edit_disk", classes="detail-disks", disabled=True)
|
|
1731
1724
|
yield remove_button
|
|
1732
|
-
yield Button(
|
|
1725
|
+
yield Button(ButtonLabels.DISK_HELP, id="detail_disk_help", classes="detail-disks")
|
|
1733
1726
|
|
|
1734
1727
|
with Horizontal(classes="button-details"):
|
|
1735
1728
|
yield disable_button
|
|
@@ -1748,14 +1741,14 @@ class VMDetailModal(ModalScreen):
|
|
|
1748
1741
|
|
|
1749
1742
|
with Vertical(classes="button-details"):
|
|
1750
1743
|
with Horizontal():
|
|
1751
|
-
yield Button(
|
|
1752
|
-
yield Button(
|
|
1753
|
-
yield Button(
|
|
1744
|
+
yield Button(ButtonLabels.EDIT_INTERFACE, id="edit-network-interface-button", classes="detail-disks", variant="primary", disabled=True)
|
|
1745
|
+
yield Button(ButtonLabels.ADD_INTERFACE, id="add-network-interface-button", classes="detail-disks", variant="primary")
|
|
1746
|
+
yield Button(ButtonLabels.REMOVE_INTERFACE, id="remove-network-interface-button", classes="detail-disks", variant="error", disabled=True)
|
|
1754
1747
|
|
|
1755
1748
|
if self.vm_info.get("devices"):
|
|
1756
1749
|
with TabPane("VirtIO-FS", id="detail-virtiofs-tab"):
|
|
1757
1750
|
# Always create label, toggle visibility
|
|
1758
|
-
lbl = Label(
|
|
1751
|
+
lbl = Label(WarningMessages.VIRTIOFS_SHARED_MEM_WARNING, id="virtiofs-shared-mem-warning", classes="tabd-warning")
|
|
1759
1752
|
lbl.display = not self.vm_info.get('shared_memory')
|
|
1760
1753
|
yield lbl
|
|
1761
1754
|
with ScrollableContainer(classes="info-details"):
|
|
@@ -1774,10 +1767,10 @@ class VMDetailModal(ModalScreen):
|
|
|
1774
1767
|
yield virtiofs_table
|
|
1775
1768
|
with Vertical(classes="button-details"):
|
|
1776
1769
|
with Horizontal():
|
|
1777
|
-
yield Button(
|
|
1778
|
-
yield Button(
|
|
1779
|
-
yield Button(
|
|
1780
|
-
yield Button(
|
|
1770
|
+
yield Button(ButtonLabels.ADD, variant="primary", id="add-virtiofs-btn", classes="detail-disks")
|
|
1771
|
+
yield Button(ButtonLabels.EDIT, variant="default", id="edit-virtiofs-btn", disabled=True, classes="detail-disks")
|
|
1772
|
+
yield Button(ButtonLabels.DELETE, variant="error", id="delete-virtiofs-btn", disabled=True, classes="detail-disks")
|
|
1773
|
+
yield Button(ButtonLabels.VIRTIOFS_HELP, id="detail_virtiofs_help", classes="detail-disks")
|
|
1781
1774
|
|
|
1782
1775
|
with TabPane("Video", id="detail-video-tab"):
|
|
1783
1776
|
with Vertical(classes="info-details"):
|
|
@@ -1854,25 +1847,25 @@ class VMDetailModal(ModalScreen):
|
|
|
1854
1847
|
|
|
1855
1848
|
with TabPane("Graphics", id="detail-graphics-tab"):
|
|
1856
1849
|
with ScrollableContainer(classes="info-details"):
|
|
1857
|
-
yield Label(
|
|
1850
|
+
yield Label(StaticText.TYPE_LABEL)
|
|
1858
1851
|
yield Select(
|
|
1859
1852
|
[("VNC", "vnc"), ("Spice", "spice"), ("None", "")],
|
|
1860
1853
|
value=self.graphics_info['type'],
|
|
1861
1854
|
id="graphics-type-select",
|
|
1862
1855
|
disabled=not self.is_vm_stopped
|
|
1863
1856
|
)
|
|
1864
|
-
yield Label(
|
|
1857
|
+
yield Label(StaticText.LISTEN_TYPE)
|
|
1865
1858
|
yield Select(
|
|
1866
1859
|
[("Address", "address"), ("None", "none")],
|
|
1867
1860
|
value=self.graphics_info['listen_type'],
|
|
1868
1861
|
id="graphics-listen-type-select",
|
|
1869
1862
|
disabled=not self.is_vm_stopped
|
|
1870
1863
|
)
|
|
1871
|
-
yield Label(
|
|
1864
|
+
yield Label(StaticText.ADDRESS_LABEL)
|
|
1872
1865
|
with RadioSet(id="graphics-address-radioset", disabled=not self.is_vm_stopped or self.graphics_info['listen_type'] != 'address'):
|
|
1873
|
-
yield RadioButton(
|
|
1874
|
-
yield RadioButton(
|
|
1875
|
-
yield RadioButton(
|
|
1866
|
+
yield RadioButton(StaticText.HYPERVISOR_DEFAULT, id="graphics-address-default", value=self.graphics_info['address'] not in ['127.0.0.1', '0.0.0.0'])
|
|
1867
|
+
yield RadioButton(StaticText.LOCALHOST_ONLY, id="graphics-address-localhost", value=self.graphics_info['address'] == '127.0.0.1')
|
|
1868
|
+
yield RadioButton(StaticText.ALL_INTERFACES, id="graphics-address-all", value=self.graphics_info['address'] == '0.0.0.0')
|
|
1876
1869
|
yield Checkbox(
|
|
1877
1870
|
"Auto Port",
|
|
1878
1871
|
value=self.graphics_info['autoport'],
|
|
@@ -1899,7 +1892,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1899
1892
|
password=True, # Hide password input
|
|
1900
1893
|
disabled=not self.is_vm_stopped or not self.graphics_info['password_enabled']
|
|
1901
1894
|
)
|
|
1902
|
-
yield Button(
|
|
1895
|
+
yield Button(ButtonLabels.APPLY_GRAPHICS_SETTINGS, id="graphics-apply-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
1903
1896
|
with TabPane("TPM", id="detail-tpm-tab"):
|
|
1904
1897
|
tpm_model = self.tpm_info[0].get('model') if self.tpm_info else 'none'
|
|
1905
1898
|
tpm_type = self.tpm_info[0].get('type') if self.tpm_info else 'emulated'
|
|
@@ -1908,7 +1901,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1908
1901
|
tpm_backend_path = self.tpm_info[0].get('backend_path', '') if self.tpm_info else ''
|
|
1909
1902
|
|
|
1910
1903
|
with Vertical(classes="info-details"):
|
|
1911
|
-
yield Label(
|
|
1904
|
+
yield Label(StaticText.TPM_MODEL)
|
|
1912
1905
|
yield Select(
|
|
1913
1906
|
[("None", "none"), ("tpm-crb", "tpm-crb"), ("tpm-tis", "tpm-tis")],
|
|
1914
1907
|
value=tpm_model,
|
|
@@ -1916,7 +1909,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1916
1909
|
disabled=not self.is_vm_stopped,
|
|
1917
1910
|
allow_blank=False,
|
|
1918
1911
|
)
|
|
1919
|
-
yield Label(
|
|
1912
|
+
yield Label(StaticText.TPM_TYPE)
|
|
1920
1913
|
yield Select(
|
|
1921
1914
|
[("Emulated", "emulated"), ("Passthrough", "passthrough")],
|
|
1922
1915
|
value=tpm_type,
|
|
@@ -1924,51 +1917,51 @@ class VMDetailModal(ModalScreen):
|
|
|
1924
1917
|
disabled=not self.is_vm_stopped,
|
|
1925
1918
|
allow_blank=False,
|
|
1926
1919
|
)
|
|
1927
|
-
yield Label(
|
|
1920
|
+
yield Label(StaticText.DEVICE_PATH_PASSTHROUGH)
|
|
1928
1921
|
yield Input(
|
|
1929
1922
|
value=tpm_device_path,
|
|
1930
1923
|
id="tpm-device-path-input",
|
|
1931
1924
|
disabled=not self.is_vm_stopped or tpm_type != 'passthrough',
|
|
1932
|
-
placeholder="
|
|
1925
|
+
placeholder="=/dev/tpm0"
|
|
1933
1926
|
)
|
|
1934
|
-
yield Label(
|
|
1927
|
+
yield Label(StaticText.BACKEND_TYPE_PASSTHROUGH)
|
|
1935
1928
|
yield Input(
|
|
1936
1929
|
value=tpm_backend_type,
|
|
1937
1930
|
id="tpm-backend-type-input",
|
|
1938
1931
|
disabled=not self.is_vm_stopped or tpm_type != 'passthrough',
|
|
1939
1932
|
placeholder="emulator or passthrough"
|
|
1940
1933
|
)
|
|
1941
|
-
yield Label(
|
|
1934
|
+
yield Label(StaticText.BACKEND_PATH_PASSTHROUGH)
|
|
1942
1935
|
yield Input(
|
|
1943
1936
|
value=tpm_backend_path,
|
|
1944
1937
|
id="tpm-backend-path-input",
|
|
1945
1938
|
disabled=not self.is_vm_stopped or tpm_type != 'passthrough',
|
|
1946
1939
|
placeholder="/dev/tpmrm0"
|
|
1947
1940
|
)
|
|
1948
|
-
yield Button(
|
|
1941
|
+
yield Button(ButtonLabels.APPLY_TPM_SETTINGS, id="apply-tpm-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
1949
1942
|
|
|
1950
1943
|
|
|
1951
1944
|
with TabbedContent(id="detail2-vm"):
|
|
1952
1945
|
with TabPane("RNG", id="detail-rng-tab"):
|
|
1953
1946
|
with Vertical(classes="info-details"):
|
|
1954
1947
|
current_path = self.rng_info["backend_path"]
|
|
1955
|
-
yield Label(
|
|
1948
|
+
yield Label(StaticText.HOST_DEVICE)
|
|
1956
1949
|
yield Input(value=current_path, id="rng-host-device")
|
|
1957
|
-
yield Button(
|
|
1950
|
+
yield Button(ButtonLabels.APPLY_RNG_SETTINGS, id="apply-rng-btn", variant="primary")
|
|
1958
1951
|
|
|
1959
1952
|
with TabPane("Serial", id="detail-serial-tab"):
|
|
1960
1953
|
with ScrollableContainer(classes="info-details"):
|
|
1961
1954
|
yield DataTable(id="serial-table", cursor_type="row")
|
|
1962
1955
|
with Vertical(classes="button-details"):
|
|
1963
1956
|
with Horizontal():
|
|
1964
|
-
yield Button(
|
|
1965
|
-
yield Button(
|
|
1957
|
+
yield Button(ButtonLabels.ADD_PTY_CONSOLE, id="add-serial-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
1958
|
+
yield Button(ButtonLabels.REMOVE_CONSOLE, id="remove-serial-btn", variant="error", disabled=True)
|
|
1966
1959
|
with TabPane("Watchdog", id="detail-watchdog-tab"):
|
|
1967
1960
|
watchdog_model = self.watchdog_info.get('model') if self.watchdog_info and self.watchdog_info.get('model') else 'none'
|
|
1968
1961
|
watchdog_action = self.watchdog_info.get('action') if self.watchdog_info and self.watchdog_info.get('action') else 'reset'
|
|
1969
1962
|
|
|
1970
1963
|
with Vertical(classes="info-details"):
|
|
1971
|
-
yield Label(
|
|
1964
|
+
yield Label(StaticText.WATCHDOG_MODEL)
|
|
1972
1965
|
|
|
1973
1966
|
watchdog_models = [("None", "none"), ("i6300esb", "i6300esb"), ("ib700", "ib700"), ("diag288", "diag288")]
|
|
1974
1967
|
|
|
@@ -1984,7 +1977,7 @@ class VMDetailModal(ModalScreen):
|
|
|
1984
1977
|
disabled=not self.is_vm_stopped,
|
|
1985
1978
|
allow_blank=False
|
|
1986
1979
|
)
|
|
1987
|
-
yield Label(
|
|
1980
|
+
yield Label(StaticText.ACTION_LABEL)
|
|
1988
1981
|
yield Select(
|
|
1989
1982
|
[("Reset", "reset"), ("Shutdown", "shutdown"), ("Poweroff", "poweroff"), ("Pause", "pause"), ("None", "none"), ("Dump", "dump"), ("Inject-NMI", "inject-nmi")],
|
|
1990
1983
|
value=watchdog_action,
|
|
@@ -1994,8 +1987,8 @@ class VMDetailModal(ModalScreen):
|
|
|
1994
1987
|
)
|
|
1995
1988
|
with Vertical(classes="button-details"):
|
|
1996
1989
|
with Horizontal():
|
|
1997
|
-
yield Button(
|
|
1998
|
-
yield Button(
|
|
1990
|
+
yield Button(ButtonLabels.APPLY_WATCHDOG_SETTINGS, id="apply-watchdog-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
1991
|
+
yield Button(ButtonLabels.REMOVE_WATCHDOG, id="remove-watchdog-btn", variant="error", disabled=not self.is_vm_stopped or watchdog_model == 'none')
|
|
1999
1992
|
|
|
2000
1993
|
if not self.is_bulk:
|
|
2001
1994
|
with TabPane("Input", id="detail-input-tab"):
|
|
@@ -2003,41 +1996,40 @@ class VMDetailModal(ModalScreen):
|
|
|
2003
1996
|
yield DataTable(id="input-table", cursor_type="row")
|
|
2004
1997
|
with Vertical(classes="button-details"):
|
|
2005
1998
|
with Horizontal():
|
|
2006
|
-
yield Button(
|
|
2007
|
-
yield Button(
|
|
1999
|
+
yield Button(ButtonLabels.ADD_INPUT, id="add-input-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
2000
|
+
yield Button(ButtonLabels.REMOVE_INPUT, id="remove-input-btn", variant="error", disabled=True)
|
|
2008
2001
|
|
|
2009
2002
|
with TabPane("Controller", id="detail-controler-tab"):
|
|
2010
2003
|
with ScrollableContainer(classes="info-details"):
|
|
2011
2004
|
yield DataTable(id="controller-table", cursor_type="row")
|
|
2012
2005
|
with Vertical(classes="button-details"):
|
|
2013
2006
|
with Horizontal():
|
|
2014
|
-
yield Button(
|
|
2015
|
-
yield Button(
|
|
2016
|
-
yield Button(
|
|
2017
|
-
yield Button(
|
|
2018
|
-
|
|
2007
|
+
yield Button(ButtonLabels.ADD_USB2, id="add-usb2-controller-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
2008
|
+
yield Button(ButtonLabels.ADD_USB3, id="add-usb3-controller-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
2009
|
+
yield Button(ButtonLabels.ADD_SCSI, id="add-scsi-controller-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
2010
|
+
yield Button(ButtonLabels.REMOVE, id="remove-controller-btn", variant="error", disabled=True)
|
|
2019
2011
|
if not self.is_bulk:
|
|
2020
2012
|
with TabPane("USB Host", id="detail-usbhost-tab"):
|
|
2021
2013
|
with Horizontal(classes="boot-manager"):
|
|
2022
2014
|
with Vertical(classes="boot-main-container"):
|
|
2023
|
-
yield Label(
|
|
2015
|
+
yield Label(StaticText.AVAILABLE_HOST_USB)
|
|
2024
2016
|
yield ListView(id="available-usb-list", classes="boot-list-container")
|
|
2025
2017
|
with Vertical(classes="boot-buttons-container"):
|
|
2026
|
-
yield Button(
|
|
2027
|
-
yield Button(
|
|
2018
|
+
yield Button(ButtonLabels.ATTACH_ARROW, id="attach-usb-btn", disabled=True)
|
|
2019
|
+
yield Button(ButtonLabels.DETACH_ARROW, id="detach-usb-btn", disabled=True)
|
|
2028
2020
|
with Vertical(classes="boot-main-container"):
|
|
2029
|
-
yield Label(
|
|
2021
|
+
yield Label(StaticText.ATTACHED_TO_VM)
|
|
2030
2022
|
yield ListView(id="attached-usb-list", classes="boot-list-container")
|
|
2031
2023
|
with TabPane("PCI Host", id="detail-PCIhost-tab"):
|
|
2032
2024
|
with Horizontal(classes="boot-manager"):
|
|
2033
2025
|
with Vertical(classes="boot-main-container"):
|
|
2034
|
-
yield Label(
|
|
2026
|
+
yield Label(StaticText.AVAILABLE_HOST_PCI)
|
|
2035
2027
|
yield ListView(id="available-pci-list", classes="boot-list-container")
|
|
2036
2028
|
with Vertical(classes="boot-buttons-container"):
|
|
2037
|
-
yield Button(
|
|
2038
|
-
yield Button(
|
|
2029
|
+
yield Button(ButtonLabels.ATTACH_ARROW, id="attach-pci-btn", disabled=True)
|
|
2030
|
+
yield Button(ButtonLabels.DETACH_ARROW, id="detach-pci-btn", disabled=True)
|
|
2039
2031
|
with Vertical(classes="boot-main-container"):
|
|
2040
|
-
yield Label(
|
|
2032
|
+
yield Label(StaticText.ATTACHED_TO_VM)
|
|
2041
2033
|
yield ListView(id="attached-pci-list", classes="boot-list-container")
|
|
2042
2034
|
#with TabPane("PCIe", id="detail-pcie-tab"):
|
|
2043
2035
|
# yield Label("PCIe")
|
|
@@ -2048,10 +2040,10 @@ class VMDetailModal(ModalScreen):
|
|
|
2048
2040
|
yield DataTable(id="channel-table", cursor_type="row")
|
|
2049
2041
|
with Vertical(classes="button-details"):
|
|
2050
2042
|
with Horizontal():
|
|
2051
|
-
yield Button(
|
|
2052
|
-
yield Button(
|
|
2043
|
+
yield Button(ButtonLabels.ADD_CHANNEL, id="add-channel-btn", variant="primary", disabled=not self.is_vm_stopped)
|
|
2044
|
+
yield Button(ButtonLabels.REMOVE_CHANNEL, id="remove-channel-btn", variant="error", disabled=True)
|
|
2053
2045
|
|
|
2054
|
-
yield Button(
|
|
2046
|
+
yield Button(ButtonLabels.CLOSE, variant="default", id="close-btn", classes="close-button")
|
|
2055
2047
|
|
|
2056
2048
|
def _update_tpm_ui(self) -> None:
|
|
2057
2049
|
"""Updates the UI elements for the TPM tab based on self.tpm_info."""
|