Warn the logs, not just the web UI, about the deprecated Docker Hub image - #846
Merged
Merged
Conversation
…mage An admin who runs codex headless and never opens the settings drawer had no way to learn that their image had stopped being the real one. Say it where they are actually looking. The warning names the registry to move to and links to the migration docs, and only the Docker Hub image ever emits it. It fires at startup beside the other lines about how this install is configured, and once a day from the janitor's version check rather than from a new job of its own. That call sits inside the fetch gate: while the version cache is empty every API hit queues a check, and only the one that wins the lock should nag. Co-Authored-By: Claude Opus 5 <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.
Why
The deprecated Docker Hub image already tells admins to switch registries, but only in the web UI: a snackbar and a settings-footer link. An admin who runs Codex headless, or who simply never opens the settings drawer, had no way to learn that their image had stopped being the real one. That is most of the audience this whole effort is aimed at, since the stranded installs are the ones nobody is actively tending. So say it where they are actually looking.
What changed
The warning text lives in one place,
log_docker_hub_deprecationincodex/util.py, besideis_docker(). It returns immediately unless the deprecated image's flag is set, so ghcr.io and native installs emit nothing at all. The message names the registry to move to and links to the migration docs, because a log line nobody can act on is worse than no log line.Two call sites, no new janitor job:
codex_init(), alongside the existing lines about the URL path prefix and remote-user auth.The one placement decision worth reviewing
The daily call sits inside the PyPI fetch gate, not at the top of
update_latest_version.While the version cache is empty, every hit on
/api/v4/versionqueues one of these tasks. A call at the top of the method would therefore turn a daily nag into a log flood during a cold cache or a PyPI outage, which is exactly the failure the_FetchGatelock was added to prevent for outbound requests. Inside the lock, only the task that actually wins the fetch logs. In steady state the sole caller is the nightly forced run, so it is once a day. A test covers the flood case directly by holding the lock and asserting silence.The cost of this choice: if PyPI is unreachable, the failure backoff bounds the nag to once per ten minutes rather than once a day, and a fetch that never succeeds still logs. Both seemed better than the flood.
Verification
WARNINGlevel immediately before "Running Codex v2.3.1"; without it, nothing is logged anywhere.tests/test_latest_version_fetch.pycover the message contents, silence on every other install, the cold-cache flood guard, and the fresh-cache skip.make fix,make lintandmake tyclean.Notes for the reviewer
codex/util.pynow importscodex.settings, so it is no longer a leaf module. Nothing undercodex/settings/importscodex.util, so there is no cycle, and the settings module is fully loaded before any app imports util. Both live boots and the full suite confirm it.codex/views/version.pyalready pairs these same two imports.update depscommit (940ce1380), which was in the working tree when the branch was cut.uv lock --checkpasses, so dependency resolution is sound.make lint, both unnecessaryreportUnusedFunctionignores, intests/conftest.py:33andtests/test_onlinetag_snapshot.py:58. Neither is in a file this branch touches.🤖 Generated with Claude Code