{ config, lib, pkgs, ... }: with lib; let cfg = config.services.podman; podman-lib = import ./podman-lib.nix { inherit lib config; }; activation = import ./activation.nix { inherit config podman-lib; }; activationCleanupScript = activation.cleanup; # derivation to build a single Podman quadlet, outputting its systemd unit files buildPodmanQuadlet = quadlet: pkgs.stdenv.mkDerivation { name = "home-${quadlet.resourceType}-${quadlet.serviceName}"; buildInputs = [ cfg.package ]; dontUnpack = true; installPhase = '' mkdir $out # Directory for the quadlet file mkdir -p $out/quadlets # Directory for systemd unit files mkdir -p $out/units # Write the quadlet file echo -n "${quadlet.source}" > $out/quadlets/${quadlet.serviceName}.${quadlet.resourceType} # Generate systemd unit file/s from the quadlet file export QUADLET_UNIT_DIRS=$out/quadlets ${cfg.package}/lib/systemd/user-generators/podman-user-generator $out/units ''; passthru = { outPath = self.out; quadletData = quadlet; }; }; # Create a derivation for each quadlet spec builtQuadlets = map buildPodmanQuadlet cfg.internal.quadletDefinitions; accumulateUnitFiles = prefix: path: quadlet: let entries = builtins.readDir path; processEntry = name: type: let newPath = "${path}/${name}"; newPrefix = prefix + (if prefix == "" then "" else "/") + name; in if type == "directory" then accumulateUnitFiles newPrefix newPath quadlet else [{ key = newPrefix; value = { path = newPath; parentQuadlet = quadlet; }; }]; in flatten (map (name: processEntry name (getAttr name entries)) (attrNames entries)); allUnitFiles = concatMap (builtQuadlet: accumulateUnitFiles "" "${builtQuadlet.outPath}/units" builtQuadlet.quadletData) builtQuadlets; # we're doing this because the home-manager recursive file linking implementation can't # merge from multiple sources. so we link each file explicitly, which is fine for all unique files generateSystemdFileLinks = files: listToAttrs (map (unitFile: { name = "${config.xdg.configHome}/systemd/user/${unitFile.key}"; value = { source = unitFile.value.path; }; }) files); in { imports = [ ./options.nix ]; config = mkIf cfg.enable { home.file = generateSystemdFileLinks allUnitFiles; # if the length of builtQuadlets is 0, then we don't need register the activation script home.activation.podmanQuadletCleanup = lib.mkIf (lib.length builtQuadlets >= 1) (lib.hm.dag.entryAfter [ "reloadSystemd" ] activationCleanupScript); }; }