{ config, lib, pkgs, ... }: with lib; let cfg = config.services.podman; podman-lib = import ./podman-lib.nix { inherit pkgs lib config; }; createQuadletSource = name: buildDef: let buildConfig = podman-lib.deepMerge { Build = { AuthFile = buildDef.authFile; Environment = buildDef.environment; File = buildDef.file; ImageTag = [ "homemanager/${name}" ] ++ buildDef.tags; Label = buildDef.labels // { "nix.home-manager.managed" = true; }; PodmanArgs = buildDef.extraPodmanArgs; SetWorkingDirectory = buildDef.workingDirectory; TLSVerify = buildDef.tlsVerify; }; Install = { WantedBy = optionals buildDef.autoStart [ "default.target" "multi-user.target" ]; }; Service = { TimeoutStartSec = 300; RemainAfterExit = "yes"; }; Unit = { Description = buildDef.description; }; } buildDef.extraConfig; in '' # Automatically generated by home-manager for podman build configuration # DO NOT EDIT THIS FILE DIRECTLY # # ${name}.build ${podman-lib.toQuadletIni buildConfig} ''; toQuadletInternal = name: buildDef: { assertions = podman-lib.buildConfigAsserts name buildDef.extraConfig; serviceName = "podman-${name}"; # quadlet service name: 'podman--build.service source = podman-lib.removeBlankLines (createQuadletSource name buildDef); resourceType = "build"; }; in let buildDefinitionType = types.submodule ({ name, ... }: { options = { autoStart = mkOption { type = types.bool; default = true; description = "Whether to start the build on boot. Requires user lingering."; }; authFile = mkOption { type = with types; nullOr path; default = null; description = "Path of the authentication file."; }; description = mkOption { type = with types; nullOr str; default = "Service for build ${name}"; defaultText = "Service for build \${name}"; example = "My Build"; description = "The description of the build."; }; environment = mkOption { type = podman-lib.primitiveAttrs; default = { }; example = literalExpression '' { VAR1 = "0:100"; VAR2 = true; VAR3 = 5; } ''; description = "Environment variables to set in the build."; }; extraConfig = mkOption { type = podman-lib.extraConfigType; default = { }; example = literalExpression '' { Build = { Arch = "aarch64"; }; Service = { TimeoutStartSec = 15; }; } ''; description = "INI sections and values to populate the Build Quadlet."; }; extraPodmanArgs = mkOption { type = types.listOf types.str; default = [ ]; example = [ "--retries 5" ]; description = "Extra arguments to pass to the podman build command."; }; file = mkOption { type = types.str; example = literalExpression '' `"xdg.configFile."containerfiles/my-img/Containerfile"` or `"https://github.com/.../my-img/Containerfile"` ''; description = "Path to a Containerfile which contains instructions to build the image."; }; tags = mkOption { type = with types; listOf str; default = [ ]; description = '' Name associated with the build. First tag will always be "homemanager/". ''; }; labels = mkOption { type = with types; attrsOf str; default = { }; example = { app = "myapp"; some-label = "somelabel"; }; description = "The labels to apply to the build."; }; tlsVerify = mkOption { type = types.bool; default = true; description = "Require HTTPS and verification of certificates when contacting registries."; }; workingDirectory = mkOption { type = with types; nullOr path; default = null; description = "WorkingDirectory of the systemd unit file."; }; }; }); in { options.services.podman.builds = mkOption { type = types.attrsOf buildDefinitionType; default = { }; description = "Defines Podman build quadlet configurations."; }; config = let buildQuadlets = mapAttrsToList toQuadletInternal cfg.builds; in mkIf cfg.enable { services.podman.internal.quadletDefinitions = buildQuadlets; assertions = flatten (map (build: build.assertions) buildQuadlets); xdg.configFile."podman/images.manifest".text = podman-lib.generateManifestText buildQuadlets; }; }