diff --git a/.gitignore b/.gitignore
index b774adf0..478debc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,5 @@ build
*.swp
*.swo
*.pyc
-.testrepository
\ No newline at end of file
+.testrepository
+.DS_Store
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 93f8db96..7ce2f253 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -12,6 +12,17 @@ Juno approved specs:
specs/juno/*
+=============
+Volume V2 API
+=============
+
+.. toctree::
+ :glob:
+ :maxdepth: 1
+
+ specs/api/v2/*
+
+
==================
Indices and tables
==================
diff --git a/specs/api/v2/additional_resources.rst b/specs/api/v2/additional_resources.rst
new file mode 100644
index 00000000..f2ed3842
--- /dev/null
+++ b/specs/api/v2/additional_resources.rst
@@ -0,0 +1,10 @@
+====================
+Additional resources
+====================
+
+You can download the latest API-related documents from
+`docs.openstack.org/api/ `__.
+
+This API uses standard HTTP 1.1 response codes as documented at:
+`www.w3.org/Protocols/rfc2616/rfc2616-sec10.html `__.
+
diff --git a/specs/api/v2/block_storage_general_api_info.rst b/specs/api/v2/block_storage_general_api_info.rst
new file mode 100644
index 00000000..ed4c8d44
--- /dev/null
+++ b/specs/api/v2/block_storage_general_api_info.rst
@@ -0,0 +1,74 @@
+========================================
+General Block Storage v2 API information
+========================================
+
+OpenStack Block Storage provides volume management with the OpenStack
+Compute service.
+
+This document describes the features available with the Block Storage
+API v2.
+
+We welcome feedback, comments and bug reports at
+`bugs.launchpad.net/Cinder `__.
+
+Intended audience
+-----------------
+
+This spec assumes the reader has a general understanding of storage and is familiar with these concepts:
+
+- ReSTful web services
+
+- HTTP/1.1 conventions
+
+- JSON and/or XML data serialization formats
+
+The Block Storage API is implemented using a ReSTful web service
+interface. Like other OpenStack projects, Block Storage shares a common
+token-based authentication system that allows access between products
+and services.
+
+Note
+~~~~
+
+All requests to authenticate against and operate the service are
+performed using SSL over HTTP (HTTPS) on TCP port 443.
+
+Authentication
+--------------
+
+You can use `cURL `__ to try the authentication
+process in two steps: get a token, and send the token to a service.
+
+#. Get an authentication token by providing your user name and either
+ your API key or your password. Here are examples of both approaches:
+
+ *You can request a token by providing your user name and your
+ password.*
+
+ .. code::
+
+ $ curl -X POST https://localhost:5000/v2.0/tokens -d '{"auth":{"passwordCredentials":{"username": "joecool", "password":"coolword"}, "tenantId":"5"}}' -H 'Content-type: application/json'
+
+ Successful authentication returns a token which you can use as
+ evidence that your identity has already been authenticated. To use
+ the token, pass it to other services as an ``X-Auth-Token`` header.
+
+ Authentication also returns a service catalog, listing the endpoints
+ you can use for Cloud services.
+
+#. Use the authentication token to send a GET to a service you would
+ like to use.
+
+Authentication tokens are typically valid for 24 hours. Applications
+should be designed to re-authenticate after receiving a 401
+(Unauthorized) response from a service endpoint.
+
+Important
+~~~~~~~~~
+
+If you programmatically parse an authentication response, be aware that
+service names are stable for the life of the particular service and can
+be used as keys. You should also be aware that a user's service catalog
+can include multiple uniquely-named services that perform similar
+functions.
+
diff --git a/specs/api/v2/block_storage_v2_overview.rst b/specs/api/v2/block_storage_v2_overview.rst
new file mode 100644
index 00000000..c2fe91dd
--- /dev/null
+++ b/specs/api/v2/block_storage_v2_overview.rst
@@ -0,0 +1,69 @@
+=============================
+Block Storage API v2 Overview
+=============================
+
+OpenStack Block Storage is a block-level storage solution that enables
+you to:
+
+- Mount drives to OpenStack Cloud Servers™ to scale storage without
+ paying for more compute resources.
+
+- Use high performance storage to serve database or I/O-intensive
+ applications.
+
+You interact with Block Storage programmatically through the Block
+Storage API as described in this guide.
+
+Note
+~~~~
+
+- OpenStack Block Storage is an add-on feature to OpenStack Nova
+ Compute in Folsom versions and earlier.
+
+- Block Storage is multi-tenant rather than dedicated.
+
+- Block Storage allows you to create snapshots that you can save, list,
+ and restore.
+
+- Block Storage allows you to create backups of your volumes to Object
+ Storage for archival and disaster recovery purposes. These backups
+ can be subsequently restored to the same volume or new volumes.
+
+Concepts
+--------
+
+To use the Block Storage API effectively, you must understand several
+key concepts:
+
+- **Volume**
+
+ A detachable block storage device. You can think of it as a USB hard
+ drive. It can only be attached to one instance at a time.
+
+- **Volume type**
+
+ A type of a block storage volume. You can define whatever types work
+ best for you, such as SATA, SCSCI, SSD, etc. These can be customized
+ or defined by the OpenStack admin.
+
+ You can also define extra\_specs associated with your volume types.
+ For instance, you could have a VolumeType=SATA, with extra\_specs
+ (RPM=10000, RAID-Level=5) . Extra\_specs are defined and customized
+ by the admin.
+
+- **Snapshot**
+
+ A point in time copy of the data contained in a volume.
+
+- **Instance**
+
+ A virtual machine (VM) that runs inside the cloud.
+
+- **Backup**
+
+ A full copy of a volume stored in an external service. The service
+ can be configured. The only supported service for now is Object
+ Storage. A backup can subsequently be restored from the external
+ service to either the same volume that the backup was originally
+ taken from, or to a new volume.
+
diff --git a/specs/api/v2/date_and_time_format.rst b/specs/api/v2/date_and_time_format.rst
new file mode 100644
index 00000000..94f74a38
--- /dev/null
+++ b/specs/api/v2/date_and_time_format.rst
@@ -0,0 +1,46 @@
+====================
+Date and time format
+====================
+
+Block Storage uses an ISO-8601 compliant date format for the display and
+consumption of date time values.
+
+**Example 2.3. DB service date and time format**
+
+.. code::
+
+ yyyy-MM-dd'T'HH:mm:ss.SSSZ
+
+May 19th, 2011 at 8:07:08 AM, GMT-5 has the following format:
+
+.. code::
+
+ 2011-05-19T08:07:08-05:00
+
+|
+
+The following table describes the date time format codes:
+
+**Table 2.4. Date time format codes**
+
+==== ===========
+Code Description
+==== ===========
+
+yyyy Four digit year
+
+MM Two digit month
+
+dd Two digit day of month
+
+T Separator for date time
+
+HH Two digit hour of day (00-23)
+
+mm Two digit minutes of hour
+
+ss Two digit seconds of the minute
+
+SSS Three digit milliseconds of the second
+
+Z RFC-822 timezone
diff --git a/specs/api/v2/faults.rst b/specs/api/v2/faults.rst
new file mode 100644
index 00000000..6a75651b
--- /dev/null
+++ b/specs/api/v2/faults.rst
@@ -0,0 +1,173 @@
+======
+Faults
+======
+
+When an error occurs, Block Storage returns a fault object containing an
+HTTP error response code that denotes the type of error. The response
+body returns additional information about the fault.
+
+The following table lists possible fault types with their associated
+error codes and descriptions.
+
+Fault type Associated error code Description
+
+``badRequest`` 400 The user request contains one or more errors.
+
+``unauthorized`` 401 The supplied token is not authorized to access the resources, either it's expired or invalid.
+
+``forbidden`` 403 Access to the requested resource was denied.
+
+``itemNotFound`` 404 The back-end services did not find anything matching the Request-URI.
+
+``badMethod`` 405 The request method is not allowed for this resource.
+
+``overLimit`` 413 Either the number of entities in the request is larger than allowed limits, or the user has exceeded allowable request rate limits. See the ``details`` element for more specifics. Contact your cloud provider if you think you need higher request rate limits.
+
+``badMediaType`` 415 The requested content type is not supported by this service.
+
+``unprocessableEntity`` 422 The requested resource could not be processed on at the moment.
+
+``instanceFault`` 500 This is a generic server error and the message contains the reason for the error. This error could wrap several error messages and is a catch all.
+
+``notImplemented`` 501 The requested method or resource is not implemented.
+
+``serviceUnavailable`` 503 Block Storage is not available.
+
+The following two ``instanceFault`` examples show errors when the server
+has erred or cannot perform the requested operation:
+
+**Example 2.4. Example instanceFault response: XML**
+
+.. code::
+
+ HTTP/1.1 500 Internal Server Error
+ Content-Type: application/xml
+ Content-Length: 121
+ Date: Mon, 28 Nov 2011 18:19:37 GMT
+
+.. code::
+
+
+
+ The server has either erred or is incapable of
+ performing the requested operation.
+
+
+|
+
+**Example 2.5. Example fault response: JSON**
+
+.. code::
+
+ HTTP/1.1 500 Internal Server Error
+ Content-Length: 120
+ Content-Type: application/json; charset=UTF-8
+ Date: Tue, 29 Nov 2011 00:33:48 GMT
+
+.. code::
+
+ {
+ "instanceFault":{
+ "code":500,
+ "message":"The server has either erred or is incapable of performing the requested operation."
+ }
+ }
+
+|
+
+The error code (``code``) is returned in the body of the response for
+convenience. The ``message`` element returns a human-readable message
+that is appropriate for display to the end user. The ``details`` element
+is optional and may contain information that is useful for tracking down
+an error, such as a stack trace. The ``details`` element may or may not
+be appropriate for display to an end user, depending on the role and
+experience of the end user.
+
+The fault's root element (for example, ``instanceFault``) may change
+depending on the type of error.
+
+The following two ``badRequest`` examples show errors when the volume
+size is invalid:
+
+**Example 2.6. Example badRequest fault on volume size errors: XML**
+
+.. code::
+
+ HTTP/1.1 400 None
+ Content-Type: application/xml
+ Content-Length: 121
+ Date: Mon, 28 Nov 2011 18:19:37 GMT
+
+.. code::
+
+
+
+ Volume 'size' needs to be a positive integer value, -1.0
+ cannot be accepted.
+
+
+|
+
+**Example 2.7. Example badRequest fault on volume size errors: JSON**
+
+.. code::
+
+ HTTP/1.1 400 None
+ Content-Length: 120
+ Content-Type: application/json; charset=UTF-8
+ Date: Tue, 29 Nov 2011 00:33:48 GMT
+
+.. code::
+
+ {
+ "badRequest":{
+ "code":400,
+ "message":"Volume 'size' needs to be a positive integer value, -1.0 cannot be accepted."
+ }
+ }
+
+|
+
+The next two examples show ``itemNotFound`` errors:
+
+**Example 2.8. Example itemNotFound fault: XML**
+
+.. code::
+
+ HTTP/1.1 404 Not Found
+ Content-Length: 147
+ Content-Type: application/xml; charset=UTF-8
+ Date: Mon, 28 Nov 2011 19:50:15 GMT
+
+.. code::
+
+
+
+ The resource could not be found.
+
+
+|
+
+**Example 2.9. Example itemNotFound fault: JSON**
+
+.. code::
+
+ HTTP/1.1 404 Not Found
+ Content-Length: 78
+ Content-Type: application/json; charset=UTF-8
+ Date: Tue, 29 Nov 2011 00:35:24 GMT
+
+.. code::
+
+ {
+ "itemNotFound":{
+ "code":404,
+ "message":"The resource could not be found."
+ }
+ }
+
+|
+
diff --git a/specs/api/v2/high-level_task_flow.rst b/specs/api/v2/high-level_task_flow.rst
new file mode 100644
index 00000000..1624a369
--- /dev/null
+++ b/specs/api/v2/high-level_task_flow.rst
@@ -0,0 +1,27 @@
+====================
+High-level task flow
+====================
+
+**Procedure 1.1. To create and attach a volume**
+
+#. You create a volume.
+
+ For example, you might create a 30 GB volume called ``vol1``, as
+ follows:
+
+ .. code::
+
+ $ cinder create --display-name vol1 30
+
+ The command returns the ``521752a6-acf6-4b2d-bc7a-119f9148cd8c``
+ volume ID.
+
+#. You attach that volume to a virtual machine (VM) with the
+ ``616fb98f-46ca-475e-917e-2563e5a8cd19`` ID, as follows:
+
+ For example:
+
+ .. code::
+
+ $ nova volume-attach 616fb98f-46ca-475e-917e-2563e5a8cd19 521752a6-acf6-4b2d-bc7a-119f9148cd8c /dev/vdb
+
diff --git a/specs/api/v2/http_response_status_codes.rst b/specs/api/v2/http_response_status_codes.rst
new file mode 100644
index 00000000..3010f8ef
--- /dev/null
+++ b/specs/api/v2/http_response_status_codes.rst
@@ -0,0 +1,17 @@
+==========================
+HTTP response status codes
+==========================
+
+When an error occurs, Block Storage returns an HTTP error response code
+that denotes the type of error. Some errors returns a response body,
+which returns additional information about the error.
+
+The following table describes the possible status codes:
+
+======== =========== ==============
+Response Status code Response body?
+======== =========== ==============
+
+Generic 200 Yes
+Entity created. 201 Yes
+Successful response without body. 204 No
diff --git a/specs/api/v2/limits.rst b/specs/api/v2/limits.rst
new file mode 100644
index 00000000..0324ba4b
--- /dev/null
+++ b/specs/api/v2/limits.rst
@@ -0,0 +1,106 @@
+======
+Limits
+======
+
+All accounts, by default, have a preconfigured set of thresholds (or
+limits) to manage capacity and prevent abuse of the system. The system
+recognizes two kinds of limits: *rate limits* and *absolute limits*.
+Rate limits are thresholds that are reset after a certain amount of time
+passes. Absolute limits are fixed.
+
+Rate limits
+~~~~~~~~~~~
+
+Rate limits are specified in terms of both a human-readable wild-card
+URI and a machine-processable regular expression. The regular expression
+boundary matcher '^' takes effect after the root URI path. For example,
+the regular expression ^/v1.0/instances would match the bolded portion
+of the following URI:
+https://dfw.blockstorage.api.openstackcloud.com\ **/v1.0/instances**.
+
+The following table specifies the default rate limits for all API
+operations for all **GET**, **POST**, **PUT**, and **DELETE** calls for
+volumes:
+
+**Table 2.2. Default rate limits**
+
+Verb
+
+URI
+
+RegEx
+
+Default
+
+**GET** changes-since
+
+\*/instances/\*
+
+^/v\\d+\\.\\d+/\\d+/instances.\*
+
+3/minute
+
+**POST**
+
+\*/instances/\*
+
+^/v\\d+\\.\\d+/\\d+/instances.\*
+
+10/minute
+
+**POST** instances
+
+\*/instances/\*
+
+^/v\\d+\\.\\d+/\\d+/instances.\*
+
+50/day
+
+**PUT**
+
+\*/instances/\*
+
+^/v\\d+\\.\\d+/\\d+/instances.\*
+
+10/minute
+
+**DELETE**
+
+\*/instances/\*
+
+^/v\\d+\\.\\d+/\\d+/instances.\*
+
+100/minute
+
+|
+
+Rate limits are applied in order relative to the verb, going from least
+to most specific. For example, although the threshold for **POST** to
+/v1.0/\* is 10 per minute, one cannot **POST** to /v1.0/\* more than 50
+times within a single day.
+
+If you exceed the thresholds established for your account, a 413 (Rate
+Control) HTTP response will be returned with a ``Retry-After`` header to
+notify the client when it can attempt to try again.
+
+Absolute limits
+~~~~~~~~~~~~~~~
+
+The following table shows the absolute limits:
+
+**Table 2.3. Absolute limits**
+
+Name
+
+Description
+
+Limit
+
+Block Storage
+
+Maximum amount of block storage
+
+1 TB
+
+|
+
diff --git a/specs/api/v2/request_and_response_types.rst b/specs/api/v2/request_and_response_types.rst
new file mode 100644
index 00000000..6a383c8f
--- /dev/null
+++ b/specs/api/v2/request_and_response_types.rst
@@ -0,0 +1,67 @@
+==========================
+Request and response types
+==========================
+
+The Block Storage API supports both the JSON and XML data serialization
+formats. The request format is specified using the ``Content-Type``
+header and is required for calls that have a request body. The response
+format can be specified in requests either by using the ``Accept``
+header or by adding an ``.xml`` or ``.json`` extension to the request
+URI. Note that it is possible for a response to be serialized using a
+format different from the request. If no response format is specified,
+JSON is the default. If conflicting formats are specified using both an
+``Accept`` header and a query extension, the query extension takes
+precedence.
+
+Some operations support an Atom representation that can be used to
+efficiently determine when the state of services has changed.
+
+**Table 2.1. Response formats**
+
+====== ============= =============== =======
+Format Accept Header Query Extension Default
+====== ============= =============== =======
+
+JSON application/json .json Yes
+
+XML application/xml .xml No
+
+In the request example below, notice that *``Content-Type``* is set to
+*``application/json``*, but *``application/xml``* is requested via the
+*``Accept``* header:
+
+**Example 2.1. Request with headers: Get volume types**
+
+.. code::
+
+ GET /v2/441446/types HTTP/1.1
+ Host: dfw.blockstorage.api.openstackcloud.com
+ X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
+ Accept: application/xml
+
+|
+
+An XML response format is returned:
+
+**Example 2.2. Response with headers**
+
+.. code::
+
+ HTTP/1.1 200 OK
+ Date: Fri, 20 Jul 2012 20:32:13 GMT
+ Content-Length: 187
+ Content-Type: application/xml
+ X-Compute-Request-Id: req-8e0295cd-a283-46e4-96da-cae05cbfd1c7
+
+
+
+
+
+
+
+
+
+
+
+|
+
diff --git a/tests/test_titles.py b/tests/test_titles.py
index 70c232e6..fe95aca7 100644
--- a/tests/test_titles.py
+++ b/tests/test_titles.py
@@ -89,10 +89,11 @@ class TestTitles(testtools.TestCase):
(len(matches), tpl))
def test_template(self):
- files = ['specs/template.rst'] + glob.glob('specs/*/*')
+ release = ['juno', 'kilo']
+ files = ['specs/template.rst'] + glob.glob("specs/%s/*/*" % release)
for filename in files:
self.assertTrue(filename.endswith(".rst"),
- "spec's file must uses 'rst' extension.")
+ "spec's file must use 'rst' extension.")
with open(filename) as f:
data = f.read()