Publish your charm on Charmhub

From Zero to Hero: Write your first Kubernetes charm > Pushing your charm to charmhub

See previous: Open a Kubernetes port in your charm

This document is part of a series, and we recommend you follow it in sequence. However, you can also jump straight in by checking out the code from the previous branches:

git clone https://github.com/canonical/juju-sdk-tutorial-k8s.git
cd juju-sdk-tutorial-k8s
git checkout 11_open_port_k8s_service

In this tutorial you’ve done a lot of work, and the result is an increasingly functional charm.

You can enjoy this charm on your own, or pass it around to friends, but why not share it with the whole world?

The Canonical way to share a charm publicly is to publish it on Charmhub. Aside from making your charm more visible, this also means you can deploy it more easily, as Charmhub is the default source for juju deploy. Besides, Charmcraft is there to support you every step of the way.

In this chapter of the tutorial you will use Charmcraft to release your charm on Charmhub.

Contents:

  1. Log in to Charmhub
  2. Register your charm’s name
  3. Upload the charm and its resources
  4. Release the charm

Log in to Charmhub

You will need an Ubuntu SSO account.
If you don’t have one yet, sign up on Cookies required

Logging into Charmhub is typically a simple matter of running charmcraft login . However, here we are within a Multipass VM, so we have to take some extra steps.

On your Multipass VM, run the code below:

ubuntu@charm-dev:~/fastapi-demo$ charmcraft login --export ~/secrets.auth

Once you’ve put in your login information, you should see something similar to the output below:

Opening an authorization web page in your browser.
If it does not open, please open this URL:
 https://api.jujucharms.com/identity/login?did=48d45d919ca2b897a81470dc5e98b1a3e1e0b521b2fbcd2e8dfd414fd0e3fa96

Copy-paste the provided web link into your web browser. Use your Ubuntu SSO to log in.

When you’re done, you should see in your terminal the following:

Login successful. Credentials exported to '~/secrets.auth'.

Now set an environment variable with the new token:

export CHARMCRAFT_AUTH=$(cat ~/secrets.auth)

Well done, you’re now logged in to Charmhub!

Register your charm’s name

On your Multipass VM, generate a random 8-digit hexadecimal hash, then view it in the shell:

random_hash=$(cat /dev/urandom | tr -dc 'a-f0-9' | head -c 8)
echo "Random 8-digit hash: $random_hash"

Naming your charm is usually less random than that; see Charm naming guidelines. However, here we are in a tutorial setting, so you just need to make sure to pick a unique name, any name.

Navigate to the charmcraft.yaml file of your charm and update the name field with the randomly generated name.

Once done, prepare the charm for upload by executing charmcraft pack . This command will create a compressed file with the updated name prefix, as discussed earlier.

Now pass this hash as the name to register for your charm on Charmhub:

$ charmcraft register <your random hash name>
Congrats! You are now the publisher of '<your random hash name>'

You’re all set!

Upload the charm and its resources

On your Multipass VM, run the code below. (The argument to charmcraft upload is the filepath to the .charm file.)

charmcraft upload <your random hash name>_ubuntu-22.04-amd64.charm
Revision 1 of <your random hash name> created

Every time a new binary is uploaded for a charm, a new revision is created on Charmhub. We can verify its current status easily by running charmcraft revisions <charm-name>.

Now upload the charm’s resource – in your case, the demo-server-image OCI image specified in your charm’s charmcraft.yaml as follows:

First, pull it locally:

docker pull ghcr.io/canonical/api_demo_server:1.0.1

Then, take note of the image ID:

docker images ghcr.io/canonical/api_demo_server

This should output something similar to the output below:

REPOSITORY                          TAG       IMAGE ID       CREATED        SIZE
ghcr.io/canonical/api_demo_server   1.0.1     <image-id>   6 months ago   532MB 

Finally, upload the image as below, specifying first the charm name, then the image name, then a flag with the image digest:

charmcraft upload-resource <your random hash name> demo-server-image --image=<image-id>

Sample output:

Revision 1 created of resource 'demo-server-image' for charm '<your random hash name>'.

All set!

Release the charm

Release your charm as below.

Do not worry:
While releasing a charm to Charmhub gives it a public URL, the charm will not appear in the Charmhub search results until it has passed formal review – see Requirements for public listing.

$ charmcraft release <your random hash name> --revision=1 --channel=beta --resource=demo-server-image:1
Revision 1 of charm '<your random hash name>` released to beta

This releases it into a channel so it can become available for downloading.

Just in case, also check your charm’s status:

$ charmcraft status <your random hash name>
Track    Base                  Channel    Version    Revision    Resources                                                                                                                    
latest   ubuntu 22.04 (amd64)  stable     -          -           -                                                                                                                            
                               candidate  -          -           -                                                                                                                            
                               beta       1          1           demo-server-image (r1)                                                                                                       
                               edge       ↑          ↑           ↑

Congratulations, your charm has now been published to charmhub.io!

You can view it at any time at charmhub.io/<your random hash name>.

Contributors: @abatisse, @ibraaoad, @mvlassis, @mylesjp, @tmihoc, @pik4ez

2 Likes

@tmihoc please assist with the login section with the way that was proposed in the past

is there a way to push an image straight from the upstream without downloading it ?

Not according to Charmcraft source code, when image isn’t within the canonical registry it always tries to get from user’s local registry

As of Charmcraft 2.5 the charm information is in charmcraft.yaml rather than metadata.yaml so the following references should be updated:

Navigate to the metadata.yaml file of your charm and update the name field with the randomly generated name.

Now upload the charm’s resource – in your case, the demo-server-image OCI image specified in your charm’s metadata.yaml as follows:

1 Like

Hi @ibraaoad

If I check the upload-resource sub-command help I can see:

$ charmcraft help upload-resource

....

Options:
          --image:  The digest (remote or local) or id (local, exclude
                    "sha256:") of the OCI image

So if I remove sha256 and try to upload the resource I get:

$ charmcraft upload-resource loki-worker-k8s loki-image --image=583ddc10f52bb4fe4806baa05ecbaa2a3246238f1423bd2a6c35b02fd87b446c
Unknown OCI image reference.                                                                                                                 
Recommended resolution: Pass a valid container transport string.                                                                             
Full execution log: '/home/jose/.local/state/charmcraft/log/charmcraft-20240801-171033.641131.log' 

The same happens if I do not remove sha256:

$ charmcraft upload-resource loki-worker-k8s loki-image --image=sha256:583ddc10f52bb4fe4806baa05ecbaa2a3246238f1423bd2a6c35b02fd87b446c
Unknown OCI image reference.                                                                                                                 
Recommended resolution: Pass a valid container transport string.                                                                             
Full execution log: '/home/jose/.local/state/charmcraft/log/charmcraft-20240801-171905.784405.log' 

I’ve found an old Facundo’s reply mentioning IMAGE ID, so:

$ docker images ubuntu/loki --digests
REPOSITORY    TAG         DIGEST                                                                    IMAGE ID       CREATED       SIZE
ubuntu/loki   3.0-22.04   sha256:583ddc10f52bb4fe4806baa05ecbaa2a3246238f1423bd2a6c35b02fd87b446c   8dad11c50d75   5 weeks ago   351MB

And now using the IMAGE ID the image is uploaded:

$ charmcraft upload-resource loki-worker-k8s loki-image --image=8dad11c50d75
Revision 1 created of resource 'loki-image' for charm 'loki-worker-k8s'. 
$ charmcraft resources loki-worker-k8s
Charm Rev    Resource    Type       Optional                                                                                                 
1            loki-image  oci-image  True  

I’m using charmcraft 3.1.1

@sergiusens Do you know if this is just a documentation issue for the sub-command upload-resource or is an issue of the sub-command itself??

Hi @jose ! Yeah, this is an issue related to a behaviour change in Charmcraft 3. I’ve created a bug report for it.

The short version is that when we changed from home-grown implementations to using docker-py and skopeo, we forgot to reimplement the piece that checks for a digest, so it only works with the image ID right now.

Separately I’ve added another issue to document the new functionality this gives us.

1 Like