I’m migrating my NAS to nixos, and I got to the point of setting up my restic backups.

services.restic.backups is great, but – on top of the systemd timers/services – I also want some helper scripts (eg. one to easily mount the backups, stuff that with ansible I currently generate into /usr/local/sbin).

These scripts would be entirely generated from the services.restic.backups config and would reference sops secrets also from configuration.nix, so… I don’t think it would make sense to make a package out of them?

What should I use to make these scripts? Should I use nixpkgs.writeShellApplication and then alter the PATH?

  • hallettj@beehaw.org
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    1 年前

    Yes, writeShellApplication is a good solution. But instead of altering your path, put the result right in the environment.systemPackages list, or in users.users.your-user.packages.

    writeShellApplication produces a derivation (a value that will be turned into a store path when it’s “instantiated”). Basically it’s already a package. You can use the derivation the same way you would use a package from nixpkgs.

    You’re likely already aware, but when you get secrets from sops those are paths to files in /var/run/ generated at runtime; so your scripts will need to run with sufficient privileges to read the secrets files.

    Edit: Sorry, I meant “instantiated”, not “realized”

    • gompOP
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      1 年前

      Thanks: that helps a lot. I’m still quite confused about nixos concepts (and by the lingo too).

      edit: Turns out you can’t just put writeShellApplicaiton { ... } in systemPackages directly: you need to add the package via an overlay (see https://discourse.nixos.org/t/referencing-the-output-of-writeshellapplication-as-a-package-in-another-nix-file/23363)

      edit2: Actually, /u/hallettj@beehaw.org is 100% right: one can put writeShellApplicaiton { ... } inside systemPackages, but it must be systemPackages = [(writeShellApplicaiton { ... })] with the parentheses, otherwise writeShellApplicaiton is not applied to its argument and the two end up as two separate elements in the list.

      • hallettj@beehaw.org
        link
        fedilink
        English
        arrow-up
        2
        ·
        1 年前

        Yeah, it was quite a learning curve for me too. I found reading Nix Pills was helpful. I put it off too long even after seeing lots of recommendations. It turns out the recommendations are apt.

      • hallettj@beehaw.org
        link
        fedilink
        English
        arrow-up
        2
        ·
        1 年前

        I can at least try to define the concepts I mentioned in my comment.

        • store path is a directory or file in /nix/store/. It has the format /nix/store/--. Every installed package gets a store path. There is other stuff too - if you use flakes each flake and each flake input are copied to a store path before being evaluated. IIUC certain directories within each store path are treated specially. For example if a store path has a bin/ directory, and that store path is included in your user “profile” of installed packages, then everything in that bin/ directory is automatically symlinked to your profile bin/ directory, which is in your $PATH. For example,
        $ which git
        /home/jesse/.nix-profile/bin/git
        $ ls -l $(which git)
        lrwxrwxrwx 62 root 31 Dec  1969 /home/jesse/.nix-profile/bin/git -> /nix/store/nqdyqplahmhdgz8pzzd5nip17zf3ijzx-git-2.40.1/bin/git
        
        • derivation is a value in the Nix language that represents one or more files that could potentially be written to a store path. Specifically a derivation is an attribute set (the Nix term for a dictionary/object) with certain special attributes/properties. A derivation contains all the information necessary to produce some files to go into a store path (often by downloading or compiling something), and also contains the specific path that those files will be written to. When you access a package in a Nix expression, such as nixpkgs.git, the value you get is a derivation. But you can also make derivations yourself using functions like stdenv.mkDerivation or writeShellApplication. I think you can even write an attribute set from scratch if you want to.

        To get from a Nix attribute set to a set of files there is a process called instantiation that is separate from evaluation of Nix expressions. (By “expressions” I mean Nix programs, anything in a .nix file.) Certain Nix programs will evaluate a Nix expression, read a derivation that the expression produces, and do the instantiation to actually create the files. As I mentioned the derivation includes all of the information necessary to do this. Part of this process actually serializes each derivation to a file in /nix/store/ - that’s what the .drv files in there are. Those are very-specialized scripts that produce store paths.

        • package is I think a less-specific term for a derivation or a store path. Maybe there is an implication that a derivation that is a package comes from a software repository, or includes either executables or libraries. (Derivations don’t necessarily have to provide executables or libraries - they can represent any file or directory of files.)