inspection: Show inspection error in details page
This commit is contained in:
parent
c21e0db6ea
commit
2dcfaafcac
356
ui/details.ui
356
ui/details.ui
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.2 -->
|
||||
<!-- Generated with glade 3.20.3 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.14"/>
|
||||
<object class="GtkAccelGroup" id="accelgroup1"/>
|
||||
|
@ -1399,171 +1399,114 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box12">
|
||||
<object class="GtkBox" id="box14">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box14">
|
||||
<object class="GtkFrame" id="details-inspection-os">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="details-inspection-os">
|
||||
<object class="GtkAlignment" id="alignment43">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment43">
|
||||
<object class="GtkGrid" id="table17">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="table17">
|
||||
<object class="GtkLabel" id="label72">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label72">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Product name:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="inspection-hostname">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">foo</property>
|
||||
<property name="selectable">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label71">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Hostname:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Operating system:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="inspection-product-name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">foo</property>
|
||||
<property name="selectable">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="inspection-type">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">foo</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Product name:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label70">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Operating System</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="details-inspection-apps">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment44">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">3</property>
|
||||
<property name="left_padding">21</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow6">
|
||||
<property name="height_request">150</property>
|
||||
<object class="GtkLabel" id="inspection-hostname">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">etched-in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="inspection-apps">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">foo</property>
|
||||
<property name="selectable">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label71">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Hostname:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="label" translatable="yes">Operating system:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="inspection-product-name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">foo</property>
|
||||
<property name="selectable">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="inspection-type">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">foo</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label73">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Applications</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label70">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Operating System</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -1573,71 +1516,124 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="details-overview-error-box">
|
||||
<object class="GtkExpander" id="details-inspection-apps">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<object class="GtkAlignment" id="alignment44">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="stock">gtk-dialog-warning</property>
|
||||
<property name="top_padding">3</property>
|
||||
<property name="left_padding">21</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow6">
|
||||
<property name="height_request">150</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">etched-in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="inspection-apps">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="details-overview-error">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label73">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="label" translatable="yes">Error message bar</property>
|
||||
<property name="max_width_chars">80</property>
|
||||
<property name="label" translatable="yes"><b>Applications</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="details-inspection-refresh">
|
||||
<property name="label" translatable="yes">Refresh</property>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">end</property>
|
||||
<signal name="clicked" handler="on_details_inspection_refresh_clicked" swapped="no"/>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="details-overview-error-box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="stock">gtk-dialog-warning</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="details-overview-error">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="label">Error message baraaaaaaaa aaaaaaaaaaaaaa aaaaaaaaaaaaaaaa</property>
|
||||
<property name="justify">fill</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">60</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="details-inspection-refresh">
|
||||
<property name="label" translatable="yes">Refresh</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">start</property>
|
||||
<signal name="clicked" handler="on_details_inspection_refresh_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="box12-atkobject">
|
||||
<property name="AtkObject::accessible-name">inspection-tab</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
|
|
|
@ -2372,10 +2372,11 @@ class vmmDetails(vmmGObjectUI):
|
|||
def refresh_inspection_page(self):
|
||||
inspection_supported = self.config.inspection_supported()
|
||||
uiutil.set_grid_row_visible(self.widget("details-overview-error"),
|
||||
self.vm.inspection.error)
|
||||
if self.vm.inspection.error:
|
||||
msg = _("Error while inspecting the guest configuration")
|
||||
self.widget("details-overview-error").set_text(msg)
|
||||
bool(self.vm.inspection.errorstr))
|
||||
if self.vm.inspection.errorstr:
|
||||
self.widget("details-overview-error").set_text(
|
||||
self.vm.inspection.errorstr)
|
||||
inspection_supported = False
|
||||
|
||||
self.widget("details-inspection-os").set_visible(inspection_supported)
|
||||
self.widget("details-inspection-apps").set_visible(inspection_supported)
|
||||
|
|
|
@ -146,7 +146,7 @@ class vmmInspectionData(object):
|
|||
self.product_variant = None
|
||||
self.icon = None
|
||||
self.applications = None
|
||||
self.error = False
|
||||
self.errorstr = None
|
||||
|
||||
|
||||
class vmmDomainSnapshot(vmmLibvirtObject):
|
||||
|
|
|
@ -26,6 +26,12 @@ from .baseclass import vmmGObject
|
|||
from .domain import vmmInspectionData
|
||||
|
||||
|
||||
def _inspection_error(_errstr):
|
||||
data = vmmInspectionData()
|
||||
data.errorstr = _errstr
|
||||
return data
|
||||
|
||||
|
||||
class vmmInspection(vmmGObject):
|
||||
# Can't find a way to make Thread release our reference
|
||||
_leak_check = False
|
||||
|
@ -63,7 +69,6 @@ class vmmInspection(vmmGObject):
|
|||
|
||||
self._q = queue.Queue()
|
||||
self._conns = {}
|
||||
self._vmseen = {}
|
||||
self._cached_data = {}
|
||||
|
||||
val = self.config.get_libguestfs_inspect_vms()
|
||||
|
@ -78,7 +83,6 @@ class vmmInspection(vmmGObject):
|
|||
self._stop()
|
||||
self._q = queue.Queue()
|
||||
self._conns = {}
|
||||
self._vmseen = {}
|
||||
self._cached_data = {}
|
||||
|
||||
# Called by the main thread whenever a connection is added or
|
||||
|
@ -135,9 +139,7 @@ class vmmInspection(vmmGObject):
|
|||
if cmd == "conn_added":
|
||||
conn = obj[1]
|
||||
uri = conn.get_uri()
|
||||
if (conn.is_remote() or
|
||||
conn.is_test() or
|
||||
uri in self._conns):
|
||||
if uri in self._conns:
|
||||
return
|
||||
|
||||
self._conns[uri] = conn
|
||||
|
@ -167,51 +169,45 @@ class vmmInspection(vmmGObject):
|
|||
# all we need is to remove it from the "seen" cache,
|
||||
# as the data itself will be replaced once the new
|
||||
# results are available.
|
||||
self._vmseen.pop(vmuuid)
|
||||
self._cached_data.pop(vmuuid, None)
|
||||
|
||||
self._process_vm(conn, vm)
|
||||
|
||||
# Try processing a single VM, keeping into account whether it was
|
||||
# visited already, and whether there are cached data for it.
|
||||
def _process_vm(self, conn, vm):
|
||||
def set_inspection_error(vm):
|
||||
data = vmmInspectionData()
|
||||
data.error = True
|
||||
self._set_vm_inspection_data(vm, data)
|
||||
# Try processing a single VM, keeping into account whether it was
|
||||
# visited already, and whether there are cached data for it.
|
||||
def _set_vm_inspection_data(_data):
|
||||
vm.inspection = _data
|
||||
vm.inspection_data_updated()
|
||||
self._cached_data[vm.get_uuid()] = _data
|
||||
|
||||
prettyvm = conn.get_uri() + ":" + vm.get_name()
|
||||
vmuuid = vm.get_uuid()
|
||||
prettyvm = vmuuid
|
||||
if vmuuid in self._cached_data:
|
||||
data = self._cached_data.get(vmuuid)
|
||||
if vm.inspection != data:
|
||||
logging.debug("Found cached data for %s", prettyvm)
|
||||
_set_vm_inspection_data(data)
|
||||
return
|
||||
|
||||
try:
|
||||
prettyvm = conn.get_uri() + ":" + vm.get_name()
|
||||
|
||||
if vmuuid in self._vmseen:
|
||||
data = self._cached_data.get(vmuuid)
|
||||
if not data:
|
||||
return
|
||||
|
||||
if vm.inspection != data:
|
||||
logging.debug("Found cached data for %s", prettyvm)
|
||||
self._set_vm_inspection_data(vm, data)
|
||||
return
|
||||
|
||||
# Whether success or failure, we've "seen" this VM now.
|
||||
self._vmseen[vmuuid] = True
|
||||
try:
|
||||
data = self._inspect_vm(conn, vm)
|
||||
if data:
|
||||
self._set_vm_inspection_data(vm, data)
|
||||
else:
|
||||
set_inspection_error(vm)
|
||||
except Exception:
|
||||
set_inspection_error(vm)
|
||||
raise
|
||||
except Exception:
|
||||
data = self._inspect_vm(conn, vm)
|
||||
except Exception as e:
|
||||
data = _inspection_error(_("Error inspection VM: %s") % str(e))
|
||||
logging.exception("%s: exception while processing", prettyvm)
|
||||
|
||||
_set_vm_inspection_data(data)
|
||||
|
||||
def _inspect_vm(self, conn, vm):
|
||||
if self._thread is None:
|
||||
return
|
||||
|
||||
if conn.is_remote():
|
||||
return _inspection_error(
|
||||
_("Cannot inspect VM on remote connection"))
|
||||
if conn.is_test():
|
||||
return _inspection_error("Cannot inspect VM on test connection")
|
||||
|
||||
import guestfs # pylint: disable=import-error
|
||||
|
||||
g = guestfs.GuestFS(close_on_exit=False)
|
||||
|
@ -222,14 +218,17 @@ class vmmInspection(vmmGObject):
|
|||
except Exception as e:
|
||||
logging.debug("%s: Error launching libguestfs appliance: %s",
|
||||
prettyvm, str(e))
|
||||
return None
|
||||
return _inspection_error(
|
||||
_("Error launching libguestfs appliance: %s") % str(e))
|
||||
|
||||
logging.debug("%s: inspection appliance connected", prettyvm)
|
||||
|
||||
# Inspect the operating system.
|
||||
roots = g.inspect_os()
|
||||
if len(roots) == 0:
|
||||
logging.debug("%s: no operating systems found", prettyvm)
|
||||
return None
|
||||
return _inspection_error(
|
||||
_("Inspection found no operating systems."))
|
||||
|
||||
# Arbitrarily pick the first root device.
|
||||
root = roots[0]
|
||||
|
@ -313,11 +312,5 @@ class vmmInspection(vmmGObject):
|
|||
data.product_variant = str(product_variant)
|
||||
data.icon = icon
|
||||
data.applications = list(apps or [])
|
||||
data.error = False
|
||||
|
||||
return data
|
||||
|
||||
def _set_vm_inspection_data(self, vm, data):
|
||||
vm.inspection = data
|
||||
vm.inspection_data_updated()
|
||||
self._cached_data[vm.get_uuid()] = data
|
||||
|
|
Loading…
Reference in New Issue