Skip to content

feat(backups): workload service control, pgBackRest paths and backup state accessors - #207

Draft
marceloneppel wants to merge 4 commits into
16/edgefrom
feat/04-backups-scaffolding
Draft

feat(backups): workload service control, pgBackRest paths and backup state accessors#207
marceloneppel wants to merge 4 commits into
16/edgefrom
feat/04-backups-scaffolding

Conversation

@marceloneppel

Copy link
Copy Markdown
Member

Issue

Unit 04 of the charm-to-library migration ports the backup and restore subsystem into the library. That port cannot start yet: the workload layer has no way to address a service by name (the abstract start_service took no argument and neither substrate implemented it), Paths does not expose the pgBackRest log directory, and every backup/restore coordination field is read through the untyped databag escape hatch with the key spelled out at each call site.

Solution

Lay the scaffolding the backup port lands on. No backup logic moves in this PR.

  • pgBackRest log directory and the two machine-charm snap service names become literals, one constant per substrate rather than one shared string: the snap keeps the log directory unversioned beside the other workload logs, while the Kubernetes charm scopes it under the version subtree of the mounted logs storage.
  • The log directory resolves through Paths, keeping that divergence out of the backup manager, which would otherwise have to branch on the substrate to build a path.
  • Typed stanza and restore-state accessors name each key once on the state object, so a rename or a scope mistake is one edit rather than a search. The stanza needs a cross-scope reader because it is published by whichever unit is primary and only later adopted by the leader, so consulting one databag alone is not enough. Field names are left exactly as the charms write them, so a cluster mid-restore survives the adoption.
  • Workload services are addressed by name — start, stop, restart, reload and query — so the manager can express the pgBackRest lifecycle without knowing whether it is talking to snapd or Pebble. reload_service is the one primitive whose meaning differs: Pebble can signal a running service to re-read its configuration, the snap layer offers no signal channel, so on machines the only available reload is a restart, which is what the machine charm already does today. Querying a service has to answer for names the substrate may not know — a snap revision predating a service omits it from its services mapping, and Pebble cannot be asked before the container is up; both read as not running rather than raising.

Unit tests follow in a separate PR, matching the code-then-tests split used for the earlier migration units.

Checklist

  • I have added or updated any relevant documentation.
  • I have cleaned any remaining cloud resources from my accounts.

The backup port needs to name the pgBackRest log directory on both
substrates and the two snap services the machine charm drives. The log
directory differs structurally between substrates - the snap keeps it
unversioned next to the other workload logs, while the Kubernetes charm
scopes it under the version subtree of the mounted logs storage - so
each side gets its own constant rather than one shared string.

Signed-off-by: Marcelo Henrique Neppel <marcelo.neppel@canonical.com>
Rendering the logrotate configuration needs the pgBackRest log directory,
and the two substrates place it differently. Resolving it through the
Paths abstraction keeps that divergence out of the backup manager, which
otherwise would have to branch on the substrate to build a path.

Signed-off-by: Marcelo Henrique Neppel <marcelo.neppel@canonical.com>
The backup and restore flows keep their coordination fields in the peer
databags, and until now every reader reached them through the untyped
data escape hatch with the key spelled out at the call site. Typed
accessors name each key once on the state object, so a rename or a scope
mistake is one edit rather than a search; the raw databag reads left in
the config manager move over as the port reaches them.

The stanza needs a cross-scope reader because it is published by whichever
unit is primary and only later adopted by the leader, so consulting one
databag alone is not enough. Field names are left exactly as the charms
write them: a cluster mid-restore has to survive the adoption.

Signed-off-by: Marcelo Henrique Neppel <marcelo.neppel@canonical.com>
The backup domain has to start, stop, restart and inspect the pgBackRest
TLS server, its exporter and the log rotator, none of which the workload
could reach: the abstract start_service took no argument and neither
substrate implemented it. Giving that stub the service name it always
needed, plus the missing stop/restart/reload/query counterparts, lets the
manager express the pgBackRest lifecycle without knowing whether it is
talking to snapd or Pebble.

reload_service is the one primitive whose meaning differs. Pebble can
signal a running service to re-read its configuration; the snap layer
offers no signal channel, so on machines the only available reload is a
restart - which is what the machine charm already does today.

Querying a service has to answer for names the substrate may not know. A
snap revision that predates a service omits it from its services mapping,
and Pebble cannot be asked at all until the container is up; both read as
not running rather than raising.

The pgBackRest binary is likewise substrate-specific, reachable only
through a snap alias on machines, so it becomes a workload property, with
the alias itself joining the other snap names in the literals module.

Signed-off-by: Marcelo Henrique Neppel <marcelo.neppel@canonical.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant