clan-core/clanModules/sunshine.nix

230 lines
6.3 KiB
Nix
Raw Normal View History

2024-03-19 11:30:40 +00:00
{
pkgs,
config,
lib,
...
}:
2024-03-08 08:47:44 +00:00
let
ms-accept = pkgs.callPackage ../pkgs/moonlight-sunshine-accept { };
sunshineConfiguration = pkgs.writeText "sunshine.conf" ''
address_family = both
channels = 5
pkey = /var/lib/sunshine/sunshine.key
cert = /var/lib/sunshine/sunshine.cert
file_state = /var/lib/sunshine/state.json
credentials_file = /var/lib/sunshine/credentials.json
'';
listenPort = 48011;
in
2024-01-17 09:33:42 +00:00
{
networking.firewall = {
allowedTCPPorts = [
47984
47989
47990
48010
2024-03-08 08:47:44 +00:00
48011
2024-01-17 09:33:42 +00:00
];
allowedUDPPorts = [
47998
47999
48000
48002
48010
];
};
networking.firewall.allowedTCPPortRanges = [
{
from = 47984;
to = 48010;
}
];
networking.firewall.allowedUDPPortRanges = [
{
from = 47998;
to = 48010;
}
];
2024-03-08 08:47:44 +00:00
networking.firewall.interfaces."zt+".allowedTCPPorts = [
47984
47989
47990
48010
listenPort
];
networking.firewall.interfaces."zt+".allowedUDPPortRanges = [
{
from = 47998;
to = 48010;
}
];
2024-01-17 09:33:42 +00:00
environment.systemPackages = [
2024-03-08 08:47:44 +00:00
ms-accept
2024-01-17 09:33:42 +00:00
pkgs.sunshine
pkgs.avahi
# Convenience script, until we find a better UX
(pkgs.writers.writeDashBin "sun" ''
2024-03-08 08:47:44 +00:00
${pkgs.sunshine}/bin/sunshine -0 ${sunshineConfiguration} "$@"
2024-01-17 09:33:42 +00:00
'')
# Create a dummy account, for easier setup,
# don't use this account in actual production yet.
(pkgs.writers.writeDashBin "init-sun" ''
${pkgs.sunshine}/bin/sunshine \
--creds "sun" "sun"
'')
];
# Required to simulate input
boot.kernelModules = [ "uinput" ];
services.udev.extraRules = ''
2024-03-08 08:47:44 +00:00
KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"
2024-01-17 09:33:42 +00:00
'';
2024-03-08 08:47:44 +00:00
security = {
rtkit.enable = true;
wrappers.sunshine = {
owner = "root";
group = "root";
capabilities = "cap_sys_admin+p";
source = "${pkgs.sunshine}/bin/sunshine";
};
2024-01-17 09:33:42 +00:00
};
2024-03-08 08:47:44 +00:00
systemd.tmpfiles.rules = [
"d '/var/lib/sunshine' 0770 'user' 'users' - -"
2024-03-19 11:30:40 +00:00
"C '/var/lib/sunshine/sunshine.cert' 0644 'user' 'users' - ${
config.clanCore.secrets.sunshine.secrets."sunshine.cert".path or ""
}"
"C '/var/lib/sunshine/sunshine.key' 0644 'user' 'users' - ${
config.clanCore.secrets.sunshine.secrets."sunshine.key".path or ""
}"
2024-03-08 08:47:44 +00:00
];
hardware.opengl.enable = true;
2024-01-17 09:33:42 +00:00
systemd.user.services.sunshine = {
2024-03-08 08:47:44 +00:00
enable = true;
description = "Sunshine self-hosted game stream host for Moonlight";
startLimitBurst = 5;
startLimitIntervalSec = 500;
script = "/run/current-system/sw/bin/env /run/wrappers/bin/sunshine ${sunshineConfiguration}";
serviceConfig = {
Restart = "on-failure";
RestartSec = "5s";
2024-03-19 11:30:40 +00:00
ReadWritePaths = [ "/var/lib/sunshine" ];
2024-03-08 08:47:44 +00:00
ReadOnlyPaths = [
(config.clanCore.secrets.sunshine.secrets."sunshine.key".path or "")
(config.clanCore.secrets.sunshine.secrets."sunshine.cert".path or "")
];
};
2024-01-17 09:33:42 +00:00
wantedBy = [ "graphical-session.target" ];
2024-03-08 08:47:44 +00:00
partOf = [ "graphical-session.target" ];
wants = [ "graphical-session.target" ];
after = [
"sunshine-init-state.service"
"sunshine-init-credentials.service"
];
};
systemd.user.services.sunshine-init-state = {
enable = true;
description = "Sunshine self-hosted game stream host for Moonlight";
startLimitBurst = 5;
startLimitIntervalSec = 500;
script = ''
2024-03-19 11:30:40 +00:00
${ms-accept}/bin/moonlight-sunshine-accept sunshine init-state --uuid ${
config.clanCore.secrets.sunshine.facts.sunshine-uuid.value or null
} --state-file /var/lib/sunshine/state.json
2024-03-08 08:47:44 +00:00
'';
serviceConfig = {
Restart = "on-failure";
RestartSec = "5s";
Type = "oneshot";
2024-03-19 11:30:40 +00:00
ReadWritePaths = [ "/var/lib/sunshine" ];
2024-01-17 09:33:42 +00:00
};
2024-03-08 08:47:44 +00:00
wantedBy = [ "graphical-session.target" ];
};
systemd.user.services.sunshine-init-credentials = {
enable = true;
description = "Sunshine self-hosted game stream host for Moonlight";
startLimitBurst = 5;
startLimitIntervalSec = 500;
script = ''
${lib.getExe pkgs.sunshine} --creds sunshine sunshine
'';
2024-01-17 09:33:42 +00:00
serviceConfig = {
2024-03-08 08:47:44 +00:00
Restart = "on-failure";
RestartSec = "5s";
Type = "oneshot";
2024-03-19 11:30:40 +00:00
ReadWritePaths = [ "/var/lib/sunshine" ];
2024-01-17 09:33:42 +00:00
};
2024-03-08 08:47:44 +00:00
wantedBy = [ "graphical-session.target" ];
};
systemd.user.services.sunshine-listener = {
enable = true;
description = "Sunshine self-hosted game stream host for Moonlight";
startLimitBurst = 5;
startLimitIntervalSec = 500;
script = ''
2024-03-19 11:30:40 +00:00
${ms-accept}/bin/moonlight-sunshine-accept sunshine listen --port ${builtins.toString listenPort} --uuid ${
config.clanCore.secrets.sunshine.facts.sunshine-uuid.value or null
} --state /var/lib/sunshine/state.json --cert '${
config.clanCore.secrets.sunshine.facts."sunshine.cert".value or null
}'
2024-03-08 08:47:44 +00:00
'';
serviceConfig = {
# ExecStart = lib.concatStringsSep " " (lib.flatten
# [
# (lib.getExe ms-accept) "sunshine" "listen"
# "--port" (builtins.toString listenPort)
# "--uuid" (config.clanCore.secrets.sunshine.facts."sunshine-uuid".value or "")
# "--state" "/var/lib/sunshine/state.json"
# "--cert" (config.clanCore.secrets.sunshine.facts."sunshine.cert".value or "")
# ]
# );
Restart = "on-failure";
RestartSec = 5;
2024-03-19 11:30:40 +00:00
ReadWritePaths = [ "/var/lib/sunshine" ];
2024-03-08 08:47:44 +00:00
};
wantedBy = [ "graphical-session.target" ];
2024-01-17 09:33:42 +00:00
};
# xdg.configFile."sunshine/apps.json".text = builtins.toJSON {
# env = "/run/current-system/sw/bin";
# apps = [
# {
# name = "Steam";
# output = "steam.txt";
# detached = [
# "${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://open/bigpicture"
# ];
# image-path = "steam.png";
# }
# ];
# };
2024-03-08 08:47:44 +00:00
clanCore.secrets.sunshine = {
secrets."sunshine.key" = { };
secrets."sunshine.cert" = { };
facts."sunshine-uuid" = { };
facts."sunshine.cert" = { };
generator.path = [
pkgs.coreutils
ms-accept
];
generator.script = ''
moonlight-sunshine-accept sunshine init
mv credentials/cakey.pem "$secrets"/sunshine.key
cp credentials/cacert.pem "$secrets"/sunshine.cert
mv credentials/cacert.pem "$facts"/sunshine.cert
mv uuid "$facts"/sunshine-uuid
'';
2024-01-17 09:33:42 +00:00
};
}