NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.15k stars 13.42k forks source link

borgmatic: allow running under different users #275323

Open Deric-W opened 8 months ago

Deric-W commented 8 months ago

Hello, I have a small Nextcloud instance which gets backed up regularly (database and files) by a custom script using borgbackup which runs under the same user as the Nextcloud to not break Postgres socket authentication and increase security by not running as root.

I was looking into replacing my custom backup script with borgmatic and noticed that there seems to be no options to allow running specific configurations as a different user.

I thought that implementing options similar to services.borgbackup.jobs would be possible by generating separate configuration directories for each job and using the --config command line option of borgmatic.

If there is interest in this feature by @imlonghao I would be willing to work on a implementation.

imlonghao commented 8 months ago

Indeed, currently borgmatic service is running as root, but it seems to be difficult to add support for running as a custom user.

Now we have services.borgmatic.settings for /etc/borgmatic/config.yaml and services.borgmatic.configurations.<name> for /etc/borgmatic.d/<name>.yaml. When the borgmatic service runs, it runs both of them, due to the per-application backups

Are you going to introduce another one, for example, services.borgmatic.jobs.<name>?

Doesn't it seem too duplicated? For one service, we have three-way to write the config, two the official way, one the Nix way.

Deric-W commented 8 months ago

You are right, there is duplication between the different configuration options.

Since the current options can be seen as a subset of services.borgmatic.jobs.<name> they could be implemented by by having an automatic "default" job when they are used (they could also be deprecated and removed).

If you think that this is not a good idea then I am fine with writing a custom systemd service for my use case but having something like services.borgmatic.jobs.<name> would make it easier for other users encountering the same problem.

jmickelin commented 2 weeks ago

For one service, we have three-way to write the config, two the official way, one the Nix way.

Note that the third way with the various --config profiles is also suggested "officially" in a sense:

If you need even more customizability, you can specify alternate configuration paths on the command-line with borgmatic's --config flag. (See borgmatic --help for more information.) For instance, if you want to schedule your various borgmatic backups to run at different times, you'll need multiple entries in your scheduling software of choice, each entry using borgmatic's --config flag instead of relying on /etc/borgmatic.d.

(https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/)


For what it's worth, for the sake of just a single configuration, customizing the user isn't particularly cumbersome at all IMHO.

Since the borgmatic service is triggered using a systemd timer, so you can use the plumbing that NixOS already provides for creating drop-in overrides for the corresponding unit files to tweak certain things not exposed by the NixOS module:

{
  services.borgmatic = {
    enable = true;
    ...
  };

  systemd.services.borgmatic = {
    serviceConfig = {
      User = "myuser";
      Group = "mygroup";
    };
  };

  systemd.timers.borgmatic = {
    timerConfig = {
      OnCalendar = "Fri *-*-* 18:00:00";
      WakeSystem = "true";
    };
  };
}

All that is really needed to extend this to work with multiple profiles would be the ability to generate multiple .service and .timer files. What if each services.borgmatic.configurations.<name> had an optional attribute profile, which caused the corresponding config to be written to e.g. /etc/borgmatic-<profile>.d/<name>.yaml, and then the systemd unit files could be "templatized" to take the profile name as an argument (e.g. borgmatic@nextcloud.service)?

This would avoid introducing a duplicate hierarchy of options, instead just reusing the existing services.borgmatic.settings and services.borgmatic.configurations.<name> ones. Drop-in overrides like above then let you create overrides per-profile (systemd.services."borgmatic@nextcloud") and globally (systemd.services."borgmatic@"), essentially for free.