mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
feat(steam): mkbeatsaber
This commit is contained in:
parent
46c6fbc8c1
commit
fc11fb8152
18 changed files with 891 additions and 44 deletions
6
lib.nix
6
lib.nix
|
|
@ -6,7 +6,7 @@
|
||||||
inherit (nixlib.strings) splitString toLower;
|
inherit (nixlib.strings) splitString toLower;
|
||||||
inherit (nixlib.lists) imap0 elemAt;
|
inherit (nixlib.lists) imap0 elemAt;
|
||||||
inherit (nixlib.attrsets) listToAttrs nameValuePair;
|
inherit (nixlib.attrsets) listToAttrs nameValuePair;
|
||||||
inherit (nixlib.strings) substring fixedWidthString;
|
inherit (nixlib.strings) substring fixedWidthString replaceStrings;
|
||||||
inherit (nixlib.trivial) flip toHexString bitOr;
|
inherit (nixlib.trivial) flip toHexString bitOr;
|
||||||
|
|
||||||
toHexStringLower = v: toLower (toHexString v);
|
toHexStringLower = v: toLower (toHexString v);
|
||||||
|
|
@ -30,12 +30,14 @@
|
||||||
in "${part0 (part 0)}${part 1}:${part 2}ff:fe${part 3}:${part 4}${part 5}";
|
in "${part0 (part 0)}${part 1}:${part 2}ff:fe${part 3}:${part 4}${part 5}";
|
||||||
|
|
||||||
userIs = group: user: builtins.elem group (user.extraGroups ++ [ user.group ]);
|
userIs = group: user: builtins.elem group (user.extraGroups ++ [ user.group ]);
|
||||||
|
|
||||||
|
mkWinPath = replaceStrings [ "/" ] [ "\\" ];
|
||||||
in {
|
in {
|
||||||
inherit tree nixlib inputs;
|
inherit tree nixlib inputs;
|
||||||
std = inputs.self.lib.Std.Std.compat;
|
std = inputs.self.lib.Std.Std.compat;
|
||||||
Std = inputs.std-fl.lib;
|
Std = inputs.std-fl.lib;
|
||||||
lib = {
|
lib = {
|
||||||
inherit userIs eui64 toHexStringLower hexCharToInt;
|
inherit mkWinPath userIs eui64 toHexStringLower hexCharToInt;
|
||||||
};
|
};
|
||||||
generate = import ./generate.nix { inherit inputs tree; };
|
generate = import ./generate.nix { inherit inputs tree; };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
111
modules/nixos/steam/account-switch.nix
Normal file
111
modules/nixos/steam/account-switch.nix
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (inputs.self.lib.lib) userIs;
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||||
|
inherit (lib.attrsets) filterAttrs mapAttrsToList listToAttrs nameValuePair;
|
||||||
|
inherit (lib.lists) singleton;
|
||||||
|
cfg = config.services.steam.accountSwitch;
|
||||||
|
in {
|
||||||
|
options.services.steam.accountSwitch = with lib.types; {
|
||||||
|
enable = mkEnableOption "steam-account-switch";
|
||||||
|
setup = mkEnableOption "steam-account-switch data";
|
||||||
|
group = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "steamaccount";
|
||||||
|
};
|
||||||
|
sharePath = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
rootDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
};
|
||||||
|
binDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.rootDir + "/bin";
|
||||||
|
};
|
||||||
|
gamesDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.rootDir + "/games";
|
||||||
|
};
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.rootDir + "/data";
|
||||||
|
};
|
||||||
|
sharedDataDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.dataDir + "/shared";
|
||||||
|
};
|
||||||
|
workingDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.rootDir + "/working";
|
||||||
|
};
|
||||||
|
sharedWorkingDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.workingDir + "/shared";
|
||||||
|
};
|
||||||
|
users = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
steamUsers = filterAttrs (_: userIs cfg.group) config.users.users;
|
||||||
|
in {
|
||||||
|
services.steam.accountSwitch = {
|
||||||
|
users = mkOptionDefault (
|
||||||
|
mapAttrsToList (_: user: user.name) steamUsers
|
||||||
|
);
|
||||||
|
};
|
||||||
|
services.tmpfiles = let
|
||||||
|
toplevel = {
|
||||||
|
owner = mkDefault "admin";
|
||||||
|
group = mkDefault cfg.group;
|
||||||
|
mode = mkDefault "3775";
|
||||||
|
};
|
||||||
|
shared = {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = "2775";
|
||||||
|
};
|
||||||
|
personal = owner: {
|
||||||
|
inherit owner;
|
||||||
|
inherit (shared) group mode;
|
||||||
|
};
|
||||||
|
setupFiles = singleton {
|
||||||
|
${cfg.rootDir} = toplevel;
|
||||||
|
${cfg.binDir} = toplevel;
|
||||||
|
${cfg.binDir + "/users"} = shared;
|
||||||
|
${cfg.dataDir} = toplevel;
|
||||||
|
${cfg.sharedDataDir} = shared;
|
||||||
|
${cfg.workingDir} = toplevel;
|
||||||
|
${cfg.sharedWorkingDir} = shared;
|
||||||
|
} ++ map (owner: {
|
||||||
|
${cfg.dataDir + "/${owner}"} = personal owner;
|
||||||
|
${cfg.workingDir + "/${owner}"} = personal owner;
|
||||||
|
}) cfg.users;
|
||||||
|
userBinFiles = listToAttrs (map (user: nameValuePair "${cfg.binDir}/users/${user}.bat" {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = "0755";
|
||||||
|
type = "copy";
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "steam-${user}.bat";
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
setx GENSO_STEAM_USER ${user}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}) cfg.users);
|
||||||
|
in {
|
||||||
|
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||||
|
files = mkMerge [
|
||||||
|
(mkIf cfg.setup (mkMerge setupFiles))
|
||||||
|
(mkIf cfg.enable userBinFiles)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
269
modules/nixos/steam/beatsaber.nix
Normal file
269
modules/nixos/steam/beatsaber.nix
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (inputs.self.lib.lib) mkWinPath userIs;
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||||
|
inherit (lib.strings) removePrefix replaceStrings;
|
||||||
|
inherit (lib.attrsets) filterAttrs mapAttrs' mapAttrsToList listToAttrs nameValuePair;
|
||||||
|
inherit (lib.lists) concatMap head singleton;
|
||||||
|
inherit (lib.meta) getExe;
|
||||||
|
inherit (config.services.steam) accountSwitch;
|
||||||
|
cfg = config.services.steam.beatsaber;
|
||||||
|
versionModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
version = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkSharePath = path: mkWinPath (
|
||||||
|
"%GENSO_SMB_SHARED_MOUNT%"
|
||||||
|
+ "/${accountSwitch.sharePath}"
|
||||||
|
+ "/${removePrefix (accountSwitch.rootDir + "/") path}"
|
||||||
|
);
|
||||||
|
vars = ''
|
||||||
|
if "%GENSO_STEAM_INSTALL%" == "" set "GENSO_STEAM_INSTALL=C:\Program Files (x86)\Steam"
|
||||||
|
if "%GENSO_STEAM_LIBRARY_BS%" == "" set "GENSO_STEAM_LIBRARY_BS=%GENSO_STEAM_INSTALL%"
|
||||||
|
if "%GENSO_STEAM_BS_VERSION%" == "" set "GENSO_STEAM_BS_VERSION=${cfg.defaultVersion}"
|
||||||
|
if "%GENSO_SMB_HOST%" == "" set "GENSO_SMB_HOST=smb.${config.networking.domain}"
|
||||||
|
if "%GENSO_SMB_SHARED_MOUNT%" == "" set "GENSO_SMB_SHARED_MOUNT=\\%GENSO_SMB_HOST%\shared"
|
||||||
|
set "STEAM_BS_LIBRARY=%GENSO_STEAM_LIBRARY_BS%\steamapps\common\Beat Saber"
|
||||||
|
set "STEAM_BS_APPDATA=%USERPROFILE%\AppData\LocalLow\Hyperbolic Magnetism\Beat Saber"
|
||||||
|
set "STEAM_USER_DATA=${mkSharePath accountSwitch.dataDir}\%GENSO_STEAM_USER%"
|
||||||
|
set "STEAM_WORKING_DATA=${mkSharePath accountSwitch.workingDir}\%GENSO_STEAM_USER%"
|
||||||
|
set "STEAM_BINDIR=${mkSharePath accountSwitch.binDir}"
|
||||||
|
if "%GENSO_STEAM_USER%" == "" goto NOUSER
|
||||||
|
'';
|
||||||
|
eof = ''
|
||||||
|
goto:eof
|
||||||
|
|
||||||
|
:NOUSER
|
||||||
|
echo no steam user set
|
||||||
|
'';
|
||||||
|
mount = ''
|
||||||
|
rmdir "%STEAM_BS_APPDATA%"
|
||||||
|
mklink /D "%STEAM_BS_APPDATA%" "%STEAM_USER_DATA%\BeatSaber\AppData"
|
||||||
|
|
||||||
|
rmdir "%STEAM_BS_LIBRARY%"
|
||||||
|
mklink /D "%STEAM_BS_LIBRARY%" "%STEAM_WORKING_DATA%\BeatSaber\%GENSO_STEAM_BS_VERSION%"
|
||||||
|
'';
|
||||||
|
mountbeatsaber = ''
|
||||||
|
${vars}
|
||||||
|
${mount}
|
||||||
|
${eof}
|
||||||
|
'';
|
||||||
|
launchbeatsaber = ''
|
||||||
|
${vars}
|
||||||
|
${mount}
|
||||||
|
cd /d "%STEAM_BS_LIBRARY%"
|
||||||
|
"%STEAM_BS_LIBRARY%\Beat Saber.exe"
|
||||||
|
${eof}
|
||||||
|
'';
|
||||||
|
fpfcbeatsaber = ''
|
||||||
|
${vars}
|
||||||
|
${mount}
|
||||||
|
cd /d "%STEAM_BS_LIBRARY%"
|
||||||
|
"%STEAM_BS_LIBRARY%\Beat Saber.exe" fpfc
|
||||||
|
${eof}
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkbeatsabersh = pkgs.writeShellScriptBin "mkbeatsaber.sh" ''
|
||||||
|
source ${./mkbeatsaber.sh}
|
||||||
|
'';
|
||||||
|
mkbeatsaber = pkgs.writeShellScriptBin "mkbeatsaber" ''
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ARG_GAME_VERSION=$1
|
||||||
|
shift
|
||||||
|
if [[ $# -gt 0 ]]; then
|
||||||
|
ARG_USER=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
ARG_USER=$(${pkgs.coreutils}/bin/id -un)
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ${accountSwitch.workingDir}
|
||||||
|
mkdir -m2775 -p "$ARG_USER/BeatSaber/$ARG_GAME_VERSION"
|
||||||
|
chown "$ARG_USER" "$ARG_USER" "$ARG_USER/BeatSaber"
|
||||||
|
cd "$ARG_USER/BeatSaber/$ARG_GAME_VERSION"
|
||||||
|
${getExe mkbeatsabersh} \
|
||||||
|
"${accountSwitch.gamesDir}/BeatSaber" \
|
||||||
|
"$ARG_GAME_VERSION" \
|
||||||
|
"${accountSwitch.sharedDataDir}/BeatSaber" \
|
||||||
|
"${accountSwitch.dataDir}/$ARG_USER/BeatSaber"
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
options.services.steam.beatsaber = with lib.types; {
|
||||||
|
enable = mkEnableOption "beatsaber scripts";
|
||||||
|
setup = mkEnableOption "beatsaber data" // {
|
||||||
|
default = accountSwitch.setup;
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "beatsaber";
|
||||||
|
};
|
||||||
|
defaultVersion = mkOption {
|
||||||
|
type = str;
|
||||||
|
};
|
||||||
|
versions = mkOption {
|
||||||
|
type = attrsOf (submodule versionModule);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
users = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
in {
|
||||||
|
services.steam.beatsaber = let
|
||||||
|
bsUsers = filterAttrs (_: userIs cfg.group) config.users.users;
|
||||||
|
allVersions = mapAttrsToList (_: version: version.version) cfg.versions;
|
||||||
|
in {
|
||||||
|
defaultVersion = mkIf (allVersions != [ ]) (mkOptionDefault (
|
||||||
|
head allVersions
|
||||||
|
));
|
||||||
|
users = mkOptionDefault (
|
||||||
|
mapAttrsToList (_: user: user.name) bsUsers
|
||||||
|
);
|
||||||
|
};
|
||||||
|
environment = mkIf cfg.enable {
|
||||||
|
systemPackages = [
|
||||||
|
mkbeatsaber
|
||||||
|
mkbeatsabersh
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.services = mkIf cfg.setup (listToAttrs (map (user: nameValuePair "steam-setup-beatsaber-${user}" {
|
||||||
|
script = mkMerge (mapAttrsToList (_: version: ''
|
||||||
|
${getExe mkbeatsaber} ${version.version} ${user}
|
||||||
|
'') cfg.versions);
|
||||||
|
path = [
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
|
];
|
||||||
|
after = [
|
||||||
|
"tmpfiles.service"
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
RemainAfterExit = mkOptionDefault true;
|
||||||
|
User = mkOptionDefault user;
|
||||||
|
};
|
||||||
|
}) cfg.users));
|
||||||
|
services.tmpfiles = let
|
||||||
|
toplevel = {
|
||||||
|
owner = mkDefault "admin";
|
||||||
|
group = mkDefault cfg.group;
|
||||||
|
mode = mkDefault "3775";
|
||||||
|
};
|
||||||
|
shared = {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = mkDefault "2775";
|
||||||
|
};
|
||||||
|
personal = owner: {
|
||||||
|
inherit owner;
|
||||||
|
inherit (shared) group mode;
|
||||||
|
};
|
||||||
|
bin = {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = "0755";
|
||||||
|
type = "copy";
|
||||||
|
};
|
||||||
|
sharedFolders = [
|
||||||
|
"CustomAvatars"
|
||||||
|
"CustomLevels"
|
||||||
|
"CustomNotes"
|
||||||
|
"CustomPlatforms"
|
||||||
|
"CustomSabers"
|
||||||
|
"CustomWalls"
|
||||||
|
"AppData"
|
||||||
|
"UserData"
|
||||||
|
];
|
||||||
|
setupFiles = [
|
||||||
|
{
|
||||||
|
"${accountSwitch.sharedDataDir}/BeatSaber" = toplevel;
|
||||||
|
"${accountSwitch.binDir}/beatsaber" = shared;
|
||||||
|
}
|
||||||
|
(listToAttrs (
|
||||||
|
map (folder:
|
||||||
|
nameValuePair "${accountSwitch.sharedDataDir}/BeatSaber/${folder}" shared
|
||||||
|
) sharedFolders
|
||||||
|
))
|
||||||
|
] ++ concatMap (owner:
|
||||||
|
singleton {
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber" = personal owner;
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/AppData" = personal owner;
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/UserData" = personal owner;
|
||||||
|
} ++ mapAttrsToList (_: version: {
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/${version.version}" = personal owner;
|
||||||
|
}) cfg.versions
|
||||||
|
) accountSwitch.users
|
||||||
|
++ mapAttrsToList (_: version: {
|
||||||
|
"${accountSwitch.sharedDataDir}/BeatSaber/${version.version}" = shared;
|
||||||
|
}) cfg.versions;
|
||||||
|
versionBinFiles = mapAttrs' (_: version: nameValuePair
|
||||||
|
"${accountSwitch.binDir}/beatsaber/${replaceStrings [ "." ] [ "_" ] version.version}.bat"
|
||||||
|
{
|
||||||
|
inherit (bin) owner group mode type;
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "beatsaber-${version.version}.bat";
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
setx GENSO_STEAM_BS_VERSION ${version.version}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) cfg.versions;
|
||||||
|
binFiles = {
|
||||||
|
"${accountSwitch.binDir}/beatsaber/mount.bat" = {
|
||||||
|
inherit (bin) owner group mode type;
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "beatsaber-mount.bat";
|
||||||
|
executable = true;
|
||||||
|
text = mountbeatsaber;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"${accountSwitch.binDir}/beatsaber/launch.bat" = {
|
||||||
|
inherit (bin) owner group mode type;
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "beatsaber-launch.bat";
|
||||||
|
executable = true;
|
||||||
|
text = launchbeatsaber;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"${accountSwitch.binDir}/beatsaber/fpfc.bat" = {
|
||||||
|
inherit (bin) owner group mode type;
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "beatsaber-fpfc.bat";
|
||||||
|
executable = true;
|
||||||
|
text = fpfcbeatsaber;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"${accountSwitch.binDir}/beatsaber/ModAssistant.exe" = {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = "0755";
|
||||||
|
type = "copy";
|
||||||
|
src = pkgs.fetchurl {
|
||||||
|
url = "https://github.com/Assistant/ModAssistant/releases/download/v1.1.32/ModAssistant.exe";
|
||||||
|
hash = "sha256-ozu2gYFiz+2BjptqL80DmUopbahbyGKFO1IPd7BhVPM=";
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // versionBinFiles;
|
||||||
|
in {
|
||||||
|
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||||
|
files = mkMerge [
|
||||||
|
(mkIf cfg.setup (mkMerge setupFiles))
|
||||||
|
(mkIf cfg.enable binFiles)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
46
modules/nixos/steam/library.nix
Normal file
46
modules/nixos/steam/library.nix
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
|
inherit (config.services.steam) accountSwitch;
|
||||||
|
cfg = config.services.steam.library;
|
||||||
|
in {
|
||||||
|
options.services.steam.library = with lib.types; {
|
||||||
|
setup = mkEnableOption "steam library data";
|
||||||
|
group = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = accountSwitch.group;
|
||||||
|
};
|
||||||
|
rootDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
};
|
||||||
|
steamappsDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.rootDir + "/steamapps";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.tmpfiles = let
|
||||||
|
toplevel = {
|
||||||
|
owner = mkDefault "admin";
|
||||||
|
group = mkDefault cfg.group;
|
||||||
|
mode = mkDefault "3775";
|
||||||
|
};
|
||||||
|
shared = {
|
||||||
|
inherit (toplevel) owner group;
|
||||||
|
mode = "2775";
|
||||||
|
};
|
||||||
|
setupFiles = {
|
||||||
|
${cfg.rootDir} = toplevel;
|
||||||
|
${cfg.steamappsDir} = shared;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
enable = mkIf cfg.setup true;
|
||||||
|
files = mkIf cfg.setup setupFiles;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
83
modules/nixos/steam/mkbeatsaber.sh
Normal file
83
modules/nixos/steam/mkbeatsaber.sh
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ARG_GAME_SRC=$1
|
||||||
|
ARG_GAME_VERSION=$2
|
||||||
|
ARG_SHARED_DATA=$3
|
||||||
|
ARG_USER_DATA=$4
|
||||||
|
shift 4
|
||||||
|
|
||||||
|
if ! [[ -e "$ARG_GAME_SRC/$ARG_GAME_VERSION/Beat Saber.exe" ]]; then
|
||||||
|
echo unexpected game src >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/"*.{exe,dll} ./
|
||||||
|
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/"{MonoBleedingEdge,Plugins} ./
|
||||||
|
rm "Beat Saber.exe"
|
||||||
|
cp "$ARG_GAME_SRC/$ARG_GAME_VERSION/Beat Saber.exe" ./
|
||||||
|
chmod 0775 "Beat Saber.exe"
|
||||||
|
|
||||||
|
BSDATA="Beat Saber_Data"
|
||||||
|
mkdir -pm2775 "$BSDATA"
|
||||||
|
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/$BSDATA/"* "$BSDATA/" || true
|
||||||
|
ln -srf "$ARG_SHARED_DATA/CustomLevels" "$BSDATA/"
|
||||||
|
rm -f "$BSDATA/Managed"
|
||||||
|
|
||||||
|
mkdir -pm2775 UserData
|
||||||
|
|
||||||
|
ln -srf "$ARG_SHARED_DATA/"{CustomAvatars,CustomNotes,CustomPlatforms,CustomSabers,CustomWalls,Playlists} ./
|
||||||
|
for shareddir in DynamicOpenVR IPA Libs Logs Plugins "$BSDATA/Managed" UserData/SongCore; do
|
||||||
|
shareddirsrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/$shareddir"
|
||||||
|
if [[ ! -e $shareddirsrc ]]; then
|
||||||
|
mkdir -pm2775 "$shareddirsrc"
|
||||||
|
if [[ $shareddir = */Managed ]]; then
|
||||||
|
cp "$ARG_GAME_SRC/$ARG_GAME_VERSION/$BSDATA/Managed/"* "$shareddirsrc/" || true
|
||||||
|
chmod 0775 "$shareddirsrc/"*.dll || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ln -srf "$shareddirsrc" "./$(dirname "$shareddir")"
|
||||||
|
done
|
||||||
|
for sharedfile in IPA.exe IPA.exe.config IPA.runtimeconfig.json winhttp.dll; do
|
||||||
|
sharedfilesrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/$sharedfile"
|
||||||
|
if [[ ! -e "$sharedfilesrc" ]]; then
|
||||||
|
mkdir -pm2775 "$(dirname "$sharedfilesrc")"
|
||||||
|
if [[ $sharedfile = *.json ]]; then
|
||||||
|
echo '{}' > "$sharedfilesrc"
|
||||||
|
else
|
||||||
|
touch "$sharedfilesrc"
|
||||||
|
fi
|
||||||
|
chmod 0775 "$sharedfilesrc" || true
|
||||||
|
fi
|
||||||
|
ln -f "$sharedfilesrc" ./
|
||||||
|
done
|
||||||
|
|
||||||
|
for sharedfile in "Beat Saber IPA.json"; do
|
||||||
|
sharedfilesrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/UserData/$sharedfile"
|
||||||
|
if [[ ! -e "$sharedfilesrc" ]]; then
|
||||||
|
mkdir -pm2775 "$(dirname "$sharedfilesrc")"
|
||||||
|
if [[ $sharedfile = *.json ]]; then
|
||||||
|
echo '{}' > "$sharedfilesrc"
|
||||||
|
else
|
||||||
|
touch "$sharedfilesrc"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ln -f "$sharedfilesrc" "UserData/$(dirname "$sharedfile")"
|
||||||
|
done
|
||||||
|
ln -f "$ARG_SHARED_DATA/UserData/"*.{json,ini,proto,etag} UserData/
|
||||||
|
ln -srf "$ARG_SHARED_DATA/UserData/"{ScoreSaber,Chroma,Nya,SongRankedBadge,HitScoreVisualizer}/ UserData/
|
||||||
|
|
||||||
|
SFDATA="UserData/Saber Factory"
|
||||||
|
mkdir -pm2775 "$SFDATA"
|
||||||
|
ln -srf "$ARG_SHARED_DATA/$SFDATA/"*/ "$SFDATA/"
|
||||||
|
ln -srf "$ARG_USER_DATA/$SFDATA/"*/ "$SFDATA/"
|
||||||
|
ln -f "$ARG_USER_DATA/$SFDATA/"*.json "$SFDATA/"
|
||||||
|
|
||||||
|
for userdir in Camera2 DrinkWater Enhancements; do
|
||||||
|
userdirsrc="$ARG_USER_DATA/UserData/$userdir"
|
||||||
|
if [[ ! -e $userdirsrc ]]; then
|
||||||
|
mkdir -pm3775 "$userdirsrc"
|
||||||
|
fi
|
||||||
|
ln -srf "$userdirsrc" UserData/
|
||||||
|
done
|
||||||
|
ln -f "$ARG_USER_DATA/UserData/"*.{json,ini,dat} UserData/
|
||||||
219
modules/nixos/tmpfiles.nix
Normal file
219
modules/nixos/tmpfiles.nix
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||||
|
inherit (lib.strings) match concatStringsSep escapeShellArg optionalString;
|
||||||
|
inherit (lib.attrsets) attrValues;
|
||||||
|
inherit (lib.lists) filter;
|
||||||
|
isGroupWritable = mode: match "[234567][0-7][76][0-7]" mode != null;
|
||||||
|
isOtherWritable = mode: match "[0-7][0-7][0-7][76]" mode != null;
|
||||||
|
cfg = config.services.tmpfiles;
|
||||||
|
files = filter (file: file.enable) (attrValues cfg.files);
|
||||||
|
systemdFiles = filter (file: file.systemd.enable) files;
|
||||||
|
setupFiles = filter (file: !file.systemd.enable) files;
|
||||||
|
bindFiles = filter (file: file.type == "bind") files;
|
||||||
|
fileModule = { config, name, ... }: {
|
||||||
|
options = with lib.types; {
|
||||||
|
enable = mkEnableOption "file" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
mkdirParent = mkEnableOption "mkdir";
|
||||||
|
bindReadOnly = mkEnableOption "mount -oro";
|
||||||
|
path = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
type = mkOption {
|
||||||
|
type = enum [ "directory" "symlink" "link" "copy" "bind" ];
|
||||||
|
default = if config.src != null then "symlink" else "directory";
|
||||||
|
};
|
||||||
|
mode = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "0755";
|
||||||
|
};
|
||||||
|
owner = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = cfg.user;
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
src = mkOption {
|
||||||
|
type = nullOr path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
acls = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
systemd = {
|
||||||
|
enable = mkEnableOption "systemd-tmpfiles";
|
||||||
|
rules = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
setup = {
|
||||||
|
script = mkOption {
|
||||||
|
type = lines;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = let
|
||||||
|
acls = concatStringsSep "," config.acls;
|
||||||
|
enableAcls = config.type == "directory" && config.acls != [ ];
|
||||||
|
systemdAclRule = "a+ ${config.path} - - - - ${acls}";
|
||||||
|
systemdRule = {
|
||||||
|
directory = [
|
||||||
|
"d ${config.path} ${config.mode} ${config.owner} ${config.group}"
|
||||||
|
];
|
||||||
|
symlink = [
|
||||||
|
"L+ ${config.path} - - - - ${config.src}"
|
||||||
|
];
|
||||||
|
copy = [
|
||||||
|
"C ${config.path} - - - - ${config.src}"
|
||||||
|
"z ${config.path} ${config.mode} ${config.owner} ${config.group} - ${config.src}"
|
||||||
|
];
|
||||||
|
link = throw "unsupported link for systemd tmpfiles";
|
||||||
|
bind = throw "unsupported bind for systemd tmpfiles";
|
||||||
|
};
|
||||||
|
chown = "chown ${escapeShellArg config.owner}:${escapeShellArg config.group} ${escapeShellArg config.path}";
|
||||||
|
chmod = "chmod ${escapeShellArg config.mode} ${escapeShellArg config.path}";
|
||||||
|
parentFlag = optionalString config.mkdirParent "p";
|
||||||
|
scriptCatch = " || EXITCODE=$?";
|
||||||
|
scriptFail = "EXITCODE=1";
|
||||||
|
setupScript = {
|
||||||
|
directory = ''
|
||||||
|
if [[ -d ${escapeShellArg config.path} ]]; then
|
||||||
|
${chmod} &&
|
||||||
|
${chown}${scriptCatch}
|
||||||
|
elif [[ ! -e ${escapeShellArg config.path} ]]; then
|
||||||
|
mkdir -${parentFlag}m ${escapeShellArg config.mode} ${escapeShellArg config.path} &&
|
||||||
|
${chown}${scriptCatch}
|
||||||
|
else
|
||||||
|
echo ${escapeShellArg config.path} exists but is not a directory >&2
|
||||||
|
${scriptFail}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
symlink = ''
|
||||||
|
if [[ ! -e ${escapeShellArg config.path} || -L ${escapeShellArg config.path} ]]; then
|
||||||
|
ln -sf ${escapeShellArg config.src} ${escapeShellArg config.path}${scriptCatch}
|
||||||
|
else
|
||||||
|
echo ${escapeShellArg config.path} exists but is not a symlink >&2
|
||||||
|
${scriptFail}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
link = ''
|
||||||
|
if [[ -L ${escapeShellArg config.path} ]]; then
|
||||||
|
rm -f ${escapeShellArg config.path}
|
||||||
|
fi
|
||||||
|
ln -f ${escapeShellArg config.src} ${escapeShellArg config.path}${scriptCatch}
|
||||||
|
'';
|
||||||
|
copy = ''
|
||||||
|
if [[ ! -e ${escapeShellArg config.path} || -f ${escapeShellArg config.path} ]]; then
|
||||||
|
cp -f ${escapeShellArg config.src} ${escapeShellArg config.path} &&
|
||||||
|
${chmod} &&
|
||||||
|
${chown}${scriptCatch}
|
||||||
|
else
|
||||||
|
echo ${escapeShellArg config.path} exists but is not a file >&2
|
||||||
|
${scriptFail}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
bind = ''
|
||||||
|
if [[ ! -e ${escapeShellArg config.src} ]]; then
|
||||||
|
echo ${escapeShellArg config.src} does not exist >&2
|
||||||
|
${scriptFail}
|
||||||
|
elif [[ -d $(readlink -f ${escapeShellArg config.src}) ]]; then
|
||||||
|
mkdir -p ${escapeShellArg config.path}${scriptCatch}
|
||||||
|
else
|
||||||
|
if [[ ! -e ${escapeShellArg config.path} ]]; then
|
||||||
|
touch ${escapeShellArg config.path}${scriptCatch}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
aclScript = ''
|
||||||
|
setfacl -b -m ${escapeShellArg acls} ${escapeShellArg config.path}${scriptCatch}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
acls = mkOptionDefault [
|
||||||
|
(mkIf (isGroupWritable config.mode) "default:group::rwx")
|
||||||
|
(mkIf (isOtherWritable config.mode) "default:other::rwx")
|
||||||
|
];
|
||||||
|
setup.script = mkMerge [
|
||||||
|
setupScript.${config.type}
|
||||||
|
(mkIf enableAcls aclScript)
|
||||||
|
];
|
||||||
|
systemd = {
|
||||||
|
rules = mkMerge [
|
||||||
|
systemdRule.${config.type}
|
||||||
|
(mkIf enableAcls [ systemdAclRule ])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.services.tmpfiles = with lib.types; {
|
||||||
|
enable = mkEnableOption "extended tmpfiles" // {
|
||||||
|
default = cfg.files != { };
|
||||||
|
};
|
||||||
|
user = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = if config.proxmoxLXC.privileged or true then "root" else "admin";
|
||||||
|
};
|
||||||
|
files = mkOption {
|
||||||
|
type = attrsOf (submodule fileModule);
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
systemd = mkIf cfg.enable {
|
||||||
|
tmpfiles.rules = mkMerge (
|
||||||
|
map (file: file.systemd.rules) systemdFiles
|
||||||
|
);
|
||||||
|
services.tmpfiles = {
|
||||||
|
path = [ pkgs.coreutils pkgs.acl ];
|
||||||
|
script = mkMerge (
|
||||||
|
[ ''
|
||||||
|
EXITCODE=0
|
||||||
|
'' ]
|
||||||
|
++ map (file: file.setup.script) setupFiles
|
||||||
|
++ [ ''
|
||||||
|
exit $EXITCODE
|
||||||
|
'' ]
|
||||||
|
);
|
||||||
|
wantedBy = [
|
||||||
|
"sysinit.target"
|
||||||
|
];
|
||||||
|
after = [
|
||||||
|
"local-fs.target"
|
||||||
|
];
|
||||||
|
before = [
|
||||||
|
"systemd-tmpfiles-setup.service"
|
||||||
|
"systemd-tmpfiles-resetup.service"
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
User = mkOptionDefault cfg.user;
|
||||||
|
RemainAfterExit = mkOptionDefault true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mounts = map (file: rec {
|
||||||
|
enable = file.enable;
|
||||||
|
type = "none";
|
||||||
|
options = mkMerge [
|
||||||
|
"bind"
|
||||||
|
(mkIf file.bindReadOnly "ro")
|
||||||
|
];
|
||||||
|
what = file.src;
|
||||||
|
where = file.path;
|
||||||
|
wantedBy = [
|
||||||
|
"tmpfiles.service"
|
||||||
|
];
|
||||||
|
after = wantedBy;
|
||||||
|
}) bindFiles;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge;
|
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||||
inherit (lib.strings) match concatStringsSep;
|
inherit (lib.strings) removePrefix;
|
||||||
inherit (lib.lists) optional;
|
inherit (lib.attrsets) listToAttrs nameValuePair;
|
||||||
|
inherit (config.services.steam) accountSwitch;
|
||||||
cfg = config.kyuuto;
|
cfg = config.kyuuto;
|
||||||
in {
|
in {
|
||||||
options.kyuuto = with lib.types; {
|
options.kyuuto = with lib.types; {
|
||||||
|
|
@ -15,49 +16,96 @@ in {
|
||||||
type = path;
|
type = path;
|
||||||
default = "/mnt/kyuuto-media";
|
default = "/mnt/kyuuto-media";
|
||||||
};
|
};
|
||||||
libraryDir = mkOption {
|
shareDir = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
default = cfg.mountDir + "/library";
|
default = cfg.mountDir + "/shared";
|
||||||
};
|
};
|
||||||
transferDir = mkOption {
|
transferDir = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
default = cfg.mountDir + "/transfer";
|
default = cfg.mountDir + "/transfer";
|
||||||
};
|
};
|
||||||
shareDir = mkOption {
|
libraryDir = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
default = cfg.mountDir + "/shared";
|
default = cfg.mountDir + "/library";
|
||||||
|
};
|
||||||
|
gameLibraryDir = mkOption {
|
||||||
|
type = path;
|
||||||
|
default = cfg.libraryDir + "/games";
|
||||||
|
};
|
||||||
|
gameLibraries = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [ "PC" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
systemd.tmpfiles.rules = let
|
kyuuto = {
|
||||||
isGroupWritable = mode: match "[375][0-7][76][0-7]" mode != null;
|
gameLibraries = [
|
||||||
isOtherWritable = mode: match "[375][0-7][0-7][76]" mode != null;
|
"PC"
|
||||||
mkKyuutoDir = {
|
"Wii" "Gamecube" "N64" "SNES" "NES"
|
||||||
path,
|
"NDS" "GBA" "GBC"
|
||||||
mode ? "3775",
|
"PS3" "PS2" "PS1"
|
||||||
owner ? "guest",
|
"PSVita" "PSP"
|
||||||
group ? "kyuuto",
|
"Genesis"
|
||||||
acls ? optional (isGroupWritable mode) "default:group::rwx"
|
];
|
||||||
++ optional (isOtherWritable mode) "default:other::rwx",
|
};
|
||||||
}: [
|
services.steam = {
|
||||||
"d ${path} ${mode} ${owner} ${group}"
|
library = {
|
||||||
] ++ optional (acls != [ ]) "a+ ${path} - - - - ${concatStringsSep "," acls}";
|
setup = mkDefault cfg.setup;
|
||||||
in mkIf cfg.setup (
|
rootDir = cfg.shareDir + "/steam/library";
|
||||||
mkKyuutoDir { path = cfg.transferDir; }
|
};
|
||||||
++ mkKyuutoDir { path = cfg.shareDir; owner = "root"; }
|
accountSwitch = {
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir; owner = "root"; }
|
setup = mkDefault cfg.setup;
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/unsorted"; }
|
sharePath = removePrefix "${cfg.shareDir}/" accountSwitch.rootDir;
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/music"; owner = "root"; }
|
rootDir = cfg.shareDir + "/steam";
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/music/assorted"; owner = "sonarr"; mode = "7775"; }
|
};
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/music/collections"; }
|
};
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/anime"; owner = "sonarr"; mode = "7775"; }
|
services.tmpfiles = let
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/tv"; owner = "sonarr"; mode = "7775"; }
|
shared = {
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/movies"; owner = "radarr"; mode = "7775"; }
|
owner = mkDefault "admin";
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/software"; }
|
group = mkDefault "kyuuto";
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/books"; }
|
mode = mkDefault "3775";
|
||||||
++ mkKyuutoDir { path = cfg.libraryDir + "/games"; }
|
};
|
||||||
);
|
leaf = {
|
||||||
|
inherit (shared) owner group;
|
||||||
|
mode = mkDefault "2775";
|
||||||
|
};
|
||||||
|
setupFiles = [
|
||||||
|
{
|
||||||
|
${cfg.shareDir} = mkMerge [
|
||||||
|
shared
|
||||||
|
{ group = "peeps"; }
|
||||||
|
];
|
||||||
|
${cfg.transferDir} = shared;
|
||||||
|
${cfg.libraryDir} = shared;
|
||||||
|
${cfg.libraryDir + "/unsorted"} = shared;
|
||||||
|
${cfg.libraryDir + "/music"} = shared;
|
||||||
|
${cfg.libraryDir + "/music/assorted"} = leaf;
|
||||||
|
${cfg.libraryDir + "/music/collections"} = shared;
|
||||||
|
${cfg.libraryDir + "/anime"} = leaf;
|
||||||
|
${cfg.libraryDir + "/tv"} = leaf;
|
||||||
|
${cfg.libraryDir + "/movies"} = leaf;
|
||||||
|
${cfg.libraryDir + "/software"} = leaf;
|
||||||
|
${cfg.libraryDir + "/books"} = leaf;
|
||||||
|
${cfg.gameLibraryDir} = shared;
|
||||||
|
}
|
||||||
|
(listToAttrs (
|
||||||
|
map (gameLibrary: nameValuePair (cfg.gameLibraryDir + "/${gameLibrary}") leaf) cfg.gameLibraries
|
||||||
|
))
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
enable = mkIf cfg.setup true;
|
||||||
|
files = mkMerge [
|
||||||
|
(mkIf cfg.setup (mkMerge setupFiles))
|
||||||
|
(mkIf accountSwitch.enable {
|
||||||
|
${accountSwitch.gamesDir} = {
|
||||||
|
type = "bind";
|
||||||
|
bindReadOnly = true;
|
||||||
|
src = cfg.gameLibraryDir + "/PC";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
users = let
|
users = let
|
||||||
mapId = id: if config.proxmoxLXC.privileged or true then 100000 + id else id;
|
mapId = id: if config.proxmoxLXC.privileged or true then 100000 + id else id;
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ in {
|
||||||
public = false;
|
public = false;
|
||||||
browseable = false;
|
browseable = false;
|
||||||
"valid users" = [ "@peeps" ];
|
"valid users" = [ "@peeps" ];
|
||||||
"acl group control" = true;
|
"create mask" = "0775";
|
||||||
"create mask" = "0664";
|
"force file mode" = "3010";
|
||||||
"force directory mode" = "3000";
|
"force directory mode" = "3000";
|
||||||
"directory mask" = "7775";
|
"directory mask" = "7775";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
10
nixos/steam/account-switch.nix
Normal file
10
nixos/steam/account-switch.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.modules) mkDefault;
|
||||||
|
in {
|
||||||
|
services.steam.accountSwitch = {
|
||||||
|
enable = mkDefault true;
|
||||||
|
};
|
||||||
|
}
|
||||||
15
nixos/steam/beatsaber.nix
Normal file
15
nixos/steam/beatsaber.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.modules) mkDefault;
|
||||||
|
in {
|
||||||
|
services.steam.beatsaber = {
|
||||||
|
enable = mkDefault true;
|
||||||
|
defaultVersion = mkDefault "1.29.0";
|
||||||
|
versions = {
|
||||||
|
"1.29.0" = { };
|
||||||
|
"1.34.2" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,12 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [ "users" "peeps" "kyuuto" "wheel" ];
|
extraGroups = [
|
||||||
|
"users" "peeps"
|
||||||
|
"kyuuto"
|
||||||
|
"steamaccount" "beatsaber"
|
||||||
|
"wheel"
|
||||||
|
];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8Z6briIboxIdedPGObEWB6QEQkvxKvnMW/UVU9t/ac mew-pgp"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8Z6briIboxIdedPGObEWB6QEQkvxKvnMW/UVU9t/ac mew-pgp"
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,10 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [ "users" "peeps" "kyuuto" ];
|
extraGroups = [
|
||||||
|
"users" "peeps"
|
||||||
|
"kyuuto"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
users.groups.connieallure = { name, ... }: {
|
users.groups.connieallure = { name, ... }: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,19 @@ in {
|
||||||
filterAttrs (_: user: userIs "peeps" user && userIs "kyuuto" user) config.users.users
|
filterAttrs (_: user: userIs "peeps" user && userIs "kyuuto" user) config.users.users
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
steamaccount = {
|
||||||
|
gid = 8131;
|
||||||
|
};
|
||||||
|
beatsaber = {
|
||||||
|
gid = 8132;
|
||||||
|
};
|
||||||
|
|
||||||
|
admin = {
|
||||||
|
gid = 8126;
|
||||||
|
members = mapAttrsToList (_: user: user.name) (
|
||||||
|
filterAttrs (_: user: userIs "peeps" user && userIs "wheel" user) config.users.users
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
users.users = {
|
users.users = {
|
||||||
guest = {
|
guest = {
|
||||||
|
|
@ -27,5 +40,10 @@ in {
|
||||||
group = "nogroup";
|
group = "nogroup";
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
admin = {
|
||||||
|
uid = 8126;
|
||||||
|
group = "admin";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [ "users" "peeps" "kyuuto" ];
|
extraGroups = [
|
||||||
|
"users" "peeps"
|
||||||
|
"kyuuto"
|
||||||
|
"steamaccount" "beatsaber"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
users.groups.kaosubaloo = { name, ... }: {
|
users.groups.kaosubaloo = { name, ... }: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [ "users" "peeps" "kyuuto" "wheel" ];
|
extraGroups = [
|
||||||
|
"users" "peeps"
|
||||||
|
"kyuuto"
|
||||||
|
"steamaccount" "beatsaber"
|
||||||
|
"wheel"
|
||||||
|
];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCocjQqiDIvzq+Qu3jkf7FXw5piwtvZ1Mihw9cVjdVcsra3U2c9WYtYrA3rS50N3p00oUqQm9z1KUrvHzdE+03ZCrvaGdrtYVsaeoCuuvw7qxTQRbItTAEsfRcZLQ5c1v/57HNYNEsjVrt8VukMPRXWgl+lmzh37dd9w45cCY1QPi+JXQQ/4i9Vc3aWSe4X6PHOEMSBHxepnxm5VNHm4PObGcVbjBf0OkunMeztd1YYA9sEPyEK3b8IHxDl34e5t6NDLCIDz0N/UgzCxSxoz+YJ0feQuZtud/YLkuQcMxW2dSGvnJ0nYy7SA5DkW1oqcy6CGDndHl5StOlJ1IF9aGh0gGkx5SRrV7HOGvapR60RphKrR5zQbFFka99kvSQgOZqSB3CGDEQGHv8dXKXIFlzX78jjWDOBT67vA/M9BK9FS2iNnBF5x6shJ9SU5IK4ySxq8qvN7Us8emkN3pyO8yqgsSOzzJT1JmWUAx0tZWG/BwKcFBHfceAPQl6pwxx28TM3BTBRYdzPJLTkAy48y6iXW6UYdfAPlShy79IYjQtEThTuIiEzdzgYdros0x3PDniuAP0KOKMgbikr0gRa6zahPjf0qqBnHeLB6nHAfaVzI0aNbhOg2bdOueE1FX0x48sjKqjOpjlIfq4WeZp9REr2YHEsoLFOBfgId5P3BPtpBQ== yubikey5"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCocjQqiDIvzq+Qu3jkf7FXw5piwtvZ1Mihw9cVjdVcsra3U2c9WYtYrA3rS50N3p00oUqQm9z1KUrvHzdE+03ZCrvaGdrtYVsaeoCuuvw7qxTQRbItTAEsfRcZLQ5c1v/57HNYNEsjVrt8VukMPRXWgl+lmzh37dd9w45cCY1QPi+JXQQ/4i9Vc3aWSe4X6PHOEMSBHxepnxm5VNHm4PObGcVbjBf0OkunMeztd1YYA9sEPyEK3b8IHxDl34e5t6NDLCIDz0N/UgzCxSxoz+YJ0feQuZtud/YLkuQcMxW2dSGvnJ0nYy7SA5DkW1oqcy6CGDndHl5StOlJ1IF9aGh0gGkx5SRrV7HOGvapR60RphKrR5zQbFFka99kvSQgOZqSB3CGDEQGHv8dXKXIFlzX78jjWDOBT67vA/M9BK9FS2iNnBF5x6shJ9SU5IK4ySxq8qvN7Us8emkN3pyO8yqgsSOzzJT1JmWUAx0tZWG/BwKcFBHfceAPQl6pwxx28TM3BTBRYdzPJLTkAy48y6iXW6UYdfAPlShy79IYjQtEThTuIiEzdzgYdros0x3PDniuAP0KOKMgbikr0gRa6zahPjf0qqBnHeLB6nHAfaVzI0aNbhOg2bdOueE1FX0x48sjKqjOpjlIfq4WeZp9REr2YHEsoLFOBfgId5P3BPtpBQ== yubikey5"
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDPsu3vNsvBb/G+wALpstD/DnoRZ3fipAs00jtl8rzDuv96RlS7AJr4aNvG6Pt2D9SYn2wVLaiw+76mz2gOycH9/N+VCvL4/0MN9uqj+7XIcxNRo0gHVOblmi2bOXcmGKh3eRwHj1xyDwRxo9WIuBEP2bPpDPz75OXRtEdlTgvky7siSguQxJu03cb0p9hNAYhUoohNXyWW2CjDCLUQVE1+QRVUzsKq3KkPy0cHYgmZC1gRSMQyKpMt72L5tayLz3Tp/zrshucc+QO5IJeZdqMxsNAcvALsysT1J5EqxZoYH9VpWLRhSgVD6Nvn853pycJAlXQxgOCpSD3/v/JbgUe5NE+ci0o7NMy5IiHUv2gQMRIEhwBHlRGwokUPL9upx0lsjaEiPya5xQqqDKRom87xytM778ANS5CuMdQMWg9qVbpHZUHMjA0QmNkjPgq71pUDXHk5L4mZuS8wVjyjnvlw68yIJuHEc8P7QiLcjvRHFS2L9Ck8NRmPDTQXlQi9kk6LmMyu6fdevR/kZL21b+xO1e2DMyxBbNDTot8luppiiL8adgUDMwptpIne7JCWB1o9NFCbXUVgwuCCYBif6pOGSc6bGo1JTAKMflRlcy6Mi3t5H0mR2lj/sCSTWwTlP5FM4aPIq08NvW6PeuK1bFJY9fIgTwVsUnbAKOhmsMt62w== cardno:12 078 454"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDPsu3vNsvBb/G+wALpstD/DnoRZ3fipAs00jtl8rzDuv96RlS7AJr4aNvG6Pt2D9SYn2wVLaiw+76mz2gOycH9/N+VCvL4/0MN9uqj+7XIcxNRo0gHVOblmi2bOXcmGKh3eRwHj1xyDwRxo9WIuBEP2bPpDPz75OXRtEdlTgvky7siSguQxJu03cb0p9hNAYhUoohNXyWW2CjDCLUQVE1+QRVUzsKq3KkPy0cHYgmZC1gRSMQyKpMt72L5tayLz3Tp/zrshucc+QO5IJeZdqMxsNAcvALsysT1J5EqxZoYH9VpWLRhSgVD6Nvn853pycJAlXQxgOCpSD3/v/JbgUe5NE+ci0o7NMy5IiHUv2gQMRIEhwBHlRGwokUPL9upx0lsjaEiPya5xQqqDKRom87xytM778ANS5CuMdQMWg9qVbpHZUHMjA0QmNkjPgq71pUDXHk5L4mZuS8wVjyjnvlw68yIJuHEc8P7QiLcjvRHFS2L9Ck8NRmPDTQXlQi9kk6LmMyu6fdevR/kZL21b+xO1e2DMyxBbNDTot8luppiiL8adgUDMwptpIne7JCWB1o9NFCbXUVgwuCCYBif6pOGSc6bGo1JTAKMflRlcy6Mi3t5H0mR2lj/sCSTWwTlP5FM4aPIq08NvW6PeuK1bFJY9fIgTwVsUnbAKOhmsMt62w== cardno:12 078 454"
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ in {
|
||||||
nixos.base
|
nixos.base
|
||||||
nixos.reisen-ct
|
nixos.reisen-ct
|
||||||
nixos.kyuuto
|
nixos.kyuuto
|
||||||
|
nixos.steam.account-switch
|
||||||
|
nixos.steam.beatsaber
|
||||||
nixos.tailscale
|
nixos.tailscale
|
||||||
nixos.cloudflared
|
nixos.cloudflared
|
||||||
nixos.ddclient
|
nixos.ddclient
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,17 @@
|
||||||
nixos.base
|
nixos.base
|
||||||
nixos.reisen-ct
|
nixos.reisen-ct
|
||||||
nixos.kyuuto
|
nixos.kyuuto
|
||||||
|
nixos.steam.account-switch
|
||||||
|
nixos.steam.beatsaber
|
||||||
nixos.tailscale
|
nixos.tailscale
|
||||||
nixos.nfs
|
nixos.nfs
|
||||||
];
|
];
|
||||||
|
|
||||||
kyuuto.setup = true;
|
kyuuto.setup = true;
|
||||||
|
services.steam = {
|
||||||
|
accountSwitch.enable = false;
|
||||||
|
beatsaber.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
proxmoxLXC.privileged = true;
|
proxmoxLXC.privileged = true;
|
||||||
|
|
||||||
|
|
|
||||||
3
tree.nix
3
tree.nix
|
|
@ -30,6 +30,7 @@
|
||||||
};
|
};
|
||||||
"modules/nixos" = {
|
"modules/nixos" = {
|
||||||
functor = {
|
functor = {
|
||||||
|
enable = true;
|
||||||
external = with (import (inputs.arcexprs + "/modules")).nixos; [
|
external = with (import (inputs.arcexprs + "/modules")).nixos; [
|
||||||
nix
|
nix
|
||||||
systemd
|
systemd
|
||||||
|
|
@ -54,7 +55,7 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"modules/nixos".functor.enable = true;
|
"modules/nixos/steam".functor.enable = true;
|
||||||
"modules/meta".functor.enable = true;
|
"modules/meta".functor.enable = true;
|
||||||
"modules/system".functor.enable = true;
|
"modules/system".functor.enable = true;
|
||||||
"modules/home".functor.enable = true;
|
"modules/home".functor.enable = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue