How to change step behavior when creating a charm

See also:

Charmcraft supports the definition of a parts section in charmcraft.yaml, and that allows the charm developer to specify payloads in a very flexible way. Developers can also change the way each part step is executed by writing a scriptlet that replaces the built-in handling for that step by using override-<step> entries:

parts:
  charm:
    override-build: |
      echo "Running the build step"

This however completely replaces the original build step: in this example, the charm source will not be built. To fix that, executing the original step handler is also necessary.

To run the default processing for a step even if it’s overriden, create a new charm project with charmcraft init:

$ mkdir mycharm
$ charmcraft init
Charm operator package file and directory tree initialized.
...

Replace the contents of the new charm project’s charmcraft.yaml file with the following :

type: "charm"
bases:
  - build-on:
    - name: "ubuntu"
      channel: "20.04"
    run-on:
    - name: "ubuntu"
      channel: "20.04"

parts:
  charm:
    override-build: |
       echo "Running the build step"
       craftctl default

Run charmcraft pack to execute the parts lifecycle and package the charm. Charmcraft will run commands from the override-build scriptlet and call the default build handler for the charm plugin to create the final charm payload.

2 Likes

Nice feature. Thanks for sharing @cmatsuoka! Do we have some documentation about what happen in each step that can be overwritten?

The parts lifecycle is similar to the one currently used in Snapcraft. Proper documentation for the common parts processing for all craft tools should be available soon, but for now the Snapcraft guide should help you. Note that the SNAPCRAFT_* variables mentioned in the linked page must be changed to CRAFT_* (so use CRAFT_PART_SRC instead of SNAPCRAFT_PART_SRC).

1 Like

Great! Thanks Claudio! Your explanation and the link clarify a lot about it.

1 Like

Would it be possible to use this somehow to add a pre-pack hook independent of all other pack dependencies? Explanation: I have a script that dynamically generates the metadata.yaml file, and I need to execute it on charmcraft pack and delete it afterwards.

So I was trying to pack with:

parts:
  charm:
    override-build: |
       echo "unpacking"
       unpack  # will create metadata.yaml
       craftctl default
       echo "cleaning up yaml..."
       cleanup # will delete metadata.yaml
       echo "all done."

but charmcraft complains that there is no ‘metadata.yaml’ file…

If your example doesn’t work it seems that Charmcraft is checking for files too early in the process. @facundo, WDYT? Can we address this problem with a solution similar to the default entry point verification?

There are some file projects that can be constructed/built/unpacked during the build step, but not all of them.

The metadata.yaml file falls into the category of files that we need before the build process (particularly, we need the name of the charm from that file to build some structures even before the lifecycle process starts).

so bottom line is: for my use case, I’d need to alias charmcraft or create a custom command to do what I need. Thanks for looking into it!