Added preferences via GConf
This commit is contained in:
parent
3ed0ef3458
commit
1b6e7727dd
|
@ -3,7 +3,7 @@
|
|||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkWindow" id="vm-manager">
|
||||
<widget class="GtkWindow" id="vmm-manager">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Virtual Machine Manager</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
|
@ -83,7 +83,7 @@
|
|||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menu_edit_details">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Details</property>
|
||||
<property name="label" translatable="yes">VM details</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_edit_details_activate" last_modification_time="Tue, 28 Mar 2006 17:06:34 GMT"/>
|
||||
|
||||
|
@ -109,6 +109,21 @@
|
|||
<signal name="activate" handler="on_menu_edit_delete_activate" last_modification_time="Tue, 28 Mar 2006 17:06:34 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separator2">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menu_edit_preferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">gtk-preferences</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_menu_edit_preferences_activate" last_modification_time="Wed, 29 Mar 2006 09:57:25 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -301,6 +316,7 @@ Inactive virtual machines</property>
|
|||
<child>
|
||||
<widget class="GtkButton" id="vm-delete">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
|
@ -327,6 +343,7 @@ Inactive virtual machines</property>
|
|||
<child>
|
||||
<widget class="GtkButton" id="vm-details">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
|
@ -402,6 +419,7 @@ Inactive virtual machines</property>
|
|||
<child>
|
||||
<widget class="GtkButton" id="vm-open">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-open</property>
|
||||
|
@ -471,9 +489,9 @@ Inactive virtual machines</property>
|
|||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkAboutDialog" id="vm-about">
|
||||
<widget class="GtkAboutDialog" id="vmm-about">
|
||||
<property name="visible">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="name" translatable="yes">Virtual Machine Manager</property>
|
||||
<property name="copyright" translatable="yes">Copyright (C) 2006 Red Hat Inc.</property>
|
||||
<property name="comments" translatable="yes"></property>
|
||||
|
@ -494,9 +512,10 @@ Inactive virtual machines</property>
|
|||
<property name="wrap_license">False</property>
|
||||
<property name="authors">Daniel P. Berrange <berrange@redhat.com></property>
|
||||
<property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
|
||||
<signal name="delete_event" handler="on_vmm_about_delete_event" last_modification_time="Wed, 29 Mar 2006 10:31:19 GMT"/>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkWindow" id="vm-details">
|
||||
<widget class="GtkWindow" id="vmm-details">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Virtual Machine Details</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
|
@ -1740,4 +1759,305 @@ Inactive virtual machines</property>
|
|||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="vmm-preferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Virtual Machine Manager Preferences</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="delete_event" handler="on_vmm_preferences_delete_event" last_modification_time="Wed, 29 Mar 2006 10:12:05 GMT"/>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="helpbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-11</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="close">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-7</property>
|
||||
<signal name="clicked" handler="on_close_clicked" last_modification_time="Wed, 29 Mar 2006 10:11:44 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame1">
|
||||
<property name="border_width">3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment2">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="table3">
|
||||
<property name="border_width">3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">3</property>
|
||||
<property name="column_spacing">3</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label36">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Update status every</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label37">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Maintain history of</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="stats-update-interval">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="update_policy">GTK_UPDATE_IF_VALID</property>
|
||||
<property name="snap_to_ticks">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="adjustment">5 1 60 1 5 5</property>
|
||||
<signal name="changed" handler="on_stats_update_interval_changed" last_modification_time="Wed, 29 Mar 2006 10:12:17 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label38">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">seconds</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label39">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">samples</property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="stats-history-length">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="update_policy">GTK_UPDATE_IF_VALID</property>
|
||||
<property name="snap_to_ticks">False</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="adjustment">10 10 100 1 5 5</property>
|
||||
<signal name="changed" handler="on_stats_history_length_changed" last_modification_time="Wed, 29 Mar 2006 10:12:22 GMT"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label35">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Status monitoring</b></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import gconf
|
||||
import gtk
|
||||
import gobject
|
||||
import gtk.gdk
|
||||
import gtk.glade
|
||||
from time import time
|
||||
import re
|
||||
import os
|
||||
import os.path
|
||||
import libvirt
|
||||
|
||||
tickrate = 5000
|
||||
gconf_dir = "/apps/gnome-virtual-manager"
|
||||
|
||||
# Ought not to hardcode stuff as being in /usr
|
||||
gladedir = "/usr/share/gnome-vm-manager"
|
||||
|
@ -20,79 +22,167 @@ if os.path.exists("./gnome-vm-manager.glade"):
|
|||
|
||||
class vmmAbout:
|
||||
def __init__(self):
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vm-about")
|
||||
self.window.get_widget("vm-about").hide()
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vmm-about")
|
||||
self.window.get_widget("vmm-about").hide()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_vmm_about_delete_event": self.close,
|
||||
})
|
||||
|
||||
def show(self):
|
||||
dialog = self.window.get_widget("vm-about")
|
||||
dialog = self.window.get_widget("vmm-about")
|
||||
dialog.set_version("0.1")
|
||||
dialog.show_all()
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-about").hide()
|
||||
return 1
|
||||
|
||||
|
||||
class vmmDetails:
|
||||
def __init__(self, vmm):
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vmm-details")
|
||||
self.vmm = vmm
|
||||
|
||||
|
||||
class vmmPreferences:
|
||||
def __init__(self, conf):
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vmm-preferences")
|
||||
self.conf = conf
|
||||
self.window.get_widget("vmm-preferences").hide()
|
||||
|
||||
self.conf.on_stats_update_interval_changed(self.refresh_update_interval)
|
||||
self.conf.on_stats_history_length_changed(self.refresh_history_length)
|
||||
|
||||
self.refresh_update_interval()
|
||||
self.refresh_history_length()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_stats_update_interval_changed": self.change_update_interval,
|
||||
"on_stats_history_length_changed": self.change_history_length,
|
||||
|
||||
"on_close_clicked": self.close,
|
||||
"on_vmm_preferences_delete_event": self.close,
|
||||
})
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-preferences").hide()
|
||||
return 1
|
||||
|
||||
def show(self):
|
||||
self.window.get_widget("vmm-preferences").show_all()
|
||||
|
||||
def refresh_update_interval(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
|
||||
self.window.get_widget("stats-update-interval").set_value(self.conf.get_stats_update_interval())
|
||||
|
||||
def refresh_history_length(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
|
||||
self.window.get_widget("stats-history-length").set_value(self.conf.get_stats_history_length())
|
||||
|
||||
def change_update_interval(self, src):
|
||||
self.conf.set_stats_update_interval(src.get_value_as_int())
|
||||
|
||||
def change_history_length(self, src):
|
||||
self.conf.set_stats_history_length(src.get_value_as_int())
|
||||
|
||||
|
||||
class vmmManager:
|
||||
def __init__(self):
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vm-manager")
|
||||
self.window = gtk.glade.XML(gladedir + "/gnome-vm-manager.glade", "vmm-manager")
|
||||
self.conf = vmmConfig()
|
||||
self.vmm = libvirt.openReadOnly(None)
|
||||
#self.vmm = libvirt.open(None)
|
||||
|
||||
self.stats = {}
|
||||
|
||||
self.record_stats()
|
||||
self.stats = vmmStats(self.vmm, self.conf)
|
||||
self.populate_vms()
|
||||
self.tickrate = 5000
|
||||
self.about = None;
|
||||
|
||||
self.timer = gobject.timeout_add(self.tickrate, self.refresh_stats)
|
||||
self.about = None
|
||||
self.preferences = None
|
||||
|
||||
# Setup update timers
|
||||
self.conf.on_stats_update_interval_changed(self.change_timer_interval)
|
||||
self.schedule_timer()
|
||||
|
||||
self.conf.on_vmlist_status_visible_changed(self.toggle_status_visible_widget)
|
||||
self.conf.on_vmlist_cpu_usage_visible_changed(self.toggle_cpu_usage_visible_widget)
|
||||
self.conf.on_vmlist_memory_usage_visible_changed(self.toggle_memory_usage_visible_widget)
|
||||
self.conf.on_vmlist_disk_usage_visible_changed(self.toggle_disk_usage_visible_widget)
|
||||
self.conf.on_vmlist_network_traffic_visible_changed(self.toggle_network_traffic_visible_widget)
|
||||
|
||||
self.window.get_widget("menu_view_status").set_active(self.conf.is_vmlist_status_visible())
|
||||
self.window.get_widget("menu_view_cpu_usage").set_active(self.conf.is_vmlist_cpu_usage_visible())
|
||||
self.window.get_widget("menu_view_memory_usage").set_active(self.conf.is_vmlist_memory_usage_visible())
|
||||
self.window.get_widget("menu_view_disk_usage").set_active(self.conf.is_vmlist_disk_usage_visible())
|
||||
self.window.get_widget("menu_view_network_traffic").set_active(self.conf.is_vmlist_network_traffic_visible())
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_menu_view_status_activate" : self.toggle_status_column,
|
||||
"on_menu_view_cpu_usage_activate" : self.toggle_cpu_column,
|
||||
"on_menu_view_memory_usage_activate" : self.toggle_memory_column,
|
||||
"on_menu_view_disk_usage_activate" : self.toggle_disk_column,
|
||||
"on_menu_view_network_traffic_activate" : self.toggle_network_column,
|
||||
"on_menu_view_status_activate" : self.toggle_status_visible_conf,
|
||||
"on_menu_view_cpu_usage_activate" : self.toggle_cpu_usage_visible_conf,
|
||||
"on_menu_view_memory_usage_activate" : self.toggle_memory_usage_visible_conf,
|
||||
"on_menu_view_disk_usage_activate" : self.toggle_disk_usage_visible_conf,
|
||||
"on_menu_view_network_traffic_activate" : self.toggle_network_traffic_visible_conf,
|
||||
|
||||
"on_vm_manager_delete_event": self.exit_app,
|
||||
"on_menu_file_quit_activate": self.exit_app,
|
||||
"on_vmm_close_clicked": self.exit_app,
|
||||
|
||||
"on_menu_edit_preferences_activate": self.show_preferences,
|
||||
"on_menu_help_about_activate": self.show_about,
|
||||
})
|
||||
|
||||
self.vm_selected(None)
|
||||
self.window.get_widget("vm-list").get_selection().connect("changed", self.vm_selected)
|
||||
|
||||
|
||||
def exit_app(self, ignore=None,ignore2=None):
|
||||
gtk.main_quit()
|
||||
|
||||
def schedule_timer(self):
|
||||
interval = self.conf.get_stats_update_interval() * 1000
|
||||
print "Scheduling at " + str(interval)
|
||||
self.timer_started = time() * 1000
|
||||
self.timer = gobject.timeout_add(interval, self.refresh_stats)
|
||||
|
||||
|
||||
def change_timer_interval(self,ignore1,ignore2,ignore3,ignore4):
|
||||
print "Removing timer"
|
||||
gobject.source_remove(self.timer)
|
||||
self.refresh_stats()
|
||||
self.schedule_timer()
|
||||
|
||||
def vm_selected(self, selection):
|
||||
if selection == None or selection.count_selected_rows() == 0:
|
||||
self.window.get_widget("vm-delete").set_sensitive(False)
|
||||
self.window.get_widget("vm-details").set_sensitive(False)
|
||||
self.window.get_widget("vm-open").set_sensitive(False)
|
||||
self.window.get_widget("menu_edit_delete").set_sensitive(False)
|
||||
self.window.get_widget("menu_edit_details").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("vm-delete").set_sensitive(True)
|
||||
self.window.get_widget("vm-details").set_sensitive(True)
|
||||
self.window.get_widget("vm-open").set_sensitive(True)
|
||||
self.window.get_widget("menu_edit_delete").set_sensitive(True)
|
||||
self.window.get_widget("menu_edit_details").set_sensitive(True)
|
||||
|
||||
def show_about(self, ignore=None):
|
||||
if self.about == None:
|
||||
self.about = vmmAbout()
|
||||
self.about.show()
|
||||
|
||||
def show_preferences(self, ignore=None):
|
||||
if self.preferences == None:
|
||||
self.preferences = vmmPreferences(self.conf)
|
||||
self.preferences.show()
|
||||
|
||||
def refresh_stats(self):
|
||||
self.record_stats()
|
||||
self.timer = gobject.timeout_add(self.tickrate, self.refresh_stats)
|
||||
self.stats.tick()
|
||||
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
model = vmlist.get_model()
|
||||
print "Refresh " + str(model.iter_n_children(None))
|
||||
|
||||
for row in range(model.iter_n_children(None)):
|
||||
model.row_changed(str(row), model.iter_nth_child(None, row))
|
||||
|
||||
def record_stats(self):
|
||||
print "Record"
|
||||
doms = self.vmm.listDomainsID()
|
||||
if doms != None:
|
||||
for id in self.vmm.listDomainsID():
|
||||
vm = self.vmm.lookupByID(id)
|
||||
info = vm.info()
|
||||
name = vm.name()
|
||||
|
||||
if not(self.stats.has_key(name)):
|
||||
self.stats[name] = []
|
||||
if len(self.stats[name]) > 4:
|
||||
self.stats[name] = (self.stats[name])[1:len(self.stats[name])]
|
||||
self.stats[name].append(info)
|
||||
# XXX why is max-mem wrong for Domain-0 when run as root ?!?!?!
|
||||
#print info
|
||||
return 1
|
||||
|
||||
|
||||
def populate_vms(self):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
|
@ -105,7 +195,7 @@ class vmmManager:
|
|||
cpuUsageCol = gtk.TreeViewColumn("CPU usage")
|
||||
memoryUsageCol = gtk.TreeViewColumn("Memory usage")
|
||||
diskUsageCol = gtk.TreeViewColumn("Disk usage")
|
||||
networkUsageCol = gtk.TreeViewColumn("Network traffic")
|
||||
networkTrafficCol = gtk.TreeViewColumn("Network traffic")
|
||||
|
||||
name_txt = gtk.CellRendererText()
|
||||
nameCol.pack_start(name_txt, True)
|
||||
|
@ -116,27 +206,32 @@ class vmmManager:
|
|||
vmlist.append_column(cpuUsageCol)
|
||||
vmlist.append_column(memoryUsageCol)
|
||||
vmlist.append_column(diskUsageCol)
|
||||
vmlist.append_column(networkUsageCol)
|
||||
vmlist.append_column(networkTrafficCol)
|
||||
|
||||
status_txt = gtk.CellRendererText()
|
||||
statusCol.pack_start(status_txt, True)
|
||||
statusCol.set_cell_data_func(status_txt, self.status_text, None)
|
||||
|
||||
statusCol.set_visible(self.conf.is_vmlist_status_visible())
|
||||
|
||||
cpuUsage_txt = gtk.CellRendererText()
|
||||
cpuUsageCol.pack_start(cpuUsage_txt, True)
|
||||
cpuUsageCol.set_cell_data_func(cpuUsage_txt, self.cpu_usage_text, None)
|
||||
cpuUsageCol.set_visible(self.conf.is_vmlist_cpu_usage_visible())
|
||||
|
||||
memoryUsage_txt = gtk.CellRendererText()
|
||||
memoryUsageCol.pack_start(memoryUsage_txt, True)
|
||||
memoryUsageCol.set_cell_data_func(memoryUsage_txt, self.memory_usage_text, None)
|
||||
memoryUsageCol.set_visible(self.conf.is_vmlist_memory_usage_visible())
|
||||
|
||||
diskUsage_txt = gtk.CellRendererText()
|
||||
diskUsageCol.pack_start(diskUsage_txt, True)
|
||||
diskUsageCol.set_cell_data_func(diskUsage_txt, self.disk_usage_text, None)
|
||||
diskUsageCol.set_visible(self.conf.is_vmlist_disk_usage_visible())
|
||||
|
||||
networkUsage_txt = gtk.CellRendererText()
|
||||
networkUsageCol.pack_start(networkUsage_txt, True)
|
||||
networkUsageCol.set_cell_data_func(networkUsage_txt, self.network_usage_text, None)
|
||||
networkTraffic_txt = gtk.CellRendererText()
|
||||
networkTrafficCol.pack_start(networkTraffic_txt, True)
|
||||
networkTrafficCol.set_cell_data_func(networkTraffic_txt, self.network_usage_text, None)
|
||||
networkTrafficCol.set_visible(self.conf.is_vmlist_network_traffic_visible())
|
||||
|
||||
doms = self.vmm.listDomainsID()
|
||||
if doms != None:
|
||||
|
@ -144,79 +239,65 @@ class vmmManager:
|
|||
vm = self.vmm.lookupByID(id)
|
||||
model.append([vm.name()])
|
||||
|
||||
def toggle_status_column(self,menu):
|
||||
def toggle_status_visible_conf(self, menu):
|
||||
self.conf.set_vmlist_status_visible(menu.get_active())
|
||||
|
||||
def toggle_status_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_status")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(1)
|
||||
col.set_visible(menu.get_active())
|
||||
col.set_visible(self.conf.is_vmlist_status_visible())
|
||||
|
||||
def toggle_cpu_column(self,menu):
|
||||
def toggle_cpu_usage_visible_conf(self, menu):
|
||||
self.conf.set_vmlist_cpu_usage_visible(menu.get_active())
|
||||
|
||||
def toggle_cpu_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_cpu_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(2)
|
||||
col.set_visible(menu.get_active())
|
||||
col.set_visible(self.conf.is_vmlist_cpu_usage_visible())
|
||||
|
||||
def toggle_memory_column(self,menu):
|
||||
def toggle_memory_usage_visible_conf(self, menu):
|
||||
self.conf.set_vmlist_memory_usage_visible(menu.get_active())
|
||||
|
||||
def toggle_memory_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_memory_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(3)
|
||||
col.set_visible(menu.get_active())
|
||||
col.set_visible(self.conf.is_vmlist_memory_usage_visible())
|
||||
|
||||
def toggle_disk_column(self,menu):
|
||||
def toggle_disk_usage_visible_conf(self, menu):
|
||||
self.conf.set_vmlist_disk_usage_visible(menu.get_active())
|
||||
|
||||
def toggle_disk_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_disk_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(4)
|
||||
col.set_visible(menu.get_active())
|
||||
col.set_visible(self.conf.is_vmlist_disk_usage_visible())
|
||||
|
||||
def toggle_network_column(self,menu):
|
||||
def toggle_network_traffic_visible_conf(self, menu):
|
||||
self.conf.set_vmlist_network_traffic_visible(menu.get_active())
|
||||
|
||||
def toggle_network_traffic_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_network_traffic")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(5)
|
||||
col.set_visible(menu.get_active())
|
||||
col.set_visible(self.conf.is_vmlist_network_traffic_visible())
|
||||
|
||||
|
||||
def status_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
statusRecord = self.stats[name]
|
||||
info = statusRecord[len(statusRecord)-1]
|
||||
if info[0] == libvirt.VIR_DOMAIN_NOSTATE:
|
||||
cell.set_property('text', "Unknown")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_RUNNING:
|
||||
cell.set_property('text', "Running")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_BLOCKED:
|
||||
cell.set_property('text', "Blocked")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_PAUSED:
|
||||
cell.set_property('text', "Paused")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_SHUTDOWN:
|
||||
cell.set_property('text', "Shutdown")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_SHUTOFF:
|
||||
cell.set_property('text', "Shutoff")
|
||||
elif info[0] == libvirt.VIR_DOMAIN_CRASHED:
|
||||
cell.set_property('text', "Crashed")
|
||||
cell.set_property('text', self.stats.run_status(name))
|
||||
|
||||
def cpu_usage_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
statusRecord = self.stats[name]
|
||||
nSample = len(statusRecord)
|
||||
|
||||
if nSample < 2:
|
||||
cell.set_property('text', "-")
|
||||
else:
|
||||
total = 0
|
||||
for dom in self.stats.keys():
|
||||
last = self.stats[dom][len(self.stats[dom])-2]
|
||||
current = self.stats[dom][len(self.stats[dom])-1]
|
||||
total += current[4] - last[4]
|
||||
|
||||
last = statusRecord[len(statusRecord)-2]
|
||||
current = statusRecord[len(statusRecord)-1]
|
||||
fraction = current[4] - last[4]
|
||||
|
||||
percentage = fraction * 100.0 / total
|
||||
|
||||
cell.set_property('text',"%2.2f %%" % percentage)
|
||||
cell.set_property('text', "%2.2f %%" % self.stats.percent_cpu_time(name))
|
||||
|
||||
def memory_usage_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
statusRecord = self.stats[name]
|
||||
current = statusRecord[len(statusRecord)-1]
|
||||
|
||||
cell.set_property('text', "%s of %s" % (self.pretty_mem(current[2]), self.pretty_mem(current[1])))
|
||||
current = self.stats.current_memory(name)
|
||||
maximum = self.stats.maximum_memory(name)
|
||||
cell.set_property('text', "%s of %s" % (self.pretty_mem(current), self.pretty_mem(maximum)))
|
||||
#cell.set_property('text', self.pretty_mem(current[2]))
|
||||
|
||||
def pretty_mem(self, mem):
|
||||
|
@ -232,6 +313,193 @@ class vmmManager:
|
|||
def network_usage_text(self, column, cell, model, iter, data):
|
||||
#cell.set_property('text', "100 bytes/sec")
|
||||
cell.set_property('text', "-")
|
||||
|
||||
class vmmConfig:
|
||||
def __init__(self):
|
||||
self.conf = gconf.client_get_default()
|
||||
self.conf.add_dir (gconf_dir,
|
||||
gconf.CLIENT_PRELOAD_NONE)
|
||||
|
||||
def is_vmlist_status_visible(self):
|
||||
return self.conf.get_bool(gconf_dir + "/vmlist-fields/status")
|
||||
|
||||
def is_vmlist_cpu_usage_visible(self):
|
||||
return self.conf.get_bool(gconf_dir + "/vmlist-fields/cpu_usage")
|
||||
|
||||
def is_vmlist_memory_usage_visible(self):
|
||||
return self.conf.get_bool(gconf_dir + "/vmlist-fields/memory_usage")
|
||||
|
||||
def is_vmlist_disk_usage_visible(self):
|
||||
return self.conf.get_bool(gconf_dir + "/vmlist-fields/disk_usage")
|
||||
|
||||
def is_vmlist_network_traffic_visible(self):
|
||||
return self.conf.get_bool(gconf_dir + "/vmlist-fields/network_traffic")
|
||||
|
||||
|
||||
|
||||
def set_vmlist_status_visible(self, state):
|
||||
self.conf.set_bool(gconf_dir + "/vmlist-fields/status", state)
|
||||
|
||||
def set_vmlist_cpu_usage_visible(self, state):
|
||||
self.conf.set_bool(gconf_dir + "/vmlist-fields/cpu_usage", state)
|
||||
|
||||
def set_vmlist_memory_usage_visible(self, state):
|
||||
self.conf.set_bool(gconf_dir + "/vmlist-fields/memory_usage", state)
|
||||
|
||||
def set_vmlist_disk_usage_visible(self, state):
|
||||
self.conf.set_bool(gconf_dir + "/vmlist-fields/disk_usage", state)
|
||||
|
||||
def set_vmlist_network_traffic_visible(self, state):
|
||||
self.conf.set_bool(gconf_dir + "/vmlist-fields/network_traffic", state)
|
||||
|
||||
|
||||
|
||||
def on_vmlist_status_visible_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/vmlist-fields/status", callback)
|
||||
|
||||
def on_vmlist_cpu_usage_visible_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/vmlist-fields/cpu_usage", callback)
|
||||
|
||||
def on_vmlist_memory_usage_visible_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/vmlist-fields/memory_usage", callback)
|
||||
|
||||
def on_vmlist_disk_usage_visible_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/vmlist-fields/disk_usage", callback)
|
||||
|
||||
def on_vmlist_network_traffic_visible_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/vmlist-fields/network_traffic", callback)
|
||||
|
||||
|
||||
|
||||
def get_stats_update_interval(self):
|
||||
interval = self.conf.get_int(gconf_dir + "/stats/update-interval")
|
||||
if interval < 1:
|
||||
return 1
|
||||
return interval
|
||||
|
||||
def get_stats_history_length(self):
|
||||
history = self.conf.get_int(gconf_dir + "/stats/history-length")
|
||||
if history < 10:
|
||||
return 10
|
||||
return history
|
||||
|
||||
|
||||
def set_stats_update_interval(self, interval):
|
||||
self.conf.set_int(gconf_dir + "/stats/update-interval", interval)
|
||||
|
||||
def set_stats_history_length(self, length):
|
||||
self.conf.set_int(gconf_dir + "/stats/history-length", length)
|
||||
|
||||
|
||||
def on_stats_update_interval_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/stats/update-interval", callback)
|
||||
|
||||
def on_stats_history_length_changed(self, callback):
|
||||
self.conf.notify_add(gconf_dir + "/stats/history-length", callback)
|
||||
|
||||
|
||||
class vmmStats:
|
||||
def __init__(self, vmm, conf):
|
||||
self.vmm = vmm
|
||||
self.vms = {}
|
||||
self.conf = conf
|
||||
self.callbacks = { "notify_added": [], "notify_removed": [] }
|
||||
self.tick()
|
||||
|
||||
def connect_to_signal(self, name, callback):
|
||||
if not(self.callbacks.has_key(name)):
|
||||
raise "unknown signal " + name + "requested"
|
||||
|
||||
self.callbacks[name].append(callback)
|
||||
|
||||
def notify_added(self, name):
|
||||
for cb in self.callbacks["notify_added"]:
|
||||
cb(name)
|
||||
|
||||
|
||||
def notify_removed(self, name):
|
||||
for cb in self.callbacks["notify_added"]:
|
||||
cb(name)
|
||||
|
||||
def tick(self):
|
||||
doms = self.vmm.listDomainsID()
|
||||
newVms = {}
|
||||
if doms != None:
|
||||
for id in self.vmm.listDomainsID():
|
||||
vm = self.vmm.lookupByID(id)
|
||||
newVms[vm.name()] = vm
|
||||
|
||||
for name in self.vms.keys():
|
||||
if not(newVms.has_key(name)):
|
||||
del self.vms[name]
|
||||
self.notify_removed(name)
|
||||
|
||||
for name in newVms.keys():
|
||||
if not(self.vms.has_key(name)):
|
||||
self.vms[name] = { "handle": newVms[name],
|
||||
"stats": [] }
|
||||
self.notify_added(name)
|
||||
|
||||
now = time()
|
||||
|
||||
totalCpuTime = 0
|
||||
for name in self.vms.keys():
|
||||
info = self.vms[name]["handle"].info()
|
||||
|
||||
if len(self.vms[name]["stats"]) > self.conf.get_stats_history_length():
|
||||
self.vms[name]["stats"] = self.vms[name]["stats"][0:len(self.vms[name]["stats"])-1]
|
||||
|
||||
prevCpuTime = 0
|
||||
prevTimestamp = 0
|
||||
if len(self.vms[name]["stats"]) > 0:
|
||||
prevTimestamp = self.vms[name]["stats"][0]["timestamp"]
|
||||
prevCpuTime = self.vms[name]["stats"][0]["absCpuTime"]
|
||||
|
||||
print str(now-prevTimestamp)
|
||||
print str(info[4]-prevCpuTime)
|
||||
print str((now - prevTimestamp)*1000 * 1000)
|
||||
print
|
||||
pcentCpuTime = (info[4]-prevCpuTime) * 100 / ((now - prevTimestamp)*1000 * 1000*1000)
|
||||
|
||||
newStats = [{ "timestamp": now,
|
||||
"status": info[0],
|
||||
"absCpuTime": info[4],
|
||||
"relCpuTime": (info[4]-prevCpuTime),
|
||||
"pcentCpuTime": pcentCpuTime,
|
||||
"currMem": info[2],
|
||||
"maxMem": info[1] }]
|
||||
totalCpuTime = totalCpuTime + newStats[0]["relCpuTime"]
|
||||
newStats.append(self.vms[name]["stats"])
|
||||
self.vms[name]["stats"] = newStats
|
||||
|
||||
def current_memory(self, name):
|
||||
return self.vms[name]["stats"][0]["currMem"]
|
||||
|
||||
def maximum_memory(self, name):
|
||||
return self.vms[name]["stats"][0]["maxMem"]
|
||||
|
||||
def percent_cpu_time(self, name):
|
||||
return self.vms[name]["stats"][0]["pcentCpuTime"]
|
||||
|
||||
def run_status(self, name):
|
||||
status = self.vms[name]["stats"][0]["status"]
|
||||
if status == libvirt.VIR_DOMAIN_NOSTATE:
|
||||
return "Idle"
|
||||
elif status == libvirt.VIR_DOMAIN_RUNNING:
|
||||
return "Running"
|
||||
elif status == libvirt.VIR_DOMAIN_BLOCKED:
|
||||
return "Blocked"
|
||||
elif status == libvirt.VIR_DOMAIN_PAUSED:
|
||||
return "Paused"
|
||||
elif status == libvirt.VIR_DOMAIN_SHUTDOWN:
|
||||
return "Shutdown"
|
||||
elif status == libvirt.VIR_DOMAIN_SHUTOFF:
|
||||
return "Shutoff"
|
||||
elif status == libvirt.VIR_DOMAIN_CRASHED:
|
||||
return "Crashed"
|
||||
else:
|
||||
raise "Unknown status code"
|
||||
|
||||
|
||||
# Run me!
|
||||
def main():
|
||||
|
|
Loading…
Reference in New Issue