Document referential integrity and the delete behavior changes - #150
Merged
Conversation
FOG 1.6 declares its relationships in the database (fogproject ADR 0031). Before, cleaning up after a delete was the job of whatever PHP ran the delete, so every delete path had to remember every dependent table and the ones that forgot left rows pointing at something gone. Nothing told an admin that; they found out when one of those rows did something visible. Three of the changes are ones an admin will actually hit, so they get a reference page plus a note where they will be standing when they hit them: - Deleting a storage group is now REFUSED while nodes still belong to it, a location names it, or file deletions are queued against it. This is the one worth documenting loudly -- before 1.6 it was allowed and silently orphaned. On one real installation, deleting a single storage group left three storage nodes belonging to nothing. - There is no "remove node from group" any more. A node must belong to a group; a group with no nodes is fine. Moving a node means assigning it to the group you want it in. - Deleting an image unassigns the hosts that had it, rather than leaving them naming an image that is gone. The page states what a refused delete LOOKS like, and how to read it. FOG surfaces the database's own message, and the constraint in it is named fk_<table>_<column> -- so the message already says what is holding the record, if you know to read it that way. Documenting the real text rather than a friendlier one we do not emit. Also covers what the upgrade does: it cleans up orphaned rows once, before it can declare any rule, and records what it removed in the audit log with a per-table count under `schema.orphan.sweep`. And that a rule which cannot be applied does not fail the upgrade -- it is skipped, logged, and FOG keeps 1.5 behavior for that one relationship until the data is fixed. The case that occurs in practice is a storage node in no group, which nothing can guess a group for. Two cross-links added, both path-qualified and on one line so they parse. Verified by building the site: 115 files, no errors, zero unparsed `[[` in the three pages, both links resolving to real hrefs, and the new page present in the content index and its context_id redirect stub emitted.
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Documents the user-visible half of fogproject ADR 0031 (FOGProject/fogproject#1469
and FOGProject/fog-plugins#29, both merged): FOG 1.6 declares its
relationships in the database, so deletes now behave consistently no matter
what performed them.
What is here
docs/kb/reference/referential-integrity.md— the full set ofrules, what each delete now does, what a refused delete looks like and how
to read it, and what the upgrade does to existing data.
management/web/storage-node.md— a "Moving and deleting nodes"section, because this is where the two behavior changes an admin will
actually trip over live.
management/web/images.md— a short note that deleting an imagedefinition unassigns the hosts that had it.
The three an admin will notice
a location names it, or file deletions are queued against it. This is the
one worth documenting loudly: before 1.6 it was allowed and silently
orphaned. On one real installation, deleting a single storage group left
three storage nodes belonging to nothing.
group; a group with no nodes is fine. Moving a node means assigning it to
the group you want it in, which moves it in one step.
an image that is gone.
Two choices worth flagging for review
It documents the raw error text. FOG surfaces the database's own message
on a refused delete — we do not translate it. The page prints a real example
and explains how to read it, because the constraint name is
fk_<table>_<column>and therefore already says what is holding the record.Writing a friendlier message we do not actually emit would be worse than
ugly, it would be wrong. (A friendlier one is worth doing in
fogproject; itis a change to a shared base class and belongs in its own change.)
It states that the upgrade can skip a rule without failing. That is
deliberate rather than a caveat buried in a note:
ADD CONSTRAINTvalidatesexisting rows, so a server holding data this release did not anticipate would
otherwise abort the upgrade and strand itself on
?node=schemaover datathat is otherwise intact. Instead the rule is skipped, the reason is logged,
and FOG keeps 1.5 behavior for that one relationship. The case that occurs in
practice is a storage node sitting in no group, which nothing can guess a
group for.
Verified
npm run docs:build— 115 files, no errors. Beyond that, the failures thisrepo's own conventions warn about are silent, so each was checked directly:
[[in all three pagescontext_idredirect stub was emittedcontext_idis unique site-wide, and every tag used already exists🤖 Generated with Claude Code
https://claude.ai/code/session_019Q7gwbNYDmYVFRBrXDXFz5