Esempio n. 1
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['patron.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):
                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
Esempio n. 2
0
    def _action_create_image(self, req, id, body):
        """Snapshot a server instance."""
        context = req.environ['patron.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):
                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
Esempio n. 3
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)
Esempio n. 4
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: patron.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
Esempio n. 5
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])