Charm Compat Api

Available at: https://api.charmhub.io/charms/v5/

This API exists to mimic a subset of the original charmstore API (documented here), sufficient to support old versions of juju deploying charms. (Newer versions of Juju use the new Charm API instead.)

Instead of being driven by charmstore data, the compatibility API is driven by data from charmhub, which is populated by daily migrations of charm data from the charmstore, combined with new charm data published using charmhub tools.

The subset that the compatibility API supports is as follows:

1. Only provide a subset of the endpoints

Namely those listed below.

2. Only support the single-charm form of each endpoint.

Compatibility API does support endpoints in the form:

.../CHARMID/ENDPOINTNAME

Where:

  • CHARMID might be eg "~owner/name", but can have many forms, see the charmstore API docs.
  • ENDPOINTNAME might be eg "meta/any"

There is an alternate supported form for the /meta/any endpoint:

.../meta/any?id=CHARMID

However, in general this 2nd form is not supported for endpoints other than /meta/any, and (unlike the charmstore API) it does not accept multiple ID parameters.

3. Don't support addressing a revision using its supportedseries.

Each revision is published to charmstore identified by the pair (series, revision-number), where 'series' is one of the ubuntu series, eg "focal", "bionic", etc. and 'revision-number' is a 0-indexed integer.

In both charmstore and the compatibility API, a particular revision can be retrieved using a charmid constructed using this series:

~owner/series/name-revno

Many modern charms no longer populate the series field, in which case the canonical revision ID is simply:

~owner/name-revno

Instead of the single value 'series' field, modern charms populate the 'supportedseries' field, which may contain several values.

In charmstore, a revision can be retrieved using ANY of these supported series. e.g if a single revision populates revno=123, and supportedseries={focal,bionic,xenial}, then it can be retrieved using any of:

~owner/focal/name-123
~owner/bionic/name-123
~owner/xenial/name-123

However, in the compatibility API, we don't support this addressing by supportedseries. If the above revision had series=focal, then it could only be retrieved from the compatibility API using:

~owner/focal/name-123

or, if this revision's series is null, only:

~owner/name-123

4. Errors are similar but not identical.

The compatibility API's errors generally return the same HTTP status codes as charmstore API. The returned error payload is similar, but not identical:

{
   "Code": str,
   "Message": str,
   "Info": dict,
}

The 'Info' key is omitted by charmstore if empty, and is never present in the compatibility API. The values of Code are intended to match those used by the compatibility API, but this hasn't been rigorously tested. The human-readable Message field differs substantially.

5. No data in the compatibility API requires authorization.

And hence also, the param 'ignore-auth=1' is never used.

6. Data is up to 24 hours out of date.

Updates to charmstore data, such as publishers publishing new revisions, are periodically migrated over to charmhub, where they become available to the compatibility API. These migrations currently happen daily.

Conversely, charm data updated by publishers using the new charmhub tools will be written straight to charmhub, and hence available immediately in compatibility API. These changes will not be migrated back to charmstore, so will never be available in the charmstore API.

To prevent conflicts, once a particular charm begins sending updates using the new charmhub tools, we will stop migrating that charm's data from the charmstore.

7. Each endpoint lists its own additional restrictions below.

charms_v5_meta_any

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/meta/any

Return the charm's requested metadata information

Implements the original charmstore API endpoint.

Not supported:

  • Only supports GET, not PUT.
  • The 'include' GET params may only request optional response fields 'id', 'id-revision', 'published', and 'supported-series'.

Response JSON Schema

{
    "additionalProperties": false,
    "properties": {
        "Id": {
            "type": "string"
        },
        "Meta": {
            "type": "object"
        }
    },
    "required": [
        "Id"
    ],
    "type": "object"
}

charms_v5_meta_any_alt

Introduced in version 48

Summary: GET /charms/v5/meta/any

Return the charm's requested metadata information

Implements the original charmstore's bulk request variant of the /meta/any endpoint.

ie. allows requests of the form:

/meta/any?id=cs:X

which return the same as:

/X/meta/any

except that, for charmstore compatibility, the response object is embedded in an array, which will only ever contain one item.

Original charmstore features that are not supported:

  • We only implement this alternate form for /meta/any, not any other endpoints.
  • Only supports GET, not PUT.
  • The 'include' GET params may only request optional response fields 'id', 'id-revision', 'published', and 'supported-series'.
  • We only accept one 'id' parameter.
  • Original charmstore required the 'id' parameter to be prefixed with 'cs:', we also accept values without this prefix.
  • Original charmstore would respond to errors like missing charms with a 200 array which omits the missing charms, and hence might be empty. Instead, for ease of implementation, we simply let a 404 error propagate out.

Response JSON Schema

{
    "maxProperties": 1,
    "minProperties": 1,
    "patternProperties": {
        "": {
            "additionalProperties": false,
            "properties": {
                "Id": {
                    "type": "string"
                },
                "Meta": {
                    "type": "object"
                }
            },
            "required": [
                "Id"
            ],
            "type": "object"
        }
    },
    "type": "object"
}

charms_v5_meta_id

Introduced in version 46

Summary: GET /charms/v5/<path:charm_id>/meta/id

Quick and dirty implementation to support requests from mojo

Given a charm_id, eg. "GET ~bob/trusty/wordpress/meta/id" Return the structured ID components, eg:

Response JSON Schema

{
    "additionalProperties": false,
    "properties": {
        "Id": {
            "type": "string"
        },
        "Name": {
            "type": "string"
        },
        "Revision": {
            "type": "integer"
        },
        "Series": {
            "type": "string"
        },
        "User": {
            "type": "string"
        }
    },
    "required": [
        "Id",
        "Name",
        "Revision"
    ],
    "type": "object"
}

charms_v5_meta_resources

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/meta/resources

Return the charm's resources list with metadata.

Implements the original charmstore API endpoint.

Response JSON Schema

{
    "items": {
        "additionalProperties": false,
        "properties": {
            "Description": {
                "type": "string"
            },
            "Fingerprint": {
                "type": [
                    "string",
                    "null"
                ]
            },
            "Name": {
                "type": "string"
            },
            "Path": {
                "type": "string"
            },
            "Revision": {
                "type": "integer"
            },
            "Size": {
                "type": "integer"
            },
            "Type": {
                "type": "string"
            }
        },
        "required": [
            "Name",
            "Type",
            "Path",
            "Revision",
            "Fingerprint",
            "Size"
        ],
        "type": "object"
    },
    "type": "array"
}

charms_v5_meta_resources_by_name

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/meta/resources/<name>

Return the requested charm's resource with metadata.

Implements the original charmstore API endpoint.

Response JSON Schema

{
    "additionalProperties": false,
    "properties": {
        "Description": {
            "type": "string"
        },
        "Fingerprint": {
            "type": [
                "string",
                "null"
            ]
        },
        "Name": {
            "type": "string"
        },
        "Path": {
            "type": "string"
        },
        "Revision": {
            "type": "integer"
        },
        "Size": {
            "type": "integer"
        },
        "Type": {
            "type": "string"
        }
    },
    "required": [
        "Name",
        "Type",
        "Path",
        "Revision",
        "Fingerprint",
        "Size"
    ],
    "type": "object"
}

charms_v5_meta_resources_by_name_revision

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/meta/resources/<name>/<int:revision>

Return the requested charm's resource with metadata.

Implements the original charmstore API endpoint.

Response JSON Schema

{
    "additionalProperties": false,
    "properties": {
        "Description": {
            "type": "string"
        },
        "Fingerprint": {
            "type": [
                "string",
                "null"
            ]
        },
        "Name": {
            "type": "string"
        },
        "Path": {
            "type": "string"
        },
        "Revision": {
            "type": "integer"
        },
        "Size": {
            "type": "integer"
        },
        "Type": {
            "type": "string"
        }
    },
    "required": [
        "Name",
        "Type",
        "Path",
        "Revision",
        "Fingerprint",
        "Size"
    ],
    "type": "object"
}

charms_v5_archive

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/archive

Redirect to the charm binary URL.

Implements the original charmstore API endpoint.

Not supported:

  • Only supports GET, not POST, DELETE.
  • Does not support ID/archive/PATH requests to select files within the archive.

charms_v5_resource_by_name

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/resource/<name>

Redirect to the resource binary URL.

Implements the original charmstore API endpoint.

Not supported:

  • Only supports GET, not POST.

charms_v5_resource_by_name_revision

Introduced in version 1

Summary: GET /charms/v5/<path:charm_id>/resource/<name>/<int:revision>

Redirect to the resource binary URL.

Implements the original charmstore API endpoint.

Not supported:

  • Only supports GET, not POST.

© 2019 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.