diff --git a/modules/misc/news/2025/11/2025-11-04_16-44-03.nix b/modules/misc/news/2025/11/2025-11-04_16-44-03.nix new file mode 100644 index 000000000000..fd169e993bf2 --- /dev/null +++ b/modules/misc/news/2025/11/2025-11-04_16-44-03.nix @@ -0,0 +1,34 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + time = "2025-11-04T15:44:03+00:00"; + condition = true; + message = '' + The 'services.podman' module now supports Darwin (macOS) with declarative + machine management. + + On Darwin, podman requires running containers inside a virtual machine. + The new configuration options allow you to declaratively manage podman + machines with automatic creation, configuration, and startup. + + By default, a machine named 'podman-machine-default' will be created + automatically. You can customize machines or disable the default with: + + services.podman.useDefaultMachine = false; + services.podman.machines = { + "my-machine" = { + cpus = 4; + memory = 8192; + diskSize = 100; + autoStart = true; + }; + }; + + The module includes a launchd-based watchdog service that automatically + starts configured machines on login and keeps them running. + ''; +} diff --git a/modules/services/podman/darwin.nix b/modules/services/podman/darwin.nix new file mode 100644 index 000000000000..564430c8b3e0 --- /dev/null +++ b/modules/services/podman/darwin.nix @@ -0,0 +1,324 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (lib) + attrNames + concatStringsSep + filterAttrs + mapAttrs' + mkIf + mkOption + nameValuePair + optionalString + types + ; + + cfg = config.services.podman; + + machineDefinitionType = types.submodule { + options = { + cpus = mkOption { + type = types.ints.positive; + default = 4; + example = 2; + description = "Number of CPUs to allocate to the machine."; + }; + + diskSize = mkOption { + type = types.ints.positive; + default = 100; + example = 200; + description = "Disk size in GB for the machine."; + }; + + 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.ints.positive; + default = 2048; + example = 8192; + description = "Memory in MB to allocate to the machine."; + }; + + rootful = mkOption { + type = types.bool; + default = false; + description = '' + Whether to run the machine in rootful mode. + 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."; + }; + + timezone = mkOption { + type = types.str; + default = "local"; + example = "UTC"; + description = "Timezone to set in the machine."; + }; + + userModeNetworking = mkOption { + type = types.bool; + default = false; + description = '' + Whether to use user-mode networking, routing traffic through a host user-space process. + This may be required for certain network configurations. + ''; + }; + + username = mkOption { + type = types.str; + default = "core"; + description = "Username used in the machine image."; + }; + + 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; + 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: + - 4 CPUs + - 2048 MB RAM + - 100 GB disk + - Rootless mode + - Auto-start enabled + - No swap + - Local timezone + - Standard networking (not user-mode) + - Default username (core) + - Default volume mounts + ''; + }; + + machines = mkOption { + type = types.attrsOf machineDefinitionType; + default = { }; + description = "Declarative podman machine configurations."; + example = lib.literalExpression '' + { + "dev-machine" = { + cpus = 4; + diskSize = 100; + memory = 8192; + rootful = false; + swap = 2048; + timezone = "UTC"; + userModeNetworking = false; + volumes = [ + "/Users:/Users" + "/private:/private" + ]; + autoStart = true; + watchdogInterval = 30; + }; + "testing" = { + cpus = 2; + diskSize = 50; + image = "ghcr.io/your-org/custom-image:latest"; + memory = 4096; + rootful = false; + username = "podman"; + autoStart = false; + }; + } + ''; + }; + }; + + config = + let + podmanCmd = lib.getExe cfg.package; + allMachines = + cfg.machines + // ( + if cfg.useDefaultMachine then + { + "podman-machine-default" = { + cpus = 4; + diskSize = 100; + image = null; + memory = 2048; + rootful = false; + swap = null; + timezone = "local"; + userModeNetworking = false; + username = "core"; + volumes = [ ]; + autoStart = true; + watchdogInterval = 30; + }; + } + else + { } + ); + autoStartMachines = filterAttrs (_name: machine: machine.autoStart) allMachines; + in + mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isDarwin) { + assertions = [ + { + assertion = pkgs.stdenv.hostPlatform.isDarwin; + message = '' + Podman Darwin-specific options are configured, but you are not on a Darwin (macOS) system. + The following options are only available on macOS: + - services.podman.machines + - services.podman.useDefaultMachine + + Please remove these Darwin-specific configurations from your home-manager configuration. + ''; + } + ]; + + home.activation.podmanMachines = + let + mkMachineInitScript = + name: machine: + let + # Automatically mount host's container config into the VM + configVolume = "$HOME/.config/containers:/home/${machine.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} \ + --cpus ${toString machine.cpus} \ + --disk-size ${toString machine.diskSize} \ + ${optionalString (machine.image != null) "--image ${machine.image}"} \ + --memory ${toString machine.memory} \ + ${optionalString machine.rootful "--rootful"} \ + ${optionalString (machine.swap != null) "--swap ${toString machine.swap}"} \ + --timezone "${machine.timezone}" \ + ${optionalString machine.userModeNetworking "--user-mode-networking"} \ + --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 ecabeec99bed..b7f2a67ca0ec 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 98% rename from modules/services/podman-linux/builds.nix rename to modules/services/podman/linux/builds.nix index 087f7b68e68f..be5d3e87c793 100644 --- a/modules/services/podman-linux/builds.nix +++ b/modules/services/podman/linux/builds.nix @@ -182,7 +182,7 @@ in let buildQuadlets = lib.mapAttrsToList toQuadletInternal cfg.builds; in - lib.mkIf cfg.enable { + lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) { services.podman.internal.quadletDefinitions = buildQuadlets; assertions = lib.flatten (map (build: build.assertions) buildQuadlets); diff --git a/modules/services/podman-linux/containers.nix b/modules/services/podman/linux/containers.nix similarity index 99% rename from modules/services/podman-linux/containers.nix rename to modules/services/podman/linux/containers.nix index 384190f33ffe..329bb939a11d 100644 --- a/modules/services/podman-linux/containers.nix +++ b/modules/services/podman/linux/containers.nix @@ -401,7 +401,7 @@ in let containerQuadlets = lib.mapAttrsToList toQuadletInternal cfg.containers; in - lib.mkIf cfg.enable { + lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) { services.podman.internal.quadletDefinitions = containerQuadlets; assertions = lib.flatten (map (container: container.assertions) containerQuadlets); diff --git a/modules/services/podman/linux/default.nix b/modules/services/podman/linux/default.nix new file mode 100644 index 000000000000..fcbd59bdf8c6 --- /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 98% rename from modules/services/podman-linux/images.nix rename to modules/services/podman/linux/images.nix index 275896183051..4493feeafac6 100644 --- a/modules/services/podman-linux/images.nix +++ b/modules/services/podman/linux/images.nix @@ -165,7 +165,7 @@ in let imageQuadlets = lib.mapAttrsToList toQuadletInternal cfg.images; in - lib.mkIf cfg.enable { + lib.mkIf (cfg.enable && 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 a5326121f87b..5e7ade3de06b 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 98% rename from modules/services/podman-linux/networks.nix rename to modules/services/podman/linux/networks.nix index f495553de921..f142d45086f2 100644 --- a/modules/services/podman-linux/networks.nix +++ b/modules/services/podman/linux/networks.nix @@ -180,7 +180,7 @@ in let networkQuadlets = lib.mapAttrsToList toQuadletInternal cfg.networks; in - lib.mkIf cfg.enable { + lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) { services.podman.internal.quadletDefinitions = networkQuadlets; assertions = lib.flatten (map (network: network.assertions) networkQuadlets); diff --git a/modules/services/podman-linux/options.nix b/modules/services/podman/linux/options.nix similarity index 60% rename from modules/services/podman-linux/options.nix rename to modules/services/podman/linux/options.nix index 35bc2c95d2dd..b25233c29bfe 100644 --- a/modules/services/podman-linux/options.nix +++ b/modules/services/podman/linux/options.nix @@ -1,6 +1,13 @@ -{ lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.services.podman; + # Define the systemd service type quadletInternalType = lib.types.submodule { options = { @@ -38,6 +45,15 @@ let }; }; }; + + # Check if any Linux-specific options are configured + hasLinuxConfig = + cfg.containers != { } + || cfg.builds != { } + || cfg.images != { } + || cfg.networks != { } + || cfg.volumes != { } + || cfg.enableTypeChecks; in { options.services.podman = { @@ -56,8 +72,27 @@ in }; }; - package = lib.mkPackageOption pkgs "podman" { }; - enableTypeChecks = lib.mkEnableOption "type checks for podman quadlets"; }; + + config = lib.mkIf (cfg.enable && hasLinuxConfig) { + assertions = [ + { + assertion = pkgs.stdenv.hostPlatform.isLinux; + message = '' + Podman Linux-specific options (quadlets) are configured, but you are not on a Linux system. + The following options are only available on Linux: + - services.podman.containers + - services.podman.builds + - services.podman.images + - services.podman.networks + - services.podman.volumes + - services.podman.enableTypeChecks + - services.podman.autoUpdate + + Please remove these Linux-specific configurations from your home-manager configuration. + ''; + } + ]; + }; } 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 97% rename from modules/services/podman-linux/services.nix rename to modules/services/podman/linux/services.nix index 1ffb001dd4d5..4eb36912d8a9 100644 --- a/modules/services/podman-linux/services.nix +++ b/modules/services/podman/linux/services.nix @@ -27,7 +27,7 @@ in }; }; - config = lib.mkIf cfg.enable ( + config = lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) ( lib.mkMerge [ (lib.mkIf cfg.autoUpdate.enable { systemd.user.services."podman-auto-update" = { diff --git a/modules/services/podman-linux/volumes.nix b/modules/services/podman/linux/volumes.nix similarity index 98% rename from modules/services/podman-linux/volumes.nix rename to modules/services/podman/linux/volumes.nix index 91cfd6bc204a..86dc710369ee 100644 --- a/modules/services/podman-linux/volumes.nix +++ b/modules/services/podman/linux/volumes.nix @@ -192,7 +192,7 @@ in let volumeQuadlets = lib.mapAttrsToList toQuadletInternal cfg.volumes; in - lib.mkIf cfg.enable { + lib.mkIf (cfg.enable && pkgs.stdenv.hostPlatform.isLinux) { services.podman.internal.quadletDefinitions = volumeQuadlets; assertions = lib.flatten (map (volume: volume.assertions) volumeQuadlets); 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 cbbac2be3f9f..001d032ff9c2 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 000000000000..146a182749c0 --- /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 000000000000..3b16dee51311 --- /dev/null +++ b/tests/modules/services/podman/darwin/basic.nix @@ -0,0 +1,29 @@ +{ + 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' + assertFileRegex activate '[-][-]cpus 4' + assertFileRegex activate '[-][-]memory 2048' + assertFileRegex activate '[-][-]disk-size 100' + + # 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 000000000000..056846e085b5 --- /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 000000000000..9756c87f5555 --- /dev/null +++ b/tests/modules/services/podman/darwin/custom-machines.nix @@ -0,0 +1,64 @@ +{ + 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; + rootful = false; + 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 000000000000..7a30377e0414 --- /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 000000000000..eba64885fdd8 --- /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 000000000000..c5d8550e92aa --- /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 similarity index 100% rename from tests/modules/services/podman-linux/build-expected.service rename to tests/modules/services/podman/linux/build-expected.service 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 similarity index 100% rename from tests/modules/services/podman-linux/container-expected.service rename to tests/modules/services/podman/linux/container-expected.service 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 similarity index 67% rename from tests/modules/services/podman-linux/default.nix rename to tests/modules/services/podman/linux/default.nix index c4d832d4dbdf..d5c9b4948677 100644 --- a/tests/modules/services/podman-linux/default.nix +++ b/tests/modules/services/podman/linux/default.nix @@ -1,7 +1,4 @@ -{ lib, pkgs, ... }: - -lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { - podman-configuration = ./configuration.nix; +{ podman-container = ./container.nix; podman-build = ./build.nix; podman-image = ./image.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 similarity index 100% rename from tests/modules/services/podman-linux/integration-build-expected.service rename to tests/modules/services/podman/linux/integration-build-expected.service diff --git a/tests/modules/services/podman-linux/integration-container-bld-expected.service b/tests/modules/services/podman/linux/integration-container-bld-expected.service similarity index 100% rename from tests/modules/services/podman-linux/integration-container-bld-expected.service rename to tests/modules/services/podman/linux/integration-container-bld-expected.service diff --git a/tests/modules/services/podman-linux/integration-container-expected.service b/tests/modules/services/podman/linux/integration-container-expected.service similarity index 100% rename from tests/modules/services/podman-linux/integration-container-expected.service rename to tests/modules/services/podman/linux/integration-container-expected.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