2007-03-27 19:52:00 -04:00
|
|
|
#
|
|
|
|
|
# Copyright (C) 2007 Red Hat, Inc.
|
|
|
|
|
# Copyright (C) 2007 Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
|
#
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
#
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
|
# along with this program; if not, write to the Free Software
|
2007-11-20 11:12:20 -05:00
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
|
# MA 02110-1301 USA.
|
2007-03-27 19:52:00 -04:00
|
|
|
#
|
|
|
|
|
|
|
|
|
|
import gobject
|
|
|
|
|
import gtk
|
|
|
|
|
import gtk.glade
|
|
|
|
|
import libvirt
|
|
|
|
|
import sparkline
|
|
|
|
|
import logging
|
2007-04-10 18:47:05 -04:00
|
|
|
import os
|
2008-08-15 11:07:45 -04:00
|
|
|
import traceback
|
|
|
|
|
|
|
|
|
|
from virtinst import Storage
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2007-03-29 21:23:17 -04:00
|
|
|
from virtManager.createnet import vmmCreateNetwork
|
2008-08-15 11:07:45 -04:00
|
|
|
from virtManager.createpool import vmmCreatePool
|
|
|
|
|
from virtManager.createvol import vmmCreateVolume
|
2008-03-19 15:39:12 -04:00
|
|
|
from virtManager.error import vmmErrorDialog
|
2007-03-29 21:23:17 -04:00
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
class vmmHost(gobject.GObject):
|
|
|
|
|
__gsignals__ = {
|
2008-04-22 10:40:59 -04:00
|
|
|
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
|
|
|
|
|
gobject.TYPE_NONE, [str]),
|
2007-03-27 19:52:00 -04:00
|
|
|
}
|
|
|
|
|
def __init__(self, config, conn):
|
|
|
|
|
self.__gobject_init__()
|
|
|
|
|
self.window = gtk.glade.XML(config.get_glade_dir() + "/vmm-host.glade", "vmm-host", domain="virt-manager")
|
|
|
|
|
self.config = config
|
|
|
|
|
self.conn = conn
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
self.PIXBUF_STATE_RUNNING = gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/state_running.png", 18, 18)
|
|
|
|
|
self.PIXBUF_STATE_SHUTOFF = gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/state_shutoff.png", 18, 18)
|
|
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
topwin = self.window.get_widget("vmm-host")
|
|
|
|
|
topwin.hide()
|
|
|
|
|
|
2008-03-19 15:39:12 -04:00
|
|
|
self.err = vmmErrorDialog(topwin,
|
|
|
|
|
0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
|
|
|
|
|
_("Unexpected Error"),
|
|
|
|
|
_("An unexpected error occurred"))
|
|
|
|
|
|
2007-09-27 11:20:45 -04:00
|
|
|
self.window.get_widget("overview-uri").set_text(self.conn.get_uri())
|
2007-08-31 17:31:00 -04:00
|
|
|
self.window.get_widget("overview-hostname").set_text(self.conn.get_hostname(True))
|
2007-09-10 20:09:58 -04:00
|
|
|
self.window.get_widget("overview-hypervisor").set_text(self.conn.get_driver())
|
2007-03-27 19:52:00 -04:00
|
|
|
self.window.get_widget("overview-memory").set_text(self.conn.pretty_host_memory_size())
|
|
|
|
|
self.window.get_widget("overview-cpus").set_text(str(self.conn.host_active_processor_count()))
|
|
|
|
|
self.window.get_widget("overview-arch").set_text(self.conn.host_architecture())
|
2008-03-24 11:39:19 -04:00
|
|
|
self.window.get_widget("config-autoconnect").set_active(conn.get_autoconnect())
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2007-07-14 14:43:20 -04:00
|
|
|
netListModel = gtk.ListStore(str, str, str)
|
2007-03-27 19:52:00 -04:00
|
|
|
self.window.get_widget("net-list").set_model(netListModel)
|
|
|
|
|
self.populate_networks(netListModel)
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
poolListModel = gtk.ListStore(str, str, float)
|
|
|
|
|
self.window.get_widget("pool-list").set_model(poolListModel)
|
|
|
|
|
self.populate_storage_pools(poolListModel)
|
|
|
|
|
|
|
|
|
|
volListModel = gtk.ListStore(str, str, str, str)
|
|
|
|
|
self.window.get_widget("vol-list").set_model(volListModel)
|
|
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
self.window.get_widget("net-list").get_selection().connect("changed", self.net_selected)
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("pool-list").get_selection().connect("changed", self.pool_selected)
|
|
|
|
|
self.window.get_widget("vol-list").get_selection().connect("changed", self.vol_selected)
|
2007-03-27 19:52:00 -04:00
|
|
|
|
|
|
|
|
netCol = gtk.TreeViewColumn("Networks")
|
|
|
|
|
net_txt = gtk.CellRendererText()
|
|
|
|
|
net_img = gtk.CellRendererPixbuf()
|
|
|
|
|
netCol.pack_start(net_txt, True)
|
|
|
|
|
netCol.pack_start(net_img, False)
|
|
|
|
|
netCol.add_attribute(net_txt, 'text', 1)
|
2007-07-14 14:43:20 -04:00
|
|
|
netCol.add_attribute(net_img, 'stock-id', 2)
|
2007-03-27 19:52:00 -04:00
|
|
|
self.window.get_widget("net-list").append_column(netCol)
|
2008-08-26 10:55:03 -04:00
|
|
|
netListModel.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
poolCol = gtk.TreeViewColumn("Pools")
|
|
|
|
|
pool_txt = gtk.CellRendererText()
|
|
|
|
|
pool_prg = gtk.CellRendererProgress()
|
|
|
|
|
poolCol.pack_start(pool_txt, True)
|
|
|
|
|
poolCol.pack_start(pool_prg, False)
|
|
|
|
|
poolCol.add_attribute(pool_txt, 'text', 1)
|
|
|
|
|
poolCol.add_attribute(pool_prg, 'value', 2)
|
|
|
|
|
self.window.get_widget("pool-list").append_column(poolCol)
|
2008-08-26 10:55:03 -04:00
|
|
|
poolListModel.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
volCol = gtk.TreeViewColumn("Volumes")
|
|
|
|
|
vol_txt1 = gtk.CellRendererText()
|
|
|
|
|
volCol.pack_start(vol_txt1, True)
|
|
|
|
|
volCol.add_attribute(vol_txt1, 'text', 1)
|
2008-08-26 10:55:03 -04:00
|
|
|
volCol.set_sort_column_id(1)
|
|
|
|
|
self.window.get_widget("net-details").set_sensitive(False)
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("vol-list").append_column(volCol)
|
|
|
|
|
|
|
|
|
|
volSizeCol = gtk.TreeViewColumn("Size")
|
|
|
|
|
vol_txt2 = gtk.CellRendererText()
|
|
|
|
|
volSizeCol.pack_start(vol_txt2, False)
|
|
|
|
|
volSizeCol.add_attribute(vol_txt2, 'text', 2)
|
2008-08-26 10:55:03 -04:00
|
|
|
volSizeCol.set_sort_column_id(2)
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("vol-list").append_column(volSizeCol)
|
|
|
|
|
|
|
|
|
|
volFormatCol = gtk.TreeViewColumn("Format")
|
|
|
|
|
vol_txt3 = gtk.CellRendererText()
|
|
|
|
|
volFormatCol.pack_start(vol_txt3, False)
|
|
|
|
|
volFormatCol.add_attribute(vol_txt3, 'text', 3)
|
2008-08-26 10:55:03 -04:00
|
|
|
volFormatCol.set_sort_column_id(3)
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("vol-list").append_column(volFormatCol)
|
2008-08-26 10:55:03 -04:00
|
|
|
volListModel.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
2008-08-15 11:07:45 -04:00
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
self.cpu_usage_graph = sparkline.Sparkline()
|
|
|
|
|
self.cpu_usage_graph.show()
|
|
|
|
|
self.window.get_widget("performance-table").attach(self.cpu_usage_graph, 1, 2, 0, 1)
|
|
|
|
|
|
|
|
|
|
self.memory_usage_graph = sparkline.Sparkline()
|
|
|
|
|
self.memory_usage_graph.show()
|
|
|
|
|
self.window.get_widget("performance-table").attach(self.memory_usage_graph, 1, 2, 1, 2)
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
self.addnet = None
|
|
|
|
|
self.addpool = None
|
|
|
|
|
self.addvol = None
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2007-03-29 21:23:17 -04:00
|
|
|
self.conn.connect("net-added", self.repopulate_networks)
|
|
|
|
|
self.conn.connect("net-removed", self.repopulate_networks)
|
2008-08-15 11:07:45 -04:00
|
|
|
self.conn.connect("net-started", self.refresh_network)
|
|
|
|
|
self.conn.connect("net-stopped", self.refresh_network)
|
|
|
|
|
|
|
|
|
|
self.conn.connect("pool-added", self.repopulate_storage_pools)
|
|
|
|
|
self.conn.connect("pool-removed", self.repopulate_storage_pools)
|
|
|
|
|
self.conn.connect("pool-started", self.refresh_storage_pool)
|
|
|
|
|
self.conn.connect("pool-stopped", self.refresh_storage_pool)
|
2007-03-29 21:23:17 -04:00
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
self.window.signal_autoconnect({
|
|
|
|
|
"on_menu_file_close_activate": self.close,
|
|
|
|
|
"on_vmm_host_delete_event": self.close,
|
2008-04-22 11:25:00 -04:00
|
|
|
"on_menu_help_contents_activate": self.show_help,
|
2007-03-29 21:23:17 -04:00
|
|
|
"on_net_add_clicked": self.add_network,
|
2007-04-03 14:01:45 -04:00
|
|
|
"on_net_delete_clicked": self.delete_network,
|
|
|
|
|
"on_net_stop_clicked": self.stop_network,
|
|
|
|
|
"on_net_start_clicked": self.start_network,
|
2008-08-26 11:17:31 -04:00
|
|
|
"on_net_autostart_toggled": self.net_autostart_changed,
|
|
|
|
|
"on_net_apply_clicked": self.net_apply,
|
2008-08-15 11:07:45 -04:00
|
|
|
"on_pool_add_clicked" : self.add_pool,
|
|
|
|
|
"on_vol_add_clicked" : self.add_vol,
|
|
|
|
|
"on_pool_stop_clicked": self.stop_pool,
|
|
|
|
|
"on_pool_start_clicked": self.start_pool,
|
|
|
|
|
"on_pool_delete_clicked": self.delete_pool,
|
|
|
|
|
"on_pool_autostart_toggled": self.pool_autostart_changed,
|
|
|
|
|
"on_vol_delete_clicked": self.delete_vol,
|
|
|
|
|
"on_pool_apply_clicked": self.pool_apply,
|
2008-03-24 11:39:19 -04:00
|
|
|
"on_config_autoconnect_toggled": self.toggle_autoconnect,
|
2007-03-27 19:52:00 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
self.conn.connect("resources-sampled", self.refresh_resources)
|
2007-09-10 20:09:58 -04:00
|
|
|
self.refresh_resources()
|
2008-08-15 11:07:45 -04:00
|
|
|
self.reset_pool_state()
|
2008-08-26 10:55:03 -04:00
|
|
|
self.reset_net_state()
|
2007-03-27 19:52:00 -04:00
|
|
|
|
|
|
|
|
def show(self):
|
2008-03-24 11:39:19 -04:00
|
|
|
# Update autostart value
|
|
|
|
|
self.window.get_widget("config-autoconnect").set_active(self.conn.get_autoconnect())
|
2007-03-27 19:52:00 -04:00
|
|
|
dialog = self.window.get_widget("vmm-host")
|
|
|
|
|
dialog.present()
|
|
|
|
|
|
|
|
|
|
def is_visible(self):
|
|
|
|
|
if self.window.get_widget("vmm-host").flags() & gtk.VISIBLE:
|
|
|
|
|
return 1
|
|
|
|
|
return 0
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
def close(self,ignore1=None,ignore2=None):
|
|
|
|
|
self.window.get_widget("vmm-host").hide()
|
|
|
|
|
return 1
|
2007-08-28 21:43:27 -04:00
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
def show_help(self, src):
|
|
|
|
|
self.emit("action-show-help", "virt-manager-host-window")
|
2007-03-29 21:23:17 -04:00
|
|
|
|
2008-03-24 11:39:19 -04:00
|
|
|
def toggle_autoconnect(self, ignore=None):
|
|
|
|
|
if self.conn.get_autoconnect() != \
|
|
|
|
|
self.window.get_widget("config-autoconnect").get_active():
|
|
|
|
|
self.conn.toggle_autoconnect()
|
|
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
def refresh_resources(self, ignore=None):
|
|
|
|
|
self.window.get_widget("performance-cpu").set_text("%d %%" % self.conn.cpu_time_percentage())
|
|
|
|
|
vm_memory = self.conn.pretty_current_memory()
|
|
|
|
|
host_memory = self.conn.pretty_host_memory_size()
|
|
|
|
|
self.window.get_widget("performance-memory").set_text("%s of %s" % (vm_memory, host_memory))
|
|
|
|
|
|
|
|
|
|
cpu_vector = self.conn.cpu_time_vector()
|
|
|
|
|
cpu_vector.reverse()
|
|
|
|
|
self.cpu_usage_graph.set_property("data_array", cpu_vector)
|
|
|
|
|
|
|
|
|
|
memory_vector = self.conn.current_memory_vector()
|
|
|
|
|
memory_vector.reverse()
|
|
|
|
|
self.memory_usage_graph.set_property("data_array", memory_vector)
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
# -------------------------
|
|
|
|
|
# Virtual Network functions
|
|
|
|
|
# -------------------------
|
|
|
|
|
|
|
|
|
|
def delete_network(self, src):
|
|
|
|
|
net = self.current_network()
|
2008-08-26 12:10:25 -04:00
|
|
|
if net is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
result = self.err.yes_no(_("This will permanently delete the network "
|
|
|
|
|
"'%s,' are you sure?") % net.get_name())
|
|
|
|
|
if not result:
|
|
|
|
|
return
|
|
|
|
|
try:
|
2008-08-15 11:07:45 -04:00
|
|
|
net.delete()
|
2008-08-26 12:10:25 -04:00
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error deleting network: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def start_network(self, src):
|
|
|
|
|
net = self.current_network()
|
2008-08-26 12:10:25 -04:00
|
|
|
if net is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
2008-08-15 11:07:45 -04:00
|
|
|
net.start()
|
2008-08-26 12:10:25 -04:00
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error starting network: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def stop_network(self, src):
|
|
|
|
|
net = self.current_network()
|
2008-08-26 12:10:25 -04:00
|
|
|
if net is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
2008-08-15 11:07:45 -04:00
|
|
|
net.stop()
|
2008-08-26 12:10:25 -04:00
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error stopping network: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def add_network(self, src):
|
2008-08-26 12:10:25 -04:00
|
|
|
try:
|
|
|
|
|
if self.addnet is None:
|
|
|
|
|
self.addnet = vmmCreateNetwork(self.config, self.conn)
|
|
|
|
|
self.addnet.show()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error launching network wizard: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
2008-08-26 11:17:31 -04:00
|
|
|
def net_apply(self, src):
|
|
|
|
|
net = self.current_network()
|
|
|
|
|
if net is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
net.set_autostart(self.window.get_widget("net-autostart").get_active())
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error setting net autostart: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
return
|
|
|
|
|
self.window.get_widget("net-apply").set_sensitive(False)
|
|
|
|
|
|
|
|
|
|
def net_autostart_changed(self, src):
|
|
|
|
|
auto = self.window.get_widget("net-autostart").get_active()
|
|
|
|
|
self.window.get_widget("net-autostart").set_label(auto and \
|
|
|
|
|
_("On Boot") or \
|
|
|
|
|
_("Never"))
|
|
|
|
|
self.window.get_widget("net-apply").set_sensitive(True)
|
|
|
|
|
|
2007-04-03 14:01:45 -04:00
|
|
|
def current_network(self):
|
|
|
|
|
sel = self.window.get_widget("net-list").get_selection()
|
|
|
|
|
active = sel.get_selected()
|
|
|
|
|
if active[1] != None:
|
|
|
|
|
curruuid = active[0].get_value(active[1], 0)
|
|
|
|
|
return self.conn.get_net(curruuid)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def refresh_network(self, src, uri, uuid):
|
|
|
|
|
sel = self.window.get_widget("net-list").get_selection()
|
|
|
|
|
active = sel.get_selected()
|
|
|
|
|
if active[1] != None:
|
|
|
|
|
curruuid = active[0].get_value(active[1], 0)
|
|
|
|
|
if curruuid == uuid:
|
|
|
|
|
self.net_selected(sel)
|
2007-03-27 19:52:00 -04:00
|
|
|
|
|
|
|
|
def net_selected(self, src):
|
2008-08-26 10:55:03 -04:00
|
|
|
selected = src.get_selected()
|
|
|
|
|
if selected[1] == None or \
|
|
|
|
|
selected[0].get_value(selected[1], 0) == None:
|
|
|
|
|
self.reset_net_state()
|
|
|
|
|
return
|
|
|
|
|
net = self.conn.get_net(selected[0].get_value(selected[1], 0))
|
|
|
|
|
active = net.is_active()
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("net-details").set_sensitive(True)
|
|
|
|
|
self.window.get_widget("net-name").set_text(net.get_name())
|
|
|
|
|
|
|
|
|
|
if active:
|
|
|
|
|
self.window.get_widget("net-device").set_text(net.get_bridge_device())
|
|
|
|
|
self.window.get_widget("net-device").set_sensitive(True)
|
|
|
|
|
self.window.get_widget("net-state").set_text(_("Active"))
|
|
|
|
|
self.window.get_widget("net-state-icon").set_from_pixbuf(self.PIXBUF_STATE_RUNNING)
|
|
|
|
|
else:
|
|
|
|
|
self.window.get_widget("net-device").set_text("")
|
|
|
|
|
self.window.get_widget("net-device").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("net-state").set_text(_("Inactive"))
|
|
|
|
|
self.window.get_widget("net-state-icon").set_from_pixbuf(self.PIXBUF_STATE_SHUTOFF)
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("net-start").set_sensitive(not active)
|
|
|
|
|
self.window.get_widget("net-stop").set_sensitive(active)
|
|
|
|
|
self.window.get_widget("net-delete").set_sensitive(not active)
|
|
|
|
|
|
|
|
|
|
autostart = net.get_autostart()
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-autostart").set_active(autostart)
|
2008-08-26 10:55:03 -04:00
|
|
|
if autostart:
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-autostart").set_label(_("On Boot"))
|
2008-08-26 10:55:03 -04:00
|
|
|
else:
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-autostart").set_label(_("Never"))
|
2008-08-26 10:55:03 -04:00
|
|
|
|
|
|
|
|
network = net.get_ipv4_network()
|
|
|
|
|
self.window.get_widget("net-ip4-network").set_text(str(network))
|
|
|
|
|
|
|
|
|
|
dhcp = net.get_ipv4_dhcp_range()
|
|
|
|
|
self.window.get_widget("net-ip4-dhcp-start").set_text(str(dhcp[0]))
|
|
|
|
|
self.window.get_widget("net-ip4-dhcp-end").set_text(str(dhcp[1]))
|
|
|
|
|
|
|
|
|
|
(forward, forwardDev) = net.get_ipv4_forward()
|
|
|
|
|
if forward:
|
|
|
|
|
self.window.get_widget("net-ip4-forwarding-icon").set_from_stock(gtk.STOCK_CONNECT, gtk.ICON_SIZE_MENU)
|
|
|
|
|
if forwardDev != None and forwardDev != "":
|
|
|
|
|
self.window.get_widget("net-ip4-forwarding").set_text(_("NAT to physical device %s") % (forwardDev))
|
2007-03-27 19:52:00 -04:00
|
|
|
else:
|
2008-08-26 10:55:03 -04:00
|
|
|
self.window.get_widget("net-ip4-forwarding").set_text(_("NAT to any physical device"))
|
2007-03-27 19:52:00 -04:00
|
|
|
else:
|
2008-08-26 10:55:03 -04:00
|
|
|
self.window.get_widget("net-ip4-forwarding-icon").set_from_stock(gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_MENU)
|
|
|
|
|
self.window.get_widget("net-ip4-forwarding").set_text(_("Isolated virtual network"))
|
|
|
|
|
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-apply").set_sensitive(False)
|
|
|
|
|
|
2008-08-26 10:55:03 -04:00
|
|
|
def reset_net_state(self):
|
|
|
|
|
self.window.get_widget("net-details").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("net-name").set_text("")
|
|
|
|
|
self.window.get_widget("net-device").set_text("")
|
|
|
|
|
self.window.get_widget("net-device").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("net-state").set_text(_("Inactive"))
|
|
|
|
|
self.window.get_widget("net-state-icon").set_from_pixbuf(self.PIXBUF_STATE_SHUTOFF)
|
|
|
|
|
self.window.get_widget("net-start").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("net-stop").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("net-delete").set_sensitive(False)
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-autostart").set_label(_("Never"))
|
|
|
|
|
self.window.get_widget("net-autostart").set_active(False)
|
2008-08-26 10:55:03 -04:00
|
|
|
self.window.get_widget("net-ip4-network").set_text("")
|
|
|
|
|
self.window.get_widget("net-ip4-dhcp-start").set_text("")
|
|
|
|
|
self.window.get_widget("net-ip4-dhcp-end").set_text("")
|
|
|
|
|
self.window.get_widget("net-ip4-forwarding-icon").set_from_stock(gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_MENU)
|
|
|
|
|
self.window.get_widget("net-ip4-forwarding").set_text(_("Isolated virtual network"))
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("net-apply").set_sensitive(False)
|
2007-03-27 19:52:00 -04:00
|
|
|
|
2007-03-29 21:23:17 -04:00
|
|
|
def repopulate_networks(self, src, uri, uuid):
|
|
|
|
|
self.populate_networks(self.window.get_widget("net-list").get_model())
|
|
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
def populate_networks(self, model):
|
|
|
|
|
model.clear()
|
|
|
|
|
for uuid in self.conn.list_net_uuids():
|
|
|
|
|
net = self.conn.get_net(uuid)
|
2007-07-14 14:43:20 -04:00
|
|
|
model.append([uuid, net.get_name(), gtk.STOCK_NETWORK])
|
2007-03-27 19:52:00 -04:00
|
|
|
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
# ------------------------------
|
|
|
|
|
# Storage Manager methods
|
|
|
|
|
# ------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def stop_pool(self, src):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if pool is not None:
|
|
|
|
|
try:
|
|
|
|
|
pool.stop()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error starting pool '%s': %s") % \
|
|
|
|
|
(pool.get_name(), str(e)),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
|
|
|
|
|
def start_pool(self, src):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if pool is not None:
|
|
|
|
|
try:
|
|
|
|
|
pool.start()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error starting pool '%s': %s") % \
|
|
|
|
|
(pool.get_name(), str(e)),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
|
|
|
|
|
def delete_pool(self, src):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if pool is None:
|
|
|
|
|
return
|
|
|
|
|
|
2008-08-25 16:26:35 -04:00
|
|
|
result = self.err.yes_no(_("This will permanently delete the pool "
|
2008-08-15 11:07:45 -04:00
|
|
|
"'%s,' are you sure?") % pool.get_name())
|
|
|
|
|
if not result:
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
pool.delete()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error deleting pool: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
|
|
|
|
|
def delete_vol(self, src):
|
|
|
|
|
vol = self.current_vol()
|
|
|
|
|
if vol is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
result = self.err.yes_no(_("This will permanently delete the volume "
|
|
|
|
|
"'%s,' are you sure?") % vol.get_name())
|
|
|
|
|
if not result:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
vol.delete()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error deleting volume: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
return
|
|
|
|
|
self.populate_storage_volumes()
|
|
|
|
|
|
|
|
|
|
def add_pool(self, src):
|
2008-08-26 12:10:25 -04:00
|
|
|
try:
|
|
|
|
|
if self.addpool is None:
|
|
|
|
|
self.addpool = vmmCreatePool(self.config, self.conn)
|
|
|
|
|
self.addpool.show()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error launching pool wizard: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def add_vol(self, src):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if pool is None:
|
|
|
|
|
return
|
2008-08-15 12:44:45 -04:00
|
|
|
try:
|
|
|
|
|
if self.addvol is None:
|
|
|
|
|
self.addvol = vmmCreateVolume(self.config, self.conn, pool)
|
|
|
|
|
self.addvol.connect("vol-created", self.refresh_current_pool)
|
|
|
|
|
else:
|
|
|
|
|
self.addvol.set_parent_pool(pool)
|
|
|
|
|
self.addvol.show()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error launching volume wizard: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def refresh_current_pool(self, ignore1=None):
|
|
|
|
|
cp = self.current_pool()
|
|
|
|
|
if cp is None:
|
|
|
|
|
return
|
|
|
|
|
self.refresh_storage_pool(None, None, cp.get_uuid())
|
|
|
|
|
|
|
|
|
|
def current_pool(self):
|
|
|
|
|
sel = self.window.get_widget("pool-list").get_selection()
|
|
|
|
|
active = sel.get_selected()
|
|
|
|
|
if active[1] != None:
|
|
|
|
|
curruuid = active[0].get_value(active[1], 0)
|
|
|
|
|
return self.conn.get_pool(curruuid)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def current_vol(self):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if not pool:
|
|
|
|
|
return None
|
|
|
|
|
sel = self.window.get_widget("vol-list").get_selection()
|
|
|
|
|
active = sel.get_selected()
|
|
|
|
|
if active[1] != None:
|
|
|
|
|
curruuid = active[0].get_value(active[1], 0)
|
|
|
|
|
return pool.get_volume(curruuid)
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def pool_apply(self, src):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
if pool is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
pool.set_autostart(self.window.get_widget("pool-autostart").get_active())
|
|
|
|
|
except Exception, e:
|
|
|
|
|
self.err.show_err(_("Error setting pool autostart: %s") % str(e),
|
|
|
|
|
"".join(traceback.format_exc()))
|
|
|
|
|
return
|
|
|
|
|
self.window.get_widget("pool-apply").set_sensitive(False)
|
|
|
|
|
|
|
|
|
|
def pool_autostart_changed(self, src):
|
|
|
|
|
auto = self.window.get_widget("pool-autostart").get_active()
|
|
|
|
|
self.window.get_widget("pool-autostart").set_label(auto and \
|
|
|
|
|
_("On Boot") or \
|
|
|
|
|
_("Never"))
|
|
|
|
|
self.window.get_widget("pool-apply").set_sensitive(True)
|
|
|
|
|
|
|
|
|
|
def pool_selected(self, src):
|
|
|
|
|
selected = src.get_selected()
|
|
|
|
|
if selected[1] is None or \
|
|
|
|
|
selected[0].get_value(selected[1], 0) is None:
|
|
|
|
|
self.reset_pool_state()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
uuid = selected[0].get_value(selected[1], 0)
|
|
|
|
|
pool = self.conn.get_pool(uuid)
|
|
|
|
|
auto = pool.get_autostart()
|
|
|
|
|
active = pool.is_active()
|
|
|
|
|
|
|
|
|
|
# Set pool details state
|
|
|
|
|
self.window.get_widget("pool-details").set_sensitive(True)
|
|
|
|
|
self.window.get_widget("pool-name").set_markup("<b>%s:</b>" % \
|
|
|
|
|
pool.get_name())
|
|
|
|
|
self.window.get_widget("pool-sizes").set_markup("""<span size="large">%s Free</span> / <i>%s In Use</i>""" % (pool.get_pretty_available(), pool.get_pretty_allocation()))
|
|
|
|
|
self.window.get_widget("pool-type").set_text(Storage.StoragePool.get_pool_type_desc(pool.get_type()))
|
|
|
|
|
self.window.get_widget("pool-location").set_text(pool.get_target_path())
|
|
|
|
|
self.window.get_widget("pool-state-icon").set_from_pixbuf((active and self.PIXBUF_STATE_RUNNING) or self.PIXBUF_STATE_SHUTOFF)
|
|
|
|
|
self.window.get_widget("pool-state").set_text((active and _("Active")) or _("Inactive"))
|
2008-08-26 11:17:31 -04:00
|
|
|
self.window.get_widget("pool-autostart").set_label((auto and _("On Boot")) or _("Never"))
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("pool-autostart").set_active(auto)
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("vol-list").set_sensitive(active)
|
|
|
|
|
self.populate_storage_volumes()
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("pool-delete").set_sensitive(not active)
|
|
|
|
|
self.window.get_widget("pool-stop").set_sensitive(active)
|
|
|
|
|
self.window.get_widget("pool-start").set_sensitive(not active)
|
|
|
|
|
self.window.get_widget("pool-apply").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("vol-add").set_sensitive(active)
|
|
|
|
|
self.window.get_widget("vol-delete").set_sensitive(False)
|
|
|
|
|
|
|
|
|
|
def refresh_storage_pool(self, src, uri, uuid):
|
|
|
|
|
sel = self.window.get_widget("pool-list").get_selection()
|
2008-08-26 12:58:53 -04:00
|
|
|
model = self.window.get_widget("pool-list").get_model()
|
2008-08-15 11:07:45 -04:00
|
|
|
active = sel.get_selected()
|
2008-09-05 21:28:26 -04:00
|
|
|
if active[1] == None:
|
|
|
|
|
return
|
|
|
|
|
curruuid = active[0].get_value(active[1], 0)
|
|
|
|
|
if curruuid != uuid:
|
|
|
|
|
return
|
2008-08-26 12:58:53 -04:00
|
|
|
self.pool_selected(sel)
|
|
|
|
|
for row in model:
|
|
|
|
|
if row[0] == curruuid:
|
|
|
|
|
row[2] = self.get_pool_size_percent(uuid)
|
|
|
|
|
break
|
2008-08-15 11:07:45 -04:00
|
|
|
|
|
|
|
|
def reset_pool_state(self):
|
|
|
|
|
self.window.get_widget("pool-details").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("pool-name").set_text("")
|
2008-08-26 10:55:03 -04:00
|
|
|
self.window.get_widget("pool-sizes").set_markup("""<span size="large"> </span>""")
|
2008-08-15 11:07:45 -04:00
|
|
|
self.window.get_widget("pool-type").set_text("")
|
|
|
|
|
self.window.get_widget("pool-location").set_text("")
|
|
|
|
|
self.window.get_widget("pool-state-icon").set_from_pixbuf(self.PIXBUF_STATE_SHUTOFF)
|
|
|
|
|
self.window.get_widget("pool-state").set_text(_("Inactive"))
|
|
|
|
|
self.window.get_widget("vol-list").get_model().clear()
|
|
|
|
|
self.window.get_widget("pool-autostart").set_label(_("Never"))
|
|
|
|
|
self.window.get_widget("pool-autostart").set_active(False)
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("pool-delete").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("pool-stop").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("pool-start").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("pool-apply").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("vol-add").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("vol-delete").set_sensitive(False)
|
|
|
|
|
self.window.get_widget("vol-list").set_sensitive(False)
|
|
|
|
|
|
|
|
|
|
def vol_selected(self, src):
|
|
|
|
|
selected = src.get_selected()
|
|
|
|
|
if selected[1] is None or \
|
|
|
|
|
selected[0].get_value(selected[1], 0) is None:
|
|
|
|
|
self.window.get_widget("vol-delete").set_sensitive(False)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.window.get_widget("vol-delete").set_sensitive(True)
|
|
|
|
|
|
|
|
|
|
def repopulate_storage_pools(self, src, uri, uuid):
|
|
|
|
|
self.populate_storage_pools(self.window.get_widget("pool-list").get_model())
|
|
|
|
|
|
2008-08-26 12:58:53 -04:00
|
|
|
def get_pool_size_percent(self, uuid):
|
|
|
|
|
pool = self.conn.get_pool(uuid)
|
|
|
|
|
cap = pool.get_capacity()
|
|
|
|
|
all = pool.get_allocation()
|
|
|
|
|
if not cap or all is None:
|
|
|
|
|
per = 0
|
|
|
|
|
else:
|
|
|
|
|
per = int(((float(all) / float(cap)) * 100))
|
|
|
|
|
return per
|
|
|
|
|
|
2008-08-15 11:07:45 -04:00
|
|
|
def populate_storage_pools(self, model):
|
|
|
|
|
model.clear()
|
|
|
|
|
for uuid in self.conn.list_pool_uuids():
|
2008-08-26 12:58:53 -04:00
|
|
|
per = self.get_pool_size_percent(uuid)
|
2008-08-15 11:07:45 -04:00
|
|
|
pool = self.conn.get_pool(uuid)
|
|
|
|
|
model.append([uuid, pool.get_name(), per])
|
|
|
|
|
|
|
|
|
|
def populate_storage_volumes(self):
|
|
|
|
|
pool = self.current_pool()
|
|
|
|
|
model = self.window.get_widget("vol-list").get_model()
|
|
|
|
|
model.clear()
|
|
|
|
|
vols = pool.get_volumes()
|
|
|
|
|
for key in vols.keys():
|
|
|
|
|
vol = vols[key]
|
|
|
|
|
model.append([key, vol.get_name(), vol.get_pretty_capacity(),
|
|
|
|
|
vol.get_format() or ""])
|
|
|
|
|
|
2007-03-27 19:52:00 -04:00
|
|
|
gobject.type_register(vmmHost)
|