Charm architecture¶
bingo is a Go application providing paste creation, retrieval, and expiry - a self-hosted
pastebin service for Canonical. The charm is built with the
go-framework Charmcraft extension,
part of the 12-factor app support provided by
Charmcraft, Rockcraft, and paas-charm.
The general container/sidecar layout, Pebble usage, and PaasCharm base class shared by every
12-factor app charm are already documented centrally:
Charm architecture - the sidecar pattern, the
app/charm container split, and how OCI images are built with Rockcraft.Juju events - the full list of events any
paas-charm-based charm may observe, and its default response to each.How 12-factor principles are applied - why the framework works the way it does.
This page only covers what’s specific to bingo’s usage of go-framework.
bingo container¶
bingo’s workload container (Kubernetes container name app, per the go-framework extension) runs
the compiled bingo binary (built from cmd/bingo/) directly under Pebble. The process runs as
the _daemon_ user with working directory /app, and listens on port 8080 by default (the
app-port framework configuration).
The binary reads its configuration from environment variables: charm configuration options (for
example base-url, max-paste-size-bytes, log-level, web-dir) are injected as APP_*, while
integration data is injected using each integration’s own convention. For example,
POSTGRESQL_DB_CONNECT_STRING is used for the database, and standard OTEL_* variables are used for tracing.
The image is defined in rockcraft.yaml
at the repository root, using the
go-framework Rockcraft extension
with two customizations:
the main package lives at cmd/bingo/ rather than the module root, and the production Vite build
of the React frontend is staged into the image under /app/web/dist, served by the binary as a
single-page application when the web-dir configuration option is set.
Charm code overview¶
charm/src/charm.py defines
the BingoCharm class, which inherits from paas_charm.go.Charm (itself a PaasCharm subclass;
see the generic charm code overview
for how PaasCharm.__init__ wires up event observers).
BingoCharm adds two customizations on top of the inherited behavior:
It observes
config_changeda second time (after the parent class’s own handler) to block the unit ifoauth-redirect-pathhas been changed away from its required fixed value (/auth/callback) - bingo’s OIDC callback route is hardcoded and does not read that configuration option.It overrides the
_base_urlproperty so that thebase-urlconfiguration option, when set, takes priority over the ingress-derived URL thatpaas_charm.go.Charm._base_urlwould otherwise always return, letting operators control the externally-visible link text used in generated paste URLs.
Juju events¶
bingo’s charmcraft.yaml
declares postgresql, tracing, and oauth under requires, alongside the
logging/ingress/secret-storage relations injected automatically by the go-framework
extension. Of all the integration-related events listed in the generic Juju events reference, only the ones tied to those relations are ever fired for
bingo:
PostgreSQL (required):
database_created,endpoints_changed,database_relation_brokenOAuth (optional):
oauth_info_changed,oauth_info_removedTracing (optional):
tracing_endpoint_changed,tracing_endpoint_removedIngress (auto-injected):
ingress_ready,ingress_revokedrotate_secret_key
Events tied to the other integrations paas-charm supports never occur, since bingo’s
charmcraft.yaml doesn’t
declare those relations.
On top of the generic response described in the events reference, two behaviors are specific to bingo:
Every
config_changedevent also validatesoauth-redirect-path: if it has been changed away from its required fixed value, the unit is blocked (see Charm code overview above).No event ever triggers
paas-charm’s migration runner, since bingo ships no migrate script in its image - thebingobinary instead applies its own migrations internally on every process start (seedatabase.Migrateincmd/bingo/main.go).
See Relation endpoints for bingo’s full list of relations, and Charm for more on the charm lifecycle in general.