Fix#6458 completely: the reporter's host runs inside a hypervisor that
masks AVX, and the old per-tool AVX wrappers (amd64-only, PATH-based)
were bypassed by absolute-path mongod invocations.
- New general snap-src/bin/cpu-exec: runs any binary directly when the
CPU has the features it declares (--features x86_64=avx,aarch64=atomics
or WEKAN_REQUIRED_CPU_FEATURES) and through same-arch qemu-user when
not; plain zero-overhead exec with no declared features. Lookup order:
WEKAN_QEMU_USER, qemu-<arch> next to the script (bundle/Docker),
$SNAP/qemu-<arch>, the snap's migratemongo/avx one, then system
qemu-user(-static). Clear error + direct run when no qemu exists, so
the real SIGILL surfaces instead of hiding.
- Snap: mongodb-control and migration-control run every mongod 7 through
cpu-exec, so MongoDB works without AVX (slower) and migration can READ
modern MongoDB data on such CPUs; completed-FerretDB switch and
migration fallbacks unchanged (switch_to_completed_ferretdb extracted).
- release-all.yml: every Linux bundle .zip ships cpu-exec + this-arch's
static qemu-user (amd64/arm64/ppc64le/s390x/riscv64; stripped from
win64/mac bundles), flowing into Docker and Snap automatically;
Sandstorm .spk gets both via build-deps.sh. Bundle launcher and Docker
entrypoint route node/ferretdb through cpu-exec.
- Docs: mongodb-avx-qemu.md and mongodb-raspi4-qemu.md document the
built-in mechanism.
Tests, with negative cases, for the newest features and fixes at
changelog: htmljs array-vs-attributes (#6459), description draft
normalize/reset (#6455), comment draft lifecycle (#5547), attachment
delete guard (#5282), rules move actions + import normalization (#6472),
snap mongod-failure/migration recovery (#6458#6466), FerretDB polling
defaults (#6467#6468), UI density guards for every #6465 fix, and a
behavioral cpu-exec test against fake cpuinfo + fake qemu. All wired
into test:unit:node. Go table tests for the FerretDB SQLite filter
pushdown are in the wekan/FerretDB repo.
Updated ChangeLog.
Thanks to xet7.
- #6459: card More menu rendered empty (no Delete): the vendored jade
compiler's htmljs patch made isConstructedObject(Array) false, so
'label {{_ ...}}:' lines got their content array mis-assigned as tag
attributes and Blaze threw 'foreign objects in attributes' killing the
whole cardMorePopup. Also fixed the list More link input (nonexistent
rootUrl helper -> absoluteUrl).
- #6455: saving a card description never removed a pre-existing unsaved-
edits record, and the draft/description comparison mismatched on Markdown
hard-breaks and empty descriptions, re-creating a phantom draft on every
save. Save now clears the draft; both sides normalized the same way.
- #5547: comment drafts: the draft-saving escape handler had been disarmed
since 2019 (flag with no setter), so a comment being written was lost
when the card closed. Drafts are now saved continuously (debounced),
flushed on teardown, cleared on submit; text no longer visually vanishes
on outside clicks.
- #5282: attachment delete: guard against the doc being already evicted
from Minimongo ('Removed nonexistent document'), like the existing
comment/checklist guards.
- #6472: rules move card to top/bottom: fall back to the card's current
list when listName does not resolve (was a swallowed TypeError = rule
silently did nothing); wizard stored listTitle which the engine never
reads (listName); empty destination wrote sort +-Infinity; rules JSON/CSV
import now uses the rules.createRule method instead of client inserts
rejected into minimongo limbo, and defaults missing trigger matching
fields to '*'; empty boardId no longer overrides the real board; the
server-side orphaned-cards fallback in List.cards()/cardsUnfiltered()
now actually resolves its async swimlane lookup.
- #6465: desktop density back to WeKan 6.09: base font 14px and headings
22/18/16px (vw clamps resolved to 18/24px on desktop), All Boards
wrapper padding 10px/15px, card details docks to the right edge instead
of floating on top of its own card (still draggable), 20px canvas
padding instead of ~48px white borders, removed the force-all-card-text-
to-title-size rule, admin org/team table Select/Unselect-all header
links are compact icons and header cells may wrap, zoom pill no longer
cut off, one-click board settings cog in the board header.
- #6458#6466: snap: mongodb-control now checks mongod's exit status and
does an AVX pre-flight (MongoDB 5+ needs AVX; without it mongod SIGILLs)
instead of pinging a dead port forever behind a 502: it switches to a
completed FerretDB migration, or (re)runs the migration (AVX-free) with
a 3-attempt guard. Migration importers no longer fail the whole run on
>=10 per-item errors ('Avatars Errors' etc.), and a failed 3.x-source
migration keeps the copied FerretDB data + checkpoint and resumes next
start instead of deleting it and 'falling back' to a mongod 7 that
cannot open 3.x data files.
- #6467#6468: with FerretDB, calm Meteor's no-oplog polling storm
(METEOR_POLLING_THROTTLE_MS=2000, METEOR_POLLING_INTERVAL_MS=30000
defaults in the snap and bundle launcher; overridable). The FerretDB
fork gets filter pushdown, a sane pool size and less locking in its own
repo.
- Updated ChangeLog.
Thanks to xet7.
Problem: the control scripts force-switched to FerretDB whenever a *.sqlite file existed, so
`snap set wekan database=mongodb` did not stick and a failed migration caused downtime with no
way to keep WeKan running on MongoDB while fixing it.
- The `database` snap setting is now AUTHORITATIVE. Removed the "FerretDB SQLite present ->
force ferretdb / disable mongodb" overrides from wekan-control, ferretdb-control and
mongodb-control. wekan-control keeps only the safety guard (never start an EMPTY FerretDB
while MongoDB has data).
- New `snap run wekan.database mongodb|ferretdb` command (bin/wekan-database): switch which
database WeKan runs on. `mongodb` also pauses auto-migration (migrate=off) so it does not
switch back; `ferretdb` requires a non-empty SQLite first.
- Auto-migration can be paused: migration-pending now also returns "not pending" when
`snap get migrate` == off. A migration that FAILS now runs fail_and_run_mongodb: delete the
partial SQLite, set migrate=off, and exec mongodb-control so WeKan keeps working on MongoDB
(no downtime, no retry loop). fall_back_to_mongodb likewise sets migrate=off instead of the
done marker. `snap run wekan.migrate` re-enables migrate and retries.
- finish_success now restarts wekan.wekan so it reconnects to FerretDB after a successful
migration instead of waiting for the now-stopped MongoDB.
Registered the `database` app in snapcraft.yaml and snapcraft-core26.yaml (also added the
previously-missing migrate/maintenance apps to core26).
Thanks to xet7.
For unattended upgrades at scale (6.09/MongoDB 3.2 -> 9.x/FerretDB across many servers), the
"did the migration succeed?" test must not be fooled by a 0-byte stub file.
- New shared helper snap-src/bin/ferretdb-has-data: exit 0 only if a *.sqlite file bigger than
0 bytes exists in files/db. Used by mongodb-control, ferretdb-control and wekan-control in
place of the previous "*.sqlite exists" glob, so the DB decision is based on a real,
non-empty FerretDB database. (Deliberately does NOT require the -wal file, which SQLite may
checkpoint away when FerretDB is stopped - that would cause false negatives at startup.)
- migration-control finish_success now verifies the non-empty SQLite database exists (and logs
the WAL/shm sidecars) BEFORE switching the snap to FerretDB. If the importer returns success
but wrote no data, it does not switch or set the done marker - MongoDB data is kept and the
migration retries on the next start.
Thanks to xet7.
wekan.migrate (bin/wekan-force-migrate): force a fresh MongoDB -> FerretDB migration,
ignoring the database setting and the migration marker. Removes any partial FerretDB SQLite +
resume checkpoint, sets database=mongodb, and starts wekan.mongodb so migration-control
re-reads the existing MongoDB (3 or 7) data and migrates again. Source MongoDB data untouched.
wekan.maintenance on|off (bin/wekan-maintenance): toggles a $SNAP_COMMON/.wekan-maintenance
marker. While present, mongodb-control / ferretdb-control do NOT auto-migrate or auto-disable,
so `snap start wekan.mongodb` or `snap start wekan.ferretdb` stays up and you can reach the
data over the MongoDB wire protocol on port 27019 (one at a time - they share the port).
Maintenance page (bin/wekan-maintenance-page.mjs): in maintenance mode wekan-control execs
this instead of WeKan; it serves an "under maintenance" page (HTTP 503) on the web port for
ALL URLs. It shows the Admin Panel product name if set (not "WeKan"), read from
$SNAP_COMMON/.productname.txt, which is cached while a database is running by wekan-control
(new db-eval `product-name` command) and by both migration importers - so it is available even
when both databases are stopped.
Registered `migrate` and `maintenance` apps in snapcraft.yaml.
Thanks to xet7.
Regression fix. An earlier change made mongodb-control/ferretdb-control/wekan-control key
the "use FerretDB / disable MongoDB" decision off the .migration-to-ferretdb-done marker.
But migration-control ALSO writes that marker when the migration falls back (data
unreadable, tools missing) or when there is nothing to migrate - producing NO FerretDB
data. So on a server whose MongoDB 7 -> FerretDB migration failed:
- mongodb-control saw the marker -> "migration already finished; disabling mongodb
service" -> disabled MongoDB;
- FerretDB SQLite (files/db) was EMPTY;
- database=mongodb, so wekan-control waited on MongoDB -> "MongoDB not ready yet,
retrying in 5 seconds..." forever, and wekan.mongodb refused to stay up.
Now all three scripts decide from ACTUAL DATA ON DISK: MongoDB is disabled / FerretDB is
forced ONLY when a *.sqlite database exists in files/db. An empty files/db means the
migration did not succeed, so mongod starts normally and WeKan keeps working (and the
migration can be retried). The marker still prevents re-running a finished migration.
Thanks to xet7.
Symptom: WeKan never started, looping "MongoDB not ready yet, retrying in 5 seconds..."
forever, even though mongod appeared to be running.
Cause: mongodb-control started mongod with a HARDCODED --wiredTigerCacheSizeGB 32. On any
server with less than ~34 GB RAM, mongod was OOM-killed seconds after startup. That
included the temporary mongod started to initialise the replica set: it died before
db-eval could reach it (log showed "child process started successfully" then 30 s of
failed pings), so the replica set was never initiated. The final mongod then ran with
--replSet rs0 but no config, no PRIMARY was elected, and wekan-control (which needs the
replica-set primary for Meteor change streams) waited forever.
Fixes in mongodb-control:
- WiredTiger cache is now RAM-aware: ~50% of (MemTotal - 1 GB), the same formula mongod
uses for its own default, capped at 32 GB, min 1 GB. Override with
MONGODB_WIREDTIGER_CACHE_GB. Applied to both the temp replica-set-check mongod and the
final mongod.
- Temporary-mongod readiness wait raised 30 s -> 90 s so a large database that needs
longer to replay its journal still gets its replica set initialised/reconfigured.
Fix in migration-control:
- The temporary source mongod started to READ the data during a MongoDB -> FerretDB
migration now uses a conservative RAM-aware cache (1/4 of (MemTotal - 1 GB), cap 8 GB,
override MIGRATION_MONGOD_CACHE_GB), leaving room for the target FerretDB and the Node
importer that run alongside it. Applied only to the mongod 7 (WiredTiger-only) read so
the flag can never clash with a legacy MMAPv1 MongoDB 3.x dbpath.
Thanks to xet7.
Symptom: on an already-migrated install, `sudo snap start --enable wekan.ferretdb`
started FerretDB and then it immediately stopped itself, logging:
"database is 'mongodb', not 'ferretdb'. Disabling ferretdb service."
Cause: every DB service keyed its behaviour off the `database` snap setting alone. If
that setting was never flipped to ferretdb (e.g. the migration's INTERNAL `snapctl set`
did not re-run the configure hook), ferretdb-control read `database=mongodb` and disabled
itself, so FerretDB could not be started by hand without first running
`snap set wekan database=ferretdb`.
Fix: the marker $SNAP_COMMON/.migration-to-ferretdb-done is now authoritative.
- ferretdb-control: if the marker exists, repair database=ferretdb and keep running
instead of self-disabling.
- mongodb-control: if the marker exists, repair database=ferretdb and disable mongodb,
BEFORE the migration-pending check so a finished migration is never re-attempted.
- wekan-control: already forces ferretdb on the marker (previous commit).
Immediate recovery on an already-migrated install running an older release:
sudo snap set wekan database=ferretdb
Thanks to xet7.
Databases / MongoDB clients:
- Remove the mongosh binary everywhere (snap + bundles). All scripted DB access
(readiness ping, replica-set initiate/status, v8.43 schema migration) now runs
through the new snap-src/bin/db-eval (bundled Node.js 24 + the mongodb driver).
Ports wekan-control, mongodb-control, migration-control, start-wekan.sh/.bat and
migrate-schema-v843.js -> .mjs off mongosh. The legacy MongoDB 3.2 mongo shell
(migratemongo, amd64) stays for migration-time reads only.
- MongoDB Database Tools now come from the wekan/mongo-tools fork (pure Go, every
arch) instead of mongodb.com, in snapcraft and the Windows bundle. version.sh /
test-download-urls.sh no longer probe mongodb.com for mongosh/tools. The MongoDB 7
server (mongod) is still fetched from MongoDB (amd64/arm64 only).
- FerretDB v1 downloaded per-arch (ferretdb-<arch>) from wekan/FerretDB, no
ferretdb.zip: release-all.yml bundle jobs, docker-compose.yml, sandstorm build.
Snap:
- Default snapcraft.yaml is now the core24 grade:stable build (core26 variant kept
as snapcraft-core26.yaml); release publishes to candidate + edge.
- Add s390x, ppc64el, riscv64 platforms as FerretDB-only (mongod not built there);
new installs default to FerretDB v1 (snap/hooks/install already guards existing
MongoDB data), DDP_TRANSPORT=sockjs. Fix Caddy ppc64el->ppc64le mapping.
Docs: add docs/Platforms/FOSS/Snap/CPU-platforms.md; update CHANGELOG and the
Sandstorm migration doc.
On first boot after upgrading an old MongoDB-based WeKan snap, mongodb-control now
hands off to a new migration-control before starting mongod:
- Detects existing MongoDB data in $SNAP_COMMON and opens it with the right
bundled mongod: mongod 7 for MongoDB 7 data (all arches, including the arm64
snaps already on newest WeKan), or a bundled old mongod 3.2 (amd64 only, new
mongodb-old part) for WeKan 6.09 / MongoDB 3.2 data.
- Starts a temporary FerretDB v1 (SQLite) and runs migrate-mongodb-to-ferretdb.mjs,
which migrates text data to FerretDB and BOTH CollectionFS GridFS and
Meteor-Files GridFS attachments+avatars to the filesystem, shows a live progress
counter at ROOT_URL, checkpoints to $SNAP_COMMON (resumable), and compacts the
old MongoDB when done.
- On success switches the snap to database=ferretdb.
Idempotent (migration-pending helper + completion marker), resumable, never
deletes the source MongoDB data, only switches on success. The migrator is bundled
into the snap (/bin). Progress dashboard title fixed to 'MongoDB -> FerretDB'.
NOT yet tested end-to-end against a real 6.09 snap; in particular the 2016 mongod
3.2 binary may need extra runtime libraries on a modern base (amd64 6.09 path).
The arm64/MongoDB-7 path uses the already-bundled mongod 7.
Thanks to xet7.
Adds a 'database' snap setting (mongodb|ferretdb). A new ferretdb service runs
FerretDB v1 (SQLite) on the same port MongoDB would use; only one database runs
at a time. The configure hook flips the two services when the setting changes,
mongodb-control disables itself when ferretdb is selected, and wekan-control
drops MONGO_OPLOG_URL for FerretDB (which has no replica-set oplog, so WeKan
uses polling) and waits on a plain ping instead of rs.status().
The FerretDB binary ships inside the WeKan bundle the wekan part already
downloads, so no extra build is needed. New installs default to FerretDB on all
platforms via the install hook (fresh installs only; upgrades keep MongoDB, and
a pre-existing MongoDB data dir is detected and kept). Switch with
'snap set wekan database=mongodb'.
mongosh collects anonymized usage analytics by default and the snap invokes it
several times; disable it (writable HOME + disableTelemetry) so nothing phones
home. mongod itself has no phone-home telemetry (Free Monitoring is opt-in).
Thanks to xet7.