Repository navigation
feat: container update lifecycle hooks (pre_update, post_update, pre_stop, pre_rollback, post_rollback) - #217
Merged
Conversation
added 15 commits
July 30, 2026 22:47
Two-layer gate for the upcoming container update hooks feature: ALLOW_HOOKS (backend, default false) is the feature gate, ALLOW_EXEC (agent, default false) is defense in depth so a compromised/misbehaving backend can't get arbitrary exec on agents that haven't opted in.
No allowlist here (unlike RunCommandRequestBodySchema/command_validator) - this schema is for the arbitrary-command-by-design exec endpoint, gated instead by the agent's ALLOW_EXEC flag.
Runs sh -c "<command>" inside a container via python_on_whales' container.execute(). Refuses with 403 unless ALLOW_EXEC=true; a non-zero exit is already turned into a 424 with stdout/stderr by the existing DockerException handler.
Single JSON field (not per-hook columns) so new hook types never need another migration. Discussed and agreed in Quenary#214.
…d endpoint
PATCH /containers/{host_id}/{c_name} now rejects a hooks payload with
403 when ALLOW_HOOKS is off. GET /containers/hooks_enabled lets the
frontend decide whether to show the hooks form at all.
pre_update/pre_stop failures abort that container's update via the existing errors/_can_update mechanism (no new abort path needed). post_update/pre_rollback/post_rollback are report-only. pre_rollback fires while the failed container is still alive, both from the healthcheck-fail branch and the exception/cleanup branch.
Quenary
approved these changes
Aug 1, 2026
Quenary
approved these changes
Aug 1, 2026
Quenary
approved these changes
Aug 1, 2026
Quenary
approved these changes
Aug 1, 2026
Quenary
approved these changes
Aug 1, 2026
Quenary
approved these changes
Aug 1, 2026
Owner
|
Great work! |
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.
Summary
Closes #214.
Implements the container update lifecycle hooks feature agreed in the issue thread: users can configure shell commands per container that run inside that container at specific points of the update/rollback flow, so they can do things like
pg_dumpbefore an update without Tugtainer knowing anything about databases.POST /api/container/exec/{name_or_id}endpoint, runssh -c "<command>"inside a container viapython_on_whales. Refuses with403unlessALLOW_EXEC=trueon that agent (defaultfalse).hooksJSON column oncontainers(not per-hook columns, so future hook types never need another migration) with hook namespre_update,post_update,pre_stop,pre_rollback,post_rollback. Writes are rejected with403unlessALLOW_HOOKS=trueon the backend (defaultfalse), and the executor never issues exec calls at all when the flag is off, even if stale hook data exists in the db from a previously-enabled period.execute_update_plan:pre_stopruns for every container about to be stopped;pre_updateadditionally for containers actually being updated. A failure aborts that container's update through the existingerrors/_can_update()mechanism — no new abort path needed, the container is simply left running.post_update,pre_rollback,post_rollbackare report-only (logged, never block).pre_rollbackfires while the failed/unhealthy container is still alive, right before it gets stopped — both from the healthcheck-fail branch and from the exception/cleanup branch (only if the container is actually still running at that point).ALLOW_HOOKS=true.Both
ALLOW_HOOKSandALLOW_EXECdefault tofalseand are documented in.env.exampleand the new README "Hooks" section.Test plan
pytest(agent + backend + shared): 79 passed, 1 pre-existing unrelated failure (test_workdir_logic, a Windows path-separator issue incontainer_util, reproduces onmainwithout this branch, unrelated to hooks)ruff check .: cleanmypy backend agent shared: cleanng test(frontend): 126/126 passedng lint: cleanprettier --check .: cleanDesign decisions were discussed and agreed with @Quenary in #214 before implementation, including the
ALLOW_HOOKS/ALLOW_EXECtwo-layer gate.