Extending nixos-config with new options

In order to make my nixos configuration easier to read and maintain, I’d like to do the following:

  1. Define some new options that don’t currently exist (I know this can be done with lib.mkOption).

  2. Write a function that takes those new options as input and returns a set of old options that nixos knows how to interpret.

  3. Set up my system such that the function in 2) automatically get called on the options in 1) to update my nixos configuration.

The end result would be that I could add something like the following to my nixos configuration:

dsuite.containers."ubuntu" = {
    image = "ubuntu-plus:22.04";
    base-image = "ubuntu:22.04";
    icon = "ubuntu";
    work-dir = "/workspace";
    build-files = [../build-files/ubuntu-plus.dockerfile];
    init = "echo This is a persistent Ubuntu 22.04 container.";
}

and know that this will get turned into a set of home-manager options that result in home-manager adding files to my home directory.

I already have the function to convert the options (2 in my list above), but I don’t know how to configure my system such that the functions will automatically be called on my new options to produce the home-manager options (3 on the list above).

Does that question make any sense? Does anyone have thoughts? Thanks.

PS: I know there’s a simpler solution where I import the file containing the function definition and call that directly in my nixos configuration. I’m wondering whether the alternate approach I’m describing here is possible.

I figured it out. I just needed to make my new option with lib.mkOption and then make a module that uses that option to update home-manager with the new files.

{ config, pkgs, lib, ... }:
let 
  add-container = import ../functions/add-container.nix;
  add = name: (add-container ({inherit lib name;} //
                      config.dsuite-containers.${name}));
in
{home-manager.users."${config.identity.username}" =
  lib.mkMerge (map add (lib.attrNames config.dsuite-containers));}
1 Like