WIP: New module for handling podman pod
Handles basic container, needs to be expanded to all options
This commit is contained in:
parent
3fbf5735fe
commit
c243852601
1 changed files with 170 additions and 0 deletions
170
modules/virtualisation/podman-pod.nix
Normal file
170
modules/virtualisation/podman-pod.nix
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
# Save this as podman-pod.nix
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.podmanPods;
|
||||||
|
|
||||||
|
podOptions = { name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Name of the pod";
|
||||||
|
};
|
||||||
|
ports = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of port mappings (e.g. ['8080:80'])";
|
||||||
|
};
|
||||||
|
containers = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
image = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Docker image for the container";
|
||||||
|
};
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "Additional options for the container";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = { };
|
||||||
|
description = "Containers to run in the pod";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
createPodScript = name: podDef:
|
||||||
|
let
|
||||||
|
podDefinitionString = builtins.toJSON { inherit (podDef) ports; };
|
||||||
|
in
|
||||||
|
pkgs.writeScript "manage-pod-${name}.sh" ''
|
||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p htop curl
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
POD_NAME="${name}"
|
||||||
|
POD_DEFINITION='${podDefinitionString}'
|
||||||
|
|
||||||
|
create_pod() {
|
||||||
|
podman pod create --name "$POD_NAME" \
|
||||||
|
${concatStringsSep " " (map (port: "--publish ${port}") podDef.ports)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if podman pod exists "$POD_NAME"; then
|
||||||
|
CURRENT_CONFIG=$(podman pod inspect "$POD_NAME" | jq -c '.[0] | {ports: [.PortMappings[].HostPort | tostring + ":" + (.ContainerPort | tostring)]}')
|
||||||
|
if [ "$CURRENT_CONFIG" != "$POD_DEFINITION" ]; then
|
||||||
|
echo "Pod configuration has changed. Recreating pod..."
|
||||||
|
podman pod rm -f "$POD_NAME"
|
||||||
|
create_pod
|
||||||
|
else
|
||||||
|
echo "Pod configuration unchanged."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Pod does not exist. Creating..."
|
||||||
|
create_pod
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.podmanPods = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule podOptions);
|
||||||
|
default = { };
|
||||||
|
description = "Podman pods to create";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg != { }) {
|
||||||
|
virtualisation.podman.enable = true;
|
||||||
|
virtualisation.oci-containers.backend = "podman";
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.jq ];
|
||||||
|
|
||||||
|
systemd.services = mapAttrs'
|
||||||
|
(name: podDef:
|
||||||
|
nameValuePair "podman-pod-${name}" {
|
||||||
|
description = "Manage Podman pod: ${name}";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${createPodScript name podDef}";
|
||||||
|
};
|
||||||
|
path = [ pkgs.podman ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cfg //
|
||||||
|
mapAttrs'
|
||||||
|
(podName: podDef:
|
||||||
|
nameValuePair "podman-pod-${podName}" {
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cfg //
|
||||||
|
mapAttrs'
|
||||||
|
(podName: podDef:
|
||||||
|
nameValuePair "podman-${podName}" {
|
||||||
|
after = [ "podman-pod-${podName}.service" ];
|
||||||
|
requires = [ "podman-pod-${podName}.service" ];
|
||||||
|
partOf = [ "podman-pod-${podName}.service" ];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(flattenAttrs (mapAttrsToList
|
||||||
|
(podName: podDef:
|
||||||
|
mapAttrs'
|
||||||
|
(containerName: containerDef:
|
||||||
|
nameValuePair "${podName}-${containerName}" containerDef
|
||||||
|
)
|
||||||
|
podDef.containers
|
||||||
|
)
|
||||||
|
cfg));
|
||||||
|
|
||||||
|
virtualisation.oci-containers.containers = flatten (mapAttrsToList
|
||||||
|
(podName: podDef:
|
||||||
|
mapAttrsToList
|
||||||
|
(containerName: containerDef:
|
||||||
|
nameValuePair "${podName}-${containerName}" ({
|
||||||
|
inherit (containerDef) image;
|
||||||
|
extraOptions = [ "--pod=${podName}" ] ++ containerDef.extraOptions;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
podDef.containers
|
||||||
|
)
|
||||||
|
cfg);
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = flatten (mapAttrsToList
|
||||||
|
(name: podDef:
|
||||||
|
map (portMapping: lib.toInt (lib.head (lib.splitString ":" portMapping))) podDef.ports
|
||||||
|
)
|
||||||
|
cfg);
|
||||||
|
|
||||||
|
# systemd.services = mapAttrs'
|
||||||
|
# (podName: podDef:
|
||||||
|
# nameValuePair "podman-pod-${podName}" {
|
||||||
|
# after = [ "network.target" ];
|
||||||
|
# wantedBy = [ "multi-user.target" ];
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# cfg //
|
||||||
|
# mapAttrs'
|
||||||
|
# (podName: podDef:
|
||||||
|
# nameValuePair "podman-${podName}" {
|
||||||
|
# after = [ "podman-pod-${podName}.service" ];
|
||||||
|
# requires = [ "podman-pod-${podName}.service" ];
|
||||||
|
# partOf = [ "podman-pod-${podName}.service" ];
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
# (flattenAttrs (mapAttrsToList
|
||||||
|
# (podName: podDef:
|
||||||
|
# mapAttrs'
|
||||||
|
# (containerName: containerDef:
|
||||||
|
# nameValuePair "${podName}-${containerName}" containerDef
|
||||||
|
# )
|
||||||
|
# podDef.containers
|
||||||
|
# )
|
||||||
|
# cfg));
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue