diff --git a/configs/nixos/guests/romm.nix b/configs/nixos/guests/romm.nix new file mode 100644 index 0000000..44ab9a5 --- /dev/null +++ b/configs/nixos/guests/romm.nix @@ -0,0 +1,228 @@ +{ + 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."; + }; + + 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"; + } + ]; + + registry."stable-uid".${config.networking.hostName} = { + romm = 20005; + "redis-romm" = 20006; + }; + + guests.romm = { + interior = { + networking.firewall.allowedTCPPorts = [ 80 ]; + + services.romm = { + enable = true; + group = "storage"; + database.createLocally = true; + redis.createLocally = true; + watcher.enable = true; + nginx.virtualHost = cfg.reverseProxy.route.domain; + inherit environmentFile; + }; + + users.users = { + romm.uid = rommUid; + redis-romm.uid = redisUid; + }; + }; + + 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.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}} + STEAMGRIDDB_API_KEY=${config.sops.placeholder.${cfg.steamGridDbApiKeySecret}} + ''; + }; + }; +} diff --git a/configs/nixos/hosts/pikachu/default.nix b/configs/nixos/hosts/pikachu/default.nix index b7bdf4d..856759c 100644 --- a/configs/nixos/hosts/pikachu/default.nix +++ b/configs/nixos/hosts/pikachu/default.nix @@ -88,6 +88,26 @@ }; }; + guests.romm = { + enable = true; + vlan = 20; + address = "10.23.20.44"; + dataPath = "/pikachu/data/romm"; + postgresqlPath = "/pikachu/data/romm/postgresql"; + redisPath = "/pikachu/data/romm/redis"; + romsPath = "/pikachu/media/games/emulation/roms"; + biosPath = "/pikachu/media/games/emulation/bios"; + usersPath = "/pikachu/media/games/emulation/users"; + reverseProxy = { + enable = true; + route = { + domain = "romm.alexion.dev"; + protocol = "https"; + port = 80; + }; + }; + }; + guests.reverse-proxy = { enable = true; vlan = 20; diff --git a/configs/nixos/registry/stable-uid.nix b/configs/nixos/registry/stable-uid.nix index 055bbea..06f821b 100644 --- a/configs/nixos/registry/stable-uid.nix +++ b/configs/nixos/registry/stable-uid.nix @@ -12,7 +12,7 @@ let in { - # Next stable UID: 20005 + # Next stable UID: 20007 type = lib.types.ints.positive;