Description
Issue
When updating bridge configs, the new config is written to a temp file and then replaces the existing file using os.Rename
here:
go-util/configupgrade/upgrade.go
Line 153 in fc01e95
This is a very safe approach because renaming is atomic, so chances of loosing the config are minimal.
Unfortunately, it does not work when the config is a mounted file in a docker container like in this example:
whatsapp-bridge:
image: dock.mau.dev/mautrix/whatsapp:latest
volumes:
- ./config/whatsapp.yaml:/data/config.yaml
It produces an error like this:
Error updating config: failed to override current config with temp file: rename ./mautrix-config-1962078080.yaml config.yaml: device or resource busy
Replacing the file does not work in this scenario, but truncating and writing would work. But it would no longer be atomic.
Solution proposal
If the replace fails with device or resource busy
, could we fall back and try truncating and writing? This would increase the risk of loosing the config value, but it's still very minimal because we only copy from a temp file so the generation is already done, and we would only do this after os.Rename
had failed as a fallback.
If necessary, we could even copy the original config into a backup before truncating, and then attempt to restore if writing the new config fails (although this seems overkill and likely not helpful, because writing back the backup will likely also fail).
Or we could make this an opt-in config option in the bridge.
Does this sound reasonable? I would be willing to provide a PR. Thank you for providing these awesome bridges!