diff options
22 files changed, 955 insertions, 5 deletions
diff --git a/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json b/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json new file mode 100644 index 000000000..1548aeb59 --- /dev/null +++ b/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json @@ -0,0 +1,34 @@ +{ + "image": { + "OS-EXT-IMG-SIZE:size": "74185822", + "created": "2011-01-01T01:02:03Z", + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "True", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage7", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + } +}
\ No newline at end of file diff --git a/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml b/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml new file mode 100644 index 000000000..49fe2ee31 --- /dev/null +++ b/doc/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml @@ -0,0 +1,12 @@ +<?xml version='1.0' encoding='UTF-8'?> +<image xmlns:OS-EXT-IMG-SIZE="http://docs.openstack.org/compute/ext/image_size/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage7" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="70a599e0-31e7-49b7-b260-868f441e862b" OS-EXT-IMG-SIZE:size="74185822"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">True</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" type="application/vnd.openstack.image" rel="alternate"/> +</image>
\ No newline at end of file diff --git a/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json b/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json new file mode 100644 index 000000000..bbd9dcfb1 --- /dev/null +++ b/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json @@ -0,0 +1,219 @@ +{ + "images": [ + { + "OS-EXT-IMG-SIZE:size": "74185822", + "created": "2011-01-01T01:02:03Z", + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "True", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage7", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "25165824", + "created": "2011-01-01T01:02:03Z", + "id": "155d900f-4e14-4e4c-a73d-069cbf4541e6", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "58145823", + "created": "2011-01-01T01:02:03Z", + "id": "a2459075-d96c-40d5-893e-577ff92e721c", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "49163826", + "created": "2011-01-01T01:02:03Z", + "id": "a440c04b-79fa-479c-bed1-0b816eaec379", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "False", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage6", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "26360814", + "created": "2011-01-01T01:02:03Z", + "id": "c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "155d900f-4e14-4e4c-a73d-069cbf4541e6", + "ramdisk_id": null + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "84035174", + "created": "2011-01-01T01:02:03Z", + "id": "cedef40a-ed67-4d10-800e-17455edce175", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "OS-EXT-IMG-SIZE:size": "83594576", + "created": "2011-01-01T01:02:03Z", + "id": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "bookmark" + }, + { + "href": "http://glance.openstack.example.com/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + } + ] +}
\ No newline at end of file diff --git a/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml b/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml new file mode 100644 index 000000000..d0b5787ca --- /dev/null +++ b/doc/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml @@ -0,0 +1,71 @@ +<?xml version='1.0' encoding='UTF-8'?> +<images xmlns:OS-EXT-IMG-SIZE="http://docs.openstack.org/compute/ext/image_size/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1"> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage7" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="70a599e0-31e7-49b7-b260-868f441e862b" OS-EXT-IMG-SIZE:size="74185822"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">True</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="155d900f-4e14-4e4c-a73d-069cbf4541e6" OS-EXT-IMG-SIZE:size="25165824"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="a2459075-d96c-40d5-893e-577ff92e721c" OS-EXT-IMG-SIZE:size="58145823"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage6" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="a440c04b-79fa-479c-bed1-0b816eaec379" OS-EXT-IMG-SIZE:size="49163826"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">False</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="c905cedb-7281-47e4-8a62-f26bc5fc4c77" OS-EXT-IMG-SIZE:size="26360814"> + <metadata> + <meta key="kernel_id">155d900f-4e14-4e4c-a73d-069cbf4541e6</meta> + <meta key="ramdisk_id">None</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="cedef40a-ed67-4d10-800e-17455edce175" OS-EXT-IMG-SIZE:size="84035174"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" id="76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" OS-EXT-IMG-SIZE:size="83594576"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="http://openstack.example.com/v2/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" rel="self"/> + <atom:link href="http://openstack.example.com/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" rel="bookmark"/> + <atom:link href="http://glance.openstack.example.com/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" type="application/vnd.openstack.image" rel="alternate"/> + </image> +</images>
\ No newline at end of file diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json index 0ce9b9aca..0ad7a6498 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.json +++ b/doc/api_samples/all_extensions/extensions-get-resp.json @@ -25,6 +25,14 @@ "updated": "2013-01-30T00:00:00+00:00" }, { + "alias": "OS-EXT-IMG-SIZE", + "description": "Adds image size to image listings.", + "links": [], + "name": "ImageSize", + "namespace": "http://docs.openstack.org/compute/ext/image_size/api/v1.1", + "updated": "2013-02-19T00:00:00+00:00" + }, + { "alias": "OS-EXT-IPS", "description": "Adds type parameter to the ip list.", "links": [], @@ -322,7 +330,7 @@ }, { "alias": "os-instance-actions", - "description": "View a log of actions taken on an instance", + "description": "View a log of actions and events taken on an instance.", "links": [], "name": "InstanceActions", "namespace": "http://docs.openstack.org/compute/ext/instance-actions/api/v1.1", diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml index 4fcdeb285..da20e0b61 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.xml +++ b/doc/api_samples/all_extensions/extensions-get-resp.xml @@ -9,6 +9,9 @@ <extension alias="OS-EXT-AZ" updated="2013-01-30T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/extended_availability_zone/api/v2" name="ExtendedAvailabilityZone"> <description>Extended Server Attributes support.</description> </extension> + <extension alias="OS-EXT-IMG-SIZE" updated="2013-02-19T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/image_size/api/v1.1" name="ImageSize"> + <description>Adds image size to image listings.</description> + </extension> <extension alias="OS-EXT-IPS" updated="2013-01-06T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/extended_ips/api/v1.1" name="ExtendedIps"> <description>Adds type parameter to the ip list.</description> </extension> @@ -139,7 +142,7 @@ <description>Admin-only hypervisor administration.</description> </extension> <extension alias="os-instance-actions" updated="2013-02-08T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/instance-actions/api/v1.1" name="InstanceActions"> - <description>View a log of actions taken on an instance</description> + <description>View a log of actions and events taken on an instance.</description> </extension> <extension alias="os-instance_usage_audit_log" updated="2012-07-06T01:00:00+00:00" namespace="http://docs.openstack.org/ext/services/api/v1.1" name="OSInstanceUsageAuditLog"> <description>Admin-only Task Log Monitoring.</description> diff --git a/etc/nova/policy.json b/etc/nova/policy.json index fb54efc8b..5a6800f94 100644 --- a/etc/nova/policy.json +++ b/etc/nova/policy.json @@ -67,6 +67,7 @@ "compute_extension:hide_server_addresses": "is_admin:False", "compute_extension:hosts": "rule:admin_api", "compute_extension:hypervisors": "rule:admin_api", + "compute_extension:image_size": "", "compute_extension:instance_actions": "", "compute_extension:instance_actions:events": "rule:admin_api", "compute_extension:instance_usage_audit_log": "rule:admin_api", diff --git a/nova/api/openstack/compute/contrib/image_size.py b/nova/api/openstack/compute/contrib/image_size.py new file mode 100644 index 000000000..21998738f --- /dev/null +++ b/nova/api/openstack/compute/contrib/image_size.py @@ -0,0 +1,88 @@ +# Copyright 2013 Rackspace Hosting +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.api.openstack import extensions +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil + +authorize = extensions.soft_extension_authorizer('compute', 'image_size') + + +def make_image(elem): + elem.set('{%s}size' % Image_size.namespace, '%s:size' % Image_size.alias) + + +class ImagesSizeTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('images') + elem = xmlutil.SubTemplateElement(root, 'image', selector='images') + make_image(elem) + return xmlutil.SlaveTemplate(root, 1, nsmap={ + Image_size.alias: Image_size.namespace}) + + +class ImageSizeTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('image', selector='image') + make_image(root) + return xmlutil.SlaveTemplate(root, 1, nsmap={ + Image_size.alias: Image_size.namespace}) + + +class ImageSizeController(wsgi.Controller): + + def _extend_image(self, image, image_cache): + key = "%s:size" % Image_size.alias + image[key] = image_cache['size'] + + @wsgi.extends + def show(self, req, resp_obj, id): + context = req.environ["nova.context"] + if authorize(context): + # Attach our slave template to the response object + resp_obj.attach(xml=ImageSizeTemplate()) + image_resp = resp_obj.obj['image'] + # image guaranteed to be in the cache due to the core API adding + # it in its 'show' method + image_cached = req.get_db_item('images', image_resp['id']) + self._extend_image(image_resp, image_cached) + + @wsgi.extends + def detail(self, req, resp_obj): + context = req.environ['nova.context'] + if authorize(context): + # Attach our slave template to the response object + resp_obj.attach(xml=ImagesSizeTemplate()) + images_resp = list(resp_obj.obj['images']) + # images guaranteed to be in the cache due to the core API adding + # it in its 'detail' method + for image in images_resp: + image_cached = req.get_db_item('images', image['id']) + self._extend_image(image, image_cached) + + +class Image_size(extensions.ExtensionDescriptor): + """Adds image size to image listings.""" + + name = "ImageSize" + alias = "OS-EXT-IMG-SIZE" + namespace = ("http://docs.openstack.org/compute/ext/" + "image_size/api/v1.1") + updated = "2013-02-19T00:00:00+00:00" + + def get_controller_extensions(self): + controller = ImageSizeController() + extension = extensions.ControllerExtension(self, 'images', controller) + return [extension] diff --git a/nova/api/openstack/compute/images.py b/nova/api/openstack/compute/images.py index 7dda64f87..703d2fe2d 100644 --- a/nova/api/openstack/compute/images.py +++ b/nova/api/openstack/compute/images.py @@ -144,6 +144,7 @@ class Controller(wsgi.Controller): explanation = _("Image not found.") raise webob.exc.HTTPNotFound(explanation=explanation) + req.cache_db_items('images', [image], 'id') return self._view_builder.show(req, image) def delete(self, req, id): @@ -200,6 +201,7 @@ class Controller(wsgi.Controller): except exception.Invalid as e: raise webob.exc.HTTPBadRequest(explanation=str(e)) + req.cache_db_items('images', images, 'id') return self._view_builder.detail(req, images) def create(self, *args, **kwargs): diff --git a/nova/tests/api/openstack/compute/contrib/test_image_size.py b/nova/tests/api/openstack/compute/contrib/test_image_size.py new file mode 100644 index 000000000..886bccfa7 --- /dev/null +++ b/nova/tests/api/openstack/compute/contrib/test_image_size.py @@ -0,0 +1,130 @@ +# Copyright 2013 Rackspace Hosting +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from lxml import etree +import webob + +from nova.api.openstack.compute.contrib import image_size +from nova.image import glance +from nova.openstack.common import jsonutils +from nova import test +from nova.tests.api.openstack import fakes + +NOW_API_FORMAT = "2010-10-11T10:30:22Z" +IMAGES = [{ + 'id': '123', + 'name': 'public image', + 'metadata': {'key1': 'value1'}, + 'updated': NOW_API_FORMAT, + 'created': NOW_API_FORMAT, + 'status': 'ACTIVE', + 'progress': 100, + 'minDisk': 10, + 'minRam': 128, + 'size': 12345678, + "links": [{ + "rel": "self", + "href": "http://localhost/v2/fake/images/123", + }, + { + "rel": "bookmark", + "href": "http://localhost/fake/images/123", + }], + }, + { + 'id': '124', + 'name': 'queued snapshot', + 'updated': NOW_API_FORMAT, + 'created': NOW_API_FORMAT, + 'status': 'SAVING', + 'progress': 25, + 'minDisk': 0, + 'minRam': 0, + 'size': 87654321, + "links": [{ + "rel": "self", + "href": "http://localhost/v2/fake/images/124", + }, + { + "rel": "bookmark", + "href": "http://localhost/fake/images/124", + }], + }] + + +def fake_show(*args, **kwargs): + return IMAGES[0] + + +def fake_detail(*args, **kwargs): + return IMAGES + + +class ImageSizeTest(test.TestCase): + content_type = 'application/json' + prefix = 'OS-EXT-IMG-SIZE' + + def setUp(self): + super(ImageSizeTest, self).setUp() + self.stubs.Set(glance.GlanceImageService, 'show', fake_show) + self.stubs.Set(glance.GlanceImageService, 'detail', fake_detail) + self.flags(osapi_compute_extension=['nova.api.openstack.compute' + '.contrib.image_size.Image_size']) + + def _make_request(self, url): + req = webob.Request.blank(url) + req.headers['Accept'] = self.content_type + res = req.get_response(fakes.wsgi_app()) + return res + + def _get_image(self, body): + return jsonutils.loads(body).get('image') + + def _get_images(self, body): + return jsonutils.loads(body).get('images') + + def assertImageSize(self, image, size): + self.assertEqual(image.get('%s:size' % self.prefix), size) + + def test_show(self): + url = '/v2/fake/images/1' + res = self._make_request(url) + + self.assertEqual(res.status_int, 200) + image = self._get_image(res.body) + self.assertImageSize(image, 12345678) + + def test_detail(self): + url = '/v2/fake/images/detail' + res = self._make_request(url) + + self.assertEqual(res.status_int, 200) + images = self._get_images(res.body) + self.assertImageSize(images[0], 12345678) + self.assertImageSize(images[1], 87654321) + + +class ImageSizeXmlTest(ImageSizeTest): + content_type = 'application/xml' + prefix = '{%s}' % image_size.Image_size.namespace + + def _get_image(self, body): + return etree.XML(body) + + def _get_images(self, body): + return etree.XML(body).getchildren() + + def assertImageSize(self, image, size): + self.assertEqual(int(image.get('%ssize' % self.prefix)), size) diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py index bd3fde1f3..68e5e1b99 100644 --- a/nova/tests/api/openstack/compute/test_extensions.py +++ b/nova/tests/api/openstack/compute/test_extensions.py @@ -185,6 +185,7 @@ class ExtensionControllerTest(ExtensionTestCase): "FloatingIpsBulk", "Fox In Socks", "Hosts", + "ImageSize", "InstanceActions", "Keypairs", "Multinic", diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index beb99a3f5..7da10e73e 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -227,7 +227,7 @@ def _make_image_fixtures(): # Public image add_fixture(id=image_id, name='public image', is_public=True, status='active', properties={'key1': 'value1'}, - min_ram="128", min_disk="10") + min_ram="128", min_disk="10", size='25165824') image_id += 1 # Snapshot for User 1 @@ -238,7 +238,7 @@ def _make_image_fixtures(): 'deleted', 'pending_delete'): add_fixture(id=image_id, name='%s snapshot' % status, is_public=False, status=status, - properties=snapshot_properties) + properties=snapshot_properties, size='25165824') image_id += 1 # Image without a name diff --git a/nova/tests/fake_policy.py b/nova/tests/fake_policy.py index 80b3a9c85..7f9fffddc 100644 --- a/nova/tests/fake_policy.py +++ b/nova/tests/fake_policy.py @@ -144,6 +144,7 @@ policy_data = """ "compute_extension:hide_server_addresses": "", "compute_extension:hosts": "", "compute_extension:hypervisors": "", + "compute_extension:image_size": "", "compute_extension:instance_actions": "", "compute_extension:instance_actions:events": "is_admin:True", "compute_extension:instance_usage_audit_log": "", diff --git a/nova/tests/image/fake.py b/nova/tests/image/fake.py index 51cf30a3e..06f2f5147 100644 --- a/nova/tests/image/fake.py +++ b/nova/tests/image/fake.py @@ -52,6 +52,7 @@ class _FakeImageService(object): 'is_public': False, 'container_format': 'raw', 'disk_format': 'raw', + 'size': '25165824', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel, 'architecture': 'x86_64'}} @@ -66,6 +67,7 @@ class _FakeImageService(object): 'is_public': True, 'container_format': 'ami', 'disk_format': 'ami', + 'size': '58145823', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel}} @@ -79,6 +81,7 @@ class _FakeImageService(object): 'is_public': True, 'container_format': None, 'disk_format': None, + 'size': '83594576', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel}} @@ -92,6 +95,7 @@ class _FakeImageService(object): 'is_public': True, 'container_format': 'ami', 'disk_format': 'ami', + 'size': '84035174', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel}} @@ -105,6 +109,7 @@ class _FakeImageService(object): 'is_public': True, 'container_format': 'ami', 'disk_format': 'ami', + 'size': '26360814', 'properties': {'kernel_id': '155d900f-4e14-4e4c-a73d-069cbf4541e6', 'ramdisk_id': None}} @@ -119,6 +124,7 @@ class _FakeImageService(object): 'is_public': False, 'container_format': 'ova', 'disk_format': 'vhd', + 'size': '49163826', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel, 'architecture': 'x86_64', @@ -134,6 +140,7 @@ class _FakeImageService(object): 'is_public': False, 'container_format': 'ova', 'disk_format': 'vhd', + 'size': '74185822', 'properties': {'kernel_id': CONF.null_kernel, 'ramdisk_id': CONF.null_kernel, 'architecture': 'x86_64', diff --git a/nova/tests/image/test_fake.py b/nova/tests/image/test_fake.py index 614201b67..c63bb5389 100644 --- a/nova/tests/image/test_fake.py +++ b/nova/tests/image/test_fake.py @@ -41,7 +41,8 @@ class FakeImageServiceTestCase(test.TestCase): self.assertEquals(keys, set(['id', 'name', 'created_at', 'updated_at', 'deleted_at', 'deleted', 'status', 'is_public', 'properties', - 'disk_format', 'container_format'])) + 'disk_format', 'container_format', + 'size'])) self.assertTrue(isinstance(image['created_at'], datetime.datetime)) self.assertTrue(isinstance(image['updated_at'], datetime.datetime)) diff --git a/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json.tpl b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json.tpl new file mode 100644 index 000000000..f5f470cbc --- /dev/null +++ b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.json.tpl @@ -0,0 +1,34 @@ +{ + "image": { + "created": "2011-01-01T01:02:03Z", + "id": "%(image_id)s", + "links": [ + { + "href": "%(host)s/v2/openstack/images/%(image_id)s", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/%(image_id)s", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/%(image_id)s", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "True", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage7", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "%(timestamp)s" + } +} diff --git a/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml.tpl b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml.tpl new file mode 100644 index 000000000..e36ddc76c --- /dev/null +++ b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/image-get-resp.xml.tpl @@ -0,0 +1,12 @@ +<?xml version='1.0' encoding='UTF-8'?> +<image xmlns:OS-EXT-IMG-SIZE="http://docs.openstack.org/compute/ext/image_size/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage7" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="%(image_id)s"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">True</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/%(image_id)s" rel="self"/> + <atom:link href="%(host)s/openstack/images/%(image_id)s" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/%(image_id)s" type="application/vnd.openstack.image" rel="alternate"/> +</image> diff --git a/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json.tpl b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json.tpl new file mode 100644 index 000000000..a29172bf4 --- /dev/null +++ b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.json.tpl @@ -0,0 +1,219 @@ +{ + "images": [ + { + "created": "2011-01-01T01:02:03Z", + "id": "70a599e0-31e7-49b7-b260-868f441e862b", + "links": [ + { + "href": "%(host)s/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "True", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage7", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "155d900f-4e14-4e4c-a73d-069cbf4541e6", + "links": [ + { + "href": "%(host)s/v2/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "progress": 100, + "OS-EXT-IMG-SIZE:size": %(int)s, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "a2459075-d96c-40d5-893e-577ff92e721c", + "links": [ + { + "href": "%(host)s/v2/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "a440c04b-79fa-479c-bed1-0b816eaec379", + "links": [ + { + "href": "%(host)s/v2/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "architecture": "x86_64", + "auto_disk_config": "False", + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage6", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "links": [ + { + "href": "%(host)s/v2/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "155d900f-4e14-4e4c-a73d-069cbf4541e6", + "ramdisk_id": null + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "cedef40a-ed67-4d10-800e-17455edce175", + "links": [ + { + "href": "%(host)s/v2/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/cedef40a-ed67-4d10-800e-17455edce175", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + }, + { + "created": "2011-01-01T01:02:03Z", + "id": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "links": [ + { + "href": "%(host)s/v2/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "self" + }, + { + "href": "%(host)s/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "bookmark" + }, + { + "href": "%(glance_host)s/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6", + "rel": "alternate", + "type": "application/vnd.openstack.image" + } + ], + "metadata": { + "kernel_id": "nokernel", + "ramdisk_id": "nokernel" + }, + "minDisk": 0, + "minRam": 0, + "name": "fakeimage123456", + "OS-EXT-IMG-SIZE:size": %(int)s, + "progress": 100, + "status": "ACTIVE", + "updated": "2011-01-01T01:02:03Z" + } + ] +} diff --git a/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml.tpl b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml.tpl new file mode 100644 index 000000000..4c1e4c4be --- /dev/null +++ b/nova/tests/integrated/api_samples/OS-EXT-IMG-SIZE/images-details-get-resp.xml.tpl @@ -0,0 +1,71 @@ +<?xml version='1.0' encoding='UTF-8'?> +<images xmlns:OS-EXT-IMG-SIZE="http://docs.openstack.org/compute/ext/image_size/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1"> + <image xmlns:OS-EXT-IMG-SIZE="http://docs.openstack.org/compute/ext/image_size/api/v1.1" status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage7" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="70a599e0-31e7-49b7-b260-868f441e862b"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">True</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="self"/> + <atom:link href="%(host)s/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="155d900f-4e14-4e4c-a73d-069cbf4541e6"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" rel="self"/> + <atom:link href="%(host)s/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/155d900f-4e14-4e4c-a73d-069cbf4541e6" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="a2459075-d96c-40d5-893e-577ff92e721c"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" rel="self"/> + <atom:link href="%(host)s/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/a2459075-d96c-40d5-893e-577ff92e721c" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage6" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="a440c04b-79fa-479c-bed1-0b816eaec379"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="auto_disk_config">False</meta> + <meta key="ramdisk_id">nokernel</meta> + <meta key="architecture">x86_64</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" rel="self"/> + <atom:link href="%(host)s/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/a440c04b-79fa-479c-bed1-0b816eaec379" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="c905cedb-7281-47e4-8a62-f26bc5fc4c77"> + <metadata> + <meta key="kernel_id">155d900f-4e14-4e4c-a73d-069cbf4541e6</meta> + <meta key="ramdisk_id">None</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" rel="self"/> + <atom:link href="%(host)s/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/c905cedb-7281-47e4-8a62-f26bc5fc4c77" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="cedef40a-ed67-4d10-800e-17455edce175"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" rel="self"/> + <atom:link href="%(host)s/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/cedef40a-ed67-4d10-800e-17455edce175" type="application/vnd.openstack.image" rel="alternate"/> + </image> + <image status="ACTIVE" updated="2011-01-01T01:02:03Z" name="fakeimage123456" created="2011-01-01T01:02:03Z" minDisk="0" progress="100" minRam="0" OS-EXT-IMG-SIZE:size="%(int)s" id="76fa36fc-c930-4bf3-8c8a-ea2a2420deb6"> + <metadata> + <meta key="kernel_id">nokernel</meta> + <meta key="ramdisk_id">nokernel</meta> + </metadata> + <atom:link href="%(host)s/v2/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" rel="self"/> + <atom:link href="%(host)s/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" rel="bookmark"/> + <atom:link href="%(glance_host)s/openstack/images/76fa36fc-c930-4bf3-8c8a-ea2a2420deb6" type="application/vnd.openstack.image" rel="alternate"/> + </image> +</images> diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl index 831c93436..1faf7f480 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl @@ -33,6 +33,14 @@ "updated": "%(timestamp)s" }, { + "alias": "OS-EXT-IMG-SIZE", + "description": "%(text)s", + "links": [], + "name": "ImageSize", + "namespace": "http://docs.openstack.org/compute/ext/image_size/api/v1.1", + "updated": "%(timestamp)s" + }, + { "alias": "OS-EXT-SRV-ATTR", "description": "%(text)s", "links": [], diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl index c76b55bbb..0aefc123f 100644 --- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl +++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl @@ -12,6 +12,9 @@ <extension alias="OS-EXT-IPS" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/extended_ips/api/v1.1" name="ExtendedIps"> <description>%(text)s</description> </extension> + <extension alias="OS-EXT-IMG-SIZE" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/image_size/api/v1.1" name="ImageSize"> + <description>%(text)s</description> + </extension> <extension alias="OS-EXT-SRV-ATTR" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/extended_status/api/v1.1" name="ExtendedServerAttributes"> <description>%(text)s</description> </extension> diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py index 474e0aa22..db26b07ec 100644 --- a/nova/tests/integrated/test_api_samples.py +++ b/nova/tests/integrated/test_api_samples.py @@ -325,6 +325,7 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase): 'glance_host': self._get_glance_host(), 'compute_host': self.compute.host, 'text': text, + 'int': '[0-9]+', } def _get_response(self, url, method, body=None, strip_version=False): @@ -3205,6 +3206,30 @@ class InstanceActionsSampleXmlTest(InstanceActionsSampleJsonTest): ctype = 'xml' +class ImageSizeSampleJsonTests(ApiSampleTestBase): + extension_name = ("nova.api.openstack.compute.contrib" + ".image_size.Image_size") + + def test_show(self): + # Get api sample of one single image details request. + image_id = fake.get_valid_image_id() + response = self._do_get('images/%s' % image_id) + self.assertEqual(response.status, 200) + subs = self._get_regexes() + subs['image_id'] = image_id + return self._verify_response('image-get-resp', subs, response) + + def test_detail(self): + # Get api sample of all images details request. + response = self._do_get('images/detail') + subs = self._get_regexes() + return self._verify_response('images-details-get-resp', subs, response) + + +class ImageSizeSampleXmlTests(ImageSizeSampleJsonTests): + ctype = 'xml' + + class ConfigDriveSampleJsonTest(ServersSampleBase): extension_name = ("nova.api.openstack.compute.contrib.config_drive." "Config_drive") |