Hello everyone!
I am looking to modularize my nixOS configuration and for many of my modules, all I need to do is add options and config to existing nixpkgs modules.
An example of this is using restic. It works by creating an arbitrary attrSet
of named backups, and creating systemd units for each one.
I am attempting to add the following option:
options.services.restic.backups = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule (
{ name, ... }:
{
options = {
dailySnapshotsToKeep = lib.mkOption {
type = lib.types.int;
};
};
}
)
);
};
This is a convenience option which I would like to use as a wrapper for restic’s pruneOpts
option. Here is where I run into my issue; the following is my intuitive attempt to implement config based on this option:
config.services.restic.backups = lib.mapAttrs
(
name: backup:
backup //
{
pruneOpts = [
"--keep-daily ${ lib.toString backup.dailySnapshotsToKeep }"
]
}
)
config.services.restic.backups
This implementation will not work due to infinite recursion, because config.services.restic.backups
requires itself to be evaluated before itself.
After reading through the manual and watching this Nix Hour, it seems that the solution would be to push down the dependencies like so:
config.services.restic.backups.<backupName>.pruneOpts = [
"--keep-daily ${ lib.toString config.services.restic.backups.<backupName>.dailySnapshotsToKeep }"
];
This would prevent infinite recursion by using more specific paths. The issue in this case is that I can’t know what the attributes on backups
are, so I can’t use these more specific paths.
I currently have two solutions for how to get around this infinite recursion, both of which are suboptimal in my opinion:
-
Change the path to my option to something like
options.myOptions.services.restic.backups
This would allow me to loop over the attributes of my custom option, getting around the recursion, but would in turn require me to maintain the same set of
backups
attributes in two separate options. -
Disable the restic module from nixpkgs, paste its contents into my custom module
Here I can implement all of the options and config in one place, but this would require me to maintain all the unrelated parts of the module, which is already being done by the module’s maintainers in nixpkgs
Are there any other options for making changes to arbitrarily defined attribute sets in this way, or have I run into a limitation of the nix module system?
Thanks for the help!