Handling Hooks¶
In Juju, a hook is a notification to the charm that the internal representation of Juju has changed in a way that requires a reaction from the charm so that the unit’s state and the controller’s state can be reconciled. You can find the list of available hooks and more hook-related information in the Juju documentation.
Hook execution¶
This notification is sent in the form of Juju executing the charm binary with a specific set of environment variables. The charm binary is expected to handle the hook by comparing its existing state with the intended state and performing the necessary actions to reconcile them.
Juju expects the charm binary to be named dispatch
and to be located in the charm root directory. This is why we inform charmcraft to rename the binary to dispatch
in the charmcraft.yaml
file.
parts:
charm:
source: .
plugin: go
build-snaps:
- go
organize:
bin/example: dispatch
Handling hooks with goops
¶
During the hook execution goops
provides access to the following:
- Hook Commands:
goops
exposes every Juju hook commands, as a Go function. - Environment Variables:
goops
provides access to every Juju-defined environment variables. - Charm metadata:
goops
provides access to the charm metadata as defined incharmcraft.yaml
. - Pebble:
goops
provides access to the Pebble API, allowing you to manage services and containers for Kubernetes charms.
Independent hook handling¶
The hook name is made available by Juju through an environment variable. In your charm, you can access it using the ReadEnv()
function and handle it accordingly.
package main
import (
"os"
"github.com/gruyaume/goops"
"github.com/gruyaume/goops/internal/charm"
)
func main() {
env := goops.ReadEnv()
switch env.HookName {
case "install":
err := charm.Install()
if err != nil {
goops.LogErrorf("Error handling install hook: %s", err.Error())
os.Exit(1)
}
case "remove":
err := charm.Remove()
if err != nil {
goops.LogErrorf("Error handling remove hook: %s", err.Error())
os.Exit(1)
}
case "":
goops.LogInfof("No hook name provided, running default configuration.")
default:
err := charm.Configure()
if err != nil {
goops.LogErrorf("Error handling default hook: %s", err.Error())
os.Exit(1)
}
}
}