Skip to content

fix(computers): a restarted desktop clears the X lock a killed X left - #411

Open
earakely-scale wants to merge 1 commit into
mainfrom
fix/desktop-clears-a-stale-x-lock
Open

earakely-scale wants to merge 1 commit into
mainfrom
fix/desktop-clears-a-stale-x-lock

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

recording_chaos_test.py::test_a_restarted_driver_forgets_its_recording_and_keeps_the_segments_it_closed fails now and then in integration-local-slow: after docker restart -t 2 the driver answers again within a second, but computer-ready says not ready for the whole 60 s wait.

Why

docker restart keeps the container's filesystem. When the stop outlasts its grace period, X is killed before it can remove /tmp/.X99-lock. On the next boot pids are handed out again from 1, so the pid in that lock is often taken, by X itself or by another program. X then takes the lock for a server still running and exits with Server is already active for display 99. supervisord retries three times. When the pid belongs to a process that stays up, every retry fails and xvfb ends FATAL. The driver keeps serving, so the readiness checks fail forever.

Reproduced on the base image and on a composed desktop: a hard restart left xvfb FATAL with the reference driver RUNNING.

Change

  • start-desktop xvfb removes the lock before starting X. supervisord runs one X at a time, so any lock there is stale.
  • A new base test plants a lock naming pid 1 (tini), hard-restarts, and expects every program RUNNING. It fails on main and passes here.
  • _ready's timeout now names the checks that failed, so a computer that never comes up says why.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 4/5

The fix appears safe to merge, with a non-blocking gap in the new regression test.

Fix All in CursorFindings

  1. P2 Failed startup passes the test ▶
Fix with agent prompt
### Issue 1
tst/integration/computer/base_computer_test.py:98-101
The new test passes if `_all_running(name)` returns an empty string after the restart. That helper returns the last command's output even when every attempt fails, and `all(...)` over empty output is true. Assert that `running` is nonempty before checking its lines so a desktop that never starts cannot pass this regression test.

```suggestion
    assert running and all(" RUNNING " in line for line in running.splitlines()), running

@pytest.mark.parametrize("setting, value, error", [
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Removes the leftover X lock before Xvfb starts after a hard restart.

  • The Ubuntu desktop clears X’s stale lock before it starts the display.
  • Recording restart timeouts say which readiness checks failed.

Reviews (1) · Last reviewed commit: "fix(computers): a restarted desktop clea..." · Reviewed by Greptile

docker restart keeps the container's files, so an X killed before it removed /tmp/.X99-lock leaves it behind. Pids
start again from 1, so the pid it names is often taken; X then refuses to start and supervisord gives up on it, while
the driver keeps answering not ready. start-desktop now removes the lock before starting X, since supervisord runs
one X at a time. A base test plants a lock naming pid 1 and hard-restarts; the restart chaos test's timeout names the
checks that failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale requested a review from a team as a code owner October 30, 2026 17:38
Comment on lines +98 to 101
assert all(" RUNNING " in line for line in running.splitlines()), running


@pytest.mark.parametrize("setting, value, error", [

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Failed startup passes the test

The new test passes if _all_running(name) returns an empty string after the restart. That helper returns the last command's output even when every attempt fails, and all(...) over empty output is true. Assert that running is nonempty before checking its lines so a desktop that never starts cannot pass this regression test.

Suggested change
assert all(" RUNNING " in line for line in running.splitlines()), running
@pytest.mark.parametrize("setting, value, error", [
assert running and all(" RUNNING " in line for line in running.splitlines()), running
@pytest.mark.parametrize("setting, value, error", [
Prompt To Fix With AI
This is a comment left during a code review.
Path: tst/integration/computer/base_computer_test.py
Line: 98-101

Comment:
**Failed startup passes the test**

The new test passes if `_all_running(name)` returns an empty string after the restart. That helper returns the last command's output even when every attempt fails, and `all(...)` over empty output is true. Assert that `running` is nonempty before checking its lines so a desktop that never starts cannot pass this regression test.

```suggestion
    assert running and all(" RUNNING " in line for line in running.splitlines()), running

@pytest.mark.parametrize("setting, value, error", [
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Cursor Fix in Claude Code Fix in Codex

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant