Merge lp:~ralsina/tanuki-agent/fix-product-ref into lp:tanuki-agent

Proposed by Roberto Alsina on 2016-01-04
Status: Merged
Approved by: Roberto Alsina on 2016-01-04
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
Reviewer Review Type Date Requested Status
Bret Barker 2016-01-04 Approve on 2016-01-04
Review via email: mp+281536@code.launchpad.net

Commit message

Update doc to the current product-based API (part 1: products/testspecs/baseimages)

Description of the change

Update doc to the current product-based API (part 1: products/testspecs/baseimages)

To post a comment you must log in.
Bret Barker (noise) wrote :

LGTM, I can take a stab at the FIXMEs after.

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: