Compose runner

{
  lib,
  pkgs,
  config,
  ...
}: let
  cfg = config.dr460nixed.compose-runner;
in {
  options.dr460nixed.compose-runner = lib.mkOption (with lib; {
    type = types.attrsOf (types.submodule {
      options = {
        source = mkOption {
          default = null;
          description = "Folder containing a compose file.";
          type = types.path;
        };
        envfile = mkOption {
          default = null;
          description = "Direct path to a valid .env file";
          type = types.nullOr types.path;
        };
      };
    });
    default = {};
  });

  config = {
    systemd.services =
      lib.mapAttrs'
      (name: value:
        lib.nameValuePair ("compose-runner-" + name) (
          let
            output = derivation {
              builder = pkgs.writeShellScript "build" ''
                PATH="${pkgs.rsync}/bin:${pkgs.coreutils}/bin:${pkgs.gnused}/bin"
                set -e
                mkdir "$out"
                sed -r 's/(^\s+restart:\s*)(unless-stopped|always)(\s*($|#))/\1on-failure\3/g' "$src/compose.yml" > "$out/compose.yml"
                rsync -a "$src/" "$out"
              '';
              name = "compose-runner-" + name;
              src = value.source;
              inherit (pkgs.hostPlatform) system;
            };
            statepath = "/var/compose-runner/${name}";
          in {
            description = "Compose runner for ${name}";
            path = with pkgs; [rsync docker-compose podman bash];
            serviceConfig = {
              ExecStart = pkgs.writeShellScript ("execstart-compose-runner-" + name) ''
                set -e
                mkdir -p "${statepath}"
                rsync -a --no-owner --size-only "${output}/" "${statepath}"
                ${lib.optionalString (value.envfile != null) ''
                  cp "${value.envfile}" "${statepath}/.env"
                  chmod 600 "${statepath}/.env"
                ''}
                cd "${statepath}"
                docker-compose up
              '';
              ExecStopPost = pkgs.writeShellScript ("execstop-compose-runner-" + name) ''
                set -e
                cd "${statepath}"
                docker-compose down
              '';
            };
            unitConfig = {
              After = "podman.socket";
              Requisite = "podman.socket";
              StopPropagatedFrom = "podman.socket";
            };
            wantedBy = ["multi-user.target"];
          }
        ))
      cfg;
    environment.systemPackages = lib.mkIf (cfg != {}) [pkgs.docker-compose];
    virtualisation.podman.enable = lib.mkIf (cfg != {}) true;
    networking.firewall.interfaces."podman1".allowedUDPPorts = lib.mkIf (cfg != {}) [53];
    virtualisation.podman.defaultNetwork.settings = {dns_enabled = true;};
  };
}