Merge NetdevHelper and OpticalHelper into new class HalHelper

Provides all the signals we need from the previous two classes.
This commit is contained in:
Cole Robinson 2009-11-30 16:25:39 -05:00
parent 18d331a241
commit 837ed55501
7 changed files with 203 additions and 259 deletions

View File

@ -24,15 +24,14 @@ src/virtManager/domain.py
src/virtManager/engine.py
src/virtManager/error.py
src/virtManager/graphwidgets.py
src/virtManager/halhelper.py
src/virtManager/host.py
src/virtManager/keyring.py
src/virtManager/manager.py
src/virtManager/mediadev.py
src/virtManager/migrate.py
src/virtManager/netdev.py
src/virtManager/netdevhelper.py
src/virtManager/network.py
src/virtManager/opticalhelper.py
src/virtManager/preferences.py
src/virtManager/remote.py
src/virtManager/secret.py

View File

@ -93,7 +93,7 @@ class vmmChooseCD(gobject.GObject):
idx = cd.get_active()
model = cd.get_model()
if idx != -1:
path = model[idx][uihelpers.OPTICAL_PATH]
path = model[idx][uihelpers.OPTICAL_DEV_PATH]
if path == "" or path == None:
return self.err.val_err(_("Invalid Media Path"),

View File

@ -91,7 +91,7 @@ class vmmConnection(gobject.GObject):
STATE_ACTIVE = 2
STATE_INACTIVE = 3
def __init__(self, config, uri, readOnly=None, netdev_helper=None):
def __init__(self, config, uri, readOnly=None, hal_helper=None):
self.__gobject_init__()
self.config = config
@ -132,8 +132,9 @@ class vmmConnection(gobject.GObject):
self.record = []
self.hostinfo = None
self.hal_helper = hal_helper
self.netdev_initialized = False
self.netdev_helper = netdev_helper
self.netdev_error = ""
self.netdev_use_libvirt = False
@ -146,25 +147,25 @@ class vmmConnection(gobject.GObject):
"""
Determine how we will be polling for net devices (HAL or libvirt)
"""
if self.is_nodedev_capable() and self.interface_capable:
if self.is_nodedev_capable() and self.interface_capable and False:
try:
self._build_libvirt_netdev_list()
self.netdev_use_libvirt = True
except Exception, e:
self.netdev_error = _("Could build physical interface "
"list via libvirt: %s") % str(e)
elif self.netdev_helper:
elif self.hal_helper:
if self.is_remote():
self.netdev_error = _("Libvirt version does not support "
"physical interface listing")
else:
error = self.netdev_helper.get_init_error()
error = self.hal_helper.get_init_error()
if not error:
self.netdev_helper.connect("netdev-added",
self._netdev_added)
self.netdev_helper.connect("netdev-removed",
self._netdev_removed)
self.hal_helper.connect("netdev-added",
self._netdev_added)
self.hal_helper.connect("device-removed",
self._haldev_removed)
else:
self.netdev_error = _("Could not initialize HAL for "
"interface listing: %s") % error
@ -597,8 +598,9 @@ class vmmConnection(gobject.GObject):
name = netdev.get_name()
self.netdevs[name] = netdev
def _netdev_removed(self, ignore, name):
del self.netdevs[name]
def _haldev_removed(self, ignore, name):
if self.netdevs.has_key(name):
del self.netdevs[name]
######################################

View File

@ -29,7 +29,7 @@ import libvirt
import virtinst
from virtManager.about import vmmAbout
from virtManager.netdevhelper import vmmNetDevHelper
from virtManager.halhelper import vmmHalHelper
from virtManager.clone import vmmCloneVM
from virtManager.connect import vmmConnect
from virtManager.connection import vmmConnection
@ -86,7 +86,7 @@ class vmmEngine(gobject.GObject):
# keep running in system tray if enabled
self.windows = 0
self.netdevHelper = vmmNetDevHelper(self.config)
self.halHelper = vmmHalHelper()
self.init_systray()
self.config.on_stats_update_interval_changed(self.reschedule_timer)
@ -440,7 +440,7 @@ class vmmEngine(gobject.GObject):
def add_connection(self, uri, readOnly=None, autoconnect=False):
conn = vmmConnection(self.get_config(), uri, readOnly,
self.netdevHelper)
self.halHelper)
self.connections[uri] = {
"connection": conn,
"windowHost": None,

View File

@ -27,19 +27,23 @@ import gobject
import dbus
from virtManager.netdev import vmmNetDevice
from virtManager.mediadev import vmmMediaDevice
class vmmNetDevHelper(gobject.GObject):
class vmmHalHelper(gobject.GObject):
__gsignals__ = {
"netdev-added": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[object]),
"netdev-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
"optical-added" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[object]),
"optical-media-added" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[object]),
"device-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[str]),
}
def __init__(self, config):
def __init__(self):
self.__gobject_init__()
self.config = config
self.bus = None
self.hal_iface = None
@ -50,6 +54,8 @@ class vmmNetDevHelper(gobject.GObject):
self.netdevs = {}
# Mapping of hal IDs to net names
self.hal_to_netdev = {}
# Mapping of HAL path -> vmmMediaDevice
self.optical_info = {}
self._dbus_connect()
@ -67,26 +73,15 @@ class vmmNetDevHelper(gobject.GObject):
self.hal_iface = dbus.Interface(hal_object,
'org.freedesktop.Hal.Manager')
self.populate_opt_media()
self.populate_netdevs()
# Track device add/removes so we can detect newly inserted CD media
self.hal_iface.connect_to_signal("DeviceAdded",
self._net_phys_device_added)
self._device_added)
self.hal_iface.connect_to_signal("DeviceRemoved",
self._net_phys_device_removed)
self._device_removed)
bondMasters = get_bonding_masters()
logging.debug("Bonding masters are: %s" % bondMasters)
for bond in bondMasters:
sysfspath = "/sys/class/net/" + bond
mac = get_net_mac_address(bond, sysfspath)
if mac:
self._net_device_added(bond, mac, sysfspath)
# Add any associated VLANs
self._net_tag_device_added(bond, sysfspath)
# Find info about all current present physical net devices
# This is OS portable...
for path in self.hal_iface.FindDeviceByCapability("net"):
self._net_phys_device_added(path)
except Exception, e:
(_type, value, stacktrace) = sys.exc_info ()
logging.error("Unable to connect to HAL to list network "
@ -95,64 +90,155 @@ class vmmNetDevHelper(gobject.GObject):
traceback.format_exc (stacktrace))
self.startup_error = str(e)
def connect(self, name, callback):
# Override connect, so when a new caller attaches to netdev-added,
# they get the full list of current devices
handle_id = gobject.GObject.connect(self, name, callback)
def connect(self, name, callback, *args):
handle_id = gobject.GObject.connect(self, name, callback, *args)
if name == "netdev-added":
for dev in self.netdevs.values():
self.emit("netdev-added", dev)
elif name == "optical-added":
for dev in self.optical_info.values():
self.emit("optical-added", dev)
return handle_id
#############################
# Device population methods #
#############################
##################
# Helper methods #
##################
def _net_phys_device_added(self, path):
obj = self.bus.get_object("org.freedesktop.Hal", path)
def dbus_dev_lookup(self, halpath):
obj = self.bus.get_object("org.freedesktop.Hal", halpath)
objif = dbus.Interface(obj, "org.freedesktop.Hal.Device")
return objif
if objif.QueryCapability("net"):
name = objif.GetPropertyString("net.interface")
# HAL gives back paths to like:
# /sys/devices/pci0000:00/0000:00:1e.0/0000:01:00.0/net/eth0
# which doesn't work so well - we want this:
sysfspath = "/sys/class/net/" + name
def is_cdrom_media(self, halpath):
obj = self.dbus_dev_lookup(halpath)
return bool(obj.QueryCapability("volume") and
obj.GetPropertyBoolean("volume.is_disc") and
obj.GetPropertyBoolean("volume.disc.has_data"))
# If running a device in bridged mode, there's a reasonable
# chance that the actual ethernet device has been renamed to
# something else. ethN -> pethN
psysfspath = sysfspath[0:len(sysfspath)-len(name)] + "p" + name
if os.path.exists(psysfspath):
logging.debug("Device %s named to p%s" % (name, name))
name = "p" + name
sysfspath = psysfspath
def is_cdrom(self, halpath):
obj = self.dbus_dev_lookup(halpath)
return bool(obj.QueryCapability("storage.cdrom"))
# Ignore devices that are slaves of a bond
if is_net_bonding_slave(name, sysfspath):
logging.debug("Skipping device %s in bonding slave" % name)
return
def is_netdev(self, halpath):
obj = self.dbus_dev_lookup(halpath)
return bool(obj.QueryCapability("net"))
mac = objif.GetPropertyString("net.address")
# Add the main NIC
self._net_device_added(name, mac, sysfspath, path)
#############################
# Initial device population #
#############################
# Add any associated VLANs
self._net_tag_device_added(name, sysfspath)
def populate_opt_media(self):
for path in self.hal_iface.FindDeviceByCapability("storage.cdrom"):
# Make sure we only populate CDROM devs
if not self.is_cdrom(path):
continue
def _net_phys_device_removed(self, path):
devnode, media_label, media_hal_path = self._fetch_cdrom_info(path)
obj = vmmMediaDevice(str(devnode), str(path), media_label,
media_hal_path)
self.optical_info[str(devnode)] = obj
def populate_netdevs(self):
bondMasters = get_bonding_masters()
logging.debug("Bonding masters are: %s" % bondMasters)
for bond in bondMasters:
sysfspath = "/sys/class/net/" + bond
mac = get_net_mac_address(bond, sysfspath)
if mac:
self._net_device_added(bond, mac, sysfspath)
# Add any associated VLANs
self._net_tag_device_added(bond, sysfspath)
# Find info about all current present physical net devices
for path in self.hal_iface.FindDeviceByCapability("net"):
self._net_phys_device_added(path)
#############################
# Device callback listeners #
#############################
def _device_added(self, path):
if self.is_cdrom_media(path):
self._optical_media_added(path)
elif self.is_cdrom(path):
self._optical_added(path)
elif self.is_netdev(path):
self._net_phys_device_added(path)
def _device_removed(self, path):
if self.hal_to_netdev.has_key(path):
name = self.hal_to_netdev[path]
logging.debug("Removing physical net device %s from list." % name)
dev = self.netdevs[name]
self.emit("netdev-removed", dev.get_name())
del self.netdevs[name]
del self.hal_to_netdev[path]
return
# Update optical info
for dev, obj in self.optical_info.items():
if obj.get_key() == path:
del(self.optical_info[dev])
elif obj.get_media_key() == path:
obj.clear_media()
self.emit("device-removed", str(path))
def _optical_added(self, halpath):
devpath, media_label, media_hal_path = self._fetch_cdrom_info(halpath)
obj = vmmMediaDevice(devpath, halpath, media_label, media_hal_path)
self.optical_info[devpath] = obj
self.emit("optical-added", obj)
def _optical_media_added(self, halpath):
media_hal_path = halpath
media_label, devpath = self._fetch_media_info(halpath)
obj = vmmMediaDevice(devpath, halpath, media_label, media_hal_path)
self.optical_info[devpath] = obj
self.emit("optical-media-added", obj)
def _net_phys_device_added(self, halpath):
dbusobj = self.dbus_dev_lookup(halpath)
name = dbusobj.GetPropertyString("net.interface")
mac = dbusobj.GetPropertyString("net.address")
# HAL gives back paths to like:
# /sys/devices/pci0000:00/0000:00:1e.0/0000:01:00.0/net/eth0
# which doesn't work so well - we want this:
sysfspath = "/sys/class/net/" + name
# If running a device in bridged mode, there's a reasonable
# chance that the actual ethernet device has been renamed to
# something else. ethN -> pethN
psysfspath = sysfspath[0:len(sysfspath)-len(name)] + "p" + name
if os.path.exists(psysfspath):
logging.debug("Device %s named to p%s" % (name, name))
name = "p" + name
sysfspath = psysfspath
# Ignore devices that are slaves of a bond
if is_net_bonding_slave(name, sysfspath):
logging.debug("Skipping device %s in bonding slave" % name)
return
# Add the main NIC
self._net_device_added(name, mac, sysfspath, halpath)
# Add any associated VLANs
self._net_tag_device_added(name, sysfspath)
def _net_tag_device_added(self, name, sysfspath):
for vlanpath in glob.glob(sysfspath + ".*"):
@ -197,7 +283,49 @@ class vmmNetDevHelper(gobject.GObject):
self.netdevs[name] = dev
self.emit("netdev-added", dev)
gobject.type_register(vmmNetDevHelper)
######################
# CDROM info methods #
######################
def _fetch_media_info(self, halpath):
label = None
devnode = None
volif = self.dbus_dev_lookup(halpath)
devnode = volif.GetProperty("block.device")
label = volif.GetProperty("volume.label")
if not label:
label = devnode
return (label and str(label), devnode and str(devnode))
def _fetch_cdrom_info(self, halpath):
devif = self.dbus_dev_lookup(halpath)
devnode = devif.GetProperty("block.device")
media_label = None
media_hal_path = None
if devnode:
media_label, media_hal_path = self._find_media_for_devpath(devnode)
return (devnode and str(devnode), media_label, media_hal_path)
def _find_media_for_devpath(self, devpath):
for path in self.hal_iface.FindDeviceByCapability("volume"):
if not self.is_cdrom_media(path):
continue
label, devnode = self._fetch_media_info(path)
if devnode == devpath:
return (label, path)
return None, None
gobject.type_register(vmmHalHelper)
def get_net_bridge_owner(name, sysfspath):

View File

@ -1,167 +0,0 @@
#
# Copyright (C) 2007 Red Hat, Inc.
#
# 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., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
import gobject
import dbus
import logging
from virtManager.mediadev import vmmMediaDevice
class vmmOpticalDriveHelper(gobject.GObject):
__gsignals__ = {
"optical-added" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[object]),
"optical-media-added" : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[object]),
"device-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
[str]),
}
def __init__(self):
self.__gobject_init__()
self.bus = None
self.hal_iface = None
# Mapping of HAL path -> vmmMediaDevice
self.device_info = {}
self._dbus_connect()
self.populate_opt_media()
def _dbus_connect(self):
try:
self.bus = dbus.SystemBus()
hal_object = self.bus.get_object('org.freedesktop.Hal',
'/org/freedesktop/Hal/Manager')
self.hal_iface = dbus.Interface(hal_object,
'org.freedesktop.Hal.Manager')
except Exception, e:
logging.error("Unable to connect to HAL to list cdrom "
"volumes: '%s'", e)
raise
# Track device add/removes so we can detect newly inserted CD media
self.hal_iface.connect_to_signal("DeviceAdded", self._device_added)
self.hal_iface.connect_to_signal("DeviceRemoved", self._device_removed)
def connect(self, name, callback, *args):
# Override connect, so when a new caller attaches to optical-added,
# they get the full list of current devices
handle_id = gobject.GObject.connect(self, name, callback, *args)
if name == "optical-added":
for dev in self.device_info.values():
self.emit("optical-added", dev)
return handle_id
def populate_opt_media(self):
volinfo = {}
for path in self.hal_iface.FindDeviceByCapability("storage.cdrom"):
# Make sure we only populate CDROM devs
if not self.is_cdrom(path):
continue
devnode, media_label, media_hal_path = self._fetch_cdrom_info(path)
obj = vmmMediaDevice(str(devnode), str(path), media_label,
media_hal_path)
self.device_info[str(devnode)] = obj
def _device_added(self, path):
media_label = None
media_hal_path = None
devpath = None
signal = None
if self.is_cdrom_media(path):
media_hal_path = path
media_label, devpath = self._fetch_media_info(path)
signal = "optical-media-added"
elif self.is_cdrom(path):
devpath, media_label, media_hal_path = self._fetch_cdrom_info(path)
signal = "optical-added"
else:
# Not a relevant device
return
obj = vmmMediaDevice(devpath, path, media_label, media_hal_path)
self.device_info[devpath] = obj
self.emit(signal, obj)
def _device_removed(self, path):
self.emit("device-removed", str(path))
def dbus_dev_lookup(self, halpath):
obj = self.bus.get_object("org.freedesktop.Hal", halpath)
objif = dbus.Interface(obj, "org.freedesktop.Hal.Device")
return objif
def is_cdrom_media(self, halpath):
obj = self.dbus_dev_lookup(halpath)
return bool(obj.QueryCapability("volume") and
obj.GetPropertyBoolean("volume.is_disc") and
obj.GetPropertyBoolean("volume.disc.has_data"))
def is_cdrom(self, halpath):
obj = self.dbus_dev_lookup(halpath)
return bool(obj.QueryCapability("storage.cdrom"))
def _fetch_media_info(self, halpath):
label = None
devnode = None
volif = self.dbus_dev_lookup(halpath)
devnode = volif.GetProperty("block.device")
label = volif.GetProperty("volume.label")
if not label:
label = devnode
return (label and str(label), devnode and str(devnode))
def _fetch_cdrom_info(self, halpath):
devif = self.dbus_dev_lookup(halpath)
devnode = devif.GetProperty("block.device")
media_label = None
media_hal_path = None
if devnode:
media_label, media_hal_path = self._find_media_for_devpath(devnode)
return (devnode and str(devnode), media_label, media_hal_path)
def _find_media_for_devpath(self, devpath):
for path in self.hal_iface.FindDeviceByCapability("volume"):
if not self.is_cdrom_media(path):
continue
label, devnode = self._fetch_media_info(path)
if devnode == devpath:
return (label, path)
return None, None
gobject.type_register(vmmOpticalDriveHelper)

View File

@ -25,7 +25,7 @@ import gtk
from virtinst import VirtualNetworkInterface
from virtManager.opticalhelper import vmmOpticalDriveHelper
from virtManager.halhelper import vmmHalHelper
from virtManager.error import vmmErrorDialog
OPTICAL_DEV_PATH = 0
@ -264,7 +264,7 @@ def init_optical_combo(widget, empty_sensitive=False):
if not empty_sensitive:
widget.add_attribute(text, 'sensitive', 2)
helper = vmmOpticalDriveHelper()
helper = vmmHalHelper()
helper.connect("optical-added", optical_added, widget)
helper.connect("optical-media-added", optical_media_added, widget)
helper.connect("device-removed", optical_removed, widget)
@ -304,26 +304,8 @@ def optical_removed(ignore_helper, key, widget):
optical_set_default_selection(widget)
def remove_row_from_model(widget, rmrow):
active = widget.get_active()
model = widget.get_model()
newmodel = []
for row in model:
if row != rmrow:
newmodel.append(row)
model.clear()
for row in newmodel:
print row
model.append(row)
widget.set_active(-1)
def optical_added(ignore_helper, newobj, widget):
model = widget.get_model()
active = widget.get_active()
idx = 0
# Brand new device
row = [None, None, None, None, None, newobj]