1
Fork 0

Set up a glass server instance for lapetus

This commit is contained in:
prescientmoon 2025-02-07 16:02:22 +01:00
commit 57ff202599
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
13 changed files with 267 additions and 45 deletions
hosts/nixos/lapetus

View file

@ -9,6 +9,8 @@ forgejo_mail_password: ENC[AES256_GCM,data:linrpmA8b+8e1+tWNl0=,iv:Mk7suPq0Jt960
javi_password: ENC[AES256_GCM,data:5Ifh/DclUz0/AL69Th/GckolrjerLOnDW77SOf+/L3v39T+EOYgK2GDNKtWGGWYX5sdxZ9JwLS3ZVsIOnN4zjFhgV+GChJWkkzjdpJEtpHlmmBKlyS31Fw7SixVkL3y3VJhw72aVv3bMKQ==,iv:FzAmvIlrhna5InsQCRrWVdrKZGmHMb0njWdvgBurdYs=,tag:/Iguu2FbdV/4RSGTnFdyYA==,type:str]
vpn_env: ENC[AES256_GCM,data:+61Ft1xj1WnaGH6SdUj3sQunDeTWTQ/G2GVQr1KxXVmLehAdO3W2qwqPRsq0qaad3E6eXd7kMU78w1/9fXM34mJXArmXNPW1X+0549+NX4t3QVP83cIRw6B5vwlWMIA8ixEk46a+t7/C6A10hqpyhqHmeyQEOwJvG+Pou61lBmhSkMQy5gjH4ZNsHHZV0/6ZxSk0yAPQq76cPz4dFvyDzdonLnb+2s1KhHC3D7P6SfuWnfJ1EglrDT8R+A==,iv:mw26zTyFnq9CjN06eRmBTWNjh6SRDY7WOCyhBCmyglg=,tag:cPJvzgtruQNLSg7B+br6xQ==,type:str]
guacamole_users: ENC[AES256_GCM,data:0oJdvTX/9SXV5fBdY0qr9BmSO1HMXX/7+R/f7UxeC/eQcFC9uptkdmLUYfghPvNFlmDNE8yllDylqqTk76qdFFYez78IhBmwj3MbY3C5C81PLI8yNroU0odaW1vgBvg9f8TdoQikMunnl8usNk71t8zxtZAtEbs3nogAbxFMouVy75TSnV+fx+Tb+SdSOQef3XgGrCK8BxaGnR+5LitXiFAIQwwiLV8NIf8alhklHrs3anQ1my83mSfeDYbyNd+ycTtlDa/9HVSGd/UErFP+guM4PNSuzVpNc91/3nm2gFYshMbVb36Z3zmG08fr1o3aoIs0X82XQLQuPmTDaH13RRNlTKPzoUjmXcBziryqqd3OBFRMM9BKlj7An1gZCbTzp2oNYjW2ReNQl6PyDhTZChf+Fgzx3wVXFYcGTueYQ3a1cuBWNvLrzNDFwTiYDfIP6scbEL2A07O2lhQArAGRFlvifNnhEayvzFR3Pzj10UoRhhyMSIWu2CThVKWVfRKCdvwLpTMCY4Yfn89krQu3UBYN2tFpJ9xiqRBmGCyjLNU2X6a5YxCMJkd56ptvnoc+TBF63c9W3sK91R4uLH673xf+LW+izLNFU4eQ66jtMGVx0MkX9uPAbP5+Pp+/J/OiQgsm6dL8r75lEGhKP0sMABc5I5oUNnAy6y52NY5BLOnJp5M/ulGvC4+cSdyaO0Ey2Zj+iPotxmyS60iY+mn0TMT5RnGF/Dx7q5YKzZKV2Gd5Trdum+pFta1k/ljwdLE0EwYZ0Y5bKVjV/tHYabZctrmrqmjmBHjraeYww6yqJka7HeyceBqFCt/fSAIi5WyhPlqYG4QSxM41fR50C6Y4BWeFlVmISoqx2fyq4HOZKbmG9qxvt/AofFi/X+YoBJ5w78MpOVBWRG/bRjqN2AfBFZIEpkUFXT3P1KHIqKXk6ueaMl50ftCZt0wZ770V6TNsssChsA==,iv:L5jR23mTV5oMNGM4s41Qe0fubj2PNZpjhNpNJakgUvM=,tag:IBELh0mxyHdGlAtRuQo9Uw==,type:str]
glass_server_admin_password: ENC[AES256_GCM,data:i6nLp5Jo4LmdsBQilSh9,iv:E3ukSNRlZWe+bmSANRXP0m1GBfA8GKhWAzEdT8Kyncw=,tag:M0gD9kv2P9Kv+PjwX8WuGQ==,type:str]
glass_server_secret_key: ENC[AES256_GCM,data:lfrUSUfNk9yuX++2UxDZddP5iyk+zYdA2lbTNwOvrZRRQLVHky0HE8G/D3g=,iv:E6ET35pG/4Xo83sOo9Ukb4b+zvussaDsq2Nr5vyDFRI=,tag:1CamjtZNnlMjqdO75TKTBg==,type:str]
sops:
kms: []
gcp_kms: []
@ -51,8 +53,8 @@ sops:
RkpibTJpVzVtR0txL1dHbmFkdlkvUk0KDgqO8c7CggeXhEMzx/tcLqtMG6MmuOi/
UmG9eSUO9im0Q7q7FG4Z+/lZ7+Iu15Dj8qA2/5MtDYPW+vxN3gzZrg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-06-13T14:52:30Z"
mac: ENC[AES256_GCM,data:EXVbpc8P8SzTSYw0TWwJBEWYZRpGOAXm4wFS0JbzeiNaWEybZk6Y07Vr5tyaEWucpu52VxLrVwoZn8YSdF9JPAHtTQYYY35MccBkB01+GVXpVDQfxCG9UNYO24qExNboQIs5QRWmtaX7zTbut+ETcOFKHlkqR9g95PZQhsNZx4c=,iv:1Bu9g4/V2ixRvJJBijlkdNO9pdoR+qwDGTeUgr24dsg=,tag:gyF34lCSbF0It4KPmtQYJA==,type:str]
lastmodified: "2025-02-07T14:19:08Z"
mac: ENC[AES256_GCM,data:Wb0+mRwt/FAihMIf2+pU+mYDAfk38VU6oPk9nXTZRbD2bQnry9Qqbqqmz3I/HUm99C0pPrqD0KbEsj/D7x0QD+mE7nbfQCtKXqHNZNRnv9CSXTWo63ZL2jzg2QRknANRMNXb7mZCnnRCzB/KWgTxQN7jqR2K/QxXV/2zJXOdbzo=,iv:Gj6Q/h+xy7vwFqPb/yqUI6ZTLhwl0KqCdVu9Ega85L4=,tag:Mv6MGHr0xsSmGbjKQXodOA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1
version: 3.9.1

View file

@ -0,0 +1,45 @@
{ config, ... }:
{
imports = [ ./module.nix ];
# {{{ Secrets
sops.secrets.glass_server_secret_key = {
owner = config.services.glass-server.user;
group = config.services.glass-server.user;
sopsFile = ../../secrets.yaml;
};
sops.secrets.glass_server_admin_password = {
owner = config.services.glass-server.user;
group = config.services.glass-server.user;
sopsFile = ../../secrets.yaml;
};
sops.templates.glass-server-config = {
owner = config.services.glass-server.user;
group = config.services.glass-server.user;
content = ''
{
"SECRET_KEY": "${config.sops.placeholder.glass_server_secret_key}",
"PASSWORD": "${config.sops.placeholder.glass_server_admin_password}"
}
'';
};
# }}}
satellite.cloudflared.at.arcaea.port = config.satellite.ports.glass-server;
satellite.cloudflared.at."tcp.lp.arcaea".port = config.satellite.ports.glass-server-lp-tcp;
satellite.cloudflared.at."udp.lp.arcaea".port = config.satellite.ports.glass-server-lp-udp;
services.glass-server = {
enable = true;
adminUsername = "prescientmoon";
dataDir = "/persist/state/var/lib/arcaea/server";
secretConfig = config.sops.templates.glass-server-config.path;
port = config.satellite.ports.glass-server;
linkPlayTCPPort = config.satellite.ports.glass-server-lp-tcp;
linkPlayUDPPort = config.satellite.ports.glass-server-lp-udp;
};
}

View file

@ -0,0 +1,128 @@
{
config,
lib,
pkgs,
...
}:
let
defaultUser = "taritsu";
cfg = config.services.glass-server;
pkg = pkgs.glassServer;
glassServerConfig = {
# {{{ Public config
HOST = "0.0.0.0";
PORT = cfg.port;
USERNAME = cfg.adminUsername;
LOG_BASE_DIR = "${cfg.dataDir}/log";
WORLD_MAP_FOLDER_PATH = "${cfg.dataDir}/map/";
SONG_FILE_FOLDER_PATH = "${cfg.dataDir}/songs/";
SONGLIST_FILE_PATH = "${cfg.dataDir}/songs/songlist";
CONTENT_BUNDLE_FOLDER_PATH = "${cfg.dataDir}/bundle/";
SQLITE_DATABASE_BACKUP_FOLDER_PATH = "${cfg.dataDir}/backup/";
DATABASE_INIT_PATH = "${pkg}/source/database/init/";
SQLITE_DATABASE_PATH = "${cfg.dataDir}/database/arcaea_database.db";
SQLITE_LOG_DATABASE_PATH = "${cfg.dataDir}/database/arcaea_log.db";
SQLITE_DATABASE_DELETED_PATH = "${cfg.dataDir}/database/arcaea_database_deleted.db";
SET_LINKPLAY_SERVER_AS_SUB_PROCESS = true;
LINKPLAY_HOST = "0.0.0.0";
LINKPLAY_TCP_PORT = cfg.linkPlayTCPPort;
LINKPLAY_UDP_PORT = cfg.linkPlayUDPPort;
LINKPLAY_DISPLAY_HOST = config.networking.hostName;
WORLD_RANK_MAX = 200;
IS_APRILFOOLS = true;
UPDATE_WITH_NEW_CHARACTER_DATA = true;
CHARACTER_FULL_UNLOCK = true;
WORLD_SONG_FULL_UNLOCK = true;
WORLD_SCENERY_FULL_UNLOCK = true;
SAVE_FULL_UNLOCK = true;
# }}}
};
serverConfigPath = pkgs.writeTextFile {
name = "glass-server-public-config";
text = builtins.toJSON glassServerConfig;
};
configPath = "${cfg.dataDir}/config.json";
in
{
# {{{ Options
options.services.glass-server = {
enable = lib.mkEnableOption "Arcaea private server";
dataDir = lib.mkOption { type = lib.types.str; };
port = lib.mkOption { type = lib.types.port; };
linkPlayTCPPort = lib.mkOption { type = lib.types.port; };
linkPlayUDPPort = lib.mkOption { type = lib.types.port; };
adminUsername = lib.mkOption { type = lib.types.str; };
user = lib.mkOption {
type = lib.types.str;
default = defaultUser;
description = ''
User account under which the server runs. If not specified, a default
user will be created.
'';
};
secretConfig = lib.mkOption {
type = lib.types.path;
description = ''
Path to additional config that might be generated at runtime by a tool
like sops. This might be useful for things like the admin password
'';
};
};
# }}}
config = {
# {{{ Create directory structure
systemd.tmpfiles.rules = [
"f ${cfg.dataDir}/config.json 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/log 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/map 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/songs 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/bundle 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/backup 0700 ${cfg.user} ${cfg.user}"
"d ${cfg.dataDir}/database 0700 ${cfg.user} ${cfg.user}"
];
# }}}
# {{{ Systemd service
systemd.services.arcaea-server = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Arcaea private server";
serviceConfig = {
User = cfg.user;
Group = cfg.user;
ExecStart = pkgs.writeShellScript "glass-server-startup" ''
# Merge the given configs
${lib.getExe pkgs.jq} -s ".[0] * .[1]" \
${cfg.secretConfig} \
${serverConfigPath} \
> ${configPath}
# Start the server
ARCAEA_JSON_CONFIG_PATH=${configPath} ${pkg}/bin/glass-server
'';
Restart = "on-failure";
};
};
# }}}
# {{{ Create default user
users = lib.optionalAttrs (cfg.user == defaultUser) {
users.${defaultUser} = {
group = defaultUser;
isSystemUser = true;
};
groups.${defaultUser} = { };
};
# }}}
};
}