{ config, pkgs, lib, ... }: let serverCfg = config.syscfg.server; builder = import ./builder.nix { inherit config lib pkgs serverCfg; }; loadApp = name: containerCfg: builder.mkApp name ((import (./apps + "/${name}.nix")) { inherit config pkgs lib containerCfg builder name; }); loadedContainers = lib.mapAttrs loadApp serverCfg.containers; appsList = builtins.attrValues loadedContainers; concatRuntimeLists = field: lib.concatMap (app: app.runtime.${field}) appsList; mkNamedUnits = mkUnit: items: lib.listToAttrs (map mkUnit items); mergedContainers = lib.concatMapAttrs (appName: app: lib.mapAttrs' (cName: cCfg: lib.nameValuePair "${appName}-${cName}" cCfg) app.runtime.containers ) loadedContainers; allPathConfigs = map (path: { inherit path; mode = "0755"; }) (lib.unique (builtins.attrValues serverCfg.path)) ++ concatRuntimeLists "paths"; allSetupConfigs = map (app: ({ name = app.name; envFile = ""; } // app.runtime.setup)) appsList; allCronsConfigs = concatRuntimeLists "cron"; allVMConfigs = builtins.filter (app: app.runtime.vm != null) appsList; mkPathSetup = cfg: let effectiveCfg = { owner = "root:root"; mode = "0400"; dirs = []; } // cfg; in '' ${pkgs.coreutils}/bin/mkdir -p "${effectiveCfg.path}" ${lib.concatMapStringsSep "\n" (dir: "${pkgs.coreutils}/bin/mkdir -p ${effectiveCfg.path}/${lib.escapeShellArg dir}") effectiveCfg.dirs} ${pkgs.coreutils}/bin/chown ${effectiveCfg.owner} "${effectiveCfg.path}" ${pkgs.coreutils}/bin/chmod ${effectiveCfg.mode} "${effectiveCfg.path}" ''; in { config = lib.mkMerge [{ syscfg.server.loadedContainers = loadedContainers; } (lib.mkIf (loadedContainers != {}) { virtualisation.oci-containers = { backend = "podman"; containers = mergedContainers; }; system.activationScripts.container-setup-dirs = { deps = [ "users" "groups" ]; text = lib.concatStringsSep "\n" (map mkPathSetup allPathConfigs); }; systemd.services = { podman-gc = { description = "Podman garbage collection"; serviceConfig.Type = "oneshot"; script = '' ${pkgs.podman}/bin/podman container prune -f ${pkgs.podman}/bin/podman image prune -f ''; startAt = "weekly"; }; } // mkNamedUnits (e: { name = "${e.name}-vm"; value = { description = "Isolated NixOS Guest VM for ${e.name}"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; environment = { QEMU_VM_REG_SND = "0"; NIX_DISK_IMAGE = "/media/data/kvm/${e.name}-guest.qcw2"; }; serviceConfig = { Type = "simple"; Restart = "always"; RestartSec = "10s"; ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /media/data/kvm"; ExecStart = '' ${builder.mkVm { name = e.name; vm = e.runtime.vm; }}/bin/run-${e.name}-vm -nographic ''; }; }; }) allVMConfigs // mkNamedUnits (e: { name = "${e.name}-setup"; value = { description = "Run ${e.name} setup"; after = [ "podman-${e.name}-${e.trigger}.service" ]; wants = [ "podman-${e.name}-${e.trigger}.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; TimeoutStartSec = "360s"; EnvironmentFile = e.envFile; ExecStart = e.script; RemainAfterExit = true; User = "root"; }; }; }) allSetupConfigs; services.cron = { enable = true; systemCronJobs = allCronsConfigs; }; })]; }