Merge "libvirt: virtuozzo instance resize support"

This commit is contained in:
Jenkins 2016-06-29 04:33:32 +00:00 committed by Gerrit Code Review
commit 1cb9195aa8
12 changed files with 62 additions and 19 deletions

View File

@ -385,8 +385,10 @@ driver-impl-vmware=complete
driver-impl-hyperv=complete
driver-impl-ironic=partial
driver-notes-ironic=Only certain ironic drivers support this
driver-impl-libvirt-vz-vm=missing
driver-impl-libvirt-vz-ct=missing
driver-impl-libvirt-vz-vm=complete
driver-notes-vz-vm=Resizing Virtuozzo instances implies guest filesystem resize also
driver-impl-libvirt-vz-ct=complete
driver-notes-vz-ct=Resizing Virtuozzo instances implies guest filesystem resize also
[operation.resume]
title=Restore instance

View File

@ -246,7 +246,8 @@ cp: CommandFilter, cp, root
sync: CommandFilter, sync, root
# nova/virt/libvirt/imagebackend.py:
ploop: CommandFilter, ploop, root
ploop: RegExpFilter, ploop, root, ploop, restore-descriptor, .*
prl_disk_tool: RegExpFilter, prl_disk_tool, root, prl_disk_tool, resize, --size, .*M$, --resize_partition, --hdd, .*
# nova/virt/libvirt/utils.py: 'xend', 'status'
xend: CommandFilter, xend, root

View File

@ -18,6 +18,7 @@ import tempfile
import fixtures
import mock
from oslo_concurrency import processutils
from oslo_utils import units
from nova import test
from nova import utils
@ -176,6 +177,24 @@ class APITestCase(test.NoDBTestCase):
imgsize)
self.assertFalse(mock_extendable.called)
@mock.patch.object(api, 'can_resize_image', return_value=True)
@mock.patch.object(utils, 'execute')
def test_extend_ploop(self, mock_execute, mock_can_resize_image):
imgfile = tempfile.NamedTemporaryFile()
self.addCleanup(imgfile.close)
imgsize = 10 * units.Gi
imgsize_mb = str(imgsize // units.Mi) + 'M'
image = imgmodel.LocalFileImage(imgfile, imgmodel.FORMAT_PLOOP)
api.extend(image, imgsize)
mock_can_resize_image.assert_called_once_with(image.path,
imgsize)
mock_execute.assert_called_once_with('prl_disk_tool', 'resize',
'--size', imgsize_mb,
'--resize_partition',
'--hdd', imgfile,
run_as_root=True)
def test_extend_raw_success(self):
imgfile = tempfile.NamedTemporaryFile()
self.addCleanup(imgfile.close)

View File

@ -1590,6 +1590,7 @@ class PloopTestCase(_ImageTestCase, test.NoDBTestCase):
'__call__')
self.mox.StubOutWithMock(imagebackend.libvirt_utils, 'copy_image')
self.mox.StubOutWithMock(self.utils, 'execute')
self.mox.StubOutWithMock(imagebackend.disk, 'extend')
return fn
def test_cache(self):
@ -1619,9 +1620,9 @@ class PloopTestCase(_ImageTestCase, test.NoDBTestCase):
imagebackend.libvirt_utils.copy_image(self.TEMPLATE_PATH, img_path)
self.utils.execute("ploop", "restore-descriptor", "-f", "raw",
self.PATH, img_path)
self.utils.execute("ploop", "grow", '-s', "2K",
os.path.join(self.PATH, "DiskDescriptor.xml"),
run_as_root=True)
image = imgmodel.LocalFileImage(self.PATH, imgmodel.FORMAT_PLOOP)
imagebackend.disk.extend(image, 2048)
self.mox.ReplayAll()
image = self.image_class(self.INSTANCE, self.NAME)

View File

@ -44,7 +44,7 @@ class LibvirtUtilsTestCase(test.NoDBTestCase):
@mock.patch('nova.utils.execute')
def test_copy_image_local(self, mock_execute):
libvirt_utils.copy_image('src', 'dest')
mock_execute.assert_called_once_with('cp', 'src', 'dest')
mock_execute.assert_called_once_with('cp', '-r', 'src', 'dest')
@mock.patch('nova.virt.libvirt.volume.remotefs.SshDriver.copy_file')
def test_copy_image_remote_ssh(self, mock_rem_fs_remove):

View File

@ -166,7 +166,7 @@ class RemoteFSTestCase(test.NoDBTestCase):
remotefs.RsyncDriver().copy_file('1.2.3.4:/home/star_wars',
'/home/favourite', None, None,
compression=True)
mock_execute.assert_called_once_with('rsync', '--sparse',
mock_execute.assert_called_once_with('rsync', '-r', '--sparse',
'1.2.3.4:/home/star_wars',
'/home/favourite',
'--compress',
@ -178,7 +178,7 @@ class RemoteFSTestCase(test.NoDBTestCase):
remotefs.RsyncDriver().copy_file('1.2.3.4:/home/star_wars',
'/home/favourite', None, None,
compression=False)
mock_execute.assert_called_once_with('rsync', '--sparse',
mock_execute.assert_called_once_with('rsync', '-r', '--sparse',
'1.2.3.4:/home/star_wars',
'/home/favourite',
on_completion=None,
@ -188,7 +188,7 @@ class RemoteFSTestCase(test.NoDBTestCase):
def test_remote_copy_file_ssh(self, mock_execute):
remotefs.SshDriver().copy_file('1.2.3.4:/home/SpaceOdyssey',
'/home/favourite', None, None, True)
mock_execute.assert_called_once_with('scp',
mock_execute.assert_called_once_with('scp', '-r',
'1.2.3.4:/home/SpaceOdyssey',
'/home/favourite',
on_completion=None,

View File

@ -33,6 +33,7 @@ if os.name != 'nt':
from oslo_concurrency import processutils
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import units
import nova.conf
from nova import exception
@ -158,6 +159,16 @@ def extend(image, size):
if not isinstance(image, imgmodel.LocalImage):
return
if (image.format == imgmodel.FORMAT_PLOOP):
if not can_resize_image(image.path, size):
return
utils.execute('prl_disk_tool', 'resize',
'--size', '%dM' % (size // units.Mi),
'--resize_partition',
'--hdd', image.path, run_as_root=True)
return
if not can_resize_image(image.path, size):
return

View File

@ -20,10 +20,12 @@ from nova import exception
FORMAT_RAW = "raw"
FORMAT_QCOW2 = "qcow2"
FORMAT_PLOOP = "ploop"
ALL_FORMATS = [
FORMAT_RAW,
FORMAT_QCOW2,
FORMAT_PLOOP,
]

View File

@ -1024,9 +1024,7 @@ class Ploop(Image):
utils.execute('ploop', 'restore-descriptor', '-f', self.pcs_format,
target, image_path)
if size:
dd_path = os.path.join(self.path, "DiskDescriptor.xml")
utils.execute('ploop', 'grow', '-s', '%dK' % (size >> 10),
dd_path, run_as_root=True)
self.resize_image(size)
if not os.path.exists(self.path):
if CONF.force_raw_images:
@ -1063,9 +1061,8 @@ class Ploop(Image):
create_ploop_image(base, self.path, size)
def resize_image(self, size):
dd_path = os.path.join(self.path, "DiskDescriptor.xml")
utils.execute('ploop', 'grow', '-s', '%dK' % (size >> 10), dd_path,
run_as_root=True)
image = imgmodel.LocalFileImage(self.path, imgmodel.FORMAT_PLOOP)
disk.extend(image, size)
def snapshot_extract(self, target, out_format):
img_path = os.path.join(self.path, "root.hds")

View File

@ -199,7 +199,8 @@ def copy_image(src, dest, host=None, receive=False,
# sparse files. I.E. holes will not be written to DEST,
# rather recreated efficiently. In addition, since
# coreutils 8.11, holes can be read efficiently too.
execute('cp', src, dest)
# we add '-r' argument because ploop disks are directories
execute('cp', '-r', src, dest)
else:
if receive:
src = "%s:%s" % (utils.safe_ip_format(host), src)

View File

@ -196,7 +196,8 @@ class SshDriver(RemoteFilesystemDriver):
on_execute=on_execute, on_completion=on_completion)
def copy_file(self, src, dst, on_execute, on_completion, compression):
utils.execute('scp', src, dst,
# As far as ploop disks are in fact directories we add '-r' argument
utils.execute('scp', '-r', src, dst,
on_execute=on_execute, on_completion=on_completion)
@ -324,7 +325,8 @@ class RsyncDriver(RemoteFilesystemDriver):
on_execute=on_execute, on_completion=on_completion)
def copy_file(self, src, dst, on_execute, on_completion, compression):
args = ['rsync', '--sparse', src, dst]
# As far as ploop disks are in fact directories we add '-r' argument
args = ['rsync', '-r', '--sparse', src, dst]
if compression:
args.append('--compress')
utils.execute(*args,

View File

@ -0,0 +1,7 @@
---
features:
- Virtuozzo ploop disks can be resized now during "nova resize".
upgrade:
- You must update the rootwrap configuration for the compute service
if you use ploop images, so that "ploop grow" filter is changed
to "prl_disk_tool resize".