Give a task the host died on a state of its own (schema 281) - #1212
Merged
Conversation
Ported from 1.6 #1211, completing the port of #1210. A FOS error report is recorded there, and the task itself was left exactly where it was: Queued or In-Progress, forever. The task page still said the machine was working on it, and because Host::loadTask() and getActiveTaskCount() count those states as live, the host could not be re-tasked until somebody noticed and cancelled it by hand. Adds taskStates row 6, Failed, and moves the task to it when FOS reports an error. A warning never does -- a warning means FOS carried on. Not Cancelled, which was the alternative. Cancelled means an administrator stopped it; losing the difference between "somebody stopped this" and "this broke" costs the operator the one fact they open the task list to find. Additive on a maintenance branch, which is why it is portable at all: every "is this task live" test in the tree is an allowlist -- getQueuedStates() plus getProgressState() -- so a state nobody listed is inactive by construction, and no call site had to learn about it. 1.5 has no history pane, so a Failed task is as invisible in the UI as a Complete or Cancelled one already is; what changes is that the host is free and the task has stopped claiming otherwise. The state is written for every task type, not just imaging ones: a Memtest the host died on is as finished as a deploy. Only HOST_IMAGE_FAIL stays imaging-specific. Guarded on the taskStates row existing, so a web tree updated ahead of its database leaves the task alone rather than pointing it at a state that is not there. Verified against an isolated copy of the 1.5 database (podman MariaDB, shadow web tree, throwaway host on a locally-administered MAC, 2079 real hosts): a warning left the task Queued and wrote a row typed warning; an error moved it to 6 and dropped the host's active task count to zero; error, warning and unknown-MAC all still answer an identical `##`. Step 281 applies clean on a database at 278. Seven assertions mutation-tested. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Port of #1211, completing #1210. Independent of anything else open — different base.
The problem
A FOS error report is recorded on 1.5 since #1210, and the task itself was left exactly where it was: Queued or In-Progress, forever.
Host::loadTask()andHost::getActiveTaskCount()count those states as live, so the host could not be re-tasked until somebody noticed and cancelled the task by hand.The change
taskStatesrow 6, Failed (schema 281)TaskState::getFailedState()with aFAILED_STATEhook, plus theFOGBasepassthrough its five siblings already haveTaskErrormoves the task to it on an error; a warning never doesNot Cancelled: that means an administrator stopped it, and losing the difference between "somebody stopped this" and "this broke" costs the operator the one fact they open the task list to find.
Why this is portable to a maintenance branch at all: every "is this task live" test in the tree is an allowlist —
getQueuedStates()plusgetProgressState()— so a state nobody listed is inactive by construction and no call site had to learn about it. 1.5 has no history pane, so a Failed task is exactly as invisible in the UI as a Complete or Cancelled one already is; what changes is that the host is free and the task has stopped claiming otherwise. (1.6 got a Recent-pane filter and a task log tab in #1211; neither of those panes exists here.)The state is written for every task type — a Memtest the host died on is as finished as a deploy — while
HOST_IMAGE_FAILstays imaging-specific._markFailed()is guarded on thetaskStatesrow existing, so a web tree updated ahead of its database leaves the task alone rather than pointing it at a state that is not there.Verification
Against an isolated copy of the real 1.5 database (podman MariaDB on :13306, shadow web tree, throwaway host on a locally-administered MAC, 2079 real hosts — nothing live touched):
taskLogrow typedwarninggetActiveTaskCount()→ 0,loadTask()invalid##bodySeven assertions mutation-tested (wrong constant, unseeded row, call removed, call moved either side of both gates, a second field written, guard removed). Full suite green.