1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-12-01 06:31:04 +01:00
home-manager/modules/services/podman-linux/install-quadlet.nix
Nick Hassan d800d198b8
podman: use quadlet source from file drv (#7102)
fixes potentially unwanted variable substitution
2025-05-30 10:25:03 -05:00

120 lines
3.5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.podman;
podman-lib = import ./podman-lib.nix { inherit pkgs 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:
let
quadletFile = pkgs.writeText "${quadlet.serviceName}.${quadlet.resourceType}" quadlet.source;
in
pkgs.stdenv.mkDerivation {
name = "home-${quadlet.resourceType}-${quadlet.serviceName}";
src = quadletFile;
buildInputs = [ cfg.package ] ++ quadlet.dependencies;
unpackPhase = ''
mkdir -p $out/quadlets
ln -s $src $out/quadlets/${quadlet.serviceName}.${quadlet.resourceType}
${lib.concatStringsSep "\n" (
map (
v:
"echo 'linking ${v.quadletData.serviceName}.${v.quadletData.resourceType}'; ln -s ${v.out}/quadlets/${v.quadletData.serviceName}.${v.quadletData.resourceType} $out/quadlets"
) quadlet.dependencies
)}
'';
installPhase = ''
# Directory for systemd unit files
mkdir -p $out/units
# 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 = lib.self.out;
quadletData = quadlet;
};
};
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
lib.flatten (map (name: processEntry name (lib.getAttr name entries)) (lib.attrNames entries));
allUnitFiles = lib.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:
lib.listToAttrs (
map (unitFile: {
name = "${config.xdg.configHome}/systemd/user/${unitFile.key}";
value = {
source = unitFile.value.path;
};
}) files
);
in
{
imports = [ ./options.nix ];
config = lib.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
);
services.podman.internal.builtQuadlets = lib.listToAttrs (
map (pkg: {
name =
(lib.removePrefix "podman-" pkg.passthru.quadletData.serviceName)
+ "."
+ pkg.passthru.quadletData.resourceType;
value = pkg;
}) builtQuadlets
);
};
}