Phase 2: write the missing etc/kerbside.conf.example¶
Master plan: PLAN-demo-install.md
Planned at medium effort: mechanical enumeration of a pydantic model, with one judgement call about how much to say per setting.
Situation¶
Two documents refer the reader to a file that does not exist:
docs/configuration.md:5— "Seeetc/kerbside.conf.examplefor a complete configuration example."ARCHITECTURE.md:345— "Seeetc/kerbside.conf.examplefor a complete configuration reference."
etc/ contains only example-static-sources.yaml and
kolla-ci-globals-overlay.yml. The reference has been dead
long enough that two documents accumulated it.
The configuration mechanism it should demonstrate is real
and undocumented by example:
kerbside/config.py:14-38's load_ini_settings() reads
/etc/kerbside/kerbside.ini (INI_PATH), takes keys from a
single [kerbside] section (INI_SECTION), upper-cases each
key, prefixes it with KERBSIDE_, and sets it in
os.environ only if not already set — so environment
variables win over the INI file, as docs/configuration.md:3
says.
Mission¶
etc/kerbside.conf.example exists, is a valid INI file that
load_ini_settings() would parse, covers every field on
Config, and cannot silently fall behind config.py because
a test fails when it does.
Approach¶
Shape¶
One [kerbside] section, keys in lower case (they are
upper-cased on load, so lower case reads naturally and
proves the case-insensitivity), grouped with comment headers
matching docs/configuration.md's section order so the two
can be read side by side: Basic, TLS, Keystone, Shaken Fist
console tokens, Network, gRPC control plane, SPICE firewall,
Logging and monitoring.
Every setting gets a one-line comment. Settings that are required in practice are uncommented with a placeholder; settings that have a working default are commented out showing that default. This makes the file a template rather than a wall of redundant assignments: uncomment what you need to change.
The required-in-practice set, taken from what
tools/direct-qemu/start-kerbside.sh must set for kerbside
to function: sql_url, auth_secret_seed, sources_path,
public_fqdn, cacert_path, proxy_host_cert_path,
proxy_host_cert_key_path, proxy_host_subject.
Two accuracy traps¶
-
Do not describe the sentinel defaults as absent.
AUTH_SECRET_SEED,KEYSTONE_AUTH_URL,KEYSTONE_SERVICE_AUTH_USER, andKEYSTONE_SERVICE_AUTH_PASSWORDall default to the literal string~~unconfigured~~(config.py:44,55,68,72).docs/configuration.mdcurrently callsAUTH_SECRET_SEED"String (no default)", which is wrong, and issue #131 quotes that wrongness as part of its evidence. So: state the truth inkerbside.conf.example(there is a sentinel default and nothing rejects it at startup), and do not editdocs/configuration.md's table in this phase. Record the discrepancy as a comment on issue #131 instead, so the issue and the tree do not diverge under the person fixing it. Phase 5 may link to the example file fromconfiguration.md, which is a different change. -
auth_secret_seedmust not ship a plausible-looking value. An example file containing a real-looking hex string is a value someone will paste into production. Use an obvious placeholder and give the command that generates a real one:openssl rand -hex 32, matchingstart-kerbside.sh:63.
The anti-rot test¶
Add a test in kerbside/tests/ that:
- Parses
etc/kerbside.conf.examplewithconfigparser, reading both live and commented-out keys — the commented ones are the documented defaults and must count as covered. Recognise a commented key by the pattern# key = valueat the start of a line, which means the file must use exactly that form for defaults, with a single leading#. Say so in a comment at the top of the example file, because the test now depends on its formatting. - Enumerates
Config.model_fieldsand asserts every field name, lower-cased, is present. - Asserts the converse: every key in the file corresponds to a real field, so a renamed setting leaves no orphan.
Locating the file from the test: it is repository data, not
package data, so importlib.resources does not apply. Walk
up from __file__ to the directory containing etc/, and
skip the test if not found rather than failing — an
installed wheel has no etc/, and a test that fails when
run from site-packages is a worse outcome than one that
skips. Use the same skip idiom as any existing repo-data
test in kerbside/tests/; if there is none,
unittest.SkipTest with a message naming why.
Execution¶
| Step | Effort | Model | Isolation | Brief for sub-agent |
|---|---|---|---|---|
| 2a | medium | sonnet | none | Write etc/kerbside.conf.example per the "Shape" section above. Enumerate the fields from kerbside/config.py — every field on Config, in the section grouping given, with the description= text from each Field() as the basis of its comment (condensed to one or two lines; several descriptions in config.py are long, e.g. API_SOCKET_PATH's SUN_LEN warning, which is worth keeping). Required-in-practice keys live; defaulted keys commented out in the exact form # key = value. Obey both accuracy traps: sentinel defaults described honestly, auth_secret_seed a visible placeholder with the openssl rand -hex 32 hint. Add a header comment block explaining the INI path (/etc/kerbside/kerbside.ini), the single [kerbside] section, that env vars override the file, and that the # key = value form is asserted by a test so defaults must keep that shape. |
| 2b | medium | sonnet | none | Add the anti-rot test described in "The anti-rot test" to kerbside/tests/, matching the existing test style in that directory. All three assertions: every Config field covered, no orphan keys, and the file parses. Skip cleanly when etc/ is absent. Run it, then deliberately add a throwaway field to Config and confirm the test fails, then remove it — report that you did this, because a coverage test that cannot fail is worthless. |
| 2c | low | haiku | none | Post a comment on GitHub issue #131 recording that docs/configuration.md's "String (no default)" description of AUTH_SECRET_SEED is still present and still wrong, that etc/kerbside.conf.example now documents the sentinel default accurately, and that the configuration.md table was deliberately left alone so the fix lands with the startup guard. Do not close or otherwise modify the issue. |
Note: no step here edits docs/configuration.md or
ARCHITECTURE.md. Their pointers become true the moment the
file exists, which is the point. Phase 5 revisits
configuration.md for cross-linking.
Success criteria¶
etc/kerbside.conf.exampleexists and every field onConfigappears in it.- The test from 2b passes, and has been demonstrated to fail when a field is added without updating the file.
- Dropping the file at
/etc/kerbside/kerbside.iniwith the required keys filled in is sufficient to configure kerbside — verified by doing it, not by inspection. docs/configuration.md:5andARCHITECTURE.md:345now point at something real, with no edit to either.tox -eflake8andtox -epy3pass.