Adds Image service v1 and v2 specification info in general
Goal is to maintain API specs in the specs repo for each project and to eliminate the image-api repo. Splits up original v2 API document into multiple files. Change-Id: I7b6fbb1ee4a9a2e04395a7aa942d9ebdb011cc85
This commit is contained in:
parent
113c8a55f1
commit
f46438ab1c
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ build
|
|||||||
*.swo
|
*.swo
|
||||||
*.pyc
|
*.pyc
|
||||||
.testrepository
|
.testrepository
|
||||||
|
.DS_Store
|
||||||
|
@ -28,6 +28,43 @@ Kilo approved specs:
|
|||||||
|
|
||||||
specs/kilo/*
|
specs/kilo/*
|
||||||
|
|
||||||
|
====================
|
||||||
|
Image service V2 API
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
specs/api/v2/image-api-v2.rst
|
||||||
|
specs/api/v2/image-metadata-api-v2.rst
|
||||||
|
specs/api/v2/image-binary-data-api-v2.rst
|
||||||
|
specs/api/v2/lists-image-api-v2.rst
|
||||||
|
specs/api/v2/retrieve-image-api-v2.rst
|
||||||
|
specs/api/v2/delete-image-api-v2.rst
|
||||||
|
specs/api/v2/sharing-image-api-v2.rst
|
||||||
|
specs/api/v2/http-patch-image-api-v2.rst
|
||||||
|
|
||||||
|
====================
|
||||||
|
Image service V1 API
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
specs/api/v1/image_service_v1_api
|
||||||
|
specs/api/v1/authentication
|
||||||
|
specs/api/v1/adding_a_new_virtual_machine_image
|
||||||
|
specs/api/v1/retrieving_a_virtual_machine_image
|
||||||
|
specs/api/v1/requesting_detailed_metadata_on_a_specific_image
|
||||||
|
specs/api/v1/requesting_detailed_metadata_on_public_vm_images
|
||||||
|
specs/api/v1/requesting_shared_images
|
||||||
|
specs/api/v1/requesting_image_memberships
|
||||||
|
specs/api/v1/adding_a_member_to_an_image
|
||||||
|
specs/api/v1/removing_a_member_from_an_image
|
||||||
|
specs/api/v1/replacing_a_membership_list_for_an_image
|
||||||
|
specs/api/v1/filtering_images_returned_via_get__images_and_get__images_detail
|
||||||
|
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
21
specs/api/v1/adding_a_member_to_an_image.rst
Normal file
21
specs/api/v1/adding_a_member_to_an_image.rst
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
===========================
|
||||||
|
Adding a Member to an Image
|
||||||
|
===========================
|
||||||
|
|
||||||
|
We want to authorize a tenant to access a private image. We issue a
|
||||||
|
``PUT`` request to
|
||||||
|
``http://glance.example.com/images/1/members/tenant1``. With no body,
|
||||||
|
this will add the membership to the image, leaving existing memberships
|
||||||
|
unmodified and defaulting new memberships to have \`can\_share\` set to
|
||||||
|
\`false\`. We may also optionally attach a body of the following form:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'member':
|
||||||
|
{'can_share': true}
|
||||||
|
}
|
||||||
|
|
||||||
|
If such a body is provided, both existing and new memberships will have
|
||||||
|
\`can\_share\` set to the provided value (either \`true\` or \`false\`).
|
||||||
|
This query will return a 204 ("No Content") status code.
|
||||||
|
|
173
specs/api/v1/adding_a_new_virtual_machine_image.rst
Normal file
173
specs/api/v1/adding_a_new_virtual_machine_image.rst
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
==================================
|
||||||
|
Adding a New Virtual Machine Image
|
||||||
|
==================================
|
||||||
|
|
||||||
|
We have created a new virtual machine image in some way (created a
|
||||||
|
"golden image" or snapshotted/backed up an existing image) and we wish
|
||||||
|
to do two things:
|
||||||
|
|
||||||
|
- Store the disk image data in Glance
|
||||||
|
|
||||||
|
- Store metadata about this image in Glance
|
||||||
|
|
||||||
|
We can do the above two activities in a single call to the Glance API.
|
||||||
|
Assuming, like in the examples above, that a Glance API server is
|
||||||
|
running at ``glance.example.com``, we issue a ``POST`` request to add an
|
||||||
|
image to Glance:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
POST http://glance.example.com/images/
|
||||||
|
|
||||||
|
The metadata about the image is sent to Glance in HTTP headers. The body
|
||||||
|
of the HTTP request to the Glance API will be the MIME-encoded disk
|
||||||
|
image data.
|
||||||
|
|
||||||
|
Adding Image Metadata in HTTP Headers
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Glance will view as image metadata any HTTP header that it receives in a
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
``POST`` request where the header key is prefixed with the strings
|
||||||
|
``x-image-meta-`` and ``x-image-meta-property-``.
|
||||||
|
|
||||||
|
The list of metadata headers that Glance accepts are listed below.
|
||||||
|
|
||||||
|
- ``x-image-meta-name``
|
||||||
|
|
||||||
|
This header is optional . Its value should be the name of the image.
|
||||||
|
|
||||||
|
Note that the name of an image *is not unique to a Glance node*. It
|
||||||
|
would be an unrealistic expectation of users to know all the unique
|
||||||
|
names of all other user's images.
|
||||||
|
|
||||||
|
- ``x-image-meta-id``
|
||||||
|
|
||||||
|
This header is optional.
|
||||||
|
|
||||||
|
When present, Glance will use the supplied identifier for the image.
|
||||||
|
If the identifier already exists in that Glance node, then a **409
|
||||||
|
Conflict** will be returned by Glance.
|
||||||
|
|
||||||
|
When this header is *not* present, Glance will generate an identifier
|
||||||
|
for the image and return this identifier in the response (see below)
|
||||||
|
|
||||||
|
- ``x-image-meta-store``
|
||||||
|
|
||||||
|
This header is optional. Valid values are one of ``file``, ``s3``, or
|
||||||
|
``swift``
|
||||||
|
|
||||||
|
When present, Glance will attempt to store the disk image data in the
|
||||||
|
backing store indicated by the value of the header. If the Glance
|
||||||
|
node does not support the backing store, Glance will return a **400
|
||||||
|
Bad Request**.
|
||||||
|
|
||||||
|
When not present, Glance will store the disk image data in the
|
||||||
|
backing store that is marked default. See the configuration option
|
||||||
|
``default_store`` for more information.
|
||||||
|
|
||||||
|
- ``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``
|
||||||
|
|
||||||
|
This header is optional. Valid values are one of ``aki``, ``ari``,
|
||||||
|
``ami``, ``bare``, or ``ovf``.
|
||||||
|
|
||||||
|
For more information, see :doc:\`About Disk and Container Formats
|
||||||
|
<formats>\`
|
||||||
|
|
||||||
|
- ``x-image-meta-size``
|
||||||
|
|
||||||
|
This header is optional.
|
||||||
|
|
||||||
|
When present, Glance assumes that the expected size of the request
|
||||||
|
body will be the value of this header. If the length in bytes of the
|
||||||
|
request body *does not match* the value of this header, Glance will
|
||||||
|
return a **400 Bad Request**.
|
||||||
|
|
||||||
|
When not present, Glance will calculate the image's size based on the
|
||||||
|
size of the request body.
|
||||||
|
|
||||||
|
- ``x-image-meta-checksum``
|
||||||
|
|
||||||
|
This header is optional. When present it shall be the expected
|
||||||
|
**MD5** checksum of the image file data.
|
||||||
|
|
||||||
|
When present, Glance will verify the checksum generated from the
|
||||||
|
backend store when storing your image against this value and return a
|
||||||
|
**400 Bad Request** if the values do not match.
|
||||||
|
|
||||||
|
- ``x-image-meta-is-public``
|
||||||
|
|
||||||
|
This header is optional.
|
||||||
|
|
||||||
|
When Glance finds the string "true" (case-insensitive), the image is
|
||||||
|
marked as a public image, meaning that any user may view its metadata
|
||||||
|
and may read the disk image from Glance.
|
||||||
|
|
||||||
|
When not present, the image is assumed to be *not public* and
|
||||||
|
specific to a user.
|
||||||
|
|
||||||
|
- ``x-image-meta-owner``
|
||||||
|
|
||||||
|
This header is optional and only meaningful for admins.
|
||||||
|
|
||||||
|
Glance normally sets the owner of an image to be the tenant or user
|
||||||
|
(depending on the "owner\_is\_tenant" configuration option) of the
|
||||||
|
authenticated user issuing the request. However, if the authenticated
|
||||||
|
user has the Admin role, this default may be overridden by setting
|
||||||
|
this header to null or to a string identifying the owner of the
|
||||||
|
image.
|
||||||
|
|
||||||
|
- ``x-image-meta-property-*``
|
||||||
|
|
||||||
|
When Glance receives any HTTP header whose key begins with the string
|
||||||
|
prefix ``x-image-meta-property-``, Glance adds the key and value to a
|
||||||
|
set of custom, free-form image properties stored with the image. The
|
||||||
|
key is the lower-cased string following the prefix
|
||||||
|
``x-image-meta-property-`` with dashes and punctuation replaced with
|
||||||
|
underscores.
|
||||||
|
|
||||||
|
For example, if the following HTTP header were sent:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
x-image-meta-property-distro Ubuntu 10.10
|
||||||
|
|
||||||
|
Then a key/value pair of "distro"/"Ubuntu 10.10" will be stored with
|
||||||
|
the image in Glance.
|
||||||
|
|
||||||
|
There is no limit on the number of free-form key/value attributes
|
||||||
|
that can be attached to the image. However, keep in mind that the 8K
|
||||||
|
limit on the size of all HTTP headers sent in a request will
|
||||||
|
effectively limit the number of image properties.
|
||||||
|
|
||||||
|
Updating an Image
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Glance will view as image metadata any HTTP header that it receives in a
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
``PUT`` request where the header key is prefixed with the strings
|
||||||
|
``x-image-meta-`` and ``x-image-meta-property-``.
|
||||||
|
|
||||||
|
If an image was previously reserved, and thus is in the ``queued``
|
||||||
|
state, then image data can be added by including it as the request body.
|
||||||
|
If the image already as data associated with it (e.g. not in the
|
||||||
|
``queued`` state), then including a request body will result in a **409
|
||||||
|
Conflict** exception.
|
||||||
|
|
||||||
|
On success, the ``PUT`` request will return the image metadata encoded
|
||||||
|
as HTTP headers.
|
||||||
|
|
||||||
|
See more about image statuses here: :doc:\`Image Statuses <statuses>\`
|
||||||
|
|
30
specs/api/v1/authentication.rst
Normal file
30
specs/api/v1/authentication.rst
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Authentication
|
||||||
|
--------------
|
||||||
|
|
||||||
|
You can optionally integrate Glance with the OpenStack Identity Service
|
||||||
|
project. Setting this up is relatively straightforward: the Identity
|
||||||
|
Service distribution at http://github.com/openstack/keystone includes
|
||||||
|
the requisite middleware and examples of appropriately modified
|
||||||
|
glance-api.conf and glance-registry.conf configuration files in the
|
||||||
|
examples/paste directory. Once you have installed Keystone and edited
|
||||||
|
your configuration files, newly created images will have their owner
|
||||||
|
attribute set to the tenant of the authenticated users, and the
|
||||||
|
is\_public attribute will cause access to those images for which it is
|
||||||
|
false to be restricted to only the owner.
|
||||||
|
|
||||||
|
The exception is those images for which owner is set to null, which may
|
||||||
|
only be done by those users having the Admin role. These images may
|
||||||
|
still be accessed by the public, but will not appear in the list of
|
||||||
|
public images. This allows the Glance Registry owner to publish images
|
||||||
|
for beta testing without allowing those images to show up in lists,
|
||||||
|
potentially confusing users.
|
||||||
|
|
||||||
|
It is possible to allow a private image to be shared with one or more
|
||||||
|
alternate tenants. This is done through image memberships, which are
|
||||||
|
available via the members resource of images. (For more details, see the
|
||||||
|
next chapter.) Essentially, a membership is an association between an
|
||||||
|
image and a tenant which has permission to access that image. These
|
||||||
|
membership associations may also have a can\_share attribute, which, if
|
||||||
|
set to true, delegates the authority to share an image to the named
|
||||||
|
tenant.
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
================================================================
|
||||||
|
Filtering Images Returned via GET /images and GET /images/detail
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
Both the ``GET /images`` and ``GET /images/detail`` requests
|
||||||
|
take query parameters that serve to filter the returned list of images.
|
||||||
|
The following list details these query parameters.
|
||||||
|
|
||||||
|
- ``name=NAME``
|
||||||
|
|
||||||
|
Filters images having a ``name`` attribute matching ``NAME``.
|
||||||
|
|
||||||
|
- ``container_format=FORMAT``
|
||||||
|
|
||||||
|
Filters images having a ``container_format`` attribute matching
|
||||||
|
``FORMAT``
|
||||||
|
|
||||||
|
For more information, see :doc:\`About Disk and Container Formats
|
||||||
|
<formats>\`
|
||||||
|
|
||||||
|
- ``disk_format=FORMAT``
|
||||||
|
|
||||||
|
Filters images having a ``disk_format`` attribute matching ``FORMAT``
|
||||||
|
|
||||||
|
For more information, see :doc:\`About Disk and Container Formats
|
||||||
|
<formats>\`
|
||||||
|
|
||||||
|
- ``status=STATUS``
|
||||||
|
|
||||||
|
Filters images having a ``status`` attribute matching ``STATUS``
|
||||||
|
|
||||||
|
For more information, see :doc:\`About Image Statuses <statuses>\`
|
||||||
|
|
||||||
|
- ``size_min=BYTES``
|
||||||
|
|
||||||
|
Filters images having a ``size`` attribute greater than or equal to
|
||||||
|
``BYTES``
|
||||||
|
|
||||||
|
- ``size_max=BYTES``
|
||||||
|
|
||||||
|
Filters images having a ``size`` attribute less than or equal to
|
||||||
|
``BYTES``
|
||||||
|
|
||||||
|
These two resources also accept sort parameters:
|
||||||
|
|
||||||
|
- ``sort_key=KEY``
|
||||||
|
|
||||||
|
Results will be ordered by the specified image attribute ``KEY``.
|
||||||
|
Accepted values include ``id``, ``name``, ``status``,
|
||||||
|
``disk_format``, ``container_format``, ``size``, ``created_at``
|
||||||
|
(default) and ``updated_at``.
|
||||||
|
|
||||||
|
- ``sort_dir=DIR``
|
||||||
|
|
||||||
|
Results will be sorted in the direction ``DIR``. Accepted values are
|
||||||
|
``asc`` for ascending or ``desc`` (default) for descending.
|
||||||
|
|
67
specs/api/v1/image_service_v1_api.rst
Normal file
67
specs/api/v1/image_service_v1_api.rst
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
=========================
|
||||||
|
Image service v1 REST API
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The OpenStack Image service offers retrieval, storage, and metadata
|
||||||
|
assignment for your images that you want to run in your OpenStack cloud.
|
||||||
|
The project is code-named Glance.
|
||||||
|
|
||||||
|
OpenStack Image service enables users to store and retrieve images
|
||||||
|
through a simple Web Service (ReST: Representational State Transfer)
|
||||||
|
interface.
|
||||||
|
|
||||||
|
For more details on the OpenStack Image service, please refer to
|
||||||
|
`docs.openstack.org/developer/glance/ <http://docs.openstack.org/developer/glance/>`__
|
||||||
|
|
||||||
|
We welcome feedback, comments, and bug reports at
|
||||||
|
`bugs.launchpad.net/glance <http://bugs.launchpad.net/glance>`__.
|
||||||
|
|
||||||
|
Intended Audience
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
This guide is intended to assist software developers who want to develop
|
||||||
|
applications using the OpenStack Image Service API. It fully documents
|
||||||
|
the ReST application programming interface (API) that allows developers
|
||||||
|
to interact with the storage components of the OpenStack Image system.
|
||||||
|
To use the information provided here, you should first have a general
|
||||||
|
understanding of the OpenStack Image Service and have access to an
|
||||||
|
installation of OpenStack Image Service. You should also be familiar
|
||||||
|
with:
|
||||||
|
|
||||||
|
- ReSTful web services
|
||||||
|
|
||||||
|
- HTTP/1.1
|
||||||
|
|
||||||
|
Glance has a RESTful API that exposes both metadata about registered
|
||||||
|
virtual machine images and the image data itself.
|
||||||
|
|
||||||
|
A host that runs the ``bin/glance-api`` service is said to be a *Glance
|
||||||
|
API Server*.
|
||||||
|
|
||||||
|
Assume there is a Glance API server running at the URL
|
||||||
|
``http://glance.example.com``.
|
||||||
|
|
||||||
|
Let's walk through how a user might request information from this
|
||||||
|
server.
|
||||||
|
|
||||||
|
Requesting a List of Public VM Images
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
We want to see a list of available virtual machine images that the
|
||||||
|
Glance server knows about.
|
||||||
|
|
||||||
|
We issue a ``GET`` request to ``http://glance.example.com/images/`` to
|
||||||
|
retrieve this list of available *public* images. The data is returned as
|
||||||
|
a JSON-encoded mapping in the following format:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'images': [
|
||||||
|
{'status: 'active',
|
||||||
|
'name': 'Ubuntu 10.04 Plain',
|
||||||
|
'disk_format': 'vhd',
|
||||||
|
'container_format': 'ovf',
|
||||||
|
'size': '5368709120'}
|
||||||
|
...]}
|
||||||
|
|
||||||
|
All images returned from the above `GET` request are public images
|
9
specs/api/v1/removing_a_member_from_an_image.rst
Normal file
9
specs/api/v1/removing_a_member_from_an_image.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
===============================
|
||||||
|
Removing a Member from an Image
|
||||||
|
===============================
|
||||||
|
|
||||||
|
We want to revoke a tenant's right to access a private image. We issue a
|
||||||
|
``DELETE`` request to
|
||||||
|
``http://glance.example.com/images/1/members/tenant1``. This query will
|
||||||
|
return a 204 ("No Content") status code.
|
||||||
|
|
22
specs/api/v1/replacing_a_membership_list_for_an_image.rst
Normal file
22
specs/api/v1/replacing_a_membership_list_for_an_image.rst
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
========================================
|
||||||
|
Replacing a Membership List for an Image
|
||||||
|
========================================
|
||||||
|
|
||||||
|
The full membership list for a given image may be replaced. We issue a
|
||||||
|
``PUT`` request to ``http://glance.example.com/images/1/members`` with a
|
||||||
|
body of the following form:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'memberships': [
|
||||||
|
{'member_id': 'tenant1',
|
||||||
|
'can_share': false}
|
||||||
|
...]}
|
||||||
|
|
||||||
|
All existing memberships which are not named in the replacement body are
|
||||||
|
removed, and those which are named have their \`can\_share\` settings
|
||||||
|
changed as specified. (The \`can\_share\` setting may be omitted, which
|
||||||
|
will cause that setting to remain unchanged in the existing
|
||||||
|
memberships.) All new memberships will be created, with \`can\_share\`
|
||||||
|
defaulting to \`false\` if it is not specified.
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
================================================
|
||||||
|
Requesting Detailed Metadata on a Specific Image
|
||||||
|
================================================
|
||||||
|
|
||||||
|
We want to see detailed information for a specific virtual machine image
|
||||||
|
that the Glance server knows about.
|
||||||
|
|
||||||
|
We have queried the Glance server for a list of public images and the
|
||||||
|
data returned includes the \`uri\` field for each available image. This
|
||||||
|
\`uri\` field value contains the exact location needed to get the
|
||||||
|
metadata for a specific image.
|
||||||
|
|
||||||
|
Continuing the example from above, in order to get metadata about the
|
||||||
|
first public image returned, we can issue a ``HEAD`` request to the
|
||||||
|
Glance server for the image's URI.
|
||||||
|
|
||||||
|
We issue a ``HEAD`` request to ``http://glance.example.com/images/1`` to
|
||||||
|
retrieve complete metadata for that image. The metadata is returned as a
|
||||||
|
set of HTTP headers that begin with the prefix ``x-image-meta-``. The
|
||||||
|
following shows an example of the HTTP headers returned from the above
|
||||||
|
``HEAD`` request:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
x-image-meta-name Ubuntu 10.04 Plain 5GB
|
||||||
|
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-location swift://account:key/container/image.tar.gz.0
|
||||||
|
x-image-meta-created_at 2010-02-03 09:34:01
|
||||||
|
x-image-meta-updated_at 2010-02-03 09:34:01
|
||||||
|
x-image-meta-deleted_at
|
||||||
|
x-image-meta-status available
|
||||||
|
x-image-meta-is-public true
|
||||||
|
x-image-meta-owner null
|
||||||
|
x-image-meta-property-distro Ubuntu 10.04 LTS
|
||||||
|
|
||||||
|
All timestamps returned are in UTC The \`x-image-meta-updated\_at\`
|
||||||
|
timestamp is the timestamp when an image's metadata was last updated,
|
||||||
|
not its image data, as all image data is immutable once stored in Glance
|
||||||
|
There may be multiple headers that begin with the prefix
|
||||||
|
\`x-image-meta-property-\`. These headers are free-form key/value pairs
|
||||||
|
that have been saved with the image metadata. The key is the string
|
||||||
|
after \`x-image-meta-property-\` and the value is the value of the
|
||||||
|
header The response's \`ETag\` header will always be equal to the
|
||||||
|
\`x-image-meta-checksum\` value The response's
|
||||||
|
\`x-image-meta-is-public\` value is a boolean indicating whether the
|
||||||
|
image is publicly available The response's \`x-image-meta-owner\` value
|
||||||
|
is a string which may either be null or which will indicate the owner of
|
||||||
|
the image.
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
================================================
|
||||||
|
Requesting Detailed Metadata on Public VM Images
|
||||||
|
================================================
|
||||||
|
|
||||||
|
We want to see more detailed information on available virtual machine
|
||||||
|
images that the Glance server knows about.
|
||||||
|
|
||||||
|
We issue a ``GET`` request to
|
||||||
|
``http://glance.example.com/images/detail`` to retrieve this list of
|
||||||
|
available *public* images. The data is returned as a JSON-encoded
|
||||||
|
mapping in the following format:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'images': [
|
||||||
|
{'name': 'Ubuntu 10.04 Plain 5GB',
|
||||||
|
'disk_format': 'vhd',
|
||||||
|
'container_format': 'ovf',
|
||||||
|
'size': '5368709120',
|
||||||
|
'checksum': 'c2e5db72bd7fd153f53ede5da5a06de3',
|
||||||
|
'location': 'swift://account:key/container/image.tar.gz.0',
|
||||||
|
'created_at': '2010-02-03 09:34:01',
|
||||||
|
'updated_at': '2010-02-03 09:34:01',
|
||||||
|
'deleted_at': '',
|
||||||
|
'status': 'active',
|
||||||
|
'is_public': true,
|
||||||
|
'owner': null,
|
||||||
|
'properties': {'distro': 'Ubuntu 10.04 LTS'}},
|
||||||
|
...]}
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
All images returned from the above `GET` request are public images
|
||||||
|
|
||||||
|
All timestamps returned are in UTC
|
||||||
|
|
||||||
|
The `updated_at` timestamp is the timestamp when an image's metadata
|
||||||
|
was last updated, not its image data, as all image data is immutable
|
||||||
|
once stored in Glance
|
||||||
|
|
||||||
|
The `properties` field is a mapping of free-form key/value pairs that
|
||||||
|
have been saved with the image metadata
|
||||||
|
|
||||||
|
The `checksum` field is an MD5 checksum of the image file data
|
||||||
|
|
||||||
|
The `is_public` field is a boolean indicating whether the image is
|
||||||
|
publicly available
|
||||||
|
|
||||||
|
The `owner` field is a string which may either be null or which will
|
||||||
|
indicate the owner of the image
|
||||||
|
|
26
specs/api/v1/requesting_image_memberships.rst
Normal file
26
specs/api/v1/requesting_image_memberships.rst
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
============================
|
||||||
|
Requesting Image Memberships
|
||||||
|
============================
|
||||||
|
|
||||||
|
We want to see a list of the other system tenants (or users, if
|
||||||
|
"owner\_is\_tenant" is False) that may access a given virtual machine
|
||||||
|
image that the Glance server knows about. We take the \`uri\` field of
|
||||||
|
the image data, append ``/members`` to it, and issue a ``GET`` request
|
||||||
|
on the resulting URL.
|
||||||
|
|
||||||
|
Continuing from the example above, in order to get the memberships for
|
||||||
|
the first public image returned, we can issue a ``GET`` request to the
|
||||||
|
Glance server for ``http://glance.example.com/images/1/members``. What
|
||||||
|
we will get back is JSON data such as the following:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'members': [
|
||||||
|
{'member_id': 'tenant1',
|
||||||
|
'can_share': false}
|
||||||
|
...]}
|
||||||
|
|
||||||
|
The \`member\_id\` field identifies a tenant with which the image is
|
||||||
|
shared. If that tenant is authorized to further share the image, the
|
||||||
|
\`can\_share\` field is \`true\`.
|
||||||
|
|
20
specs/api/v1/requesting_shared_images.rst
Normal file
20
specs/api/v1/requesting_shared_images.rst
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
========================
|
||||||
|
Requesting Shared Images
|
||||||
|
========================
|
||||||
|
|
||||||
|
We want to see a list of images which are shared with a given tenant. We
|
||||||
|
issue a ``GET`` request to
|
||||||
|
``http://glance.example.com/shared-images/tenant1``. We will get back
|
||||||
|
JSON data such as the following:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
{'shared_images': [
|
||||||
|
{'image_id': 1,
|
||||||
|
'can_share': false}
|
||||||
|
...]}
|
||||||
|
|
||||||
|
The \`image\_id\` field identifies an image shared with the tenant named
|
||||||
|
by *member\_id*. If the tenant is authorized to further share the image,
|
||||||
|
the \`can\_share\` field is \`true\`.
|
||||||
|
|
69
specs/api/v1/retrieving_a_virtual_machine_image.rst
Normal file
69
specs/api/v1/retrieving_a_virtual_machine_image.rst
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
==================================
|
||||||
|
Retrieving a Virtual Machine Image
|
||||||
|
==================================
|
||||||
|
|
||||||
|
We want to retrieve that actual raw data for a specific virtual machine
|
||||||
|
image that the Glance server knows about.
|
||||||
|
|
||||||
|
We have queried the Glance server for a list of public images and the
|
||||||
|
data returned includes the \`uri\` field for each available image. This
|
||||||
|
\`uri\` field value contains the exact location needed to get the
|
||||||
|
metadata for a specific image.
|
||||||
|
|
||||||
|
Continuing the example from above, in order to get metadata about the
|
||||||
|
first public image returned, we can issue a ``HEAD`` request to the
|
||||||
|
Glance server for the image's URI.
|
||||||
|
|
||||||
|
We issue a ``GET`` request to ``http://glance.example.com/images/1`` to
|
||||||
|
retrieve metadata for that image as well as the image itself encoded
|
||||||
|
into the response body.
|
||||||
|
|
||||||
|
The metadata is returned as a set of HTTP headers that begin with the
|
||||||
|
prefix ``x-image-meta-``. The following shows an example of the HTTP
|
||||||
|
headers returned from the above ``GET`` request:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
x-image-meta-name Ubuntu 10.04 Plain 5GB
|
||||||
|
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-location swift://account:key/container/image.tar.gz.0
|
||||||
|
x-image-meta-created_at 2010-02-03 09:34:01
|
||||||
|
x-image-meta-updated_at 2010-02-03 09:34:01
|
||||||
|
x-image-meta-deleted_at
|
||||||
|
x-image-meta-status available
|
||||||
|
x-image-meta-is-public true
|
||||||
|
x-image-meta-owner null
|
||||||
|
x-image-meta-property-distro Ubuntu 10.04 LTS
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
All timestamps returned are in UTC
|
||||||
|
|
||||||
|
The `x-image-meta-updated_at` timestamp is the timestamp when an
|
||||||
|
image's metadata was last updated, not its image data, as all
|
||||||
|
image data is immutable once stored in Glance
|
||||||
|
|
||||||
|
There may be multiple headers that begin with the prefix
|
||||||
|
`x-image-meta-property-`. These headers are free-form key/value pairs
|
||||||
|
that have been saved with the image metadata. The key is the string
|
||||||
|
after `x-image-meta-property-` and the value is the value of the header
|
||||||
|
|
||||||
|
The response's `Content-Length` header shall be equal to the value of
|
||||||
|
the `x-image-meta-size` header
|
||||||
|
|
||||||
|
The response's `ETag` header will always be equal to the
|
||||||
|
`x-image-meta-checksum` value
|
||||||
|
|
||||||
|
The response's `x-image-meta-is-public` value is a boolean indicating
|
||||||
|
whether the image is publicly available
|
||||||
|
|
||||||
|
The response's `x-image-meta-owner` value is a string which may either
|
||||||
|
be null or which will indicate the owner of the image
|
||||||
|
|
||||||
|
The image data itself will be the body of the HTTP response returned
|
||||||
|
from the request, which will have content-type of
|
||||||
|
`application/octet-stream`.
|
||||||
|
|
14
specs/api/v2/delete-image-api-v2.rst
Normal file
14
specs/api/v2/delete-image-api-v2.rst
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Delete an Image
|
||||||
|
---------------
|
||||||
|
|
||||||
|
**DELETE /v2/images/<IMAGE\_ID>**
|
||||||
|
|
||||||
|
Encode the ID of the image into the request URI. Request body is
|
||||||
|
ignored.
|
||||||
|
|
||||||
|
Images with the 'protected' attribute set to true (boolean) cannot be
|
||||||
|
deleted and the response will have an HTTP 403 status code. You must
|
||||||
|
first set the 'protected' attribute to false (boolean) and then perform
|
||||||
|
the delete.
|
||||||
|
|
||||||
|
The response will be empty with an HTTP 204 status code.
|
228
specs/api/v2/http-patch-image-api-v2.rst
Normal file
228
specs/api/v2/http-patch-image-api-v2.rst
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
Image API v2 HTTP PATCH media types
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
The HTTP PATCH request must provide a media type for the server to
|
||||||
|
determine how the patch should be applied to an image resource. An
|
||||||
|
unsupported media type will result in an HTTP error response with the
|
||||||
|
415 status code. For image resources, two media types are supported:
|
||||||
|
|
||||||
|
- ``application/openstack-images-v2.1-json-patch``
|
||||||
|
- ``application/openstack-images-v2.0-json-patch``
|
||||||
|
|
||||||
|
The ``application/openstack-images-v2.1-json-patch`` media type is
|
||||||
|
intended to provide a useful and compatible subset of the functionality
|
||||||
|
defined in JavaScript Object Notation (JSON) Patch
|
||||||
|
`RFC6902 <http://tools.ietf.org/html/rfc6902>`__, which defines the
|
||||||
|
``application/json-patch+json`` media type.
|
||||||
|
|
||||||
|
The ``application/openstack-images-v2.0-json-patch`` media type is based
|
||||||
|
on `draft
|
||||||
|
4 <http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-04>`__ of
|
||||||
|
the standard. Its use is deprecated.
|
||||||
|
|
||||||
|
Restricted JSON pointers
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The 'application/openstack-images-v2.1-json-patch' media type defined in
|
||||||
|
this appendix adopts a restricted form of
|
||||||
|
`JSON-Pointers <http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer>`__.
|
||||||
|
A restricted JSON pointer is a
|
||||||
|
`Unicode <http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-03#ref-Unicode>`__
|
||||||
|
string containing a sequence of exactly one reference token, prefixed by
|
||||||
|
a '/' (%x2F) character.
|
||||||
|
|
||||||
|
If a reference token contains '~' (%x7E) or '/' (%x2F) characters, they
|
||||||
|
must be encoded as '~0' and '~1' respectively.
|
||||||
|
|
||||||
|
Its ABNF syntax is:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
restricted-json-pointer = "/" reference-token
|
||||||
|
reference-token = *( unescaped / escaped )
|
||||||
|
unescaped = %x00-2E / %x30-7D / %x7F-10FFFF
|
||||||
|
escaped = "~" ( "0" / "1" )
|
||||||
|
|
||||||
|
Restricted JSON Pointers are evaluated as ordinary JSON pointers per
|
||||||
|
`JSON-Pointer <http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer>`__.
|
||||||
|
|
||||||
|
For example, given the ``image`` entity:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"name": "cirros-0.3.0-x86_64-uec-ramdisk",
|
||||||
|
"status": "active",
|
||||||
|
"visibility": "public",
|
||||||
|
"size": 2254249,
|
||||||
|
"checksum": "2cec138d7dae2aa59038ef8c9aec2390",
|
||||||
|
"~/.ssh/": "present",
|
||||||
|
"tags": ["ping", "pong"],
|
||||||
|
"created_at": "2012-08-10T19:23:50Z",
|
||||||
|
"updated_at": "2012-08-10T19:23:50Z",
|
||||||
|
"self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
}
|
||||||
|
|
||||||
|
The following restricted JSON pointers evaluate to the accompanying
|
||||||
|
values:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
"/name" "cirros-0.3.0-x86_64-uec-ramdisk"
|
||||||
|
"/size" 2254249
|
||||||
|
"/tags" ["ping", "pong"]
|
||||||
|
"/~0~1.ssh~1" "present"
|
||||||
|
|
||||||
|
Operations
|
||||||
|
----------
|
||||||
|
|
||||||
|
The application/openstack-images-v2.1-json-patch media type supports a
|
||||||
|
subset of the operations defined in the application/json-patch+json
|
||||||
|
media type. Specify the operation in the "op" member of the request
|
||||||
|
object.
|
||||||
|
|
||||||
|
- The supported operations are add, remove, and replace.
|
||||||
|
- If an operation object contains no recognized operation member, an
|
||||||
|
error occurs.
|
||||||
|
|
||||||
|
Specify the location where the requested operation is to be performed in
|
||||||
|
the target image in the "path" member of the operation object.
|
||||||
|
|
||||||
|
- The member value is a string containing a restricted JSON-pointer
|
||||||
|
value that references the location where the operation is to be
|
||||||
|
performed within the target image.
|
||||||
|
|
||||||
|
Where appropriate (that is, for the "add" and "replace" operations), the
|
||||||
|
operation object must contain the "value" data member.
|
||||||
|
|
||||||
|
- The member value is the actual value to add (or to use in the replace
|
||||||
|
operation) expressed in JSON notation. (For example, strings must be
|
||||||
|
quoted, numeric values are unquoted.)
|
||||||
|
|
||||||
|
The payload for a PATCH request must be a *list* of JSON objects. Each
|
||||||
|
object must adhere to one of the following formats.
|
||||||
|
|
||||||
|
- add
|
||||||
|
|
||||||
|
The add operation adds a new value at a specified location in the target
|
||||||
|
image. The location must reference an image property to add to an
|
||||||
|
existing image.
|
||||||
|
|
||||||
|
The operation object specifies a "value" member and associated value.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
PATCH /images/{image_id}
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"add",
|
||||||
|
"path":"/login-name",
|
||||||
|
"value":"kvothe"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
You can also use the add operation to add a location to the set of
|
||||||
|
locations that are associated with a specified image ID, as follows:
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
PATCH /images/{image_id}
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"add",
|
||||||
|
"path":"/locations/1",
|
||||||
|
"value":"scheme4://path4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
- remove
|
||||||
|
|
||||||
|
The remove operation removes the specified image property in the target
|
||||||
|
image. If an image property does not exist at the specified location, an
|
||||||
|
error occurs.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
PATCH /images/{image_id}
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"remove",
|
||||||
|
"path":"/login-name"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
You can also use the remove operation to remove a location from a set of
|
||||||
|
locations that are associated with a specified image ID, as follows:
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
PATCH /images/{image_id}
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"remove",
|
||||||
|
"path":"/locations/2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
- replace
|
||||||
|
|
||||||
|
The replace operation replaces the value of a specified image property
|
||||||
|
in the target image with a new value. The operation object contains a
|
||||||
|
"value" member that specifies the replacement value.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"replace",
|
||||||
|
"path":"/login-name",
|
||||||
|
"value":"kote"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
This operation is functionally identical to expressing a "remove"
|
||||||
|
operation for an image property, followed immediately by an "add"
|
||||||
|
operation at the same location with the replacement value.
|
||||||
|
|
||||||
|
If the specified image property does not exist for the target image, an
|
||||||
|
error occurs.
|
||||||
|
|
||||||
|
You can also use the replace operation to replace a location in the set
|
||||||
|
of locations that are associated with a specified image ID, as follows:
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
PATCH /images/{image_id}
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op":"replace",
|
||||||
|
"path":"/locations",
|
||||||
|
"value":[
|
||||||
|
"scheme5://path5",
|
||||||
|
"scheme6://path6"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
119
specs/api/v2/image-api-v2.rst
Normal file
119
specs/api/v2/image-api-v2.rst
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
General Image API v2.x information
|
||||||
|
==================================
|
||||||
|
|
||||||
|
The Image Service API v2 enables you to store and retrieve disk and
|
||||||
|
server images.
|
||||||
|
|
||||||
|
Versioning
|
||||||
|
----------
|
||||||
|
|
||||||
|
**Two-part versioning scheme**
|
||||||
|
|
||||||
|
The Image Service API v2 mimics API v1 and uses a major version and a
|
||||||
|
minor version. For example, v2.3 is major version 2 and minor version 3.
|
||||||
|
|
||||||
|
**Backwards-compatibility**
|
||||||
|
|
||||||
|
Minor version releases expand and do not reduce the interface. For
|
||||||
|
example, everything in v2.1 is available in v2.2.
|
||||||
|
|
||||||
|
**Property protections**
|
||||||
|
|
||||||
|
The Images API v2.2 enables a cloud provider to employ *property
|
||||||
|
protections*, an optional feature whereby CRUD protections are applied
|
||||||
|
to image properties.
|
||||||
|
|
||||||
|
Thus, in particular deployments, non-admin users might not be able to
|
||||||
|
view, update, or delete some image properties.
|
||||||
|
|
||||||
|
Additionally, non-admin users might be forced to follow a particular
|
||||||
|
naming convention when creating custom image properties.
|
||||||
|
|
||||||
|
It is left to the cloud provider to communicate policies concerning
|
||||||
|
property protections to users.
|
||||||
|
|
||||||
|
HTTP response status codes
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The following HTTP status codes are all valid responses:
|
||||||
|
|
||||||
|
- 200 - generic successful response, expect a body
|
||||||
|
- 201 - entity created, expect a body and a Location header
|
||||||
|
- 204 - successful response without body
|
||||||
|
- 301 - redirection
|
||||||
|
- 400 - invalid request (syntax, value, etc)
|
||||||
|
- 401 - unauthenticated client
|
||||||
|
- 403 - authenticated client unable to perform action
|
||||||
|
- 409 - that action is impossible due to some (possibly permanent)
|
||||||
|
circumstance
|
||||||
|
- 415 - unsupported media type
|
||||||
|
|
||||||
|
Responses that don't have a 200-level response code are not guaranteed
|
||||||
|
to have a body. If a response does happen to return a body, it is not
|
||||||
|
part of this spec and cannot be depended upon.
|
||||||
|
|
||||||
|
Authentication and authorization
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
This spec does not govern how one might authenticate or authorize
|
||||||
|
clients of the v2 Images API. Implementors are free to decide how to
|
||||||
|
identify clients and what authorization rules to apply.
|
||||||
|
|
||||||
|
Note that the HTTP 401 and 403 status codes are included in this
|
||||||
|
specification as valid response codes.
|
||||||
|
|
||||||
|
Request and response content format
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
The Images Service API v2 primarily accepts and serves JSON-encoded
|
||||||
|
data. In certain cases it also accepts and serves binary image data.
|
||||||
|
Most requests that send JSON-encoded data must have the proper media
|
||||||
|
type in their Content-Type header: 'application/json'. HTTP PATCH
|
||||||
|
requests must use the patch media type defined for the entity they
|
||||||
|
intend to modify. Requests that upload image data should use the media
|
||||||
|
type 'application/octet-stream'.
|
||||||
|
|
||||||
|
Each call only responds in one format, so clients should not worry about
|
||||||
|
sending an Accept header. It is ignored. The response is formatted as
|
||||||
|
'application/json' unless otherwise stated in this spec.
|
||||||
|
|
||||||
|
Image entities
|
||||||
|
--------------
|
||||||
|
|
||||||
|
An image entity is represented by a JSON-encoded data structure and its
|
||||||
|
raw binary data.
|
||||||
|
|
||||||
|
An image entity has an identifier (ID) that is guaranteed to be unique
|
||||||
|
within the endpoint to which it belongs. The ID is used as a token in
|
||||||
|
request URIs to interact with that specific image.
|
||||||
|
|
||||||
|
An image is always guaranteed to have the following attributes: id,
|
||||||
|
status, visibility, protected, tags, created\_at, file and self. The
|
||||||
|
other attributes defined in the ``image`` schema below are guaranteed to
|
||||||
|
be defined, but is only returned with an image entity if they have been
|
||||||
|
explicitly set.
|
||||||
|
|
||||||
|
A client may set arbitrarily-named attributes on their images if the
|
||||||
|
``image`` json-schema allows it. These user-defined attributes appear
|
||||||
|
like any other image attributes. See
|
||||||
|
`documentation <http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.4>`__
|
||||||
|
of the additionalProperties json-schema attribute.
|
||||||
|
|
||||||
|
JSON schemas
|
||||||
|
------------
|
||||||
|
|
||||||
|
The necessary
|
||||||
|
`json-schema <http://tools.ietf.org/html/draft-zyp-json-schema-03>`__
|
||||||
|
documents are provided at predictable URIs. A consumer should be able to
|
||||||
|
validate server responses and client requests based on the published
|
||||||
|
schemas. The schemas contained in this document are only examples and
|
||||||
|
should not be used to validate your requests. A client should **always**
|
||||||
|
fetch schemas from the server.
|
||||||
|
|
||||||
|
**Property Protections**
|
||||||
|
|
||||||
|
Version 2.2 of the Images API acknowledges the ability of a cloud
|
||||||
|
provider to employ *property protections*. Thus, there may be image
|
||||||
|
properties that will not appear in the list images response for
|
||||||
|
non-admin users.
|
||||||
|
|
40
specs/api/v2/image-binary-data-api-v2.rst
Normal file
40
specs/api/v2/image-binary-data-api-v2.rst
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Image API Binary Data API calls
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Binary Data API
|
||||||
|
===============
|
||||||
|
|
||||||
|
The following API calls are used to upload and download raw image data.
|
||||||
|
For image metadata, see `Metadata API <#metadata-api>`__.
|
||||||
|
|
||||||
|
Upload Image File
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
**PUT /v2/images/<IMAGE\_ID>/file**
|
||||||
|
|
||||||
|
NOTE: An image record must exist before a client can store binary image
|
||||||
|
data with it.
|
||||||
|
|
||||||
|
Request Content-Type must be 'application/octet-stream'. Complete
|
||||||
|
contents of request body will be stored and become accessible in its
|
||||||
|
entirety by issuing a GET request to the same URI.
|
||||||
|
|
||||||
|
Response status will be 204.
|
||||||
|
|
||||||
|
Download Image File
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
**GET /v2/images/<IMAGE\_ID>/file**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
Response body will be the raw binary data that represents the actual
|
||||||
|
virtual disk. The Content-Type header will be
|
||||||
|
'application/octet-stream'.
|
||||||
|
|
||||||
|
The `Content-MD5 <http://www.ietf.org/rfc/rfc1864.txt>`__ header will
|
||||||
|
contain an MD5 checksum of the image data. Clients are encouraged to
|
||||||
|
verify the integrity of the image data they receive using this checksum.
|
||||||
|
|
||||||
|
If no image data has been stored, an HTTP status of 204 is returned.
|
||||||
|
|
295
specs/api/v2/image-metadata-api-v2.rst
Normal file
295
specs/api/v2/image-metadata-api-v2.rst
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
Image Metadata API calls
|
||||||
|
========================
|
||||||
|
|
||||||
|
The following calls allow you to create, modify, and delete image
|
||||||
|
metadata records.
|
||||||
|
|
||||||
|
Create image
|
||||||
|
------------
|
||||||
|
|
||||||
|
**POST /v2/images**
|
||||||
|
|
||||||
|
Request body must be JSON-encoded and conform to the ``image`` JSON
|
||||||
|
schema. For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
|
||||||
|
"name": "Ubuntu 12.10",
|
||||||
|
"tags": ["ubuntu", "quantal"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Successful HTTP response is 201 Created with a Location header
|
||||||
|
containing the newly-created URI for the image. The response body shows
|
||||||
|
the created ``image`` entity. For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
|
||||||
|
"name": "Ubuntu 12.10",
|
||||||
|
"status": "queued",
|
||||||
|
"visibility": "public",
|
||||||
|
"tags": ["ubuntu", "quantal"],
|
||||||
|
"created_at": "2012-08-11T17:15:52Z",
|
||||||
|
"updated_at": "2012-08-11T17:15:52Z",
|
||||||
|
"self": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
|
||||||
|
"file": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
}
|
||||||
|
|
||||||
|
Update an image
|
||||||
|
---------------
|
||||||
|
|
||||||
|
**PATCH /v2/images/{image\_id}**
|
||||||
|
|
||||||
|
Request body must conform to the
|
||||||
|
'application/openstack-images-v2.1-json-patch' media type, documented in
|
||||||
|
Appendix B. Using **PATCH
|
||||||
|
/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd** as an example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[
|
||||||
|
{"op": "replace", "path": "/name", "value": "Fedora 17"},
|
||||||
|
{"op": "replace", "path": "/tags", "value": ["fedora", "beefy"]}
|
||||||
|
]
|
||||||
|
|
||||||
|
The response body shows the updated ``image`` entity. For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
|
||||||
|
"name": "Fedora 17",
|
||||||
|
"status": "queued",
|
||||||
|
"visibility": "public",
|
||||||
|
"tags": ["fedora", "beefy"],
|
||||||
|
"created_at": "2012-08-11T17:15:52Z",
|
||||||
|
"updated_at": "2012-08-11T17:15:52Z",
|
||||||
|
"self": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
|
||||||
|
"file": "/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
}
|
||||||
|
|
||||||
|
The PATCH method can also be used to add or remove image properties. To
|
||||||
|
add a custom user-defined property such as "login-user" to an image, use
|
||||||
|
the following example request.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[
|
||||||
|
{"op": "add", "path": "/login-user", "value": "kvothe"}
|
||||||
|
]
|
||||||
|
|
||||||
|
Similarly, to remove a property such as "login-user" from an image, use
|
||||||
|
the following example request.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[
|
||||||
|
{"op": "remove", "path": "/login-user"}
|
||||||
|
]
|
||||||
|
|
||||||
|
See Appendix B for more details about the
|
||||||
|
'application/openstack-images-v2.1-json-patch' media type.
|
||||||
|
|
||||||
|
**Property protections**
|
||||||
|
|
||||||
|
Version 2.2 of the Images API acknowledges the ability of a cloud
|
||||||
|
provider to employ *property protections*. Thus, there may be image
|
||||||
|
properties that may not be updated or deleted by non-admin users.
|
||||||
|
|
||||||
|
Add an image tag
|
||||||
|
----------------
|
||||||
|
|
||||||
|
**PUT /v2/images/{image\_id}/tags/{tag}**
|
||||||
|
|
||||||
|
The the tag you want to add should be encoded into the request URI. For
|
||||||
|
example, to tag image e7db3b45-8db7-47ad-8109-3fb55c2c24fd with
|
||||||
|
'miracle', you would **PUT
|
||||||
|
/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/tags/miracle**. The
|
||||||
|
request body is ignored.
|
||||||
|
|
||||||
|
An image tag can be up to 255 characters in length. See the 'image'
|
||||||
|
json-schema to determine which characters are allowed.
|
||||||
|
|
||||||
|
An image can only be tagged once with a specific string. Multiple
|
||||||
|
attempts to tag an image with the same string will result in a single
|
||||||
|
instance of that string being added to the image's tags list.
|
||||||
|
|
||||||
|
An HTTP status of 204 is returned.
|
||||||
|
|
||||||
|
Delete an image tag
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
**DELETE /v2/images/{image\_id}/tags/{tag}**
|
||||||
|
|
||||||
|
The tag you want to delete should be encoded into the request URI. For
|
||||||
|
example, to remove the tag 'miracle' from image
|
||||||
|
e7db3b45-8db7-47ad-8109-3fb55c2c24fd, you would **DELETE
|
||||||
|
/v2/images/e7db3b45-8db7-47ad-8109-3fb55c2c24fd/tags/miracle**. The
|
||||||
|
request body is ignored.
|
||||||
|
|
||||||
|
An HTTP status of 204 is returned. Subsequent attempts to delete the tag
|
||||||
|
will result in a 404.
|
||||||
|
|
||||||
|
List images
|
||||||
|
-----------
|
||||||
|
|
||||||
|
**GET /v2/images**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
Response body will be a list of images available to the client. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"name": "cirros-0.3.0-x86_64-uec-ramdisk",
|
||||||
|
"status": "active",
|
||||||
|
"visibility": "public",
|
||||||
|
"size": 2254249,
|
||||||
|
"checksum": "2cec138d7dae2aa59038ef8c9aec2390",
|
||||||
|
"tags": ["ping", "pong"],
|
||||||
|
"created_at": "2012-08-10T19:23:50Z",
|
||||||
|
"updated_at": "2012-08-10T19:23:50Z",
|
||||||
|
"self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0d5bcbc7-b066-4217-83f4-7111a60a399a",
|
||||||
|
"name": "cirros-0.3.0-x86_64-uec",
|
||||||
|
"status": "active",
|
||||||
|
"visibility": "public",
|
||||||
|
"size": 25165824,
|
||||||
|
"checksum": "2f81976cae15c16ef0010c51e3a6c163",
|
||||||
|
"tags": [],
|
||||||
|
"created_at": "2012-08-10T19:23:50Z",
|
||||||
|
"updated_at": "2012-08-10T19:23:50Z",
|
||||||
|
"self": "/v2/images/0d5bcbc7-b066-4217-83f4-7111a60a399a",
|
||||||
|
"file": "/v2/images/0d5bcbc7-b066-4217-83f4-7111a60a399a/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e6421c88-b1ed-4407-8824-b57298249091",
|
||||||
|
"name": "cirros-0.3.0-x86_64-uec-kernel",
|
||||||
|
"status": "active",
|
||||||
|
"visibility": "public",
|
||||||
|
"size": 4731440,
|
||||||
|
"checksum": "cfb203e7267a28e435dbcb05af5910a9",
|
||||||
|
"tags": [],
|
||||||
|
"created_at": "2012-08-10T19:23:49Z",
|
||||||
|
"updated_at": "2012-08-10T19:23:49Z",
|
||||||
|
"self": "/v2/images/e6421c88-b1ed-4407-8824-b57298249091",
|
||||||
|
"file": "/v2/images/e6421c88-b1ed-4407-8824-b57298249091/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"first": "/v2/images?limit=3",
|
||||||
|
"next": "/v2/images?limit=3&marker=e6421c88-b1ed-4407-8824-b57298249091",
|
||||||
|
"schema": "/v2/schemas/images"
|
||||||
|
}
|
||||||
|
|
||||||
|
Get images schema
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
**GET /v2/schemas/images**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
The response body contains a json-schema document that shows an
|
||||||
|
``images`` entity (a container of ``image`` entities). For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "images",
|
||||||
|
"properties": {
|
||||||
|
"images": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"name": "image",
|
||||||
|
"properties": {
|
||||||
|
"id": {"type": "string"},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"visibility": {"enum": ["public", "private"]},
|
||||||
|
"status": {"type": "string"},
|
||||||
|
"protected": {"type": "boolean"},
|
||||||
|
"tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "string"}
|
||||||
|
},
|
||||||
|
"checksum": {"type": "string"},
|
||||||
|
"size": {"type": "integer"},
|
||||||
|
"created_at": {"type": "string"},
|
||||||
|
"updated_at": {"type": "string"},
|
||||||
|
"file": {"type": "string"},
|
||||||
|
"self": {"type": "string"},
|
||||||
|
"schema": {"type": "string"}
|
||||||
|
},
|
||||||
|
"additionalProperties": {"type": "string"},
|
||||||
|
"links": [
|
||||||
|
{"href": "{self}", "rel": "self"},
|
||||||
|
{"href": "{file}", "rel": "enclosure"},
|
||||||
|
{"href": "{schema}", "rel": "describedby"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema": {"type": "string"},
|
||||||
|
"next": {"type": "string"},
|
||||||
|
"first": {"type": "string"}
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
{"href": "{first}", "rel": "first"},
|
||||||
|
{"href": "{next}", "rel": "next"},
|
||||||
|
{"href": "{schema}", "rel": "describedby"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Get image schema
|
||||||
|
----------------
|
||||||
|
|
||||||
|
**GET /v2/schemas/image**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
The response body contains a json-schema document that shows an
|
||||||
|
``image``. For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "image",
|
||||||
|
"properties": {
|
||||||
|
"id": {"type": "string"},
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"visibility": {"enum": ["public", "private"]},
|
||||||
|
"status": {"type": "string"},
|
||||||
|
"protected": {"type": "boolean"},
|
||||||
|
"tags": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "string"}
|
||||||
|
},
|
||||||
|
"checksum": {"type": "string"},
|
||||||
|
"size": {"type": "integer"},
|
||||||
|
"created_at": {"type": "string"},
|
||||||
|
"updated_at": {"type": "string"},
|
||||||
|
"file": {"type": "string"},
|
||||||
|
"self": {"type": "string"},
|
||||||
|
"schema": {"type": "string"}
|
||||||
|
},
|
||||||
|
"additionalProperties": {"type": "string"},
|
||||||
|
"links": [
|
||||||
|
{"href": "{self}", "rel": "self"},
|
||||||
|
{"href": "{file}", "rel": "enclosure"},
|
||||||
|
{"href": "{schema}", "rel": "describedby"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
50
specs/api/v2/lists-image-api-v2.rst
Normal file
50
specs/api/v2/lists-image-api-v2.rst
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
Image API v2 listing
|
||||||
|
====================
|
||||||
|
|
||||||
|
**Pagination**
|
||||||
|
|
||||||
|
This call is designed to return a subset of the larger collection of
|
||||||
|
images while providing a link that can be used to retrieve the next. You
|
||||||
|
should always check for the presence of a 'next' link and use it as the
|
||||||
|
URI in a subsequent HTTP GET request. You should follow this pattern
|
||||||
|
until there a 'next' link is no longer provided. The next link will
|
||||||
|
preserve any query parameters you send in your initial request. The
|
||||||
|
'first' link can be used to jump back to the first page of the
|
||||||
|
collection.
|
||||||
|
|
||||||
|
If you prefer to paginate through images manually, the API provides two
|
||||||
|
query parameters: 'limit' and 'marker'. The limit parameter is used to
|
||||||
|
request a specific page size. Expect a response to a limited request to
|
||||||
|
return between zero and *limit* items. The marker parameter is used to
|
||||||
|
indicate the id of the last-seen image. The typical pattern of limit and
|
||||||
|
marker is to make an initial limited request then to use the id of the
|
||||||
|
last image from the response as the marker parameter in a subsequent
|
||||||
|
limited request.
|
||||||
|
|
||||||
|
**Filtering**
|
||||||
|
|
||||||
|
The list operation accepts several types of query parameters intended to
|
||||||
|
filter the results of the returned collection.
|
||||||
|
|
||||||
|
A client can provide direct comparison filters using *most* image
|
||||||
|
attributes (i.e. name=Ubuntu, visibility=public, etc). A client cannot
|
||||||
|
filter on tags or anything defined as a 'link' in the json-schema (i.e.
|
||||||
|
self, file, schema).
|
||||||
|
|
||||||
|
The 'size\_min' and 'size\_max' query parameters can be used to do
|
||||||
|
greater-than and less-than filtering of images based on their 'size'
|
||||||
|
attribute ('size' is measured in bytes and refers to the size of an
|
||||||
|
image when stored on disk). For example, sending a size\_min filter of
|
||||||
|
1048576 and size\_max of 4194304 would filter the container to include
|
||||||
|
only images that are between one and four megabytes in size.
|
||||||
|
|
||||||
|
**Sorting**
|
||||||
|
|
||||||
|
The results of this operation can be ordered using the 'sort\_key' and
|
||||||
|
'sort\_dir' parameters. The API uses the natural sorting of whatever
|
||||||
|
image attribute is provided as the 'sort\_key'. All image attributes can
|
||||||
|
be used as the sort\_key (except tags and link attributes). The
|
||||||
|
sort\_dir parameter indicates in which direction to sort. Acceptable
|
||||||
|
values are 'asc' (ascending) and 'desc' (descending). Defaults values
|
||||||
|
for sort\_key and sort\_dir are 'created\_at' and 'desc'.
|
||||||
|
|
34
specs/api/v2/retrieve-image-api-v2.rst
Normal file
34
specs/api/v2/retrieve-image-api-v2.rst
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Get an Image
|
||||||
|
------------
|
||||||
|
|
||||||
|
**GET /v2/images/<IMAGE\_ID>**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
Response body is a single image entity. Using **GET
|
||||||
|
/v2/image/da3b75d9-3f4a-40e7-8a2c-bfab23927dea** as an example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"name": "cirros-0.3.0-x86_64-uec-ramdisk",
|
||||||
|
"status": "active",
|
||||||
|
"visibility": "public",
|
||||||
|
"size": 2254249,
|
||||||
|
"checksum": "2cec138d7dae2aa59038ef8c9aec2390",
|
||||||
|
"tags": ["ping", "pong"],
|
||||||
|
"created_at": "2012-08-10T19:23:50Z",
|
||||||
|
"updated_at": "2012-08-10T19:23:50Z",
|
||||||
|
"self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
|
||||||
|
"file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file",
|
||||||
|
"schema": "/v2/schemas/image"
|
||||||
|
}
|
||||||
|
|
||||||
|
**Property Protections**
|
||||||
|
|
||||||
|
Version 2.2 of the Images API acknowledges the ability of a cloud
|
||||||
|
provider to employ *property protections*. Thus, there may be some image
|
||||||
|
properties that will not appear in the image detail response for
|
||||||
|
non-admin users.
|
||||||
|
|
404
specs/api/v2/sharing-image-api-v2.rst
Normal file
404
specs/api/v2/sharing-image-api-v2.rst
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
Image API v2 Sharing
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The OpenStack Image Service API v2 allows users to share images with
|
||||||
|
each other.
|
||||||
|
|
||||||
|
Let the "producer" be a tenant who owns image
|
||||||
|
71c675ab-d94f-49cd-a114-e12490b328d9, and let the "consumer" be a tenant
|
||||||
|
who would like to boot an instance from that image.
|
||||||
|
|
||||||
|
The producer can share the image with the consumer by making the
|
||||||
|
consumer a **member** of that image.
|
||||||
|
|
||||||
|
To prevent spamming, the consumer must **accept** the image before it
|
||||||
|
will be included in the consumer's image list.
|
||||||
|
|
||||||
|
The consumer can still boot from the image, however, if the consumer
|
||||||
|
knows the image ID.
|
||||||
|
|
||||||
|
In summary:
|
||||||
|
|
||||||
|
- The image producer may add or remove image members, but may not
|
||||||
|
modify the member status of an image member.
|
||||||
|
- An image consumer may change his or her member status, but may not
|
||||||
|
add or remove him or herself as an image member.
|
||||||
|
- A consumer may boot an instance from a shared image regardless of
|
||||||
|
whether he/she has "accepted" the image.
|
||||||
|
|
||||||
|
Producer-Consumer Communication
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
No provision is made in this API for producer-consumer communication.
|
||||||
|
All such communication must be done independently of the API.
|
||||||
|
|
||||||
|
An example workflow is:
|
||||||
|
|
||||||
|
1. The producer posts the availability of specific images on a public
|
||||||
|
website.
|
||||||
|
2. A potential consumer provides the producer with his/her tenant ID and
|
||||||
|
email address.
|
||||||
|
3. The producer uses the Images v2 API to share the image with the
|
||||||
|
consumer.
|
||||||
|
4. The producer notifies the consumer via email that the image has been
|
||||||
|
shared and what its UUID is.
|
||||||
|
5. If the consumer wishes the image to appear in his/her image list, the
|
||||||
|
Images v2 API is used to change the image status to ``accepted``.
|
||||||
|
6. If the consumer subsequently wishes to hide the image, the Images v2
|
||||||
|
API may be used to change the member status to ``rejected``. If the
|
||||||
|
consumer wishes to hide the image, but is open to the possibility of
|
||||||
|
being reminded by the producer that the image is available, the
|
||||||
|
Images v2 API may be used to change the member status to ``pending``.
|
||||||
|
|
||||||
|
Note that as far as this API is concerned, the member status has only
|
||||||
|
two effects:
|
||||||
|
|
||||||
|
- If the member status is *not* ``accepted``, the image will not appear
|
||||||
|
in the consumer's default image list.
|
||||||
|
- The consumer's image list may be filtered by status to see shared
|
||||||
|
images in the various member statuses. For example, the consumer can
|
||||||
|
discover images that have been shared with him or her by filtering on
|
||||||
|
``visibility=shared&member_status=pending``.
|
||||||
|
|
||||||
|
Image Sharing Schemas
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
JSON schema documents are provided at the URIs listed below.
|
||||||
|
|
||||||
|
Recall that the schemas contained in this document are only examples and
|
||||||
|
should not be used to validate your requests.
|
||||||
|
|
||||||
|
Get Image Member Schema
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**GET /v2/schemas/member**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
Response body contains a json-schema document representing an image
|
||||||
|
``member`` entity.
|
||||||
|
|
||||||
|
The response from the API should be considered authoritative. The schema
|
||||||
|
is reproduced here solely for your convenience:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "member",
|
||||||
|
"properties": {
|
||||||
|
"created_at": {
|
||||||
|
"description": "Date and time of image member creation",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
"description": "An identifier for the image",
|
||||||
|
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"member_id": {
|
||||||
|
"description": "An identifier for the image member (tenantId)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"description": "The status of this image member",
|
||||||
|
"enum": [
|
||||||
|
"pending",
|
||||||
|
"accepted",
|
||||||
|
"rejected"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"description": "Date and time of last modification of image member",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Get Image Members Schema
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**GET /v2/schemas/members**
|
||||||
|
|
||||||
|
Request body ignored.
|
||||||
|
|
||||||
|
Response body contains a json-schema document representing an image
|
||||||
|
``members`` entity (a container of ``member`` entities).
|
||||||
|
|
||||||
|
The response from the API should be considered authoritative. The schema
|
||||||
|
is reproduced here solely for your convenience:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "members",
|
||||||
|
"properties": {
|
||||||
|
"members": {
|
||||||
|
"items": {
|
||||||
|
"name": "member",
|
||||||
|
"properties": {
|
||||||
|
"created_at": {
|
||||||
|
"description": "Date and time of image member creation",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
"description": "An identifier for the image",
|
||||||
|
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"member_id": {
|
||||||
|
"description": "An identifier for the image member (tenantId)",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"description": "The status of this image member",
|
||||||
|
"enum": [
|
||||||
|
"pending",
|
||||||
|
"accepted",
|
||||||
|
"rejected"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"description": "Date and time of last modification of image member",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "{schema}",
|
||||||
|
"rel": "describedby"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Image Producer Calls
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The following calls are germane to a user who wishes to act as a
|
||||||
|
producer of shared images.
|
||||||
|
|
||||||
|
Create an Image Member
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**POST /v2/images/<IMAGE\_ID>/members**
|
||||||
|
|
||||||
|
The request body must be JSON in the following format:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"member": "<MEMBER_ID>"
|
||||||
|
}
|
||||||
|
|
||||||
|
where the MEMBER\_ID is the ID of the tenant with whom the image is to
|
||||||
|
be shared.
|
||||||
|
|
||||||
|
The member status of a newly created image member is ``pending``.
|
||||||
|
|
||||||
|
If the user making the call is not the image owner, the response is HTTP
|
||||||
|
status code 404.
|
||||||
|
|
||||||
|
The response conforms to the JSON schema available at
|
||||||
|
**/v2/schemas/member**, for example,
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"created_at": "2013-09-19T20:36:53Z",
|
||||||
|
"image_id": "71c675ab-d94f-49cd-a114-e12490b328d9",
|
||||||
|
"member_id": "8989447062e04a818baf9e073fd04fa7",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "pending",
|
||||||
|
"updated_at": "2013-09-19T20:36:53Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete an Image Member
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**DELETE /v2/images/<IMAGE\_ID>/members/<MEMBER\_ID>**
|
||||||
|
|
||||||
|
A successful response is 204 (No Content).
|
||||||
|
|
||||||
|
The call returns HTTP status code 404 if MEMBER\_ID is not an image
|
||||||
|
member of the specified image.
|
||||||
|
|
||||||
|
The call returns HTTP status code 404 if the user making the call is not
|
||||||
|
the image owner.
|
||||||
|
|
||||||
|
Image Consumer Calls
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The following calls pertain to a user who wishes to act as a consumer of
|
||||||
|
shared images.
|
||||||
|
|
||||||
|
Update an Image Member
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**PUT /v2/images/<IMAGE\_ID>/members/<MEMBER\_ID>**
|
||||||
|
|
||||||
|
The body of the request is a JSON object specifying the member status to
|
||||||
|
which the image member should be updated:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"status": "<STATUS_VALUE>"
|
||||||
|
}
|
||||||
|
|
||||||
|
where STATUS\_VALUE is one of { ``pending``, ``accepted``, or
|
||||||
|
``rejected`` }.
|
||||||
|
|
||||||
|
The response conforms to the JSON schema available at
|
||||||
|
**/v2/schemas/member**, for example,
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"created_at": "2013-09-20T19:22:19Z",
|
||||||
|
"image_id": "a96be11e-8536-4910-92cb-de50aa19dfe6",
|
||||||
|
"member_id": "8989447062e04a818baf9e073fd04fa7",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "accepted",
|
||||||
|
"updated_at": "2013-09-20T20:15:31Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
If the call is made by the image owner, the response is HTTP status code
|
||||||
|
403 (Forbidden).
|
||||||
|
|
||||||
|
If the call is made by a user who is not the image owner and whose
|
||||||
|
tenant ID does not match the MEMBER\_ID, the response is HTTP status
|
||||||
|
code 404.
|
||||||
|
|
||||||
|
Image Member Status Values
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There are three image member status values:
|
||||||
|
|
||||||
|
- ``pending``: When a member is created, its status is set to
|
||||||
|
``pending``. The image is not visible in the member's image-list, but
|
||||||
|
the member can still boot instances from the image.
|
||||||
|
- ``accepted``: When a member's status is ``accepted``, the image is
|
||||||
|
visible in the member's image-list. The member can boot instances
|
||||||
|
from the image.
|
||||||
|
- ``rejected``: When a member's status is ``rejected``, the member has
|
||||||
|
decided that he or she does not wish to see the image. The image is
|
||||||
|
not visible in the member's image-list, but the member can still boot
|
||||||
|
instances from the image.
|
||||||
|
|
||||||
|
Calls for Both Producers and Consumers
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
These calls are applicable to users acting either as producers or
|
||||||
|
consumers of shared images.
|
||||||
|
|
||||||
|
Show Image Member
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**GET /v2/images/<IMAGE\_ID>/members/<MEMBER\_ID>**
|
||||||
|
|
||||||
|
The response conforms to the JSON schema available at
|
||||||
|
**/v2/schemas/member**, for example,
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"created_at": "2014-02-20T04:15:17Z",
|
||||||
|
"image_id": "634985e5-0f2e-488e-bd7c-928d9a8ea82a",
|
||||||
|
"member_id": "46a12bfd09c8459483c03e1b0d71bda8",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "pending",
|
||||||
|
"updated_at": "2014-02-20T04:15:17Z"
|
||||||
|
}
|
||||||
|
|
||||||
|
The image owner (the producer) may make this call successfully for each
|
||||||
|
image member. An image member (a consumer) may make this call
|
||||||
|
successfully only when MEMBER\_ID matches that consumer's tenant ID. For
|
||||||
|
any other MEMBER\_ID, the consumer receives a 404 response.
|
||||||
|
|
||||||
|
List Image Members
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**GET /v2/images/<IMAGE\_ID>/members**
|
||||||
|
|
||||||
|
The response conforms to the JSON schema available at
|
||||||
|
**/v2/schemas/members**, for example,
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"created_at": "2013-09-20T19:16:53Z",
|
||||||
|
"image_id": "a96be11e-8536-4910-92cb-de50aa19dfe6",
|
||||||
|
"member_id": "818baf9e073fd04fa78989447062e04a",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "pending",
|
||||||
|
"updated_at": "2013-09-20T19:16:53Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"created_at": "2013-09-20T19:22:19Z",
|
||||||
|
"image_id": "a96be11e-8536-4910-92cb-de50aa19dfe6",
|
||||||
|
"member_id": "8989447062e04a818baf9e073fd04fa7",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "pending",
|
||||||
|
"updated_at": "2013-09-20T19:22:19Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schema": "/v2/schemas/members"
|
||||||
|
}
|
||||||
|
|
||||||
|
If the call is made by a user with whom the image has been shared, the
|
||||||
|
member-list will contain *only* the information for that user. For
|
||||||
|
example, if the call is made by tenant 8989447062e04a818baf9e073fd04fa7,
|
||||||
|
the response is:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"created_at": "2013-09-20T19:22:19Z",
|
||||||
|
"image_id": "a96be11e-8536-4910-92cb-de50aa19dfe6",
|
||||||
|
"member_id": "8989447062e04a818baf9e073fd04fa7",
|
||||||
|
"schema": "/v2/schemas/member",
|
||||||
|
"status": "pending",
|
||||||
|
"updated_at": "2013-09-20T19:22:19Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schema": "/v2/schemas/members"
|
||||||
|
}
|
||||||
|
|
||||||
|
If the call is made by a user with whom the image is *not* shared, the
|
||||||
|
response is a 404.
|
||||||
|
|
||||||
|
List Shared Images
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Shared images are listed as part of the normal image list call. In this
|
||||||
|
section we emphasize some useful filtering options.
|
||||||
|
|
||||||
|
- ``visibility=shared``: show only images shared with me where my
|
||||||
|
member status is 'accepted'
|
||||||
|
- ``visibility=shared&member_status=accepted``: same as above
|
||||||
|
- ``visibility=shared&member_status=pending``: show only images shared
|
||||||
|
with me where my member status is 'pending'
|
||||||
|
- ``visibility=shared&member_status=rejected``: show only images shared
|
||||||
|
with me where my member status is 'rejected'
|
||||||
|
- ``visibility=shared&member_status=all``: show all images shared with
|
||||||
|
me regardless of my member status
|
||||||
|
- ``owner=<OWNER_ID>``: show only images shared with me by the user
|
||||||
|
whose tenant ID is OWNER\_ID
|
@ -92,7 +92,7 @@ Questions which need to be addressed by this section include:
|
|||||||
REST API impact
|
REST API impact
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Each API method which is either added or changed should have the following:
|
An /api directory is now included for REST API updates. Each API method which is either added or changed should have the following:
|
||||||
|
|
||||||
* Specification for the method
|
* Specification for the method
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ Note that the schema should be defined as restrictively as
|
|||||||
possible. Parameters which are required should be marked as such and
|
possible. Parameters which are required should be marked as such and
|
||||||
only under exceptional circumstances should additional parameters
|
only under exceptional circumstances should additional parameters
|
||||||
which are not defined in the schema be permitted (i.e.
|
which are not defined in the schema be permitted (i.e.
|
||||||
additionaProperties should be False).
|
additionalProperties should be False).
|
||||||
|
|
||||||
Reuse of existing predefined parameter types such as regexps for
|
Reuse of existing predefined parameter types such as regexps for
|
||||||
passwords and user defined names is highly encouraged.
|
passwords and user defined names is highly encouraged.
|
||||||
|
@ -93,12 +93,11 @@ class TestTitles(testtools.TestCase):
|
|||||||
self.assertEqual(0, len(titles[refs]))
|
self.assertEqual(0, len(titles[refs]))
|
||||||
|
|
||||||
def test_template(self):
|
def test_template(self):
|
||||||
files = (['specs/template.rst'] +
|
release = ['juno', 'kilo']
|
||||||
filter(lambda x: not x.endswith('index.rst'),
|
files = ['specs/template.rst'] + glob.glob("specs/%s/*/*" % release)
|
||||||
glob.glob('specs/*/*')))
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
self.assertTrue(filename.endswith(".rst"),
|
self.assertTrue(filename.endswith(".rst"),
|
||||||
"spec's file must uses 'rst' extension.")
|
"spec's file must use 'rst' extension.")
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
spec = docutils.core.publish_doctree(data)
|
spec = docutils.core.publish_doctree(data)
|
||||||
|
Loading…
Reference in New Issue
Block a user