diff --git a/.github/labeler.yml b/.github/labeler.yml
index a16e6058c..cc95a7088 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -165,7 +165,7 @@
"containers":
- changed-files:
- any-glob-to-any-file:
- - modules/services/podman-linux/**/*
+ - modules/services/podman/linux/**/*
- modules/programs/distrobox.nix
- modules/programs/docker-cli.nix
"desktop-ui":
diff --git a/modules/services/podman/assertions.nix b/modules/services/podman/assertions.nix
new file mode 100644
index 000000000..75a8941ca
--- /dev/null
+++ b/modules/services/podman/assertions.nix
@@ -0,0 +1,23 @@
+{ lib }:
+
+{
+ assertPlatform =
+ module: config: pkgs: platforms:
+ let
+ modulePath = lib.splitString "." module;
+ isEmpty = x: x == false || x == null || x == { } || x == [ ] || x == "";
+ in
+ {
+ assertion =
+ (isEmpty (lib.attrByPath modulePath null config))
+ || (lib.elem pkgs.stdenv.hostPlatform.system platforms);
+ message =
+ let
+ platformsStr = lib.concatStringsSep "\n" (map (p: " - ${p}") (lib.sort (a: b: a < b) platforms));
+ in
+ ''
+ The module ${module} does not support your platform. It only supports
+
+ ${platformsStr}'';
+ };
+}
diff --git a/modules/services/podman/darwin.nix b/modules/services/podman/darwin.nix
new file mode 100644
index 000000000..4dcec8ab1
--- /dev/null
+++ b/modules/services/podman/darwin.nix
@@ -0,0 +1,301 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ inherit (lib)
+ attrNames
+ concatStringsSep
+ filterAttrs
+ mapAttrs'
+ mkIf
+ mkOption
+ mkMerge
+ nameValuePair
+ optionalString
+ types
+ ;
+ assertions = import ./assertions.nix { inherit lib; };
+
+ cfg = config.services.podman;
+
+ machineDefinitionType = types.submodule {
+ options = {
+ cpus = mkOption {
+ type = types.nullOr types.ints.positive;
+ default = null;
+ example = 2;
+ description = "Number of CPUs to allocate to the machine. If null, uses podman's default.";
+ };
+
+ diskSize = mkOption {
+ type = types.nullOr types.ints.positive;
+ default = null;
+ example = 200;
+ description = "Disk size in GB for the machine. If null, uses podman's default.";
+ };
+
+ image = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = "Bootable image to use for the machine. If null, uses podman's default.";
+ };
+
+ memory = mkOption {
+ type = types.nullOr types.ints.positive;
+ default = null;
+ example = 8192;
+ description = "Memory in MB to allocate to the machine. If null, uses podman's default.";
+ };
+
+ rootful = mkOption {
+ type = types.nullOr types.bool;
+ default = null;
+ example = true;
+ description = ''
+ Whether to run the machine in rootful mode. If null, uses podman's default.
+ Rootful mode runs containers as root inside the VM.
+ '';
+ };
+
+ swap = mkOption {
+ type = types.nullOr types.ints.positive;
+ default = null;
+ example = 2048;
+ description = "Swap size in MB for the machine. If null, uses podman's default.";
+ };
+
+ timezone = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "UTC";
+ description = "Timezone to set in the machine. If null, uses podman's default.";
+ };
+
+ username = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "user";
+ description = "Username used in the machine image. If null, uses podman's default.";
+ };
+
+ volumes = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [
+ "/Users:/Users"
+ "/private:/private"
+ "/var/folders:/var/folders"
+ ];
+ description = ''
+ Volumes to mount in the machine, specified as source:target pairs.
+ If empty, podman will use its default volume mounts.
+ '';
+ };
+
+ autoStart = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = "Whether to automatically start this machine on login.";
+ };
+
+ watchdogInterval = mkOption {
+ type = types.ints.positive;
+ default = 30;
+ example = 60;
+ description = "Interval in seconds to check if the machine is running";
+ };
+ };
+ };
+
+ mkWatchdogScript =
+ name: machine:
+ pkgs.writeShellScript "podman-machine-watchdog-${name}" ''
+ set -euo pipefail
+
+ MACHINE_NAME="${name}"
+ INTERVAL=${toString machine.watchdogInterval}
+ PODMAN="${lib.getExe cfg.package}"
+
+ log() {
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
+ }
+
+ check_and_start() {
+ local state
+ state=$($PODMAN machine inspect "$MACHINE_NAME" --format '{{.State}}' 2>/dev/null || echo "unknown")
+
+ case "$state" in
+ running)
+ return 0
+ ;;
+ stopped|unknown)
+ log "Machine '$MACHINE_NAME' is starting..."
+ if $PODMAN machine start "$MACHINE_NAME" 2>&1 | while IFS= read -r line; do log "$line"; done; then
+ log "Machine '$MACHINE_NAME' started successfully"
+ return 0
+ else
+ log "Failed to start machine '$MACHINE_NAME'"
+ return 1
+ fi
+ ;;
+ *)
+ log "Machine '$MACHINE_NAME' is $state"
+ return 1
+ ;;
+ esac
+ }
+
+ log "Starting watchdog for machine '$MACHINE_NAME' (check interval: ''${INTERVAL}s)"
+
+ while true; do
+ check_and_start || true
+ sleep "$INTERVAL"
+ done
+ '';
+in
+{
+ options.services.podman = {
+ useDefaultMachine = mkOption {
+ type = types.bool;
+ default = pkgs.stdenv.hostPlatform.isDarwin;
+ description = ''
+ Whether to create and use the default podman machine.
+
+ The default machine will be named `podman-machine-default` and configured with podmans default values.
+ '';
+ readOnly = pkgs.stdenv.hostPlatform.isLinux;
+ };
+
+ machines = mkOption {
+ type = types.attrsOf machineDefinitionType;
+ default = { };
+ description = "Declarative podman machine configurations.";
+ example = lib.literalExpression ''
+ {
+ "dev-machine" = {
+ cpus = 4;
+ diskSize = 100;
+ memory = 8192;
+ swap = 2048;
+ timezone = "UTC";
+ volumes = [
+ "/Users:/Users"
+ "/private:/private"
+ ];
+ autoStart = true;
+ watchdogInterval = 30;
+ };
+ "testing" = {
+ cpus = 2;
+ diskSize = 50;
+ image = "ghcr.io/your-org/custom-image:latest";
+ memory = 4096;
+ username = "podman";
+ autoStart = false;
+ };
+ }
+ '';
+ };
+ };
+
+ config =
+ let
+ podmanCmd = lib.getExe cfg.package;
+ allMachines =
+ cfg.machines
+ // (
+ if cfg.useDefaultMachine then
+ {
+ "podman-machine-default" = {
+ cpus = null;
+ diskSize = null;
+ image = null;
+ memory = null;
+ rootful = null;
+ swap = null;
+ timezone = null;
+ username = null;
+ volumes = [ ];
+ autoStart = true;
+ watchdogInterval = 30;
+ };
+ }
+ else
+ { }
+ );
+ autoStartMachines = filterAttrs (_name: machine: machine.autoStart) allMachines;
+ in
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.useDefaultMachine" config pkgs lib.platforms.darwin)
+ (assertions.assertPlatform "services.podman.machines" config pkgs lib.platforms.darwin)
+ ];
+ }
+
+ (mkIf pkgs.stdenv.isDarwin {
+ home.activation.podmanMachines =
+ let
+ mkMachineInitScript =
+ name: machine:
+ let
+ # Automatically mount host's container config into the VM
+ username = if isNull machine.username then "core" else machine.username;
+ configVolume = "$HOME/.config/containers:/home/${username}/.config/containers";
+ allVolumes = [ configVolume ] ++ machine.volumes;
+ in
+ ''
+ if ! ${podmanCmd} machine list --format '{{.Name}}' 2>/dev/null | sed 's/\*$//' | grep -q '^${name}$'; then
+ echo "Creating podman machine: ${name}"
+ ${podmanCmd} machine init ${name} \
+ ${optionalString (machine.cpus != null) "--cpus ${toString machine.cpus}"} \
+ ${optionalString (machine.diskSize != null) "--disk-size ${toString machine.diskSize}"} \
+ ${optionalString (machine.image != null) "--image ${machine.image}"} \
+ ${optionalString (machine.memory != null) "--memory ${toString machine.memory}"} \
+ ${optionalString ((machine.rootful != null) && machine.rootful) "--rootful"} \
+ ${optionalString (machine.swap != null) "--swap ${toString machine.swap}"} \
+ ${optionalString (machine.timezone != null) "--timezone \"${machine.timezone}\""} \
+ ${optionalString (machine.username != null) "--username \"${machine.username}\""} \
+ ${concatStringsSep " " (map (v: "--volume \"${v}\"") allVolumes)}
+ fi
+ '';
+ in
+ lib.hm.dag.entryAfter [ "writeBoundary" ] ''
+ PATH="${cfg.package}/bin:$PATH"
+
+ ${concatStringsSep "\n" (lib.mapAttrsToList mkMachineInitScript allMachines)}
+
+ MANAGED_MACHINES="${concatStringsSep " " (attrNames allMachines)}"
+ EXISTING_MACHINES=$(${podmanCmd} machine list --format '{{.Name}}' 2>/dev/null | sed 's/\*$//' || echo "")
+
+ for machine in $EXISTING_MACHINES; do
+ if [[ ! " $MANAGED_MACHINES " =~ " $machine " ]]; then
+ echo "Removing unmanaged podman machine: $machine"
+ ${podmanCmd} machine stop "$machine" 2>/dev/null || true
+ ${podmanCmd} machine rm -f "$machine"
+ fi
+ done
+ '';
+
+ launchd.agents = mapAttrs' (
+ name: machine:
+ nameValuePair "podman-machine-${name}" {
+ enable = true;
+ config = {
+ ProgramArguments = [ "${mkWatchdogScript name machine}" ];
+ KeepAlive = {
+ Crashed = true;
+ SuccessfulExit = false;
+ };
+ ProcessType = "Background";
+ RunAtLoad = true;
+ };
+ }
+ ) autoStartMachines;
+ })
+ ]);
+}
diff --git a/modules/services/podman-linux/default.nix b/modules/services/podman/default.nix
similarity index 85%
rename from modules/services/podman-linux/default.nix
rename to modules/services/podman/default.nix
index ecabeec99..b7f2a67ca 100644
--- a/modules/services/podman-linux/default.nix
+++ b/modules/services/podman/default.nix
@@ -1,7 +1,7 @@
{
config,
- pkgs,
lib,
+ pkgs,
...
}:
let
@@ -12,21 +12,19 @@ in
meta.maintainers = [
lib.hm.maintainers.bamhm182
lib.maintainers.n-hass
+ lib.maintainers.delafthi
];
imports = [
- ./builds.nix
- ./containers.nix
- ./images.nix
- ./install-quadlet.nix
- ./networks.nix
- ./services.nix
- ./volumes.nix
+ ./linux/default.nix
+ ./darwin.nix
];
options.services.podman = {
enable = lib.mkEnableOption "Podman, a daemonless container engine";
+ package = lib.mkPackageOption pkgs "podman" { };
+
settings = {
containers = lib.mkOption {
type = toml.type;
@@ -94,14 +92,14 @@ in
};
config = lib.mkIf cfg.enable {
- assertions = [ (lib.hm.assertions.assertPlatform "podman" pkgs lib.platforms.linux) ];
-
home.packages = [ cfg.package ];
- services.podman.settings.storage = {
- storage.driver = lib.mkDefault "overlay";
- };
+ services.podman.settings.storage.storage.driver = lib.mkDefault "overlay";
+ # Configuration files are written to `$XDG_CONFIG_HOME/.config/containers`
+ # On Linux: podman reads them directly from this location
+ # On Darwin: these files are automatically mounted into the podman machine VM
+ # (see darwin.nix for the volume mount configuration)
xdg.configFile = {
"containers/policy.json".source =
if cfg.settings.policy != { } then
diff --git a/modules/services/podman-linux/activation.nix b/modules/services/podman/linux/activation.nix
similarity index 100%
rename from modules/services/podman-linux/activation.nix
rename to modules/services/podman/linux/activation.nix
diff --git a/modules/services/podman-linux/builds.nix b/modules/services/podman/linux/builds.nix
similarity index 89%
rename from modules/services/podman-linux/builds.nix
rename to modules/services/podman/linux/builds.nix
index 087f7b68e..d9a48aaa2 100644
--- a/modules/services/podman-linux/builds.nix
+++ b/modules/services/podman/linux/builds.nix
@@ -5,7 +5,13 @@
...
}:
let
- inherit (lib) mkOption types;
+ inherit (lib)
+ mkIf
+ mkOption
+ mkMerge
+ types
+ ;
+ assertions = import ../assertions.nix { inherit lib; };
cfg = config.services.podman;
@@ -182,10 +188,17 @@ in
let
buildQuadlets = lib.mapAttrsToList toQuadletInternal cfg.builds;
in
- lib.mkIf cfg.enable {
- services.podman.internal.quadletDefinitions = buildQuadlets;
- assertions = lib.flatten (map (build: build.assertions) buildQuadlets);
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.builds" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux {
+ services.podman.internal.quadletDefinitions = buildQuadlets;
+ assertions = lib.flatten (map (build: build.assertions) buildQuadlets);
- xdg.configFile."podman/images.manifest".text = podman-lib.generateManifestText buildQuadlets;
- };
+ xdg.configFile."podman/images.manifest".text = podman-lib.generateManifestText buildQuadlets;
+ })
+ ]);
}
diff --git a/modules/services/podman-linux/containers.nix b/modules/services/podman/linux/containers.nix
similarity index 94%
rename from modules/services/podman-linux/containers.nix
rename to modules/services/podman/linux/containers.nix
index 384190f33..fa7bfe659 100644
--- a/modules/services/podman-linux/containers.nix
+++ b/modules/services/podman/linux/containers.nix
@@ -5,7 +5,13 @@
...
}:
let
- inherit (lib) mkOption types;
+ inherit (lib)
+ mkIf
+ mkOption
+ mkMerge
+ types
+ ;
+ assertions = import ../assertions.nix { inherit lib; };
cfg = config.services.podman;
@@ -401,12 +407,19 @@ in
let
containerQuadlets = lib.mapAttrsToList toQuadletInternal cfg.containers;
in
- lib.mkIf cfg.enable {
- services.podman.internal.quadletDefinitions = containerQuadlets;
- assertions = lib.flatten (map (container: container.assertions) containerQuadlets);
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.containers" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux {
+ services.podman.internal.quadletDefinitions = containerQuadlets;
+ assertions = lib.flatten (map (container: container.assertions) containerQuadlets);
- # manifest file
- xdg.configFile."podman/containers.manifest".text =
- podman-lib.generateManifestText containerQuadlets;
- };
+ # manifest file
+ xdg.configFile."podman/containers.manifest".text =
+ podman-lib.generateManifestText containerQuadlets;
+ })
+ ]);
}
diff --git a/modules/services/podman/linux/default.nix b/modules/services/podman/linux/default.nix
new file mode 100644
index 000000000..fcbd59bdf
--- /dev/null
+++ b/modules/services/podman/linux/default.nix
@@ -0,0 +1,12 @@
+{
+ imports = [
+ ./options.nix
+ ./builds.nix
+ ./containers.nix
+ ./images.nix
+ ./install-quadlet.nix
+ ./networks.nix
+ ./services.nix
+ ./volumes.nix
+ ];
+}
diff --git a/modules/services/podman-linux/images.nix b/modules/services/podman/linux/images.nix
similarity index 90%
rename from modules/services/podman-linux/images.nix
rename to modules/services/podman/linux/images.nix
index 275896183..33067916a 100644
--- a/modules/services/podman-linux/images.nix
+++ b/modules/services/podman/linux/images.nix
@@ -5,7 +5,13 @@
...
}:
let
- inherit (lib) mkOption types;
+ inherit (lib)
+ mkIf
+ mkOption
+ mkMerge
+ types
+ ;
+ assertions = import ../assertions.nix { inherit lib; };
cfg = config.services.podman;
@@ -165,8 +171,15 @@ in
let
imageQuadlets = lib.mapAttrsToList toQuadletInternal cfg.images;
in
- lib.mkIf cfg.enable {
- services.podman.internal.quadletDefinitions = imageQuadlets;
- assertions = lib.flatten (map (image: image.assertions) imageQuadlets);
- };
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.images" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux {
+ services.podman.internal.quadletDefinitions = imageQuadlets;
+ assertions = lib.flatten (map (image: image.assertions) imageQuadlets);
+ })
+ ]);
}
diff --git a/modules/services/podman-linux/install-quadlet.nix b/modules/services/podman/linux/install-quadlet.nix
similarity index 98%
rename from modules/services/podman-linux/install-quadlet.nix
rename to modules/services/podman/linux/install-quadlet.nix
index a5326121f..5e7ade3de 100644
--- a/modules/services/podman-linux/install-quadlet.nix
+++ b/modules/services/podman/linux/install-quadlet.nix
@@ -99,7 +99,7 @@ in
{
imports = [ ./options.nix ];
- config = lib.mkIf cfg.enable {
+ config = lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) {
home.file = generateSystemdFileLinks allUnitFiles;
# if the length of builtQuadlets is 0, then we don't need register the activation script
diff --git a/modules/services/podman-linux/networks.nix b/modules/services/podman/linux/networks.nix
similarity index 88%
rename from modules/services/podman-linux/networks.nix
rename to modules/services/podman/linux/networks.nix
index f495553de..7dc7506ad 100644
--- a/modules/services/podman-linux/networks.nix
+++ b/modules/services/podman/linux/networks.nix
@@ -5,7 +5,13 @@
...
}:
let
- inherit (lib) mkOption types;
+ inherit (lib)
+ mkIf
+ mkOption
+ mkMerge
+ types
+ ;
+ assertions = import ../assertions.nix { inherit lib; };
cfg = config.services.podman;
@@ -180,10 +186,17 @@ in
let
networkQuadlets = lib.mapAttrsToList toQuadletInternal cfg.networks;
in
- lib.mkIf cfg.enable {
- services.podman.internal.quadletDefinitions = networkQuadlets;
- assertions = lib.flatten (map (network: network.assertions) networkQuadlets);
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.networks" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux {
+ services.podman.internal.quadletDefinitions = networkQuadlets;
+ assertions = lib.flatten (map (network: network.assertions) networkQuadlets);
- xdg.configFile."podman/networks.manifest".text = podman-lib.generateManifestText networkQuadlets;
- };
+ xdg.configFile."podman/networks.manifest".text = podman-lib.generateManifestText networkQuadlets;
+ })
+ ]);
}
diff --git a/modules/services/podman-linux/options.nix b/modules/services/podman/linux/options.nix
similarity index 66%
rename from modules/services/podman-linux/options.nix
rename to modules/services/podman/linux/options.nix
index 35bc2c95d..7611a7e8a 100644
--- a/modules/services/podman-linux/options.nix
+++ b/modules/services/podman/linux/options.nix
@@ -1,37 +1,47 @@
-{ lib, pkgs, ... }:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
let
+ inherit (lib) mkEnableOption mkIf mkOption;
+ assertions = import ../assertions.nix { inherit lib; };
+
+ cfg = config.services.podman;
+
# Define the systemd service type
quadletInternalType = lib.types.submodule {
options = {
- assertions = lib.mkOption {
+ assertions = mkOption {
type = with lib.types; listOf unspecified;
default = [ ];
internal = true;
description = "List of Nix type assertions.";
};
- dependencies = lib.mkOption {
+ dependencies = mkOption {
type = with lib.types; listOf package;
default = [ ];
internal = true;
description = "List of systemd service dependencies.";
};
- resourceType = lib.mkOption {
+ resourceType = mkOption {
type = lib.types.str;
default = "";
internal = true;
description = "The type of the podman Quadlet resource.";
};
- serviceName = lib.mkOption {
+ serviceName = mkOption {
type = lib.types.str;
internal = true;
description = "The name of the systemd service.";
};
- source = lib.mkOption {
+ source = mkOption {
type = lib.types.str;
internal = true;
description = "The quadlet source file content.";
@@ -42,13 +52,13 @@ in
{
options.services.podman = {
internal = {
- quadletDefinitions = lib.mkOption {
+ quadletDefinitions = mkOption {
type = lib.types.listOf quadletInternalType;
default = { };
internal = true;
description = "List of quadlet source file content and service names.";
};
- builtQuadlets = lib.mkOption {
+ builtQuadlets = mkOption {
type = with lib.types; attrsOf package;
default = { };
internal = true;
@@ -56,8 +66,11 @@ in
};
};
- package = lib.mkPackageOption pkgs "podman" { };
-
- enableTypeChecks = lib.mkEnableOption "type checks for podman quadlets";
+ enableTypeChecks = mkEnableOption "type checks for podman quadlets";
+ };
+ config = mkIf cfg.enable {
+ assertions = [
+ (assertions.assertPlatform "services.podman.enableTypeChecks" config pkgs lib.platforms.linux)
+ ];
};
}
diff --git a/modules/services/podman-linux/podman-lib.nix b/modules/services/podman/linux/podman-lib.nix
similarity index 100%
rename from modules/services/podman-linux/podman-lib.nix
rename to modules/services/podman/linux/podman-lib.nix
diff --git a/modules/services/podman-linux/services.nix b/modules/services/podman/linux/services.nix
similarity index 78%
rename from modules/services/podman-linux/services.nix
rename to modules/services/podman/linux/services.nix
index 1ffb001dd..3fa84d802 100644
--- a/modules/services/podman-linux/services.nix
+++ b/modules/services/podman/linux/services.nix
@@ -5,20 +5,23 @@
...
}:
let
+ inherit (lib) mkIf mkOption mkMerge;
+ assertions = import ../assertions.nix { inherit lib; };
+
cfg = config.services.podman;
in
{
options.services.podman = {
autoUpdate = {
- enable = lib.mkOption {
+ enable = mkOption {
type = lib.types.bool;
- default = false;
+ default = pkgs.stdenv.hostPlatform.isLinux;
description = "Automatically update the podman images.";
};
- onCalendar = lib.mkOption {
+ onCalendar = mkOption {
type = lib.types.str;
- default = "Sun *-*-* 00:00";
+ default = lib.optionalString pkgs.stdenv.hostPlatform.isLinux "Sun *-*-* 00:00";
description = ''
The systemd `OnCalendar` expression for the update. See
{manpage}`systemd.time(7)` for a description of the format.
@@ -27,9 +30,14 @@ in
};
};
- config = lib.mkIf cfg.enable (
- lib.mkMerge [
- (lib.mkIf cfg.autoUpdate.enable {
+ config = mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.networks" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux (mkMerge [
+ (mkIf cfg.autoUpdate.enable {
systemd.user.services."podman-auto-update" = {
Unit = {
Description = "Podman auto-update service";
@@ -86,6 +94,6 @@ in
}:/bin
'';
}
- ]
- );
+ ]))
+ ]);
}
diff --git a/modules/services/podman-linux/volumes.nix b/modules/services/podman/linux/volumes.nix
similarity index 89%
rename from modules/services/podman-linux/volumes.nix
rename to modules/services/podman/linux/volumes.nix
index 91cfd6bc2..e294248c6 100644
--- a/modules/services/podman-linux/volumes.nix
+++ b/modules/services/podman/linux/volumes.nix
@@ -5,7 +5,13 @@
...
}:
let
- inherit (lib) mkOption types;
+ inherit (lib)
+ mkIf
+ mkOption
+ mkMerge
+ types
+ ;
+ assertions = import ../assertions.nix { inherit lib; };
cfg = config.services.podman;
@@ -192,10 +198,17 @@ in
let
volumeQuadlets = lib.mapAttrsToList toQuadletInternal cfg.volumes;
in
- lib.mkIf cfg.enable {
- services.podman.internal.quadletDefinitions = volumeQuadlets;
- assertions = lib.flatten (map (volume: volume.assertions) volumeQuadlets);
+ mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (assertions.assertPlatform "services.podman.volumes" config pkgs lib.platforms.linux)
+ ];
+ }
+ (mkIf pkgs.stdenv.hostPlatform.isLinux {
+ services.podman.internal.quadletDefinitions = volumeQuadlets;
+ assertions = lib.flatten (map (volume: volume.assertions) volumeQuadlets);
- xdg.configFile."podman/volumes.manifest".text = podman-lib.generateManifestText volumeQuadlets;
- };
+ xdg.configFile."podman/volumes.manifest".text = podman-lib.generateManifestText volumeQuadlets;
+ })
+ ]);
}
diff --git a/tests/modules/services/podman-linux/build-expected.service b/tests/modules/services/podman-linux/build-expected.service
deleted file mode 100644
index 46d6eb133..000000000
--- a/tests/modules/services/podman-linux/build-expected.service
+++ /dev/null
@@ -1,30 +0,0 @@
-# Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
-#
-# Automatically generated by home-manager for podman build configuration
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# my-bld.build
-[X-Build]
-Environment=
-File=/nix/store/00000000000000000000000000000000-Containerfile
-ImageTag=homemanager/my-bld
-Label=nix.home-manager.managed=true
-TLSVerify=true
-
-[Install]
-WantedBy=default.target
-WantedBy=multi-user.target
-
-[Service]
-RemainAfterExit=yes
-TimeoutStartSec=300
-ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman build --tls-verify --tag homemanager/my-bld --label nix.home-manager.managed=true --file /nix/store/00000000000000000000000000000000-Containerfile
-SyslogIdentifier=%N
-Type=oneshot
-
-[Unit]
-Wants=podman-user-wait-network-online.service
-After=podman-user-wait-network-online.service
-Description=Service for build my-bld
-SourcePath=/nix/store/00000000000000000000000000000000-home-build-podman-my-bld/quadlets/podman-my-bld.build
-RequiresMountsFor=%t/containers
diff --git a/tests/modules/services/podman-linux/container-expected.service b/tests/modules/services/podman-linux/container-expected.service
deleted file mode 100644
index afb980358..000000000
--- a/tests/modules/services/podman-linux/container-expected.service
+++ /dev/null
@@ -1,50 +0,0 @@
-# Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
-#
-# Automatically generated by home-manager podman container configuration
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# my-container.container
-[X-Container]
-AddDevice=/dev/null:/dev/null
-AutoUpdate=registry
-ContainerName=my-container
-Entrypoint=/sleep.sh
-Environment=VAL_A=A
-Environment=VAL_B=2
-Environment=VAL_C=false
-Image=docker.io/alpine:latest
-Label=nix.home-manager.managed=true
-Network=mynet
-NetworkAlias=test-alias-1
-NetworkAlias=test-alias-2
-PodmanArgs=--security-opt=no-new-privileges
-PublishPort=8080:80
-ReadOnlyTmpfs=true
-Volume=/tmp:/tmp
-
-[Install]
-WantedBy=default.target
-WantedBy=multi-user.target
-
-[Service]
-Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
-Restart=on-failure
-TimeoutStopSec=30
-Environment=PODMAN_SYSTEMD_UNIT=%n
-KillMode=mixed
-ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
-ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
-Delegate=yes
-Type=notify
-NotifyAccess=all
-SyslogIdentifier=%N
-ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --entrypoint /sleep.sh --network-alias test-alias-1 --network-alias test-alias-2 --read-only-tmpfs --network mynet --sdnotify=conmon -d --device /dev/null:/dev/null -v /tmp:/tmp --label io.containers.autoupdate=registry --publish 8080:80 --env VAL_A=A --env VAL_B=2 --env VAL_C=false --label nix.home-manager.managed=true --security-opt=no-new-privileges docker.io/alpine:latest
-
-[Unit]
-Wants=podman-user-wait-network-online.service
-After=podman-user-wait-network-online.service
-Before=fake.target
-Description=home-manager test
-SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
-RequiresMountsFor=%t/containers
-RequiresMountsFor=/tmp
diff --git a/tests/modules/services/podman-linux/default.nix b/tests/modules/services/podman-linux/default.nix
deleted file mode 100644
index c4d832d4d..000000000
--- a/tests/modules/services/podman-linux/default.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{ lib, pkgs, ... }:
-
-lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
- podman-configuration = ./configuration.nix;
- podman-container = ./container.nix;
- podman-build = ./build.nix;
- podman-image = ./image.nix;
- podman-integration = ./integration.nix;
- podman-manifest = ./manifest.nix;
- podman-network = ./network.nix;
- podman-volume = ./volume.nix;
-}
diff --git a/tests/modules/services/podman-linux/integration-build-expected.service b/tests/modules/services/podman-linux/integration-build-expected.service
deleted file mode 100644
index f8afc5358..000000000
--- a/tests/modules/services/podman-linux/integration-build-expected.service
+++ /dev/null
@@ -1,30 +0,0 @@
-# Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
-#
-# Automatically generated by home-manager for podman build configuration
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# my-bld.build
-[X-Build]
-Environment=
-File=/nix/store/00000000000000000000000000000000-Containerfile
-ImageTag=homemanager/my-bld
-Label=nix.home-manager.managed=true
-TLSVerify=true
-
-[Install]
-WantedBy=default.target
-WantedBy=multi-user.target
-
-[Service]
-RemainAfterExit=yes
-TimeoutStartSec=300
-ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman build --tls-verify --tag homemanager/my-bld --label nix.home-manager.managed=true --file /nix/store/00000000000000000000000000000000-Containerfile
-SyslogIdentifier=%N
-Type=oneshot
-
-[Unit]
-Wants=podman-user-wait-network-online.service
-After=podman-user-wait-network-online.service
-Description=Service for build my-bld
-SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-bld.build
-RequiresMountsFor=%t/containers
diff --git a/tests/modules/services/podman-linux/integration-container-bld-expected.service b/tests/modules/services/podman-linux/integration-container-bld-expected.service
deleted file mode 100644
index 9d410b80d..000000000
--- a/tests/modules/services/podman-linux/integration-container-bld-expected.service
+++ /dev/null
@@ -1,38 +0,0 @@
-# Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
-#
-# Automatically generated by home-manager podman container configuration
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# my-container-bld.container
-[X-Container]
-ContainerName=my-container-bld
-Environment=
-Image=podman-my-bld.build
-Label=nix.home-manager.managed=true
-
-[Install]
-WantedBy=default.target
-WantedBy=multi-user.target
-
-[Service]
-Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
-Restart=always
-TimeoutStopSec=30
-Environment=PODMAN_SYSTEMD_UNIT=%n
-KillMode=mixed
-ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
-ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
-Delegate=yes
-Type=notify
-NotifyAccess=all
-SyslogIdentifier=%N
-ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container-bld --replace --rm --cgroups=split --sdnotify=conmon -d --label nix.home-manager.managed=true homemanager/my-bld
-
-[Unit]
-Wants=podman-user-wait-network-online.service
-After=podman-user-wait-network-online.service
-Description=Service for container my-container-bld
-SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-container-bld.container
-RequiresMountsFor=%t/containers
-Requires=podman-my-bld-build.service
-After=podman-my-bld-build.service
diff --git a/tests/modules/services/podman-linux/integration-container-expected.service b/tests/modules/services/podman-linux/integration-container-expected.service
deleted file mode 100644
index 151fc12cf..000000000
--- a/tests/modules/services/podman-linux/integration-container-expected.service
+++ /dev/null
@@ -1,45 +0,0 @@
-# Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
-#
-# Automatically generated by home-manager podman container configuration
-# DO NOT EDIT THIS FILE DIRECTLY
-#
-# my-container.container
-[X-Container]
-ContainerName=my-container
-Environment=
-Image=podman-my-img.image
-Label=nix.home-manager.managed=true
-Network=podman-my-app.network
-Network=externalnet
-Volume=podman-my-app.volume:/data
-
-[Install]
-WantedBy=default.target
-WantedBy=multi-user.target
-
-[Service]
-Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
-Restart=always
-TimeoutStopSec=30
-Environment=PODMAN_SYSTEMD_UNIT=%n
-KillMode=mixed
-ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
-ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
-Delegate=yes
-Type=notify
-NotifyAccess=all
-SyslogIdentifier=%N
-ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --network my-app --network externalnet --sdnotify=conmon -d -v my-app:/data --label nix.home-manager.managed=true docker.io/alpine:latest
-
-[Unit]
-Wants=podman-user-wait-network-online.service
-After=podman-user-wait-network-online.service
-Description=Service for container my-container
-SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
-RequiresMountsFor=%t/containers
-Requires=podman-my-img-image.service
-After=podman-my-img-image.service
-Requires=podman-my-app-network.service
-After=podman-my-app-network.service
-Requires=podman-my-app-volume.service
-After=podman-my-app-volume.service
diff --git a/tests/modules/services/podman-linux/configuration-containers-expected.conf b/tests/modules/services/podman/configuration-containers-expected.conf
similarity index 100%
rename from tests/modules/services/podman-linux/configuration-containers-expected.conf
rename to tests/modules/services/podman/configuration-containers-expected.conf
diff --git a/tests/modules/services/podman-linux/configuration-mounts-expected.conf b/tests/modules/services/podman/configuration-mounts-expected.conf
similarity index 100%
rename from tests/modules/services/podman-linux/configuration-mounts-expected.conf
rename to tests/modules/services/podman/configuration-mounts-expected.conf
diff --git a/tests/modules/services/podman-linux/configuration-policy-expected.json b/tests/modules/services/podman/configuration-policy-expected.json
similarity index 100%
rename from tests/modules/services/podman-linux/configuration-policy-expected.json
rename to tests/modules/services/podman/configuration-policy-expected.json
diff --git a/tests/modules/services/podman-linux/configuration-registries-expected.conf b/tests/modules/services/podman/configuration-registries-expected.conf
similarity index 100%
rename from tests/modules/services/podman-linux/configuration-registries-expected.conf
rename to tests/modules/services/podman/configuration-registries-expected.conf
diff --git a/tests/modules/services/podman-linux/configuration-storage-expected.conf b/tests/modules/services/podman/configuration-storage-expected.conf
similarity index 100%
rename from tests/modules/services/podman-linux/configuration-storage-expected.conf
rename to tests/modules/services/podman/configuration-storage-expected.conf
diff --git a/tests/modules/services/podman-linux/configuration.nix b/tests/modules/services/podman/configuration.nix
similarity index 82%
rename from tests/modules/services/podman-linux/configuration.nix
rename to tests/modules/services/podman/configuration.nix
index cbbac2be3..001d032ff 100644
--- a/tests/modules/services/podman-linux/configuration.nix
+++ b/tests/modules/services/podman/configuration.nix
@@ -1,3 +1,4 @@
+{ pkgs, ... }:
{
services.podman = {
enable = true;
@@ -46,6 +47,7 @@
storageFile=$configPath/storage.conf
mountsFile=$configPath/mounts.conf
+ # Check that config files are generated on both platforms
assertFileExists $containersFile
assertFileExists $policyFile
assertFileExists $registriesFile
@@ -63,5 +65,16 @@
assertFileContent $registriesFile ${./configuration-registries-expected.conf}
assertFileContent $storageFile ${./configuration-storage-expected.conf}
assertFileContent $mountsFile ${./configuration-mounts-expected.conf}
+
+ ${
+ if pkgs.stdenv.hostPlatform.isDarwin then
+ ''
+ # Darwin-specific: verify that config directory is automatically mounted into podman machines
+ assertFileExists activate
+ assertFileRegex activate '\$HOME/\.config/containers:/home/core/\.config/containers'
+ ''
+ else
+ ""
+ }
'';
}
diff --git a/tests/modules/services/podman/darwin/basic-expected-agent.plist b/tests/modules/services/podman/darwin/basic-expected-agent.plist
new file mode 100644
index 000000000..146a18274
--- /dev/null
+++ b/tests/modules/services/podman/darwin/basic-expected-agent.plist
@@ -0,0 +1,23 @@
+
+
+
+
+ KeepAlive
+
+ Crashed
+
+ SuccessfulExit
+
+
+ Label
+ org.nix-community.home.podman-machine-podman-machine-default
+ ProcessType
+ Background
+ ProgramArguments
+
+ /nix/store/00000000000000000000000000000000-podman-machine-watchdog-podman-machine-default
+
+ RunAtLoad
+
+
+
\ No newline at end of file
diff --git a/tests/modules/services/podman/darwin/basic.nix b/tests/modules/services/podman/darwin/basic.nix
new file mode 100644
index 000000000..f13c88e2e
--- /dev/null
+++ b/tests/modules/services/podman/darwin/basic.nix
@@ -0,0 +1,35 @@
+{
+ services.podman = {
+ enable = true;
+ useDefaultMachine = true;
+ };
+
+ nmt.script = ''
+ serviceDir=LaunchAgents
+
+ # Check that the default machine watchdog launchd service exists
+ agentFile=$serviceDir/org.nix-community.home.podman-machine-podman-machine-default.plist
+ assertFileExists $agentFile
+
+ # Normalize and verify agent file content
+ agentFileNormalized=$(normalizeStorePaths "$agentFile")
+ assertFileContent "$agentFileNormalized" ${./basic-expected-agent.plist}
+
+ # Verify home activation creates the default machine
+ assertFileExists activate
+ assertFileRegex activate 'podman-machine-default'
+ assertFileRegex activate 'podman machine init podman-machine-default'
+ assertFileNotRegex activate '[-][-]cpus'
+ assertFileNotRegex activate '[-][-]disk-size'
+ assertFileNotRegex activate '[-][-]image'
+ assertFileNotRegex activate '[-][-]memory'
+ assertFileNotRegex activate '[-][-]rootful'
+ assertFileNotRegex activate '[-][-]swap'
+ assertFileNotRegex activate '[-][-]timezone'
+ assertFileNotRegex activate '[-][-]username'
+ assertFileNotRegex activate '[-][-]volumes'
+
+ # Verify that config directory is automatically mounted into the machine
+ assertFileRegex activate '\$HOME/\.config/containers:/home/core/\.config/containers'
+ '';
+}
diff --git a/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist b/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist
new file mode 100644
index 000000000..056846e08
--- /dev/null
+++ b/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist
@@ -0,0 +1,23 @@
+
+
+
+
+ KeepAlive
+
+ Crashed
+
+ SuccessfulExit
+
+
+ Label
+ org.nix-community.home.podman-machine-dev-machine
+ ProcessType
+ Background
+ ProgramArguments
+
+ /nix/store/00000000000000000000000000000000-podman-machine-watchdog-dev-machine
+
+ RunAtLoad
+
+
+
\ No newline at end of file
diff --git a/tests/modules/services/podman/darwin/custom-machines.nix b/tests/modules/services/podman/darwin/custom-machines.nix
new file mode 100644
index 000000000..45e3838a1
--- /dev/null
+++ b/tests/modules/services/podman/darwin/custom-machines.nix
@@ -0,0 +1,63 @@
+{
+ services.podman = {
+ enable = true;
+ useDefaultMachine = false;
+ machines = {
+ "dev-machine" = {
+ cpus = 8;
+ memory = 8192;
+ diskSize = 200;
+ rootful = true;
+ autoStart = true;
+ watchdogInterval = 60;
+ };
+ "test-machine" = {
+ cpus = 2;
+ memory = 4096;
+ diskSize = 50;
+ autoStart = false;
+ watchdogInterval = 30;
+ };
+ };
+ };
+
+ nmt.script = ''
+ serviceDir=LaunchAgents
+
+ # Check that dev-machine watchdog exists (has autoStart = true)
+ devAgentFile=$serviceDir/org.nix-community.home.podman-machine-dev-machine.plist
+ assertFileExists $devAgentFile
+
+ # Normalize and verify dev-machine agent file content
+ devAgentFileNormalized=$(normalizeStorePaths "$devAgentFile")
+ assertFileContent "$devAgentFileNormalized" ${./custom-machines-dev-expected-agent.plist}
+
+ # Check that test-machine watchdog does NOT exist (has autoStart = false)
+ testAgentFile=$serviceDir/org.nix-community.home.podman-machine-test-machine.plist
+ assertPathNotExists $testAgentFile
+
+ # Verify home activation creates both machines
+ assertFileExists activate
+
+ # Check dev-machine initialization with custom parameters
+ assertFileRegex activate 'dev-machine'
+ assertFileRegex activate 'podman machine init dev-machine'
+ assertFileRegex activate '[-][-]cpus 8'
+ assertFileRegex activate '[-][-]memory 8192'
+ assertFileRegex activate '[-][-]disk-size 200'
+ assertFileRegex activate '[-][-]rootful'
+
+ # Check test-machine initialization
+ assertFileRegex activate 'test-machine'
+ assertFileRegex activate 'podman machine init test-machine'
+ assertFileRegex activate '[-][-]cpus 2'
+ assertFileRegex activate '[-][-]memory 4096'
+ assertFileRegex activate '[-][-]disk-size 50'
+
+ # Verify default machine is NOT created
+ assertFileNotRegex activate 'podman-machine-default'
+
+ # Verify that config directory is automatically mounted into all machines
+ assertFileRegex activate '\$HOME/\.config/containers:/home/core/\.config/containers'
+ '';
+}
diff --git a/tests/modules/services/podman/darwin/default.nix b/tests/modules/services/podman/darwin/default.nix
new file mode 100644
index 000000000..7a30377e0
--- /dev/null
+++ b/tests/modules/services/podman/darwin/default.nix
@@ -0,0 +1,5 @@
+{
+ podman-darwin-basic = ./basic.nix;
+ podman-darwin-custom-machines = ./custom-machines.nix;
+ podman-darwin-no-default-machine = ./no-default-machine.nix;
+}
diff --git a/tests/modules/services/podman/darwin/no-default-machine.nix b/tests/modules/services/podman/darwin/no-default-machine.nix
new file mode 100644
index 000000000..eba64885f
--- /dev/null
+++ b/tests/modules/services/podman/darwin/no-default-machine.nix
@@ -0,0 +1,20 @@
+{
+ services.podman = {
+ enable = true;
+ useDefaultMachine = false;
+ machines = { };
+ };
+
+ nmt.script = ''
+ serviceDir=LaunchAgents
+
+ # Check that the default machine watchdog launchd service does not exists
+ agentFile=$serviceDir/org.nix-community.home.podman-machine-podman-machine-default.plist
+ assertPathNotExists $agentFile
+
+ # Verify home activation script doesn't create default machine
+ activationScript=activate
+ assertFileExists $activationScript
+ assertFileNotRegex $activationScript 'podman-machine-default'
+ '';
+}
diff --git a/tests/modules/services/podman/default.nix b/tests/modules/services/podman/default.nix
new file mode 100644
index 000000000..c5d8550e9
--- /dev/null
+++ b/tests/modules/services/podman/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+{
+ podman-configuration = ./configuration.nix;
+}
+// (lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin (import ./darwin/default.nix))
+// (lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux (import ./linux/default.nix))
diff --git a/tests/modules/services/podman/linux/build-expected.service b/tests/modules/services/podman/linux/build-expected.service
new file mode 100644
index 000000000..d10233d7c
--- /dev/null
+++ b/tests/modules/services/podman/linux/build-expected.service
@@ -0,0 +1,30 @@
+ # Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
+ #
+ # Automatically generated by home-manager for podman build configuration
+ # DO NOT EDIT THIS FILE DIRECTLY
+ #
+ # my-bld.build
+ [X-Build]
+ Environment=
+ File=/nix/store/00000000000000000000000000000000-Containerfile
+ ImageTag=homemanager/my-bld
+ Label=nix.home-manager.managed=true
+ TLSVerify=true
+
+ [Install]
+ WantedBy=default.target
+ WantedBy=multi-user.target
+
+ [Service]
+ RemainAfterExit=yes
+ TimeoutStartSec=300
+ ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman build --tls-verify --tag homemanager/my-bld --label nix.home-manager.managed=true --file /nix/store/00000000000000000000000000000000-Containerfile
+ SyslogIdentifier=%N
+ Type=oneshot
+
+ [Unit]
+ Wants=podman-user-wait-network-online.service
+ After=podman-user-wait-network-online.service
+ Description=Service for build my-bld
+ SourcePath=/nix/store/00000000000000000000000000000000-home-build-podman-my-bld/quadlets/podman-my-bld.build
+ RequiresMountsFor=%t/containers
diff --git a/tests/modules/services/podman-linux/build.nix b/tests/modules/services/podman/linux/build.nix
similarity index 100%
rename from tests/modules/services/podman-linux/build.nix
rename to tests/modules/services/podman/linux/build.nix
diff --git a/tests/modules/services/podman/linux/container-expected.service b/tests/modules/services/podman/linux/container-expected.service
new file mode 100644
index 000000000..d3f79542b
--- /dev/null
+++ b/tests/modules/services/podman/linux/container-expected.service
@@ -0,0 +1,50 @@
+ # Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
+ #
+ # Automatically generated by home-manager podman container configuration
+ # DO NOT EDIT THIS FILE DIRECTLY
+ #
+ # my-container.container
+ [X-Container]
+ AddDevice=/dev/null:/dev/null
+ AutoUpdate=registry
+ ContainerName=my-container
+ Entrypoint=/sleep.sh
+ Environment=VAL_A=A
+ Environment=VAL_B=2
+ Environment=VAL_C=false
+ Image=docker.io/alpine:latest
+ Label=nix.home-manager.managed=true
+ Network=mynet
+ NetworkAlias=test-alias-1
+ NetworkAlias=test-alias-2
+ PodmanArgs=--security-opt=no-new-privileges
+ PublishPort=8080:80
+ ReadOnlyTmpfs=true
+ Volume=/tmp:/tmp
+
+ [Install]
+ WantedBy=default.target
+ WantedBy=multi-user.target
+
+ [Service]
+ Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
+ Restart=on-failure
+ TimeoutStopSec=30
+ Environment=PODMAN_SYSTEMD_UNIT=%n
+ KillMode=mixed
+ ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
+ ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
+ Delegate=yes
+ Type=notify
+ NotifyAccess=all
+ SyslogIdentifier=%N
+ ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --entrypoint /sleep.sh --network-alias test-alias-1 --network-alias test-alias-2 --read-only-tmpfs --network mynet --sdnotify=conmon -d --device /dev/null:/dev/null -v /tmp:/tmp --label io.containers.autoupdate=registry --publish 8080:80 --env VAL_A=A --env VAL_B=2 --env VAL_C=false --label nix.home-manager.managed=true --security-opt=no-new-privileges docker.io/alpine:latest
+
+ [Unit]
+ Wants=podman-user-wait-network-online.service
+ After=podman-user-wait-network-online.service
+ Before=fake.target
+ Description=home-manager test
+ SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
+ RequiresMountsFor=%t/containers
+ RequiresMountsFor=/tmp
diff --git a/tests/modules/services/podman-linux/container.nix b/tests/modules/services/podman/linux/container.nix
similarity index 100%
rename from tests/modules/services/podman-linux/container.nix
rename to tests/modules/services/podman/linux/container.nix
diff --git a/tests/modules/services/podman/linux/default.nix b/tests/modules/services/podman/linux/default.nix
new file mode 100644
index 000000000..91a9c849a
--- /dev/null
+++ b/tests/modules/services/podman/linux/default.nix
@@ -0,0 +1,9 @@
+{
+ podman-linux-container = ./container.nix;
+ podman-linux-build = ./build.nix;
+ podman-linux-image = ./image.nix;
+ podman-linux-integration = ./integration.nix;
+ podman-linux-manifest = ./manifest.nix;
+ podman-linux-network = ./network.nix;
+ podman-linux-volume = ./volume.nix;
+}
diff --git a/tests/modules/services/podman-linux/image-expected.service b/tests/modules/services/podman/linux/image-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/image-expected.service
rename to tests/modules/services/podman/linux/image-expected.service
diff --git a/tests/modules/services/podman-linux/image.nix b/tests/modules/services/podman/linux/image.nix
similarity index 100%
rename from tests/modules/services/podman-linux/image.nix
rename to tests/modules/services/podman/linux/image.nix
diff --git a/tests/modules/services/podman/linux/integration-build-expected.service b/tests/modules/services/podman/linux/integration-build-expected.service
new file mode 100644
index 000000000..d61bb9832
--- /dev/null
+++ b/tests/modules/services/podman/linux/integration-build-expected.service
@@ -0,0 +1,30 @@
+ # Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
+ #
+ # Automatically generated by home-manager for podman build configuration
+ # DO NOT EDIT THIS FILE DIRECTLY
+ #
+ # my-bld.build
+ [X-Build]
+ Environment=
+ File=/nix/store/00000000000000000000000000000000-Containerfile
+ ImageTag=homemanager/my-bld
+ Label=nix.home-manager.managed=true
+ TLSVerify=true
+
+ [Install]
+ WantedBy=default.target
+ WantedBy=multi-user.target
+
+ [Service]
+ RemainAfterExit=yes
+ TimeoutStartSec=300
+ ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman build --tls-verify --tag homemanager/my-bld --label nix.home-manager.managed=true --file /nix/store/00000000000000000000000000000000-Containerfile
+ SyslogIdentifier=%N
+ Type=oneshot
+
+ [Unit]
+ Wants=podman-user-wait-network-online.service
+ After=podman-user-wait-network-online.service
+ Description=Service for build my-bld
+ SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-bld.build
++RequiresMountsFor=%t/containers
diff --git a/tests/modules/services/podman/linux/integration-container-bld-expected.service b/tests/modules/services/podman/linux/integration-container-bld-expected.service
new file mode 100644
index 000000000..ff7a3fe4b
--- /dev/null
+++ b/tests/modules/services/podman/linux/integration-container-bld-expected.service
@@ -0,0 +1,40 @@
+ # Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
+ #
+ # Automatically generated by home-manager podman container configuration
+ # DO NOT EDIT THIS FILE DIRECTLY
+ #
+ # my-container-bld.container
+ [X-Container]
+ ContainerName=my-container-bld
+ Environment=
+ Image=podman-my-bld.build
+ Label=nix.home-manager.managed=true
+
+ [Install]
+ WantedBy=default.target
+ WantedBy=multi-user.target
+
+ [Service]
++Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
+ Restart=always
+ TimeoutStopSec=30
+ Environment=PODMAN_SYSTEMD_UNIT=%n
+ KillMode=mixed
+ ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
+ ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container-bld
+ Delegate=yes
+ Type=notify
+ NotifyAccess=all
+ SyslogIdentifier=%N
+ ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container-bld --replace --rm --cgroups=split --sdnotify=conmon -d --label nix.home-manager.managed=true homemanager/my-bld
+
+ [Unit]
+ Wants=podman-user-wait-network-online.service
+ After=podman-user-wait-network-online.service
+ Description=Service for container my-container-bld
+ SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container-bld/quadlets/podman-my-container-bld.container
+ RequiresMountsFor=%t/containers
+ Requires=podman-my-bld-build.service
+ After=podman-my-bld-build.service
++++++++ Contents of side #2
+>>>>>>> Conflict 1 of 1 ends
diff --git a/tests/modules/services/podman/linux/integration-container-expected.service b/tests/modules/services/podman/linux/integration-container-expected.service
new file mode 100644
index 000000000..047987e80
--- /dev/null
+++ b/tests/modules/services/podman/linux/integration-container-expected.service
@@ -0,0 +1,45 @@
+ # Automatically generated by /nix/store/00000000000000000000000000000000-podman/lib/systemd/user-generators/podman-user-generator
+ #
+ # Automatically generated by home-manager podman container configuration
+ # DO NOT EDIT THIS FILE DIRECTLY
+ #
+ # my-container.container
+ [X-Container]
+ ContainerName=my-container
+ Environment=
+ Image=podman-my-img.image
+ Label=nix.home-manager.managed=true
+ Network=podman-my-app.network
+ Network=externalnet
+ Volume=podman-my-app.volume:/data
+
+ [Install]
+ WantedBy=default.target
+ WantedBy=multi-user.target
+
+ [Service]
+ Environment=PATH=/run/wrappers/bin:/run/current-system/sw/bin:@nftables@/bin:/home/hm-user/.nix-profile/bin:@systemd@/bin
+ Restart=always
+ TimeoutStopSec=30
+ Environment=PODMAN_SYSTEMD_UNIT=%n
+ KillMode=mixed
+ ExecStop=/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
+ ExecStopPost=-/nix/store/00000000000000000000000000000000-podman/bin/podman rm -v -f -i my-container
+ Delegate=yes
+ Type=notify
+ NotifyAccess=all
+ SyslogIdentifier=%N
+ ExecStart=/nix/store/00000000000000000000000000000000-podman/bin/podman run --name my-container --replace --rm --cgroups=split --network my-app --network externalnet --sdnotify=conmon -d -v my-app:/data --label nix.home-manager.managed=true docker.io/alpine:latest
+
+ [Unit]
+ Wants=podman-user-wait-network-online.service
+ After=podman-user-wait-network-online.service
+ Description=Service for container my-container
+ SourcePath=/nix/store/00000000000000000000000000000000-home-container-podman-my-container/quadlets/podman-my-container.container
+ RequiresMountsFor=%t/containers
+ Requires=podman-my-img-image.service
+ After=podman-my-img-image.service
+ Requires=podman-my-app-network.service
+ After=podman-my-app-network.service
+ Requires=podman-my-app-volume.service
+ After=podman-my-app-volume.service
diff --git a/tests/modules/services/podman-linux/integration-image-expected.service b/tests/modules/services/podman/linux/integration-image-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/integration-image-expected.service
rename to tests/modules/services/podman/linux/integration-image-expected.service
diff --git a/tests/modules/services/podman-linux/integration-network-expected.service b/tests/modules/services/podman/linux/integration-network-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/integration-network-expected.service
rename to tests/modules/services/podman/linux/integration-network-expected.service
diff --git a/tests/modules/services/podman-linux/integration-volume-expected.service b/tests/modules/services/podman/linux/integration-volume-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/integration-volume-expected.service
rename to tests/modules/services/podman/linux/integration-volume-expected.service
diff --git a/tests/modules/services/podman-linux/integration.nix b/tests/modules/services/podman/linux/integration.nix
similarity index 100%
rename from tests/modules/services/podman-linux/integration.nix
rename to tests/modules/services/podman/linux/integration.nix
diff --git a/tests/modules/services/podman-linux/manifest.nix b/tests/modules/services/podman/linux/manifest.nix
similarity index 100%
rename from tests/modules/services/podman-linux/manifest.nix
rename to tests/modules/services/podman/linux/manifest.nix
diff --git a/tests/modules/services/podman-linux/network-expected.service b/tests/modules/services/podman/linux/network-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/network-expected.service
rename to tests/modules/services/podman/linux/network-expected.service
diff --git a/tests/modules/services/podman-linux/network.nix b/tests/modules/services/podman/linux/network.nix
similarity index 100%
rename from tests/modules/services/podman-linux/network.nix
rename to tests/modules/services/podman/linux/network.nix
diff --git a/tests/modules/services/podman-linux/podman-stubs.nix b/tests/modules/services/podman/linux/podman-stubs.nix
similarity index 100%
rename from tests/modules/services/podman-linux/podman-stubs.nix
rename to tests/modules/services/podman/linux/podman-stubs.nix
diff --git a/tests/modules/services/podman-linux/volume-expected.service b/tests/modules/services/podman/linux/volume-expected.service
similarity index 100%
rename from tests/modules/services/podman-linux/volume-expected.service
rename to tests/modules/services/podman/linux/volume-expected.service
diff --git a/tests/modules/services/podman-linux/volume.nix b/tests/modules/services/podman/linux/volume.nix
similarity index 100%
rename from tests/modules/services/podman-linux/volume.nix
rename to tests/modules/services/podman/linux/volume.nix