A new MEGA sync starts without history, and other things I learned moving one

Moving a MEGAcmd sync to a new host turned every file that had changed since its last upload into a conflict. On top of that, half the account quota was old versions and the rubbish bin, the package installs its own apt source, and syncs are two-way only.

My NAS keeps an offsite copy of one share on a free 20 GB MEGA account. For a long time that was a small Docker container on an old host: Debian, the megacmd package, and an entrypoint that logs in and starts mega-sync. The old host is being retired, so the sync needed a new home. I expected an afternoon of packaging. The packaging was the easy part.

Choosing a host

I looked at three options. An rclone CronJob in the cluster was out, because I couldn’t confirm that rclone’s MEGA backend handles two-factor login. An LXC container on the hypervisor was out because its RAM was fully committed. That left a Raspberry Pi 3B+ with 905 MB of RAM and nothing else to do. A quick curl speed test against a public endpoint gave about 200 Mbit/s down and 140 up, plenty for this.

Since the container was just Debian plus one package, I installed MEGAcmd natively. MEGA ships arm64 .deb files for Debian 12 and 13. An Ansible role creates a system user, mounts the NAS share over NFS, and runs mega-cmd-server as a systemd unit. The login needs a one-time code, so it can’t run unattended; the role asks for it every time with ansible.builtin.pause and echo: false.

The package manages its own apt source

My role added MEGA’s apt repository with deb822_repository, installed megacmd, and the next apt run failed:

Conflicting values set for option Signed-By

The package’s post-install script writes its own /etc/apt/sources.list.d/megaio.sources, with its own key under /etc/apt/keyrings/. Two entries for the same URL with different keys is an error. I now use my entry only to bootstrap the first install and remove it afterwards, so the package’s own source is the only one.

Tags and roles don’t mix the way I assumed

The install phase should run without the code, so I gave it a tag. Running --tags install then ran the login tasks too, and stopped at the assert that the code was set. I had tagged the role at the playbook level, and with roles: those tags apply to every task in the role. Moving the tags into the role’s main.yml fixed it. One more trap: a set_fact that merges the role’s defaults has to be tagged always, or it’s skipped under --tags and every later task sees undefined variables.

Every changed file became a conflict

Before the new host logged in, the old container had to stop. Two syncs of the same folder on one account fight each other. Then I logged in on the new host, started the sync over the existing remote folder, and got twelve sync issues, all “conflicting copies”.

A new sync has no history. It doesn’t know which side changed since the last upload, so every file that differs locally from the cloud copy is a conflict, and MEGAcmd never resolves them on its own. In my case all twelve were in directories the old host had written to on its last day: Postgres data files, application logs, a Celery schedule database, a search index. None were in the export directory that’s the actual backup.

mega-sync-issues --detail --all --disable-path-collapse

That listing is the place to start. Here the fix was to retire the stale directories rather than resolve anything. A raw Postgres data directory on a cloud drive isn’t a usable backup anyway; the database dumps are.

The quota counts things you can’t see

The account showed 16.5 GB used of 25 GB, which seemed high. mega-df said the rubbish bin held 8.1 GB, but mega-du //bin said only 270 MB. The difference is old file versions. “Used storage” is the cloud drive, plus the rubbish bin, plus every previous version of every file.

Most of it sat in //bin/SyncDebris, which had one folder per day since the sync began, each holding the files the sync had replaced. Clearing it freed about 8 GB:

mega-rm -r -f "//bin/SyncDebris/*"

Usage went from 16.5 to 8.6 GB. mega-deleteversions --all would free another 7 GB or so of old versions. I haven’t run it yet, because those versions are the only history the backup has.

Sync is two-way, always

One thing I checked before trusting it: mega-sync in MEGAcmd 2.6 has no one-way mode. Deleting a file in the MEGA web interface deletes it from the NAS share too, so the NFS mount has to be read-write. The old container behaved the same way. I just hadn’t noticed. If you want an offsite copy that a mistake in the cloud can’t reach back into, this isn’t it on its own.

The server used about 450 MB of the Pi’s RAM during the initial scan of 5,669 files, and has been quiet since. Earlier, the old container had refused to start after a restart for a different reason, a lock that outlived its process on NFS.