예제 #1
0
 def test_glance_client_image_ref(self):
     fixture = self._make_fixture(name="test image")
     image_id = self.service.create(self.context, fixture)["id"]
     image_url = "http://something-less-likely/%s" % image_id
     (service, same_id) = glance.get_remote_image_service(self.context, image_url)
     self.assertEqual(same_id, image_id)
     self.assertEqual(service._client.netloc, "something-less-likely")
     for ipv6_url in ("[::1]", "::1", "[::1]:444"):
         image_url = "http://%s/%s" % (ipv6_url, image_id)
         (service, same_id) = glance.get_remote_image_service(self.context, image_url)
         self.assertEqual(same_id, image_id)
         self.assertEqual(service._client.netloc, ipv6_url)
예제 #2
0
 def test_glance_client_image_ref(self):
     fixture = self._make_fixture(name='test image')
     image_id = self.service.create(self.context, fixture)['id']
     image_url = 'http://something-less-likely/%s' % image_id
     (service,
      same_id) = glance.get_remote_image_service(self.context, image_url)
     self.assertEqual(same_id, image_id)
     self.assertEqual('something-less-likely', service._client.netloc)
     for ipv6_url in ('[::1]', '::1', '[::1]:444'):
         image_url = 'http://%s/%s' % (ipv6_url, image_id)
         (service, same_id) = glance.get_remote_image_service(
             self.context, image_url)
         self.assertEqual(same_id, image_id)
         self.assertEqual(ipv6_url, service._client.netloc)
예제 #3
0
 def test_glance_client_image_ref(self):
     fixture = self._make_fixture(name='test image')
     image_id = self.service.create(self.context, fixture)['id']
     image_url = 'http://something-less-likely/%s' % image_id
     (service, same_id) = glance.get_remote_image_service(self.context,
                                                          image_url)
     self.assertEqual(same_id, image_id)
     self.assertEqual(service._client.netloc, 'something-less-likely')
     for ipv6_url in ('[::1]', '::1', '[::1]:444'):
         image_url = 'http://%s/%s' % (ipv6_url, image_id)
         (service, same_id) = glance.get_remote_image_service(self.context,
                                                              image_url)
         self.assertEqual(same_id, image_id)
         self.assertEqual(service._client.netloc, ipv6_url)
예제 #4
0
파일: manager.py 프로젝트: afliu/cinder
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
        try:
            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            self.driver.copy_volume_to_image(context, volume, image_service,
                                             image_meta)
            LOG.debug(_("Uploaded volume %(volume_id)s to "
                        "image (%(image_id)s) successfully"),
                      {'volume_id': volume_id, 'image_id': image_id})
        except Exception as error:
            with excutils.save_and_reraise_exception():
                payload['message'] = unicode(error)
        finally:
            if (volume['instance_uuid'] is None and
                    volume['attached_host'] is None):
                self.db.volume_update(context, volume_id,
                                      {'status': 'available'})
            else:
                self.db.volume_update(context, volume_id,
                                      {'status': 'in-use'})
예제 #5
0
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
        try:
            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            self.driver.copy_volume_to_image(context, volume, image_service,
                                             image_meta)
            LOG.debug(
                _("Uploaded volume %(volume_id)s to "
                  "image (%(image_id)s) successfully"), {
                      'volume_id': volume_id,
                      'image_id': image_id
                  })
        except Exception as error:
            with excutils.save_and_reraise_exception():
                payload['message'] = unicode(error)
        finally:
            if (volume['instance_uuid'] is None
                    and volume['attached_host'] is None):
                self.db.volume_update(context, volume_id,
                                      {'status': 'available'})
            else:
                self.db.volume_update(context, volume_id, {'status': 'in-use'})
예제 #6
0
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {"volume_id": volume_id, "image_id": image_meta["id"]}
        try:
            # NOTE(flaper87): Verify the driver is enabled
            # before going forward. The exception will be caught
            # and the volume status updated.
            utils.require_driver_initialized(self.driver)

            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = glance.get_remote_image_service(context, image_meta["id"])
            self.driver.copy_volume_to_image(context, volume, image_service, image_meta)
            LOG.debug(
                _("Uploaded volume %(volume_id)s to " "image (%(image_id)s) successfully"),
                {"volume_id": volume_id, "image_id": image_id},
            )
        except Exception as error:
            with excutils.save_and_reraise_exception():
                payload["message"] = unicode(error)
        finally:
            if volume["instance_uuid"] is None and volume["attached_host"] is None:
                self.db.volume_update(context, volume_id, {"status": "available"})
            else:
                self.db.volume_update(context, volume_id, {"status": "in-use"})
예제 #7
0
파일: manager.py 프로젝트: ArikaChen/cinder
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {"volume_id": volume_id, "image_id": image_meta["id"]}
        try:
            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = glance.get_remote_image_service(context, image_meta["id"])
            self.driver.copy_volume_to_image(context, volume, image_service, image_meta)
            LOG.debug(
                _("Uploaded volume %(volume_id)s to " "image (%(image_id)s) successfully"),
                {"volume_id": volume_id, "image_id": image_id},
            )
        except Exception as error:
            with excutils.save_and_reraise_exception():
                payload["message"] = unicode(error)
        finally:
            if volume["instance_uuid"] is None:
                self.db.volume_update(context, volume_id, {"status": "available"})
            else:
                self.db.volume_update(context, volume_id, {"status": "in-use"})
예제 #8
0
 def test_glance_client_image_ref(self):
     fixture = self._make_fixture(name="test image")
     image_id = self.service.create(self.context, fixture)["id"]
     image_url = "http://something-less-likely/%s" % image_id
     (service, same_id) = glance.get_remote_image_service(self.context, image_url)
     self.assertEquals(same_id, image_id)
     self.assertEquals(service._client.host, "something-less-likely")
예제 #9
0
 def test_glance_client_image_ref(self):
     fixture = self._make_fixture(name='test image')
     image_id = self.service.create(self.context, fixture)['id']
     image_url = 'http://something-less-likely/%s' % image_id
     (service,
      same_id) = glance.get_remote_image_service(self.context, image_url)
     self.assertEquals(same_id, image_id)
     self.assertEquals(service._client.host, 'something-less-likely')
예제 #10
0
    def create_volume(self, context, volume_id, snapshot_id=None, image_id=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")
        LOG.info(_("volume %s: creating"), volume_ref["name"])

        self.db.volume_update(context, volume_id, {"host": self.host})
        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref["host"] = self.host

        status = "available"
        model_update = False

        try:
            vol_name = volume_ref["name"]
            vol_size = volume_ref["size"]
            LOG.debug(_("volume %(vol_name)s: creating lv of" " size %(vol_size)sG") % locals())
            if snapshot_id is None and image_id is None:
                model_update = self.driver.create_volume(volume_ref)
            elif snapshot_id is not None:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(volume_ref, snapshot_ref)
            else:
                # create the volume from an image
                image_service, image_id = glance.get_remote_image_service(context, image_id)
                image_location = image_service.get_location(context, image_id)
                cloned = self.driver.clone_image(volume_ref, image_location)
                if not cloned:
                    model_update = self.driver.create_volume(volume_ref)
                    status = "downloading"

            if model_update:
                self.db.volume_update(context, volume_ref["id"], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref["name"])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref["id"], model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.volume_update(context, volume_ref["id"], {"status": "error"})

        now = timeutils.utcnow()
        self.db.volume_update(context, volume_ref["id"], {"status": status, "launched_at": now})
        LOG.debug(_("volume %s: created successfully"), volume_ref["name"])
        self._reset_stats()

        if image_id and not cloned:
            # copy the image onto the volume.
            self._copy_image_to_volume(context, volume_ref, image_id)
        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref["id"]
예제 #11
0
 def copy_volume_to_image(self, context, volume_id, image_id):
     """Uploads the specified volume to Glance."""
     payload = {"volume_id": volume_id, "image_id": image_id}
     try:
         volume = self.db.volume_get(context, volume_id)
         self.driver.ensure_export(context.elevated(), volume)
         image_service, image_id = glance.get_remote_image_service(context, image_id)
         self.driver.copy_volume_to_image(context, volume, image_service, image_id)
         LOG.debug(_("Uploaded volume %(volume_id)s to " "image (%(image_id)s) successfully") % locals())
     except Exception, error:
         with excutils.save_and_reraise_exception():
             payload["message"] = unicode(error)
예제 #12
0
 def _copy_image_to_volume(self, context, volume, image_id):
     """Downloads Glance image to the specified volume. """
     volume_id = volume["id"]
     payload = {"volume_id": volume_id, "image_id": image_id}
     try:
         image_service, image_id = glance.get_remote_image_service(context, image_id)
         self.driver.copy_image_to_volume(context, volume, image_service, image_id)
         LOG.debug(_("Downloaded image %(image_id)s to %(volume_id)s " "successfully") % locals())
         self.db.volume_update(context, volume_id, {"status": "available"})
     except Exception, error:
         with excutils.save_and_reraise_exception():
             payload["message"] = unicode(error)
             self.db.volume_update(context, volume_id, {"status": "error"})
예제 #13
0
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        LOG.info(_("cascade info, copy volume to image, image_meta is:%s"),
                 image_meta)
        force = image_meta.get('force', False)
        image_name = image_meta.get("name")
        container_format = image_meta.get("container_format")
        disk_format = image_meta.get("disk_format")
        vol_ref = self.db.volume_get(context, volume_id)
        casecaded_volume_id = vol_ref['mapping_uuid']
        cinderClient = self._get_cinder_cascaded_user_client(context)

        resp = cinderClient.volumes.upload_to_image(
            volume=casecaded_volume_id,
            force=force,
            image_name=image_name,
            container_format=container_format,
            disk_format=disk_format)

        if cfg.CONF.glance_cascading_flag:
            cascaded_image_id = resp[1]['os-volume_upload_image']['image_id']
            LOG.debug(_('Cascade info:upload volume to image,get cascaded '
                        'image id is %s'), cascaded_image_id)
            url = '%s/v2/images/%s' % (cfg.CONF.cascaded_glance_url,
                                       cascaded_image_id)
            locations = [{
                         'url': url,
                         'metadata': {'image_id': str(cascaded_image_id),
                                      'image_from': 'volume'
                                      }
                         }]

            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            LOG.debug(_("Cascade info: image service:%s"), image_service)
            glanceClient = glance.GlanceClientWrapper(
                context,
                netloc=cfg.CONF.cascading_glance_url,
                use_ssl=False,
                version="2")
            glanceClient.call(context, 'update', image_id,
                              remove_props=None, locations=locations)
            LOG.debug(_('Cascade info:upload volume to image,finish update'
                        'image %s locations %s.'), (image_id, locations))
예제 #14
0
파일: manager.py 프로젝트: tek-life/cinder
 def copy_volume_to_image(self, context, volume_id, image_id):
     """Uploads the specified volume to Glance."""
     payload = {'volume_id': volume_id, 'image_id': image_id}
     try:
         volume = self.db.volume_get(context, volume_id)
         self.driver.ensure_export(context.elevated(), volume)
         image_service, image_id = glance.get_remote_image_service(context,
                                                                   image_id)
         self.driver.copy_volume_to_image(context, volume, image_service,
                                          image_id)
         LOG.debug(_("Uploaded volume %(volume_id)s to "
                     "image (%(image_id)s) successfully") % locals())
     except Exception, error:
         with excutils.save_and_reraise_exception():
             payload['message'] = unicode(error)
예제 #15
0
파일: manager.py 프로젝트: tek-life/cinder
 def _copy_image_to_volume(self, context, volume, image_id):
     """Downloads Glance image to the specified volume. """
     volume_id = volume['id']
     payload = {'volume_id': volume_id, 'image_id': image_id}
     try:
         image_service, image_id = glance.get_remote_image_service(context,
                                                                   image_id)
         self.driver.copy_image_to_volume(context, volume, image_service,
                                          image_id)
         LOG.debug(_("Downloaded image %(image_id)s to %(volume_id)s "
                     "successfully") % locals())
         self.db.volume_update(context, volume_id,
                               {'status': 'available'})
     except Exception, error:
         with excutils.save_and_reraise_exception():
             payload['message'] = unicode(error)
             self.db.volume_update(context, volume_id, {'status': 'error'})
예제 #16
0
 def _copy_image_to_volume(self, context, volume, image_id):
     """Downloads Glance image to the specified volume. """
     volume_id = volume['id']
     payload = {'volume_id': volume_id, 'image_id': image_id}
     try:
         self.driver.ensure_export(context.elevated(), volume)
         image_service, image_id = glance.get_remote_image_service(context,
                                                                   image_id)
         self.driver.copy_image_to_volume(context, volume, image_service,
                                          image_id)
         LOG.debug(_("Downloaded image %(image_id)s to %(volume_id)s "
                     "successfully") % locals())
         self.db.volume_update(context, volume_id,
                               {'status': 'available'})
     except Exception, error:
         with excutils.save_and_reraise_exception():
             payload['message'] = unicode(error)
             self.db.volume_update(context, volume_id, {'status': 'error'})
예제 #17
0
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
        try:
            # NOTE(flaper87): Verify the driver is enabled
            # before going forward. The exception will be caught
            # and the volume status updated.
            utils.require_driver_initialized(self.driver)

            volume = self.db.volume_get(context, volume_id)

            volume_type_id = volume.get('volume_type_id', None)
            if self._is_share_volume(volume_type_id):
                self.db.volume_update(context,
                                      volume_id,
                                      {'status': 'error'})
                msg = _("Volume is share volume")
                raise exception.InvalidVolume(reason=msg)

            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            self.driver.copy_volume_to_image(context, volume, image_service,
                                             image_meta)
            LOG.debug(_("Uploaded volume %(volume_id)s to "
                        "image (%(image_id)s) successfully"),
                      {'volume_id': volume_id, 'image_id': image_id})
        except Exception as error:
            with excutils.save_and_reraise_exception():
                payload['message'] = unicode(error)
        finally:
            if not volume['volume_attachment']:
                self.db.volume_update(context, volume_id,
                                      {'status': 'available'})
            else:
                self.db.volume_update(context, volume_id,
                                      {'status': 'in-use'})
예제 #18
0
파일: manager.py 프로젝트: twigs/cinder
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
        try:
            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            self.driver.copy_volume_to_image(context, volume, image_service,
                                             image_meta)
            LOG.debug(_("Uploaded volume %(volume_id)s to "
                        "image (%(image_id)s) successfully") % locals())
        except Exception, error:
            with excutils.save_and_reraise_exception():
                payload['message'] = unicode(error)
예제 #19
0
    def copy_volume_to_image(self, context, volume_id, image_meta):
        """Uploads the specified volume to Glance.

        image_meta is a dictionary containing the following keys:
        'id', 'container_format', 'disk_format'

        """
        payload = {'volume_id': volume_id, 'image_id': image_meta['id']}
        try:
            volume = self.db.volume_get(context, volume_id)
            self.driver.ensure_export(context.elevated(), volume)
            image_service, image_id = \
                glance.get_remote_image_service(context, image_meta['id'])
            self.driver.copy_volume_to_image(context, volume, image_service,
                                             image_meta)
            LOG.debug(_("Uploaded volume %(volume_id)s to "
                        "image (%(image_id)s) successfully") % locals())
        except Exception, error:
            with excutils.save_and_reraise_exception():
                payload['message'] = unicode(error)
예제 #20
0
 def test_glance_client_image_id(self):
     fixture = self._make_fixture(name='test image')
     image_id = self.service.create(self.context, fixture)['id']
     (_service,
      same_id) = glance.get_remote_image_service(self.context, image_id)
     self.assertEqual(same_id, image_id)
예제 #21
0
 def test_glance_client_image_id(self):
     fixture = self._make_fixture(name='test image')
     image_id = self.service.create(self.context, fixture)['id']
     (service, same_id) = glance.get_remote_image_service(
             self.context, image_id)
     self.assertEquals(same_id, image_id)
예제 #22
0
파일: manager.py 프로젝트: ArikaChen/cinder
    def create_volume(
        self,
        context,
        volume_id,
        request_spec=None,
        filter_properties=None,
        allow_reschedule=True,
        snapshot_id=None,
        image_id=None,
        source_volid=None,
    ):
        """Creates and exports the volume."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref["host"] = self.host

        status = "available"
        model_update = False
        image_meta = None
        cloned = False

        try:
            LOG.debug(
                _("volume %(vol_name)s: creating lv of" " size %(vol_size)sG"),
                {"vol_name": volume_ref["name"], "vol_size": volume_ref["size"]},
            )
            snapshot_ref = None
            sourcevol_ref = None
            image_service = None
            image_location = None
            image_meta = None

            if snapshot_id is not None:
                LOG.info(_("volume %s: creating from snapshot"), volume_ref["name"])
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
            elif source_volid is not None:
                LOG.info(_("volume %s: creating from existing volume"), volume_ref["name"])
                sourcevol_ref = self.db.volume_get(context, source_volid)
            elif image_id is not None:
                LOG.info(_("volume %s: creating from image"), volume_ref["name"])
                # create the volume from an image
                image_service, image_id = glance.get_remote_image_service(context, image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
            else:
                LOG.info(_("volume %s: creating"), volume_ref["name"])

            try:
                model_update, cloned = self._create_volume(
                    context, volume_ref, snapshot_ref, sourcevol_ref, image_service, image_id, image_location
                )
            except exception.ImageCopyFailure as ex:
                LOG.error(_("Setting volume: %s status to error " "after failed image copy."), volume_ref["id"])
                self.db.volume_update(context, volume_ref["id"], {"status": "error"})
                return
            except Exception:
                # restore source volume status before reschedule
                if sourcevol_ref is not None:
                    self.db.volume_update(context, sourcevol_ref["id"], {"status": sourcevol_ref["status"]})
                exc_info = sys.exc_info()
                # try to re-schedule volume:
                self._reschedule_or_reraise(
                    context,
                    volume_id,
                    exc_info,
                    snapshot_id,
                    image_id,
                    request_spec,
                    filter_properties,
                    allow_reschedule,
                )
                return

            if model_update:
                volume_ref = self.db.volume_update(context, volume_ref["id"], model_update)
            if sourcevol_ref is not None:
                self.db.volume_glance_metadata_copy_from_volume_to_volume(context, source_volid, volume_id)

            LOG.debug(_("volume %s: creating export"), volume_ref["name"])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref["id"], model_update)
        except Exception:
            with excutils.save_and_reraise_exception():
                volume_ref["status"] = "error"
                self.db.volume_update(context, volume_ref["id"], {"status": volume_ref["status"]})
                LOG.error(_("volume %s: create failed"), volume_ref["name"])
                self._notify_about_volume_usage(context, volume_ref, "create.end")

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(context, volume_ref["id"], snapshot_id)

        if image_id and image_meta:
            # Copy all of the Glance image properties to the
            # volume_glance_metadata table for future reference.
            self.db.volume_glance_metadata_create(context, volume_ref["id"], "image_id", image_id)
            name = image_meta.get("name", None)
            if name:
                self.db.volume_glance_metadata_create(context, volume_ref["id"], "image_name", name)
            image_properties = image_meta.get("properties", {})
            for key, value in image_properties.items():
                self.db.volume_glance_metadata_create(context, volume_ref["id"], key, value)

        now = timeutils.utcnow()
        volume_ref["status"] = status
        self.db.volume_update(context, volume_ref["id"], {"status": volume_ref["status"], "launched_at": now})
        LOG.info(_("volume %s: created successfully"), volume_ref["name"])
        self._reset_stats()

        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref["id"]
예제 #23
0
    def create_volume(self,
                      context,
                      volume_id,
                      snapshot_id=None,
                      image_id=None,
                      source_volid=None,
                      **kwargs):
        context = context.elevated()
        volume = db.volume_get(context, volume_id)
        LOG.info(_("volume %s: creating"), volume['name'])
        model_update = {'host': 'lunr'}
        volume['host'] = 'lunr'
        try:
            # Try to get the volume type name, else use the default volume type
            volume_type_name = volume['volume_type']['name']
        except (KeyError, TypeError):
            volume_type_name = CONF.lunr_default_volume_type
            # Using the default volume type name,
            # ask the db for the volume type id
            vtype_id = self._get_volume_type_id(volume_type_name)
            model_update['volume_type_id'] = vtype_id
            volume['volume_type_id'] = vtype_id

        db.volume_update(context, volume['id'], model_update)

        params = {
            'name': volume['id'],
            'size': volume['size'],
            'volume_type_name': volume_type_name,
        }

        # Copy image to volume!
        if image_id:
            params['image_id'] = image_id
            image_service, image_id = glance.get_remote_image_service(
                context, image_id)
            image_meta = image_service.show(context, image_id)
            if image_meta:
                db.volume_glance_metadata_create(context, volume['id'],
                                                 'image_id', image_id)
                name = image_meta.get('name', None)
                if name:
                    db.volume_glance_metadata_create(context, volume['id'],
                                                     'image_name', name)
                image_properties = image_meta.get('properties', {})
                for key, value in image_properties.items():
                    db.volume_glance_metadata_create(context, volume['id'],
                                                     key, value)

        # If this is a snapshot request, add the backup param
        if snapshot_id:
            params['backup'] = snapshot_id
            snapshot_ref = db.snapshot_get(context, snapshot_id)
            original_vref = db.volume_get(context, snapshot_ref['volume_id'])
            if original_vref['bootable']:
                db.volume_glance_metadata_copy_to_volume(
                    context, volume_id, snapshot_id)
                db.volume_update(context, volume_id, {'bootable': True})

        # If this is a clone request, add the source_volume_id param
        if source_volid:
            params['source_volume'] = source_volid
            source_vref = db.volume_get(context, source_volid)
            if source_vref['bootable']:
                db.volume_glance_metadata_copy_from_volume_to_volume(
                    context, source_volid, volume_id)
                db.volume_update(context, volume_id, {'bootable': True})

        try:
            resp = LunrClient(volume, logger=LOG).volumes.create(
                volume['id'], **params)
        except LunrError, e:
            LOG.debug('error creating volume %s', volume['id'])
            # Don't leave an error'd volume around, the raise here
            # will notify the caller of the error (See Github Issue #343)
            # Also, in Havana, TaskFlow will revert the quota increase.
            db.volume_destroy(context, volume['id'])
            raise e
예제 #24
0
                                     direct_url='swift+http://test/image')
        image_id = self.service.create(self.context, fixture)['id']
        writer = NullWriter()
        self.flags(allowed_direct_url_schemes=['file'])
        self.flags(glance_api_version=2)
        self.service.download(self.context, image_id, writer)
<<<<<<< HEAD:cinder/tests/unit/image/test_glance.py
        self.assertIsNone(mock_copyfileobj.call_args)
=======
        self.assertEqual(None, mock_copyfileobj.call_args)
>>>>>>> refs/remotes/openstack/stable/kilo:cinder/tests/image/test_glance.py

    def test_glance_client_image_id(self):
        fixture = self._make_fixture(name='test image')
        image_id = self.service.create(self.context, fixture)['id']
        (_service, same_id) = glance.get_remote_image_service(self.context,
                                                              image_id)
        self.assertEqual(same_id, image_id)

    def test_glance_client_image_ref(self):
        fixture = self._make_fixture(name='test image')
        image_id = self.service.create(self.context, fixture)['id']
        image_url = 'http://something-less-likely/%s' % image_id
        (service, same_id) = glance.get_remote_image_service(self.context,
                                                             image_url)
        self.assertEqual(same_id, image_id)
        self.assertEqual('something-less-likely', service._client.netloc)
        for ipv6_url in ('[::1]', '::1', '[::1]:444'):
            image_url = 'http://%s/%s' % (ipv6_url, image_id)
            (service, same_id) = glance.get_remote_image_service(self.context,
                                                                 image_url)
            self.assertEqual(same_id, image_id)
예제 #25
0
    def create_volume(self, context, volume_id, snapshot_id=None,
                      image_id=None, source_volid=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")
        LOG.info(_("volume %s: creating"), volume_ref['name'])

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        status = 'available'
        model_update = False
        image_meta = None

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                        " size %(vol_size)sG") % locals())
            if all(x is None for x in(snapshot_id, image_id, source_volid)):
                model_update = self.driver.create_volume(volume_ref)
            elif snapshot_id is not None:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(
                    volume_ref,
                    snapshot_ref)
            elif source_volid is not None:
                src_vref = self.db.volume_get(context, source_volid)
                model_update = self.driver.create_cloned_volume(volume_ref,
                                                                src_vref)
                self.db.volume_glance_metadata_copy_from_volume_to_volume(
                    context,
                    source_volid,
                    volume_id)
            else:
                # create the volume from an image
                image_service, image_id = \
                    glance.get_remote_image_service(context,
                                                    image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
                cloned = self.driver.clone_image(volume_ref, image_location)
                if not cloned:
                    model_update = self.driver.create_volume(volume_ref)
                    status = 'downloading'

            if model_update:
                volume_ref = self.db.volume_update(
                    context, volume_ref['id'], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(context,
                                                          volume_ref['id'],
                                                          snapshot_id)

        now = timeutils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': status,
                                                 'launched_at': now})
        LOG.debug(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        if image_id and not cloned:
            if image_meta:
                # Copy all of the Glance image properties to the
                # volume_glance_metadata table for future reference.
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      'image_id', image_id)
                name = image_meta.get('name', None)
                if name:
                    self.db.volume_glance_metadata_create(context,
                                                          volume_ref['id'],
                                                          'image_name', name)
                image_properties = image_meta.get('properties', {})
                for key, value in image_properties.items():
                    self.db.volume_glance_metadata_create(context,
                                                          volume_ref['id'],
                                                          key, value)

            # Copy the image onto the volume.
            self._copy_image_to_volume(context, volume_ref, image_id)
        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']
예제 #26
0
파일: manager.py 프로젝트: tek-life/cinder
    def create_volume(self, context, volume_id, snapshot_id=None,
                      image_id=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")
        LOG.info(_("volume %s: creating"), volume_ref['name'])

        self.db.volume_update(context,
                              volume_id,
                              {'host': self.host})
        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        status = 'available'
        model_update = False

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                    " size %(vol_size)sG") % locals())
            if snapshot_id is None and image_id is None:
                model_update = self.driver.create_volume(volume_ref)
            elif snapshot_id is not None:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(
                    volume_ref,
                    snapshot_ref)
            else:
                # create the volume from an image
                image_service, image_id = \
                               glance.get_remote_image_service(context,
                                                               image_id)
                image_location = image_service.get_location(context, image_id)
                cloned = self.driver.clone_image(volume_ref, image_location)
                if not cloned:
                    model_update = self.driver.create_volume(volume_ref)
                    status = 'downloading'

            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})

        now = timeutils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': status,
                                                 'launched_at': now})
        LOG.debug(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        if image_id and not cloned:
            #copy the image onto the volume.
            self._copy_image_to_volume(context, volume_ref, image_id)
        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']
예제 #27
0
    def create_volume(self, context, volume_id, request_spec=None,
                      filter_properties=None, allow_reschedule=True,
                      snapshot_id=None, image_id=None, source_volid=None):
        """Creates and exports the volume."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        status = 'available'
        model_update = False
        image_meta = None
        cloned = False

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                        " size %(vol_size)sG") % locals())
            snapshot_ref = None
            sourcevol_ref = None
            image_service = None
            image_location = None
            image_meta = None

            if snapshot_id is not None:
                LOG.info(_("volume %s: creating from snapshot"),
                         volume_ref['name'])
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
            elif source_volid is not None:
                LOG.info(_("volume %s: creating from existing volume"),
                         volume_ref['name'])
                sourcevol_ref = self.db.volume_get(context, source_volid)
            elif image_id is not None:
                LOG.info(_("volume %s: creating from image"),
                         volume_ref['name'])
                # create the volume from an image
                image_service, image_id = \
                    glance.get_remote_image_service(context,
                                                    image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
            else:
                LOG.info(_("volume %s: creating"), volume_ref['name'])

            try:
                model_update, cloned = self._create_volume(context,
                                                           volume_ref,
                                                           snapshot_ref,
                                                           sourcevol_ref,
                                                           image_service,
                                                           image_id,
                                                           image_location)
            except Exception:
                # restore source volume status before reschedule
                if sourcevol_ref is not None:
                    self.db.volume_update(context, sourcevol_ref['id'],
                                          {'status': sourcevol_ref['status']})
                exc_info = sys.exc_info()
                # try to re-schedule volume:
                self._reschedule_or_reraise(context, volume_id, exc_info,
                                            snapshot_id, image_id,
                                            request_spec, filter_properties,
                                            allow_reschedule)

            if model_update:
                volume_ref = self.db.volume_update(
                    context, volume_ref['id'], model_update)
            if sourcevol_ref is not None:
                self.db.volume_glance_metadata_copy_from_volume_to_volume(
                    context,
                    source_volid,
                    volume_id)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})
                LOG.error(_("volume %s: create failed"), volume_ref['name'])

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(context,
                                                          volume_ref['id'],
                                                          snapshot_id)

        if image_id and not cloned:
            if image_meta:
                # Copy all of the Glance image properties to the
                # volume_glance_metadata table for future reference.
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      'image_id', image_id)
                name = image_meta.get('name', None)
                if name:
                    self.db.volume_glance_metadata_create(context,
                                                          volume_ref['id'],
                                                          'image_name', name)
                image_properties = image_meta.get('properties', {})
                for key, value in image_properties.items():
                    self.db.volume_glance_metadata_create(context,
                                                          volume_ref['id'],
                                                          key, value)

        now = timeutils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': status,
                                                 'launched_at': now})
        LOG.info(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']
예제 #28
0
    def create_volume(self, context, volume_id, snapshot_id=None,
                      image_id=None, source_volid=None, **kwargs):
        context = context.elevated()
        volume = db.volume_get(context, volume_id)
        LOG.info(_("volume %s: creating"), volume['name'])
        model_update = {'host': 'lunr'}
        volume['host'] = 'lunr'
        try:
            # Try to get the volume type name, else use the default volume type
            volume_type_name = volume['volume_type']['name']
        except (KeyError, TypeError):
            volume_type_name = CONF.lunr_default_volume_type
            # Using the default volume type name,
            # ask the db for the volume type id
            vtype_id = self._get_volume_type_id(volume_type_name)
            model_update['volume_type_id'] = vtype_id
            volume['volume_type_id'] = vtype_id

        db.volume_update(context, volume['id'], model_update)

        params = {
            'name': volume['id'],
            'size': volume['size'],
            'volume_type_name': volume_type_name,
        }

        # Copy image to volume!
        if image_id:
            params['image_id'] = image_id
            image_service, image_id = glance.get_remote_image_service(context,
                                                                      image_id)
            image_meta = image_service.show(context, image_id)
            if image_meta:
                db.volume_glance_metadata_create(context, volume['id'],
                                                 'image_id', image_id)
                name = image_meta.get('name', None)
                if name:
                    db.volume_glance_metadata_create(context, volume['id'],
                                                     'image_name', name)
                image_properties = image_meta.get('properties', {})
                for key, value in image_properties.items():
                    db.volume_glance_metadata_create(context, volume['id'],
                                                     key, value)

        # If this is a snapshot request, add the backup param
        if snapshot_id:
            params['backup'] = snapshot_id
            snapshot_ref = db.snapshot_get(context, snapshot_id)
            original_vref = db.volume_get(context, snapshot_ref['volume_id'])
            if original_vref['bootable']:
                db.volume_glance_metadata_copy_to_volume(
                    context, volume_id, snapshot_id)
                db.volume_update(context, volume_id, {'bootable': True})

        # If this is a clone request, add the source_volume_id param
        if source_volid:
            params['source_volume'] = source_volid
            source_vref = db.volume_get(context, source_volid)
            if source_vref['bootable']:
                db.volume_glance_metadata_copy_from_volume_to_volume(
                    context, source_volid, volume_id)
                db.volume_update(context, volume_id, {'bootable': True})

        try:
            resp = LunrClient(volume, logger=LOG).volumes.create(
                volume['id'], **params)
        except LunrError, e:
            LOG.debug('error creating volume %s', volume['id'])
            # Don't leave an error'd volume around, the raise here
            # will notify the caller of the error (See Github Issue #343)
            # Also, in Havana, TaskFlow will revert the quota increase.
            db.volume_destroy(context, volume['id'])
            raise e
예제 #29
0
    def create_volume(self,
                      context,
                      volume_id,
                      request_spec=None,
                      filter_properties=None,
                      allow_reschedule=True,
                      snapshot_id=None,
                      image_id=None,
                      source_volid=None):
        """Creates and exports the volume."""
        context_saved = context.deepcopy()
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        if volume_ref['status'] == 'migration_target_creating':
            status = 'migration_target'
        else:
            status = 'available'
        model_update = False
        image_meta = None
        cloned = False

        try:
            LOG.debug(
                _("volume %(vol_name)s: creating lv of"
                  " size %(vol_size)sG"), {
                      'vol_name': volume_ref['name'],
                      'vol_size': volume_ref['size']
                  })
            snapshot_ref = None
            sourcevol_ref = None
            image_service = None
            image_location = None
            image_meta = None

            if snapshot_id is not None:
                LOG.info(_("volume %s: creating from snapshot"),
                         volume_ref['name'])
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
            elif source_volid is not None:
                LOG.info(_("volume %s: creating from existing volume"),
                         volume_ref['name'])
                sourcevol_ref = self.db.volume_get(context, source_volid)
            elif image_id is not None:
                LOG.info(_("volume %s: creating from image"),
                         volume_ref['name'])
                # create the volume from an image
                image_service, image_id = \
                    glance.get_remote_image_service(context,
                                                    image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
            else:
                LOG.info(_("volume %s: creating"), volume_ref['name'])

            try:
                model_update, cloned = self._create_volume(
                    context, volume_ref, snapshot_ref, sourcevol_ref,
                    image_service, image_id, image_location)
            except exception.ImageCopyFailure as ex:
                LOG.error(
                    _('Setting volume: %s status to error '
                      'after failed image copy.'), volume_ref['id'])
                self.db.volume_update(context, volume_ref['id'],
                                      {'status': 'error'})
                return
            except Exception:
                exc_info = sys.exc_info()
                # restore source volume status before reschedule
                # FIXME(zhiteng) do all the clean-up before reschedule
                if sourcevol_ref is not None:
                    self.db.volume_update(context, sourcevol_ref['id'],
                                          {'status': sourcevol_ref['status']})
                rescheduled = False
                # try to re-schedule volume:
                if allow_reschedule:
                    rescheduled = self._reschedule_or_error(
                        context_saved, volume_id, exc_info, snapshot_id,
                        image_id, request_spec, filter_properties)

                if rescheduled:
                    LOG.error(_('Unexpected Error: '), exc_info=exc_info)
                    msg = (_('Creating %(volume_id)s %(snapshot_id)s '
                             '%(image_id)s was rescheduled due to '
                             '%(reason)s') % {
                                 'volume_id': volume_id,
                                 'snapshot_id': snapshot_id,
                                 'image_id': image_id,
                                 'reason': unicode(exc_info[1])
                             })
                    raise exception.CinderException(msg)
                else:
                    # not re-scheduling
                    raise exc_info[0], exc_info[1], exc_info[2]

            if model_update:
                volume_ref = self.db.volume_update(context, volume_ref['id'],
                                                   model_update)
            if sourcevol_ref is not None:
                self.db.volume_glance_metadata_copy_from_volume_to_volume(
                    context, source_volid, volume_id)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)
        except Exception:
            with excutils.save_and_reraise_exception():
                volume_ref['status'] = 'error'
                self.db.volume_update(context, volume_ref['id'],
                                      {'status': volume_ref['status']})
                LOG.error(_("volume %s: create failed"), volume_ref['name'])
                self._notify_about_volume_usage(context, volume_ref,
                                                "create.end")

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(
                context, volume_ref['id'], snapshot_id)

        if image_id and image_meta:
            # Copy all of the Glance image properties to the
            # volume_glance_metadata table for future reference.
            self.db.volume_glance_metadata_create(context, volume_ref['id'],
                                                  'image_id', image_id)
            name = image_meta.get('name', None)
            if name:
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      'image_name', name)
            # Save some more attributes into the volume metadata
            IMAGE_ATTRIBUTES = [
                'size', 'disk_format', 'container_format', 'checksum',
                'min_disk', 'min_ram'
            ]
            for key in IMAGE_ATTRIBUTES:
                value = image_meta.get(key, None)
                if value is not None:
                    self.db.volume_glance_metadata_create(
                        context, volume_ref['id'], key, value)
            image_properties = image_meta.get('properties', {})
            for key, value in image_properties.items():
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'], key,
                                                      value)

        now = timeutils.utcnow()
        volume_ref['status'] = status
        self.db.volume_update(context, volume_ref['id'], {
            'status': volume_ref['status'],
            'launched_at': now
        })
        LOG.info(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']
예제 #30
0
    def create_volume(self,
                      context,
                      volume_id,
                      request_spec=None,
                      filter_properties=None,
                      allow_reschedule=True,
                      snapshot_id=None,
                      image_id=None,
                      source_volid=None):
        """Creates and exports the volume."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        status = 'available'
        model_update = False
        image_meta = None
        cloned = False

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(
                _("volume %(vol_name)s: creating lv of"
                  " size %(vol_size)sG") % locals())
            snapshot_ref = None
            sourcevol_ref = None
            image_service = None
            image_location = None
            image_meta = None

            if snapshot_id is not None:
                LOG.info(_("volume %s: creating from snapshot"),
                         volume_ref['name'])
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
            elif source_volid is not None:
                LOG.info(_("volume %s: creating from existing volume"),
                         volume_ref['name'])
                sourcevol_ref = self.db.volume_get(context, source_volid)
            elif image_id is not None:
                LOG.info(_("volume %s: creating from image"),
                         volume_ref['name'])
                # create the volume from an image
                image_service, image_id = \
                    glance.get_remote_image_service(context,
                                                    image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
            else:
                LOG.info(_("volume %s: creating"), volume_ref['name'])

            try:
                model_update, cloned = self._create_volume(
                    context, volume_ref, snapshot_ref, sourcevol_ref,
                    image_service, image_id, image_location)
            except Exception:
                # restore source volume status before reschedule
                if sourcevol_ref is not None:
                    self.db.volume_update(context, sourcevol_ref['id'],
                                          {'status': sourcevol_ref['status']})
                exc_info = sys.exc_info()
                # try to re-schedule volume:
                self._reschedule_or_reraise(context, volume_id, exc_info,
                                            snapshot_id, image_id,
                                            request_spec, filter_properties,
                                            allow_reschedule)
                return

            if model_update:
                volume_ref = self.db.volume_update(context, volume_ref['id'],
                                                   model_update)
            if sourcevol_ref is not None:
                self.db.volume_glance_metadata_copy_from_volume_to_volume(
                    context, source_volid, volume_id)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.volume_update(context, volume_ref['id'],
                                      {'status': 'error'})
                LOG.error(_("volume %s: create failed"), volume_ref['name'])

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(
                context, volume_ref['id'], snapshot_id)

        if image_id and not cloned:
            if image_meta:
                # Copy all of the Glance image properties to the
                # volume_glance_metadata table for future reference.
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      'image_id', image_id)
                name = image_meta.get('name', None)
                if name:
                    self.db.volume_glance_metadata_create(
                        context, volume_ref['id'], 'image_name', name)
                image_properties = image_meta.get('properties', {})
                for key, value in image_properties.items():
                    self.db.volume_glance_metadata_create(
                        context, volume_ref['id'], key, value)

        now = timeutils.utcnow()
        self.db.volume_update(context, volume_ref['id'], {
            'status': status,
            'launched_at': now
        })
        LOG.info(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']
예제 #31
0
파일: manager.py 프로젝트: akutz/cinder
    def create_volume(self, context, volume_id, request_spec=None,
                      filter_properties=None, allow_reschedule=True,
                      snapshot_id=None, image_id=None, source_volid=None):
        """Creates and exports the volume."""
        context_saved = context.deepcopy()
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}
        volume_ref = self.db.volume_get(context, volume_id)
        self._notify_about_volume_usage(context, volume_ref, "create.start")

        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        if volume_ref['status'] == 'migration_target_creating':
            status = 'migration_target'
        else:
            status = 'available'
        model_update = False
        image_meta = None
        cloned = False

        try:
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                        " size %(vol_size)sG"),
                      {'vol_name': volume_ref['name'],
                       'vol_size': volume_ref['size']})
            snapshot_ref = None
            sourcevol_ref = None
            image_service = None
            image_location = None
            image_meta = None

            if snapshot_id is not None:
                LOG.info(_("volume %s: creating from snapshot"),
                         volume_ref['name'])
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
            elif source_volid is not None:
                LOG.info(_("volume %s: creating from existing volume"),
                         volume_ref['name'])
                sourcevol_ref = self.db.volume_get(context, source_volid)
            elif image_id is not None:
                LOG.info(_("volume %s: creating from image"),
                         volume_ref['name'])
                # create the volume from an image
                image_service, image_id = \
                    glance.get_remote_image_service(context,
                                                    image_id)
                image_location = image_service.get_location(context, image_id)
                image_meta = image_service.show(context, image_id)
            else:
                LOG.info(_("volume %s: creating"), volume_ref['name'])

            try:
                model_update, cloned = self._create_volume(context,
                                                           volume_ref,
                                                           snapshot_ref,
                                                           sourcevol_ref,
                                                           image_service,
                                                           image_id,
                                                           image_location)
            except exception.ImageCopyFailure as ex:
                LOG.error(_('Setting volume: %s status to error '
                            'after failed image copy.'), volume_ref['id'])
                self.db.volume_update(context,
                                      volume_ref['id'],
                                      {'status': 'error'})
                return
            except Exception:
                exc_info = sys.exc_info()
                # restore source volume status before reschedule
                # FIXME(zhiteng) do all the clean-up before reschedule
                if sourcevol_ref is not None:
                    self.db.volume_update(context, sourcevol_ref['id'],
                                          {'status': sourcevol_ref['status']})
                rescheduled = False
                # try to re-schedule volume:
                if allow_reschedule:
                    rescheduled = self._reschedule_or_error(context_saved,
                                                            volume_id,
                                                            exc_info,
                                                            snapshot_id,
                                                            image_id,
                                                            request_spec,
                                                            filter_properties)

                if rescheduled:
                    # log the original build error
                    self._log_original_error(exc_info)
                    msg = (_('Creating %(volume_id)s %(snapshot_id)s '
                             '%(image_id)s was rescheduled due to '
                             '%(reason)s')
                           % {'volume_id': volume_id,
                              'snapshot_id': snapshot_id,
                              'image_id': image_id,
                              'reason': unicode(exc_info[1])})
                    raise exception.CinderException(msg)
                else:
                    # not re-scheduling
                    raise exc_info[0], exc_info[1], exc_info[2]

            if model_update:
                volume_ref = self.db.volume_update(
                    context, volume_ref['id'], model_update)
            if sourcevol_ref is not None:
                self.db.volume_glance_metadata_copy_from_volume_to_volume(
                    context,
                    source_volid,
                    volume_id)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)
        except Exception:
            with excutils.save_and_reraise_exception():
                volume_ref['status'] = 'error'
                self.db.volume_update(context,
                                      volume_ref['id'],
                                      {'status': volume_ref['status']})
                LOG.error(_("volume %s: create failed"), volume_ref['name'])
                self._notify_about_volume_usage(context, volume_ref,
                                                "create.end")

        if snapshot_id:
            # Copy any Glance metadata from the original volume
            self.db.volume_glance_metadata_copy_to_volume(context,
                                                          volume_ref['id'],
                                                          snapshot_id)

        if image_id and image_meta:
            # Copy all of the Glance image properties to the
            # volume_glance_metadata table for future reference.
            self.db.volume_glance_metadata_create(context,
                                                  volume_ref['id'],
                                                  'image_id', image_id)
            name = image_meta.get('name', None)
            if name:
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      'image_name', name)
            # Save some more attributes into the volume metadata
            IMAGE_ATTRIBUTES = ['size', 'disk_format',
                                'container_format', 'checksum',
                                'min_disk', 'min_ram']
            for key in IMAGE_ATTRIBUTES:
                value = image_meta.get(key, None)
                if value is not None:
                    self.db.volume_glance_metadata_create(context,
                                                          volume_ref['id'],
                                                          key, value)
            image_properties = image_meta.get('properties', {})
            for key, value in image_properties.items():
                self.db.volume_glance_metadata_create(context,
                                                      volume_ref['id'],
                                                      key, value)

        now = timeutils.utcnow()
        volume_ref['status'] = status
        self.db.volume_update(context,
                              volume_ref['id'],
                              {'status': volume_ref['status'],
                               'launched_at': now})
        LOG.info(_("volume %s: created successfully"), volume_ref['name'])
        self._reset_stats()

        self._notify_about_volume_usage(context, volume_ref, "create.end")
        return volume_ref['id']