Difference between revisions of "Glance-tasks-api"
m (→Task Schema) |
(updated JSON schemas) |
||
Line 20: | Line 20: | ||
An task 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 task. | An task 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 task. | ||
− | An task is always guaranteed to have the following attributes: id, | + | An task is always guaranteed to have the following attributes: id, type, status, and self. The other attributes defined in the task schema below are guaranteed to be defined, but will only be returned with a task entity if they have been explicitly set. |
<div style="background-color: yellow"> | <div style="background-color: yellow"> | ||
Line 29: | Line 29: | ||
(no ordering, just using the numerals to keep count) | (no ordering, just using the numerals to keep count) | ||
# id | # id | ||
− | # owner | + | # type |
− | # | + | # status |
− | # | + | # owner : this is whatever is being used as the image owner in this glance installation |
+ | # input : task "parameters" | ||
+ | # result | ||
+ | # created_at | ||
+ | # updated_at | ||
# expires_at | # expires_at | ||
# message | # message | ||
Line 46: | Line 50: | ||
"description": "An identifier for the task", | "description": "An identifier for the task", | ||
"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}$", | "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" | + | "type": "string", |
+ | "required": true | ||
}, | }, | ||
"owner": { | "owner": { | ||
− | |||
"description": "An identifier for the owner of this task", | "description": "An identifier for the owner of this task", | ||
− | "type": "string" | + | "type": "string", |
+ | "required": true | ||
}, | }, | ||
− | " | + | "type" : { |
"description": "The type of task represented by this content", | "description": "The type of task represented by this content", | ||
"enum": [ | "enum": [ | ||
Line 60: | Line 65: | ||
"clone" | "clone" | ||
], | ], | ||
− | "type": "string" | + | "type": "string", |
+ | "required": true | ||
}, | }, | ||
− | " | + | "status" : { |
"description": "The current status of this task.", | "description": "The current status of this task.", | ||
"enum": [ | "enum": [ | ||
Line 70: | Line 76: | ||
"failure" | "failure" | ||
], | ], | ||
− | "type": "string" | + | "type": "string", |
+ | "required": true | ||
+ | }, | ||
+ | "created_at": { | ||
+ | "description": "Datetime when this resource was created", | ||
+ | "type": "string", | ||
+ | "required": true | ||
+ | }, | ||
+ | "updated_at": { | ||
+ | "description": "Datetime when this resource was most recently updated", | ||
+ | "type": "string", | ||
+ | "required": true | ||
}, | }, | ||
"expires_at": { | "expires_at": { | ||
"description": "Datetime when this resource is subject to removal", | "description": "Datetime when this resource is subject to removal", | ||
− | "type": "string" | + | "type": "string" |
− | |||
}, | }, | ||
− | + | "message": { | |
"description": "Human-readable informative message only included when appropriate (usually on failure)", | "description": "Human-readable informative message only included when appropriate (usually on failure)", | ||
"type": "string", | "type": "string", | ||
− | "required" : | + | }, |
− | + | "input": { | |
+ | "description": "The input parameters for this task", | ||
+ | "type": "object", | ||
+ | "required": true | ||
+ | }, | ||
+ | "result": { | ||
+ | "description": "Informatic results of this task", | ||
+ | "type": "object", | ||
+ | }, | ||
}, | }, | ||
"links": [ | "links": [ | ||
Line 97: | Line 121: | ||
} | } | ||
], | ], | ||
− | |||
} | } | ||
</pre> | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Task Request Body == | == Task Request Body == | ||
− | The basic tasks request will be <tt>Content-type: application/json</tt> and | + | The basic tasks request will be <tt>Content-type: application/json</tt> and is defined by the following JSON schema. |
<pre> | <pre> | ||
{ | { | ||
− | "task | + | "name": "task", |
− | + | "properties": { | |
− | + | "type": { | |
+ | "description": "The type of task represented by this content", | ||
+ | "enum": [ | ||
+ | "import", | ||
+ | "export", | ||
+ | "clone" | ||
+ | ], | ||
+ | "type": "string", | ||
+ | "required": true | ||
+ | }, | ||
+ | "input": { | ||
+ | "description": "The input parameters for this task", | ||
+ | "type": "object", | ||
+ | "required": true | ||
+ | } | ||
} | } | ||
} | } | ||
</pre> | </pre> | ||
− | + | ||
− | |||
− | |||
== Task Response Body == | == Task Response Body == | ||
Line 180: | Line 206: | ||
* original blueprint proposal <ref>https://blueprints.launchpad.net/glance/+spec/upload-download-workflow</ref> | * original blueprint proposal <ref>https://blueprints.launchpad.net/glance/+spec/upload-download-workflow</ref> | ||
* mailing list discussion of original proposal <ref>http://lists.openstack.org/pipermail/openstack-dev/2013-May/009385.html</ref> | * mailing list discussion of original proposal <ref>http://lists.openstack.org/pipermail/openstack-dev/2013-May/009385.html</ref> | ||
+ | * mailing list discussion of this proposal <ref>http://lists.openstack.org/pipermail/openstack-dev/2013-August/012866.html</ref> | ||
+ | * etherpad of further discussion refining this proposal <ref>https://etherpad.openstack.org/LG39UnQA7z</ref> | ||
== References == | == References == | ||
<references /> | <references /> |
Revision as of 17:29, 20 August 2013
Contents
Overview
This proposal unifies the new upload workflow [1], new download workflow [2], and image cloning [3] blueprints in an extensible, consistent, and easy-to-learn way.
General Workflow
- User posts a request to /v2/tasks
- Glance returns a 201 with Location: /v2/tasks/{task-uuid}
- The resource at /v2/tasks/{task-uuid} will be an expirable entity
- User polls /v2/tasks/{task-uuid} for status information on the requested task
- Eventually, when the task is completed, the resource will contain
- task result information, e.g.,
- if the task was successful, the location of the result of the task
- for import or clone tasks, this will be an /images resource
- for export, it will be a location where the exported item may be retrieved
- if the task was not successful, an informative message
- if the task was successful, the location of the result of the task
- the expiration datetime of the tasks resource itself
- task result information, e.g.,
Task Entities
An task entity is represented by a JSON-encoded data structure.
An task 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 task.
An task is always guaranteed to have the following attributes: id, type, status, and self. The other attributes defined in the task schema below are guaranteed to be defined, but will only be returned with a task entity if they have been explicitly set.
Note: the task entity will need to have an "owner" field (whether or not it's exposed in the response) so that we can make sure that users can't see each other's tasks.
Task Properties
(no ordering, just using the numerals to keep count)
- id
- type
- status
- owner : this is whatever is being used as the image owner in this glance installation
- input : task "parameters"
- result
- created_at
- updated_at
- expires_at
- message
Task Schema
A json-schema for the task entity will be available at the URI /v2/schemas/tasks
And it goes a little something like this:
{ "name": "task", "properties": { "id": { "description": "An identifier for the task", "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", "required": true }, "owner": { "description": "An identifier for the owner of this task", "type": "string", "required": true }, "type" : { "description": "The type of task represented by this content", "enum": [ "import", "export", "clone" ], "type": "string", "required": true }, "status" : { "description": "The current status of this task.", "enum": [ "pending", "processing", "success", "failure" ], "type": "string", "required": true }, "created_at": { "description": "Datetime when this resource was created", "type": "string", "required": true }, "updated_at": { "description": "Datetime when this resource was most recently updated", "type": "string", "required": true }, "expires_at": { "description": "Datetime when this resource is subject to removal", "type": "string" }, "message": { "description": "Human-readable informative message only included when appropriate (usually on failure)", "type": "string", }, "input": { "description": "The input parameters for this task", "type": "object", "required": true }, "result": { "description": "Informatic results of this task", "type": "object", }, }, "links": [ { "href": "{self}", "rel": "self" }, { "href": "{file}", "rel": "enclosure" }, { "href": "{schema}", "rel": "describedby" } ], }
Task Request Body
The basic tasks request will be Content-type: application/json and is defined by the following JSON schema.
{ "name": "task", "properties": { "type": { "description": "The type of task represented by this content", "enum": [ "import", "export", "clone" ], "type": "string", "required": true }, "input": { "description": "The input parameters for this task", "type": "object", "required": true } } }
Task Response Body
The basic tasks response will be Content-type: application/json and will adhere to the json schema described above.
Task States
Tasks will have the following states:
-
pending
: a task has been created, but Glance (via async worker or whatever) hasn't begun to execute the task yet -
processing
: the task is underway -
success
: the task has complete successfully -
failure
: something went wrong, the task was not able to complete
In the case of failure, it's expected that the task resource will contain a message explaining what went wrong.
Requests
Create a Task
POST /v2/tasks
Request body must be appropriate for the task_type.
Display Task Detail
GET /v2/tasks/{task_id}
Returns a task response as defined above.
List Tasks
GET /v2/tasks
Returns a list of tasks owned by the user making the request.
Query Parameters
We'll want to allow filtering on the task_type, e.g.,
GET /v2/tasks?task_type=import
would return all non-expired import tasks owned by the user making the request.
Open Questions
- What do we return when a user makes a GET for a task UUID that exists, but they don't own?
- 401 or 404?
- The task request will return a 200 even when the task_status is 'failure' (since the task response itself is being returned OK). Some of these failures will be for things like not-found, format-not-supported, conflict ... this will be mentioned in the 'message' field, but do we want to have a separate failure code or something to make it easier for an API user to extract this info?
Proposed Tasks
Related Documents
- Havana summit discussion etherpad (see bottom of pad) [7]
- original blueprint proposal [8]
- mailing list discussion of original proposal [9]
- mailing list discussion of this proposal [10]
- etherpad of further discussion refining this proposal [11]
References
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-import
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-export
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-clone
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-import
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-export
- ↑ https://wiki.openstack.org/wiki/Glance-tasks-clone
- ↑ https://etherpad.openstack.org/havana-getting-glance-ready-for-public-clouds
- ↑ https://blueprints.launchpad.net/glance/+spec/upload-download-workflow
- ↑ http://lists.openstack.org/pipermail/openstack-dev/2013-May/009385.html
- ↑ http://lists.openstack.org/pipermail/openstack-dev/2013-August/012866.html
- ↑ https://etherpad.openstack.org/LG39UnQA7z