3
The current live API lives at https://api.jujucharms.com/charmstore/v5
7
The charm store stores and indexes charms and bundles. A charm or bundle is
8
referred to by a charm store id which can take one of the following two forms:
10
* ~*owner*/*series*/*name*(-*revision*)
11
* *series*/*name*(-*revision*)
13
*Owner* is the name of the user that owns the charm.
14
*Series* is one of a small number of known possible series for charms
15
(currently just the Ubuntu series names) or the special name bundle to signify
16
that the charm id refers to a charm bundle.
18
A charm store id referring to a charm (not a bundle) can also use one of the
19
following two forms, omitting the series:
21
* ~*owner*/*name*(-*revision*)
24
In this case the store will look at all charms with the same *owner* and
25
*name*, and choose one according to its preference (for example, it currently
26
prefers the latest LTS series).
30
All endpoints that do not produce binary data produce a single JSON object as
31
their result. These will be described in terms of the Go types that produce and
32
consume the format, along with an example. A charm id is represented as a
37
If any request returns an error, it will produce it in the following form:
43
Info map[string] Error `json:",omitempty"`
51
"Message": "unexpected Content-Type \"image/jpeg\"; expected \"application/json\"",
56
Note: this format is compatible with the error results used by juju-core.
57
Currently defined codes are the following:
68
The `Info` field is set when a request returns a "multiple errors" error code;
69
currently the only two endpoints that can are "/meta" and "*id*/meta/any".
70
Each element in `Info` corresponds to an element in the PUT request, and holds
71
the error for that element. See those endpoints for examples.
73
### Bulk requests and missing metadata
75
There are two forms of "bulk" API request that can return information about
76
several items at once. The `/meta/any` endpoint (along with some others) have a
77
set of "include" flags that specify metadata to return. The `/meta` endpoint
78
has a set of "id" flags that specify a set of ids to return data on.
80
In both of these cases, when the relevant data does not exist, the result will
81
be omitted from the returned map. For example a GET of
82
`/meta/archive-size?id=something` will return an empty map if the id
83
"something" is not found; a GET of
84
`/precise/wordpress-34/meta/any?include=bundle-metadata` will return an empty
85
map if the id "precise/wordpress-34" refers to a bundle rather than a charm.
87
For the singular forms of these endpoints, a 404 "metadata not found" error
88
will be returned when this happens.
90
In the `meta/any` GET bulk request, if some data requires authorization, the
91
default behavior is to return an authorization required response. Clients
92
interested in public data only can include a `ignore-auth=1` query so that only
93
public information is returned. In this case, results requiring authorization
94
(if any) will be omitted.
98
Any entity in the charm store is considered to be part of one or more "channels"
99
(think "distribution channels"). Currently supported channels are "unpublished",
100
"development" and "stable". All entities are initially (and always) part
101
of the "unpublished" channel; subsequent operations on the publish
102
endpoint can make entities available in other channels.
104
All requests that take one or more entity ids as parameters
105
accept a "channel" query parameter that influences what channel
106
is chosen to resolve the ids. The default channel is "stable".
108
For example, if wordpress-3 has just been published to the stable
109
channel, and wordpress-4 has been published to the development
110
then a GET of wordpress/meta/id-revision?channel=development
111
will return {"Revision": 4} and a GET of wordpress/wordpress/meta/id-revision
112
will return {"Revision": 3} because the default channel is "stable".
116
The version of the API is indicated by an initial "vN" prefix to the path.
117
Later versions will increment this number. This also means we can potentially
118
serve backwardly compatible paths to juju-core. All paths in this document
119
should be read as if they had a "v5" prefix. For example, the
120
`wordpress/meta/charm-metadata` path is actually at
121
`v5/wordpress/meta/charm-metadata`.
125
Where a flag specifies a boolean property, the value must be either "1",
126
signifying true, or empty or "0", signifying false.
132
#### GET *id*/expand-id
134
The expand-id path expands a general id into a set of specific ids. It strips
135
any revision number and series from id, and returns a slice of all the possible
136
ids matched by that, including all the versions and series.
137
If *id* is in the development channel, all development and non-development
138
revisions will be returned; if it is not, then only non-development
139
revisions will be returned.
149
Example: `GET wordpress/expand-id`
153
{"Id": "trusty/wordpress-2"}
154
{"Id": "trusty/wordpress-1"},
155
{"Id": "precise/wordpress-2"},
156
{"Id": "precise/wordpress-1"},
160
Example: `GET precise/wordpress-34/expand-id`
164
{"Id": "trusty/wordpress-2"}
165
{"Id": "trusty/wordpress-1"},
166
{"Id": "precise/wordpress-2"},
167
{"Id": "precise/wordpress-1"},
171
Example: `GET development/precise/wordpress-34/expand-id`
175
{"Id": "development/trusty/wordpress-3"},
176
{"Id": "trusty/wordpress-2"},
177
{"Id": "trusty/wordpress-1"},
178
{"Id": "precise/wordpress-2"},
179
{"Id": "precise/wordpress-1"},
186
#### GET *id*/archive
188
The `/archive` path returns the raw archive zip file for the charm with the
189
given charm id. The response header includes the SHA 384 hash of the archive
190
(Content-Sha384) and the fully qualified entity id (Entity-Id).
192
Example: `GET wordpress/archive`
194
Any additional elements attached to the `/charm` path retrieve the file from
195
the charm or bundle's zip file. The `Content-Sha384` header field in the
196
response will hold the hash checksum of the archive.
198
#### GET *id*/archive/*path*
200
Retrieve a file corresponding to *path* in the charm or bundle's zip archive.
202
Example: `GET trusty/wordpress/archive/config.yaml`
204
#### POST *id*/archive
206
This uploads the given charm or bundle in zip format.
209
POST <i>id</i>/archive?hash=<i>sha384hash</i>
212
The id specified must specify the series and must not contain a revision
213
number. The hash flag must specify the SHA384 hash of the uploaded archive in
214
hexadecimal format. If the same content has already been uploaded, the response
215
will return immediately without reading the entire body.
217
The charm or bundle is verified before being made available.
219
The response holds the full charm/bundle id including the revision number.
222
type UploadedId struct {
227
Example response body:
231
"Id": "precise/wordpress-24"
235
#### DELETE *id*/archive
237
This deletes the given charm or bundle with the given id. If the ID is not
238
fully specified, the charm series or revisions are not resolved and the charm
239
is not deleted. In order to delete the charm, the ID must include series as
240
well as revisions. In order to delete all versions of the charm, use
241
`/expand-id` and iterate on all elements in the result.
245
#### GET *id*/diagram.svg
247
This returns a scalable vector-graphics image representing the entity with the
248
given id. This will return a not-found error for charms.
250
#### GET *id*/icon.svg
252
This returns the SVG image of the charm's icon. This reports a not-found error
253
for bundles. Unlike the `archive/icon.svg` where 404 is returned in case an
254
icon does not exist, this endpoint returns the default icon.
258
This returns the README.
262
#### PUT *id*/promulgate
264
A PUT to ~*user*/*anyseries*/*name*-*anyrevision* sets whether entities
265
with the id *x*/*name* are considered to be aliases
266
for ~*user*/*x*/*name* for all series *x*. The series
267
and revision in the id are ignored (except that an
268
entity must exist that matches the id).
270
If Promulgate is true, it means that any new charms published
271
to ~*user*/*x*/*name* will also be given the alias
272
*x*/*name*. The latest revision for all ids ~*user*/*anyseries*/*name*
273
will also be aliased likewise.
275
If Promulgate is false, any new charms published
276
to ~*user*/*anyseries*/*name* will not be given a promulgated
277
alias, but no change is made to any existing aliases.
279
The promulgated status can be retrieved from the
280
promulgated meta endpoint.
283
type PromulgateRequest struct {
288
Example: `PUT ~charmers/precise/wordpress-23/promulgate`
297
### Charm and bundle publishing
299
#### PUT *id*/publish
301
A PUT to the publish endpoint publishes the entity with the given id
302
on the channels provided in the request body. It reports an error if
303
there are no channels specified or if one of the channels is invalid
304
(the "unpublished" channel is special and is also considered invalid in
307
See the section on Channels in the introduction for how the published
308
channels affects id resolving.
311
type PublishRequest struct {
316
On success, the response body will be empty.
318
Example: `PUT ~charmers/trusty/django-42/publish`
323
"Channels" : ["stable"],
327
After the above request, ~charmers/trusty/django will
328
resolve to ~charmers/trusty/django-42 unless a different
329
channel is specified in the request.
333
#### GET stats/counter/...
335
This endpoint can be used to retrieve stats related to entities.
338
GET stats/counter/<i>key</i>[:<i>key</i>]...?[by=<i>unit</i>]&start=<i>date</i>][&stop=<i>date</i>][&list=1]
341
The stats path allows the retrieval of counts of operations in a general way. A
342
statistic is composed of an ordered tuple of keys:
345
<i>kind</i>:<i>series</i>:<i>name</i>:<i>user</i>
347
Operations on the store increment counts associated with a specific tuple,
348
determined by the operation and the charm being operated on.
350
When querying statistics, it is possible to aggregate statistics by using a
351
`\*` as the last tuple element, standing for all tuples with the given prefix.
352
For example, `missing:\*` will retrieve the counts for all operations of kind
353
"missing", regardless of the series, name or user.
355
If the list flag is specified, counts for all next level keys will be listed.
356
For example, a query for `stats/counter/download:*?list=1&by=week` will show
357
all the download counts for each series for each week.
359
If a date range is specified, the returned counts will be restricted to the
360
given date range. Dates are specified in the form "yyyy-mm-dd". If the `by`
361
flag is specified, one count is shown for each unit in the specified period,
362
where unit can be `week` or `day`.
369
* archive-failed-upload
374
type Statistic struct {
375
Key string `json:",omitempty"`
376
Date string `json:",omitempty"`
381
Example: `GET "stats/counter/missing:trusty:*"`
390
`GET stats/counter/download/archive-download:*?by=week&list=1&start=2014-03-01`
395
"Key": "charm-bundle:precise:*",
396
"Date": "2014-06-08",
399
"Key": "charm-bundle:trusty:*",
400
"Date": "2014-06-08",
403
"Key": "charm-bundle:oneiric:*",
404
"Date": "2014-06-08",
407
"Key": "charm-bundle:quantal:*",
408
"Date": "2014-06-08",
411
"Key": "charm-bundle:trusty:*",
412
"Date": "2014-06-15",
415
"Key": "charm-bundle:precise:*",
416
"Date": "2014-06-15",
423
We need to provide aggregated stats for downloads:
424
* promulgated and ~user counterpart charms should have the same download stats.
426
#### PUT stats/update
428
This endpoint can be used to increase the stats related to an entity.
429
This will increase the download stats by one for the entity provided and at the time stamp provided.
430
It can for future purpose include the client issuing the requests.
431
This is used when charmstore is in front of a cache server that will not call the real /archive endpoint and
432
as such will not increase the download counts.
440
type StatsUpdateRequest struct {
443
CharmReference *charm.URL
446
Example: `PUT stats/update`
452
"Timestamp":"2015-08-06T06:46:13Z",
454
"CharmReference":"cs:~charmers/utopic/wordpress-42"
462
The meta path returns an array of all the path names under meta, excluding the
463
`meta/any` path, as suitable for passing as "include=" flags to paths that
464
allow those. Note that the result does not include sub-paths of extra-info
465
because these vary according to each charm or bundle.
472
"archive-upload-time",
473
"bundle-machine-count",
476
"bundles-containing",
499
#### GET meta/*endpoint*
501
This endpoint allows a user to query any number of IDs for metadata.
503
GET meta/<i>endpoint</i>?id=<i>id0</i>[&id=<i>id1</i>...][<i>otherflags</i>]
506
This call is equivalent to calling "*id*/meta" for each id separately. The
507
result holds an element for each id in the request with the resulting metadata
508
exactly as returned by "GET *id*/meta/*endpoint*[?*otherflags*]". The map keys
509
are the ids exactly as specified in the request, although they are resolved to
510
fill in series and revision as usual when fetching the metadata. Any ids that
511
are not found, or with non-relevant metadata, will be omitted.
514
map[string] interface{}
517
Example: `GET meta/archive-size?id=wordpress&id=mysql`
530
Example: `GET /meta/any?include=archive-size&include=extra-info/featured&id=wordpress&id=mysql`
535
"Id": "precise/wordpress-3",
540
"extra-info/featured": true
544
"Id": "precise/mysql-23",
549
"extra-info/featured": true
555
#### PUT meta/*endpoint*
557
A PUT to this endpoint allows the metadata endpoint of several ids to be
558
updated. The request body is as specified in the result of the above GET
559
request. The ids in the body specify the ids that will be updated. If there is
560
a failure, the error code will be "multiple errors", and the Info field will
561
holds one entry for each id in the request body that failed, holding the error
562
for that id. If there are no errors, PUT endpoints usually return an empty body
565
Example: `PUT meta/extra-info/featured`
570
"precise/wordpress-23" : true,
571
"precise/mysql-53" : true,
572
"precise/wordpress-22" : false,
576
Example: `PUT meta/any`
581
"precise/wordpress-23": {
583
"extra-info/featured": true,
584
"extra-info/revision-info": "12dfede4ee23",
590
"extra-info/featured": false,
596
Response body (with HTTP status 500):
599
"Message": "multiple errors (1) found",
600
"Code": "multiple errors",
602
"precise/wordpress-23": {
603
"Message": "multiple errors",
604
"Code": "multiple errors",
607
"Message": "metadata not found",
616
If the request succeeds, a 200 OK status code is returned with an empty
621
This path returns the same information as the meta path. The results are the
622
same regardless of the actual id.
624
Example: `GET foo/meta`
629
"archive-upload-time",
630
"bundle-machine-count",
633
"bundles-containing",
652
#### GET *id*/meta/any
655
GET <i>id</i>/meta/any?[include=<i>meta</i>[&include=<i>meta</i>...]]
658
The `meta/any` path returns requested metadata information on the given id. If
659
the id is non-specific, the latest revision and preferred series for the id
662
Other metadata can be requested by specifying one or more `include` flags. The
663
value of each meta must be the name of one of the path elements defined under
664
the `/meta` path (for example: `charm-config`, `charm-meta`, `manifest`) and
665
causes the desired metadata to be included in the Meta field, keyed by meta. If
666
there is no metadata for the given meta path, the element will be omitted (for
667
example, if bundle-specific data is requested for a charm id).
669
The `any` path may not itself be the subject of an include directive. It is
670
allowed to specify "charm-" or "bundle-"" specific metadata paths -- if the id
671
refers to a charm then bundle-specific metadata will be omitted and vice versa.
673
Various other paths use the same `include` mechanism to allow retrieval of
678
Id string `json:",omitempty"`
679
Meta map[string] interface{} `json:",omitempty"`
683
Example: `GET wordpress/meta/any`
687
"Id": "trusty/wordpress-32"
691
Example: `GET ubuntu/meta/any?include=archive-size&include=extra-info/featured`
695
"Id": "trusty/ubuntu-3",
700
"extra-info/featured": true
705
#### PUT *id*/meta/any
707
This endpoint allows the updating of several metadata elements at once. These
708
must support PUT requests. The body of the PUT request is in the same form as
709
returned by the above GET request, except with the Id field omitted. The
710
elements inside the Meta field specify which meta endpoints will be updated. If
711
one or more of the update fails, the resulting error will contain an Info field
712
that has an entry for each update that fails, keyed by the endpoint name.
714
Example: `PUT ubuntu/meta/any`
721
"revision-info": "a46f45649f0d0e0b"
723
"extra-info/featured": true
728
Example: `PUT ubuntu/meta/any`
734
"extra-info/featured": false,
735
"archive-size": 12354,
743
"Message": "multiple errors",
744
"Code": "multiple errors",
747
"Message": "method not allowed",
748
"Code": "bad request",
754
#### GET *id*/meta/charm-metadata
756
The `/meta/charm.metadata` path returns the contents of the charm metadata file
757
for a charm. The id must refer to a charm, not a bundle.
760
type CharmMetadata struct {
763
Subordinate bool `json:",omitempty"`
764
// Provides and Requires map from the relation name to
765
// information about the relation.
766
Provides map[string]Relation `json:",omitempty"`
767
Requires map[string]Relation `json:",omitempty"`
768
Peers map[string]Relation `json:",omitempty"`
769
Tags []string `json:",omitempty"`
772
type Relation struct {
774
Optional bool `json:",omitempty"`
775
Limit int `json:",omitempty"`
779
type RelationRole string
780
type RelationScope string
783
The possible values of a `RelationScope` are
788
Example: `GET wordpress/meta/charm-metadata`
792
"Summary": "WordPress is a full featured web blogging tool, this charm deploys it.",
793
"Description": "This will install and setup WordPress optimized to run in the cloud. This install, in particular, will \n place Ngnix and php-fpm configured to scale horizontally with Nginx's reverse proxy\n",
802
"Interface": "cache",
812
"Interface": "reversenginx",
822
#### GET *id*/meta/bundle-metadata
824
The `meta/bundle-metadata` path returns the contents of the bundle metadata
825
file for a bundle. The id must refer to a bundle, not a charm.
828
type BundleData struct {
829
Applications map[string] ApplicationSpec
830
Machines map[string] MachineSpec `json:",omitempty"`
831
Series string `json:",omitempty"`
832
Relations [][]string `json:",omitempty"`
835
type MachineSpec struct {
836
Constraints string `json:",omitempty"`
837
Annotations map[string]string `json:",omitempty"`
840
type ApplicationSpec struct {
843
To []string `json:",omitempty"`
845
// Options holds the configuration values
846
// to apply to the new application. They should
847
// be compatible with the charm configuration.
848
Options map[string]interface{} `json:",omitempty"`
849
Annotations map[string]string `json:",omitempty"`
850
Constraints string `json:",omitempty"`
854
Example: `GET mediawiki/meta/bundle-metadata`
860
"Charm": "cs:precise/mediawiki-10",
864
"name": "Please set name of wiki",
873
"Charm": "cs:precise/memcached-7",
876
"connection_limit": "global",
894
#### GET *id*/meta/bundle-unit-count
896
The `meta/bundle-unit-count` path returns a count of all the units that will be
897
created by a bundle. The id must refer to a bundle, not a charm.
900
type BundleCount struct {
905
Example: `GET bundle/mediawiki/meta/bundle-unit-count`
913
#### GET *id*/meta/bundle-machine-count
915
The `meta/bundle-machine-count` path returns a count of all the machines used
916
by a bundle. The id must refer to a bundle, not a charm.
919
type BundleCount struct {
924
Example: `GET bundle/mediawiki/meta/bundle-machine-count`
932
#### GET *id*/meta/manifest
934
The `meta/manifest` path returns the list of all files in the bundle or charm's
939
type ManifestFile struct {
945
Example: `GET trusty/juju-gui-3/meta/manifest`
950
"Name": "config.yaml",
954
"Name": "HACKING.md",
962
"Name": "metadata.yaml",
970
"Name": "hooks/config-changed",
974
"Name": "hooks/install",
978
"Name": "hooks/start",
982
"Name": "hooks/stop",
988
#### GET *id*/meta/charm-actions
991
The `meta/charm-actions` path returns the actions available in a charm as
992
stored in its `actions.yaml` file. Id must refer to a charm, not a bundle.
995
type Actions struct {
996
Actions map[string]ActionSpec `json:",omitempty"`
999
type ActionSpec struct {
1005
The Params field holds a JSON schema specification of an action's parameters.
1006
See [http://json-schema.org/latest/json-schema-core.html](http://json-schema.org/latest/json-schema-core.html).
1008
Example: `GET wordpress/meta/charm-actions`
1014
"Description": "back up the charm",
1017
"destination-host": {
1020
"destination-name": {
1034
#### GET *id*/meta/charm-config
1036
The `meta/charm-config` path returns the charm's configuration specification as
1037
stored in its `config.yaml` file. Id must refer to a charm, not a bundle.
1040
type Config struct {
1041
Options map[string] Option
1044
// Option represents a single charm config option.
1045
type Option struct {
1052
Example: `GET trusty/juju-gui-3/meta/charm-config`
1059
"Description": "Enable the built-in server.",
1064
"Description": "The help text shown to the user.",
1069
"Description": "Enable read-only mode.",
1076
#### GET *id*/meta/published
1078
The `meta/published` path returns a list of the channels that
1079
the entity has been published to.
1082
type PublishedResponse struct {
1083
// Info holds an entry for each channel that the
1084
// entity has been published to.
1085
Info []PublishedInfo
1088
// PublishedInfo holds information on a channel that an entity
1089
// has been published to.
1090
type PublishedInfo struct {
1091
// Channel holds the value of the channel that
1092
// the entity has been published to.
1093
// This will never be "unpublished" as entities
1094
// cannot be published to that channel.
1097
// Current holds whether the entity is the most
1098
// recently published member of the channel.
1103
#### GET *id*/meta/terms
1105
The `meta/terms` path returns a list of terms and conditions (as recorded in
1106
the terms field of the charm metadata) the user must agree to in order to
1107
obtain the archive of the given charm id.
1109
Example: `GET some-charm/meta/terms`
1113
"enterprise-terms/1",
1118
#### GET *id*/meta/archive-size
1120
The `meta/archive-size` path returns the archive size, in bytes, of the archive
1121
of the given charm or bundle id.
1124
type ArchiveSize struct {
1129
Example: `GET wordpress/meta/archive-size`
1137
#### GET *id*/meta/hash
1139
This path returns the SHA384 hash sum of the archive of the given charm or
1143
type HashResponse struct {
1148
Example: `GET wordpress/meta/hash`
1153
"Sum": "0a410321586d244d3981e2b23a27a7e86ebdcab8bd0ca8f818d3f4c34b2ea2791e0dbdc949f70b283a3f5efdf908abf1"
1157
#### GET *id*/meta/hash256
1159
This path returns the SHA256 hash sum of the archive of the given charm or
1163
type HashResponse struct {
1168
Example: `GET wordpress/meta/hash256`
1173
"Sum": "9ab5036cc18ba61a9d25fad389e46b3d407fc02c3eba917fe5f18fdf51ee6924"
1177
#### GET *id*/meta/supported-series
1179
This path returns the set of series supported by the given
1180
charm. This endpoint is appropriate for charms only.
1183
type SupportedSeriesResponse struct {
1184
SupportedSeries []string
1188
Example: `GET precise/wordpress/meta/supported-series`
1193
"SupportedSeries": ["precise"]
1197
#### GET *id*/meta/bundles-containing
1199
The `meta/bundles-containing` path returns information on the last revision of
1200
any bundles that contain the charm with the given id.
1203
GET <i>id</i>/meta/bundles-containing[?include=<i>meta</i>[&include=<i>meta</i>...]]
1206
The Meta field is populated with information on the returned bundles according
1207
to the include flags - see the `meta/any` path for more info on how to use the
1208
`include` flag. The only values that are valid for `any-series`, `any-revision`
1209
or `all-results` flags are 0, 1 and empty. If `all-results` is enabled, all the
1210
bundle revisions are returned, not just the last one. The API should validate
1211
that and return bad request if any other value is provided.
1215
type Bundle struct {
1217
Meta map[string]interface{} `json:",omitempty"`
1221
Example: `GET mysql/meta/bundles-containing?include=featured` might return:
1226
"Id": "bundle/mysql-scalable",
1234
"Id": "bundle/wordpress-simple",
1244
#### GET *id*/meta/extra-info
1246
The meta/extra-info path reports any additional metadata recorded for the
1247
charm. This contains only information stored by clients - the API server itself
1248
does not populate any fields. The resulting object holds an entry for each
1249
piece of metadata recorded with a PUT to `meta/extra-info`.
1252
type ExtraInfo struct {
1253
Values map[string] interface{}
1257
Example: `GET wordpress/meta/extra-info`
1262
"vcs-digest": "4b6b3c7d795eb66ca5f82bc52c01eb57ab595ab2"
1266
#### GET *id*/meta/extra-info/*key*
1268
This path returns the contents of the given `extra-info` key. The result is
1269
exactly the JSON value stored as a result of the PUT request to `extra-info` or
1272
Example: `GET wordpress/meta/extra-info/featured`
1278
#### PUT *id*/meta/extra-info
1280
This request updates the value of any metadata values. Any values that are not
1281
mentioned in the request are left untouched. Any fields with null values are
1284
Example: `PUT precise/wordpress-32/meta/extra-info`
1289
"vcs-digest": "7d6a853c7bb102d90027b6add67b15834d815e08",
1293
#### PUT *id*/meta/extra-info/*key*
1295
This request creates or updates the value for a specific key.
1296
If the value is null, the key is deleted.
1298
Example: `PUT precise/wordpress-32/meta/extra-info/vcs-digest`
1303
"7d6a853c7bb102d90027b6add67b15834d815e08",
1306
The above example is equivalent to the `meta/extra-info` example above.
1308
#### GET *id*/meta/charm-related
1310
The `meta/charm-related` path returns all charms that are related to the given
1311
charm id, which must not refer to a bundle. It is possible to include
1312
additional metadata for charms by using the `include` query:
1315
GET <i>id</i>/meta/charm-related[?include=<i>meta</i>[&include=<i>meta</i>...]]
1319
type Related struct {
1320
// Requires holds an entry for each interface provided by
1321
// the charm, containing all charms that require that interface.
1322
Requires map[string] []Item `json:",omitempty"`
1325
// Provides holds an entry for each interface required by the
1326
// the charm, containing all charms that provide that interface.
1327
Provides map[string] []Item `json:",omitempty"`
1333
Meta map[string] interface{} `json:",omitempty"`
1337
The Meta field is populated according to the include flags - see the `meta`
1338
path for more info on how to use this.
1340
Example: `GET wordpress/meta/charm-related`
1346
{"Id": "precise/memcached-13"}
1349
{"Id": "precise/mysql-46"},
1350
{"Id": "~clint-fewbar/precise/galera-42"}
1355
{"Id": "precise/apache2-24"},
1356
{"Id": "precise/haproxy-31"},
1357
{"Id": "precise/squid-reverseproxy-8"}
1363
Example: `GET trusty/juju-gui-3/meta/charm-related?include=charm-config`
1370
"Id": "precise/apache2-24",
1374
"logrotate_count": {
1376
"Description": "The number of days",
1384
"nrpe-external-master": [
1386
"Id": "precise/nova-compute-31",
1390
"bridge-interface": {
1392
"Description": "Bridge interface",
1397
"Description": "IP to be assigned to bridge",
1398
"Default": "11.0.0.1"
1409
#### GET *id*/meta/archive-upload-time
1411
The `meta/archive-upload-time` path returns the time the archives for the given
1412
*id* was uploaded. The time is formatted according to RFC3339.
1415
type ArchiveUploadTimeResponse struct {
1416
UploadTime time.Time
1420
Example: `GET trusty/wordpress-42/meta/archive-upload-time`
1424
"UploadTime": "2014-07-04T13:53:57.403506102Z"
1428
#### GET *id*/meta/promulgated
1430
The `promulgated` path reports whether the entity with the given ID is promulgated.
1431
Promulgated charms do not require the user portion of the ID to be specified.
1434
type PromulgatedResponse struct {
1439
Example: `GET trusty/wordpress-42/meta/promulgated`
1447
#### GET *id*/meta/can-ingest
1449
The `can-ingest` path reports whether the entity with the given ID is
1450
eligible for ingestion. When an entity is manually uploaded (via the /archive
1451
endpoint with the POST method), it becomes ineligible for ingestion.
1454
type CanIngestResponse struct {
1459
Example: `GET trusty/wordpress-42/meta/can-ingest`
1467
#### GET *id*/meta/stats
1470
GET <i>id</i>/meta/stats?[refresh=0|1]
1473
Many clients will need to use stats to determine the best result. Details for a
1474
charm/bundle might require the stats as important information to users.
1475
Currently we track deployment stats only. We intend to open this up to
1476
additional data. The response includes downloads count for both the specific
1477
requested entity revision and for all the revisions, and it is structured as
1481
// StatsResponse holds the result of an id/meta/stats GET request.
1482
type StatsResponse struct {
1483
// ArchiveDownloadCount is superceded by ArchiveDownload but maintained for
1484
// backward compatibility.
1485
ArchiveDownloadCount int64
1486
// ArchiveDownload holds the downloads count for a specific revision of the
1488
ArchiveDownload StatsCount
1489
// ArchiveDownloadAllRevisions holds the downloads count for all revisions
1491
ArchiveDownloadAllRevisions StatsCount
1494
// StatsCount holds stats counts and is used as part of StatsResponse.
1495
type StatsCount struct {
1496
Total int64 // Total count over all time.
1497
Day int64 // Count over the last day.
1498
Week int64 // Count over the last week.
1499
Month int64 // Count over the last month.
1503
If the refresh boolean parameter is non-zero, the latest stats will be returned without caching.
1505
#### GET *id*/meta/tags
1507
The `tags` path returns any tags that are associated with the entity.
1509
Example: `GET trusty/wordpress-42/meta/tags`
1520
#### GET *id*/meta/revision-info
1522
The `revision-info` path returns information about other available revisions of
1523
the charm id that the charm store knows about. It will include both older and
1524
newer revisions. The fully qualified ids of those charms will be returned in an
1525
ordered list from newest to oldest revision. Note that the current revision
1526
will be included in the list as it is also an available revision.
1529
type RevisionInfoResponse struct {
1530
Revisions []*charm.URL
1534
Example: `GET trusty/wordpress-42/meta/revision-info`
1539
"cs:trusty/wordpress-43",
1540
"cs:trusty/wordpress-42",
1541
"cs:trusty/wordpress-41",
1542
"cs:trusty/wordpress-39"
1547
#### GET *id*/meta/id
1549
The `id` path returns information on the charm or bundle id, split apart into
1550
its various components, including the id itself. The information is exactly
1551
that contained within the entity id.
1554
type IdResponse struct {
1557
Series string `json:",omitempty"`
1563
Example: `GET ~bob/trusty/wordpress/meta/id`
1567
"Id": "~bob/trusty/wordpress-42",
1570
"Name": "wordpress",
1575
Example: `GET precise/wordpress/meta/id`
1579
"Id": "precise/wordpress-42",
1580
"Series": "precise",
1581
"Name": "wordpress",
1586
Example: `GET bundle/openstack/meta/id`
1590
"Id": "bundle/openstack-3",
1592
"Name": "openstack",
1597
#### GET *id*/meta/id-revision
1599
The `revision` path returns information on the revision of the id. The
1600
information is exactly that contained within the id.
1603
type Revision struct {
1608
Example: `GET trusty/wordpress-42/meta/id-revision`
1616
#### GET *id*/meta/id-name
1618
The `name` path returns information on the name of the id. The information is
1619
exactly that contained within the id.
1627
Example: `GET trusty/wordpress-42/meta/id-name`
1635
#### GET *id*/meta/id-user
1637
The `id-user` path returns information on the user name in the id. This
1638
information is exactly that contained within the id.
1646
Example: `GET ~bob/trusty/wordpress-42/meta/id-user`
1654
Example: `GET trusty/wordpress-42/meta/id-user`
1662
#### GET *id*/meta/id-series
1664
The `id-series` path returns information on the series in the id. This
1665
information is exactly that contained within the id. For bundles, this will
1669
type Series struct {
1674
Example: `GET ~bob/trusty/wordpress-42/meta/id-series`
1682
#### GET *id*/meta/owner
1684
The `owner` path returns information on the owner of the charm or bundle.
1685
This is the owner of the charm or bundle referenced by *id* irrespective
1686
of whether a user is included in the id.
1694
Example: `GET ~bob/trusty/wordpress-42/meta/owner`
1702
Example: `GET trusty/wordpress-42/meta/owner`
1710
#### GET *id*/meta/common-info
1712
The meta/common-info path reports any common metadata recorded for the base
1713
entity. This contains only information stored by clients - the API server
1714
itself does not populate any fields. The resulting object holds an entry for
1715
each piece of metadata recorded with a PUT to `meta/common-info`.
1718
type CommonInfo struct {
1719
Values map[string] interface{}
1723
Example: `GET wordpress/meta/common-info`
1724
`GET precise/wordpress-32/meta/common-info`
1728
"homepage": "http://wordpress.org",
1729
"bugs-url": "http://wordpress.org/bugs",
1733
#### GET *id*/meta/common-info/*key*
1735
This path returns the contents of the given `common-info` key. The result is
1736
exactly the JSON value stored as a result of the PUT request to `common-info` or
1739
Example: `GET wordpress/meta/common-info/homepage`
1740
`GET precise/wordpress-32/meta/common-info/homepage`
1743
"http://wordpress.org"
1746
#### PUT *id*/meta/common-info
1748
This request updates the value of any metadata values. Any values that are not
1749
mentioned in the request are left untouched. Any fields with null values are
1752
Example: `PUT precise/wordpress-32/meta/common-info`
1757
"bugs-url": "http://wordpress.org/newbugs",
1761
#### PUT *id*/meta/common-info/*key*
1763
This request creates or updates the value for a specific key.
1764
If the value is null, the key is deleted.
1766
Example: `PUT precise/wordpress-32/meta/common-info/bugs-url`
1771
"http://wordpress.org/newbugs",
1774
The above example is equivalent to the `meta/common-info` example above.
1776
#### GET *id*/meta/resources
1778
The `meta/resources` path returns information on all the resources associated with the given charm *id* as an array of resource objects.
1782
type Resource struct {
1783
// Name identifies the resource.
1786
// Type is the name of the resource type. Currently only
1787
// "file" is supported, which is the default if Type is not specified.
1790
// Path holds where the resource will be stored on units
1791
// deployed with the charm.
1794
// Description contains user-facing info about the resource.
1795
Description string `json:",omitempty"`
1797
// Revision is the revision, if applicable.
1800
// Fingerprint is the SHA-384 checksum for the resource blob.
1803
// Size is the size of the resource, in bytes.
1810
#### GET *id*/meta/resources/*name*[/*revision*]
1812
This endpoint retrieves information on the resource with the given *name*
1813
associated with the charm *id* as a resource object (see above).
1815
If *revision* is omitted, information on the latest revision of the resource is returned.
1819
#### POST *id*/resource/*name*?hash=*sha384*[&filename=*path*]
1822
Posting to the `resource` path uploads a resource (an arbitrary "blob"
1823
of data) associated with the charm with the given *id*, which must not
1824
be a bundle. The *sha384* parameter
1825
must hold the hex-encoded SHA384 hash of the blob.
1827
If provided, the *path* parameter should hold the filename
1828
that the resource has been read from, and its file extension will
1829
be verified against the extension of the filename in the
1830
declared charm metadata resources of the resolved charm.
1832
As a special case, if the filename in the charm metadata has no
1833
extension, any file name will be allowed.
1836
type ResourcesRevision struct {
1841
#### GET *id*/resource/*name*[/*revision*]
1843
Getting from the `/resource` path retrieves a charm resource from the charm
1844
with the given id. If version is not specified, it retrieves the latest published
1845
version of the resource (for the "unpublished" channel, this will be
1846
the most recently uploaded version of the resource).
1848
The SHA-384 checksum of the data is returned
1849
in the Content-Sha384 HTTP response header.
1855
The `search` path searches within the latest version of charms and bundles
1859
GET search[?text=<i>text</i>][&autocomplete=1][&filter=<i>value</i>...][&limit=<i>limit</i>][&skip=<i>skip</i>][&include=<i>meta</i>[&include=<i>meta</i>...]][&sort=<i>field</i>]
1862
`text` specifies any text to search for. If `autocomplete` is specified, the
1863
search will return only charms and bundles with a name that has text as a
1864
prefix. `limit` limits the number of returned items to the specified limit
1865
count. `skip` skips over the first skip items in the result. Any number of
1866
filters may be specified, limiting the search to items with attributes that
1867
match the specified filter value. Items matching any of the selected values for
1868
a filter are selected, so `name=1&name=2` would match items whose name was
1869
either 1 or 2. However, if multiple filters are specified, the charm must match
1870
all of them, so `name=1&series=2` will only match charms whose name is 1 and
1871
whose series is 2. Available filters are:
1873
* tags - the set of tags associated with the charm.
1874
* name - the charm's name.
1875
* owner - the charm's owner (the ~user element of the charm id)
1876
* promulgated - the charm has been promulgated.
1877
* provides - interfaces provided by the charm.
1878
* requires - interfaces required by the charm.
1879
* series - the charm's series.
1880
* summary - the charm's summary text.
1881
* description - the charm's description text.
1882
* type - "charm" or "bundle" to search only one doctype or the other.
1887
1. filtering on a specified, but empty, owner is the same as filtering on promulgated=1.
1888
2. a specified, but empty text field will return all charms and bundles.
1889
3. the promulgated filter is only applied if specified. If the value is "1" then only
1890
promulgated entities are returned if it is any other value only non-promulgated
1891
entities are returned.
1893
The response contains a list of information on the charms or bundles that were
1894
matched by the request. If no parameters are specified, all charms and bundles
1895
will match. By default, only the charm store id is included.
1897
The results are sorted according to the given sort field, which may be one of
1898
`owner`, `name` or `series`, corresponding to the filters of the same names. If
1899
the field is prefixed with a hyphen (-), the sorting order will be reversed. If
1900
the sort field is not specified, the results are returned in
1901
most-relevant-first order if the text filter was specified, or an arbitrary
1902
order otherwise. It is possible to specify more than one sort field to get
1903
multi-level sorting, e.g. sort=name,-series will get charms in order of the
1904
charm name and then in reverse order of series.
1906
The Meta field is populated according to the include flag - see the `meta`
1907
path for more info on how to use this.
1912
type SearchResult struct {
1914
// Meta holds at most one entry for each meta value
1915
// specified in the include flags, holding the
1916
// data that would be returned by reading /meta/meta?id=id.
1917
// Metadata not relevant to a particular result will not
1919
Meta map[string] interface{} `json:",omitempty"`
1923
Example: `GET search?text=word&autocomplete=1&limit=2&include=archive-size`
1928
"Id": "precise/wordpress-1",
1936
"Id": "precise/wordpress-2",
1946
#### GET search/interesting
1948
This returns a list of bundles and charms which are interesting from the Juju
1949
GUI perspective. Those are shown on the left sidebar of the GUI when no other
1950
search requests are performed.
1952
`GET search/interesting[?limit=limit][&include=meta]`
1954
The Meta field is populated according to the include flag - see the `meta`
1955
path for more info on how to use this.
1956
The `limit` flag is the same as for the "search" path.
1962
The `list` path lists charms and bundles within the store.
1965
GET list[?filter=<i>value</i>...][&include=<i>meta</i>[&include=<i>meta</i>...]][&sort=<i>field</i>]
1968
Any number of filters may be specified, limiting the list to items with attributes that
1969
match the specified filter value. Items matching any of the selected values for
1970
a filter are selected, so `name=1&name=2` would match items whose name was
1971
either 1 or 2. However, if multiple filters are specified, the charm must match
1972
all of them, so `name=1&series=2` will only match charms whose name is 1 and
1973
whose series is 2. Available filters are:
1975
* name - the charm's name.
1976
* owner - the charm's owner (the ~user element of the charm id)
1977
* promulgated - the charm has been promulgated.
1978
* series - the charm's series.
1979
* type - "charm" or "bundle" to search only one doctype or the other.
1984
1. the promulgated filter is only applied if specified. If the value is "1" then only
1985
promulgated entities are returned if it is any other value only non-promulgated
1986
entities are returned.
1988
The response contains a list of information on the charms or bundles that were
1989
matched by the request. If no parameters are specified, all charms and bundles
1990
will match. By default, only the charm store id is included.
1992
The results are sorted according to the given sort field, which may be one of
1993
`owner`, `name` or `series`, corresponding to the filters of the same names. If
1994
the field is prefixed with a hyphen (-), the sorting order will be reversed. If
1995
the sort field is not specified the order will be a server side logical order.
1996
It is possible to specify more than one sort field to get
1997
multi-level sorting, e.g. sort=name,-series will get charms in order of the
1998
charm name and then in reverse order of series.
2000
The Meta field is populated according to the include flag - see the `meta`
2001
path for more info on how to use this.
2006
type EntityResult struct {
2008
// Meta holds at most one entry for each meta value
2009
// specified in the include flags, holding the
2010
// data that would be returned by reading /meta/meta?id=id.
2011
// Metadata not relevant to a particular result will not
2013
Meta map[string] interface{} `json:",omitempty"`
2017
Example: `GET list?name=wordpress&include=archive-size`
2022
"Id": "precise/wordpress-1",
2030
"Id": "precise/wordpress-2",
2044
**Not yet implemented**
2046
This returns metadata describing the current version of the software running
2047
the server, and any other information deemed appropriate. The specific form of
2048
the returned data is deliberately left unspecified for now.
2050
#### GET /debug/status
2052
Used as a health check of the service. The API will also be used for nagios
2053
tests. The items that are checked:
2055
* connection to MongoDB
2056
* connection to ElasticSearch (if needed) (based on charm config) (elasticsearch cluster status, all nodes up/etc see charmworld)
2057
* number of charms and bundles in the blobstore
2058
* number of promulgated items
2059
* time and location of service start
2060
* time of last ingestion process
2061
* did ingestion finish
2062
* did ingestion finished without errors (this should not count charm/bundle ingest errors)
2065
type DebugStatuses map[string] struct {
2072
Example: `GET /debug/status`
2076
"mongo_connected" : {
2077
"Name": "MongoDB is connected",
2078
"Value": "Connected",
2081
"mongo_collections" : {
2082
"Name": "MongoDB collections",
2083
"Value": "All required collections exist",
2087
"Name": "ElasticSearch is connected",
2088
"Value": "Connected",
2092
"Name": "Entities in charm store",
2093
"Value": "5701 charms; 2000 bundles; 42 promulgated",
2097
"Name": "Server started",
2098
"Value": "123.45.67.89 2014-09-16 11:12:29Z",
2106
All entities in the charm store have their own access control lists. Read and
2107
write permissions are supported for specific users and groups. By default, all
2108
charms and bundles are readable by everyone, meaning that anonymous users can
2109
retrieve archives and metadata information without restrictions. The permission
2110
endpoints can be used to retrieve or change entities' permissions.
2112
#### GET *id*/meta/perm
2114
This path reports the read and write ACLs for the charm or bundle.
2117
type PermResponse struct {
2123
If the `Read` ACL is empty, the entity and its metadata cannot be retrieved by
2125
If the `Write` ACL is empty, the entity cannot be modified by anyone.
2126
The special user `everyone` indicates that the corresponding operation
2127
(read or write) can be performed by everyone, including anonymous users.
2129
Example: `GET ~joe/wordpress/meta/perm`
2133
"Read": ["everyone"],
2138
#### PUT *id*/meta/perm
2140
This request updates the permissions associated with the charm or bundle.
2143
type PermResponse struct {
2149
If the Read or Write ACL is empty or missing from the request body, that
2150
field will be overwritten as empty. See the *id*/meta/perm/*key* request
2151
to PUT only Read or Write.
2153
Example: `PUT precise/wordpress-32/meta/perm`
2158
"Read": ["everyone"],
2163
#### GET *id*/meta/perm/*key*
2165
This path returns the contents of the given permission *key* (that can be
2166
`read` or `write`). The result is exactly the JSON value stored as a result of
2167
the PUT request to `meta/perm/key`.
2169
Example: `GET wordpress/meta/perm/read`
2175
#### PUT *id*/meta/perm/*key*
2177
This request updates the *key* permission associated with the charm or bundle,
2178
where *key* can be `read` or `write`.
2180
Example: `PUT precise/wordpress-32/meta/perm/read`
2192
This endpoint returns a macaroon in JSON format that, when its third party
2193
caveats are discharged, will allow access to the charm store. No prior
2194
authorization is required.
2196
#### GET /delegatable-macaroon
2198
This endpoint returns a macaroon in JSON format that can be passed to
2199
third parties to allow them to access the charm store on the user's
2200
behalf. If the "id" parameter is specified (url encoded), the returned
2201
macaroon will be restricted for use only with the entity with the
2204
A delegatable macaroon will only be returned to an authorized user (not
2205
including admin). It will carry the same privileges as the macaroon used
2206
to authorize the request, but is suitable for use by third parties.
2210
This endpoint returns the user name of the client and the list of groups the
2211
user is a member of. This endpoint requires authorization.
2213
Example: `GET whoami`
2218
"Groups": ["charmers", "admin", "team-awesome"]
2222
The response is defined as:
2224
type WhoAmIResponse struct {
2234
This endpoint returns the log messages stored on the charm store. It is
2235
possible to save them by sending POST requests to the same endpoint (see
2236
below). For instance, the ingestion of charms/bundles produces logs that are
2237
collected and send to the charm store by the ingestion client.
2239
`GET /log[?limit=count][&skip=count][&id=entity-id][&level=log-level][&type=log-type]`
2242
Each log message is defined as:
2245
type LogResponse struct {
2246
// Data holds the log message as a JSON-encoded value.
2247
Data json.RawMessage
2249
// Level holds the log level as a string.
2252
// Type holds the log type as a string.
2255
// URLs holds a slice of entity URLs associated with the log message.
2256
URLs []`*`charm.URL `json:",omitempty"`
2258
// Time holds the time of the log.
2263
The log entries are ordered by last inserted (most recent logs first), and by
2264
default the last 1000 logs are returned. Use the `limit` and skip `query`
2265
parameters to change the default behavior. Logs can further be filtered by log
2266
level (“info”, “warning” or “error”) and by related entity id. The type query
2267
parameter groups entries by type. For instance, to request all the ingestion
2268
errors related to the *utopic/django* charm, use the following URL:
2270
`/log?type=ingestion&level=error&id=utopic/django`
2274
This endpoint uploads logs to the charm store. The request content type must be
2275
`application/json`. The body must contain the JSON representation of a list of
2276
logs, each one being in this format:
2280
// Data holds the log message as a JSON-encoded value.
2281
Data *json.RawMessage
2283
// Level holds the log level as a string.
2286
// Type holds the log type as a string.
2289
// URLs holds a slice of entity URLs associated with the log message.
2290
URLs []*charm.URL `json:",omitempty"`
2294
Nothing is returned if the request succeeds. Otherwise, an error is returned.
2298
Each charm store has a global feed for all new published charms and bundles.
2300
#### GET changes/published
2302
This endpoint returns the ids of published charms or bundles published, most
2303
recently published first.
2305
`GET changes/published[?limit=count][&start=fromdate][&stop=todate]`
2307
The `fromdate` and `todate` values constrain the range of publish dates, in
2308
"yyyy-mm-dd" format. If `fromdate` is specified only charms published on or
2309
after that date are returned; if `todate` is specified, only charms published
2310
on or before that date are returned. If the `limit` count is specified, it must
2311
be positive, and only the first count results are returned. The published time
2312
is in RFC3339 format.
2316
type Published struct {
2318
PublishTime time.Time
2322
Example: `GET changes/published`
2327
"Id": "cs:trusty/wordpress-42",
2328
"PublishTime": "2014-07-31T15:04:05Z"
2331
"Id": "cs:trusty/mysql-11",
2332
"PublishTime": "2014-07-30T14:20:00Z"
2335
"Id": "cs:bundle/mediawiki",
2336
"PublishTime": "2014-07-29T13:45:10Z"
2341
Example: `GET changes/published?limit=10&start=31-07-2014`
2346
"Id": "cs:trusty/wordpress-42",
2347
"PublishTime": "2014-07-31T15:04:05Z"