Skip to content

tutorial-shell

Recipe card from the charly-distros plugin (Images — the deployable catalog).

The documented example. tutorial-shell exists so the quickstart and the concepts curriculum on opencharly.ai can quote a box that is real, builds, and is re-proven on every R10 roster run — instead of illustrating with YAML that nobody executes.

Lives in the opencharly/distro-fedora repo (git submodule at box/fedora). Its fedora base is bare-local in the same self-contained submodule (import: []), and all three composed candies are pulled by @github reference.

Terminal window
charly -C box/fedora box build tutorial-shell
charly -C box/fedora check run check-tutorial-shell
Property Value
Base fedora
Candies supervisord, ripgrep, sshd
Ports 2222 (tcp, from the sshd candy)
Init supervisord — composed explicitly (see below)
Bed check-tutorial-shell (disposable: true, pod)

Each one is there to teach exactly one thing, and the composed list is kept to three so it stays readable when quoted in full on a documentation page:

Candy Teaches
supervisord (its own repo, opencharly/layer-supervisord) the init candy — declaring a service selects an init, and composing that init’s candy makes the assembled /etc/supervisord.conf deterministic
ripgrep (its own repo, opencharly/layer-ripgrep) a tool candy — packages plus deterministic probes, no service
/charly-coder:sshd a service candy, and the canonical init-polymorphism example: ONE service: list carrying both a use_packaged: systemd form and a custom exec: supervisord form

The init is composed explicitly. Because sshd declares a service, charly resolves which init the destination needs — supervisord for this container image, systemd on a machine venue. The acting init’s candy must be in the composed set: without it charly warns and injects nothing. Listing supervisord makes the assembled /etc/supervisord.conf deterministic; the same sshd candy meets systemd instead when it lands on a systemd machine.

Together they cover the whole shape of a box without any of them being a fixture: a reader can build this, shell into it, and use it.

What the box’s own plan asserts — and what it deliberately does not

Section titled “What the box’s own plan asserts — and what it deliberately does not”

The box carries one check: step, tutorial-shell-service-wired-into-init: the assembled /etc/supervisord.conf contains a [program:sshd] block.

That is the only claim composition itself produces. The supervisord candy’s plan proves the init is installed; sshd’s proves the daemon is installed; neither proves sshd became a supervisord program. Drop sshd from the composed list and the check fails: with no service: declared there is nothing to wire, so the assembled /etc/supervisord.conf holds no [program:sshd] block.

Co-residence is NOT checked here, on purpose. Every composed candy’s plan runs against this image, so ripgrep’s probes and sshd’s probes both passing already proves both landed. A box-level command -v rg && command -v sshd would duplicate them (R2), and it would pass for the wrong reason — testing the candies rather than the composition. The same applies to the bed, which carries no plan: of its own.

This distinction is the reason the box exists in its current shape, and it is worth preserving: a teaching example that restates a candy’s own probe in the composing box teaches the opposite of the rule the site’s own “the spec is the test” page states.

Editing rule — the site quotes this file verbatim

Section titled “Editing rule — the site quotes this file verbatim”

Documentation pages excerpt box/tutorial-shell/charly.yml, they do not paraphrase it. Two consequences:

  1. Keep it readable. Comments in the box are written for a first-time reader, not for a maintainer. Resist adding candies: every addition costs a line on several published pages.
  2. A change here is a documentation change. After editing the box, re-read the pages that quote it (the quickstart and the concepts curriculum) and update the surrounding prose in the same cutover — a quoted block that no longer matches its source is a doc-vs-reality divergence (R1), not a cosmetic drift.

MUST be invoked when editing the tutorial-shell box, the check-tutorial-shell bed, or any opencharly.ai page that quotes them.