Esempio n. 1
0
    def _create_disk_from_image(self, context, instance, image_meta,
                                image_type=disk_drv.DiskType.BOOT):
        """Creates a disk and copies the specified image to it.

        If the specified image has not already been uploaded, an Image LU is
        created for it.  A Disk LU is then created for the instance and linked
        to the Image LU.

        :param context: nova context used to retrieve image from glance
        :param instance: instance to create the disk for.
        :param nova.objects.ImageMeta image_meta:
            The metadata of the image of the instance.
        :param image_type: The image type. See disk_drv.DiskType.
        :return: The backing pypowervm LU storage object that was created.
        """
        LOG.info('SSP: Create %(image_type)s disk from image %(image_id)s.',
                 dict(image_type=image_type, image_id=image_meta.id),
                 instance=instance)

        image_lu = tsk_cs.get_or_upload_image_lu(
            self._tier, self._get_image_name(image_meta),
            self._any_vios_uuid(), disk_drv.IterableToFileAdapter(
                IMAGE_API.download(context, image_meta.id)),
            image_meta.size, upload_type=tsk_stg.UploadType.IO_STREAM)

        boot_lu_name = self._get_disk_name(image_type, instance)
        LOG.info('SSP: Disk name is %s', boot_lu_name, instance=instance)

        return tsk_stg.crt_lu(
            self._tier, boot_lu_name, instance.flavor.root_gb,
            typ=pvm_stg.LUType.DISK, clone=image_lu)[1]
Esempio n. 2
0
File: ssp.py Progetto: Juniper/nova
    def create_disk_from_image(self, context, instance, image_meta):
        """Creates a boot disk and links the specified image to it.

        If the specified image has not already been uploaded, an Image LU is
        created for it.  A Disk LU is then created for the instance and linked
        to the Image LU.

        :param context: nova context used to retrieve image from glance
        :param instance: instance to create the disk for.
        :param nova.objects.ImageMeta image_meta:
            The metadata of the image of the instance.
        :return: The backing pypowervm LU storage object that was created.
        """
        LOG.info('SSP: Create boot disk from image %s.', image_meta.id,
                 instance=instance)

        image_lu = tsk_cs.get_or_upload_image_lu(
            self._tier, pvm_u.sanitize_file_name_for_api(
                image_meta.name, prefix=DiskType.IMAGE + '_',
                suffix='_' + image_meta.checksum),
            random.choice(self._vios_uuids), IterableToFileAdapter(
                IMAGE_API.download(context, image_meta.id)), image_meta.size,
            upload_type=tsk_stg.UploadType.IO_STREAM)

        boot_lu_name = pvm_u.sanitize_file_name_for_api(
            instance.name, prefix=DiskType.BOOT + '_')

        LOG.info('SSP: Disk name is %s', boot_lu_name, instance=instance)

        return tsk_stg.crt_lu(
            self._tier, boot_lu_name, instance.flavor.root_gb,
            typ=pvm_stg.LUType.DISK, clone=image_lu)[1]
Esempio n. 3
0
 def test_crt_lu(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10)
     self.assertEqual(lu.name, 'lu5')
     self.assertEqual(lu.udid, 'udid_lu5')
     self.assertTrue(lu.is_thin)
     self.assertEqual(lu.lu_type, stor.LUType.DISK)
     self.assertEqual(ssp.etag, 'after')
     self.assertIn(lu, ssp.logical_units)
Esempio n. 4
0
 def test_crt_lu(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10)
     self.assertEqual(lu.name, 'lu5')
     self.assertEqual(lu.udid, 'udid_lu5')
     self.assertTrue(lu.is_thin)
     self.assertEqual(lu.lu_type, stor.LUType.DISK)
     self.assertEqual(ssp.etag, 'after')
     self.assertIn(lu, ssp.logical_units)
Esempio n. 5
0
    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.

        If the specified image has not already been uploaded, an Image LU is
        created for it.  A Disk LU is then created for the instance and linked
        to the Image LU.

        :param context: nova context used to retrieve image from glance
        :param instance: instance to create the disk for.
        :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
                             int.
        :param image_type: The image type. See disk_drv.DiskType.
        :return: The backing pypowervm LU storage object that was created.
        """
        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=image_meta.id,
                 instance_uuid=instance.uuid))

        def upload(path):
            IMAGE_API.download(context, image_meta.id, dest_path=path)

        image_lu = tsk_cs.get_or_upload_image_lu(
            self._tier,
            self._get_image_name(image_meta),
            self._any_vios_uuid(),
            upload,
            image_meta.size,
            upload_type=tsk_stg.UploadType.FUNC)

        boot_lu_name = self._get_disk_name(image_type, instance)
        LOG.info(_LI('SSP: Disk name is %s'), boot_lu_name)

        return tsk_stg.crt_lu(self._tier,
                              boot_lu_name,
                              disk_size_gb,
                              typ=pvm_stg.LUType.DISK,
                              clone=image_lu)[1]
Esempio n. 6
0
    def create_disk_from_image(self, context, instance, image_meta):
        """Creates a boot disk and links the specified image to it.

        If the specified image has not already been uploaded, an Image LU is
        created for it.  A Disk LU is then created for the instance and linked
        to the Image LU.

        :param context: nova context used to retrieve image from glance
        :param instance: instance to create the disk for.
        :param nova.objects.ImageMeta image_meta:
            The metadata of the image of the instance.
        :return: The backing pypowervm LU storage object that was created.
        """
        LOG.info('SSP: Create boot disk from image %s.',
                 image_meta.id,
                 instance=instance)

        image_lu = tsk_cs.get_or_upload_image_lu(
            self._tier,
            pvm_u.sanitize_file_name_for_api(image_meta.name,
                                             prefix=disk_drv.DiskType.IMAGE +
                                             '_',
                                             suffix='_' + image_meta.checksum),
            random.choice(self._vios_uuids),
            disk_drv.IterableToFileAdapter(
                IMAGE_API.download(context, image_meta.id)),
            image_meta.size,
            upload_type=tsk_stg.UploadType.IO_STREAM)

        boot_lu_name = pvm_u.sanitize_file_name_for_api(
            instance.name, prefix=disk_drv.DiskType.BOOT + '_')

        LOG.info('SSP: Disk name is %s', boot_lu_name, instance=instance)

        return tsk_stg.crt_lu(self._tier,
                              boot_lu_name,
                              instance.flavor.root_gb,
                              typ=pvm_stg.LUType.DISK,
                              clone=image_lu)[1]
Esempio n. 7
0
 def test_crt_lu_type_image(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, typ=stor.LUType.IMAGE)
     self.assertEqual(lu.lu_type, stor.LUType.IMAGE)
Esempio n. 8
0
 def test_crt_lu_thick(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, thin=False)
     self.assertFalse(lu.is_thin)
Esempio n. 9
0
 def test_crt_lu_thin(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, thin=True)
     self.assertTrue(lu.is_thin)
Esempio n. 10
0
def get_or_upload_image_lu(tier,
                           luname,
                           vios_uuid,
                           io_handle,
                           b_size,
                           upload_type=tsk_stg.UploadType.IO_STREAM_BUILDER):
    """Ensures our SSP has an LU containing the specified image.

    If an LU of type IMAGE with the specified luname already exists in our SSP,
    return it.  Otherwise, create it, prime it with the image contents provided
    via stream_func, and return it.

    This method assumes that consumers employ a naming convention such that an
    LU with a given name represents the same data (size and content) no matter
    where/when it's created/uploaded - for example, by including the image's
    MD5 checksum in the name.

    This method is designed to coordinate the upload of a particular image LU
    across multiple hosts which use the same SSP, but otherwise can not
    communicate with each other.

    :param tier: Tier EntryWrapper of the Shared Storage Pool Tier on which the
                 image LU is to be hosted.
    :param luname: The name of the image LU.  Note that the name may be
                   shortened to satisfy length restrictions.
    :param vios_uuid: The UUID of the Virtual I/O Server through which the
                      upload should be performed, if necessary.
    :param io_handle: The I/O handle (as defined by the upload_type).  This is
                      only used if the image_lu needs to be uploaded.
    :param b_size: Integer size, in bytes, of the image provided by
                   stream_func's return value.
    :param upload_type: (Optional, Default: IO_STREAM_BUILDER) Defines the way
                        in which the LU should be uploaded.  Refer to the
                        UploadType enumeration for valid upload mechanisms.
                        It defaults to IO_STREAM_BUILDER for legacy reasons.
    :return: LUEnt EntryWrapper representing the image LU.
    """
    # Marker (upload-in-progress) LU name prefixed with 'partxxxxxxxx'
    prefix = 'part%s' % uuid.uuid4().hex[:8]
    # Ensure the marker LU name won't be too long
    luname = u.sanitize_file_name_for_api(luname,
                                          max_len=c.MaxLen.FILENAME_DEFAULT -
                                          len(prefix))
    mkr_luname = prefix + luname
    first = True
    while True:
        # (Re)fetch the list of image LUs whose name *contains* luname.
        lus = _find_lus(tier, luname)

        # Does the LU already exist in its final, uploaded form?  If so, then
        # only that LU will exist, with an exact name match.
        if len(lus) == 1 and lus[0].name == luname:
            LOG.info(_('Using already-uploaded image LU %s.'), luname)
            return lus[0]

        # Is there an upload in progress?
        if _upload_in_progress(lus, luname, first):
            first = False
            _sleep_for_upload()
            continue

        # No upload in progress (at least as of when we grabbed the feed).
        LOG.info(_('Creating marker LU %s'), mkr_luname)
        tier, mkrlu = tsk_stg.crt_lu(tier, mkr_luname, MKRSZ, typ=IMGTYP)

        # We must remove the marker LU if
        # a) anything fails beyond this point; or
        # b) we successfully upload the image LU.
        try:
            # If another process (possibly on another host) created a marker LU
            # at the same time, there could be multiple marker LUs out there.
            # We all use _upload_conflict to decide which one of us gets to do
            # the upload.
            if _upload_conflict(tier, luname, mkr_luname):
                _sleep_for_upload()
                continue

            # Okay, we won.  Do the actual upload.
            LOG.info(_('Uploading to image LU %(lu)s (marker %(mkr)s).'), {
                'lu': luname,
                'mkr': mkr_luname
            })
            # Create the new Logical Unit.  The LU size needs to be decimal GB.
            tier, new_lu = tsk_stg.crt_lu(tier,
                                          luname,
                                          u.convert_bytes_to_gb(b_size, dp=2),
                                          typ=IMGTYP)
            try:
                tsk_stg.upload_lu(vios_uuid,
                                  new_lu,
                                  io_handle,
                                  b_size,
                                  upload_type=upload_type)
            except Exception as exc:
                LOG.exception(exc)
                # We need to remove the LU so it doesn't block others
                # attempting to use the same one.
                LOG.exception(_('Removing failed LU %s.'), luname)
                new_lu.delete()
                raise
            return new_lu
        finally:
            # Signal completion, or clean up, by removing the marker LU.
            mkrlu.delete()
Esempio n. 11
0
 def test_crt_lu_type_image(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, typ=stor.LUType.IMAGE)
     self.assertEqual(lu.lu_type, stor.LUType.IMAGE)
Esempio n. 12
0
 def test_crt_lu_thick(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, thin=False)
     self.assertFalse(lu.is_thin)
Esempio n. 13
0
 def test_crt_lu_thin(self):
     ssp, lu = ts.crt_lu(self.ssp, 'lu5', 10, thin=True)
     self.assertTrue(lu.is_thin)