calibre: Remove existing data directory before a restore operation

Fixes: #2500.

systemd 257 has introduced in which DynamicUser= services will use id-mapped
mounts[1] instead of performing chown on the entire data directory. On Debian
stable release, calibre service will contain data folders with a dynamic user
ownership while on testing release, calibre service will contain data folders
with nobody:nogroup ownership.

When a backup from stable release is restored on testing release, the two
directories are merged. The top level directory will be still owned by
nobody:nogroup while the files instead will be owned by dynamic user and group.
In this case, systemd will not recursively update the ownership. Calibre will
fail to access the library files.

The fix is to completely wipe the existing data folder before a restore. When
systemd notices that the directory ownership is not properly it will recursively
change the ownership before starting the service.

Links:

1) https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=

Tests:

- Without patch, restore the app on testing from a backup on stable machine and
notice that the data folder is owned by nobody:nogroup but files inside are
owned by a calibre-server-freedombox user and group. This leads to failure when
accessing the library.

- With patch, restore again notice that the library is accessible and all the
files are owned by nobody:nogroup.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2025-03-26 20:07:14 -07:00 committed by James Valleroy
parent ac8dbcfc1c
commit e64270ebc3
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -14,7 +14,8 @@ backup = {
'data': {
'directories': ['/var/lib/private/calibre-server-freedombox/']
},
'services': ['calibre-server-freedombox']
'services': ['calibre-server-freedombox'],
'delete_before_restore': ['/var/lib/private/calibre-server-freedombox/']
}
tags = [_('Ebook'), _('Library'), _('Ebook reader')]