2014-07-23 15:48:17 +02:00
|
|
|
# Copyright (C) 2007, 2013-2014 Red Hat, Inc.
|
2007-03-27 19:52:00 -04:00
|
|
|
# Copyright (C) 2007 Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
#
|
2018-04-04 14:35:41 +01:00
|
|
|
# This work is licensed under the GNU GPLv2 or later.
|
2018-03-20 15:00:02 -04:00
|
|
|
# See the COPYING file in the top-level directory.
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2019-06-16 21:12:39 -04:00
|
|
|
from virtinst import log
|
2008-08-15 11:07:45 -04:00
|
|
|
|
2019-06-16 22:19:17 -04:00
|
|
|
from .lib import uiutil
|
2015-04-08 18:29:48 -04:00
|
|
|
from .baseclass import vmmGObjectUI
|
2018-03-14 18:58:22 -04:00
|
|
|
from .engine import vmmEngine
|
2019-06-16 22:19:17 -04:00
|
|
|
from .lib.graphwidgets import Sparkline
|
2019-04-14 15:34:40 -04:00
|
|
|
from .hostnets import vmmHostNets
|
2019-06-16 21:59:14 -04:00
|
|
|
from .hoststorage import vmmHostStorage
|
2007-03-29 21:23:17 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
|
2010-12-08 17:26:19 -05:00
|
|
|
class vmmHost(vmmGObjectUI):
|
2018-03-15 05:53:58 -04:00
|
|
|
@classmethod
|
|
|
|
def show_instance(cls, parentobj, conn):
|
|
|
|
try:
|
|
|
|
# Maintain one dialog per connection
|
|
|
|
uri = conn.get_uri()
|
2018-03-17 19:42:19 -04:00
|
|
|
if cls._instances is None:
|
|
|
|
cls._instances = {}
|
2018-03-15 05:53:58 -04:00
|
|
|
if uri not in cls._instances:
|
2018-03-17 16:08:20 -04:00
|
|
|
cls._instances[uri] = vmmHost(conn)
|
2018-03-15 05:53:58 -04:00
|
|
|
cls._instances[uri].show()
|
2020-08-21 14:39:24 -04:00
|
|
|
except Exception as e: # pragma: no cover
|
2018-03-16 18:58:11 -04:00
|
|
|
if not parentobj:
|
|
|
|
raise
|
2018-03-15 05:53:58 -04:00
|
|
|
parentobj.err.show_err(
|
|
|
|
_("Error launching host dialog: %s") % str(e))
|
2012-05-14 14:24:56 +01:00
|
|
|
|
2011-04-13 10:47:31 -04:00
|
|
|
def __init__(self, conn):
|
2013-09-22 16:10:16 -04:00
|
|
|
vmmGObjectUI.__init__(self, "host.ui", "vmm-host")
|
2007-03-27 19:52:00 -04:00
|
|
|
self.conn = conn
|
|
|
|
|
2019-04-13 14:52:17 -04:00
|
|
|
# Set default window size
|
|
|
|
w, h = self.conn.get_details_window_size()
|
|
|
|
if w <= 0:
|
|
|
|
w = 800
|
|
|
|
if h <= 0:
|
|
|
|
h = 600
|
|
|
|
self.topwin.set_default_size(w, h)
|
|
|
|
self._window_size = None
|
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._cpu_usage_graph = None
|
|
|
|
self._memory_usage_graph = None
|
|
|
|
self._init_conn_state()
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._storagelist = None
|
|
|
|
self._init_storage_state()
|
2019-04-14 15:34:40 -04:00
|
|
|
|
|
|
|
self._hostnets = None
|
2019-04-13 12:03:42 -04:00
|
|
|
self._init_net_state()
|
2009-11-19 17:29:20 -05:00
|
|
|
|
2013-02-16 13:31:46 -05:00
|
|
|
self.builder.connect_signals({
|
2019-04-13 12:03:42 -04:00
|
|
|
"on_menu_file_view_manager_activate": self._view_manager_cb,
|
|
|
|
"on_menu_file_quit_activate": self._exit_app_cb,
|
2007-03-27 19:52:00 -04:00
|
|
|
"on_menu_file_close_activate": self.close,
|
|
|
|
"on_vmm_host_delete_event": self.close,
|
2019-04-13 14:52:17 -04:00
|
|
|
"on_vmm_host_configure_event": self._window_resized_cb,
|
2019-04-13 12:03:42 -04:00
|
|
|
"on_host_page_switch": self._page_changed_cb,
|
|
|
|
|
|
|
|
"on_overview_name_changed": self._overview_name_changed_cb,
|
|
|
|
"on_config_autoconnect_toggled": self._autoconnect_toggled_cb,
|
2012-11-08 14:15:02 +01:00
|
|
|
})
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self.conn.connect("state-changed", self._conn_state_changed_cb)
|
|
|
|
self.conn.connect("resources-sampled", self._conn_resources_sampled_cb)
|
2015-04-08 18:29:48 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._refresh_resources()
|
2019-04-14 15:34:40 -04:00
|
|
|
self._refresh_conn_state()
|
2015-04-08 18:29:48 -04:00
|
|
|
self.widget("config-autoconnect").set_active(
|
|
|
|
self.conn.get_autoconnect())
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2018-03-15 07:43:56 -04:00
|
|
|
self._cleanup_on_conn_removed()
|
|
|
|
|
2009-03-08 15:34:15 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
#######################
|
|
|
|
# Standard UI methods #
|
|
|
|
#######################
|
|
|
|
|
|
|
|
def show(self):
|
2019-06-16 21:12:39 -04:00
|
|
|
log.debug("Showing host details: %s", self.conn)
|
2019-04-13 12:03:42 -04:00
|
|
|
vis = self.is_visible()
|
|
|
|
self.topwin.present()
|
|
|
|
if vis:
|
2020-08-21 14:39:24 -04:00
|
|
|
return # pragma: no cover
|
2019-04-13 12:03:42 -04:00
|
|
|
|
|
|
|
vmmEngine.get_instance().increment_window_counter()
|
|
|
|
|
|
|
|
def close(self, src=None, event=None):
|
|
|
|
dummy = src
|
|
|
|
dummy = event
|
2019-06-16 21:12:39 -04:00
|
|
|
log.debug("Closing host window for %s", self.conn)
|
2019-04-13 12:03:42 -04:00
|
|
|
if not self.is_visible():
|
|
|
|
return
|
|
|
|
|
|
|
|
self.topwin.hide()
|
|
|
|
vmmEngine.get_instance().decrement_window_counter()
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
def _cleanup(self):
|
|
|
|
if self._window_size:
|
|
|
|
self.conn.set_details_window_size(*self._window_size)
|
|
|
|
|
|
|
|
self.conn = None
|
|
|
|
|
|
|
|
self._storagelist.cleanup()
|
|
|
|
self._storagelist = None
|
|
|
|
|
2019-04-14 15:34:40 -04:00
|
|
|
self._hostnets.cleanup()
|
|
|
|
self._hostnets = None
|
2019-04-13 12:03:42 -04:00
|
|
|
|
|
|
|
self._cpu_usage_graph.destroy()
|
|
|
|
self._cpu_usage_graph = None
|
|
|
|
|
|
|
|
self._memory_usage_graph.destroy()
|
|
|
|
self._memory_usage_graph = None
|
|
|
|
|
|
|
|
|
|
|
|
###########
|
|
|
|
# UI init #
|
|
|
|
###########
|
|
|
|
|
|
|
|
def _init_net_state(self):
|
2019-04-14 15:34:40 -04:00
|
|
|
self._hostnets = vmmHostNets(self.conn, self.builder, self.topwin)
|
|
|
|
self.widget("net-align").add(self._hostnets.top_box)
|
2017-09-22 19:39:10 +08:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
def _init_storage_state(self):
|
2019-06-16 21:59:14 -04:00
|
|
|
self._storagelist = vmmHostStorage(self.conn, self.builder, self.topwin)
|
2019-04-13 12:03:42 -04:00
|
|
|
self.widget("storage-align").add(self._storagelist.top_box)
|
2017-09-22 19:39:10 +08:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
def _init_conn_state(self):
|
2009-11-17 15:44:27 -05:00
|
|
|
uri = self.conn.get_uri()
|
|
|
|
auto = self.conn.get_autoconnect()
|
|
|
|
|
2011-07-14 13:13:13 -04:00
|
|
|
self.widget("overview-uri").set_text(uri)
|
|
|
|
self.widget("config-autoconnect").set_active(auto)
|
2009-11-17 15:44:27 -05:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._cpu_usage_graph = Sparkline()
|
2022-02-19 14:23:32 -05:00
|
|
|
self._cpu_usage_graph.set_hexpand(True)
|
2019-04-13 12:03:42 -04:00
|
|
|
self._cpu_usage_graph.show()
|
|
|
|
self.widget("performance-cpu-align").add(self._cpu_usage_graph)
|
2011-04-13 09:27:02 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._memory_usage_graph = Sparkline()
|
2022-02-19 14:23:32 -05:00
|
|
|
self._memory_usage_graph.set_hexpand(True)
|
2019-04-13 12:03:42 -04:00
|
|
|
self._memory_usage_graph.show()
|
|
|
|
self.widget("performance-memory-align").add(self._memory_usage_graph)
|
2015-04-08 18:29:48 -04:00
|
|
|
|
2009-11-17 15:18:38 -05:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
######################
|
|
|
|
# UI conn populating #
|
|
|
|
######################
|
2013-07-07 11:06:15 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
def _refresh_resources(self):
|
2019-06-07 17:19:23 -04:00
|
|
|
vm_memory = uiutil.pretty_mem(self.conn.stats_memory())
|
|
|
|
host_memory = uiutil.pretty_mem(self.conn.host_memory_size())
|
2015-05-04 16:33:56 -04:00
|
|
|
|
2011-07-11 21:22:50 -04:00
|
|
|
cpu_vector = self.conn.host_cpu_time_vector()
|
|
|
|
memory_vector = self.conn.stats_memory_vector()
|
2007-03-27 19:52:00 -04:00
|
|
|
cpu_vector.reverse()
|
|
|
|
memory_vector.reverse()
|
2011-07-11 21:22:50 -04:00
|
|
|
|
2011-07-14 13:13:13 -04:00
|
|
|
self.widget("performance-cpu").set_text("%d %%" %
|
2011-07-11 21:22:50 -04:00
|
|
|
self.conn.host_cpu_time_percentage())
|
2011-07-14 13:13:13 -04:00
|
|
|
self.widget("performance-memory").set_text(
|
2011-07-11 21:22:50 -04:00
|
|
|
_("%(currentmem)s of %(maxmem)s") %
|
|
|
|
{'currentmem': vm_memory, 'maxmem': host_memory})
|
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
self._cpu_usage_graph.set_property("data_array", cpu_vector)
|
|
|
|
self._memory_usage_graph.set_property("data_array", memory_vector)
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2019-04-14 15:34:40 -04:00
|
|
|
def _refresh_conn_state(self):
|
2014-09-11 18:16:21 -04:00
|
|
|
conn_active = self.conn.is_active()
|
2015-04-11 13:39:25 -04:00
|
|
|
|
|
|
|
self.topwin.set_title(
|
2020-09-17 08:43:59 +02:00
|
|
|
_("%(connection)s - Connection Details") %
|
|
|
|
{"connection": self.conn.get_pretty_desc()})
|
2015-04-11 13:39:25 -04:00
|
|
|
if not self.widget("overview-name").has_focus():
|
|
|
|
self.widget("overview-name").set_text(self.conn.get_pretty_desc())
|
|
|
|
|
2015-04-09 15:07:16 -04:00
|
|
|
if conn_active:
|
|
|
|
return
|
2019-04-14 15:34:40 -04:00
|
|
|
self._hostnets.close()
|
2019-04-13 12:03:42 -04:00
|
|
|
self._storagelist.close()
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2019-04-13 12:03:42 -04:00
|
|
|
|
|
|
|
################
|
|
|
|
# UI listeners #
|
|
|
|
################
|
|
|
|
|
|
|
|
def _view_manager_cb(self, src):
|
|
|
|
from .manager import vmmManager
|
|
|
|
vmmManager.get_instance(self).show()
|
|
|
|
|
|
|
|
def _exit_app_cb(self, src):
|
|
|
|
vmmEngine.get_instance().exit_app()
|
|
|
|
|
|
|
|
def _window_resized_cb(self, src, event):
|
|
|
|
if not self.is_visible():
|
|
|
|
return
|
|
|
|
self._window_size = self.topwin.get_size()
|
|
|
|
|
|
|
|
def _overview_name_changed_cb(self, src):
|
|
|
|
src = self.widget("overview-name")
|
|
|
|
self.conn.set_config_pretty_name(src.get_text())
|
|
|
|
|
|
|
|
def _autoconnect_toggled_cb(self, src):
|
|
|
|
self.conn.set_autoconnect(src.get_active())
|
|
|
|
|
|
|
|
def _page_changed_cb(self, src, child, pagenum):
|
|
|
|
if pagenum == 1:
|
2019-04-14 15:34:40 -04:00
|
|
|
self._hostnets.refresh_page()
|
2019-04-13 12:03:42 -04:00
|
|
|
elif pagenum == 2:
|
|
|
|
self._storagelist.refresh_page()
|
|
|
|
|
|
|
|
def _conn_state_changed_cb(self, conn):
|
2019-04-14 15:34:40 -04:00
|
|
|
self._refresh_conn_state()
|
2019-04-13 12:03:42 -04:00
|
|
|
|
|
|
|
def _conn_resources_sampled_cb(self, conn):
|
|
|
|
self._refresh_resources()
|