Skip to content

Commit

Permalink
Require container & disk formats on image create
Browse files Browse the repository at this point in the history
Fixes lp 933702

For images created via the glance CLI, the container and disk formats
were previously defaulted if not explicitly set. However if created via
the python or REST APIs, these attributes were not defaulted if unset.

There is no real sensible default for these formats, so now an image
create fails with 400 "Bad Request" if the format metadata are missing.

Also we ensure unset image metadata are not reported in x-image-meta-*
headers in order to disambiguate None and empty string values.

Change-Id: I8189383f5f9adf42a8cdac7f8dc7e9327baf46da
  • Loading branch information
Eoghan Glynn committed Feb 20, 2012
1 parent f8f9f17 commit 62c913c
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 170 deletions.
19 changes: 11 additions & 8 deletions bin/glance
Expand Up @@ -141,7 +141,7 @@ def print_image_formatted(client, image):
print "Container format: %s" % image['container_format']
print "Minimum Ram Required (MB): %s" % image['min_ram']
print "Minimum Disk Required (GB): %s" % image['min_disk']
if image['owner']:
if image.get('owner'):
print "Owner: %s" % image['owner']
if len(image['properties']) > 0:
for k, v in image['properties'].items():
Expand Down Expand Up @@ -173,10 +173,9 @@ is_public Optional. If specified, interpreted as a boolean value
protected Optional. If specified, interpreted as a boolean value
and enables or disables deletion protection.
The default value is False.
disk_format Optional. Possible values are 'vhd','vmdk','raw', 'qcow2',
and 'ami'. Default value is 'raw'.
container_format Optional. Possible values are 'ovf' and 'ami'.
Default value is 'ovf'.
disk_format Required. Possible values are 'vhd','vmdk','raw', 'qcow2',
and 'ami'.
container_format Required. Possible values are 'ovf' and 'ami'.
location Optional. When specified, should be a readable location
in the form of a URI: $STORE://LOCATION. For example, if
the image data is stored in a file on the local
Expand All @@ -202,7 +201,8 @@ EXAMPLES
location=http://images.ubuntu.org/images/lucid-10.04-i686.iso \\
distro="Ubuntu 10.04 LTS"
%(prog)s add name="My Image" distro="Ubuntu 10.04 LTS" < /tmp/myimage.iso"""
%(prog)s add name="My Image" disk_format=raw container_format=ovf \\
distro="Ubuntu 10.04 LTS" < /tmp/myimage.iso"""
c = get_client(options)

try:
Expand All @@ -220,10 +220,13 @@ EXAMPLES
fields.pop('is_public', False)),
'protected': utils.bool_from_string(
fields.pop('protected', False)),
'disk_format': fields.pop('disk_format', 'raw'),
'min_disk': fields.pop('min_disk', 0),
'min_ram': fields.pop('min_ram', 0),
'container_format': fields.pop('container_format', 'ovf')}
}

for format in ['disk_format', 'container_format']:
if format in fields:
image_meta[format] = fields.pop(format)

# Strip any args that are not supported
unsupported_fields = ['status', 'size']
Expand Down
47 changes: 29 additions & 18 deletions doc/source/glance.rst
Expand Up @@ -131,8 +131,8 @@ like so::
name A name for the image.
is_public If specified, interpreted as a boolean value
and sets or unsets the image's availability to the public.
disk_format Format of the disk image
container_format Format of the container
disk_format Format of the disk image (required)
container_format Format of the container (required)

All other field names are considered to be custom properties so be careful
to spell field names correctly. :)
Expand Down Expand Up @@ -186,21 +186,27 @@ that the image should be public -- anyone should be able to fetch it.
Here is how we'd upload this image to Glance. Change example IP number to your
server IP number.::

$> glance add name="My Image" is_public=true < /tmp/images/myimage.iso \
--host=65.114.169.29
$> glance add name="My Image" is_public=true \
container_format=ovf disk_format=raw \
--host=65.114.169.29 < /tmp/images/myimage.iso

Note that the disk container formats are no longer defaulted and are thus
strictly required.

If Glance was able to successfully upload and store your VM image data and
metadata attributes, you would see something like this::

$> glance add name="My Image" is_public=true < /tmp/images/myimage.iso \
--host=65.114.169.29
$> glance add name="My Image" is_public=true \
container_format=ovf disk_format=raw \
--host=65.114.169.29 < /tmp/images/myimage.iso
Added new image with ID: 991baaf9-cc0d-4183-a201-8facdf1a1430

You can use the ``--verbose`` (or ``-v``) command-line option to print some more
information about the metadata that was saved with the image::

$> glance --verbose add name="My Image" is_public=true < \
/tmp/images/myimage.iso --host=65.114.169.29
$> glance --verbose add name="My Image" is_public=true \
container_format=ovf disk_format=raw \
--host=65.114.169.29 < /tmp/images/myimage.iso
Added new image with ID: 541424be-27b1-49d6-a55b-6430b8ae0f5f
Returned the following metadata for the new image:
container_format => ovf
Expand All @@ -221,8 +227,9 @@ information about the metadata that was saved with the image::
If you are unsure about what will be added, you can use the ``--dry-run``
command-line option, which will simply show you what *would* have happened::

$> glance --dry-run add name="Foo" distro="Ubuntu" is_public=True < \
/tmp/images/myimage.iso --host=65.114.169.29
$> glance --dry-run add name="Foo" distro="Ubuntu" is_public=True \
container_format=ovf disk_format=raw \
--host=65.114.169.29 < /tmp/images/myimage.iso
Dry run. We would have done the following:
Add new image with metadata:
container_format => ovf
Expand All @@ -243,42 +250,46 @@ Examples of uploading different kinds of images

To upload an EC2 tarball VM image::

$> glance add name="ubuntu-10.10-amd64" is_public=true < \
/root/maverick-server-uec-amd64.tar.gz
$> glance add name="ubuntu-10.10-amd64" is_public=true \
container_format=ovf disk_format=raw \
< /root/maverick-server-uec-amd64.tar.gz

To upload an EC2 tarball VM image with an associated property (e.g., distro)::

$> glance add name="ubuntu-10.10-amd64" is_public=true \
container_format=ovf disk_format=raw \
distro="ubuntu 10.10" < /root/maverick-server-uec-amd64.tar.gz

To upload an EC2 tarball VM image from a URL::

$> glance add name="uubntu-10.04-amd64" is_public=true \
container_format=ovf disk_format=raw \
location="http://uec-images.ubuntu.com/lucid/current/\
lucid-server-uec-amd64.tar.gz"

To upload a qcow2 image::

$> glance add name="ubuntu-11.04-amd64" is_public=true \
distro="ubuntu 11.04" disk_format="qcow2" < /data/images/rock_natty.qcow2
container_format=ovf disk_format=qcow2 \
distro="ubuntu 11.04" < /data/images/rock_natty.qcow2

To upload a kernel file, ramdisk file and filesystem image file::

$> glance add --disk-format=aki --container-format=aki \
$> glance add disk_format=aki container_format=aki \
./maverick-server-uec-amd64-vmlinuz-virtual \
maverick-server-uec-amd64-vmlinuz-virtual
$> glance add --disk-format=ari --container-format=ari \
$> glance add disk_format=ari container_format=ari \
./maverick-server-uec-amd64-loader maverick-server-uec-amd64-loader
# Determine what the ids associated with the kernel and ramdisk files
$> glance index
# Assuming the ids are 7 and 8:
$> glance add --disk-format=ami --container-format=ami --kernel=7 \
$> glance add disk_format=ami container_format=ami --kernel=7 \
--ramdisk=8 ./maverick-server-uec-amd64.img maverick-server-uec-amd64.img

To upload a raw image file::

$> glance add --disk_format=raw ./maverick-server-uec-amd64.img \
maverick-server-uec-amd64.img_v2
$> glance add disk_format=raw container_format=ovf \
./maverick-server-uec-amd64.img maverick-server-uec-amd64.img_v2


Register a virtual machine image in another location
Expand Down
12 changes: 6 additions & 6 deletions doc/source/glanceapi.rst
Expand Up @@ -181,8 +181,8 @@ following shows an example of the HTTP headers returned from the above

x-image-meta-uri http://glance.example.com/images/71c675ab-d94f-49cd-a114-e12490b328d9
x-image-meta-name Ubuntu 10.04 Plain 5GB
x-image-meta-disk-format vhd
x-image-meta-container-format ovf
x-image-meta-disk_format vhd
x-image-meta-container_format ovf
x-image-meta-size 5368709120
x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3
x-image-meta-created_at 2010-02-03 09:34:01
Expand Down Expand Up @@ -244,8 +244,8 @@ returned from the above ``GET`` request::

x-image-meta-uri http://glance.example.com/images/71c675ab-d94f-49cd-a114-e12490b328d9
x-image-meta-name Ubuntu 10.04 Plain 5GB
x-image-meta-disk-format vhd
x-image-meta-container-format ovf
x-image-meta-disk_format vhd
x-image-meta-container_format ovf
x-image-meta-size 5368709120
x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3
x-image-meta-created_at 2010-02-03 09:34:01
Expand Down Expand Up @@ -353,14 +353,14 @@ The list of metadata headers that Glance accepts are listed below.
store that is marked default. See the configuration option ``default_store``
for more information.

* ``x-image-meta-disk-format``
* ``x-image-meta-disk_format``

This header is optional. Valid values are one of ``aki``, ``ari``, ``ami``,
``raw``, ``iso``, ``vhd``, ``vdi``, ``qcow2``, or ``vmdk``.

For more information, see :doc:`About Disk and Container Formats <formats>`

* ``x-image-meta-container-format``
* ``x-image-meta-container_format``

This header is optional. Valid values are one of ``aki``, ``ari``, ``ami``,
``bare``, or ``ovf``.
Expand Down
18 changes: 8 additions & 10 deletions glance/common/utils.py
Expand Up @@ -77,16 +77,14 @@ def image_meta_to_http_headers(image_meta):
"""
headers = {}
for k, v in image_meta.items():
if v is None:
v = ''
if k == 'properties':
for pk, pv in v.items():
if pv is None:
pv = ''
headers["x-image-meta-property-%s"
% pk.lower()] = unicode(pv)
else:
headers["x-image-meta-%s" % k.lower()] = unicode(v)
if v is not None:
if k == 'properties':
for pk, pv in v.items():
if pv is not None:
headers["x-image-meta-property-%s"
% pk.lower()] = unicode(pv)
else:
headers["x-image-meta-%s" % k.lower()] = unicode(v)
return headers


Expand Down
4 changes: 2 additions & 2 deletions glance/registry/db/api.py
Expand Up @@ -313,11 +313,11 @@ def validate_image(values):
msg = "Invalid image status '%s' for image." % status
raise exception.Invalid(msg)

if disk_format and disk_format not in DISK_FORMATS:
if not disk_format or disk_format not in DISK_FORMATS:
msg = "Invalid disk format '%s' for image." % disk_format
raise exception.Invalid(msg)

if container_format and container_format not in CONTAINER_FORMATS:
if not container_format or container_format not in CONTAINER_FORMATS:
msg = "Invalid container format '%s' for image." % container_format
raise exception.Invalid(msg)

Expand Down

0 comments on commit 62c913c

Please sign in to comment.