Fix make mongodb failing to start from a clean checkout — Closes #113 - #116
Draft
conradbzura wants to merge 1 commit into
Draft
Fix make mongodb failing to start from a clean checkout — Closes #113#116conradbzura wants to merge 1 commit into
conradbzura wants to merge 1 commit into
Conversation
`make mongodb` could not bring up a working database from a fresh clone. Two independent defects, either fatal on its own. `ensureIndex` in scripts/create-indexes.js called `getIndexes()` to look for a conflicting index, which throws NamespaceNotFound (code 26) on a collection that has never been written to — the normal state of a database with no dump restored. `jobs` is the only collection routed through the helper, so it was the single index that aborted the run, and `set -e` in the startup script took the container down with it. Treat only NamespaceNotFound as "no index to conflict with" and fall through to `createIndex`, which creates the namespace. Any other server error still propagates, and the IndexOptionsConflict drop-and-recreate path is untouched: a collection with no indexes cannot produce a name match. Dockerfile.mongodb copied `database/` into the image, but that directory is gitignored (the 4DN dump was removed in 2fc98f8) so on a clean clone it does not exist and the build failed outright with `"/database": not found`. It only appeared to work where a stray file such as `.DS_Store` kept the directory alive. Create the directory in the image instead and mount the dump read-only at run time from the Makefile, guarding the restore on the mount being non-empty. The image no longer varies with what a developer happens to have on disk, and obtaining a dump later is a container restart rather than a rebuild. `set -e` is deliberately kept: it surfaced a real bug rather than causing one, and a failed restore of a dump that IS present should stop the container rather than leave a half-loaded database looking healthy. README's Docker Startup section claimed step 1 restores sample data and that `POST /sync` was optional. Both were false — correct them and record `database/` as the drop-in point for an optional dump. Closes #113
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
Make
make mongodbproduce a working database from a clean checkout. Two independent defects blocked it, and either one alone was fatal — the container either failed to build or exited 1 seconds after starting.The first is a latent build failure:
database/is gitignored, soCOPY database/ /data/database/fails outright on a fresh clone. This has been broken since2fc98f8removed the committed 4DN dump without updating the Dockerfile, and went unnoticed because a stray.DS_Storekept the directory alive on developer machines. Move the dump from a build-timeCOPYto a run-time read-only mount, which fixes the build and is the better shape regardless — the image no longer varies with what a developer has on disk, and obtaining a dump later costs a container restart rather than a rebuild.The second is the reported symptom:
ensureIndexin the index bootstrap callsgetIndexes(), which raisesNamespaceNotFoundrather than returning an empty list when the collection has never been written. Treat that specific error as "no existing index to conflict with" and fall through tocreateIndex, which creates the collection.Deliberately not changed:
set -ein the startup script, andmongorestore.set -esurfaced a real bug rather than causing one, and a failed restore of a dump that is present should stop the container rather than leave a half-loaded database looking healthy.mongorestorewas never at fault — it handled the dump-less directory correctly, logging0 document(s) restoredand exiting 0.Closes #113
Proposed changes
Stop baking the dump into the image
Replace
COPY database/ /data/database/withRUN mkdir -p /data/database, and mountdatabase/read-only at run time from themongodbMakefile target. The directory is still created inside the image somongorestorealways has a valid target — it exits 1 on a nonexistent path, which underset -ewould take the container down — and so running the image with no mount at all degrades to an empty database rather than a crash. The Makefile createsdatabase/locally so the mount source always exists and the drop-in point stays visible.Guard the restore on a dump actually being present
Branch on the directory being non-empty. An absent dump is the normal state of a clean checkout, so report it as such rather than leaving the reader to interpret
mongorestore's0 document(s) restoredtrace, which reads like a failure.Survive a namespace that does not exist
Wrap
getIndexes()in a try/catch that swallows onlyNamespaceNotFound(code 26) and rethrows everything else, so a genuine server error still aborts rather than silently producing a half-indexed database. TheIndexOptionsConflictdrop-and-recreate path is untouched and unreachable in the empty case — a collection with no indexes cannot produce a name match.Only
ensureIndexwas affected. Every barecreateIndexcall in the file is immune becausecreateIndexcreates the namespace implicitly, which is whyjobs— the soleensureIndexcaller — was the single collection that aborted the run.Correct the README
The Docker Startup block claimed step 1 restores sample data and that
POST /syncwas optional. Both are false: the database starts empty and/syncis how it gets data. The Makefile Targets table repeated the same claim and is corrected to match, so the two places state one fact in one voice.Test cases
No automated tests accompany this change, and the reason is worth stating rather than glossing: the defects live in a Dockerfile and a
mongoshbootstrap script, neither of which the Python suite executes.tests/test_indexes.pypins the operational index specs in lockstep betweenscripts/create-indexes.jsandsrc/cfdb/indexes.py, but it parses the specs rather than running the script against a server — which is precisely why aNamespaceNotFoundraised at run time was invisible to a green suite. Closing that gap needs a container-backed integration test and is larger than this fix.Verification was performed by hand against real containers:
database/directoryDockerfile.mongodbis built"/database": not founddatabase/make mongodbrunsNo dump at /data/database, thenAll indexes created successfullycfdb.jobsindexes are listedworkflow_key_active_uniqueandterminal_ttlensureIndexpath completesmongodump --gzipintodatabase/make mongodbruns2 document(s) restored, indexes still apply, docs are queryableThe Python suite was confirmed unchanged at 1112 passed, 91 deselected against
origin/master, andtests/test_indexes.pypasses 29/29. Ruff reports two findings, both pre-existing onmasterand in files this PR does not touch.