diff --git a/modules/virtualisation/podman-pod.nix b/modules/virtualisation/podman-pod.nix index 814a7d7..788382b 100644 --- a/modules/virtualisation/podman-pod.nix +++ b/modules/virtualisation/podman-pod.nix @@ -18,19 +18,22 @@ let 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"; - }; - }; - }); + 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"; }; @@ -42,13 +45,11 @@ 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 - + #! /bin/sh set -e POD_NAME="${name}" - POD_DEFINITION='${podDefinitionString}' + POD_DEFINITION="${podDefinitionString}" create_pod() { podman pod create --name "$POD_NAME" \ @@ -56,7 +57,9 @@ let } if podman pod exists "$POD_NAME"; then - CURRENT_CONFIG=$(podman pod inspect "$POD_NAME" | jq -c '.[0] | {ports: [.PortMappings[].HostPort | tostring + ":" + (.ContainerPort | tostring)]}') + CURRENT_CONFIG=$(podman pod inspect "$POD_NAME" | jq -c '{ports: .[0].InfraConfig.PortBindings | to_entries | map("\(.value[0].HostPort):\(.key | split("/")[0])") | sort'}) + echo "POD_DEFINITION: $POD_DEFINITION" + echo "CURRENT_CONFIG: $CURRENT_CONFIG" if [ "$CURRENT_CONFIG" != "$POD_DEFINITION" ]; then echo "Pod configuration has changed. Recreating pod..." podman pod rm -f "$POD_NAME" @@ -83,46 +86,7 @@ in 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 + virtualisation.oci-containers.containers = listToAttrs (flatten (mapAttrsToList (podName: podDef: mapAttrsToList (containerName: containerDef: @@ -133,7 +97,7 @@ in ) podDef.containers ) - cfg); + cfg)); networking.firewall.allowedTCPPorts = flatten (mapAttrsToList (name: podDef: @@ -141,30 +105,32 @@ in ) 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)); + systemd.services = + let + podServices = mapAttrs' + (name: podDef: + nameValuePair "podman-pod-${name}" { + description = "Manage Podman pod: ${name}"; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${createPodScript name podDef}"; + }; + path = [ pkgs.jq pkgs.podman ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + } + ) + cfg; + containerServices = mapAttrs' + (name: container: + nameValuePair "podman-${name}" { + after = [ "podman-pod-${lib.head (lib.splitString "-" name)}.service" ]; + requires = [ "podman-pod-${lib.head (lib.splitString "-" name)}.service" ]; + partOf = [ "podman-pod-${lib.head (lib.splitString "-" name)}.service" ]; + } + ) + config.virtualisation.oci-containers.containers; + in + podServices // containerServices; }; }