Merge lp:~ralsina/tanuki-agent/fix-product-ref into lp:tanuki-agent
- fix-product-ref
- Merge into trunk
Proposed by
Roberto Alsina
Status: | Merged |
---|---|
Approved by: | Roberto Alsina |
Approved revision: | 200 |
Merged at revision: | 199 |
Proposed branch: | lp:~ralsina/tanuki-agent/fix-product-ref |
Merge into: | lp:tanuki-agent |
Diff against target: |
757 lines (+303/-179) 1 file modified
docs/api-reference-products.md (+303/-179) |
To merge this branch: | bzr merge lp:~ralsina/tanuki-agent/fix-product-ref |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bret Barker (community) | Approve | ||
Review via email: mp+281536@code.launchpad.net |
Commit message
Update doc to the current product-based API (part 1: products/
Description of the change
Update doc to the current product-based API (part 1: products/
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'docs/api-reference-products.md' | |||
2 | --- docs/api-reference-products.md 2015-11-27 12:34:13 +0000 | |||
3 | +++ docs/api-reference-products.md 2016-01-04 19:07:00 +0000 | |||
4 | @@ -1,5 +1,5 @@ | |||
5 | 1 | Title: Ubuntu Core Product Integration API Guide | 1 | Title: Ubuntu Core Product Integration API Guide |
7 | 2 | Version: 20151105 | 2 | Version: 20160104 |
8 | 3 | 3 | ||
9 | 4 | [TOC] | 4 | [TOC] |
10 | 5 | 5 | ||
11 | @@ -14,6 +14,9 @@ | |||
12 | 14 | the Product. It is free-form with data of your choosing (e.g. a | 14 | the Product. It is free-form with data of your choosing (e.g. a |
13 | 15 | pointer to a binary to be provisioned on the device). Defined either | 15 | pointer to a binary to be provisioned on the device). Defined either |
14 | 16 | via a manifest or advertised to the system on-demand. | 16 | via a manifest or advertised to the system on-demand. |
15 | 17 | - **Base Image**: represents a tested configuration, | ||
16 | 18 | specifically the combination of snaps that form that configuration. It can be | ||
17 | 19 | marked as "released", meaning it's in use by end users. | ||
18 | 17 | - **Test Spec**: defines Tests to be run on | 20 | - **Test Spec**: defines Tests to be run on |
19 | 18 | matching images | 21 | matching images |
20 | 19 | - **Test Opportunity**: an instance of a | 22 | - **Test Opportunity**: an instance of a |
21 | @@ -26,11 +29,11 @@ | |||
22 | 26 | ============ | 29 | ============ |
23 | 27 | 30 | ||
24 | 28 | All API endpoints are authenticated, which ensures private access | 31 | All API endpoints are authenticated, which ensures private access |
26 | 29 | to your Organization's information. | 32 | to your product's information. |
27 | 30 | 33 | ||
28 | 31 | To authenticate properly to the system, you'll first need oauth | 34 | To authenticate properly to the system, you'll first need oauth |
29 | 32 | credentials that are obtained via the Agent (see next chapter below, | 35 | credentials that are obtained via the Agent (see next chapter below, |
31 | 33 | “Lab Operation”, under “<span class="c28">[Authentication](#h.u7ke0hug9g6j)” | 36 | "Lab Operation", under "<span class="c28">[Authentication](#h.u7ke0hug9g6j)" |
32 | 34 | section). | 37 | section). |
33 | 35 | 38 | ||
34 | 36 | <!-- LINK TO CORRECT PLACE IN TUTORIAL? --> | 39 | <!-- LINK TO CORRECT PLACE IN TUTORIAL? --> |
35 | @@ -75,11 +78,9 @@ | |||
36 | 75 | 78 | ||
37 | 76 | Make a signed request to the Manifest Listing endpoint: | 79 | Make a signed request to the Manifest Listing endpoint: |
38 | 77 | 80 | ||
40 | 78 | >>> url = "https://spi.canonical.com/orgs/docs-org/products/manifests" | 81 | >>> url = "https://spi.canonical.com/products" |
41 | 79 | >>> res = authenticated_session.get(url) | 82 | >>> res = authenticated_session.get(url) |
42 | 80 | 83 | ||
43 | 81 | |||
44 | 82 | |||
45 | 83 | The authenticated\_session will oauth-sign the request, appending | 84 | The authenticated\_session will oauth-sign the request, appending |
46 | 84 | an HTTP Authorization header that looks like: | 85 | an HTTP Authorization header that looks like: |
47 | 85 | 86 | ||
48 | @@ -93,13 +94,16 @@ | |||
49 | 93 | >>> res.status_code | 94 | >>> res.status_code |
50 | 94 | 200 | 95 | 200 |
51 | 95 | >>> res.json() | 96 | >>> res.json() |
59 | 96 | {'manifests': [{'base\_image\_reference': 'http://foo.com/bar', | 97 | {'packages': ['test-snap.foo'], |
60 | 97 | 'created_at': '2015-08-25T08:00:10.500533', | 98 | 'products': [{'active': True, |
61 | 98 | 'id': '71e81dbb-4eb5-45df-a813-6e9efe0851be', | 99 | 'created_at': '2016-01-04T16:03:18.721607', |
62 | 99 | 'image_name': 'docs-img68f9005f7fdb4c07ae322de432f22f26', | 100 | 'id': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', |
63 | 100 | 'release': '15.04', | 101 | 'name': 'test-product.foo', |
64 | 101 | 'snaps': [{'locked': True, 'name': 'snap-a', 'revision': 1}, | 102 | 'primary_snap_name': 'test-snap.foo', |
65 | 102 | {'locked': False, 'name': 'snap-b', 'revision': None}]}]} | 103 | 'release': '15.04-core', |
66 | 104 | 'snaps': ['pi2.canonical', | ||
67 | 105 | 'webdm.canonical', | ||
68 | 106 | 'test-snap.foo']}]} | ||
69 | 103 | 107 | ||
70 | 104 | In order to simplify the examples given in the API references | 108 | In order to simplify the examples given in the API references |
71 | 105 | throughout this document, we have provided a helper script as part of | 109 | throughout this document, we have provided a helper script as part of |
72 | @@ -143,71 +147,43 @@ | |||
73 | 143 | Product Management | 147 | Product Management |
74 | 144 | ------------------ | 148 | ------------------ |
75 | 145 | 149 | ||
102 | 146 | Note: Product Manifests support products built from | 150 | **FIXME ADD EXPLANATIONS** |
103 | 147 | Snaps. If you are instead bootstrapping Product Integration with a pre-existing binary | 151 | |
104 | 148 | image, please skip ahead to the next section - Test Management. | 152 | A product contains the following fields: |
105 | 149 | 153 | ||
106 | 150 | A Product is defined by a Manifest that has an image\_name | 154 | - ```name```: a unique name for this product that is combined with each |
81 | 151 | and either a list of snaps that comprise the image (e.g. as specified in | ||
82 | 152 | a Gadget Snap) or a base\_image\_reference. | ||
83 | 153 | |||
84 | 154 | The image\_name is used to relate Test Specs (see below) to | ||
85 | 155 | Manifests. | ||
86 | 156 | |||
87 | 157 | Manifests and Test Specs may be deactivated or deleted | ||
88 | 158 | permanently. Even if deleted, details of the Test Spec and Manifest (if | ||
89 | 159 | any) that led to the Test Opportunity are persisted in the Test Result | ||
90 | 160 | data. | ||
91 | 161 | |||
92 | 162 | |||
93 | 163 | |||
94 | 164 | To modify a Test Spec or Manifest, the user should delete the | ||
95 | 165 | existing one and create a new one with the desired changes. That will | ||
96 | 166 | not automatically trigger new tests, for that see [Test Triggering](#test-triggering). | ||
97 | 167 | |||
98 | 168 | A manifest contains the following fields: | ||
99 | 169 | |||
100 | 170 | - ```image_name```: a unique name within an | ||
101 | 171 | organization that is combined with each | ||
107 | 172 | test case to produce the full set of test | 155 | test case to produce the full set of test |
108 | 173 | opportunities. I.e. if you have two test cases with a | 156 | opportunities. I.e. if you have two test cases with a |
110 | 174 | matching image\_name, then two test opportunities will be created. | 157 | matching name, then two test opportunities will be created. |
111 | 175 | Maximum length is 200 characters. | 158 | Maximum length is 200 characters. |
112 | 176 | - ```release``` snappy release series, e.g. | 159 | - ```release``` snappy release series, e.g. |
120 | 177 | “15.04”. Maximum length is 200 characters. | 160 | "15.04". Maximum length is 200 characters. |
121 | 178 | - ```base_image_reference``` is opaque to | 161 | - ```primary_snap_name``` name of the snap used to control access to this product. |
115 | 179 | the system; it is for your Provisioning Kit in your lab to | ||
116 | 180 | interpret and use. It can be any JSON | ||
117 | 181 | value. This allows for URLs to actual image binaries, | ||
118 | 182 | data for on-the-fly image composition, etc. Maximum length is 1000 | ||
119 | 183 | characters. | ||
122 | 184 | - ```snaps``` list of snaps that make up the | 162 | - ```snaps``` list of snaps that make up the |
123 | 185 | product. This list will be used to for snappy based products to | 163 | product. This list will be used to for snappy based products to |
124 | 186 | trigger tests when new Snap revisions are made available. | 164 | trigger tests when new Snap revisions are made available. |
125 | 187 | 165 | ||
126 | 188 | The format is a list of: ```[snap_name, revision_num, locked]``` | ||
127 | 189 | |||
128 | 190 | - ```snap_name``` is the name of the Snap in the Store | ||
129 | 191 | - ```revision``` is the revision number (integer) that was used in the base image creation | ||
130 | 192 | - ```locked``` is a boolean indicating if that revision should be locked when generating Tests or can float as snaps are updated. | ||
131 | 193 | |||
132 | 194 | In the current system, interaction is via an HTTP API and detailed below: | 166 | In the current system, interaction is via an HTTP API and detailed below: |
133 | 195 | 167 | ||
134 | 196 | <table class="table"> | 168 | <table class="table"> |
135 | 197 | <tr> | 169 | <tr> |
137 | 198 | <th> Action <th>Manifest Creation | 170 | <th> Action <th>Product Creation |
138 | 199 | <tr> | 171 | <tr> |
140 | 200 | <td>URL <td>https://spi.canonical.com/orgs/<org-id\>/products/manifests | 172 | <td>URL <td>https://spi.canonical.com/products |
141 | 201 | <tr> | 173 | <tr> |
142 | 202 | <td>Method <td>POST | 174 | <td>Method <td>POST |
143 | 203 | <tr> | 175 | <tr> |
144 | 204 | <td>Data <td> | 176 | <td>Data <td> |
145 | 205 | <pre> | 177 | <pre> |
146 | 206 | { | 178 | { |
151 | 207 | “image_name”: "test\_image", | 179 | "primary_snap_name": "test-snap.foo", |
152 | 208 | “release”: “15.04”, | 180 | "name": "test-product.foo", |
153 | 209 | “base_image_reference”: "http://foo.bar", | 181 | "release": "15.04-core", |
154 | 210 | “snaps”: [['snap A', 1, true],['snap B', null, false]] | 182 | "snaps": [ |
155 | 183 | "pi2.canonical", | ||
156 | 184 | "webdm.canonical", | ||
157 | 185 | "test-snap.foo" | ||
158 | 186 | ] | ||
159 | 211 | } | 187 | } |
160 | 212 | </pre> | 188 | </pre> |
161 | 213 | <tr> | 189 | <tr> |
162 | @@ -217,33 +193,31 @@ | |||
163 | 217 | <tr> | 193 | <tr> |
164 | 218 | <td>Example <td> | 194 | <td>Example <td> |
165 | 219 | <pre> | 195 | <pre> |
171 | 220 | $ ./scripts/api_example.py -X POST conf.ini https://spi.canonical.com/orgs/docs-org/products/manifests --data '{ | 196 | $ ./scripts/api_example.py -X POST conf.ini https://spi.canonical.com/products --data '{ |
172 | 221 | "image_name": "test_image", | 197 | "primary_snap_name": "test-snap.foo", |
173 | 222 | "release": "15.04", | 198 | "name": "test-product.foo", |
174 | 223 | "base_image_reference": "http://foo.bar", | 199 | "release": "15.04-core", |
175 | 224 | "snaps": [["snap A", 1, true],["snap B", null, false]] | 200 | "snaps": [ |
176 | 201 | "pi2.canonical", | ||
177 | 202 | "webdm.canonical", | ||
178 | 203 | "test-snap.foo" | ||
179 | 204 | ] | ||
180 | 225 | }' | 205 | }' |
181 | 226 | 206 | ||
182 | 227 | HTTP 201 | 207 | HTTP 201 |
183 | 228 | { | 208 | { |
186 | 229 | "manifest": { | 209 | "product": { |
187 | 230 | "image_name": "test_image", | 210 | "created_at": "2016-01-04T16:58:25.835796", |
188 | 211 | "active": true, | ||
189 | 231 | "snaps": [ | 212 | "snaps": [ |
200 | 232 | { | 213 | "pi2.canonical", |
201 | 233 | "locked": true, | 214 | "webdm.canonical", |
202 | 234 | "revision": 1, | 215 | "test-snap.foo" |
193 | 235 | "name": "snap A" | ||
194 | 236 | }, | ||
195 | 237 | { | ||
196 | 238 | "locked": false, | ||
197 | 239 | "revision": null, | ||
198 | 240 | "name": "snap B" | ||
199 | 241 | } | ||
203 | 242 | ], | 216 | ], |
208 | 243 | "base_image_reference": "http://foo.bar", | 217 | "release": "15.04-core", |
209 | 244 | "id": "ae02b198-bfc8-4d26-aa7b-53dbfdd38230", | 218 | "primary_snap_name": "test-snap.foo", |
210 | 245 | "release": "15.04", | 219 | "name": "test-product.foo", |
211 | 246 | "created_at": "2015-08-28T20:15:15.726057" | 220 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" |
212 | 247 | } | 221 | } |
213 | 248 | } | 222 | } |
214 | 249 | </pre> | 223 | </pre> |
215 | @@ -251,42 +225,39 @@ | |||
216 | 251 | 225 | ||
217 | 252 | <table class="table"> | 226 | <table class="table"> |
218 | 253 | <tr> | 227 | <tr> |
220 | 254 | <th>Action <th>Manifest Listing | 228 | <th>Action <th>Product Listing |
221 | 255 | <tr> | 229 | <tr> |
223 | 256 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/products/manifests | 230 | <td>URL <td>https://spi.canonical.com/products |
224 | 257 | <tr> | 231 | <tr> |
225 | 258 | <td>Method <td>GET | 232 | <td>Method <td>GET |
226 | 259 | <tr> | 233 | <tr> |
227 | 260 | <td>Data <td>N/A | 234 | <td>Data <td>N/A |
228 | 261 | <tr> | 235 | <tr> |
230 | 262 | <td>Response <td><code>200</code> a JSON list of manifests | 236 | <td>Response <td><code>200</code> a JSON list of products and packages for the user. |
231 | 263 | <tr> | 237 | <tr> |
232 | 264 | <td>Example <td> | 238 | <td>Example <td> |
233 | 265 | <pre> | 239 | <pre> |
235 | 266 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/orgs/docs-org/products/manifests | 240 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/products |
236 | 267 | 241 | ||
238 | 268 | HTTP 200 | 242 | HTTP 200 |
239 | 269 | { | 243 | { |
241 | 270 | "manifests": [ | 244 | "products": [ |
242 | 271 | { | 245 | { |
245 | 272 | "image_name": "e2e-img8c80b8b271814262add99ccf4d3deba6", | 246 | "primary_snap_name": "test-snap.foo", |
246 | 273 | "base_image_reference": "http://foo.com/bar", | 247 | "active": true, |
247 | 274 | "snaps": [ | 248 | "snaps": [ |
258 | 275 | { | 249 | "pi2.canonical", |
259 | 276 | "revision": 1, | 250 | "webdm.canonical", |
260 | 277 | "name": "snap-a", | 251 | "test-snap.foo" |
251 | 278 | "locked": true | ||
252 | 279 | }, | ||
253 | 280 | { | ||
254 | 281 | "revision": null, | ||
255 | 282 | "name": "snap-b", | ||
256 | 283 | "locked": false | ||
257 | 284 | } | ||
261 | 285 | ], | 252 | ], |
265 | 286 | "id": "9b2ff50c-5fab-4039-a5e5-1a9672d71223", | 253 | "release": "15.04-core", |
266 | 287 | "release": "15.04", | 254 | "name": "test-product.e2e", |
267 | 288 | "created_at": "2015-08-28T20:00:11.058236" | 255 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", |
268 | 256 | "created_at": "2016-01-04T17:34:39.093142" | ||
269 | 289 | } | 257 | } |
270 | 258 | ], | ||
271 | 259 | "packages": [ | ||
272 | 260 | "test-snap.foo" | ||
273 | 290 | ] | 261 | ] |
274 | 291 | } | 262 | } |
275 | 292 | </pre> | 263 | </pre> |
276 | @@ -294,9 +265,9 @@ | |||
277 | 294 | 265 | ||
278 | 295 | <table class="table"> | 266 | <table class="table"> |
279 | 296 | <tr> | 267 | <tr> |
281 | 297 | <th>Action <th>Manifest View | 268 | <th>Action <th>Product View |
282 | 298 | <tr> | 269 | <tr> |
284 | 299 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/products/manifests/<manifest-id> | 270 | <td>URL <td>https://spi.canonical.com/products/<product-id> |
285 | 300 | <tr> | 271 | <tr> |
286 | 301 | <td>Method <td>GET | 272 | <td>Method <td>GET |
287 | 302 | <tr> | 273 | <tr> |
288 | @@ -306,28 +277,22 @@ | |||
289 | 306 | <tr> | 277 | <tr> |
290 | 307 | <td>Example <td> | 278 | <td>Example <td> |
291 | 308 | <pre> | 279 | <pre> |
293 | 309 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/orgs/docs-org/products/manifests/9b2ff50c-5fab-4039-a5e5-1a9672d71223 | 280 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
294 | 310 | 281 | ||
296 | 311 | HTTP 200 | 282 | HTTP 200 |
297 | 312 | { | 283 | { |
303 | 313 | "manifest": { | 284 | "product": { |
304 | 314 | "release": "15.04", | 285 | "release": "15.04-core", |
300 | 315 | "base_image_reference": "http://foo.com/bar", | ||
301 | 316 | "id": "9b2ff50c-5fab-4039-a5e5-1a9672d71223", | ||
302 | 317 | "image_name": "e2e-img8c80b8b271814262add99ccf4d3deba6", | ||
305 | 318 | "snaps": [ | 286 | "snaps": [ |
316 | 319 | { | 287 | "pi2.canonical", |
317 | 320 | "locked": true, | 288 | "webdm.canonical", |
318 | 321 | "name": "snap-a", | 289 | "test-snap.foo" |
309 | 322 | "revision": 1 | ||
310 | 323 | }, | ||
311 | 324 | { | ||
312 | 325 | "locked": false, | ||
313 | 326 | "name": "snap-b", | ||
314 | 327 | "revision": null | ||
315 | 328 | } | ||
319 | 329 | ], | 290 | ], |
321 | 330 | "created_at": "2015-08-28T20:00:11.058236" | 291 | "primary_snap_name": "test-snap.foo", |
322 | 292 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", | ||
323 | 293 | "created_at": "2016-01-04T17:34:39.093142", | ||
324 | 294 | "name": "test-product.foo", | ||
325 | 295 | "active": true | ||
326 | 331 | } | 296 | } |
327 | 332 | } | 297 | } |
328 | 333 | </pre> | 298 | </pre> |
329 | @@ -336,16 +301,16 @@ | |||
330 | 336 | 301 | ||
331 | 337 | <table class="table"> | 302 | <table class="table"> |
332 | 338 | <tr> | 303 | <tr> |
334 | 339 | <th>Action <th>Manifest Deactivation/Reactivation | 304 | <th>Action <th>Product Deactivation/Reactivation |
335 | 340 | <tr> | 305 | <tr> |
337 | 341 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/products/manifests/<manifest-id> | 306 | <td>URL <td>https://spi.canonical.com/products/<product-id> |
338 | 342 | <tr> | 307 | <tr> |
339 | 343 | <td>Method <td>PUT | 308 | <td>Method <td>PUT |
340 | 344 | <tr> | 309 | <tr> |
341 | 345 | <td>Data <td> | 310 | <td>Data <td> |
342 | 346 | <pre> | 311 | <pre> |
343 | 347 | { | 312 | { |
345 | 348 | “active”: "false", # or “true” to reactivate | 313 | "active": "false", # or "true" to reactivate |
346 | 349 | } | 314 | } |
347 | 350 | </pre> | 315 | </pre> |
348 | 351 | <tr> | 316 | <tr> |
349 | @@ -354,7 +319,9 @@ | |||
350 | 354 | <td>Example <td> | 319 | <td>Example <td> |
351 | 355 | <pre> | 320 | <pre> |
352 | 356 | $ ./scripts/api_example.py -X PUT conf.ini \ | 321 | $ ./scripts/api_example.py -X PUT conf.ini \ |
354 | 357 | https://spi.canonical.com/orgs/docs-org/products/manifests/9b2ff50c-5fab-4039-a5e5-1a9672d71223 | 322 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -data '{ |
355 | 323 | "active": "true" | ||
356 | 324 | }' | ||
357 | 358 | 325 | ||
358 | 359 | HTTP 200 | 326 | HTTP 200 |
359 | 360 | { | 327 | { |
360 | @@ -364,9 +331,9 @@ | |||
361 | 364 | 331 | ||
362 | 365 | <table class="table"> | 332 | <table class="table"> |
363 | 366 | <tr> | 333 | <tr> |
365 | 367 | <th>Action <th>Manifest Deletion | 334 | <th>Action <th>Product Deletion |
366 | 368 | <tr> | 335 | <tr> |
368 | 369 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/products/manifests/<manifest-id> | 336 | <td>URL <td>https://spi.canonical.com/products/<product-id> |
369 | 370 | <tr> | 337 | <tr> |
370 | 371 | <td>Method <td>DELETE | 338 | <td>Method <td>DELETE |
371 | 372 | <tr> | 339 | <tr> |
372 | @@ -377,36 +344,154 @@ | |||
373 | 377 | <td>Example <td> | 344 | <td>Example <td> |
374 | 378 | <pre> | 345 | <pre> |
375 | 379 | $ ./scripts/api_example.py -X DELETE conf.ini \ | 346 | $ ./scripts/api_example.py -X DELETE conf.ini \ |
383 | 380 | https://spi.canonical.com/orgs/docs-org/products/manifests/9b2ff50c-5fab-4039-a5e5-1a9672d71223 | 347 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
384 | 381 | 348 | ||
385 | 382 | HTTP 200 | 349 | HTTP 200 |
386 | 383 | { | 350 | { |
387 | 384 | "ok": true | 351 | "ok": true |
388 | 385 | } | 352 | } |
389 | 386 | </table> | 353 | </table> |
390 | 354 | |||
391 | 355 | Base Image Management | ||
392 | 356 | --------------------- | ||
393 | 357 | |||
394 | 358 | Base Images are automatically created. The user can mark them as released, to indicate that | ||
395 | 359 | the specific combination of snaps is representative of a product release, or as active/inactive | ||
396 | 360 | to mark them as not useful anymore. | ||
397 | 361 | |||
398 | 362 | <table class="table"> | ||
399 | 363 | <tr> | ||
400 | 364 | <th>Action <th>Base Image Listing | ||
401 | 365 | <tr> | ||
402 | 366 | <td>URL <td>https://spi.canonical.com/products/<product-id>/baseimages | ||
403 | 367 | <tr> | ||
404 | 368 | <td>Method <td>GET | ||
405 | 369 | <tr> | ||
406 | 370 | <td>Data <td>N/A | ||
407 | 371 | <tr> | ||
408 | 372 | <td>Response <td><code>200 OK</code> and a JSON representation of the available baseimages | ||
409 | 373 | <tr> | ||
410 | 374 | <td>Example <td> | ||
411 | 375 | <pre> | ||
412 | 376 | $ ./scripts/api_example.py conf.ini \ | ||
413 | 377 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/baseimages | ||
414 | 378 | |||
415 | 379 | HTTP 200 | ||
416 | 380 | { | ||
417 | 381 | "baseimages": [ | ||
418 | 382 | { | ||
419 | 383 | "released_at": null, | ||
420 | 384 | "product_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", | ||
421 | 385 | "snaps": [ | ||
422 | 386 | { | ||
423 | 387 | "name": "test-snap.foo", | ||
424 | 388 | "revision": 1 | ||
425 | 389 | }, | ||
426 | 390 | { | ||
427 | 391 | "name": "webdm.canonical", | ||
428 | 392 | "revision": 1 | ||
429 | 393 | }, | ||
430 | 394 | { | ||
431 | 395 | "name": "pi2.canonical", | ||
432 | 396 | "revision": 1 | ||
433 | 397 | } | ||
434 | 398 | ], | ||
435 | 399 | "channel": "stable", | ||
436 | 400 | "created_at": "2016-01-04T18:45:48.853476", | ||
437 | 401 | "active": true, | ||
438 | 402 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
439 | 403 | } | ||
440 | 404 | ] | ||
441 | 405 | } | ||
442 | 406 | </table> | ||
443 | 407 | |||
444 | 408 | <table class="table"> | ||
445 | 409 | <tr> | ||
446 | 410 | <th>Action <th>Base Image Viewing | ||
447 | 411 | <tr> | ||
448 | 412 | <td>URL <td>https://spi.canonical.com/products/<product-id>/baseimages/<image-id> | ||
449 | 413 | <tr> | ||
450 | 414 | <td>Method <td>GET | ||
451 | 415 | <tr> | ||
452 | 416 | <td>Data <td>N/A | ||
453 | 417 | <tr> | ||
454 | 418 | <td>Response <td><code>200 OK</code> and a JSON representation of the base image. | ||
455 | 419 | <tr> | ||
456 | 420 | <td>Example <td> | ||
457 | 421 | <pre> | ||
458 | 422 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/baseimages/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
459 | 423 | |||
460 | 424 | HTTP 200 | ||
461 | 425 | { | ||
462 | 426 | "baseimage": { | ||
463 | 427 | "created_at": "2016-01-04T18:45:48.853476", | ||
464 | 428 | "channel": "stable", | ||
465 | 429 | "active": true, | ||
466 | 430 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", | ||
467 | 431 | "snaps": [ | ||
468 | 432 | { | ||
469 | 433 | "name": "test-snap.foo", | ||
470 | 434 | "revision": 1 | ||
471 | 435 | }, | ||
472 | 436 | { | ||
473 | 437 | "name": "webdm.canonical", | ||
474 | 438 | "revision": 1 | ||
475 | 439 | }, | ||
476 | 440 | { | ||
477 | 441 | "name": "pi2.canonical", | ||
478 | 442 | "revision": 1 | ||
479 | 443 | } | ||
480 | 444 | ], | ||
481 | 445 | "product_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", | ||
482 | 446 | "released_at": null | ||
483 | 447 | } | ||
484 | 448 | } | ||
485 | 449 | </table> | ||
486 | 450 | |||
487 | 451 | <table class="table"> | ||
488 | 452 | <tr> | ||
489 | 453 | <th>Action <th>Base Image Updating | ||
490 | 454 | <tr> | ||
491 | 455 | <td>URL <td>https://spi.canonical.com/products/<product-id>/baseimages/<image-id> | ||
492 | 456 | <tr> | ||
493 | 457 | <td>Method <td>PUT | ||
494 | 458 | <tr> | ||
495 | 459 | <td>Data <td> | ||
496 | 460 | <pre> | ||
497 | 461 | { | ||
498 | 462 | "active": "false", # or "true" to reactivate | ||
499 | 463 | "released": "true", # or "false" | ||
500 | 464 | } | ||
501 | 465 | </pre> | ||
502 | 466 | <tr> | ||
503 | 467 | <td>Response <td><code>200 OK</code> | ||
504 | 468 | <tr> | ||
505 | 469 | <td>Example <td> | ||
506 | 470 | <pre> | ||
507 | 471 | $ ./scripts/api_example.py -X PUT conf.ini \ | ||
508 | 472 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/baseimages/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -data '{ | ||
509 | 473 | "released": "true" | ||
510 | 474 | }' | ||
511 | 475 | |||
512 | 476 | HTTP 200 | ||
513 | 477 | { | ||
514 | 478 | "ok": true | ||
515 | 479 | } | ||
516 | 480 | </table> | ||
517 | 481 | |||
518 | 482 | |||
519 | 387 | 483 | ||
520 | 388 | Test Management | 484 | Test Management |
521 | 389 | --------------- | 485 | --------------- |
522 | 390 | 486 | ||
523 | 391 | Tests are defined with Test Specs. There may be multiple | 487 | Tests are defined with Test Specs. There may be multiple |
536 | 392 | Test Specs per product and they are related via the image\_name field. | 488 | Test Specs per product and they form the basis for TestOpportunity creation. |
525 | 393 | TestSpecs are required for both Image and Snappy based workflows as they | ||
526 | 394 | form the basis for TestOpportunity creation. | ||
527 | 395 | |||
528 | 396 | Test Specs are immutable but may be deleted or deactivated to be | ||
529 | 397 | hidden from view. The details of the Test Spec that led to a Test | ||
530 | 398 | Opportunity is always persisted in the Test Result data. | ||
531 | 399 | |||
532 | 400 | To modify a Test Spec, the user should delete the existing one and | ||
533 | 401 | create a new one with the desired changes. That will not automatically | ||
534 | 402 | trigger new tests, for that see [Test | ||
535 | 403 | Triggering](#test-triggering). | ||
537 | 404 | 489 | ||
538 | 405 | <table class="table"> | 490 | <table class="table"> |
539 | 406 | <tr> | 491 | <tr> |
540 | 407 | <th>Action <th>Test Spec Creation | 492 | <th>Action <th>Test Spec Creation |
541 | 408 | <tr> | 493 | <tr> |
543 | 409 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/tests/specs | 494 | <td>URL <td>https://spi.canonical.com/products/<product-id>/tests/specs |
544 | 410 | <tr> | 495 | <tr> |
545 | 411 | <td>Method <td>POST | 496 | <td>Method <td>POST |
546 | 412 | <tr> | 497 | <tr> |
547 | @@ -414,10 +499,10 @@ | |||
548 | 414 | <pre> | 499 | <pre> |
549 | 415 | { | 500 | { |
550 | 416 | "platform": platform of the product | 501 | "platform": platform of the product |
553 | 417 | "name": unique (within an org) name of the Test | 502 | "name": unique (within the product) name of the Test |
552 | 418 | "image_name": name that ties this test to the product/manifest | ||
554 | 419 | "test_payload": an arbitrary JSON value with all the information needed to run the test | 503 | "test_payload": an arbitrary JSON value with all the information needed to run the test |
555 | 420 | (maximum size 4000 bytes), optional defaulting to null | 504 | (maximum size 4000 bytes), optional defaulting to null |
556 | 505 | "channel_combos": **FIXME DESCRIBE** | ||
557 | 421 | } | 506 | } |
558 | 422 | </pre> | 507 | </pre> |
559 | 423 | <tr> | 508 | <tr> |
560 | @@ -428,21 +513,43 @@ | |||
561 | 428 | $ ./scripts/api_example.py -X POST conf.ini https://spi.canonical.com/orgs/docs-org/tests/specs \ | 513 | $ ./scripts/api_example.py -X POST conf.ini https://spi.canonical.com/orgs/docs-org/tests/specs \ |
562 | 429 | --data ' | 514 | --data ' |
563 | 430 | { | 515 | { |
564 | 516 | "name": "foo-spec_bar", | ||
565 | 431 | "platform": "amd64", | 517 | "platform": "amd64", |
568 | 432 | "image_name": "imgname", | 518 | "channel_combos": [ |
569 | 433 | "name": "specname32" | 519 | { |
570 | 520 | "update": "edge", | ||
571 | 521 | "base": "stable" | ||
572 | 522 | } | ||
573 | 523 | ], | ||
574 | 524 | "test_payload": "{'foo': 'bar'}" | ||
575 | 434 | }' | 525 | }' |
576 | 435 | 526 | ||
577 | 436 | HTTP 201 | 527 | HTTP 201 |
578 | 528 | Location: https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tests/specs/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
579 | 437 | { | 529 | { |
580 | 438 | "spec": { | 530 | "spec": { |
584 | 439 | "image_name": "imgname", | 531 | "product_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
585 | 440 | "id": "cd98a77f-f7da-4388-b007-0a8a3604b676", | 532 | "created_at": "2016-01-04T16:58:26.357538", |
586 | 441 | "name": "specname32", | 533 | "active": true, |
587 | 442 | "platform": "amd64", | 534 | "platform": "amd64", |
591 | 443 | "created_at": "2015-08-28T20:28:46.334756", | 535 | "test_payload": "{'foo': 'bar'}", |
592 | 444 | "test_payload": null | 536 | "name": "foo-spec_bar", |
593 | 445 | } | 537 | "channel_combos": [ |
594 | 538 | { | ||
595 | 539 | "update": "edge", | ||
596 | 540 | "base": "stable" | ||
597 | 541 | } | ||
598 | 542 | ], | ||
599 | 543 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
600 | 544 | }, | ||
601 | 545 | "test_ids": [ | ||
602 | 546 | [ | ||
603 | 547 | { | ||
604 | 548 | "image_unique_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", | ||
605 | 549 | "test_opportunity_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
606 | 550 | } | ||
607 | 551 | ] | ||
608 | 552 | ] | ||
609 | 446 | } | 553 | } |
610 | 447 | </pre> | 554 | </pre> |
611 | 448 | </table> | 555 | </table> |
612 | @@ -451,7 +558,7 @@ | |||
613 | 451 | <tr> | 558 | <tr> |
614 | 452 | <th>Action <th>Test Spec List | 559 | <th>Action <th>Test Spec List |
615 | 453 | <tr> | 560 | <tr> |
617 | 454 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/tests/specs | 561 | <td>URL <td>https://spi.canonical.com/products/<product-id>/tests/specs |
618 | 455 | <tr> | 562 | <tr> |
619 | 456 | <td>Method <td>GET | 563 | <td>Method <td>GET |
620 | 457 | <tr> | 564 | <tr> |
621 | @@ -461,18 +568,25 @@ | |||
622 | 461 | <tr> | 568 | <tr> |
623 | 462 | <td>Example <td> | 569 | <td>Example <td> |
624 | 463 | <pre> | 570 | <pre> |
626 | 464 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/orgs/docs-org/tests/specs | 571 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tests/specs |
627 | 465 | 572 | ||
629 | 466 | HTTP 200 | 573 | HTTP 200 |
630 | 467 | { | 574 | { |
631 | 468 | "specs": [ | 575 | "specs": [ |
632 | 469 | { | 576 | { |
637 | 470 | "created_at": "2015-08-28T20:28:46.334756", | 577 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
638 | 471 | "id": "cd98a77f-f7da-4388-b007-0a8a3604b676", | 578 | "active": true, |
639 | 472 | "test_payload": null, | 579 | "created_at": "2016-01-04T17:34:39.626802", |
640 | 473 | "image_name": "imgname", | 580 | "product_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
641 | 581 | "test_payload": "{'foo': 'bar'}", | ||
642 | 582 | "name": "foo-spec_bar", | ||
643 | 474 | "platform": "amd64", | 583 | "platform": "amd64", |
645 | 475 | "name": "specname32" | 584 | "channel_combos": [ |
646 | 585 | { | ||
647 | 586 | "update": "edge", | ||
648 | 587 | "base": "stable" | ||
649 | 588 | } | ||
650 | 589 | ] | ||
651 | 476 | } | 590 | } |
652 | 477 | ] | 591 | ] |
653 | 478 | } | 592 | } |
654 | @@ -483,7 +597,7 @@ | |||
655 | 483 | <tr> | 597 | <tr> |
656 | 484 | <th>Action <th>Test Spec View | 598 | <th>Action <th>Test Spec View |
657 | 485 | <tr> | 599 | <tr> |
659 | 486 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/tests/specs/<spec-id> | 600 | <td>URL <td>https://spi.canonical.com/products/<product-id>/tests/specs/<spec-id> |
660 | 487 | <tr> | 601 | <tr> |
661 | 488 | <td>Method <td>GET | 602 | <td>Method <td>GET |
662 | 489 | <tr> | 603 | <tr> |
663 | @@ -493,17 +607,24 @@ | |||
664 | 493 | <tr> | 607 | <tr> |
665 | 494 | <td>Example <td> | 608 | <td>Example <td> |
666 | 495 | <pre> | 609 | <pre> |
668 | 496 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/orgs/docs-org/tests/specs/cd98a77f-f7da-4388-b007-0a8a3604b676 | 610 | $ ./scripts/api_example.py conf.ini https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tests/specs/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
669 | 497 | 611 | ||
670 | 498 | HTTP 200 | 612 | HTTP 200 |
671 | 499 | { | 613 | { |
672 | 500 | "spec": { | 614 | "spec": { |
679 | 501 | "id": "cd98a77f-f7da-4388-b007-0a8a3604b676", | 615 | "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
680 | 502 | "name": "specname32", | 616 | "active": true, |
681 | 503 | "platform": "amd64", | 617 | "created_at": "2016-01-04T17:34:39.626802", |
682 | 504 | "created_at": "2015-08-28T20:28:46.334756", | 618 | "product_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
683 | 505 | "test_payload": null, | 619 | "test_payload": "{'foo': 'bar'}", |
684 | 506 | "image_name": "imgname" | 620 | "name": "foo-spec_bar", |
685 | 621 | "platform": "amd64", | ||
686 | 622 | "channel_combos": [ | ||
687 | 623 | { | ||
688 | 624 | "update": "edge", | ||
689 | 625 | "base": "stable" | ||
690 | 626 | } | ||
691 | 627 | ] | ||
692 | 507 | } | 628 | } |
693 | 508 | } | 629 | } |
694 | 509 | 630 | ||
695 | @@ -514,14 +635,14 @@ | |||
696 | 514 | <tr> | 635 | <tr> |
697 | 515 | <th>Action <th>Test Spec Deactivation/Reactivation | 636 | <th>Action <th>Test Spec Deactivation/Reactivation |
698 | 516 | <tr> | 637 | <tr> |
700 | 517 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/tests/specs/<spec-id> | 638 | <td>URL <td>https://spi.canonical.com/products/<product-id>/tests/specs/<spec-id> |
701 | 518 | <tr> | 639 | <tr> |
702 | 519 | <td>Method <td>PUT | 640 | <td>Method <td>PUT |
703 | 520 | <tr> | 641 | <tr> |
704 | 521 | <td>Data <td> | 642 | <td>Data <td> |
705 | 522 | <pre> | 643 | <pre> |
706 | 523 | { | 644 | { |
708 | 524 | “active”: "false", # or “true” to reactivate | 645 | "active": "false", # or "true" to reactivate |
709 | 525 | } | 646 | } |
710 | 526 | </pre> | 647 | </pre> |
711 | 527 | <tr> | 648 | <tr> |
712 | @@ -530,7 +651,10 @@ | |||
713 | 530 | <td>Example <td> | 651 | <td>Example <td> |
714 | 531 | <pre> | 652 | <pre> |
715 | 532 | $ ./scripts/api_example.py -X PUT conf.ini \ | 653 | $ ./scripts/api_example.py -X PUT conf.ini \ |
717 | 533 | https://spi.canonical.com/orgs/docs-org/tests/specs/cd98a77f-f7da-4388-b007-0a8a3604b676 | 654 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tests/specs/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --data ' |
718 | 655 | { | ||
719 | 656 | "active": "false" | ||
720 | 657 | }' | ||
721 | 534 | 658 | ||
722 | 535 | HTTP 200 | 659 | HTTP 200 |
723 | 536 | { | 660 | { |
724 | @@ -543,7 +667,7 @@ | |||
725 | 543 | <tr> | 667 | <tr> |
726 | 544 | <th>Action <th>Test Spec Deletion | 668 | <th>Action <th>Test Spec Deletion |
727 | 545 | <tr> | 669 | <tr> |
729 | 546 | <td>URL <td>https://spi.canonical.com/orgs/<org-id>/tests/specs/<spec-id> | 670 | <td>URL <td>https://spi.canonical.com/products/<product-id>/tests/specs/<spec-id> |
730 | 547 | <tr> | 671 | <tr> |
731 | 548 | <td>Method <td>DELETE | 672 | <td>Method <td>DELETE |
732 | 549 | <tr> | 673 | <tr> |
733 | @@ -554,7 +678,7 @@ | |||
734 | 554 | <td>Example <td> | 678 | <td>Example <td> |
735 | 555 | <pre> | 679 | <pre> |
736 | 556 | $ ./scripts/api_example.py -X DELETE conf.ini \ | 680 | $ ./scripts/api_example.py -X DELETE conf.ini \ |
738 | 557 | https://spi.canonical.com/orgs/docs-org/tests/specs/cd98a77f-f7da-4388-b007-0a8a3604b676 | 681 | https://spi.canonical.com/products/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/tests/specs/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
739 | 558 | 682 | ||
740 | 559 | HTTP 200 | 683 | HTTP 200 |
741 | 560 | { | 684 | { |
742 | @@ -562,6 +686,7 @@ | |||
743 | 562 | }</pre> | 686 | }</pre> |
744 | 563 | </table> | 687 | </table> |
745 | 564 | 688 | ||
746 | 689 | |||
747 | 565 | Test Triggering | 690 | Test Triggering |
748 | 566 | --------------- | 691 | --------------- |
749 | 567 | 692 | ||
750 | @@ -572,7 +697,6 @@ | |||
751 | 572 | has the following required fields: | 697 | has the following required fields: |
752 | 573 | 698 | ||
753 | 574 | 699 | ||
754 | 575 | |||
755 | 576 | - ```image_name```: a unique name within an | 700 | - ```image_name```: a unique name within an |
756 | 577 | organization that is combined with each | 701 | organization that is combined with each |
757 | 578 | test case to produce the full set of test | 702 | test case to produce the full set of test |
LGTM, I can take a stab at the FIXMEs after.