diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2012-11-13 11:15:40 +0000 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2012-11-21 11:53:07 +0000 |
commit | 6aebaca79ad394c99d0b9698834bccfcfa226ab4 (patch) | |
tree | 0efaebbf1440666362ed7ef32baf74b76151897e | |
parent | 72918415f2b6a241d6097a563aba55a849936591 (diff) | |
download | nova-6aebaca79ad394c99d0b9698834bccfcfa226ab4.tar.gz nova-6aebaca79ad394c99d0b9698834bccfcfa226ab4.tar.xz nova-6aebaca79ad394c99d0b9698834bccfcfa226ab4.zip |
Remove img_handlers config parameter usage
Now that the only disk code requiring host filesystem
mounts is the LXC filesystem setup, the img_handlers
config parameter is an solution looking for a purpose.
For any disk image format we can categorically say
whether it should be mounted using loop or qemu-nbd
mount impls. There is no desire to use libguestfs FUSE
for mounting LXC disk images, since users of LXC do
not want a huge KVM process alongside every container!
Move the mount class choice logic into the mount API,
by creating new methods
nova.virt.disk.mount.API.instance_for_format()
nova.virt.disk.mount.API.instance_for_device()
and then call these from nova.virt.disk.API code
blueprint: virt-disk-api-refactoring
Change-Id: I088b5debdf62d4a9a6b4521eee68cd4757f2ff42
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r-- | nova/tests/test_virt.py | 8 | ||||
-rw-r--r-- | nova/virt/disk/api.py | 70 | ||||
-rw-r--r-- | nova/virt/disk/mount/api.py | 25 | ||||
-rw-r--r-- | nova/virt/disk/mount/loop.py | 1 | ||||
-rw-r--r-- | nova/virt/disk/mount/nbd.py | 1 |
5 files changed, 44 insertions, 61 deletions
diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 2c5dd4734..0cede2197 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -107,7 +107,6 @@ class TestVirtDisk(test.TestCase): '/mnt/loop/part': '/dev/mapper/loop0p1', '/mnt/nbd/nopart': '/dev/nbd15', '/mnt/nbd/part': '/dev/mapper/nbd15p1', - '/mnt/guestfs': 'guestmount', } return mount_points[mount_point] @@ -141,11 +140,4 @@ class TestVirtDisk(test.TestCase): ('qemu-nbd', '-d', '/dev/nbd15'), ] - disk_api.destroy_container('/mnt/guestfs') - expected_commands += [ - ('fusermount', '-u', '/mnt/guestfs'), - ] - # It's not worth trying to match the last timeout command - self.executes.pop() - self.assertEqual(self.executes, expected_commands) diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py index 33773e59c..9d9d672d7 100644 --- a/nova/virt/disk/api.py +++ b/nova/virt/disk/api.py @@ -37,9 +37,7 @@ from nova.openstack.common import cfg from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova import utils -from nova.virt.disk.mount import guestfs -from nova.virt.disk.mount import loop -from nova.virt.disk.mount import nbd +from nova.virt.disk.mount import api as mount from nova.virt.disk.vfs import api as vfs from nova.virt import images @@ -50,9 +48,6 @@ disk_opts = [ cfg.StrOpt('injected_network_template', default='$pybasedir/nova/virt/interfaces.template', help='Template file for injected network'), - cfg.ListOpt('img_handlers', - default=['loop', 'nbd', 'guestfs'], - help='Order of methods used to mount disk images'), # NOTE(yamahata): ListOpt won't work because the command may include a # comma. For example: @@ -174,25 +169,14 @@ class _DiskImage(object): self.image = image self.partition = partition self.mount_dir = mount_dir + self.use_cow = use_cow # Internal self._mkdir = False self._mounter = None self._errors = [] - # As a performance tweak, don't bother trying to - # directly loopback mount a cow image. - self.handlers = CONF.img_handlers[:] - if use_cow and 'loop' in self.handlers: - self.handlers.remove('loop') - - if not self.handlers: - msg = _('no capable image handler configured') - raise exception.NovaException(msg) - if mount_dir: - # Note the os.path.ismount() shortcut doesn't - # work with libguestfs due to permissions issues. device = self._device_for_path(mount_dir) if device: self._reset(device) @@ -211,12 +195,10 @@ class _DiskImage(object): def _reset(self, device): """Reset internal state for a previously mounted directory.""" - mounter_cls = self._handler_class(device=device) - mounter = mounter_cls(image=self.image, - partition=self.partition, - mount_dir=self.mount_dir, - device=device) - self._mounter = mounter + self._mounter = mount.Mount.instance_for_device(self.image, + self.mount_dir, + self.partition, + device) mount_name = os.path.basename(self.mount_dir or '') self._mkdir = mount_name.startswith(self.tmp_prefix) @@ -226,17 +208,6 @@ class _DiskImage(object): """Return the collated errors from all operations.""" return '\n--\n'.join([''] + self._errors) - @staticmethod - def _handler_class(mode=None, device=None): - """Look up the appropriate class to use based on MODE or DEVICE.""" - for cls in (loop.LoopMount, nbd.NbdMount, guestfs.GuestFSMount): - if mode and cls.mode == mode: - return cls - elif device and cls.device_id_string in device: - return cls - msg = _("no disk image handler for: %s") % mode or device - raise exception.NovaException(msg) - def mount(self): """Mount a disk image, using the object attributes. @@ -252,21 +223,19 @@ class _DiskImage(object): self.mount_dir = tempfile.mkdtemp(prefix=self.tmp_prefix) self._mkdir = True - try: - for h in self.handlers: - mounter_cls = self._handler_class(h) - mounter = mounter_cls(image=self.image, - partition=self.partition, - mount_dir=self.mount_dir) - if mounter.do_mount(): - self._mounter = mounter - break - else: - LOG.debug(mounter.error) - self._errors.append(mounter.error) - finally: - if not self._mounter: - self.umount() # rmdir + imgfmt = "raw" + if self.use_cow: + imgfmt = "qcow2" + + mounter = mount.Mount.instance_for_format(self.image, + self.mount_dir, + self.partition, + imgfmt) + if mounter.do_mount(): + self._mounter = mounter + else: + LOG.debug(mounter.error) + self._errors.append(mounter.error) return bool(self._mounter) @@ -275,6 +244,7 @@ class _DiskImage(object): try: if self._mounter: self._mounter.do_umount() + self._mounter = None finally: if self._mkdir: os.rmdir(self.mount_dir) diff --git a/nova/virt/disk/mount/api.py b/nova/virt/disk/mount/api.py index e683658d2..b63aa3300 100644 --- a/nova/virt/disk/mount/api.py +++ b/nova/virt/disk/mount/api.py @@ -17,6 +17,7 @@ import os +from nova.openstack.common import importutils from nova.openstack.common import log as logging from nova import utils @@ -30,7 +31,29 @@ class Mount(object): to be called in that order. """ - mode = device_id_string = None # to be overridden in subclasses + mode = None # to be overridden in subclasses + + @staticmethod + def instance_for_format(imgfile, mountdir, partition, imgfmt): + if imgfmt == "raw": + return importutils.import_object( + "nova.virt.disk.mount.loop.LoopMount", + imgfile, mountdir, partition) + else: + return importutils.import_object( + "nova.virt.disk.mount.nbd.NbdMount", + imgfile, mountdir, partition) + + @staticmethod + def instance_for_device(imgfile, mountdir, partition, device): + if "loop" in device: + return importutils.import_object( + "nova.virt.disk.mount.loop.LoopMount", + imgfile, mountdir, partition, device) + else: + return importutils.import_object( + "nova.virt.disk.mount.nbd.NbdMount", + imgfile, mountdir, partition, device) def __init__(self, image, mount_dir, partition=None, device=None): diff --git a/nova/virt/disk/mount/loop.py b/nova/virt/disk/mount/loop.py index 9b87b6df5..d6c53cbce 100644 --- a/nova/virt/disk/mount/loop.py +++ b/nova/virt/disk/mount/loop.py @@ -22,7 +22,6 @@ from nova.virt.disk.mount import api class LoopMount(api.Mount): """loop back support for raw images.""" mode = 'loop' - device_id_string = mode def get_dev(self): out, err = utils.trycmd('losetup', '--find', '--show', self.image, diff --git a/nova/virt/disk/mount/nbd.py b/nova/virt/disk/mount/nbd.py index 01d8b66b5..4a27d4f75 100644 --- a/nova/virt/disk/mount/nbd.py +++ b/nova/virt/disk/mount/nbd.py @@ -39,7 +39,6 @@ CONF.register_opts(nbd_opts) class NbdMount(api.Mount): """qemu-nbd support disk images.""" mode = 'nbd' - device_id_string = mode # NOTE(padraig): There are three issues with this nbd device handling # 1. max_nbd_devices should be inferred (#861504) |