Ejemplo n.º 1
0
    def test_create_image_with_metadata(self):
        body = {"createImage": {"name": "Snapshot 1", "metadata": {"key": "asdf"}}}

        response = self.controller._action_create_image(self.req, FAKE_UUID, body=body)

        location = response.headers["Location"]
        self.assertEqual(self.image_url + "123" if self.image_url else glance.generate_image_url("123"), location)
Ejemplo n.º 2
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ["nova.context"]
        authorize(context, action="create_image")

        entity = body["createImage"]
        image_name = entity["name"]
        metadata = entity.get("metadata", {})

        common.check_img_metadata_properties_quota(context, metadata)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(context, instance, bdms):
                authorize(context, action="create_image:allow_volume_backed")
                image = self.compute_api.snapshot_volume_backed(
                    context, instance, image_name, extra_properties=metadata
                )
            else:
                image = self.compute_api.snapshot(context, instance, image_name, extra_properties=metadata)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error, "createImage", id)
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image["id"])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers["Location"] = image_ref
        return resp
Ejemplo n.º 3
0
 def _get_bookmark_link(self, request, identifier, collection_name):
     """Create a URL that refers to a specific resource."""
     if collection_name == "images":
         glance_url = glance.generate_image_url(identifier)
         return self._update_glance_link_prefix(glance_url)
     else:
         raise NotImplementedError
Ejemplo n.º 4
0
 def _get_bookmark_link(self, request, identifier, collection_name):
     """Create a URL that refers to a specific resource."""
     if collection_name == "images":
         glance_url = glance.generate_image_url(identifier)
         return self._update_glance_link_prefix(glance_url)
     else:
         raise NotImplementedError
    def snapshot(self, context, instance, image_id, update_task_state):
        """Snapshots the specified 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.
        """
        return
        config = self.load_config()

        azure_sms = self.get_management_service(ServiceManagementService,
                                                config=config)

        # Power off vm
        result = self.power_off(instance=instance)
        result.wait()

        hosted_service_name = 'compunovacloud'
        deployment_name = 'dep1'
        vm_name = 'vm1'
        image_name = instance.uuid + 'image'

        image = CaptureRoleAsVMImage('Specialized', image_name,
                                     image_name + 'label',
                                     image_name + 'description', 'english',
                                     'openstack-virtual-machines')

        result = azure_sms.capture_vm_image(hosted_service_name,
                                            deployment_name, vm_name, image)

        image_service = glance.get_default_image_service()

        snapshot = image_service.show(context, image_id)
        LOG.debug("**** Snapshot info--> %s" % snapshot)
        snapshot_name = haikunator.haikunate()
        image_url = glance.generate_image_url(image_id)
        LOG.debug("**** image url--> '%s' ****" % image_url)

        image_metadata = {
            'is_public': False,
            'status': 'active',
            'name': '-'.join(('azure', snapshot_name)),
            'properties': {
                'kernel_id': instance['kernel_id'],
                'image_location': 'snapshot',
                'image_state': 'available',
                'ramdisk_id': instance['ramdisk_id'],
                'owner_id': instance['project_id']
            }
        }
        if instance['os_type']:
            image_metadata['properties']['os_type'] = instance['os_type']

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

        azure_sms.snapshot(service_name, vm_name, image_id, snapshot_name)
        image_service.update(context, image_id, image_metadata,
                             "fake image data")
Ejemplo n.º 6
0
    def test_create_image_with_metadata(self):
        body = {"create_image": {"name": "Snapshot 1", "metadata": {"key": "asdf"}}}

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers["Location"]
        self.assertEqual(glance.generate_image_url("123"), location)
Ejemplo n.º 7
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['nova.context']
        authorize(context, action='create_image')

        entity = body["createImage"]
        image_name = entity["name"]
        metadata = entity.get('metadata', {})

        common.check_img_metadata_properties_quota(context, metadata)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                    context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(context, instance,
                                                          bdms):
                authorize(context, action="create_image:allow_volume_backed")
                img = instance.image_ref
                if not img:
                    properties = bdms.root_metadata(
                            context, self.compute_api.image_api,
                            self.compute_api.volume_api)
                    image_meta = {'properties': properties}
                else:
                    image_meta = self.compute_api.image_api.get(context, img)

                image = self.compute_api.snapshot_volume_backed(
                                                       context,
                                                       instance,
                                                       image_meta,
                                                       image_name,
                                                       extra_properties=
                                                       metadata)
            else:
                image = self.compute_api.snapshot(context,
                                                  instance,
                                                  image_name,
                                                  extra_properties=metadata)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                        'createImage', id)
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image['id'])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers['Location'] = image_ref
        return resp
Ejemplo n.º 8
0
    def test_create_image(self):
        body = {
            'create_image': {
                'name': 'Snapshot 1',
            },
        }

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers['Location']
        self.assertEqual(glance.generate_image_url('123'), location)
Ejemplo n.º 9
0
    def test_create_image(self):
        body = {
            'createImage': {
                'name': 'Snapshot 1',
            },
        }

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers['Location']
        self.assertEqual(glance.generate_image_url('123'), location)
Ejemplo n.º 10
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['nova.context']

        entity = body["createImage"]
        image_name = entity["name"]
        metadata = entity.get('metadata', {})

        common.check_img_metadata_properties_quota(context, metadata)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                    context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(context, instance,
                                                          bdms):
                img = instance['image_ref']
                if not img:
                    properties = bdms.root_metadata(
                            context, self.compute_api.image_api,
                            self.compute_api.volume_api)
                    image_meta = {'properties': properties}
                else:
                    image_meta = self.compute_api.image_api.get(context, img)

                image = self.compute_api.snapshot_volume_backed(
                                                       context,
                                                       instance,
                                                       image_meta,
                                                       image_name,
                                                       extra_properties=
                                                       metadata)
            else:
                image = self.compute_api.snapshot(context,
                                                  instance,
                                                  image_name,
                                                  extra_properties=metadata)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                        'createImage', id)
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image['id'])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers['Location'] = image_ref
        return resp
Ejemplo n.º 11
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ["nova.context"]
        entity = body.get("create_image", {})

        image_name = entity.get("name")

        if not image_name:
            msg = _("create_image entity requires name attribute")
            raise exc.HTTPBadRequest(explanation=msg)

        props = {}
        metadata = entity.get("metadata", {})
        common.check_img_metadata_properties_quota(context, metadata)
        try:
            props.update(metadata)
        except ValueError:
            msg = _("Invalid metadata")
            raise exc.HTTPBadRequest(explanation=msg)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(context, instance, bdms):
                img = instance["image_ref"]
                if not img:
                    properties = bdms.root_metadata(context, self.compute_api.image_api, self.compute_api.volume_api)
                    image_meta = {"properties": properties}
                else:
                    image_meta = self.compute_api.image_api.get(context, img)

                image = self.compute_api.snapshot_volume_backed(
                    context, instance, image_meta, image_name, extra_properties=props
                )
            else:
                image = self.compute_api.snapshot(context, instance, image_name, extra_properties=props)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error, "create_image")
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image["id"])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers["Location"] = image_ref
        return resp
Ejemplo n.º 12
0
    def snapshot(self, context, instance, image_id, update_task_state):
        """Snapshot an image of the specified instance on EC2 and create an
        Image which gets stored in AMI (internally in EBS Snapshot)

        :param context: security context
        :param instance: nova.objects.instance.Instance
        :param image_id: Reference to a pre-created image that will hold the
        snapshot.
        """
        if instance.metadata.get('ec2_id', None) is None:
            raise exception.InstanceNotFound(instance_id=instance['uuid'])
        # Adding the below line only alters the state of the instance and not
        # its image in OpenStack.
        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                          expected_state=task_states.IMAGE_SNAPSHOT)
        ec2_id = self._get_ec2_id_from_instance(instance)
        ec_instance_info = self.ec2_conn.get_only_instances(
            instance_ids=[ec2_id],
            filters=None,
            dry_run=False,
            max_results=None)
        ec2_instance = ec_instance_info[0]
        if ec2_instance.state == 'running':
            ec2_image_id = ec2_instance.create_image(
                name=str(image_id),
                description="Image created by OpenStack",
                no_reboot=False,
                dry_run=False)
            LOG.info("Image created: %s." % ec2_image_id)
        # The instance will be in pending state when it comes up, waiting
        # for it to be in available
        self._wait_for_image_state(ec2_image_id, "available")

        image_api = glance.get_default_image_service()
        image_ref = glance.generate_image_url(image_id)

        metadata = {
            'is_public': False,
            'location': image_ref,
            'properties': {
                'kernel_id': instance['kernel_id'],
                'image_state': 'available',
                'owner_id': instance['project_id'],
                'ramdisk_id': instance['ramdisk_id'],
                'ec2_image_id': ec2_image_id
            }
        }
        # TODO(jhurt): This currently fails, leaving the status of an instance
        #              as 'snapshotting'
        image_api.update(context, image_id, metadata)
Ejemplo n.º 13
0
    def test_create_image(self):
        body = {
            'createImage': {
                'name': 'Snapshot 1',
            },
        }

        response = self.controller._action_create_image(self.req, FAKE_UUID,
                                                        body=body)

        location = response.headers['Location']
        self.assertEqual(self.image_url + '123' if self.image_url else
                         glance.generate_image_url('123'),
                         location)
Ejemplo n.º 14
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['nova.context']
        context.can(server_policies.SERVERS % 'create_image')

        entity = body["createImage"]
        image_name = common.normalize_name(entity["name"])
        metadata = entity.get('metadata', {})

        common.check_img_metadata_properties_quota(context, metadata)

        instance = self._get_server(context, req, id)

        bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
                    context, instance.uuid)

        try:
            if compute_utils.is_volume_backed_instance(context, instance,
                                                          bdms):
                context.can(server_policies.SERVERS %
                    'create_image:allow_volume_backed')
                image = self.compute_api.snapshot_volume_backed(
                                                       context,
                                                       instance,
                                                       image_name,
                                                       extra_properties=
                                                       metadata)
            else:
                image = self.compute_api.snapshot(context,
                                                  instance,
                                                  image_name,
                                                  extra_properties=metadata)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                        'createImage', id)
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image['id'])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers['Location'] = image_ref
        return resp
Ejemplo n.º 15
0
    def snapshot(self, context, instance, image_id, update_task_state):
        """Snapshot an image of the specified instance
        on EC2 and create an Image which gets stored in AMI (internally in EBS Snapshot)
        :param context: security context
        :param instance: nova.objects.instance.Instance
        :param image_id: Reference to a pre-created image that will hold the snapshot.
        """
        LOG.info("***** Calling SNAPSHOT *******************")

        if instance['metadata']['ec2_id'] is None:
            raise exception.InstanceNotRunning(instance_id=instance['uuid'])

        # Adding the below line only alters the state of the instance and not
        # its image in OpenStack.
        update_task_state(
            task_state=task_states.IMAGE_UPLOADING, expected_state=task_states.IMAGE_SNAPSHOT)
        ec2_id = instance['metadata']['ec2_id']
        ec_instance_info = self.ec2_conn.get_only_instances(
            instance_ids=[ec2_id], filters=None, dry_run=False, max_results=None)
        ec2_instance = ec_instance_info[0]
        if ec2_instance.state == 'running':
            ec2_image_id = ec2_instance.create_image(name=str(
                image_id), description="Image from OpenStack", no_reboot=False, dry_run=False)
            LOG.info("Image has been created state to %s." % ec2_image_id)

        # The instance will be in pending state when it comes up, waiting forit to be in available
        self._wait_for_image_state(ec2_image_id, "available")

        image_api = glance.get_default_image_service()
        image_ref = glance.generate_image_url(image_id)

        metadata = {'is_public': False,
                    'location': image_ref,
                    'properties': {
                        'kernel_id': instance['kernel_id'],
                        'image_state': 'available',
                        'owner_id': instance['project_id'],
                        'ramdisk_id': instance['ramdisk_id'],
                        'ec2_image_id': ec2_image_id }
                    }
        image_api.update(context, image_id, metadata)
    def snapshot(self, context, instance, image_id, update_task_state):
        aws_node = self._get_node_by_uuid(instance.uuid)

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

        if aws_node.state['Name'] == 'running':
            ec2_image = aws_node.create_image(
                Name=str(image_id),
                Description="Image from OpenStack",
                NoReboot=False,
                DryRun=False)
        else:
            # TODO: else case
            LOG.error(
                'Node state: "{}". Must be "running" for snapshot.'.format(
                    aws_node.state['Name']))
            return
        # The instance will be in pending state when it comes up, waiting for it to be in available
        self._wait_for_image_state(ec2_image, "available")

        image_api = glance.get_default_image_service()
        image_ref = glance.generate_image_url(image_id)

        metadata = {
            'is_public': False,
            'location': image_ref,
            'properties': {
                'kernel_id': instance['kernel_id'],
                'image_state': 'available',
                'owner_id': instance['project_id'],
                'ramdisk_id': instance['ramdisk_id'],
                'ec2_image_id': ec2_image.id
            }
        }
        # TODO: HTTPInternalServerError: 500 Internal Server Error:
        # TODO: The server has either erred or is incapable of performing the requested operation.
        image_api.update(context, image_id, metadata)
Ejemplo n.º 17
0
def info_from_instance(context, instance, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:instance: nova.objects.Instance
    :param:network_info: network_info provided if not None
    :param:system_metadata: system_metadata DB entries for the instance,
    if not None

    .. note::

        Currently unused here in trunk, but needed for potential custom
        modifications.

    """

    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_int(s):
        return int(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance.image_ref)

    instance_type = instance.get_flavor()
    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    instance_info = dict(
        # Owner properties
        tenant_id=instance.project_id,
        user_id=instance.user_id,

        # Identity properties
        instance_id=instance.uuid,
        display_name=instance.display_name,
        reservation_id=instance.reservation_id,
        hostname=instance.hostname,

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance.instance_type_id,
        instance_flavor_id=instance_flavorid,
        architecture=instance.architecture,

        # Capacity properties
        memory_mb=instance.memory_mb,
        disk_gb=instance.root_gb + instance.ephemeral_gb,
        vcpus=instance.vcpus,
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance.root_gb,
        ephemeral_gb=instance.ephemeral_gb,

        # Location properties
        host=instance.host,
        node=instance.node,
        availability_zone=instance.availability_zone,
        cell_name=null_safe_str(instance.cell_name),

        # Date properties
        created_at=str(instance.created_at),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance.get('terminated_at', None)),
        deleted_at=null_safe_isotime(instance.get('deleted_at', None)),
        launched_at=null_safe_isotime(instance.get('launched_at', None)),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance.os_type,
        kernel_id=instance.kernel_id,
        ramdisk_id=instance.ramdisk_id,

        # Status properties
        state=instance.vm_state,
        state_description=null_safe_str(instance.task_state),
        progress=null_safe_int(instance.progress),

        # accessIPs
        access_ip_v4=instance.access_ip_v4,
        access_ip_v6=instance.access_ip_v6,
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(instance.system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance.metadata

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 18
0
    def _do_test_create_volume_backed_image(self, extra_properties):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['createImage']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id('a'),
                    volume_size=1,
                    device_name='vda',
                    delete_on_termination=False)]
        props = dict(kernel_id=_fake_id('b'),
                     ramdisk_id=_fake_id('c'),
                     root_device_name='/dev/vda',
                     block_device_mapping=bdm)
        original_image = dict(properties=props,
                              container_format='ami',
                              status='active',
                              is_public=True)

        image_service.create(None, original_image)

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
                       fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_instance_get(image_ref=original_image['id'],
                                           vm_state=vm_states.ACTIVE,
                                           root_device_name='/dev/vda')
        self.stubs.Set(db, 'instance_get_by_uuid', instance)

        self.mox.StubOutWithMock(self.controller.compute_api.compute_rpcapi,
                                 'quiesce_instance')
        self.controller.compute_api.compute_rpcapi.quiesce_instance(
            mox.IgnoreArg(), mox.IgnoreArg()).AndRaise(
                exception.InstanceQuiesceNotSupported(instance_id='fake',
                                                      reason='test'))

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')
        snapshot = dict(id=_fake_id('d'))
        self.mox.StubOutWithMock(self.controller.compute_api, 'volume_api')
        volume_api = self.controller.compute_api.volume_api
        volume_api.get(mox.IgnoreArg(), volume['id']).AndReturn(volume)
        volume_api.create_snapshot_force(mox.IgnoreArg(), volume['id'],
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(snapshot)

        self.mox.ReplayAll()

        response = self.controller._action_create_image(self.req, FAKE_UUID,
                                                        body=body)

        location = response.headers['Location']
        image_id = location.replace(self.image_url or
                                        glance.generate_image_url(''), '')
        image = image_service.show(None, image_id)

        self.assertEqual(image['name'], 'snapshot_of_volume_backed')
        properties = image['properties']
        self.assertEqual(properties['kernel_id'], _fake_id('b'))
        self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
        self.assertEqual(properties['root_device_name'], '/dev/vda')
        self.assertEqual(properties['bdm_v2'], True)
        bdms = properties['block_device_mapping']
        self.assertEqual(len(bdms), 1)
        self.assertEqual(bdms[0]['boot_index'], 0)
        self.assertEqual(bdms[0]['source_type'], 'snapshot')
        self.assertEqual(bdms[0]['destination_type'], 'volume')
        self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
        for fld in ('connection_info', 'id',
                    'instance_uuid', 'device_name'):
            self.assertNotIn(fld, bdms[0])
        for k in extra_properties.keys():
            self.assertEqual(properties[k], extra_properties[k])
Ejemplo n.º 19
0
def info_from_instance(context, instance_ref, network_info, system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """

    def null_safe_str(s):
        return str(s) if s else ""

    image_ref_url = glance.generate_image_url(instance_ref["image_ref"])

    instance_type_name = instance_ref.get("instance_type", {}).get("name", "")

    if system_metadata is None:
        system_metadata = utils.metadata_to_dict(instance_ref["system_metadata"])

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref["project_id"],
        user_id=instance_ref["user_id"],
        # Identity properties
        instance_id=instance_ref["uuid"],
        display_name=instance_ref["display_name"],
        reservation_id=instance_ref["reservation_id"],
        hostname=instance_ref["hostname"],
        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref["instance_type_id"],
        architecture=instance_ref["architecture"],
        # Capacity properties
        memory_mb=instance_ref["memory_mb"],
        disk_gb=instance_ref["root_gb"] + instance_ref["ephemeral_gb"],
        vcpus=instance_ref["vcpus"],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref["root_gb"],
        ephemeral_gb=instance_ref["ephemeral_gb"],
        # Location properties
        host=instance_ref["host"],
        availability_zone=instance_ref["availability_zone"],
        # Date properties
        created_at=str(instance_ref["created_at"]),
        # Nova's deleted vs terminated instance terminology is confusing,
        # this should be when the instance was deleted (i.e. terminated_at),
        # not when the db record was deleted. (mdragon)
        deleted_at=null_safe_str(instance_ref.get("terminated_at")),
        launched_at=null_safe_str(instance_ref.get("launched_at")),
        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref["os_type"],
        kernel_id=instance_ref["kernel_id"],
        ramdisk_id=instance_ref["ramdisk_id"],
        # Status properties
        state=instance_ref["vm_state"],
        state_description=null_safe_str(instance_ref.get("task_state")),
        # accessIPs
        access_ip_v4=instance_ref["access_ip_v4"],
        access_ip_v6=instance_ref["access_ip_v6"],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info["fixed_ips"] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info["metadata"] = instance_ref["metadata"]

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 20
0
def info_from_instance(context, instance, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:instance: nova.objects.Instance
    :param:network_info: network_info provided if not None
    :param:system_metadata: system_metadata DB entries for the instance,
    if not None

    .. note::

        Currently unused here in trunk, but needed for potential custom
        modifications.

    """
    image_ref_url = glance.generate_image_url(instance.image_ref)

    instance_type = instance.get_flavor()
    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    instance_info = dict(
        # Owner properties
        tenant_id=instance.project_id,
        user_id=instance.user_id,

        # Identity properties
        instance_id=instance.uuid,
        display_name=instance.display_name,
        reservation_id=instance.reservation_id,
        hostname=instance.hostname,

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance.instance_type_id,
        instance_flavor_id=instance_flavorid,
        architecture=instance.architecture,

        # Capacity properties
        memory_mb=instance.flavor.memory_mb,
        disk_gb=instance.flavor.root_gb + instance.flavor.ephemeral_gb,
        vcpus=instance.flavor.vcpus,
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance.flavor.root_gb,
        ephemeral_gb=instance.flavor.ephemeral_gb,

        # Location properties
        host=instance.host,
        node=instance.node,
        availability_zone=instance.availability_zone,
        cell_name=null_safe_str(instance.cell_name),

        # Date properties
        created_at=str(instance.created_at),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance.get('terminated_at', None)),
        deleted_at=null_safe_isotime(instance.get('deleted_at', None)),
        launched_at=null_safe_isotime(instance.get('launched_at', None)),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance.os_type,
        kernel_id=instance.kernel_id,
        ramdisk_id=instance.ramdisk_id,

        # Status properties
        state=instance.vm_state,
        state_description=null_safe_str(instance.task_state),
        # NOTE(gibi): It might seems wrong to default the progress to an empty
        # string but this is how legacy work and this code only used by the
        # legacy notification so try to keep the compatibility here but also
        # keep it contained.
        progress=int(instance.progress) if instance.progress else '',

        # accessIPs
        access_ip_v4=instance.access_ip_v4,
        access_ip_v6=instance.access_ip_v6,
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(instance.system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance.metadata

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 21
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['nova.context']
        entity = body.get("create_image", {})

        image_name = entity.get("name")

        if not image_name:
            msg = _("create_image entity requires name attribute")
            raise exc.HTTPBadRequest(explanation=msg)

        props = {}
        metadata = entity.get('metadata', {})
        common.check_img_metadata_properties_quota(context, metadata)
        try:
            props.update(metadata)
        except ValueError:
            msg = _("Invalid metadata")
            raise exc.HTTPBadRequest(explanation=msg)

        instance = self._get_server(context, req, id)

        bdms = block_device_obj.BlockDeviceMappingList.get_by_instance_uuid(
            context, instance.uuid)

        try:
            if self.compute_api.is_volume_backed_instance(
                    context, instance, bdms):
                img = instance['image_ref']
                if not img:
                    props = bdms.root_metadata(context,
                                               self.compute_api.image_service,
                                               self.compute_api.volume_api)
                    image_meta = {'properties': props}
                else:
                    src_image = self.compute_api.\
                        image_service.show(context, img)
                    image_meta = dict(src_image)

                image = self.compute_api.snapshot_volume_backed(
                    context,
                    instance,
                    image_meta,
                    image_name,
                    extra_properties=props)
            else:
                image = self.compute_api.snapshot(context,
                                                  instance,
                                                  image_name,
                                                  extra_properties=props)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'create_image')
        except exception.Invalid as err:
            raise exc.HTTPBadRequest(explanation=err.format_message())

        # build location of newly-created image entity
        image_id = str(image['id'])
        image_ref = glance.generate_image_url(image_id)

        resp = webob.Response(status_int=202)
        resp.headers['Location'] = image_ref
        return resp
Ejemplo n.º 22
0
def info_from_instance(context, instance_ref, network_info, system_metadata,
                       **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """
    def null_safe_str(s):
        return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type = instance_types.extract_instance_type(instance_ref)
    instance_type_name = instance_type.get('name', '')

    if system_metadata is None:
        system_metadata = utils.metadata_to_dict(
            instance_ref['system_metadata'])

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Nova's deleted vs terminated instance terminology is confusing,
        # this should be when the instance was deleted (i.e. terminated_at),
        # not when the db record was deleted. (mdragon)
        deleted_at=null_safe_str(instance_ref.get('terminated_at')),
        launched_at=null_safe_str(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance_ref['metadata']

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 23
0
    def _do_test_create_volume_backed_image(
            self, extra_properties, mock_vol_create_side_effect=None):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['createImage']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id('a'),
                    volume_size=1,
                    device_name='vda',
                    delete_on_termination=False)]

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stub_out('nova.db.block_device_mapping_get_all_by_instance',
                      fake_block_device_mapping_get_all_by_instance)

        system_metadata = dict(image_kernel_id=_fake_id('b'),
                               image_ramdisk_id=_fake_id('c'),
                               image_root_device_name='/dev/vda',
                               image_block_device_mapping=str(bdm),
                               image_container_format='ami')
        instance = fakes.fake_instance_get(image_ref=uuids.fake,
                                           vm_state=vm_states.ACTIVE,
                                           root_device_name='/dev/vda',
                                           system_metadata=system_metadata)
        self.stub_out('nova.db.instance_get_by_uuid', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')

        snapshot = dict(id=_fake_id('d'))

        with test.nested(
            mock.patch.object(self.controller.compute_api.compute_rpcapi,
                'quiesce_instance',
                side_effect=exception.InstanceQuiesceNotSupported(
                    instance_id='fake', reason='test')),
            mock.patch.object(self.controller.compute_api.volume_api, 'get',
                              return_value=volume),
            mock.patch.object(self.controller.compute_api.volume_api,
                              'create_snapshot_force',
                              return_value=snapshot),
        ) as (mock_quiesce, mock_vol_get, mock_vol_create):

            if mock_vol_create_side_effect:
                mock_vol_create.side_effect = mock_vol_create_side_effect

            response = self.controller._action_create_image(self.req,
                FAKE_UUID, body=body)

            location = response.headers['Location']
            image_id = location.replace(self.image_url or
                                        glance.generate_image_url(''), '')
            image = image_service.show(None, image_id)

            self.assertEqual(image['name'], 'snapshot_of_volume_backed')
            properties = image['properties']
            self.assertEqual(properties['kernel_id'], _fake_id('b'))
            self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
            self.assertEqual(properties['root_device_name'], '/dev/vda')
            self.assertTrue(properties['bdm_v2'])
            bdms = properties['block_device_mapping']
            self.assertEqual(len(bdms), 1)
            self.assertEqual(bdms[0]['boot_index'], 0)
            self.assertEqual(bdms[0]['source_type'], 'snapshot')
            self.assertEqual(bdms[0]['destination_type'], 'volume')
            self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
            self.assertEqual('/dev/vda', bdms[0]['device_name'])
            for fld in ('connection_info', 'id', 'instance_uuid'):
                self.assertNotIn(fld, bdms[0])
            for k in extra_properties.keys():
                self.assertEqual(properties[k], extra_properties[k])

            mock_quiesce.assert_called_once_with(mock.ANY, mock.ANY)
            mock_vol_get.assert_called_once_with(mock.ANY, volume['id'])
            mock_vol_create.assert_called_once_with(mock.ANY, volume['id'],
                                                    mock.ANY, mock.ANY)
Ejemplo n.º 24
0
def info_from_instance(context, instance_ref, network_info, system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """

    def null_safe_str(s):
        return str(s) if s else ""

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ""

    image_ref_url = glance.generate_image_url(instance_ref["image_ref"])

    instance_type = flavors.extract_flavor(instance_ref)
    instance_type_name = instance_type.get("name", "")
    instance_flavorid = instance_type.get("flavorid", "")

    if system_metadata is None:
        system_metadata = utils.instance_sys_meta(instance_ref)

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref["project_id"],
        user_id=instance_ref["user_id"],
        # Identity properties
        instance_id=instance_ref["uuid"],
        display_name=instance_ref["display_name"],
        reservation_id=instance_ref["reservation_id"],
        hostname=instance_ref["hostname"],
        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref["instance_type_id"],
        instance_flavor_id=instance_flavorid,
        architecture=instance_ref["architecture"],
        # Capacity properties
        memory_mb=instance_ref["memory_mb"],
        disk_gb=instance_ref["root_gb"] + instance_ref["ephemeral_gb"],
        vcpus=instance_ref["vcpus"],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref["root_gb"],
        ephemeral_gb=instance_ref["ephemeral_gb"],
        # Location properties
        host=instance_ref["host"],
        node=instance_ref["node"],
        availability_zone=instance_ref["availability_zone"],
        # Date properties
        created_at=str(instance_ref["created_at"]),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance_ref.get("terminated_at")),
        deleted_at=null_safe_isotime(instance_ref.get("deleted_at")),
        launched_at=null_safe_isotime(instance_ref.get("launched_at")),
        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref["os_type"],
        kernel_id=instance_ref["kernel_id"],
        ramdisk_id=instance_ref["ramdisk_id"],
        # Status properties
        state=instance_ref["vm_state"],
        state_description=null_safe_str(instance_ref.get("task_state")),
        # accessIPs
        access_ip_v4=instance_ref["access_ip_v4"],
        access_ip_v6=instance_ref["access_ip_v6"],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info["fixed_ips"] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info["metadata"] = utils.instance_meta(instance_ref)

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 25
0
def info_from_instance(context, instance, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:instance: nova.objects.Instance
    :param:network_info: network_info provided if not None
    :param:system_metadata: system_metadata DB entries for the instance,
    if not None

    .. note::

        Currently unused here in trunk, but needed for potential custom
        modifications.

    """

    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_int(s):
        return int(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance.image_ref)

    instance_type = instance.get_flavor()
    # # pf9: Get the instance type from sys metadata if it's stashed.  If not,
    # # fall back to fetching it via the object API
    # try:
    #     instance_type = flavors.extract_flavor(instance)
    # except KeyError:
    #     instance_type_id = instance['instance_type_id']
    #     instance_type = objects.Flavor.get_by_id(context, instance_type_id)

    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    instance_info = dict(
        # Owner properties
        tenant_id=instance.project_id,
        user_id=instance.user_id,

        # Identity properties
        instance_id=instance.uuid,
        display_name=instance.display_name,
        reservation_id=instance.reservation_id,
        hostname=instance.hostname,

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance.instance_type_id,
        instance_flavor_id=instance_flavorid,
        architecture=instance.architecture,

        # Capacity properties
        memory_mb=instance.memory_mb,
        disk_gb=instance.root_gb + instance.ephemeral_gb,
        vcpus=instance.vcpus,
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance.root_gb,
        ephemeral_gb=instance.ephemeral_gb,

        # Location properties
        host=instance.host,
        node=instance.node,
        availability_zone=instance.availability_zone,
        cell_name=null_safe_str(instance.cell_name),

        # Date properties
        created_at=str(instance.created_at),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance.get('terminated_at', None)),
        deleted_at=null_safe_isotime(instance.get('deleted_at', None)),
        launched_at=null_safe_isotime(instance.get('launched_at', None)),
        # PF9 begin
        updated_at = null_safe_isotime(instance.get('updated_at', None)),
        # PF9 end

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance.os_type,
        kernel_id=instance.kernel_id,
        ramdisk_id=instance.ramdisk_id,

        # Status properties
        state=instance.vm_state,
        state_description=null_safe_str(instance.task_state),
        progress=null_safe_int(instance.progress),

        # accessIPs
        access_ip_v4=instance.access_ip_v4,
        access_ip_v6=instance.access_ip_v6,
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(instance.system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance.metadata

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 26
0
def info_from_instance(context, instance_ref, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param network_info: network_info provided if not None
    :param system_metadata: system_metadata DB entries for the instance,
    if not None.  *NOTE*: Currently unused here in trunk, but needed for
    potential custom modifications.
    """

    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type = flavors.extract_flavor(instance_ref)
    instance_type_name = instance_type.get('name', '')

    if system_metadata is None:
        system_metadata = utils.instance_sys_meta(instance_ref)

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        node=instance_ref['node'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Nova's deleted vs terminated instance terminology is confusing,
        # this should be when the instance was deleted (i.e. terminated_at),
        # not when the db record was deleted. (mdragon)
        deleted_at=null_safe_isotime(instance_ref.get('terminated_at')),
        launched_at=null_safe_isotime(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = instance_ref['metadata']

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 27
0
    def _do_test_create_volume_backed_image(self, extra_properties):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['createImage']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id('a'),
                    volume_size=1,
                    device_name='vda',
                    delete_on_termination=False)]
        props = dict(kernel_id=_fake_id('b'),
                     ramdisk_id=_fake_id('c'),
                     root_device_name='/dev/vda',
                     block_device_mapping=bdm)
        original_image = dict(properties=props,
                              container_format='ami',
                              status='active',
                              is_public=True)

        image_service.create(None, original_image)

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
                       fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_instance_get(image_ref=original_image['id'],
                                           vm_state=vm_states.ACTIVE,
                                           root_device_name='/dev/vda')
        self.stubs.Set(db, 'instance_get_by_uuid', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')
        snapshot = dict(id=_fake_id('d'))
        self.mox.StubOutWithMock(self.controller.compute_api, 'volume_api')
        volume_api = self.controller.compute_api.volume_api
        volume_api.get(mox.IgnoreArg(), volume['id']).AndReturn(volume)
        volume_api.create_snapshot_force(mox.IgnoreArg(), volume['id'],
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(snapshot)

        self.mox.ReplayAll()

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers['Location']
        image_id = location.replace(glance.generate_image_url(''), '')
        image = image_service.show(None, image_id)

        self.assertEqual(image['name'], 'snapshot_of_volume_backed')
        properties = image['properties']
        self.assertEqual(properties['kernel_id'], _fake_id('b'))
        self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
        self.assertEqual(properties['root_device_name'], '/dev/vda')
        self.assertEqual(properties['bdm_v2'], True)
        bdms = properties['block_device_mapping']
        self.assertEqual(len(bdms), 1)
        self.assertEqual(bdms[0]['boot_index'], 0)
        self.assertEqual(bdms[0]['source_type'], 'snapshot')
        self.assertEqual(bdms[0]['destination_type'], 'volume')
        self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
        for fld in ('connection_info', 'id',
                    'instance_uuid', 'device_name'):
            self.assertNotIn(fld, bdms[0])
        for k in extra_properties.keys():
            self.assertEqual(properties[k], extra_properties[k])
Ejemplo n.º 28
0
    def _do_test_create_volume_backed_image(self, extra_properties):
        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(create_image=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['create_image']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [
            dict(volume_id=_fake_id('a'),
                 volume_size=1,
                 device_name='vda',
                 delete_on_termination=False)
        ]
        props = dict(kernel_id=_fake_id('b'),
                     ramdisk_id=_fake_id('c'),
                     root_device_name='/dev/vda',
                     block_device_mapping=bdm)
        original_image = dict(properties=props,
                              container_format='ami',
                              status='active',
                              is_public=True)

        image_service.create(None, original_image)

        def fake_block_device_mapping_get_all_by_instance(context, inst_id):
            return [
                dict(volume_id=_fake_id('a'),
                     source_type='snapshot',
                     destination_type='volume',
                     volume_size=1,
                     device_name='vda',
                     snapshot_id=1,
                     boot_index=0,
                     delete_on_termination=False,
                     no_device=None)
            ]

        self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
                       fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_instance_get(image_ref=original_image['id'],
                                           vm_state=vm_states.ACTIVE,
                                           root_device_name='/dev/vda')
        self.stubs.Set(db, 'instance_get_by_uuid', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')
        snapshot = dict(id=_fake_id('d'))
        self.mox.StubOutWithMock(self.controller.compute_api, 'volume_api')
        volume_api = self.controller.compute_api.volume_api
        volume_api.get(mox.IgnoreArg(), volume['id']).AndReturn(volume)
        volume_api.create_snapshot_force(mox.IgnoreArg(), volume['id'],
                                         mox.IgnoreArg(),
                                         mox.IgnoreArg()).AndReturn(snapshot)

        self.mox.ReplayAll()

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers['Location']
        image_id = location.replace(glance.generate_image_url(''), '')
        image = image_service.show(None, image_id)

        self.assertEqual(image['name'], 'snapshot_of_volume_backed')
        properties = image['properties']
        self.assertEqual(properties['kernel_id'], _fake_id('b'))
        self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
        self.assertEqual(properties['root_device_name'], '/dev/vda')
        bdms = properties['block_device_mapping']
        self.assertEqual(len(bdms), 1)
        self.assertEqual(bdms[0]['device_name'], 'vda')
        self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
        for k in extra_properties.keys():
            self.assertEqual(properties[k], extra_properties[k])
Ejemplo n.º 29
0
    def _do_test_create_volume_backed_image(self, extra_properties):
        def _fake_id(x):
            return "%s-%s-%s-%s" % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name="snapshot_of_volume_backed"))

        if extra_properties:
            body["createImage"]["metadata"] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id("a"), volume_size=1, device_name="vda", delete_on_termination=False)]

        def fake_block_device_mapping_get_all_by_instance(context, inst_id, use_slave=False):
            return [
                fake_block_device.FakeDbBlockDeviceDict(
                    {
                        "volume_id": _fake_id("a"),
                        "source_type": "snapshot",
                        "destination_type": "volume",
                        "volume_size": 1,
                        "device_name": "vda",
                        "snapshot_id": 1,
                        "boot_index": 0,
                        "delete_on_termination": False,
                        "no_device": None,
                    }
                )
            ]

        self.stub_out("nova.db.block_device_mapping_get_all_by_instance", fake_block_device_mapping_get_all_by_instance)

        system_metadata = dict(
            image_kernel_id=_fake_id("b"),
            image_ramdisk_id=_fake_id("c"),
            image_root_device_name="/dev/vda",
            image_block_device_mapping=str(bdm),
            image_container_format="ami",
        )
        instance = fakes.fake_instance_get(
            image_ref=str(uuid.uuid4()),
            vm_state=vm_states.ACTIVE,
            root_device_name="/dev/vda",
            system_metadata=system_metadata,
        )
        self.stub_out("nova.db.instance_get_by_uuid", instance)

        self.mox.StubOutWithMock(self.controller.compute_api.compute_rpcapi, "quiesce_instance")
        self.controller.compute_api.compute_rpcapi.quiesce_instance(mox.IgnoreArg(), mox.IgnoreArg()).AndRaise(
            exception.InstanceQuiesceNotSupported(instance_id="fake", reason="test")
        )

        volume = dict(id=_fake_id("a"), size=1, host="fake", display_description="fake")
        snapshot = dict(id=_fake_id("d"))
        self.mox.StubOutWithMock(self.controller.compute_api, "volume_api")
        volume_api = self.controller.compute_api.volume_api
        volume_api.get(mox.IgnoreArg(), volume["id"]).AndReturn(volume)
        volume_api.create_snapshot_force(mox.IgnoreArg(), volume["id"], mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
            snapshot
        )

        self.mox.ReplayAll()

        response = self.controller._action_create_image(self.req, FAKE_UUID, body=body)

        location = response.headers["Location"]
        image_id = location.replace(self.image_url or glance.generate_image_url(""), "")
        image = image_service.show(None, image_id)

        self.assertEqual(image["name"], "snapshot_of_volume_backed")
        properties = image["properties"]
        self.assertEqual(properties["kernel_id"], _fake_id("b"))
        self.assertEqual(properties["ramdisk_id"], _fake_id("c"))
        self.assertEqual(properties["root_device_name"], "/dev/vda")
        self.assertTrue(properties["bdm_v2"])
        bdms = properties["block_device_mapping"]
        self.assertEqual(len(bdms), 1)
        self.assertEqual(bdms[0]["boot_index"], 0)
        self.assertEqual(bdms[0]["source_type"], "snapshot")
        self.assertEqual(bdms[0]["destination_type"], "volume")
        self.assertEqual(bdms[0]["snapshot_id"], snapshot["id"])
        self.assertEqual("/dev/vda", bdms[0]["device_name"])
        for fld in ("connection_info", "id", "instance_uuid"):
            self.assertNotIn(fld, bdms[0])
        for k in extra_properties.keys():
            self.assertEqual(properties[k], extra_properties[k])
Ejemplo n.º 30
0
def info_from_instance(context, instance_ref, network_info, system_metadata,
                       **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:network_info: network_info provided if not None
    :param:system_metadata: system_metadata DB entries for the instance,
    if not None

    .. note::

        Currently unused here in trunk, but needed for potential custom
        modifications.

    """
    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type = flavors.extract_flavor(instance_ref)
    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    if system_metadata is None:
        system_metadata = utils.instance_sys_meta(instance_ref)

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        instance_flavor_id=instance_flavorid,
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        node=instance_ref['node'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance_ref.get('terminated_at')),
        deleted_at=null_safe_isotime(instance_ref.get('deleted_at')),
        launched_at=null_safe_isotime(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = utils.instance_meta(instance_ref)

    instance_info.update(kw)
    return instance_info
Ejemplo n.º 31
0
    def _do_test_create_volume_backed_image(self, extra_properties):
        def _fake_id(x):
            return "%s-%s-%s-%s" % (x * 8, x * 4, x * 4, x * 12)

        body = dict(create_image=dict(name="snapshot_of_volume_backed"))

        if extra_properties:
            body["create_image"]["metadata"] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id("a"), volume_size=1, device_name="vda", delete_on_termination=False)]
        props = dict(
            kernel_id=_fake_id("b"), ramdisk_id=_fake_id("c"), root_device_name="/dev/vda", block_device_mapping=bdm
        )
        original_image = dict(properties=props, container_format="ami", status="active", is_public=True)

        image_service.create(None, original_image)

        def fake_block_device_mapping_get_all_by_instance(context, inst_id, use_slave=False):
            return [
                fake_block_device.FakeDbBlockDeviceDict(
                    {
                        "volume_id": _fake_id("a"),
                        "source_type": "snapshot",
                        "destination_type": "volume",
                        "volume_size": 1,
                        "device_name": "vda",
                        "snapshot_id": 1,
                        "boot_index": 0,
                        "delete_on_termination": False,
                        "no_device": None,
                    }
                )
            ]

        self.stubs.Set(db, "block_device_mapping_get_all_by_instance", fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_instance_get(
            image_ref=original_image["id"], vm_state=vm_states.ACTIVE, root_device_name="/dev/vda"
        )
        self.stubs.Set(db, "instance_get_by_uuid", instance)

        volume = dict(id=_fake_id("a"), size=1, host="fake", display_description="fake")
        snapshot = dict(id=_fake_id("d"))
        self.mox.StubOutWithMock(self.controller.compute_api, "volume_api")
        volume_api = self.controller.compute_api.volume_api
        volume_api.get(mox.IgnoreArg(), volume["id"]).AndReturn(volume)
        volume_api.create_snapshot_force(mox.IgnoreArg(), volume["id"], mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
            snapshot
        )

        self.mox.ReplayAll()

        req = fakes.HTTPRequestV3.blank(self.url)
        response = self.controller._action_create_image(req, FAKE_UUID, body)

        location = response.headers["Location"]
        image_id = location.replace(glance.generate_image_url(""), "")
        image = image_service.show(None, image_id)

        self.assertEqual(image["name"], "snapshot_of_volume_backed")
        properties = image["properties"]
        self.assertEqual(properties["kernel_id"], _fake_id("b"))
        self.assertEqual(properties["ramdisk_id"], _fake_id("c"))
        self.assertEqual(properties["root_device_name"], "/dev/vda")
        self.assertEqual(properties["bdm_v2"], True)
        bdms = properties["block_device_mapping"]
        self.assertEqual(len(bdms), 1)
        self.assertEqual(bdms[0]["boot_index"], 0)
        self.assertEqual(bdms[0]["source_type"], "snapshot")
        self.assertEqual(bdms[0]["destination_type"], "volume")
        self.assertEqual(bdms[0]["snapshot_id"], snapshot["id"])
        for fld in ("connection_info", "id", "instance_uuid", "device_name"):
            self.assertNotIn(fld, bdms[0])
        for k in extra_properties.keys():
            self.assertEqual(properties[k], extra_properties[k])