Merge "Convert to use nova.objects.ImageMeta"

This commit is contained in:
Jenkins 2016-01-20 16:00:59 +00:00 committed by Gerrit Code Review
commit a01f3ca869
10 changed files with 66 additions and 51 deletions

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import objects
from nova.objects import flavor
import os
import sys
@ -57,6 +58,16 @@ TEST_MIGRATION_SAME_HOST = {
'new_instance_type_id': 2,
}
IMAGE1 = {
'id': 1,
'name': 'image1',
'size': 300,
'container_format': 'bare',
'disk_format': 'raw'
}
TEST_IMAGE1 = objects.ImageMeta.from_dict(IMAGE1)
# NOTE(mikal): All of this is because if dnspython is present in your
# environment then eventlet monkeypatches socket.getaddrinfo() with an
# implementation which doesn't work for IPv6. What we're checking here is

View File

@ -18,6 +18,7 @@ import mock
from nova import test
from nova_powervm.tests.virt import powervm
from nova_powervm.tests.virt.powervm import fixtures as fx
from nova_powervm.virt.powervm.disk import driver as disk_dvr
@ -40,8 +41,7 @@ class TestDiskAdapter(test.TestCase):
def test_get_image_upload(self):
# Test if there is an ID, that we get a file adapter back
img_meta = {'id': 'test_id'}
temp = self.st_adpt._get_image_upload(mock.Mock(), img_meta)
temp = self.st_adpt._get_image_upload(mock.Mock(), powervm.TEST_IMAGE1)
self.assertIsInstance(temp, disk_dvr.IterableToFileAdapter)
def test_get_info(self):

View File

@ -24,6 +24,7 @@ from pypowervm.tests.test_utils import pvmhttp
from pypowervm.wrappers import storage as pvm_stor
from pypowervm.wrappers import virtual_io_server as pvm_vios
from nova_powervm.tests.virt import powervm
from nova_powervm.tests.virt.powervm import fixtures as fx
from nova_powervm.virt.powervm.disk import driver as disk_dvr
from nova_powervm.virt.powervm.disk import localdisk as ld
@ -75,16 +76,16 @@ class TestLocalDisk(test.TestCase):
@mock.patch('nova.image.API')
def test_create_disk_from_image(self, mock_img_api, mock_file_adpt,
mock_upload_vdisk):
mock_img = {'id': 'fake_id', 'size': 50}
mock_upload_vdisk.return_value = ('vdisk', None)
inst = mock.Mock()
inst.name = 'Inst Name'
inst.uuid = 'd5065c2c-ac43-3fa6-af32-ea84a3960291'
vdisk = self.get_ls(self.apt).create_disk_from_image(
None, inst, mock_img, 20)
None, inst, powervm.TEST_IMAGE1, 20)
mock_upload_vdisk.assert_called_with(mock.ANY, mock.ANY, mock.ANY,
mock.ANY, 'b_Inst_Nam_d506', 50,
mock.ANY, 'b_Inst_Nam_d506',
powervm.TEST_IMAGE1.size,
d_size=21474836480)
self.assertEqual('vdisk', vdisk)

View File

@ -28,6 +28,7 @@ from pypowervm.wrappers import cluster as pvm_clust
from pypowervm.wrappers import storage as pvm_stg
from pypowervm.wrappers import virtual_io_server as pvm_vios
from nova_powervm.tests.virt import powervm
from nova_powervm.tests.virt.powervm import fixtures as fx
from nova_powervm.virt.powervm.disk import driver as disk_dvr
from nova_powervm.virt.powervm.disk import ssp
@ -304,17 +305,14 @@ class TestSSPDiskAdapter(test.TestCase):
@mock.patch('nova.image.API')
def test_create_disk_from_new_image(self, mock_img_api, mock_it2fadp,
mock_upload_lu, mock_crt_lnk_cln):
b1G = 1024 * 1024 * 1024
b2G = 2 * b1G
ssp_stor = self._get_ssp_stor()
img = dict(name='image-name', id='image-id', size=b2G)
def verify_upload_new_lu(vios_uuid, ssp1, stream, lu_name, f_size):
self.assertIn(vios_uuid, ssp_stor.vios_uuids)
self.assertEqual(ssp_stor._ssp_wrap, ssp1)
# 'image' + '_' + s/-/_/g(image['id']), per _get_image_name
self.assertEqual('image_image_name', lu_name)
self.assertEqual(b2G, f_size)
# 'image' + '_' + s/-/_/g(image.name), per _get_image_name
self.assertEqual('image_' + powervm.TEST_IMAGE1.name, lu_name)
self.assertEqual(powervm.TEST_IMAGE1.size, f_size)
return 'image_lu', None
def verify_create_lu_linked_clone(ssp1, clust1, imglu, lu_name, sz_gb):
@ -325,7 +323,8 @@ class TestSSPDiskAdapter(test.TestCase):
mock_upload_lu.side_effect = verify_upload_new_lu
mock_crt_lnk_cln.side_effect = verify_create_lu_linked_clone
lu = ssp_stor.create_disk_from_image(None, self.instance, img, 1)
lu = ssp_stor.create_disk_from_image(None, self.instance,
powervm.TEST_IMAGE1, 1)
self.assertEqual('new_lu', lu)
@mock.patch('pypowervm.tasks.storage.crt_lu_linked_clone')
@ -333,12 +332,9 @@ class TestSSPDiskAdapter(test.TestCase):
@mock.patch('nova.image.API')
def test_create_disk_from_existing_image(self, mock_img_api, mock_it2fadp,
mock_crt_lnk_cln):
b1G = 1024 * 1024 * 1024
b2G = 2 * b1G
ssp_stor = self._get_ssp_stor()
img = dict(name='image-name', id='image-id', size=b2G)
# Mock the 'existing' image LU
img_lu = pvm_stg.LU.bld(None, 'image_image_name', 123,
img_lu = pvm_stg.LU.bld(None, 'image_' + powervm.TEST_IMAGE1.name, 123,
typ=pvm_stg.LUType.IMAGE)
ssp_stor._ssp_wrap.logical_units.append(img_lu)
@ -353,7 +349,8 @@ class TestSSPDiskAdapter(test.TestCase):
return ssp1, 'new_lu'
mock_crt_lnk_cln.side_effect = verify_create_lu_linked_clone
lu = ssp_stor.create_disk_from_image(None, Instance(), img, 1)
lu = ssp_stor.create_disk_from_image(
None, Instance(), powervm.TEST_IMAGE1, 1)
self.assertEqual('new_lu', lu)
def test_find_lu(self):

View File

@ -1106,7 +1106,7 @@ class TestPowerVMDriver(test.TestCase):
# Invoke the method.
self.drv.rescue('context', inst, mock.MagicMock(),
mock.MagicMock(), 'rescue_psswd')
powervm.TEST_IMAGE1, 'rescue_psswd')
self.assertTrue(mock_task_vm.power_off.called)
self.assertTrue(self.drv.disk_dvr.create_disk_from_image.called)

View File

@ -238,10 +238,11 @@ class DiskAdapter(object):
built for the invoker.
:param context: User context
:param image_meta: The image metadata.
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:return: The stream to send to pypowervm.
"""
chunks = self.image_api.download(context, image_meta['id'])
chunks = self.image_api.download(context, image_meta.id)
return IterableToFileAdapter(chunks)
@staticmethod
@ -265,7 +266,7 @@ class DiskAdapter(object):
@staticmethod
def _get_image_name(image_meta):
"""Generate a name for a virtual storage copy of an image."""
return pvm_util.sanitize_file_name_for_api(image_meta['name'],
return pvm_util.sanitize_file_name_for_api(image_meta.name,
prefix=DiskType.IMAGE + '_')
@staticmethod
@ -320,7 +321,8 @@ class DiskAdapter(object):
:param context: nova context used to retrieve image from glance
:param instance: instance to create the disk for.
:param image_meta: dict identifying the image in glance
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param disk_size: The size of the disk to create in GB. If smaller
than the image, it will be ignored (as the disk
must be at least as big as the image). Must be an

View File

@ -166,13 +166,14 @@ class LocalStorage(disk_dvr.DiskAdapter):
'disk_name': disk_name, 'mp_uuid': self.mp_uuid,
'vios_name': vios_uuid})
def create_disk_from_image(self, context, instance, image, disk_size,
def create_disk_from_image(self, context, instance, image_meta, disk_size,
image_type=disk_dvr.DiskType.BOOT):
"""Creates a disk and copies the specified image to it.
:param context: nova context used to retrieve image from glance
:param instance: instance to create the disk for.
:param image: image dict used to locate the image in glance
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param disk_size: The size of the disk to create in GB. If smaller
than the image, it will be ignored (as the disk
must be at least as big as the image). Must be an
@ -183,11 +184,11 @@ class LocalStorage(disk_dvr.DiskAdapter):
LOG.info(_LI('Create disk.'))
# Transfer the image
stream = self._get_image_upload(context, image)
stream = self._get_image_upload(context, image_meta)
vol_name = self._get_disk_name(image_type, instance, short=True)
# Disk size to API is in bytes. Input from method is in Gb
disk_bytes = self._disk_gb_to_bytes(disk_size, floor=image['size'])
disk_bytes = self._disk_gb_to_bytes(disk_size, floor=image_meta.size)
# This method will create a new disk at our specified size. It will
# then put the image in the disk. If the disk is bigger, user can
@ -196,7 +197,7 @@ class LocalStorage(disk_dvr.DiskAdapter):
# enough to support the image (up to 1 Gb boundary).
vdisk, f_wrap = tsk_stg.upload_new_vdisk(
self.adapter, self._vios_uuid, self.vg_uuid, stream, vol_name,
image['size'], d_size=disk_bytes)
image_meta.size, d_size=disk_bytes)
return vdisk

View File

@ -199,7 +199,8 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
"""
tsk_stg.rm_ssp_storage(self._ssp, storage_elems)
def create_disk_from_image(self, context, instance, img_meta, disk_size_gb,
def create_disk_from_image(self, context, instance, image_meta,
disk_size_gb,
image_type=disk_drv.DiskType.BOOT):
"""Creates a boot disk and links the specified image to it.
@ -209,9 +210,8 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
:param context: nova context used to retrieve image from glance
:param instance: instance to create the disk for.
:param img_meta: image metadata dict:
{ 'id': reference used to locate the image in glance,
'size': size in bytes of the image. }
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param disk_size_gb: The size of the disk to create in GB. If smaller
than the image, it will be ignored (as the disk
must be at least as big as the image). Must be an
@ -221,7 +221,7 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
"""
LOG.info(_LI('SSP: Create %(image_type)s disk from image %(image_id)s '
'for instance %(instance_uuid)s.'),
dict(image_type=image_type, image_id=img_meta['id'],
dict(image_type=image_type, image_id=image_meta.id,
instance_uuid=instance.uuid))
# TODO(IBM): There's an optimization to be had here if we can create
@ -229,7 +229,7 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
# This will require some nontrivial refactoring, though, as the LUs are
# created down inside of upload_new_lu and crt_lu_linked_clone.
image_lu = self._get_or_upload_image_lu(context, img_meta)
image_lu = self._get_or_upload_image_lu(context, image_meta)
boot_lu_name = self._get_disk_name(image_type, instance)
LOG.info(_LI('SSP: Disk name is %s'), boot_lu_name)
@ -245,7 +245,7 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
if lu.lu_type == lu_type and lu.name == lu_name:
return lu
def _get_or_upload_image_lu(self, context, img_meta):
def _get_or_upload_image_lu(self, context, image_meta):
"""Ensures our SSP has an LU containing the specified image.
If an LU of type IMAGE corresponding to the input image metadata
@ -253,13 +253,12 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
with the image contents from glance, and return it.
:param context: nova context used to retrieve image from glance
:param img_meta: image metadata dict:
{ 'id': reference used to locate the image in glance,
'size': size in bytes of the image. }
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:return: A pypowervm LU ElementWrapper representing the image.
"""
# Key off of the name to see whether we already have the image
luname = self._get_image_name(img_meta)
luname = self._get_image_name(image_meta)
lu = self._find_lu(luname, pvm_stg.LUType.IMAGE)
if lu:
LOG.info(_LI('SSP: Using already-uploaded image LU %s.'), luname)
@ -267,10 +266,10 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
# We don't have it yet. Create it and upload the glance image to it.
# Make the image LU only as big as the image.
stream = self._get_image_upload(context, img_meta)
stream = self._get_image_upload(context, image_meta)
LOG.info(_LI('SSP: Uploading new image LU %s.'), luname)
lu, f_wrap = tsk_stg.upload_new_lu(
self._any_vios_uuid(), self._ssp, stream, luname, img_meta['size'])
self._any_vios_uuid(), self._ssp, stream, luname, image_meta.size)
return lu
def get_disk_ref(self, instance, disk_type):

View File

@ -236,8 +236,8 @@ class PowerVMDriver(driver.ComputeDriver):
:param instance: Instance object as returned by DB layer.
This function should use the data there to guide
the creation of the new instance.
:param image_meta: image object returned by nova.image.glance that
defines the image from which to boot this instance
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param injected_files: User files to inject into instance.
:param admin_password: Administrator password to set in instance.
:param network_info:
@ -635,14 +635,18 @@ class PowerVMDriver(driver.ComputeDriver):
rescue_password):
"""Rescue the specified instance.
:param instance: nova.objects.instance.Instance
:param nova.context.RequestContext context:
The context for the rescue.
:param nova.objects.instance.Instance instance:
The instance being rescued.
:param nova.network.model.NetworkInfo network_info:
Necessary network information for the resume.
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param rescue_password: new root password to set for rescue.
"""
self._log_operation('rescue', instance)
# We need the image size, which isn't in the system meta data
# so get the all the info.
image_meta = self.image_api.get(context, image_meta['id'])
pvm_inst_uuid = vm.get_pvm_uuid(instance)
# Define the flow
flow = tf_lf.Flow("rescue")
@ -1006,9 +1010,8 @@ class PowerVMDriver(driver.ComputeDriver):
:param disk_info: the newly transferred disk information
:param network_info:
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param image_meta: image object returned by nova.image.glance that
defines the image from which this instance
was created
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param resize_instance: True if the instance disks are being resized,
False otherwise
:param block_device_info: instance volume block device info

View File

@ -133,7 +133,8 @@ class CreateDiskForImg(task.Task):
:param disk_dvr: The storage driver.
:param context: The context passed into the driver method.
:param instance: The nova instance.
:param image_meta: The image metadata.
:param nova.objects.ImageMeta image_meta:
The metadata of the image of the instance.
:param disk_size: The size of disk to create. If the size is smaller
than the image, the image size will be used.
:param image_type: The image type. See disk/driver.py