garethgeorge / backrest

Backrest is a web UI and orchestrator for restic backup.
GNU General Public License v3.0
1.04k stars 34 forks source link

Add hook suitable for mounting/unmounting drives #227

Open eknoes opened 4 months ago

eknoes commented 4 months ago

Is your feature request related to a problem? Please describe. I store my backup on a physical USB hard drive. Currently, it is permanently mounted, which keeps the HDD running for ~30 minutes, after going into some standby mode. I would like to unmount it right after the backup.

I tried using the snapshot start hook of the repository, but it seems like that one is already "too late", as my backup fails because the repository is not mounted. The mounting on snapshot start works, but after the backup (and unmount) "forget" has the following error:

error: forget: get snapshots for repo ExternalHDD: command "/home/XXX/.local/share/backrest/restic-0.16.4 forget --json --keep-hourly 24 --keep-daily 7 --keep-weekly 4 --keep-monthly 3 -o sftp.args=-oBatchMode=yes --tag plan:SystemBackup --group-by tag" failed: exit status 1
Process STDOUT: 
Fatal: unable to open config file: stat /mnt/backup/config: no such file or directory

Describe the solution you'd like I'd like to have pre-backup anda post-backup hook that is suitable for unmounting the hard drive.

garethgeorge commented 4 months ago

Interesting -- this is a bit of an oversight on my part. I had intended the backup start and stop hooks to work for this type of application but (obviously in retrospect) you need a hook that applies to every operation that does work on the repo if you're actually storing the repo on an external drive.

Two ways I can see solving this

In either case, it's also true that backrest runs multiple tasks that are generally unaware of one another (and trigger their own hooks) in a backup flow. E.g. CONDITION_OPERATION_(START|END) will be triggered in quick succession by the backup task, the forget task, and the index snapshots task in a given scheduled execution of a plan.

Do you have ideas how you might debounce the events (or apply a timeout?)? Or more broadly what UX you'd want to make the hooks most usable

edit: thought about this a bit more today, I think the right way to handle this will be to introduce a CONDITION_REPO_MOUNT and CONDITION_REPO_UNMOUNT hook where backrest handles timeout / indicates when it's safe to essentially run setup or unmount the repo.

eknoes commented 4 months ago

edit: thought about this a bit more today, I think the right way to handle this will be to introduce a CONDITION_REPO_MOUNT and CONDITION_REPO_UNMOUNT hook where backrest handles timeout / indicates when it's safe to essentially run setup or unmount the repo.

That sounds good!

I am not so familiar with how backrest works, but I guess some hook that always runs when opening / closing the repo would be the best! But I also think these operations are not that costly compared to the backup operation. So if its not so easy to ensure all operations run in between the hooks, it would be also fine if the hooks run multiple times (E.g. Mount -> Backup -> Unmount -> Mount -> Forget -> Unmount -> Mount -> Index -> Unmount).

tdehaeze commented 4 months ago

I would also be interested by such options. However my use case is a bit different. I would like to poweroff the machine on which I store the backups when the backup is finished. I therefore put "ssh backup-machine sudo systemctl poweroff" in the "CONDITION_SNAPSHOT_END" hook. But in that case the "forget" operation fails as the machine is powered off. (I turn ON the machine every day just before the backup). Therefore, I would need an hook operation that happens after the "forget" operation.

Overall, I think that having more options in the "hook" section would be very nice for many people. Cheers

rikroe commented 1 month ago

I've build myself a hook like this to backup an external SSD. Basically it checks if the external drive is available and will cancel otherwise. You might try to adjust this and actually mount a device if not available.

image

hefistion commented 2 weeks ago

I can use CONDITION_RESTIC_START to mount the external USB drive and CONDITION_RESTIC_ENDto unmount it, but since it does a forget after each snapshot, and since CONDITION_RESTIC_END unmounts the drive, I get an error because it doesn't find the repository. It would be interesting to add some option that allows controlling when forget ends.

garethgeorge commented 2 weeks ago

This is something I still need to look at, part of my hesitancy to take action on this bug is that I'm concerned any solutions here won't be very robust. Running a mount and unmount command before / after each operation is likely to mount and unmount your drive rapidly in sequence as Backrest runs restic commands on your behalf.

Something a bit more clever feels like it might be needed.

hefistion commented 1 week ago

I understand, maybe some option that allows running a post backup script?