mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-25 23:21:45 +03:00
Added dialog for viewing host status & resource config
This commit is contained in:
parent
d06e495a04
commit
25a92026c4
@ -36,6 +36,8 @@ class vmmConnection(gobject.GObject):
|
||||
[str, str]),
|
||||
"vm-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||
[str, str]),
|
||||
"resources-sampled": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||
[]),
|
||||
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [str])
|
||||
}
|
||||
|
||||
@ -56,6 +58,7 @@ class vmmConnection(gobject.GObject):
|
||||
self.nets = {}
|
||||
self.vms = {}
|
||||
self.activeUUIDs = []
|
||||
self.record = []
|
||||
|
||||
def is_read_only(self):
|
||||
return self.readOnly
|
||||
@ -63,7 +66,7 @@ class vmmConnection(gobject.GObject):
|
||||
def get_type(self):
|
||||
return self.vmm.getType()
|
||||
|
||||
def get_name(self):
|
||||
def get_hostname(self):
|
||||
hostname = "localhost"
|
||||
try:
|
||||
(host, aliases, ipaddrs) = gethostbyaddr(gethostname())
|
||||
@ -71,28 +74,27 @@ class vmmConnection(gobject.GObject):
|
||||
except:
|
||||
logging.warning("Unable to resolve local hostname for machine")
|
||||
|
||||
if self.get_type()[0:3] == "Xen" and self.uri == "xen" or self.uri == "Xen" or self.uri is None:
|
||||
return hostname
|
||||
|
||||
if self.get_type() == "QEMU" and ( self.uri == "qemu:///session" or self.uri == "qemu://system"):
|
||||
return hostname
|
||||
|
||||
try:
|
||||
urlbits = urlparse(self.uri)
|
||||
return urlbits.netloc
|
||||
except:
|
||||
return hostname
|
||||
|
||||
def get_name(self):
|
||||
if self.get_type()[0:3] == "Xen":
|
||||
if self.uri == "xen" or self.uri == "Xen" or self.uri is None:
|
||||
return "Xen: " + hostname
|
||||
else:
|
||||
try:
|
||||
urlbits = urlparse(self.uri)
|
||||
return "Xen: " + urlbits.netloc
|
||||
except:
|
||||
return self.uri
|
||||
return "Xen: " + self.get_hostname()
|
||||
elif self.get_type() == "QEMU":
|
||||
if self.uri == "qemu:///session":
|
||||
return "QEMU session: " + hostname
|
||||
elif self.uri == "qemu:///system":
|
||||
return "QEMU system: " + hostname
|
||||
return "QEMU session: " + self.get_hostname()
|
||||
else:
|
||||
try:
|
||||
urlbits = urlparse(self.uri)
|
||||
return "QEMU system: " + urlbits.netloc
|
||||
except:
|
||||
return self.uri
|
||||
else:
|
||||
return self.uri
|
||||
return "QEMU system: " + self.get_hostname()
|
||||
|
||||
|
||||
def get_uri(self):
|
||||
return self.uri
|
||||
@ -129,9 +131,20 @@ class vmmConnection(gobject.GObject):
|
||||
|
||||
return handle_id
|
||||
|
||||
def pretty_host_memory_size(self):
|
||||
mem = self.host_memory_size()
|
||||
if mem > (1024*1024):
|
||||
return "%2.2f GB" % (mem/(1024.0*1024.0))
|
||||
else:
|
||||
return "%2.2f MB" % (mem/1024.0)
|
||||
|
||||
|
||||
def host_memory_size(self):
|
||||
return self.hostinfo[1]*1024
|
||||
|
||||
def host_architecture(self):
|
||||
return self.hostinfo[0]
|
||||
|
||||
def host_active_processor_count(self):
|
||||
return self.hostinfo[2]
|
||||
|
||||
@ -169,7 +182,7 @@ class vmmConnection(gobject.GObject):
|
||||
|
||||
# Now we can clear the list of actives from the last time through
|
||||
self.activeUUIDs = []
|
||||
|
||||
|
||||
newActiveIDs = self.vmm.listDomainsID()
|
||||
newInactiveNames = []
|
||||
try:
|
||||
@ -283,8 +296,109 @@ class vmmConnection(gobject.GObject):
|
||||
|
||||
for uuid in updateVMs.keys():
|
||||
self.vms[uuid].tick(now)
|
||||
|
||||
if not noStatsUpdate:
|
||||
self.recalculate_stats(now)
|
||||
|
||||
return 1
|
||||
|
||||
def recalculate_stats(self, now):
|
||||
expected = self.config.get_stats_history_length()
|
||||
current = len(self.record)
|
||||
if current > expected:
|
||||
del self.record[expected:current]
|
||||
|
||||
mem = 0
|
||||
cpuTime = 0
|
||||
|
||||
for uuid in self.vms:
|
||||
vm = self.vms[uuid]
|
||||
if vm.get_id() != -1:
|
||||
cpuTime = cpuTime + vm.get_cputime()
|
||||
mem = mem + vm.get_memory()
|
||||
|
||||
|
||||
pcentCpuTime = 0
|
||||
if len(self.record) > 0:
|
||||
prevTimestamp = self.record[0]["timestamp"]
|
||||
|
||||
pcentCpuTime = (cpuTime) * 100.0 / ((now - prevTimestamp)*1000.0*1000.0*1000.0*self.host_active_processor_count())
|
||||
# Due to timing diffs between getting wall time & getting
|
||||
# the domain's time, its possible to go a tiny bit over
|
||||
# 100% utilization. This freaks out users of the data, so
|
||||
# we hard limit it.
|
||||
if pcentCpuTime > 100.0:
|
||||
pcentCpuTime = 100.0
|
||||
# Enforce >= 0 just in case
|
||||
if pcentCpuTime < 0.0:
|
||||
pcentCpuTime = 0.0
|
||||
|
||||
pcentMem = mem * 100.0 / self.host_memory_size()
|
||||
|
||||
newStats = {
|
||||
"timestamp": now,
|
||||
"memory": mem,
|
||||
"memoryPercent": pcentMem,
|
||||
"cpuTime": cpuTime,
|
||||
"cpuTimePercent": pcentCpuTime
|
||||
}
|
||||
|
||||
self.record.insert(0, newStats)
|
||||
self.emit("resources-sampled")
|
||||
|
||||
def cpu_time_vector(self):
|
||||
vector = []
|
||||
stats = self.record
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
if i < len(stats):
|
||||
vector.append(stats[i]["cpuTimePercent"]/100.0)
|
||||
else:
|
||||
vector.append(0)
|
||||
return vector
|
||||
|
||||
def cpu_time_vector_limit(self, limit):
|
||||
cpudata = self.cpu_time_vector()
|
||||
if len(cpudata) > limit:
|
||||
cpudata = cpudata[0:limit]
|
||||
return cpudata
|
||||
|
||||
def cpu_time_percentage(self):
|
||||
if len(self.record) == 0:
|
||||
return 0
|
||||
return self.record[0]["cpuTimePercent"]
|
||||
|
||||
def current_memory(self):
|
||||
if len(self.record) == 0:
|
||||
return 0
|
||||
return self.record[0]["memory"]
|
||||
|
||||
def pretty_current_memory(self):
|
||||
mem = self.current_memory()
|
||||
if mem > (1024*1024):
|
||||
return "%2.2f GB" % (mem/(1024.0*1024.0))
|
||||
else:
|
||||
return "%2.2f MB" % (mem/1024.0)
|
||||
|
||||
def current_memory(self):
|
||||
if len(self.record) == 0:
|
||||
return 0
|
||||
return self.record[0]["memory"]
|
||||
|
||||
def current_memory_percentage(self):
|
||||
if len(self.record) == 0:
|
||||
return 0
|
||||
return self.record[0]["memoryPercent"]
|
||||
|
||||
def current_memory_vector(self):
|
||||
vector = []
|
||||
stats = self.record
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
if i < len(stats):
|
||||
vector.append(stats[i]["memoryPercent"]/100.0)
|
||||
else:
|
||||
vector.append(0)
|
||||
return vector
|
||||
|
||||
def uuidstr(self, rawuuid):
|
||||
hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
|
||||
uuid = []
|
||||
|
@ -220,6 +220,11 @@ class vmmDomain(gobject.GObject):
|
||||
return 0
|
||||
return self.record[0]["currMemPercent"]
|
||||
|
||||
def get_cputime(self):
|
||||
if len(self.record) == 0:
|
||||
return 0
|
||||
return self.record[0]["cpuTime"]
|
||||
|
||||
def get_memory_pretty(self):
|
||||
mem = self.get_memory()
|
||||
if mem > (1024*1024):
|
||||
|
@ -35,6 +35,7 @@ from virtManager.asyncjob import vmmAsyncJob
|
||||
from virtManager.create import vmmCreate
|
||||
from virtManager.serialcon import vmmSerialConsole
|
||||
from virtManager.error import vmmErrorDialog
|
||||
from virtManager.host import vmmHost
|
||||
|
||||
class vmmEngine:
|
||||
def __init__(self, config):
|
||||
@ -158,8 +159,9 @@ class vmmEngine:
|
||||
for name in [ "windowDetails", "windowConsole", "windowSerialConsole" ]:
|
||||
for window in conn[name].values():
|
||||
ct += window.is_visible()
|
||||
if conn["windowManager"]:
|
||||
ct += conn["windowManager"].is_visible()
|
||||
for name in [ "windowManager", "windowHost"]:
|
||||
if conn[name] != None and conn[name].is_visible():
|
||||
ct += 1
|
||||
if self.windowCreate:
|
||||
ct += self.windowCreate.is_visible()
|
||||
return ct
|
||||
@ -175,6 +177,8 @@ class vmmEngine:
|
||||
self.show_about()
|
||||
def _do_show_preferences(self, src):
|
||||
self.show_preferences()
|
||||
def _do_show_host(self, src, uri):
|
||||
self.show_host(uri)
|
||||
def _do_show_connect(self, src):
|
||||
self.show_connect()
|
||||
def _do_show_manager(self, src, uri):
|
||||
@ -211,6 +215,15 @@ class vmmEngine:
|
||||
self.windowPreferences.connect("action-show-help", self._do_show_help)
|
||||
self.windowPreferences.show()
|
||||
|
||||
def show_host(self, uri):
|
||||
con = self.get_connection(uri)
|
||||
|
||||
if self.connections[uri]["windowHost"] == None:
|
||||
manager = vmmHost(self.get_config(), con)
|
||||
manager.connect("action-show-help", self._do_show_help)
|
||||
self.connections[uri]["windowHost"] = manager
|
||||
self.connections[uri]["windowHost"].show()
|
||||
|
||||
def show_connect(self):
|
||||
if self.windowConnect == None:
|
||||
self.windowConnect = vmmConnect(self.get_config(), self)
|
||||
@ -248,7 +261,7 @@ class vmmEngine:
|
||||
def show_details_config(self, uri, uuid):
|
||||
win = self.show_details(uri, uuid)
|
||||
win.activate_config_page()
|
||||
|
||||
|
||||
def show_details(self, uri, uuid):
|
||||
con = self.get_connection(uri)
|
||||
|
||||
@ -277,6 +290,7 @@ class vmmEngine:
|
||||
manager.connect("action-show-create", self._do_show_create)
|
||||
manager.connect("action-show-help", self._do_show_help)
|
||||
manager.connect("action-show-about", self._do_show_about)
|
||||
manager.connect("action-show-host", self._do_show_host)
|
||||
manager.connect("action-show-connect", self._do_show_connect)
|
||||
self.connections[uri]["windowManager"] = manager
|
||||
self.connections[uri]["windowManager"].show()
|
||||
@ -295,6 +309,7 @@ class vmmEngine:
|
||||
self.connections[uri] = {
|
||||
"connection": vmmConnection(self.get_config(), uri, readOnly),
|
||||
"windowManager": None,
|
||||
"windowHost": None,
|
||||
"windowDetails": {},
|
||||
"windowConsole": {},
|
||||
"windowSerialConsole": {},
|
||||
|
150
src/virtManager/host.py
Normal file
150
src/virtManager/host.py
Normal file
@ -0,0 +1,150 @@
|
||||
#
|
||||
# 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
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
|
||||
import gobject
|
||||
import gtk
|
||||
import gtk.glade
|
||||
import libvirt
|
||||
import sparkline
|
||||
import logging
|
||||
|
||||
class vmmHost(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
"action-show-help": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE, [str]),
|
||||
}
|
||||
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
|
||||
|
||||
topwin = self.window.get_widget("vmm-host")
|
||||
topwin.hide()
|
||||
|
||||
self.window.get_widget("overview-hostname").set_text(self.conn.get_hostname())
|
||||
self.window.get_widget("overview-hypervisor").set_text(self.conn.get_type())
|
||||
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())
|
||||
|
||||
netListModel = gtk.ListStore(str, str, gtk.gdk.Pixbuf)
|
||||
self.window.get_widget("net-list").set_model(netListModel)
|
||||
self.populate_networks(netListModel)
|
||||
|
||||
self.window.get_widget("net-list").get_selection().connect("changed", self.net_selected)
|
||||
|
||||
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)
|
||||
netCol.add_attribute(net_img, 'pixbuf', 2)
|
||||
|
||||
self.window.get_widget("net-list").append_column(netCol)
|
||||
self.window.get_widget("net-details").set_sensitive(False)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
self.window.get_widget("details-tabs").get_nth_page(2).hide()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_menu_file_close_activate": self.close,
|
||||
"on_vmm_host_delete_event": self.close,
|
||||
"on_menu_help_about_activate": self.show_help,
|
||||
})
|
||||
|
||||
self.conn.connect("resources-sampled", self.refresh_resources)
|
||||
|
||||
def show(self):
|
||||
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
|
||||
|
||||
def show_help(self, src):
|
||||
# From the Details window, show the help document from the Details page
|
||||
self.emit("action-show-help", "virt-manager-host-window")
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-host").hide()
|
||||
return 1
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def net_selected(self, src):
|
||||
active = src.get_selected()
|
||||
if active[1] != None:
|
||||
uuid = active[0].get_value(active[1], 0)
|
||||
if uuid is None:
|
||||
self.window.get_widget("net-details").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("net-details").set_sensitive(True)
|
||||
net = self.conn.get_net(uuid)
|
||||
self.window.get_widget("net-name").set_text(net.get_name())
|
||||
self.window.get_widget("net-uuid").set_text(net.get_uuid())
|
||||
self.window.get_widget("net-device").set_text(net.get_bridge_device())
|
||||
|
||||
ip4 = net.get_ip4_config()
|
||||
self.window.get_widget("net-ip4-address").set_text(ip4[0])
|
||||
self.window.get_widget("net-ip4-netmask").set_text(ip4[1])
|
||||
self.window.get_widget("net-ip4-dhcp-start").set_text(ip4[2])
|
||||
self.window.get_widget("net-ip4-dhcp-end").set_text(ip4[3])
|
||||
|
||||
if ip4[4] != None and ip4[4] != "":
|
||||
self.window.get_widget("net-ip4-forwarding").set_text(_("NAT to physical device ") + ip4[4])
|
||||
else:
|
||||
self.window.get_widget("net-ip4-forwarding").set_text(_("Masquerade to default route"))
|
||||
else:
|
||||
self.window.get_widget("net-details").set_sensitive(False)
|
||||
|
||||
def populate_networks(self, model):
|
||||
model.clear()
|
||||
for uuid in self.conn.list_net_uuids():
|
||||
net = self.conn.get_net(uuid)
|
||||
model.append([uuid, net.get_name(), gtk.gdk.pixbuf_new_from_file(self.config.get_icon_dir() + "/icon_ethernet.png")])
|
||||
|
||||
#model.append([None, "Add network", gtk.gdk.pixbuf_new_from_file(self.config.get_icon_dir() + "/icon_addnew.png")])
|
||||
|
||||
|
||||
gobject.type_register(vmmHost)
|
@ -47,6 +47,8 @@ class vmmManager(gobject.GObject):
|
||||
gobject.TYPE_NONE, (str,str)),
|
||||
"action-show-about": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE, []),
|
||||
"action-show-host": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE, [str]),
|
||||
"action-show-preferences": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE, []),
|
||||
"action-show-create": (gobject.SIGNAL_RUN_FIRST,
|
||||
@ -95,7 +97,7 @@ class vmmManager(gobject.GObject):
|
||||
self.vmmenu_icons["run"] = gtk.Image()
|
||||
self.vmmenu_icons["run"].set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/icon_run.png", 18, 18))
|
||||
self.vmmenu_icons["pause"] = gtk.Image()
|
||||
self.vmmenu_icons["pause"].set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/icon_pause.png", 18, 18))
|
||||
self.vmmenu_icons["pause"].set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/icon_pause.png", 18, 18))
|
||||
self.vmmenu_icons["resume"] = gtk.Image()
|
||||
self.vmmenu_icons["resume"].set_from_pixbuf(gtk.gdk.pixbuf_new_from_file_at_size(self.config.get_icon_dir() + "/icon_pause.png", 18, 18))
|
||||
self.vmmenu_icons["shutdown"] = gtk.Image()
|
||||
@ -170,6 +172,7 @@ class vmmManager(gobject.GObject):
|
||||
"on_vm_new_clicked": self.show_vm_create,
|
||||
"on_vm_delete_clicked": self.delete_vm,
|
||||
"on_menu_edit_details_activate": self.show_vm_details,
|
||||
"on_menu_host_details_activate": self.show_host,
|
||||
|
||||
"on_vm_view_changed": self.vm_view_changed,
|
||||
"on_vm_list_row_activated": self.open_vm_console,
|
||||
@ -495,6 +498,9 @@ class vmmManager(gobject.GObject):
|
||||
def show_preferences(self, src):
|
||||
self.emit("action-show-preferences")
|
||||
|
||||
def show_host(self, src):
|
||||
self.emit("action-show-host", self.connection.get_uri())
|
||||
|
||||
def prepare_vmlist(self):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
|
||||
|
@ -64,30 +64,54 @@ class vmmNetwork(gobject.GObject):
|
||||
def get_uuid(self):
|
||||
return self.uuid
|
||||
|
||||
def get_bridge_device(self):
|
||||
return self.net.bridgeName()
|
||||
|
||||
def get_ip4_config(self):
|
||||
doc = self._get_xml_doc()
|
||||
try:
|
||||
addr = self._get_xml_path(doc, "/network/ip/@address")
|
||||
netmask = self._get_xml_path(doc, "/network/ip/@netmask")
|
||||
dhcpstart = self._get_xml_path(doc, "/network/ip/dhcp/range[1]/@start")
|
||||
dhcpend = self._get_xml_path(doc, "/network/ip/dhcp/range[1]/@end")
|
||||
forward = self._get_xml_path(doc, "string(count(/network/forward))")
|
||||
forwardDev = None
|
||||
if forward != None:
|
||||
forwardDev = self._get_xml_path(doc, "string(/network/forward/@dev)")
|
||||
|
||||
return [addr, netmask,dhcpstart,dhcpend,forwardDev]
|
||||
finally:
|
||||
doc.freeDoc()
|
||||
|
||||
def is_read_only(self):
|
||||
if self.connection.is_read_only():
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_xml_string(self, path):
|
||||
def _get_xml_doc(self):
|
||||
xml = self.net.XMLDesc(0)
|
||||
doc = None
|
||||
try:
|
||||
doc = libxml2.parseDoc(xml)
|
||||
except:
|
||||
return None
|
||||
return doc
|
||||
|
||||
def _get_xml_path(self, doc, path):
|
||||
ctx = doc.xpathNewContext()
|
||||
try:
|
||||
ret = ctx.xpathEval(path)
|
||||
tty = None
|
||||
if len(ret) == 1:
|
||||
tty = ret[0].content
|
||||
str = None
|
||||
if ret != None:
|
||||
if type(ret) == list:
|
||||
if len(ret) == 1:
|
||||
str = ret[0].content
|
||||
else:
|
||||
str = ret
|
||||
ctx.xpathFreeContext()
|
||||
doc.freeDoc()
|
||||
return tty
|
||||
return str
|
||||
except:
|
||||
ctx.xpathFreeContext()
|
||||
doc.freeDoc()
|
||||
return None
|
||||
|
||||
gobject.type_register(vmmNetwork)
|
||||
|
1509
src/vmm-host.glade
Normal file
1509
src/vmm-host.glade
Normal file
File diff suppressed because it is too large
Load Diff
@ -52,7 +52,7 @@
|
||||
<accelerator key="n" modifiers="GDK_MOD1_MASK" signal="activate"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image102">
|
||||
<widget class="GtkImage" id="image106">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
<property name="icon_size">1</property>
|
||||
@ -75,7 +75,7 @@
|
||||
<accelerator key="r" modifiers="GDK_MOD1_MASK" signal="activate"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image103">
|
||||
<widget class="GtkImage" id="image107">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-open</property>
|
||||
<property name="icon_size">1</property>
|
||||
@ -102,7 +102,7 @@
|
||||
<signal name="activate" handler="on_menu_file_open_connection_activate" last_modification_time="Mon, 12 Jun 2006 20:34:47 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image104">
|
||||
<widget class="GtkImage" id="image108">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-connect</property>
|
||||
<property name="icon_size">1</property>
|
||||
@ -152,6 +152,15 @@
|
||||
<child>
|
||||
<widget class="GtkMenu" id="menuitem5_menu">
|
||||
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="menu_host_details">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Host details...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_menu_host_details_activate" last_modification_time="Tue, 27 Mar 2007 21:31:10 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="menu_edit_details">
|
||||
<property name="visible">True</property>
|
||||
@ -160,7 +169,7 @@
|
||||
<signal name="activate" handler="on_menu_edit_details_activate" last_modification_time="Tue, 28 Mar 2006 17:06:34 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image105">
|
||||
<widget class="GtkImage" id="image109">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
<property name="icon_size">1</property>
|
||||
@ -181,7 +190,7 @@
|
||||
<signal name="activate" handler="on_menu_edit_delete_activate" last_modification_time="Tue, 28 Mar 2006 17:06:34 GMT"/>
|
||||
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="image106">
|
||||
<widget class="GtkImage" id="image110">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-delete</property>
|
||||
<property name="icon_size">1</property>
|
||||
|
Loading…
Reference in New Issue
Block a user