v1.6.20
Capone and Subnet Group declare their foreign keys, and an id column can no
longer ship without a decision behind it.
Applies the relationships declared in
fogproject#1481.
Three columns nobody had decided about
fogproject's constraint map requires every id column to be classified —
constrained, or explicitly recorded as unconstrainable. But the gate enforcing
that walks commons/schema-expected.php, which is 70 core tables. No
plugin table is in it, so for the whole of ADR 0031 nothing ever asked the
question of a plugin's columns. Three had never had an answer:
| column | → | action |
|---|---|---|
capone.cImageID |
images.imageID |
RESTRICT |
capone.cOSID |
os.osID |
RESTRICT |
subnetgroup.sgGroupID |
groups.groupID |
CASCADE |
tests/plugin-id-columns-are-classified.test.php is the missing half of that
gate and lives here, because this repository is fetched on its own and is the
only side that knows its own tables. It covers 52 id columns across 24 tables.
Capone refuses rather than cascades
Nothing in FOG deleted a Capone rule when its image or OS went — no hook, no
deletemass() case — so the reference simply dangled. Deleting an image or an
operating system that a Capone rule still uses is now refused, with a
sentence naming what is holding it. CASCADE would instead have silently
deleted an administrator's deployment rule as a side effect.
Subnet Group is the opposite: removesubnetgroupgroup.hook.php already
deleted those rows when a group was destroyed, so its CASCADE states in the
schema what was relying on a hook being registered. Nothing observable
changes.
Upgrade notes
capone.cOSID becomes MEDIUMINT(9) to match os.osID, and both Capone
columns become nullable so that "no reference" is spelled NULL rather than
0 — a foreign key accepts nothing else. Existing 0 values are converted
in place and the row count is logged.
No rows are deleted. Because the columns are nullable, the orphan sweep
nulls a dangling reference rather than removing the row that holds it.