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:
Anne Gentle 2014-10-17 14:50:44 -05:00
parent 113c8a55f1
commit f46438ab1c
24 changed files with 1824 additions and 6 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ build
*.swo *.swo
*.pyc *.pyc
.testrepository .testrepository
.DS_Store

View File

@ -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
================== ==================

View 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.

View 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>\`

View 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.

View File

@ -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.

View 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

View 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.

View 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.

View File

@ -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.

View File

@ -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

View 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\`.

View 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\`.

View 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`.

View 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.

View 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"
]
}
]

View 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.

View 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.

View 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"}
]
}

View 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'.

View 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.

View 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

View File

@ -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.

View File

@ -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)