def _get_snapshot_metadata(self, virt_dom, context, instance, snapshot_id):
        _image_service = glance.get_remote_image_service(context, snapshot_id)
        snapshot_image_service, snapshot_image_id = _image_service
        snapshot = snapshot_image_service.show(context, snapshot_image_id)
        metadata = {'is_public': True,
                    'status': 'active',
                    'name': snapshot['name'],
                    'properties': {
                        'kernel_id': instance['kernel_id'],
                        'image_location': 'snapshot',
                        'image_state': 'available',
                        'owner_id': instance['project_id'],
                        'ramdisk_id': instance['ramdisk_id'],
                        }
                    }

        (image_service, image_id) = glance.get_remote_image_service(
            context, instance['image_ref'])
        try:
            base = image_service.show(context, image_id)
        except exception.ImageNotFound:
            base = {}

        if 'architecture' in base.get('properties', {}):
            arch = base['properties']['architecture']
            metadata['properties']['architecture'] = arch

        metadata['disk_format'] = 'raw'
        metadata['container_format'] = base.get('container_format', 'bare')
        return metadata
Пример #2
0
    def _handle_kernel_and_ramdisk(context, kernel_id, ramdisk_id,
                                   image):
        """Choose kernel and ramdisk appropriate for the instance.

        The kernel and ramdisk can be chosen in one of three ways:
            1. Passed in with create-instance request.
            2. Inherited from image.
            3. Forced to None by using `null_kernel` FLAG.
        """
        # Inherit from image if not specified
        image_properties = image.get('properties', {})

        if kernel_id is None:
            kernel_id = image_properties.get('kernel_id')

        if ramdisk_id is None:
            ramdisk_id = image_properties.get('ramdisk_id')

        # Force to None if using null_kernel
        if kernel_id == str(CONF.null_kernel):
            kernel_id = None
            ramdisk_id = None

        # Verify kernel and ramdisk exist (fail-fast)
        if kernel_id is not None:
            image_service, kernel_id = glance.get_remote_image_service(
                context, kernel_id)
            image_service.show(context, kernel_id)

        if ramdisk_id is not None:
            image_service, ramdisk_id = glance.get_remote_image_service(
                context, ramdisk_id)
            image_service.show(context, ramdisk_id)

        return kernel_id, ramdisk_id
    def _get_snapshot_metadata(self, virt_dom, context, instance, snapshot_id):
        _image_service = glance.get_remote_image_service(context, snapshot_id)
        snapshot_image_service, snapshot_image_id = _image_service
        snapshot = snapshot_image_service.show(context, snapshot_image_id)
        metadata = {
            "is_public": True,
            "status": "active",
            "name": snapshot["name"],
            "properties": {
                "kernel_id": instance["kernel_id"],
                "image_location": "snapshot",
                "image_state": "available",
                "owner_id": instance["project_id"],
                "ramdisk_id": instance["ramdisk_id"],
            },
        }

        (image_service, image_id) = glance.get_remote_image_service(context, instance["image_ref"])
        try:
            base = image_service.show(context, image_id)
        except exception.ImageNotFound:
            base = {}

        if "architecture" in base.get("properties", {}):
            arch = base["properties"]["architecture"]
            metadata["properties"]["architecture"] = arch

        metadata["disk_format"] = "raw"
        metadata["container_format"] = base.get("container_format", "bare")
        return metadata
Пример #4
0
    def test_start(self):
        consumer = glance.UpdateGlanceImage("context", "id", "metadata", "stream")
        image_service = self.mox.CreateMock(glance.GlanceImageService)

        self.mox.StubOutWithMock(glance, "get_remote_image_service")

        glance.get_remote_image_service("context", "id").AndReturn((image_service, "image_id"))
        image_service.update("context", "image_id", "metadata", "stream", purge_props=False)

        self.mox.ReplayAll()

        consumer.start()
    def create_overlay_vm(self, context, instance,
                          overlay_name, overlay_id, update_task_state):
        try:
            if hasattr(self, "_lookup_by_name"):
                # icehouse
                virt_dom = self._lookup_by_name(instance['name'])
            else:
                # kilo
                virt_dom = self._host.get_domain(instance)
        except exception.InstanceNotFound:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])

        # make sure base vm is cached
        (image_service, image_id) = glance.get_remote_image_service(
            context, instance['image_ref'])
        image_meta = image_service.show(context, image_id)
        base_sha256_uuid, memory_snap_id, diskhash_snap_id, memhash_snap_id = \
            self._get_basevm_meta_info(image_meta)
        self._get_cache_image(context, instance, image_meta['id'])
        self._get_cache_image(context, instance, memory_snap_id)
        self._get_cache_image(context, instance, diskhash_snap_id)
        self._get_cache_image(context, instance, memhash_snap_id)

        # pause VM
        self.pause(instance)

        # create VM overlay
        (image_service, image_id) = glance.get_remote_image_service(
            context, instance['image_ref'])
        meta_metadata = self._get_snapshot_metadata(virt_dom, context,
                                                    instance, overlay_id)
        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD,
                          expected_state=None)

        vm_overlay = self.resumed_vm_dict.get(instance['uuid'], None)
        if vm_overlay is None:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])
        del self.resumed_vm_dict[instance['uuid']]
        vm_overlay.create_overlay()
        overlay_zip = vm_overlay.overlay_zipfile
        LOG.info("overlay : %s" % str(overlay_zip))

        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                          expected_state=task_states.IMAGE_PENDING_UPLOAD)

        # export to glance
        self._update_to_glance(context, image_service, overlay_zip,
                               overlay_id, meta_metadata)
        LOG.info(_("overlay_vm upload complete"), instance=instance)

        if os.path.exists(overlay_zip):
            os.remove(overlay_zip)
Пример #6
0
    def test_start(self):
        consumer = glance.UpdateGlanceImage(
            'context', 'id', 'metadata', 'stream')
        image_service = self.mox.CreateMock(glance.GlanceImageService)

        self.mox.StubOutWithMock(glance, 'get_remote_image_service')

        glance.get_remote_image_service(
            'context', 'id').AndReturn((image_service, 'image_id'))
        image_service.update(
            'context', 'image_id', 'metadata', 'stream', purge_props=False)

        self.mox.ReplayAll()

        consumer.start()
Пример #7
0
    def _get_image(self, context, image_id):
        if not image_id:
            return None

        (image_service, image_id) = glance.get_remote_image_service(context,
                image_id)
        return image_service.show(context, image_id)
Пример #8
0
def upload_image(context, image, instance, **kwargs):
    """Upload the snapshotted vm disk file to Glance image server."""
    LOG.debug(_("Uploading image %s to the Glance image server") % image,
              instance=instance)
    read_file_handle = read_write_util.VmWareHTTPReadFile(
                                kwargs.get("host"),
                                kwargs.get("data_center_name"),
                                kwargs.get("datastore_name"),
                                kwargs.get("cookies"),
                                kwargs.get("file_path"))
    file_size = read_file_handle.get_size()
    (image_service, image_id) = glance.get_remote_image_service(context, image)
    # The properties and other fields that we need to set for the image.
    image_metadata = {"is_public": True,
                      "disk_format": "vmdk",
                      "container_format": "bare",
                      "type": "vmdk",
                      "properties": {"vmware_adaptertype":
                                            kwargs.get("adapter_type"),
                                     "vmware_ostype": kwargs.get("os_type"),
                                     "vmware_image_version":
                                            kwargs.get("image_version")}}
    start_transfer(context, read_file_handle, file_size,
                   image_service=image_service,
                   image_id=image_id, image_meta=image_metadata)
    LOG.debug(_("Uploaded image %s to the Glance image server") % image,
              instance=instance)
Пример #9
0
def get_test_image_info(context, instance_ref):
    if not context:
        context = get_test_admin_context()

    image_ref = instance_ref["image_ref"]
    image_service, image_id = glance.get_remote_image_service(context, image_ref)
    return image_service.show(context, image_id)
Пример #10
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.host, "something-less-likely")
Пример #11
0
    def create_image_from_volume(self, device_name, context, image_id, image_meta):
        """Capture the contents of a volume and upload to glance

        :param device_name: device in /dev/ to capture
        :param context: nova context for operation
        :param image_id: image reference to pre-created image in glance
        :param image_meta: metadata for new image
        """

        # do the disk copy
        dest_file_path = common.aix_path_join(CONF.powervm_img_remote_path, image_id)
        self._copy_device_to_file(device_name, dest_file_path)

        # compress and copy the file back to the nova-compute host
        snapshot_file_path = self._copy_image_file_from_host(dest_file_path, CONF.powervm_img_local_path, compress=True)

        # get glance service
        glance_service, image_id = glance.get_remote_image_service(context, image_id)

        # upload snapshot file to glance
        with open(snapshot_file_path, "r") as img_file:
            glance_service.update(context, image_id, image_meta, img_file)
            LOG.debug(_("Snapshot added to glance."))

        # clean up local image file
        try:
            os.remove(snapshot_file_path)
        except OSError as ose:
            LOG.warn(_("Failed to clean up snapshot file " "%(snapshot_file_path)s") % locals())
Пример #12
0
    def _snapshot_ve(self, context, instance, image_id, update_task_state, ve):
        def upload(context, image_service, image_id, metadata, f):
            LOG.info("Start uploading image %s ..." % image_id)
            image_service.update(context, image_id, metadata, f)
            LOG.info("Image %s uploading complete." % image_id)

        _image_service = glance.get_remote_image_service(context, image_id)
        snapshot_image_service, snapshot_image_id = _image_service
        snapshot = snapshot_image_service.show(context, snapshot_image_id)
        disk_format = CONF.pcs_snapshot_disk_format

        metadata = {'is_public': False,
                    'status': 'active',
                    'name': snapshot['name'],
                    'container_format': 'bare',
                    'disk_format': disk_format,
        }

        props = {}
        metadata['properties'] = props

        if ve.get_vm_type() == pc.PVT_VM:
            props['vm_mode'] = 'hvm'
        else:
            props['vm_mode'] = 'exe'

        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                    expected_state=task_states.IMAGE_PENDING_UPLOAD)

        hdd = pcsutils.get_boot_disk(ve)
        hdd_path = hdd.get_image_path()

        props['pcs_ostemplate'] = ve.get_os_template()
        if disk_format == 'ploop':
            xml_path = os.path.join(hdd_path, "DiskDescriptor.xml")
            cmd = ['ploop', 'snapshot-list', '-H', '-o', 'fname', xml_path]
            out, err = utils.execute(*cmd, run_as_root=True)
            image_path = out.strip()

            with open(xml_path) as f:
                props['pcs_disk_descriptor'] = f.read().replace('\n', '')

            with open(image_path) as f:
                upload(context, snapshot_image_service, image_id, metadata, f)
        elif disk_format == 'cploop':
            uploader = pcsutils.CPloopUploader(hdd_path)
            f = uploader.start()
            try:
                upload(context, snapshot_image_service, image_id, metadata, f)
            finally:
                uploader.wait()
        else:
            dst = tempfile.mktemp(dir=os.path.dirname(hdd_path))
            LOG.info("Convert image %s to %s format ..." %
                     (image_id, disk_format))
            pcsutils.convert_image(hdd_path, dst, disk_format,
                                   root_helper=utils._get_root_helper())
            with open(dst) as f:
                upload(context, snapshot_image_service, image_id, metadata, f)
            os.unlink(dst)
Пример #13
0
def fetch_image(context, instance, host, dc_name, ds_name, file_path,
                cookies=None):
    """Download image from the glance image server."""
    image_ref = instance['image_ref']
    LOG.debug("Downloading image file data %(image_ref)s to the "
              "data store %(data_store_name)s",
              {'image_ref': image_ref,
               'data_store_name': ds_name},
              instance=instance)

    (image_service, image_id) = glance.get_remote_image_service(context,
                                                                image_ref)
    metadata = image_service.show(context, image_id)
    file_size = int(metadata['size'])
    read_iter = image_service.download(context, image_id)
    read_file_handle = read_write_util.GlanceFileRead(read_iter)
    write_file_handle = read_write_util.VMwareHTTPWriteFile(
        host, dc_name, ds_name, cookies, file_path, file_size)
    start_transfer(context, read_file_handle, file_size,
                   write_file_handle=write_file_handle)
    LOG.debug("Downloaded image file data %(image_ref)s to "
              "%(upload_name)s on the data store "
              "%(data_store_name)s",
              {'image_ref': image_ref,
               'upload_name': 'n/a' if file_path is None else file_path,
               'data_store_name': 'n/a' if ds_name is None else ds_name},
              instance=instance)
Пример #14
0
    def apply(self, context, resource, **kwargs):

        if resource.image_href:
            (image_service, image_id) = glance.get_remote_image_service(
                                                 context, resource.image_href)
            resource.image = jsonutils.to_primitive(image_service.show(
                                                                    context,
                                                                    image_id))
            if resource.image['status'] != 'active':
                raise exception.ImageNotActive(image_id=image_id)
        else:
            resource.image = {}

        if resource.instance_type['memory_mb'] < int(
                                           resource.image.get('min_ram') or 0):
            raise exception.InstanceTypeMemoryTooSmall()
        if resource.instance_type['root_gb'] < int(
                                          resource.image.get('min_disk') or 0):
            raise exception.InstanceTypeDiskTooSmall()

        resource.kernel_id, resource.ramdisk_id = \
                                       self._handle_kernel_and_ramdisk(context,
                                                           resource.kernel_id,
                                                           resource.ramdisk_id,
                                                           resource.image)

        return orc_utils.DictableObject(details='image_validated',
                                        resource=resource)
Пример #15
0
 def get_by_image_id(cls, image_id):
     (image_service, image_id) = glance.get_remote_image_service(
             context, image_id)
     image_meta = image_service.show(context, image_id)
     obj = cls()
     obj.from_image_props(image_meta.get('properties', {}))
     return obj
Пример #16
0
    def _retrieve_and_inject_jar_in_container(self, context, container_id, jar_image_id, jar_image_path, jar_image_name):
        (image_service, image_id) = glance.get_remote_image_service(
            context, jar_image_id)
        try:
            image_service.show(context, image_id)
        except exception.ImageNotFound:
            LOG.audit("Sorry jar image does not found")
            #Here I can re-raise the exception to avoid creation of instance without jar file
            return
        #Now I obtain the absolute path where copy jar image inside container
        LOG.audit('Container ID: "%s"', container_id['Id'])
        info = self.docker.inspect_container(container_id)
        if not info:
            LOG.audit("Container does not exist")
            return
        rel_path = "/var/lib/docker/aufs/mnt/{0}".format(info['Id'])
        abs_path = rel_path + jar_image_path + "/" + jar_image_name
        LOG.audit('The absolute path of file to inject in this container is: "%s"', abs_path)
        p_dir = os.path.dirname(abs_path)
        LOG.audit('The absolute path is: "%s"', p_dir)
        utils.execute('mkdir', '-p', p_dir, run_as_root=True)
        LOG.audit('Path created')

	#Now i can download image and save it in the path create (inside the container)
        image_chunks = image_service.download(context, jar_image_id)
        for chunk in image_chunks:
            self._write_file(abs_path, chunk)
        LOG.audit("Injection success")
Пример #17
0
 def _save_glance_image(self, context, image_id, image_vhd_path):
     (glance_image_service,
      image_id) = glance.get_remote_image_service(context, image_id)
     image_metadata = {"disk_format": "vhd",
                       "container_format": "bare"}
     with self._pathutils.open(image_vhd_path, 'rb') as f:
         glance_image_service.update(context, image_id, image_metadata, f,
                                     purge_props=False)
Пример #18
0
def fetch(context, image_href, path, _user_id, _project_id, max_size=0):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    (image_service, image_id) = glance.get_remote_image_service(context, image_href)
    with fileutils.remove_path_on_error(path):
        image_service.download(context, image_id, dst_path=path)
    def perform_vmhandoff(self, context, instance, handoff_url, update_task_state, residue_glance_id=None):
        try:
            if hasattr(self, "_lookup_by_name"):
                # icehouse
                virt_dom = self._lookup_by_name(instance["name"])
            else:
                # kilo
                virt_dom = self._host.get_domain(instance)
        except exception.InstanceNotFound:
            raise exception.InstanceNotRunning(instance_id=instance["uuid"])
        synthesized_vm = self.synthesized_vm_dics.get(instance["uuid"], None)
        if synthesized_vm is None:
            raise exception.InstanceNotRunning(instance_id=instance["uuid"])

        # get the file path for Base VM and VM overlay
        (image_service, image_id) = glance.get_remote_image_service(context, instance["image_ref"])
        image_meta = image_service.show(context, image_id)
        base_sha256_uuid, memory_snap_id, diskhash_snap_id, memhash_snap_id = self._get_basevm_meta_info(image_meta)
        basedisk_path = self._get_cache_image(context, instance, image_meta["id"])
        basemem_path = self._get_cache_image(context, instance, memory_snap_id)
        diskhash_path = self._get_cache_image(context, instance, diskhash_snap_id)
        memhash_path = self._get_cache_image(context, instance, memhash_snap_id)
        base_vm_paths = [basedisk_path, basemem_path, diskhash_path, memhash_path]

        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD, expected_state=None)
        try:
            residue_filepath = self._handoff_send(base_vm_paths, base_sha256_uuid, synthesized_vm, handoff_url)
        except handoff.HandoffError as e:
            msg = "failed to perform VM handoff:\n"
            msg += str(e)
            raise exception.ImageNotFound(msg)

        del self.synthesized_vm_dics[instance["uuid"]]
        if residue_filepath:
            LOG.info("residue saved at %s" % residue_filepath)
        if residue_filepath and residue_glance_id:
            # export to glance
            (image_service, image_id) = glance.get_remote_image_service(context, instance["image_ref"])
            meta_metadata = self._get_snapshot_metadata(virt_dom, context, instance, residue_glance_id)
            update_task_state(task_state=task_states.IMAGE_UPLOADING, expected_state=task_states.IMAGE_PENDING_UPLOAD)
            self._update_to_glance(context, image_service, residue_filepath, residue_glance_id, meta_metadata)
        # clean up
        LOG.info(_("VM residue upload complete"), instance=instance)
        if residue_filepath and os.path.exists(residue_filepath):
            os.remove(residue_filepath)
Пример #20
0
 def _save_glance_image(self, context, image_id, image_vhd_path):
     (glance_image_service,
      image_id) = glance.get_remote_image_service(context, image_id)
     image_metadata = {"is_public": False,
                       "disk_format": "vhd",
                       "container_format": "bare",
                       "properties": {}}
     with self._pathutils.open(image_vhd_path, 'rb') as f:
         glance_image_service.update(context, image_id, image_metadata, f)
Пример #21
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')
Пример #22
0
def get_test_image_object(context, instance_ref):
    if not context:
        context = get_test_admin_context()

    image_ref = instance_ref['image_ref']
    image_service, image_id = glance.get_remote_image_service(context,
                                                              image_ref)
    return objects.ImageMeta.from_dict(
        image_service.show(context, image_id))
Пример #23
0
 def test_get_remote_service_from_href(self, gcwi_mocked):
     id_or_uri = 'http://127.0.0.1/123'
     _ignored, image_id = glance.get_remote_image_service(
             mock.sentinel.ctx, id_or_uri)
     self.assertEqual('123', image_id)
     gcwi_mocked.assert_called_once_with(context=mock.sentinel.ctx,
                                         host='127.0.0.1',
                                         port=80,
                                         use_ssl=False)
Пример #24
0
    def create_volume(self, context, volume_id, snapshot_id=None, image_id=None, reservations=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()
        volume_ref = 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()
        self._notify_about_volume_usage(context, volume_ref, "create.end")

        if image_id and not cloned:
            # copy the image onto the volume.
            self._copy_image_to_volume(context, volume_ref, image_id)
        return volume_id
Пример #25
0
def fetch(context, image_href, path, _user_id, _project_id):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    (image_service, image_id) = glance.get_remote_image_service(context,
                                                                image_href)
    with utils.remove_path_on_error(path):
        with open(path, "wb") as image_file:
            metadata = image_service.get(context, image_id, image_file)
            return metadata
Пример #26
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)
Пример #27
0
 def _fetch_image(self, context, image_id, image_meta, path,
                  user_id=None, project_id=None, location=None,
                  **kwargs):
     # TODO(vish): Improve context handling and add owner and auth data
     #             when it is added to glance.  Right now there is no
     #             auth checking in glance, so we assume that access was
     #             checked before we got here.
     (image_service, _image_id) = glance.get_remote_image_service(context,
                                                                  image_id)
     with fileutils.remove_path_on_error(path):
         image_service.download(context, image_id, dst_path=path)
     return os.path.exists(path)
Пример #28
0
    def _get_image_size_glance(self, context, image_href):
        (image_service, image_id) = glance.get_remote_image_service(
            context, image_href)

        try:
            image_meta = image_service.show(context, image_href)
        except nova_exception.ImageNotFound:
            image_meta = {}
            return 0

        size_byte = image_meta['size']
        return float(size_byte) / 1024 / 1024 / 1024
Пример #29
0
    def _get_session_and_image_id(self, context, id_or_uri):
        """Returns a tuple of (session, image_id). If the supplied `id_or_uri`
        is an image ID, then the default client session will be returned
        for the context's user, along with the image ID. If the supplied
        `id_or_uri` parameter is a URI, then a client session connecting to
        the URI's image service endpoint will be returned along with a
        parsed image ID from that URI.

        :param context: The `nova.context.Context` object for the request
        :param id_or_uri: A UUID identifier or an image URI to look up image
                          information for.
        """
        return glance.get_remote_image_service(context, id_or_uri)
Пример #30
0
def fetch_image(context, target, image_id, user_id, project_id, max_size=0):
    """Grab image."""
    path_dir = os.path.dirname(target)
    
    (image_service, image_id) = glance.get_remote_image_service(context, image_id)
    image = image_service.show(context, image_id)
    parent_id = image.get('parent_id', None)
    
    if parent_id is None:
        images.fetch_to_raw(context, image_id, target, user_id, project_id,
                             max_size, False)
    else:
        images.fetch_with_backing_file(context, image_id, target, path_dir, user_id, project_id, max_size)
Пример #31
0
 def _delete_image(self, context, image_id):
     (image_service,
      image_id) = glance.get_remote_image_service(context, image_id)
     return image_service.delete(context, image_id)
Пример #32
0
    def snapshot(self, context, instance, image_id, update_task_state):
        """Create snapshot from a running VM instance.

        :param context: security context
        :param instance: nova.objects.instance.Instance
        :param image_id: Reference to a pre-created image that will
                         hold the snapshot.
        :param update_task_state: Callback function to update the task_state
            on the instance while the snapshot operation progresses. The
            function takes a task_state argument and an optional
            expected_task_state kwarg which defaults to
            nova.compute.task_states.IMAGE_SNAPSHOT. See
            nova.objects.instance.Instance.save for expected_task_state usage.
        """

        # Check the image status
        (image_service,
         image_id) = glance.get_remote_image_service(context, image_id)

        # Update the instance task_state to image_pending_upload
        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)

        # Call zvmsdk guest_capture to generate the image
        try:
            self._reqh.call('guest_capture', instance['name'], image_id)
        except Exception as err:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed to capture the instance %(instance)s "
                            "to generate an image with reason: %(err)s"), {
                                'instance': instance['name'],
                                'err': err
                            },
                          instance=instance)
                # Clean up the image from glance
                image_service.delete(context, image_id)

        # Export the image to nova-compute server temporary
        image_path = os.path.join(os.path.normpath(CONF.zvm_image_tmp_path),
                                  image_id)
        dest_path = "file://" + image_path
        try:
            resp = self._reqh.call('image_export',
                                   image_id,
                                   dest_path,
                                   remote_host=self._get_host())
        except Exception as err:
            LOG.error(
                _("Failed to export image %s from SDK server to nova "
                  "compute server") % image_id)
            self._reqh.call('image_delete', image_id)
        # Save image to glance
        new_image_meta = {
            'is_public': False,
            'status': 'active',
            'properties': {
                'image_location': 'snapshot',
                'image_state': 'available',
                'owner_id': instance['project_id'],
                'os_distro': resp['os_version'],
                'architecture': const.ARCHITECTURE,
                'hypervisor_type': const.HYPERVISOR_TYPE
            },
            'disk_format': 'raw',
            'container_format': 'bare',
        }

        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                          expected_state=task_states.IMAGE_PENDING_UPLOAD)
        # Save the image to glance
        try:
            with open(image_path, 'r') as image_file:
                image_service.update(context,
                                     image_id,
                                     new_image_meta,
                                     image_file,
                                     purge_props=False)
        except Exception:
            with excutils.save_and_reraise_exception():
                image_service.delete(context, image_id)
        finally:
            self._pathutils.clean_up_file(image_path)
            self._reqh.call('image_delete', image_id)
        LOG.debug("Snapshot image upload complete", instance=instance)
Пример #33
0
    def snapshot(self, context, instance, name):
        """Create snapshot from a running VM instance."""
        instance_name = instance["name"]
        vm = self._vmutils.lookup(self._conn, instance_name)
        if vm is None:
            raise exception.InstanceNotFound(instance=instance_name)
        vm = self._conn.Msvm_ComputerSystem(ElementName=instance_name)[0]
        vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]

        LOG.debug(_("Creating snapshot for instance %s"), instance_name)
        (job_path, ret_val, snap_setting_data) = \
            vs_man_svc.CreateVirtualSystemSnapshot(vm.path_())
        if ret_val == constants.WMI_JOB_STATUS_STARTED:
            success = self._vmutils.check_job_status(job_path)
            if success:
                job_wmi_path = job_path.replace('\\', '/')
                job = wmi.WMI(moniker=job_wmi_path)
                snap_setting_data = job.associators(
                    wmi_result_class='Msvm_VirtualSystemSettingData')[0]
        else:
            success = (ret_val == 0)
        if not success:
            raise vmutils.HyperVException(
                _('Failed to create snapshot for VM %s') % instance_name)

        export_folder = None
        f = None

        try:
            src_vhd_path = os.path.join(FLAGS.instances_path, instance_name,
                                        instance_name + ".vhd")

            image_man_svc = self._conn.Msvm_ImageManagementService()[0]

            LOG.debug(_("Getting info for VHD %s"), src_vhd_path)
            (src_vhd_info, job_path, ret_val) = \
                image_man_svc.GetVirtualHardDiskInfo(src_vhd_path)
            if ret_val == constants.WMI_JOB_STATUS_STARTED:
                success = self._vmutils.check_job_status(job_path)
            else:
                success = (ret_val == 0)
            if not success:
                raise vmutils.HyperVException(
                    _("Failed to get info for disk %s") % (src_vhd_path))

            src_base_disk_path = None
            et = ElementTree.fromstring(src_vhd_info)
            for item in et.findall("PROPERTY"):
                if item.attrib["NAME"] == "ParentPath":
                    src_base_disk_path = item.find("VALUE").text
                    break

            export_folder = self._vmutils.make_export_path(instance_name)

            dest_vhd_path = os.path.join(export_folder,
                                         os.path.basename(src_vhd_path))
            LOG.debug(_('Copying VHD %(src_vhd_path)s to %(dest_vhd_path)s'),
                      locals())
            shutil.copyfile(src_vhd_path, dest_vhd_path)

            image_vhd_path = None
            if not src_base_disk_path:
                image_vhd_path = dest_vhd_path
            else:
                dest_base_disk_path = os.path.join(
                    export_folder, os.path.basename(src_base_disk_path))
                LOG.debug(
                    _('Copying base disk %(src_vhd_path)s to '
                      '%(dest_base_disk_path)s'), locals())
                shutil.copyfile(src_base_disk_path, dest_base_disk_path)

                LOG.debug(
                    _("Reconnecting copied base VHD "
                      "%(dest_base_disk_path)s and diff VHD %(dest_vhd_path)s"
                      ), locals())
                (job_path, ret_val) = \
                    image_man_svc.ReconnectParentVirtualHardDisk(
                        ChildPath=dest_vhd_path,
                        ParentPath=dest_base_disk_path,
                        Force=True)
                if ret_val == constants.WMI_JOB_STATUS_STARTED:
                    success = self._vmutils.check_job_status(job_path)
                else:
                    success = (ret_val == 0)
                if not success:
                    raise vmutils.HyperVException(
                        _("Failed to reconnect base disk "
                          "%(dest_base_disk_path)s and diff disk "
                          "%(dest_vhd_path)s") % locals())

                LOG.debug(
                    _("Merging base disk %(dest_base_disk_path)s and "
                      "diff disk %(dest_vhd_path)s"), locals())
                (job_path, ret_val) = image_man_svc.MergeVirtualHardDisk(
                    SourcePath=dest_vhd_path,
                    DestinationPath=dest_base_disk_path)
                if ret_val == constants.WMI_JOB_STATUS_STARTED:
                    success = self._vmutils.check_job_status(job_path)
                else:
                    success = (ret_val == 0)
                if not success:
                    raise vmutils.HyperVException(
                        _("Failed to merge base disk %(dest_base_disk_path)s "
                          "and diff disk %(dest_vhd_path)s") % locals())
                image_vhd_path = dest_base_disk_path

            (glance_image_service, image_id) = \
                glance.get_remote_image_service(context, name)
            image_metadata = {
                "is_public": False,
                "disk_format": "vhd",
                "container_format": "bare",
                "properties": {}
            }
            f = ioutils.open(image_vhd_path, 'rb')
            LOG.debug(
                _("Updating Glance image %(image_id)s with content from "
                  "merged disk %(image_vhd_path)s"), locals())
            glance_image_service.update(context, image_id, image_metadata, f)

            LOG.debug(
                _("Snapshot image %(image_id)s updated for VM "
                  "%(instance_name)s"), locals())
        finally:
            LOG.debug(_("Removing snapshot %s"), name)
            (job_path, ret_val) = vs_man_svc.RemoveVirtualSystemSnapshot(
                snap_setting_data.path_())
            if ret_val == constants.WMI_JOB_STATUS_STARTED:
                success = self._vmutils.check_job_status(job_path)
            else:
                success = (ret_val == 0)
            if not success:
                raise vmutils.HyperVException(
                    _('Failed to remove snapshot for VM %s') % instance_name)
            if f:
                f.close()
            if export_folder:
                LOG.debug(_('Removing folder %s '), export_folder)
                shutil.rmtree(export_folder)
Пример #34
0
    def perform_vmhandoff(self,
                          context,
                          instance,
                          handoff_url,
                          update_task_state,
                          residue_glance_id=None):
        try:
            if hasattr(self, "_lookup_by_name"):
                # icehouse
                virt_dom = self._lookup_by_name(instance['name'])
            else:
                # kilo
                virt_dom = self._host.get_domain(instance)
        except exception.InstanceNotFound:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])
        synthesized_vm = self.synthesized_vm_dics.get(instance['uuid'], None)
        if synthesized_vm is None:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])

        # get the file path for Base VM and VM overlay
        (image_service,
         image_id) = glance.get_remote_image_service(context,
                                                     instance['image_ref'])
        image_meta = image_service.show(context, image_id)
        base_sha256_uuid, memory_snap_id, diskhash_snap_id, memhash_snap_id = \
            self._get_basevm_meta_info(image_meta)
        basedisk_path = self._get_cache_image(context, instance,
                                              image_meta['id'])
        basemem_path = self._get_cache_image(context, instance, memory_snap_id)
        diskhash_path = self._get_cache_image(context, instance,
                                              diskhash_snap_id)
        memhash_path = self._get_cache_image(context, instance,
                                             memhash_snap_id)
        base_vm_paths = [
            basedisk_path, basemem_path, diskhash_path, memhash_path
        ]

        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD,
                          expected_state=None)
        try:
            residue_filepath = self._handoff_send(base_vm_paths,
                                                  base_sha256_uuid,
                                                  synthesized_vm, handoff_url)
        except handoff.HandoffError as e:
            msg = "failed to perform VM handoff:\n"
            msg += str(e)
            raise exception.ImageNotFound(msg)

        del self.synthesized_vm_dics[instance['uuid']]
        if residue_filepath:
            LOG.info("residue saved at %s" % residue_filepath)
        if residue_filepath and residue_glance_id:
            # export to glance
            (image_service, image_id) = glance.get_remote_image_service(
                context, instance['image_ref'])
            meta_metadata = self._get_snapshot_metadata(
                virt_dom, context, instance, residue_glance_id)
            update_task_state(task_state=task_states.IMAGE_UPLOADING,
                              expected_state=task_states.IMAGE_PENDING_UPLOAD)
            self._update_to_glance(context, image_service, residue_filepath,
                                   residue_glance_id, meta_metadata)
        # clean up
        LOG.info(_("VM residue upload complete"), instance=instance)
        if residue_filepath and os.path.exists(residue_filepath):
            os.remove(residue_filepath)
Пример #35
0
    def cloudlet_base(self, context, instance, vm_name, disk_meta_id,
                      memory_meta_id, diskhash_meta_id, memoryhash_meta_id,
                      update_task_state):
        """create base vm and save it to glance
        """
        try:
            if hasattr(self, "_lookup_by_name"):
                # icehouse
                virt_dom = self._lookup_by_name(instance['name'])
            else:
                # kilo
                virt_dom = self._host.get_domain(instance)
        except exception.InstanceNotFound:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])

        # pause VM
        self.pause(instance)

        (image_service,
         image_id) = glance.get_remote_image_service(context,
                                                     instance['image_ref'])

        disk_metadata = self._get_snapshot_metadata(virt_dom, context,
                                                    instance, disk_meta_id)
        mem_metadata = self._get_snapshot_metadata(virt_dom, context, instance,
                                                   memory_meta_id)
        diskhash_metadata = self._get_snapshot_metadata(
            virt_dom, context, instance, diskhash_meta_id)
        memhash_metadata = self._get_snapshot_metadata(virt_dom, context,
                                                       instance,
                                                       memoryhash_meta_id)

        disk_path = libvirt_utils.find_disk(virt_dom)
        source_format = libvirt_utils.get_disk_type(disk_path)
        snapshot_name = uuid.uuid4().hex
        (state, _max_mem, _mem, _cpus, _t) = virt_dom.info()
        state = libvirt_driver.LIBVIRT_POWER_STATE[state]

        # creating base vm requires cold snapshotting
        snapshot_backend = self.image_backend.snapshot(
            disk_path, image_type=source_format)

        LOG.info(_("Beginning cold snapshot process"), instance=instance)
        # not available at icehouse
        # snapshot_backend.snapshot_create()

        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD,
                          expected_state=None)
        snapshot_directory = libvirt_driver.CONF.libvirt.snapshots_directory
        fileutils.ensure_tree(snapshot_directory)
        with utils.tempdir(dir=snapshot_directory) as tmpdir:
            try:
                out_path = os.path.join(tmpdir, snapshot_name)
                # At this point, base vm should be "raw" format
                snapshot_backend.snapshot_extract(out_path, "raw")
            finally:
                # snapshotting logic is changed since icehouse.
                #  : cannot find snapshot_create and snapshot_delete.
                # snapshot_extract is replacing these two operations.
                # snapshot_backend.snapshot_delete()
                LOG.info(_("Snapshot extracted, beginning image upload"),
                         instance=instance)

            # generate memory snapshop and hashlist
            basemem_path = os.path.join(tmpdir, snapshot_name + "-mem")
            diskhash_path = os.path.join(tmpdir, snapshot_name + "-disk_hash")
            memhash_path = os.path.join(tmpdir, snapshot_name + "-mem_hash")

            update_task_state(task_state=task_states.IMAGE_UPLOADING,
                              expected_state=task_states.IMAGE_PENDING_UPLOAD)
            synthesis._create_baseVM(self._conn,
                                     virt_dom,
                                     out_path,
                                     basemem_path,
                                     diskhash_path,
                                     memhash_path,
                                     nova_util=libvirt_utils)

            self._update_to_glance(context, image_service, out_path,
                                   disk_meta_id, disk_metadata)
            LOG.info(_("Base disk upload complete"), instance=instance)
            self._update_to_glance(context, image_service, basemem_path,
                                   memory_meta_id, mem_metadata)
            LOG.info(_("Base memory image upload complete"), instance=instance)
            self._update_to_glance(context, image_service, diskhash_path,
                                   diskhash_meta_id, diskhash_metadata)
            LOG.info(_("Base disk upload complete"), instance=instance)
            self._update_to_glance(context, image_service, memhash_path,
                                   memoryhash_meta_id, memhash_metadata)
            LOG.info(_("Base memory image upload complete"), instance=instance)
Пример #36
0
    def snapshot(self, context, instance, image_id, update_task_state):

        (image_service,
         image_id) = glance.get_remote_image_service(context, image_id)

        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)

        try:
            self._hypervisor.guest_capture(instance.name, image_id)
        except Exception as err:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    "Failed to capture the instance "
                    "to generate an image with reason: %(err)s", {'err': err},
                    instance=instance)
                # Clean up the image from glance
                image_service.delete(context, image_id)

        # Export the image to nova-compute server temporary
        image_path = os.path.join(os.path.normpath(CONF.zvm.image_tmp_path),
                                  image_id)
        dest_path = "file://" + image_path
        try:
            resp = self._hypervisor.image_export(image_id, dest_path)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    "Failed to export image %s from SDK server to "
                    "nova compute server", image_id)
                image_service.delete(context, image_id)
                self._hypervisor.image_delete(image_id)

        # Save image to glance
        new_image_meta = {
            'status': 'active',
            'properties': {
                'image_location': 'snapshot',
                'image_state': 'available',
                'owner_id': instance['project_id'],
                'os_distro': resp['os_version'],
                'architecture': obj_fields.Architecture.S390X,
                'hypervisor_type': obj_fields.HVType.ZVM,
            },
            'disk_format': 'raw',
            'container_format': 'bare',
        }
        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                          expected_state=task_states.IMAGE_PENDING_UPLOAD)

        # Save the image to glance
        try:
            with open(image_path, 'r') as image_file:
                image_service.update(context,
                                     image_id,
                                     new_image_meta,
                                     image_file,
                                     purge_props=False)
        except Exception:
            with excutils.save_and_reraise_exception():
                image_service.delete(context, image_id)
        finally:
            zvmutils.clean_up_file(image_path)
            self._hypervisor.image_delete(image_id)

        LOG.debug("Snapshot image upload complete", instance=instance)
Пример #37
0
 def test_get_remote_service_from_id(self, gcwi_mocked):
     id_or_uri = '123'
     _ignored, image_id = glance.get_remote_image_service(
             mock.sentinel.ctx, id_or_uri)
     self.assertEqual(id_or_uri, image_id)
     gcwi_mocked.assert_called_once_with()
Пример #38
0
    def setUp(self, mock_register):
        super(ConfigDriveTestCase, self).setUp()
        vm_util.vm_refs_cache_reset()
        self.context = context.RequestContext('fake', 'fake', is_admin=False)
        self.flags(cluster_name='test_cluster',
                   host_ip='test_url',
                   host_username='******',
                   host_password='******',
                   use_linked_clone=False, group='vmware')
        self.flags(enabled=False, group='vnc')
        vmwareapi_fake.reset()
        stubs.set_stubs(self.stubs)
        nova.tests.unit.image.fake.stub_out_image_service(self.stubs)
        self.conn = driver.VMwareVCDriver(fake.FakeVirtAPI)
        self.network_info = utils.get_test_network_info()
        self.node_name = self.conn._nodename
        image_ref = nova.tests.unit.image.fake.get_valid_image_id()
        instance_values = {
            'vm_state': 'building',
            'project_id': 'fake',
            'user_id': 'fake',
            'name': '1',
            'kernel_id': '1',
            'ramdisk_id': '1',
            'mac_addresses': [{'address': 'de:ad:be:ef:be:ef'}],
            'memory_mb': 8192,
            'flavor': objects.Flavor(vcpus=4, extra_specs={}),
            'instance_type_id': 0,
            'vcpus': 4,
            'root_gb': 80,
            'image_ref': image_ref,
            'host': 'fake_host',
            'task_state': 'scheduling',
            'reservation_id': 'r-3t8muvr0',
            'id': 1,
            'uuid': 'fake-uuid',
            'node': self.node_name,
            'metadata': [],
            'expected_attrs': ['system_metadata'],
        }
        self.test_instance = fake_instance.fake_instance_obj(self.context,
                                                             **instance_values)
        self.test_instance.flavor = objects.Flavor(vcpus=4, memory_mb=8192,
                                                   ephemeral_gb=0, swap=0,
                                                   extra_specs={})

        (image_service, image_id) = glance.get_remote_image_service(context,
                                    image_ref)
        metadata = image_service.show(context, image_id)
        self.image = {
            'id': image_ref,
            'disk_format': 'vmdk',
            'size': int(metadata['size']),
        }

        class FakeInstanceMetadata(object):
            def __init__(self, instance, content=None, extra_md=None,
                         network_info=None):
                pass

            def metadata_for_config_drive(self):
                return []

        self.useFixture(fixtures.MonkeyPatch(
                'nova.api.metadata.base.InstanceMetadata',
                FakeInstanceMetadata))

        def fake_make_drive(_self, _path):
            pass
        # We can't actually make a config drive v2 because ensure_tree has
        # been faked out
        self.stubs.Set(nova.virt.configdrive.ConfigDriveBuilder,
                       'make_drive', fake_make_drive)

        def fake_upload_iso_to_datastore(iso_path, instance, **kwargs):
            pass
        self.stubs.Set(images,
                       'upload_iso_to_datastore',
                       fake_upload_iso_to_datastore)
Пример #39
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)