Fix cdrom installs where the iso is a storage volume (bz 524109) Fix path
permissions for kernel/initrd download location (bz 523960)
This commit is contained in:
parent
2fb1649c38
commit
a8a375285f
349
virt-manager-0.8.0-fix-path-perms.patch
Normal file
349
virt-manager-0.8.0-fix-path-perms.patch
Normal file
@ -0,0 +1,349 @@
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253738576 14400
|
||||
# Node ID e7ee75a8f1353f2c42df93b5090b05fbdf89720a
|
||||
# Parent 292a065aad7e4e5e5d50a71337efab2361378313
|
||||
Add dialog-with-checkbox helper functions.
|
||||
|
||||
Useful for things like "Don't show this again'.
|
||||
|
||||
diff -r 292a065aad7e -r e7ee75a8f135 src/virtManager/error.py
|
||||
--- a/src/virtManager/error.py Wed Sep 23 11:49:35 2009 -0400
|
||||
+++ b/src/virtManager/error.py Wed Sep 23 16:42:56 2009 -0400
|
||||
@@ -131,3 +131,61 @@
|
||||
def ok_cancel(self, text1, text2=None):
|
||||
return self._show_warning(gtk.BUTTONS_OK_CANCEL, text1, text2)
|
||||
|
||||
+ def warn_chkbox(self, text1, text2=None, chktext=None):
|
||||
+ chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_WARNING)
|
||||
+ return chkbox.show_chkbox(text1, text2, chktext)
|
||||
+
|
||||
+ def err_chkbox(self, text1, text2=None, chktext=None):
|
||||
+ chkbox = vmmCheckDialog(self.parent, gtk.MESSAGE_ERROR)
|
||||
+ return chkbox.show_chkbox(text1, text2, chktext)
|
||||
+
|
||||
+class vmmCheckDialog (gtk.MessageDialog):
|
||||
+ def __init__ (self, parent=None, typ=gtk.MESSAGE_INFO):
|
||||
+ if typ == gtk.MESSAGE_WARNING:
|
||||
+ buttons = gtk.BUTTONS_OK_CANCEL
|
||||
+ else:
|
||||
+ buttons = gtk.BUTTONS_OK
|
||||
+
|
||||
+ gtk.MessageDialog.__init__ (self, parent, 0, typ, buttons)
|
||||
+
|
||||
+ self.connect("response", self.response_cb)
|
||||
+ self.connect("delete-event", self.hide_on_delete)
|
||||
+ self.set_title("")
|
||||
+
|
||||
+ self.chk_vbox = gtk.VBox(False, False)
|
||||
+ self.chk_vbox.set_spacing(0)
|
||||
+
|
||||
+ self.chk_align = gtk.Alignment()
|
||||
+ self.chk_align.set_padding(0, 0, 62, 0)
|
||||
+ self.chk_align.add(self.chk_vbox)
|
||||
+
|
||||
+ self.chk_align.show_all()
|
||||
+ self.vbox.pack_start(self.chk_align)
|
||||
+
|
||||
+ def response_cb(self, src, ignore):
|
||||
+ src.hide()
|
||||
+
|
||||
+ def show_chkbox(self, text1, text2=None, chktext=None):
|
||||
+ chkbox = None
|
||||
+ res = None
|
||||
+ chkres = None
|
||||
+
|
||||
+ self.hide()
|
||||
+ for c in self.chk_vbox.get_children():
|
||||
+ self.chk_vbox.remove(c)
|
||||
+
|
||||
+ self.set_property("text", text1)
|
||||
+
|
||||
+ if text2:
|
||||
+ self.format_secondary_text(text2)
|
||||
+
|
||||
+ if chktext:
|
||||
+ chkbox = gtk.CheckButton(chktext)
|
||||
+ self.chk_vbox.add(chkbox)
|
||||
+ chkbox.show()
|
||||
+
|
||||
+ res = self.run() in [ gtk.RESPONSE_YES, gtk.RESPONSE_OK ]
|
||||
+ if chktext:
|
||||
+ res = [res, chkbox.get_active()]
|
||||
+
|
||||
+ return res
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253738620 14400
|
||||
# Node ID f5f3ff4f8942d631234f8e008d806bd502c58bc3
|
||||
# Parent e7ee75a8f1353f2c42df93b5090b05fbdf89720a
|
||||
connection: Add is_qemu_system helper.
|
||||
|
||||
diff -r e7ee75a8f135 -r f5f3ff4f8942 src/virtManager/connection.py
|
||||
--- a/src/virtManager/connection.py Wed Sep 23 16:42:56 2009 -0400
|
||||
+++ b/src/virtManager/connection.py Wed Sep 23 16:43:40 2009 -0400
|
||||
@@ -201,6 +201,13 @@
|
||||
def is_nodedev_capable(self):
|
||||
return virtinst.NodeDeviceParser.is_nodedev_capable(self.vmm)
|
||||
|
||||
+ def is_qemu_system(self):
|
||||
+ (scheme, ignore, ignore,
|
||||
+ path, ignore, ignore) = virtinst.util.uri_split(self.uri)
|
||||
+ if path == "/system" and scheme.startswith("qemu"):
|
||||
+ return True
|
||||
+ return False
|
||||
+
|
||||
def is_qemu_session(self):
|
||||
(scheme, ignore, ignore,
|
||||
path, ignore, ignore) = virtinst.util.uri_split(self.uri)
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253806909 14400
|
||||
# Node ID cfcd19d057ddc973a129e7816cd4ea39f0d4365a
|
||||
# Parent f5f3ff4f8942d631234f8e008d806bd502c58bc3
|
||||
create: Don't prompt with same dialog multiple times.
|
||||
|
||||
diff -r f5f3ff4f8942 -r cfcd19d057dd src/virtManager/create.py
|
||||
--- a/src/virtManager/create.py Wed Sep 23 16:43:40 2009 -0400
|
||||
+++ b/src/virtManager/create.py Thu Sep 24 11:41:49 2009 -0400
|
||||
@@ -1122,7 +1122,7 @@
|
||||
if pagenum == PAGE_NAME:
|
||||
return self.validate_name_page()
|
||||
elif pagenum == PAGE_INSTALL:
|
||||
- return self.validate_install_page()
|
||||
+ return self.validate_install_page(revalidate=False)
|
||||
elif pagenum == PAGE_MEM:
|
||||
return self.validate_mem_page()
|
||||
elif pagenum == PAGE_STORAGE:
|
||||
@@ -1135,7 +1135,7 @@
|
||||
return False
|
||||
elif not self.validate_mem_page():
|
||||
return False
|
||||
- return self.validate_storage_page()
|
||||
+ return self.validate_storage_page(revalidate=False)
|
||||
|
||||
elif pagenum == PAGE_FINISH:
|
||||
# Since we allow the user to change to change HV type + arch
|
||||
@@ -1169,7 +1169,7 @@
|
||||
|
||||
return True
|
||||
|
||||
- def validate_install_page(self):
|
||||
+ def validate_install_page(self, revalidate=True):
|
||||
instmethod = self.get_config_install_page()
|
||||
installer = None
|
||||
location = None
|
||||
@@ -1270,7 +1270,7 @@
|
||||
|
||||
return True
|
||||
|
||||
- def validate_storage_page(self):
|
||||
+ def validate_storage_page(self, revalidate=True):
|
||||
use_storage = self.window.get_widget("enable-storage").get_active()
|
||||
|
||||
self.guest.disks = []
|
||||
@@ -1296,19 +1296,21 @@
|
||||
return self.verr(_("Storage parameter error."), str(e))
|
||||
|
||||
isfatal, errmsg = disk.is_size_conflict()
|
||||
- if not isfatal and errmsg:
|
||||
+ if not revalidate and not isfatal and errmsg:
|
||||
# Fatal errors are reported when setting 'size'
|
||||
res = self.err.ok_cancel(_("Not Enough Free Space"), errmsg)
|
||||
if not res:
|
||||
return False
|
||||
|
||||
# Disk collision
|
||||
- if disk.is_conflict_disk(self.guest.conn):
|
||||
- return self.err.yes_no(_('Disk "%s" is already in use by another '
|
||||
- 'guest!' % disk.path),
|
||||
- _("Do you really want to use the disk?"))
|
||||
- else:
|
||||
- return True
|
||||
+ if not revalidate and disk.is_conflict_disk(self.guest.conn):
|
||||
+ res = self.err.yes_no(_('Disk "%s" is already in use by another '
|
||||
+ 'guest!' % disk.path),
|
||||
+ _("Do you really want to use the disk?"))
|
||||
+ if not res:
|
||||
+ return False
|
||||
+
|
||||
+ return True
|
||||
|
||||
def validate_final_page(self):
|
||||
nettype, devname, macaddr = self.get_config_network_info()
|
||||
diff -r 343b42ebee5b src/virtManager/addhardware.py
|
||||
--- a/src/virtManager/addhardware.py Thu Sep 24 11:41:49 2009 -0400
|
||||
+++ b/src/virtManager/addhardware.py Thu Sep 24 11:44:49 2009 -0400
|
||||
@@ -31,6 +31,7 @@
|
||||
import virtinst
|
||||
from virtinst import VirtualCharDevice, VirtualDevice, VirtualVideoDevice
|
||||
|
||||
+import virtManager.create
|
||||
import virtManager.util as vmmutil
|
||||
from virtManager.asyncjob import vmmAsyncJob
|
||||
from virtManager.error import vmmErrorDialog
|
||||
@@ -1054,6 +1055,7 @@
|
||||
return self.err.val_err(_("Hardware Type Required"), \
|
||||
_("You must specify what type of hardware to add."))
|
||||
self._dev = None
|
||||
+
|
||||
elif page_num == PAGE_DISK:
|
||||
path = self.get_config_disk_image()
|
||||
if path == None or len(path) == 0:
|
||||
@@ -1102,6 +1104,11 @@
|
||||
_("Do you really want to use the disk?"))
|
||||
return res
|
||||
|
||||
+ # Make sure qemu can access path
|
||||
+ virtManager.create.check_path_search_for_qemu(self,
|
||||
+ self.vm.connection,
|
||||
+ self._dev.path)
|
||||
+
|
||||
elif page_num == PAGE_NETWORK:
|
||||
net = self.get_config_network()
|
||||
if self.window.get_widget("net-type-network").get_active():
|
||||
diff -r 343b42ebee5b src/virtManager/choosecd.py
|
||||
--- a/src/virtManager/choosecd.py Thu Sep 24 11:41:49 2009 -0400
|
||||
+++ b/src/virtManager/choosecd.py Thu Sep 24 11:44:49 2009 -0400
|
||||
@@ -24,6 +24,7 @@
|
||||
import virtinst
|
||||
|
||||
import virtManager.opticalhelper
|
||||
+import virtManager.create
|
||||
from virtManager.storagebrowse import vmmStorageBrowser
|
||||
from virtManager.error import vmmErrorDialog
|
||||
|
||||
@@ -108,6 +109,10 @@
|
||||
except Exception, e:
|
||||
return self.err.val_err(_("Invalid Media Path"), str(e))
|
||||
|
||||
+ # Make sure qemu can access the path
|
||||
+ virtManager.create.check_path_search_for_qemu(self, self.conn,
|
||||
+ disk.path)
|
||||
+
|
||||
self.emit("cdrom-chosen", disk.type, disk.path, self.dev_id_info)
|
||||
self.cancel()
|
||||
|
||||
diff -r 343b42ebee5b src/virtManager/config.py
|
||||
--- a/src/virtManager/config.py Thu Sep 24 11:41:49 2009 -0400
|
||||
+++ b/src/virtManager/config.py Thu Sep 24 11:44:49 2009 -0400
|
||||
@@ -558,3 +558,15 @@
|
||||
else:
|
||||
return os.getcwd()
|
||||
|
||||
+ def add_perms_fix_ignore(self, pathlist):
|
||||
+ current_list = self.get_perms_fix_ignore() or []
|
||||
+ for path in pathlist:
|
||||
+ if path in current_list:
|
||||
+ continue
|
||||
+ current_list.append(path)
|
||||
+ self.conf.set_list(self.conf_dir + "/paths/perms_fix_ignore",
|
||||
+ gconf.VALUE_STRING,
|
||||
+ current_list)
|
||||
+ def get_perms_fix_ignore(self):
|
||||
+ return self.conf.get_list(self.conf_dir + "/paths/perms_fix_ignore",
|
||||
+ gconf.VALUE_STRING)
|
||||
diff -r 343b42ebee5b src/virtManager/create.py
|
||||
--- a/src/virtManager/create.py Thu Sep 24 11:41:49 2009 -0400
|
||||
+++ b/src/virtManager/create.py Thu Sep 24 11:44:49 2009 -0400
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
import virtinst
|
||||
from virtinst import VirtualNetworkInterface
|
||||
+from virtinst import VirtualDisk
|
||||
|
||||
import virtManager.opticalhelper
|
||||
from virtManager import util
|
||||
@@ -53,6 +54,54 @@
|
||||
INSTALL_PAGE_URL = 1
|
||||
INSTALL_PAGE_PXE = 2
|
||||
|
||||
+def check_path_search_for_qemu(vmm_obj, conn, path):
|
||||
+ if conn.is_remote() or not conn.is_qemu_system():
|
||||
+ return
|
||||
+
|
||||
+ user = "qemu"
|
||||
+
|
||||
+ skip_paths = vmm_obj.config.get_perms_fix_ignore()
|
||||
+ broken_paths = VirtualDisk.check_path_search_for_user(conn.vmm, path, user)
|
||||
+ for p in broken_paths:
|
||||
+ if p in skip_paths:
|
||||
+ broken_paths.remove(p)
|
||||
+
|
||||
+ if not broken_paths:
|
||||
+ return
|
||||
+
|
||||
+ logging.debug("No search access for dirs: %s" % broken_paths)
|
||||
+ resp, chkres = vmm_obj.err.warn_chkbox(
|
||||
+ _("The emulator may not have search permissions "
|
||||
+ "for the path '%s'.") % path,
|
||||
+ _("Do you want to correct this now?"),
|
||||
+ _("Don't ask about these directories again."))
|
||||
+
|
||||
+ if chkres:
|
||||
+ vmm_obj.config.add_perms_fix_ignore(broken_paths)
|
||||
+ if not resp:
|
||||
+ return
|
||||
+
|
||||
+ logging.debug("Attempting to correct permission issues.")
|
||||
+ errors = VirtualDisk.fix_path_search_for_user(conn.vmm, path, user)
|
||||
+ if not errors:
|
||||
+ return
|
||||
+
|
||||
+ errmsg = _("Errors were encountered changing permissions for the "
|
||||
+ "following directories:")
|
||||
+ details = ""
|
||||
+ for path, error in errors.items():
|
||||
+ if path not in broken_paths:
|
||||
+ continue
|
||||
+ details += "%s : %s\n" % (path, error)
|
||||
+
|
||||
+ logging.debug("Permission errors:\n%s" % details)
|
||||
+
|
||||
+ ignore, chkres = vmm_obj.err.err_chkbox(errmsg, details,
|
||||
+ _("Don't ask about these directories again."))
|
||||
+
|
||||
+ if chkres:
|
||||
+ vmm_obj.config.add_perms_fix_ignore(errors.keys())
|
||||
+
|
||||
class vmmCreate(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
"action-show-console": (gobject.SIGNAL_RUN_FIRST,
|
||||
@@ -1245,6 +1294,11 @@
|
||||
return self.err.val_err(_("Error setting OS information."),
|
||||
str(e))
|
||||
|
||||
+ if instmethod == INSTALL_PAGE_ISO and not revalidate:
|
||||
+ # Check if 'qemu' user can access disk
|
||||
+ check_path_search_for_qemu(self, self.conn,
|
||||
+ self.guest.installer.location)
|
||||
+
|
||||
# Validation passed, store the install path (if there is one) in
|
||||
# gconf
|
||||
self.get_config_local_media(store_media=True)
|
||||
@@ -1286,10 +1340,10 @@
|
||||
if not diskpath:
|
||||
return self.verr(_("A storage path must be specified."))
|
||||
|
||||
- disk = virtinst.VirtualDisk(conn = self.conn.vmm,
|
||||
- path = diskpath,
|
||||
- size = disksize,
|
||||
- sparse = sparse)
|
||||
+ disk = VirtualDisk(conn = self.conn.vmm,
|
||||
+ path = diskpath,
|
||||
+ size = disksize,
|
||||
+ sparse = sparse)
|
||||
|
||||
self.guest.disks.append(disk)
|
||||
except Exception, e:
|
||||
@@ -1310,6 +1364,10 @@
|
||||
if not res:
|
||||
return False
|
||||
|
||||
+ if not revalidate:
|
||||
+ # Check if 'qemu' user can access disk
|
||||
+ check_path_search_for_qemu(self, self.conn, disk.path)
|
||||
+
|
||||
return True
|
||||
|
||||
def validate_final_page(self):
|
96
virt-manager-0.8.0-refresh-disk-space.patch
Normal file
96
virt-manager-0.8.0-refresh-disk-space.patch
Normal file
@ -0,0 +1,96 @@
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253563791 14400
|
||||
# Node ID f75237b0a84e73552a55ef0121215633c4530879
|
||||
# Parent d3b377306a994f66cd1c03f3bcbef17c4b060720
|
||||
Use timer to refresh available disk space in 'New VM' wizard (bz 502777)
|
||||
|
||||
diff -r d3b377306a99 -r f75237b0a84e src/virtManager/create.py
|
||||
--- a/src/virtManager/create.py Thu Sep 17 13:45:53 2009 -0400
|
||||
+++ b/src/virtManager/create.py Mon Sep 21 16:09:51 2009 -0400
|
||||
@@ -93,6 +93,10 @@
|
||||
# 'Guest' class from the previous failed install
|
||||
self.failed_guest = None
|
||||
|
||||
+ # Host space polling
|
||||
+ self.host_storage_timer = None
|
||||
+ self.host_storage = None
|
||||
+
|
||||
self.window.signal_autoconnect({
|
||||
"on_vmm_newcreate_delete_event" : self.close,
|
||||
|
||||
@@ -136,8 +140,18 @@
|
||||
|
||||
def close(self, ignore1=None, ignore2=None):
|
||||
self.topwin.hide()
|
||||
+ self.remove_timers()
|
||||
+
|
||||
return 1
|
||||
|
||||
+ def remove_timers(self):
|
||||
+ try:
|
||||
+ if self.host_storage_timer:
|
||||
+ gobject.source_remote(self.host_storage_timer)
|
||||
+ self.host_storage_timer = None
|
||||
+ except:
|
||||
+ pass
|
||||
+
|
||||
def set_conn(self, newconn):
|
||||
if self.conn == newconn:
|
||||
return
|
||||
@@ -303,9 +317,11 @@
|
||||
self.window.get_widget("config-cpus").set_value(1)
|
||||
|
||||
# Storage
|
||||
+ if not self.host_storage_timer:
|
||||
+ self.host_storage_timer = gobject.timeout_add(3 * 1000,
|
||||
+ self.host_space_tick)
|
||||
self.window.get_widget("enable-storage").set_active(True)
|
||||
self.window.get_widget("config-storage-create").set_active(True)
|
||||
- # FIXME: Make sure this doesn't exceed host?
|
||||
self.window.get_widget("config-storage-size").set_value(8)
|
||||
self.window.get_widget("config-storage-entry").set_text("")
|
||||
self.window.get_widget("config-storage-nosparse").set_active(True)
|
||||
@@ -437,11 +453,6 @@
|
||||
# Storage
|
||||
have_storage = (is_local or is_storage_capable)
|
||||
storage_tooltip = None
|
||||
- max_storage = self.host_disk_space()
|
||||
- hd_label = "%s available on the host" % self.pretty_storage(max_storage)
|
||||
- hd_label = ("<span color='#484848'>%s</span>" % hd_label)
|
||||
- self.window.get_widget("phys-hd-label").set_markup(hd_label)
|
||||
- self.window.get_widget("config-storage-size").set_range(1, max_storage)
|
||||
|
||||
use_storage = self.window.get_widget("config-storage-select")
|
||||
storage_area = self.window.get_widget("config-storage-area")
|
||||
@@ -863,6 +874,7 @@
|
||||
# FIXME: use a conn specific function after we send pool-added
|
||||
pool = virtinst.util.lookup_pool_by_path(self.conn.vmm, path)
|
||||
if pool:
|
||||
+ pool.refresh(0)
|
||||
avail = int(virtinst.util.get_xml_path(pool.XMLDesc(0),
|
||||
"/pool/available"))
|
||||
|
||||
@@ -870,7 +882,21 @@
|
||||
vfs = os.statvfs(os.path.dirname(path))
|
||||
avail = vfs[statvfs.F_FRSIZE] * vfs[statvfs.F_BAVAIL]
|
||||
|
||||
- return int(avail / 1024.0 / 1024.0 / 1024.0)
|
||||
+ return float(avail / 1024.0 / 1024.0 / 1024.0)
|
||||
+
|
||||
+ def host_space_tick(self):
|
||||
+ max_storage = self.host_disk_space()
|
||||
+ if self.host_storage == max_storage:
|
||||
+ return 1
|
||||
+ self.host_storage = max_storage
|
||||
+
|
||||
+ hd_label = ("%s available in the default location" %
|
||||
+ self.pretty_storage(max_storage))
|
||||
+ hd_label = ("<span color='#484848'>%s</span>" % hd_label)
|
||||
+ self.window.get_widget("phys-hd-label").set_markup(hd_label)
|
||||
+ self.window.get_widget("config-storage-size").set_range(1, self.host_storage)
|
||||
+
|
||||
+ return 1
|
||||
|
||||
def get_config_network_info(self):
|
||||
netidx = self.window.get_widget("config-netdev").get_active()
|
@ -8,7 +8,7 @@
|
||||
|
||||
Name: virt-manager
|
||||
Version: 0.8.0
|
||||
Release: 4%{_extra_release}
|
||||
Release: 5%{_extra_release}
|
||||
Summary: Virtual Machine Manager
|
||||
|
||||
Group: Applications/Emulators
|
||||
@ -36,6 +36,10 @@ Patch6: %{name}-%{version}-conn-close-exception.patch
|
||||
Patch7: %{name}-%{version}-manager-ui-tweaks.patch
|
||||
# Generate better errors is disk/net stats polling fails
|
||||
Patch8: %{name}-%{version}-stats-logging.patch
|
||||
# Refresh host disk space in create wizard (bz 502777)
|
||||
Patch9: %{name}-%{version}-refresh-disk-space.patch
|
||||
# Offer to fix disk permission issues (bz 517379)
|
||||
Patch10: %{name}-%{version}-fix-path-perms.patch
|
||||
|
||||
# These two are just the oldest version tested
|
||||
Requires: pygtk2 >= 1.99.12-6
|
||||
@ -61,7 +65,7 @@ Requires: gnome-python2-gnome
|
||||
# Minimum we've tested with
|
||||
Requires: libxml2-python >= 2.6.23
|
||||
# Required to install Xen & QEMU guests
|
||||
Requires: python-virtinst >= 0.500.0
|
||||
Requires: python-virtinst >= 0.500.0-4
|
||||
# Required for loading the glade UI
|
||||
Requires: pygtk2-libglade
|
||||
# Required for our graphics which are currently SVG format
|
||||
@ -111,6 +115,8 @@ cp %{SOURCE3} pixmaps
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
|
||||
%build
|
||||
%configure
|
||||
@ -184,6 +190,10 @@ fi
|
||||
%{_datadir}/dbus-1/services/%{name}.service
|
||||
|
||||
%changelog
|
||||
* Thu Sep 24 2009 Cole Robinson <crobinso@redhat.com> - 0.8.0-5.fc12
|
||||
- Refresh host disk space in create wizard (bz 502777)
|
||||
- Offer to fix disk permission issues (bz 517379)
|
||||
|
||||
* Thu Sep 17 2009 Cole Robinson <crobinso@redhat.com> - 0.8.0-4.fc12
|
||||
- Don't close libvirt connection for non-fatal errors (bz 522168)
|
||||
- Manager UI tweaks
|
||||
|
193
virtinst-0.500.0-change-path-perms.patch
Normal file
193
virtinst-0.500.0-change-path-perms.patch
Normal file
@ -0,0 +1,193 @@
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253738317 14400
|
||||
# Node ID 53cd275974ab35a790b4c4bf1424d0950d5b095e
|
||||
# Parent aff98f0152935ad7cd57e86c4172a6683e6306c5
|
||||
VirtualDisk: Add methods for checking/changing path perms for username.
|
||||
|
||||
Since libvirtd can now run qemu processes as non-root, the tools need to
|
||||
try to check directory permissions and make sure they are at least searchable
|
||||
by a specific username. This simply implements the functions to make that
|
||||
happen.
|
||||
|
||||
diff -r aff98f015293 -r 53cd275974ab virtinst/VirtualDisk.py
|
||||
--- a/virtinst/VirtualDisk.py Mon Sep 21 15:52:04 2009 -0400
|
||||
+++ b/virtinst/VirtualDisk.py Wed Sep 23 16:38:37 2009 -0400
|
||||
@@ -19,9 +19,11 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
-import os, statvfs
|
||||
+import os, stat, pwd, statvfs
|
||||
import subprocess
|
||||
import logging
|
||||
+import re
|
||||
+
|
||||
import urlgrabber.progress as progress
|
||||
import libvirt
|
||||
|
||||
@@ -69,6 +71,46 @@
|
||||
|
||||
return fmt
|
||||
|
||||
+def _name_uid(user):
|
||||
+ """
|
||||
+ Return UID for string username
|
||||
+ """
|
||||
+ pwdinfo = pwd.getpwnam(user)
|
||||
+ return pwdinfo[2]
|
||||
+
|
||||
+def _is_dir_searchable(uid, username, path):
|
||||
+ """
|
||||
+ Check if passed directory is searchable by uid
|
||||
+ """
|
||||
+ try:
|
||||
+ statinfo = os.stat(path)
|
||||
+ except OSError:
|
||||
+ return False
|
||||
+
|
||||
+ if uid == statinfo.st_uid:
|
||||
+ flag = stat.S_IXUSR
|
||||
+ elif uid == statinfo.st_gid:
|
||||
+ flag = stat.S_IXGRP
|
||||
+ else:
|
||||
+ flag = stat.S_IXOTH
|
||||
+
|
||||
+ if bool(statinfo.st_mode & flag):
|
||||
+ return True
|
||||
+
|
||||
+ # Check POSIX ACL (since that is what we use to 'fix' access)
|
||||
+ cmd = ["getfacl", path]
|
||||
+ proc = subprocess.Popen(cmd,
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ stderr=subprocess.PIPE)
|
||||
+ out, err = proc.communicate()
|
||||
+
|
||||
+ if proc.returncode != 0:
|
||||
+ logging.debug("Cmd '%s' failed: %s" % (cmd, err))
|
||||
+ return False
|
||||
+
|
||||
+ return bool(re.search("user:%s:..x" % username, out))
|
||||
+
|
||||
+
|
||||
class VirtualDisk(VirtualDevice):
|
||||
"""
|
||||
Builds a libvirt domain disk xml description
|
||||
@@ -156,6 +198,63 @@
|
||||
|
||||
return False
|
||||
|
||||
+ @staticmethod
|
||||
+ def check_path_search_for_user(conn, path, username):
|
||||
+ """
|
||||
+ Check if the passed user has search permissions for all the
|
||||
+ directories in the disk path.
|
||||
+
|
||||
+ @return: List of the directories the user cannot search, or empty list
|
||||
+ @rtype : C{list}
|
||||
+ """
|
||||
+ if _util.is_uri_remote(conn.getURI()):
|
||||
+ return []
|
||||
+
|
||||
+ uid = _name_uid(username)
|
||||
+ fixlist = []
|
||||
+
|
||||
+ dirname, base = os.path.split(path)
|
||||
+ while base:
|
||||
+ if not _is_dir_searchable(uid, username, dirname):
|
||||
+ fixlist.append(dirname)
|
||||
+
|
||||
+ dirname, base = os.path.split(dirname)
|
||||
+
|
||||
+ return fixlist
|
||||
+
|
||||
+ @staticmethod
|
||||
+ def fix_path_search_for_user(conn, path, username):
|
||||
+ """
|
||||
+ Try to fix any permission problems found by check_path_search_for_user
|
||||
+
|
||||
+ @return: Return a dictionary of entries { broken path : error msg }
|
||||
+ @rtype : C{dict}
|
||||
+ """
|
||||
+ fixlist = VirtualDisk.check_path_search_for_user(conn, path, username)
|
||||
+ if not fixlist:
|
||||
+ return []
|
||||
+
|
||||
+ fixlist.reverse()
|
||||
+ errdict = {}
|
||||
+
|
||||
+ for dirname in fixlist:
|
||||
+ try:
|
||||
+ cmd = ["setfacl", "--modify", "user:%s:x" % username, dirname]
|
||||
+ proc = subprocess.Popen(cmd,
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ stderr=subprocess.PIPE)
|
||||
+ out, err = proc.communicate()
|
||||
+
|
||||
+ logging.debug("Cmd '%s' output: \nout=%s, \nerr=%s" %
|
||||
+ (cmd, out, err))
|
||||
+ if proc.returncode != 0:
|
||||
+ raise ValueError(err)
|
||||
+ except Exception, e:
|
||||
+ errdict[dirname] = str(e)
|
||||
+
|
||||
+ return errdict
|
||||
+
|
||||
+
|
||||
def __init__(self, path=None, size=None, transient=False, type=None,
|
||||
device=DEVICE_DISK, driverName=None, driverType=None,
|
||||
readOnly=False, sparse=True, conn=None, volObject=None,
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253741935 14400
|
||||
# Node ID a523260ac56eb90e1eda067c2bbd5fc726bb0165
|
||||
# Parent 53cd275974ab35a790b4c4bf1424d0950d5b095e
|
||||
VirtualDisk: Teach perms changing functions about a target directory.
|
||||
|
||||
diff -r 53cd275974ab -r a523260ac56e virtinst/VirtualDisk.py
|
||||
--- a/virtinst/VirtualDisk.py Wed Sep 23 16:38:37 2009 -0400
|
||||
+++ b/virtinst/VirtualDisk.py Wed Sep 23 17:38:55 2009 -0400
|
||||
@@ -213,7 +213,12 @@
|
||||
uid = _name_uid(username)
|
||||
fixlist = []
|
||||
|
||||
- dirname, base = os.path.split(path)
|
||||
+ if os.path.isdir(path):
|
||||
+ dirname = path
|
||||
+ base = "-"
|
||||
+ else:
|
||||
+ dirname, base = os.path.split(path)
|
||||
+
|
||||
while base:
|
||||
if not _is_dir_searchable(uid, username, dirname):
|
||||
fixlist.append(dirname)
|
||||
diff -r 53cd275974ab virtinst/Installer.py
|
||||
--- a/virtinst/Installer.py Wed Sep 23 16:38:37 2009 -0400
|
||||
+++ b/virtinst/Installer.py Wed Sep 23 17:32:14 2009 -0400
|
||||
@@ -141,12 +141,20 @@
|
||||
return XEN_SCRATCH
|
||||
if os.path.exists(LIBVIRT_SCRATCH):
|
||||
return LIBVIRT_SCRATCH
|
||||
- else:
|
||||
- scratch = os.path.expanduser("~/.virtinst/boot")
|
||||
- if not os.path.exists(scratch):
|
||||
- os.makedirs(scratch, 0750)
|
||||
- _util.selinux_restorecon(scratch)
|
||||
- return scratch
|
||||
+
|
||||
+ scratch = os.path.expanduser("~/.virtinst/boot")
|
||||
+ if not os.path.exists(scratch):
|
||||
+ os.makedirs(scratch, 0751)
|
||||
+
|
||||
+ if (self.conn and
|
||||
+ not _util.is_uri_remote(self.conn.getURI()) and
|
||||
+ _util.is_qemu_system(self.conn.getURI())):
|
||||
+ # If we are using local qemu:///system, try to make sure the
|
||||
+ # download location is searchable by the 'qemu' user
|
||||
+ VirtualDisk.fix_path_search_for_user(self.conn, scratch, "qemu")
|
||||
+
|
||||
+ _util.selinux_restorecon(scratch)
|
||||
+ return scratch
|
||||
scratchdir = property(get_scratchdir)
|
||||
|
||||
def get_cdrom(self):
|
196
virtinst-0.500.0-no-iso-driver.patch
Normal file
196
virtinst-0.500.0-no-iso-driver.patch
Normal file
@ -0,0 +1,196 @@
|
||||
# HG changeset patch
|
||||
# User Cole Robinson <crobinso@redhat.com>
|
||||
# Date 1253562724 14400
|
||||
# Node ID aff98f0152935ad7cd57e86c4172a6683e6306c5
|
||||
# Parent 143b09da8bccc3b6b2069c29073ea5a6ef9ce69b
|
||||
VirtualDisk: Don't use 'iso' as a qemu driver name (bz 524109)
|
||||
|
||||
diff -r 143b09da8bcc -r aff98f015293 tests/testdriver.xml
|
||||
--- a/tests/testdriver.xml Mon Sep 21 15:47:33 2009 -0400
|
||||
+++ b/tests/testdriver.xml Mon Sep 21 15:52:04 2009 -0400
|
||||
@@ -67,6 +67,22 @@
|
||||
</target>
|
||||
</volume>
|
||||
<volume>
|
||||
+ <name>iso-vol</name>
|
||||
+ <capacity>1000000</capacity>
|
||||
+ <allocation>50000</allocation>
|
||||
+ <target>
|
||||
+ <format type='iso'/>
|
||||
+ </target>
|
||||
+ </volume>
|
||||
+ <volume>
|
||||
+ <name>bochs-vol</name>
|
||||
+ <capacity>1000000</capacity>
|
||||
+ <allocation>50000</allocation>
|
||||
+ <target>
|
||||
+ <format type='bochs'/>
|
||||
+ </target>
|
||||
+ </volume>
|
||||
+ <volume>
|
||||
<name>testvol1.img</name>
|
||||
<capacity>1000000</capacity>
|
||||
<allocation>50000</allocation>
|
||||
diff -r 143b09da8bcc -r aff98f015293 tests/xmlconfig-xml/misc-qemu-iso-disk.xml
|
||||
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||
+++ b/tests/xmlconfig-xml/misc-qemu-iso-disk.xml Mon Sep 21 15:52:04 2009 -0400
|
||||
@@ -0,0 +1,36 @@
|
||||
+<domain type='xen'>
|
||||
+ <name>TestGuest</name>
|
||||
+ <currentMemory>204800</currentMemory>
|
||||
+ <memory>409600</memory>
|
||||
+ <uuid>12345678-1234-1234-1234-123456789012</uuid>
|
||||
+ <os>
|
||||
+ <type arch='i686'>hvm</type>
|
||||
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
+ <boot dev='cdrom'/>
|
||||
+ </os>
|
||||
+ <features>
|
||||
+ <acpi/><apic/>
|
||||
+ </features>
|
||||
+ <clock offset="utc"/>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>destroy</on_reboot>
|
||||
+ <on_crash>destroy</on_crash>
|
||||
+ <vcpu>5</vcpu>
|
||||
+ <devices>
|
||||
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
+ <disk type='file' device='disk'>
|
||||
+ <driver name='qemu' type='raw'/>
|
||||
+ <source file='/default-pool/iso-vol'/>
|
||||
+ <target dev='hda' bus='ide'/>
|
||||
+ </disk>
|
||||
+ <disk type='block' device='cdrom'>
|
||||
+ <driver name='qemu'/>
|
||||
+ <source dev='/dev/loop0'/>
|
||||
+ <target dev='hdc' bus='ide'/>
|
||||
+ <readonly/>
|
||||
+ </disk>
|
||||
+ <input type='mouse' bus='ps2'/>
|
||||
+ <graphics type='sdl' display=':3.4' xauth='/testdir/.Xauthority'/>
|
||||
+ <console type='pty'/>
|
||||
+ </devices>
|
||||
+</domain>
|
||||
diff -r 143b09da8bcc -r aff98f015293 tests/xmlconfig.py
|
||||
--- a/tests/xmlconfig.py Mon Sep 21 15:47:33 2009 -0400
|
||||
+++ b/tests/xmlconfig.py Mon Sep 21 15:52:04 2009 -0400
|
||||
@@ -302,9 +302,15 @@
|
||||
g.disks.append(get_blkdisk())
|
||||
self._compare(g, "misc-qemu-driver-name", True)
|
||||
|
||||
+ VirtualDisk._get_uri = new_get_uri
|
||||
g = get_basic_fullyvirt_guest()
|
||||
g.disks.append(get_filedisk())
|
||||
self._compare(g, "misc-qemu-driver-type", True)
|
||||
+
|
||||
+ VirtualDisk._get_uri = new_get_uri
|
||||
+ g = get_basic_fullyvirt_guest()
|
||||
+ g.disks.append(get_filedisk("/default-pool/iso-vol"))
|
||||
+ self._compare(g, "misc-qemu-iso-disk", True)
|
||||
finally:
|
||||
VirtualDisk._get_uri = oldgetdriver
|
||||
|
||||
diff -r 143b09da8bcc -r aff98f015293 virtinst/VirtualDisk.py
|
||||
--- a/virtinst/VirtualDisk.py Mon Sep 21 15:47:33 2009 -0400
|
||||
+++ b/virtinst/VirtualDisk.py Mon Sep 21 15:52:04 2009 -0400
|
||||
@@ -55,6 +55,20 @@
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
+def _qemu_sanitize_drvtype(phystype, fmt):
|
||||
+ """
|
||||
+ Sanitize libvirt storage volume format to a valid qemu driver type
|
||||
+ """
|
||||
+ raw_list = [ "iso" ]
|
||||
+
|
||||
+ if phystype == VirtualDisk.TYPE_BLOCK:
|
||||
+ return VirtualDisk.DRIVER_QEMU_RAW
|
||||
+
|
||||
+ if fmt in raw_list:
|
||||
+ return VirtualDisk.DRIVER_QEMU_RAW
|
||||
+
|
||||
+ return fmt
|
||||
+
|
||||
class VirtualDisk(VirtualDevice):
|
||||
"""
|
||||
Builds a libvirt domain disk xml description
|
||||
@@ -490,8 +504,8 @@
|
||||
|
||||
http://lists.gnu.org/archive/html/qemu-devel/2008-04/msg00675.html
|
||||
"""
|
||||
- drvname = None
|
||||
- drvtype = None
|
||||
+ drvname = self._driverName
|
||||
+ drvtype = self._driverType
|
||||
|
||||
if self.conn:
|
||||
driver = _util.get_uri_driver(self._get_uri())
|
||||
@@ -499,15 +513,15 @@
|
||||
drvname = self.DRIVER_QEMU
|
||||
|
||||
if self.vol_object:
|
||||
- drvtype = _util.get_xml_path(self.vol_object.XMLDesc(0),
|
||||
- "/volume/target/format/@type")
|
||||
+ fmt = _util.get_xml_path(self.vol_object.XMLDesc(0),
|
||||
+ "/volume/target/format/@type")
|
||||
+ if drvname == self.DRIVER_QEMU:
|
||||
+ drvtype = _qemu_sanitize_drvtype(self.type, fmt)
|
||||
|
||||
elif self.vol_install:
|
||||
if drvname == self.DRIVER_QEMU:
|
||||
- if self.vol_install.file_type == libvirt.VIR_STORAGE_VOL_FILE:
|
||||
- drvtype = self.vol_install.format
|
||||
- else:
|
||||
- drvtype = self.DRIVER_QEMU_RAW
|
||||
+ drvtype = _qemu_sanitize_drvtype(self.type,
|
||||
+ self.vol_install.format)
|
||||
|
||||
elif self.__creating_storage():
|
||||
if drvname == self.DRIVER_QEMU:
|
||||
@@ -729,8 +743,10 @@
|
||||
managed_storage = self.__storage_specified()
|
||||
create_media = self.__creating_storage()
|
||||
|
||||
+ self.__set_dev_type()
|
||||
self.__set_size()
|
||||
self.__set_format()
|
||||
+ self.__set_driver()
|
||||
|
||||
if not self.selinux_label:
|
||||
# If we are using existing storage, pull the label from it
|
||||
@@ -745,9 +761,6 @@
|
||||
|
||||
self._selinux_label = context or ""
|
||||
|
||||
- # Set driverName + driverType
|
||||
- self.__set_driver()
|
||||
-
|
||||
# If not creating the storage, our job is easy
|
||||
if not create_media:
|
||||
# Make sure we have access to the local path
|
||||
@@ -757,7 +770,6 @@
|
||||
raise ValueError(_("The path '%s' must be a file or a "
|
||||
"device, not a directory") % self.path)
|
||||
|
||||
- self.__set_dev_type()
|
||||
return True
|
||||
|
||||
|
||||
@@ -770,7 +782,6 @@
|
||||
if self.type is self.TYPE_BLOCK:
|
||||
raise ValueError, _("Local block device path '%s' must "
|
||||
"exist.") % self.path
|
||||
- self.set_type(self.TYPE_FILE, validate=False)
|
||||
|
||||
# Path doesn't exist: make sure we have write access to dir
|
||||
if not os.access(os.path.dirname(self.path), os.R_OK):
|
||||
@@ -782,9 +793,6 @@
|
||||
if not os.access(os.path.dirname(self.path), os.W_OK):
|
||||
raise ValueError, _("No write access to directory '%s'") % \
|
||||
os.path.dirname(self.path)
|
||||
- else:
|
||||
- # Set dev type from existing storage
|
||||
- self.__set_dev_type()
|
||||
|
||||
# Applicable for managed or local storage
|
||||
ret = self.is_size_conflict()
|
Loading…
Reference in New Issue
Block a user