How to run borgmatic with launchd on macOS #293
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hi, Dan. I opened #265 a while back, and after much back and forth, I've landed on a working solution for running borgmatic on macOS (tested on 10.14.6).
The Problem
macOS has a security boundary that prevents applications and scripts from reading private data unless they've been granted "Full Disk Access" (FDA) in the Security preferences pane.
FDA is a bit of a black box. Even the developers don't understand how it works. FDA privileges can pass from one process to other processes that it spawns, but only if the parent process is a bundled application that resides in the Applications folder. It does not apply to scripts, even if they're compiled into binaries. It may not pass through
borgmatic
toborg
, but it's a right pain to troubleshoot because of the lack of logs.Because of all these opaque conditions, the solution I'm proposing may have more steps than are necessary. I've tried to eliminate variables one at a time to arrive at the minimum number of steps.
The Solution
run-borgmatic.sh
with simple contents:None
Run in background
/usr/local/Cellar/borgmatic/{VERSION}/libexec/bin/borgmatic
to the list of bundled files (platypus-adding-borgmatic.png)Borgmatic.app
- move this into/Applications
+
to add an application and select Borgmatic.app in/Applications
/usr/local/Caskroom/borgbackup/{VERSION}/borg-macosx64
, but I'm unsure if it's needed here. Try without it, and if it fails, add it./Library/LaunchDaemons/com.whatever.borgmatic.plist
from the contents of borgmatic.plist (I tried to attach this as a.txt
but Gitea won't let me.)Label
: unimportant. I generated this plist from Zerowidth. This label is used if you uselaunchctl start/stop
to kick off or kill the process manually.ProgramArguments
: Set this to the location of the app, but point it to theborgmatic
binary that was bundled into the app. The only part that needs to change is the app name (the part that ends in.app
) if the app was named something other thanborgmatic.app
.Standard(Out|Error)Path
: I'm writing out to/var/log/borgmatic.log
and rotating that file automatically w/ the rest of the macOS logfiles.StartCalendarInterval
: When the job should run. The main reason for usinglaunchd
overcron
is thatlaunchd
will run a process later if the start time has already passed, and it will do it exactly once. If my laptop is off for 3 days, and I turn it on at 10am on the 4th day,launchd
will run exactly one borgmatic job as soon as the machine boots up, even though 4 jobs were skipped.UserName
: if not root, borgmatic/borg will error on files that it can't copy.You've probably noticed that we don't actually use the script that we created. That's because launchd needs to call the actual binary inside the bundle, but Platypus builds bundles from scripts. We can still double-click the application to kick off a manual borgmatic run, but then you'll be running it as yourself, not as root.
There might be a better way to do this with a different bundler. It's voodoo. I thought that my previous method wasn't working because it wouldn't log anything to anywhere, but then I discovered that it was actually making backups. I don't know if those backups include restricted content. I prefer this method over the previous one because this method writes out to the logfile.
An awesome caveat here is that if
borgmatic
is updated, the app has to be re-bundled with the new binary, and that may also require removing and re-adding it to the FDA section in Security Preferences. FDA tends to respond poorly to things changing after they've been granted permission.Wow, thanks for figuring out this process and writing it up! Super obnoxious though that you have to go through this to give borgmatic full disk access on macOS. I think our best bet at this point is to link to your series of steps from the borgmatic docs, unless you have other ideas.
Side note:
.txt
file uploads may be permitted now. (Gitea config change.)You're welcome, and yes, it's frustrating. :) Feel free to link the docs to this issue (and close it), and if I come up with a better way, I'll let you know.
I've linked to this ticket from the docs! Thanks again for the investigation and write-up.
Hi,
Thanks for the write up! Unfortunately this doesn't work for me... I still get the feared:
[Errno 2] No such file or directory: 'borg'
I have added both the platypus binary and the borg binary (in my case located in /usr/local/bin/borg) to FDA, but no luck. It's a shame that Apple make it so hard to use our computers however we want. No luck with cron either.
One minor thing, since the user we execute is root, I had the create a config file in
/etc/borgmatic/config.yaml
. It couldn't find one otherwise.EDIT: I'll have to give Vorta a try.
Same as @Fackelmann – getting no such file for
borg
despite having bundled (from/usr/local/bin
, there’s no such path as described in the tutorial after brew’ing it in my system).I will also resort to Vorta, but I wanted to backup more than just the user folder, and Vorta apparently doesn’t even run as root, so it’s not a solution to the FDA problem this scheme is trying to solve. I even considered triggering borgmatic via ssh from the remote borg server (doing an ssh round-trip), just to be able to use cron in a sane system—but then of course you lose the benefit of anacron-like behaviour, unless you reinvent anacron over ssh.
I'm not a macOS user and so it's entirely possible I don't know what I'm talking about here, but have you tried setting the
local_path
configuration option in borgmatic to the full path of your Borg binary? Example:@witten That’s a good idea. I don’t know anything about this OS either. The questions are, can you access commands in the root fs from ‘inside’ the Native Mac Application Bundle? And if you can, will the FDA thing ‘pass’ to the borg script?
I will try it for science when I have access to that hellish maschine again.
It is very frustrating and behaves contrary to logic. I've actually stopped using borgmatic on my Macs because, while I trust borgmatic implicitly, I don't trust MacOS permissions allowing a restore to happen. Catalina has the whole read-only rootfs with overlayfs mounts to subdirectories...I just went back to Time Machine.
I'm not sure why this works, but another solution is to add
/bin/bash
to the list of apps that get full disk access.Hello all, i saw this referenced from the Docs, so i thought it might be useful to mention, the way i do this;
Create a LaunchDaemon with the LaunchControl app, and then my script uses fdautil, creates an APFS snapshot of the whole drive, and then runs the backup with Borgmatic.
Here's a script that should give an overview of how to do it, it needs to be adjusted for Borgmatic of course: https://gist.github.com/QuantumGhost/1aae8eb8527c9d522fe2a57f214f6ee5