Runtime hooks

A hook is a bash script that an SDK ships under its hooks/ directory. Workshop runs the script at a specific point in the workshop lifecycle to give the SDK a chance to set up its environment, report its health, or persist data across a refresh. Without hooks, an SDK is a passive bundle of files; hooks are how it participates in the running workshop.

SDKcraft enumerates an SDK’s hooks automatically when packing it, so they do not need to be listed in the SDK definition.

The five hooks

Workshop recognizes five hooks, each one answering a different question about the SDK’s relationship to the workshop.

  • setup-base: System-level preparation for the SDK, run as root inside the workshop container before the project directory is mounted and before any plug or slot is connected. It runs once when the SDK is first installed and again when its revision changes. A refresh reuses the post-setup-base base snapshot instead of running the hook again, but only if the base image and the SDKs listed above this one in the definition are unchanged; a change to any of these invalidates the snapshot, causing setup-base to re-run for this SDK and the ones below it in the definition.

  • setup-project: Per-project preparation, run as the workshop user after the project directory is mounted and after auto-connect has finished. This is the SDK’s chance to do setup that depends on the project directory, the workshop user’s home directory, or the slot resources the SDK now has access to. Use it to prepare the environment, not to build the project itself; daily build activities belong in actions.

  • check-health: The SDK’s report on whether it can operate in this workshop. It runs after setup-project (and, on a refresh, after restore-state), reports its result through workshopctl set-health, and controls whether the SDK becomes Ready. See Talking back with workshopctl below.

  • save-state: Runs during a refresh, on the old SDK revision, before the workshop is stopped and rebuilt. A refresh discards the workshop’s writable filesystem, so anything the SDK keeps there (caches, generated configuration, state that the new revision expects to find) needs to be explicitly copied under $SDK_STATE_DIR to survive.

  • restore-state: Runs during the same refresh as save-state, but on the new SDK revision, after every SDK’s setup-project has finished, and reads back from $SDK_STATE_DIR.

Execution contract

Every hook runs in a non-interactive bash login session with the errexit and pipefail options set, which means a non-zero exit code from any command, or any pipe stage, ends the hook and surfaces the failure to the workshop change that triggered it. When --verbose is passed to workshop launch or workshop refresh, the xtrace option is also set, making each command in the script visible in the change output.

The runner provides the $SDK directory variable to every hook; beyond that, some hooks see additional variables in scope. The privilege, working directory, and extra variables differ by hook (None in the table below means no extras beyond $SDK, not no environment at all):

Hook

Working directory

Runs as

Extra environment

setup-base

The SDK’s hooks/ directory

root

None

setup-project

/project/

The workshop user

$HOME, $XDG_RUNTIME_DIR, $DBUS_SESSION_BUS_ADDRESS

check-health

The SDK’s hooks/ directory

root

None

save-state

The SDK’s hooks/ directory

root

$SDK_STATE_DIR

restore-state

The SDK’s hooks/ directory

root

$SDK_STATE_DIR

For the precise launch and refresh stages at which each hook fires, see the hook reference.

Ordering across SDKs

When several SDKs in a workshop define the same hook, Workshop runs them sequentially, not in parallel, and waits for each hook to finish before starting the next.

The order is fixed: the system SDK first, then the user-listed SDKs in the order they appear in the workshop definition, then the sketch SDK if present. There is no dependency resolution between SDKs; the listing order is the contract. If an SDK relies on another SDK’s setup-base having finished, list it later in the workshop definition.

Talking back with workshopctl

From inside a hook, the SDK can call workshopctl to interact with the workshop daemon.

The only possible use at the moment is workshopctl set-health from check-health, which sets the SDK’s health to okay, waiting, or error. The workshop’s overall status is derived from the union of these results:

  • The hook reports okay and exits with code zero: the SDK is Ready.

  • The hook reports waiting: Workshop sleeps for one second and runs check-health again. After ten consecutive waiting results, the SDK is moved to Error.

  • The hook reports error, exits with a non-zero code, exits without reporting a status, or fails to return within five seconds: the SDK is moved to Error.

See also

Explanation:

Reference:

Tutorial: