mirror of
https://github.com/nix-community/home-manager.git
synced 2026-01-10 08:59:24 +08:00
podman: add darwin support with machine management
- restructure module from `podman-linux` to platform-agnostic `podman` - move linux-specific implementation to `modules/services/podman/linux/` - add darwin module with declarative machine management - implement launchd-based watchdog for auto-starting machines - maintains backward compatibility with existing linux functionality
This commit is contained in:
committed by
Austin Horstman
parent
297a085108
commit
f4bcc1ae1c
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -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":
|
||||
|
||||
23
modules/services/podman/assertions.nix
Normal file
23
modules/services/podman/assertions.nix
Normal file
@@ -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}'';
|
||||
};
|
||||
}
|
||||
301
modules/services/podman/darwin.nix
Normal file
301
modules/services/podman/darwin.nix
Normal file
@@ -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;
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -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;
|
||||
})
|
||||
]);
|
||||
}
|
||||
12
modules/services/podman/linux/default.nix
Normal file
12
modules/services/podman/linux/default.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
imports = [
|
||||
./options.nix
|
||||
./builds.nix
|
||||
./containers.nix
|
||||
./images.nix
|
||||
./install-quadlet.nix
|
||||
./networks.nix
|
||||
./services.nix
|
||||
./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;
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -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)
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
'';
|
||||
}
|
||||
]
|
||||
);
|
||||
]))
|
||||
]);
|
||||
}
|
||||
@@ -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;
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
""
|
||||
}
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>Crashed</key>
|
||||
<true/>
|
||||
<key>SuccessfulExit</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Label</key>
|
||||
<string>org.nix-community.home.podman-machine-podman-machine-default</string>
|
||||
<key>ProcessType</key>
|
||||
<string>Background</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/nix/store/00000000000000000000000000000000-podman-machine-watchdog-podman-machine-default</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
35
tests/modules/services/podman/darwin/basic.nix
Normal file
35
tests/modules/services/podman/darwin/basic.nix
Normal file
@@ -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'
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>Crashed</key>
|
||||
<true/>
|
||||
<key>SuccessfulExit</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Label</key>
|
||||
<string>org.nix-community.home.podman-machine-dev-machine</string>
|
||||
<key>ProcessType</key>
|
||||
<string>Background</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/nix/store/00000000000000000000000000000000-podman-machine-watchdog-dev-machine</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
63
tests/modules/services/podman/darwin/custom-machines.nix
Normal file
63
tests/modules/services/podman/darwin/custom-machines.nix
Normal file
@@ -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'
|
||||
'';
|
||||
}
|
||||
5
tests/modules/services/podman/darwin/default.nix
Normal file
5
tests/modules/services/podman/darwin/default.nix
Normal file
@@ -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;
|
||||
}
|
||||
20
tests/modules/services/podman/darwin/no-default-machine.nix
Normal file
20
tests/modules/services/podman/darwin/no-default-machine.nix
Normal file
@@ -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'
|
||||
'';
|
||||
}
|
||||
6
tests/modules/services/podman/default.nix
Normal file
6
tests/modules/services/podman/default.nix
Normal file
@@ -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))
|
||||
30
tests/modules/services/podman/linux/build-expected.service
Normal file
30
tests/modules/services/podman/linux/build-expected.service
Normal file
@@ -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
|
||||
@@ -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
|
||||
9
tests/modules/services/podman/linux/default.nix
Normal file
9
tests/modules/services/podman/linux/default.nix
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user