How to work with Resources in Charmcraft

Introduction

Duration: 1:00

A Juju Charm Resource is additional content/files that a charm can make use of or may require in order to run.

There are two types of resources (specified in the type key for each resource in the charm’s metadata.yaml file): file and oci-image. Support for resources type file is available since charmcraft 0.8.1+50, support for resources type oci-images is expected in the following weeks.

To learn more about resources check these docs.

As resoures are declared in the charm’s metadata.yaml file, they are intrinsically associated with the charm, and there’s no need to register them in Charmhub as a separate step (as long as a revision of the charm with a resource was uploaded to Charmhub, we’re ready to upload and do more work on that resource). Note that other charms may have resources using the same name, but this is not a problem, as collision will not happen because to reference a resource we always use both the charm and resource names.

So, for a charm to use a resource, we just need to upload it, and attach it when releasing the charm. Let’s see all the process in detail.

Verify the resource is associated to the charm

Duration: 2:00

First we need to check that the resource we want to manage is already associated to our charm:

jdoe@machine:~/blogsystem$ charmcraft resources my-super-charm
No resources associated to my-super-charm.

As the message states, Charmhub doesn’t have the relation yet.

For that to happen, let’s modify the charm’s metadata.yaml file to indicate it owns the resource:

jdoe@machine:~/blogsystem$ cat metadata.yaml 
name: my-super-charm
summary: My super charm.
description: My super duper charm, used for testing.
series:
    - bionic
resources:
    someresource:
        type: file
        filename: superdb.bin
        description: the DB with needed info

In this case only one resource is included, but of course we could include as many as we want.

Now it’s time to build and upload the charm with this new metadata:

jdoe@machine:~/blogsystem$ charmcraft build
Created 'my-super-charm.charm'.
jdoe@machine:~/blogsystem$ charmcraft upload my-super-charm.charm
Revision 13 of 'my-super-charm' created

Let’s ask again for the resources of the charm:

jdoe@machine:~/blogsystem$ charmcraft resources my-super-charm
Name          Type    Revision    Optional
someresource  file    13          True

Note that the resource is associated to the revision 13 of charm. This is important when releasing later the charm, as resources can be attached only to the charm revisions which included them in the metadata.

Upload a resource

Duration: 1:00

Once the resource name is associated to the charm, it’s time to upload the resource content.

jdoe@machine:~/blogsystem$ charmcraft upload-resource my-super-charm someresource --filepath=/tmp/superdb.bin
Revision 1 created of resource 'someresource' for charm 'my-super-charm'

If we need to change our resource in any way, we would need to upload the new version of the file to Charmhub. It’s exactly the same procedure we just saw:

jdoe@machine:~/blogsystem$ charmcraft upload-resource my-super-charm someresource --filepath=/tmp/superdb.bin
Revision 2 created of resource 'someresource' for charm 'my-super-charm'

We can verify all the revisions we uploaded for a specific resource:

jdoe@machine:~/blogsystem$ charmcraft resource-revisions my-super-charm someresource 
Revision    Created at    Size
2           2021-03-05  192.3K
1           2021-03-05  204.9K

Attach a resource to a charm at release time

Duration: 2:30

Any of the uploaded versions of the resource can be attached to the charm at release time. This way we can decide which version of our charm will work with which version of our resource, allowing a controlled evolution of the code and the data it uses.

jdoe@machine:~/blogsystem$ charmcraft release my-super-charm --revision=13 --channel=stable --resource=someresource:2
Revision 13 of charm 'my-super-charm' released to stable (attaching resources: 'someresource' r2)

As an example, let’s say that for a feature we want to implement, we need to modify the charm’s code to adapt it to a new version of the resource it uses.

After doing all the necessary changes, we would need to build and upload the new version of the charm…

jdoe@machine:~/blogsystem$ charmcraft build
Created 'my-super-charm.charm'.
jdoe@machine:~/blogsystem$ charmcraft upload my-super-charm.charm
Revision 14 of 'my-super-charm' created

…, also upload the new content of the resource…

jdoe@machine:~/blogsystem$ charmcraft upload-resource my-super-charm someresource --filepath=/tmp/superdb.bin
Revision 3 created of resource 'someresource' for charm 'my-super-charm'

…and finally we’ll be able to release the new charm version indicating to use this resource content (to edge, as it’s a quite risky change, for example):

jdoe@machine:~/blogsystem$ charmcraft release my-super-charm --revision=14 --channel=edge --resource=someresource:3
Revision 14 of charm 'my-super-charm' released to edge (attaching resources: 'someresource' r3)

We can inspect which resources are attached to which charm releases just by asking for the charm status:

jdoe@machine:~/blogsystem$ charmcraft status my-super-charm
Track       Channel    Version    Revision    Resources
latest      stable     7.4a       13          someresource (r1)
            candidate  ↑          ↑           ↑
            beta       7.4a       10
            edge       7.4a       14          someresource (r3)

This resulting table shows how the different versions of the resources are attached to different charm revisions released in different channels (and it even shows how the revision 10 of the charm doesn’t have a resource attached to it).