Hi everyone I’m currently in the process to move one of my RPI4s from RaspberryOS to NixOS and I’m struggling to setup one of the services.

On the RPI I have a python script that is creating offsite backups via a Wireguard tunnel:

  • Open the wg tunnel
  • mount and encrypt the external disk on the offsite RPI
  • mount the source from my nas
  • start the restic-rest server container offsite
  • trigger the restic command to backup to the restic repo

allthough it’s a bit overkill it works quite well for a few years now. Since most of the tasks are actually outsourced to systemd units those where quite easy to setup in nixOS. What I’m struggling is, how can I create a virtual python env to run the python script. All the guides I found for managing python dependencies are usually for development and use nix shell

My current workaround is, that I copy the script and requirements.txt from my script repo and create the venv manually. This does work, but I feel there is a better way, maybe the whole setup is already on the wrong pat as I tried to solve each hurdle separately?

Here’s my current implementation of the remotebackup module (the wireguard and mount units are in different modules):

{inputs, config, pkgs, lib, ... }:

let configpath = builtins.toString inputs.infra-configs;
in
{
systemd.tmpfiles.settings = {
  "remotebackup" = {
    "/var/lib/remotebackup" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
      };
    };
    "/var/lib/remotebackup/assets" = {

      d = {
        group = "root";
        user = "root";
        mode = "755";
        };
      };

    };
  };

sops.secrets = {
  "restic/remotebackup/rest" = {};
  "restic/remotebackup/restic" = {};
};

sops.templates."remotebackup" = {
  content = ''
  {
    "rest" : "${config.sops.placeholder."restic/remotebackup/rest"}",
    "restic": "${config.sops.placeholder."restic/remotebackup/restic"}",
  }
  '';
  path = "/var/lib/remotebackup/assets/restic.cred";
  };


system.activationScripts.addPythonScript = lib.stringAfter ["var"] ''
    cp ${configpath}/scripts/remotebackup/script/restic_remotebackup.py /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/requirements.txt /var/lib/remotebackup/requirements.txt
    chmod 733 /var/lib/remotebackup/restic_remotebackup.py
    cp ${configpath}/scripts/remotebackup/script/assets/backup_paths.txt /var/lib/remotebackup/assets/backup_paths.txt
    '';

}

Also, on the RPI I’m triggering the script with cron, according to the wiki cron should be replaced by systemd.timers. Would you also suggest moving to systemd.timers

P.S.: If at all possible, I’d like to keep the script within my script repo…

  • JustinA
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 month ago

    I believe the "nix"y way to do this would be to have a flake that installs the python dependencies, creates a reference to the script file, and then sets up the systemd service to run it.