fix(l4d2-web): server delete job now removes the DB row
The delete job ran l4d2ctl delete (host-side cleanup) but never removed the Server row, so deleted servers kept appearing on /servers. Hard-delete the row in the worker's success path and skip the post-op status refresh, since the systemd unit is gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fb3c6be052
commit
c8a2d563ce
2 changed files with 47 additions and 0 deletions
|
|
@ -311,6 +311,15 @@ def run_job(job_id: int) -> None:
|
||||||
on_stderr=on_stderr,
|
on_stderr=on_stderr,
|
||||||
should_cancel=should_cancel,
|
should_cancel=should_cancel,
|
||||||
)
|
)
|
||||||
|
# Host-side cleanup succeeded; remove the DB row so the server
|
||||||
|
# disappears from /servers. Status refresh is skipped — the
|
||||||
|
# systemd unit is gone and querying it would just log noise.
|
||||||
|
with session_scope() as db:
|
||||||
|
server = db.scalar(select(Server).where(Server.id == server_id))
|
||||||
|
if server is not None:
|
||||||
|
db.delete(server)
|
||||||
|
finish_job(job_id, "succeeded", 0)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"unknown job operation: {operation}")
|
raise ValueError(f"unknown job operation: {operation}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,44 @@ def test_unexpected_exception_fails_job_with_exit_code_one(seeded_worker, monkey
|
||||||
job = load_job(job_id)
|
job = load_job(job_id)
|
||||||
assert job.state == "failed"
|
assert job.state == "failed"
|
||||||
assert job.exit_code == 1
|
assert job.exit_code == 1
|
||||||
|
# Failed delete must keep the Server row.
|
||||||
|
with session_scope() as session:
|
||||||
|
assert session.scalar(select(Server).where(Server.id == ids.server_one)) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_successful_delete_removes_server_row(seeded_worker, monkeypatch) -> None:
|
||||||
|
app, ids = seeded_worker
|
||||||
|
job_id = add_job(ids.user, "delete", server_id=ids.server_one)
|
||||||
|
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def fake_delete(server_id, *, on_stdout=None, on_stderr=None, should_cancel=None):
|
||||||
|
del should_cancel
|
||||||
|
calls.append(server_id)
|
||||||
|
on_stdout("removing systemd unit")
|
||||||
|
|
||||||
|
def fake_status(name): # pragma: no cover — would mean delete didn't skip refresh
|
||||||
|
pytest.fail(f"server_status must not be called after a successful delete (got {name!r})")
|
||||||
|
|
||||||
|
monkeypatch.setattr(l4d2_facade, "delete_server", fake_delete)
|
||||||
|
monkeypatch.setattr(l4d2_facade, "server_status", fake_status)
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
assert run_worker_once() is True
|
||||||
|
|
||||||
|
assert calls == [ids.server_one]
|
||||||
|
job = load_job(job_id)
|
||||||
|
assert job.state == "succeeded"
|
||||||
|
assert job.exit_code == 0
|
||||||
|
with session_scope() as session:
|
||||||
|
assert session.scalar(select(Server).where(Server.id == ids.server_one)) is None
|
||||||
|
# Sibling server is untouched.
|
||||||
|
assert session.scalar(select(Server).where(Server.id == ids.server_two)) is not None
|
||||||
|
# The delete job itself stays in the job log; outerjoin in views shows
|
||||||
|
# "-" for its (now-orphaned) server_id pointer.
|
||||||
|
finished_job = session.scalar(select(Job).where(Job.id == job_id))
|
||||||
|
assert finished_job is not None
|
||||||
|
assert finished_job.server_id == ids.server_one
|
||||||
|
|
||||||
|
|
||||||
def test_same_server_jobs_do_not_overlap(seeded_worker, monkeypatch) -> None:
|
def test_same_server_jobs_do_not_overlap(seeded_worker, monkeypatch) -> None:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue