Charm developers rejoice: today we are announcing the availability of track creation for charms via a public API.
Until now, track creation for charms needed to be requested in the forum and handled manually by Charmhub admins. To speed up this process, we created an API and clear track creation guidelines.
Now with the API, you tell us what kind of track you need to create (denoted as a regular expression). We validate that the general pattern is reasonable and fits within the use cases for tracks. We then do a one-time administrative setup on our side, and you will be able to create tracks as needed, as long as they conform to the agreed-upon pattern. For this, charm publishers can use Charmcraft and jq to generate the authentication token, and then curl (or any other HTTP client) to perform the operations via the Charmhub API.
Client support for Charmcraft and Charmhub is coming, but we felt the self-service track creation feature was useful enough in its current form to release to charm authors.
Process overview
A publisher must first request (from the Snap Store admins) the creation of new “guardrails" that will govern future track creation. Once the guardrails are set, the publishers can use the new APIs for self-service track creation. The following guide will take you through these steps in detail.
1. Requesting new guardrails from the Snap Store
The first step of the process involves creating the associated guardrails for the charm. Track guardrails are simple regexes that the track name(s) must match to be allowed.
As such, when publishers want to create new tracks for a charm, they must first contact the store admins in the forum to agree on the creation patterns that will be granted to the charm. Having track names that comply with specific patterns ensures that reasonable names will be used, thus avoiding the creation of tracks that don’t make sense or are semantically obscure.
In addition, working closely with the Snap Store admins in this first step provides a good opportunity for established publishers to ask for clarifications on tracks and their optimal usage. It also allows new publishers to learn more about the process and the purpose of tracks. This will avoid anti-patterns in usage and naming of tracks.
As an example, a publisher wants to create tracks for major releases of their project which use semantic versioning. A creation pattern of ‘\d+’ is agreed upon, which allows track names consisting of only digits, to cover only major releases. The publisher can then self-serve and create tracks named ‘1’, ‘2’ and so on.
If at some point the convention to only create tracks for major releases is “forgotten” and someone tries to create a ‘1.1’ track, this will be disallowed by the pattern. This is as agreed/discussed because the semantics of a minor version track like 1.1 may be different and confusing to end users.
2. Using curl + charmcraft for authentication
For access to the Charmhub API, we suggest using Charmcraft, which understands the authentication mechanism used by Charmhub. Charmcraft can generate a suitable authentication token (macaroon) and use curl directly to interact with the API. This technique has the advantage that it can be adapted to use any HTTP client or library as long as it can pass custom headers.
In order to do this, Charmcraft, curl and jq must be installed.
First, log in with Charmcraft and export the credentials/token to a file:
charmcraft login --export charmhub-creds.dat
Next, decode and extract the macaroon from the .dat file and place it in a header in an environment variable for easy access in subsequent commands using curl:
export CHARMHUB_MACAROON_HEADER="Authorization: Macaroon $(cat charmhub-creds.dat | base64 -d | jq -r .v)"
Subsequent curl commands can use the variable and, importantly, must also specify the correct Content-Type
.
3. Creating new tracks
With the guardrails in place, a publisher can create new tracks by issuing an HTTP POST
request to:
/v1/<namespace>/<name>/tracks
As described in its API documentation. name
and namespace
refer to the name and type of the package respectively. For example, given a charm named hello-world-charm
, one can use curl
to create 2 tracks v.1
and v.2
as follows:
curl https://api.charmhub.io/v1/charm/hello-world-charm/tracks -X POST -H'Content-type: application/json' -H "$CHARMHUB_MACAROON_HEADER" -d '[{"name": "v.1"}, {"name": "v.2"}]'
To view the guardrails and tracks associated with a specific charm an HTTP GET
request should be issued to:
/v1/<namespace>/<name>
, as described in its API documentation. The guardrails and tracks of the package will be under the track-guardrails
and tracks
keys of metadata
. With curl
this translates to:
curl https://api.charmhub.io/v1/charm/hello-world-charm -H'Content-type: application/json' -H "$CHARMHUB_MACAROON_HEADER"
Finally, to view the guardrails and tracks for all published charms an HTTP GET
request should be issued to:
/v1/<namespace>
, as described in its API documentation. With curl
:
curl https://api.charmhub.io/v1/charm -H'Content-type: application/json' -H "$CHARMHUB_MACAROON_HEADER"
4. What next?
Please let us know here if you have any questions, problems using this feature, or any ideas or requests to enhance it.
Keep in mind that client support via Charmcraft and Charmhub is coming, so there’s no need to explicitly request those as features.
Happy tracking!
- The Charmhub / Snap Store team