Hi, I am trying to dynamically import modules to make my life easier in the future. I have made a couple of simple functions to help me with this and it usually it works except for this in specific case and I cant figure it out.
I have written this to dynamically import modules from a pathlist:
{config, lib, inputs, ...}:
with lib;
let
pathList = (import ./../../../helpers/importAllModules.nix).getModulesFromDir {dir = ./containers;};
importPathList = cfg: lib: paths: boxAttrs: i: if i < (builtins.length paths)
then importPathList cfg lib paths (boxAttrs // ((import (builtins.elemAt paths i)) {lib = lib; cfg = cfg;})) (i + 1)
else boxAttrs;
importBoxes = {cfg, lib, pathList}: importPathList cfg lib pathList {} 0;
cfg = config.quadlets.containers.streaming;
in {
options.quadlets.containers.streaming = {
enable = mkEnableOption "Enables streaming pod and containers";
gid = mkOption {
type = types.str;
example = "994";
description = "gives group id to pod and containers";
};
uid = mkOption {
type = types.str;
example = "991";
description = "gives user id to pod and containers";
};
tz = mkOption {
type = types.str;
example = "Europe/Amsterdam";
description = "give timezone to containers for internal timekeeping";
};
podName = mkOption {
type = types.str;
example = "streaming";
default = "streaming";
description = "gives a name to the contianer cluster";
};
};
config = mkIf cfg.enable {
virtualisation.quadlet = let
inherit (config.virtualisation.quadlet) networks pods;
in {
containers = {} // builtins.trace (builtins.deepSeq (importBoxes {inherit cfg lib; pathList = pathList;}) (importBoxes {inherit cfg lib; pathList = pathList;})) (importBoxes {inherit cfg lib; pathList = pathList;});
};
};
}
This is a typical module/container:
{ cfg, lib, ... }:
with lib;
{
jellyfin-box = {
autoStart = true;
unitConfig = {
Description = "jellyfin-test";
};
containerConfig = {
image = "lscr.io/linuxserver/jellyfin:latest";
autoUpdate = "registry";
devices = [
"/dev/dri:/dev/dri"
];
environments = {
TZ = cfg.tz;
GID = cfg.gid;
UID = cfg.uid;
};
volumes = [
"/data/streaming/media:/media:rw,z"
"/var/cache/jellyfin:/cache:Z"
"/etc/container-data/streaming/jellyfin:/config:Z"
];
tmpfses = [
"/tmp"
];
publishPorts = [
"0.0.0.0:8096:8096/tcp"
];
networks = [
"host"
];
} // optionalAttrs (cfg.podName != null) {pod = cfg.podName;};
serviceConfig = {
SuccessExitStatus = "0 143";
};
};
}
ImportAllModules.nix(I need to rename it) is a function that finds all modules from a specifc directory checks if their modules and returns a directory list. I know this works as I use it elsewhere in my code.
The output of the trace is:
trace: { bazarr-box = «thunk»; flaresolverr-box = «thunk»; jellyfin-box = «thunk»; prowlarr-box = «thunk»; qbittorrent-box = «thunk»; radarr-box = «thunk»; sonarr-box = «thunk»; }
Which on a top level looks correct but then I dont see any containers show up in podman containers ps or as a systemd service.
Maybe its something to do with lazy evaluation that I need to force it to load the variables in before executing? I have tried with some hardcoded modules in a previous test which did seem to work but im unsure if its the culprit since I did it in a separate file from the module file, so maybe its something to do with that.
I dont know what it could be.
Also some tips on how to write nix logic cleanly would be appreciated. Their very messy.
Thanks in advance.