-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tarsnap-service: add persistent option for systemd timer #8823
Conversation
|
||
path = [ pkgs.tarsnap pkgs.coreutils ]; | ||
path = [ pkgs.tarsnap pkgs.coreutils pkgs.iputils ]; | ||
preStart = "/run/current-system/sw/bin/sh -c 'while ! ping -q -c 1 betatest-server.tarsnap.com &> /dev/null; do true; done'"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this hack?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this, running the service when offline or when the tarsnap server is otherwise unavailable might count as having performed a backup (just guessing here).
I dislike this. I prefer using after/requires network-online.target and leave it at that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To add to this: for persistent timers, it seems systemd only keeps track of whether the service was triggered, not whether it completed successfully. For backups, I suppose the latter is what we actually want ... I'm not quite sure if this hack even accomplishes this, though (i.e, whether systemd waits until the main process starts before counting the service as "triggered").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I wish the network-online.target stuff was enough but it doesn't seem to be and I'm not exactly sure why. The docs seem to suggest that network-online.target should simply work as is or you can use something like NetworkManager-wait-online.service/system-networkd-wait-online.service to force the network.target to wait until the network is online (like network-online.target is suppose to do) which is overkill/overreaching to enable. Now systemd.networkd-wait-online.service had a change about a year ago which removed the before requirement on network.target, so that would seem to suggest that enabling that service might actually make network-online.target work correctly now without requiring everything with dependencies on network.target to wait as well (didn't actually test this). The NetworkManager service still has a before requirement on network.target. We have our own thing for NetworkManager which triggers network-online.target when an interface comes up (which I don't know what exactly NetworkManager's definition of "up" is). Ultimately, if we have to enable a special service to get network-online.target to work for each possible network management system we support, some of them don't provide a built in facility for this waiting stuff (NetworkManager and systemd-networkd ship units to do this but seem to differ in their actual effect on the boot process as mentioned above) and they differ in their definition of what "online" means, then the persistent option is only going to work if users are using some limited set of network management systems and be broken (in the sense that tarsnap will bail out every time) otherwise.
The PreStart hack ensures that the tarsnap only starts when we can actually reach out to the tarsnap server -- regardless of what is managing the network configuration -- since otherwise there's no point in performing a backup. Note, there is a timeout for starting a service (90s by default) so it is not going to sit there forever pinging away. The unit will just fail if we can't connect to the server after 90s, so if the system is extremely slow booting/waking up or the system is extremely slow getting a network connection, then the unit will fail even though it might have worked in a few minutes. We can of course tweak this with TimeoutStartSec in the service file and we could expose this to be configurable by the user if we think it needs to be. Definitely another downside to the PreStart thing, but it hasn't hit me in the year I've been doing it.
I'm happy to explore other options, I'm not very fond of the PreStart thing either, but it's the easiest way I know how to ensure that it works for nearly all cases. If we could get all our network stuff to agree on what network-online.target means, whether that is "I have an IP" or "I can connect to some arbitrary location" or something else, then we might have a clearer way forward, but I suspect they will probably not all mean "I can connect to the internet" since that is a fairly broad definition of "online". Thus, we are probably still going to need something which delays execution until we know that yes, the network is up/"online" and we've at least tried to connect to the outside world before failing.
And yes, persistent timers just track the last time the service was triggered (i.e., the whole service was asked to start, so regardless of it starts successfully or not) not the last time it completed successfully, which is fine for my uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am unaffected by the backup-will-eventually-succeed-but-not-right-now problem and failed to consider it, but I can see how preStart might be warranted, esp. for people who backup rarely and so could end up not backing up for a long time if the service is triggered at bootup. It is unfortunate that network-online.target is underspecified on NixOS, but that seems to be a more general problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that doing sh -c ...
in preStart
is unnecessary.
@@ -258,12 +272,13 @@ in | |||
serviceConfig = { | |||
IOSchedulingClass = "idle"; | |||
NoNewPrivileges = "true"; | |||
CapabilityBoundingSet = "CAP_DAC_READ_SEARCH"; | |||
CapabilityBoundingSet = "CAP_DAC_READ_SEARCH CAP_NET_RAW"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do away with this if you set PermissionsStartOnly = true
; then, restrictions only apply to the process launched by ExecStart
.
This is very useful for things like daily backups on a laptop (or any not constantly running system) since one generally want them to happen every day the system is awake regardless of if the machine was awake *at the exact trigger time*. In order for this to work reliably, we wait until we are sure we can connect to the server before backing up.
4f84786
to
94c4fd3
Compare
Made the couple of changes suggested by @joachifm. |
|
||
path = [ pkgs.tarsnap pkgs.coreutils ]; | ||
path = [ pkgs.tarsnap pkgs.coreutils pkgs.iputils ]; | ||
preStart = "while ! ping -q -c 1 betatest-server.tarsnap.com &> /dev/null; do true; done"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
betatest-server
? What's that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot check right now, but I believe tarsnap itself uses betatest-server.tarsnap.com to test network connectivity. I think the proposed patch basically replicates what tarsnap does on network resolution failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
betatest-server.tarsnap.com
is the address the tarsnap client connects to, i.e, it's where the tarsnap server code is running. Why it still carries the name betatest
after all these years is unknown to me (^_^).
The goal here is to wait until we can connect to the server so that tarsnap doesn't run and just die because it couldn't connect to the server when it could have connected successfully a few seconds later (after the network has finished setting up).
Is there actually a reason to make this an option? Maybe just set |
Sorry for taking so long with this, it looks good to me, and I'll need it for my current laptop. :) I'm cleaning this up and pushing a modified version shortly - thank you for this! |
cool, thank you @thoughtpolice |
This is very useful for things like daily backups on a laptop (or any
not constantly running system) since one generally want them to happen
every day the system is awake regardless of if the machine was awake at
the exact trigger time. In order for this to work reliably, we wait
until we are sure we can connect to the server before backing up.