{ config, lib, ... }: let cfg = config.guests.romm; environmentFile = "/run/secrets/romm.env"; rommUid = config.registry."stable-uid".${config.networking.hostName}.romm; redisUid = config.registry."stable-uid".${config.networking.hostName}."redis-romm"; in { options.guests.romm = { dataPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/romm"; description = "Host path mounted as RomM application data."; }; postgresqlPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/romm/postgresql"; description = "Host path mounted as RomM's PostgreSQL data."; }; redisPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/romm/redis"; description = "Host path mounted as RomM's Redis data."; }; romsPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/roms"; description = "Host path mounted as RomM's ROM library."; }; biosPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/bios"; description = "Host path mounted as RomM's BIOS library."; }; usersPath = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; example = "/srv/romm/users"; description = "Host path mounted as RomM's user assets."; }; igdbClientIdSecret = lib.mkOption { type = lib.types.str; default = "services/romm/igdb/client-id"; description = "SOPS secret name containing RomM's IGDB client ID."; }; igdbClientSecretSecret = lib.mkOption { type = lib.types.str; default = "services/romm/igdb/client-secret"; description = "SOPS secret name containing RomM's IGDB client secret."; }; screenScraperUserSecret = lib.mkOption { type = lib.types.str; default = "services/romm/screenscraper/user"; description = "SOPS secret name containing RomM's ScreenScraper user name."; }; screenScraperPasswordSecret = lib.mkOption { type = lib.types.str; default = "services/romm/screenscraper/password"; description = "SOPS secret name containing RomM's ScreenScraper password."; }; retroAchievementsApiKeySecret = lib.mkOption { type = lib.types.str; default = "services/romm/retroachievements/api-key"; description = "SOPS secret name containing RomM's RetroAchievements API key."; }; steamGridDbApiKeySecret = lib.mkOption { type = lib.types.str; default = "services/romm/steamgriddb/api-key"; description = "SOPS secret name containing RomM's SteamGridDB API key."; }; }; config = lib.mkIf cfg.enable { assertions = map (path: { assertion = path.value != null; message = "guests.romm.${path.name} must point at the host directory that stores ${path.description}."; }) [ { name = "dataPath"; value = cfg.dataPath; description = "RomM application data"; } { name = "postgresqlPath"; value = cfg.postgresqlPath; description = "RomM PostgreSQL data"; } { name = "redisPath"; value = cfg.redisPath; description = "RomM Redis data"; } { name = "romsPath"; value = cfg.romsPath; description = "RomM's ROM library"; } { name = "biosPath"; value = cfg.biosPath; description = "RomM's BIOS library"; } { name = "usersPath"; value = cfg.usersPath; description = "RomM's user assets"; } ]; guests.romm = { interior.modules.services.romm = { enable = true; virtualHost = cfg.reverseProxy.route.domain; }; mounts = { "/var/lib/romm" = { directory = cfg.dataPath; owner = rommUid; group = "storage"; mode = "2770"; }; "/var/lib/postgresql" = { directory = cfg.postgresqlPath; owner = config.ids.uids.postgres; group = "storage"; mode = "0700"; }; "/var/lib/redis-romm" = { directory = cfg.redisPath; owner = redisUid; group = "storage"; mode = "0700"; }; "/var/lib/romm/library/roms" = { directory = cfg.romsPath; owner = rommUid; group = "storage"; mode = "2770"; }; "/var/lib/romm/library/bios" = { directory = cfg.biosPath; owner = rommUid; group = "storage"; mode = "2770"; }; "/var/lib/romm/assets/users" = { directory = cfg.usersPath; owner = rommUid; group = "storage"; mode = "2770"; }; ${environmentFile} = { file = config.sops.templates."romm.env".path; readOnly = true; }; }; limits = { memory = lib.mkDefault "4G"; cpu = lib.mkDefault "200%"; tasksMax = lib.mkDefault 512; }; }; sops.secrets = lib.genAttrs [ cfg.igdbClientIdSecret cfg.igdbClientSecretSecret cfg.screenScraperUserSecret cfg.screenScraperPasswordSecret cfg.retroAchievementsApiKeySecret cfg.steamGridDbApiKeySecret ] (_: { sopsFile = ../secrets + "/${config.networking.hostName}.yaml"; }); sops.templates."romm.env" = { owner = "root"; group = "storage"; mode = "0440"; content = '' IGDB_CLIENT_ID=${config.sops.placeholder.${cfg.igdbClientIdSecret}} IGDB_CLIENT_SECRET=${config.sops.placeholder.${cfg.igdbClientSecretSecret}} SCREENSCRAPER_USER=${config.sops.placeholder.${cfg.screenScraperUserSecret}} SCREENSCRAPER_PASSWORD=${config.sops.placeholder.${cfg.screenScraperPasswordSecret}} RETROACHIEVEMENTS_API_KEY=${config.sops.placeholder.${cfg.retroAchievementsApiKeySecret}} STEAMGRIDDB_API_KEY=${config.sops.placeholder.${cfg.steamGridDbApiKeySecret}} ''; }; }; }