Files
ocf-managed-container/docs/review.md
T

116 lines
7.4 KiB
Markdown

# Freeze review — 2026-09-12
This review preserves the implementation reported as production-tested by the
operator. No production systems were changed. It is a source/documentation
freeze, not certification of every failure mode or a byte-level deployment
attestation. Production hash collection remains outstanding in [testing.md](testing.md).
## Corrections and their reasons
- Added operations.md to distinguish container lifecycle, PostgreSQL lifecycle,
Pacemaker state, scores, fencing, controlled switchover and former-primary rejoin.
- Added testing.md to record the operator's SBD failover/VIP/rewind/rejoin sequence
and final three-node roles/scores, separately from local automated checks.
Recorded exact repository RA/module/helper/bootstrap hashes without inventing
deployed hashes. Included read-only per-node hash collection commands.
- Required target-role=Promoted, promoted-max=1, Promoted-role VIP colocation and
promotion-before-VIP-start ordering in the operating policy. Compatibility
tests for absent/Started target roles are not recommendations to change production.
- Fixed plan-promotion-cleanup.py to emit only temporary node-preference removal
and preserve target-role=Promoted. Removed its obsolete inherited-Started
check because it no longer clears the direct target role. Updated its exact
expected-output test; ambiguity and unrelated-rule protections remain. Added
an explicit Promoted-target scheduler case and used that target in fencing
scenarios; compatibility cases remain.
- Explicitly prohibited clearing former-primary failed actions before successful
rejoin and verification of streaming recovery. Documented rewind before any
explicitly authorized basebackup fallback, and that failed rewind may require
further recovery rather than a normal restart.
- Documented literal env-file quotes and the mismatch between generated pgpass
and the RA's direct container environment password. All examples use obvious
fake values; no actual password from the handoff was copied into the repository.
- Updated README and historical handoffs/notes to point to current operations
and evidence. Corrected the PID 1 simplification: bootstrap executes the
maintenance command, possibly behind Podman's init shim.
- Included current operating/testing/review documents in source/RPM documentation.
Retained the old ELITEDESK installer as a clearly marked historical lab tool:
its hostname/cluster/hash guards reject the scoring implementation. It is not
a production installer and was not executed.
- Ignored generated review patches; the commit records the actual files instead
of duplicating obsolete proposed commands in patch attachments. Refreshed the
checksum manifest. Existing local patch files remain available locally.
The staged scoring, state helper, tests and RPM workflow from the preceding
implementation work are included in this freeze commit. This review did not
modify RA/module/scoring-helper or bootstrap code. The frozen original remains
unchanged, and all 29 original lifecycle bodies still compare byte-for-byte.
## Checks completed in this review
- Structural/default/metadata verification and all 22 differential lifecycle cases.
- 25 promotion-scoring tests, 16 disconnected-state/monitor tests, 11 synthetic
Pacemaker scheduler tests and 4 corrected preference-planner tests: all pass.
- Nine SQL scenarios against a disposable PostgreSQL 18 container: all pass for
the original strict predicate and current observation query. Container removed.
- Bash syntax and Python AST parsing across repository code and historical installer:
pass. ShellCheck and Gitleaks were not installed; no claim of running them is made.
- Repository/diff review for private keys, recognizable tokens, credential-bearing
URLs, and credential assignments, plus manual inspection of matches: no actual
secrets found. Matches were variable references, redacted snapshots, or explicit
fake examples. No CIB, secret file, .pgpass content or raw environment dump was added.
- A disposable Podman test reproduced literal env-file quotes using only a fake
value. No production credentials or environments were inspected.
- Fedora 43 development RPM build with the new docs passed; artifacts are in
dist/documentation-freeze/ and the log is /tmp/mc-freeze-build.log. The extra
Promoted-target scheduler case was subsequently verified separately.
- Checksum manifest and git diff whitespace checks are verified immediately before
commit.
## Privilege and safety boundaries reviewed
The RA does not source host-side PostgreSQL environment/configuration. Its
root-to-service-user boundary preserves argument arrays, and container commands
consume intentional injected settings. Authentication secrets are not placed in
RA command arguments or host-side pgpass files. The stored bootstrap is separate
and has a different provisioning interface.
The scoring helper uses bounded subprocesses, a root-only runtime directory,
strictly parsed JSON, per-resource locks and atomic replacement. Its identity
includes postmaster start time, so a restarted/replaced data instance must stream
successfully before receiving disconnected eligibility. Notification state uses
a separate root-owned /run directory and relies on Pacemaker serializing actions
for the same resource; it is not a distributed locking or fencing mechanism.
Original SQL/shell construction in some lifecycle helpers assumes trusted,
conventional resource configuration (identifiers, paths, connection fields).
It is not a general escaping layer for arbitrary user-supplied text. Restrict CIB
write access and container ownership; do not expose RA parameters to untrusted
input. No new untrusted input interface was introduced by this review.
## Remaining concerns and explicit limits
- The three production nodes' exact deployed hashes and confirmation that those
bytes were used in the fencing test are missing. Source hashes are not a
substitute. The runtime-context bootstrap may differ from deployed production.
- The saved bootstrap's fresh-primary provisioning path passes a replication
password through a psql --set argument. That can expose it to process-argument
inspection under local /proc permissions. This is a concrete existing exposure,
not a claim that the RA rejoin path leaks a password. It must be reviewed against
the actual deployed bootstrap before calling provisioning secret-safe; no
bootstrap rewrite or production secret change was made in this freeze.
- Existing bootstrap pgpass generation assumes values needing no additional
colon/backslash escaping. Do not treat the documented quote correction as a
universal password-encoding solution. Inspect the deployed bootstrap before
changing provisioning behavior.
- Scores are observations, not fencing authorization or atomic promotion guards.
IPC failure can leave a prior score; monitor cadence/fencing latency can exceed
freshness. Two disconnected candidates are not ranked by cross-node WAL history.
- Asynchronous replication can lose acknowledged transactions. Neither the test
nor the freshness threshold proves a numerical data-loss bound.
- The reported fenced-failure/rejoin success does not prove every concurrent-write
controlled-switchover scenario or optional destructive basebackup fallback.
- License provenance remains unresolved as documented in packaging/PROVENANCE.md.
This source freeze is not a license grant or public-release authorization.
No push or production rollout is part of this review.