mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-22 02:09:39 +01:00
podman: use dependency quadlets directly in build for generator
This commit is contained in:
parent
eb5d59dac9
commit
4108ec3aa8
4 changed files with 80 additions and 64 deletions
|
|
@ -9,54 +9,46 @@ let
|
||||||
|
|
||||||
createQuadletSource = name: containerDef:
|
createQuadletSource = name: containerDef:
|
||||||
let
|
let
|
||||||
formatServiceNameForType = type: name:
|
# formatServiceNameForType = type: name:
|
||||||
{
|
# {
|
||||||
image = "podman-${name}-image.service";
|
# image = "${name}-image.service";
|
||||||
build = "podman-${name}-build.service";
|
# build = "${name}-build.service";
|
||||||
network = "podman-${name}-network.service";
|
# network = "${name}-network.service";
|
||||||
volume = "podman-${name}-volume.service";
|
# volume = "${name}-volume.service";
|
||||||
}."${type}";
|
# }."${type}";
|
||||||
|
|
||||||
dependencyByHomeManagerQuadlet = type: name:
|
dependencyBySuffix = type: name:
|
||||||
let
|
if (hasInfix ".${type}" name) then
|
||||||
definitionsOfType =
|
let
|
||||||
filter (q: q.resourceType == type) cfg.internal.quadletDefinitions;
|
baseName = elemAt (splitString ".${type}" name) 0;
|
||||||
matchingName =
|
in
|
||||||
filter (q: q.serviceName == "podman-${name}") definitionsOfType;
|
if (hasAttr (builtins.trace (baseName) baseName) cfg.internal.builtQuadlets) then
|
||||||
in if ((length matchingName) == 1) then
|
[ (cfg.internal.builtQuadlets.${baseName}) ]
|
||||||
[ (formatServiceNameForType type name) ]
|
else
|
||||||
|
[ ]
|
||||||
else
|
else
|
||||||
[ ];
|
[ ];
|
||||||
|
|
||||||
forEachValue = type: value:
|
|
||||||
let resolve = v: dependencyByHomeManagerQuadlet type v;
|
|
||||||
in if isList value then
|
|
||||||
concatLists (map resolve value)
|
|
||||||
else
|
|
||||||
resolve value;
|
|
||||||
|
|
||||||
withResolverFor = type: value:
|
withResolverFor = type: value:
|
||||||
{
|
let
|
||||||
"image" = forEachValue "image" value;
|
resolve = v: dependencyBySuffix type v;
|
||||||
"build" = forEachValue "build" value;
|
in
|
||||||
"network" = forEachValue "network" value;
|
if builtins.isList value
|
||||||
"volume" = let
|
then builtins.concatLists (map resolve value) # Flatten list of lists
|
||||||
a = if isList value then value else [ value ];
|
else resolve value;
|
||||||
volumes = map (v: elemAt (splitString ":" v) 0) a;
|
|
||||||
in forEachValue "volume" volumes;
|
|
||||||
}.${type};
|
|
||||||
|
|
||||||
dependencyServices = (withResolverFor "image" containerDef.image)
|
dependencyServices = (withResolverFor "image" containerDef.image) ++
|
||||||
++ (withResolverFor "build" containerDef.image)
|
(withResolverFor "build" containerDef.image) ++
|
||||||
++ (withResolverFor "network" containerDef.network)
|
(withResolverFor "network" containerDef.network) ++
|
||||||
++ (withResolverFor "volume" containerDef.volumes);
|
(withResolverFor "volume" containerDef.volumes);
|
||||||
|
|
||||||
resolvedImage = if (builtins.hasAttr containerDef.image cfg.images) then
|
getActualImage =
|
||||||
cfg.images."${containerDef.image}".image
|
if (builtins.hasAttr containerDef.image cfg.images) then
|
||||||
else if (builtins.hasAttr containerDef.image cfg.builds) then
|
cfg.images."${containerDef.image}".image
|
||||||
"localhost/homemanager/${containerDef.image}"
|
else if (builtins.hasAttr containerDef.image cfg.builds) then
|
||||||
else
|
"localhost/homemanager/${containerDef.image}"
|
||||||
containerDef.image;
|
else
|
||||||
|
containerDef.image;
|
||||||
|
|
||||||
quadlet = (podman-lib.deepMerge {
|
quadlet = (podman-lib.deepMerge {
|
||||||
Container = {
|
Container = {
|
||||||
|
|
@ -101,29 +93,34 @@ let
|
||||||
TimeoutStopSec = 30;
|
TimeoutStopSec = 30;
|
||||||
};
|
};
|
||||||
Unit = {
|
Unit = {
|
||||||
After = dependencyServices;
|
|
||||||
Requires = dependencyServices;
|
|
||||||
Description = (if (builtins.isString containerDef.description) then
|
Description = (if (builtins.isString containerDef.description) then
|
||||||
containerDef.description
|
containerDef.description
|
||||||
else
|
else
|
||||||
"Service for container ${name}");
|
"Service for container ${name}");
|
||||||
};
|
};
|
||||||
} containerDef.extraConfig);
|
} containerDef.extraConfig);
|
||||||
in ''
|
in
|
||||||
# Automatically generated by home-manager podman container configuration
|
{
|
||||||
# DO NOT EDIT THIS FILE DIRECTLY
|
dependencies = dependencyServices;
|
||||||
#
|
text = ''
|
||||||
# ${name}.container
|
# Automatically generated by home-manager podman container configuration
|
||||||
${podman-lib.toQuadletIni quadlet}
|
# DO NOT EDIT THIS FILE DIRECTLY
|
||||||
'';
|
#
|
||||||
|
# ${name}.container
|
||||||
|
${podman-lib.toQuadletIni quadlet}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
toQuadletInternal = name: containerDef: {
|
toQuadletInternal = name: containerDef: let
|
||||||
|
quadletSrc = createQuadletSource name containerDef;
|
||||||
|
in {
|
||||||
assertions = podman-lib.buildConfigAsserts name containerDef.extraConfig;
|
assertions = podman-lib.buildConfigAsserts name containerDef.extraConfig;
|
||||||
|
dependencies = quadletSrc.dependencies;
|
||||||
resourceType = "container";
|
resourceType = "container";
|
||||||
serviceName =
|
serviceName =
|
||||||
"podman-${name}"; # quadlet service name: 'podman-<name>.service'
|
"podman-${name}"; # quadlet service name: 'podman-<name>.service'
|
||||||
source =
|
source =
|
||||||
podman-lib.removeBlankLines (createQuadletSource name containerDef);
|
podman-lib.removeBlankLines quadletSrc.text;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Define the container user type as the user interface
|
# Define the container user type as the user interface
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,14 @@ let
|
||||||
|
|
||||||
buildInputs = [ cfg.package ];
|
buildInputs = [ cfg.package ];
|
||||||
|
|
||||||
dontUnpack = true;
|
# dontUnpack = true;
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
mkdir -p $out/quadlets
|
||||||
|
${concatStringsSep "\n" (map (v: "cp ${v.out}/quadlets/${v.quadletData.serviceName}.${v.quadletData.resourceType} $out/quadlets") quadlet.dependencies)}
|
||||||
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir $out
|
|
||||||
# Directory for the quadlet file
|
|
||||||
mkdir -p $out/quadlets
|
|
||||||
# Directory for systemd unit files
|
# Directory for systemd unit files
|
||||||
mkdir -p $out/units
|
mkdir -p $out/units
|
||||||
|
|
||||||
|
|
@ -84,5 +86,7 @@ in {
|
||||||
home.activation.podmanQuadletCleanup =
|
home.activation.podmanQuadletCleanup =
|
||||||
lib.mkIf (lib.length builtQuadlets >= 1)
|
lib.mkIf (lib.length builtQuadlets >= 1)
|
||||||
(lib.hm.dag.entryAfter [ "reloadSystemd" ] activationCleanupScript);
|
(lib.hm.dag.entryAfter [ "reloadSystemd" ] activationCleanupScript);
|
||||||
|
|
||||||
|
services.podman.internal.builtQuadlets = listToAttrs (map (pkg: { name = removePrefix "podman-" pkg.passthru.quadletData.serviceName; value = pkg; }) builtQuadlets);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,13 @@ let
|
||||||
description = "List of Nix type assertions.";
|
description = "List of Nix type assertions.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dependencies = lib.mkOption {
|
||||||
|
type = with lib.types; listOf package;
|
||||||
|
default = [ ];
|
||||||
|
internal = true;
|
||||||
|
description = "List of systemd service dependencies.";
|
||||||
|
};
|
||||||
|
|
||||||
resourceType = lib.mkOption {
|
resourceType = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "";
|
default = "";
|
||||||
|
|
@ -33,11 +40,19 @@ let
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.services.podman = {
|
options.services.podman = {
|
||||||
internal.quadletDefinitions = lib.mkOption {
|
internal = {
|
||||||
type = lib.types.listOf quadletInternalType;
|
quadletDefinitions = lib.mkOption {
|
||||||
default = { };
|
type = lib.types.listOf quadletInternalType;
|
||||||
internal = true;
|
default = { };
|
||||||
description = "List of quadlet source file content and service names.";
|
internal = true;
|
||||||
|
description = "List of quadlet source file content and service names.";
|
||||||
|
};
|
||||||
|
builtQuadlets = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf package;
|
||||||
|
default = { };
|
||||||
|
internal = true;
|
||||||
|
description = "All built quadlets.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
package = lib.mkOption {
|
package = lib.mkOption {
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@
|
||||||
};
|
};
|
||||||
containers = {
|
containers = {
|
||||||
"my-container" = {
|
"my-container" = {
|
||||||
image = "my-img";
|
image = "my-img.image";
|
||||||
network = [ "my-net" "externalnet" ];
|
network = [ "my-net.network" "externalnet" ];
|
||||||
volumes = [ "my-vol:/data" ];
|
volumes = [ "my-vol.volume:/data" ];
|
||||||
};
|
};
|
||||||
"my-container-bld" = { image = "my-bld"; };
|
"my-container-bld" = { image = "my-bld"; };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue