diff --git a/hosts/server/toggles.nix b/hosts/server/toggles.nix index 2a0ab30..9bead84 100644 --- a/hosts/server/toggles.nix +++ b/hosts/server/toggles.nix @@ -81,6 +81,7 @@ in "stash" "synapse" "syncplay" + "synctube" "unpackerr" "yamtrack" ] diff --git a/hosts/vps/configuration.nix b/hosts/vps/configuration.nix index e1edce6..074559e 100644 --- a/hosts/vps/configuration.nix +++ b/hosts/vps/configuration.nix @@ -38,6 +38,7 @@ let synapseFederation = toString ports.synapseFederation; synapseClient = toString config.my.servers.synapse.port; syncplay = toString config.my.servers.syncplay.port; + synctube = toString config.my.servers.synctube.port; stash = toString config.my.servers.stash.port; jellyfin = toString config.my.servers.jellyfin.port; audiobookshelf = toString config.my.servers.audiobookshelf.port; @@ -112,7 +113,7 @@ in iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.syncthing} accept iifname "${wgInterface}" ip saddr ${ips.homeServer}/32 ip daddr ${subnets.wgFriends} tcp dport ${portsStr.syncthing} accept - iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 tcp dport { ${portsStr.synapseClient}, ${portsStr.synapseFederation}, ${portsStr.syncplay} } accept + iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 tcp dport { ${portsStr.synapseClient}, ${portsStr.synapseFederation}, ${portsStr.syncplay}, ${portsStr.synctube} } accept iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 icmp type echo-request accept iifname "${wgInterface}" ip saddr ${ips.wgFriend1}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept diff --git a/modules/servers/synctube.nix b/modules/servers/synctube.nix new file mode 100644 index 0000000..8629f38 --- /dev/null +++ b/modules/servers/synctube.nix @@ -0,0 +1,175 @@ +{ + lib, + config, + pkgs, + ... +}: +let + setup = import ../factories/mkserver.nix { inherit lib config; }; + cfg = config.my.servers.synctube; + withCommas = lib.replaceStrings [ "." ] [ "," ]; + mkHaxeLib = + { + libname, + version, + src, + }: + pkgs.stdenv.mkDerivation { + name = "${libname}-${version}"; + inherit src; + installPhase = '' + runHook preInstall + mkdir -p "$out/lib/haxe/${withCommas libname}/${withCommas version}" + echo -n "${version}" > "$out/lib/haxe/${withCommas libname}/.current" + cp -dpR . "$out/lib/haxe/${withCommas libname}/${withCommas version}/" + runHook postInstall + ''; + }; + mkHaxeGitLib = + { + libname, + owner, + repo, + rev, + hash, + }: + mkHaxeLib { + inherit libname; + version = "git"; + src = pkgs.fetchFromGitHub { + inherit + owner + repo + rev + hash + ; + }; + }; + hxnodejsGit = mkHaxeGitLib { + libname = "hxnodejs"; + owner = "HaxeFoundation"; + repo = "hxnodejs"; + rev = "ba7d9a566a79b3b36b4e1f58bc8e66306983e9e4"; + hash = "sha256-RZ+GoRlTvcalVsexd8Fw3/P4XZYh5IZQJNzyFkEOgAc="; + }; + hxnodejsWs = mkHaxeGitLib { + libname = "hxnodejs-ws"; + owner = "haxe-externs"; + repo = "hxnodejs-ws"; + rev = "2d0e770489abdb8d095fc4694353eaa9d6743562"; + hash = "sha256-Gls4OeOCSU9Ld3rZ76086BH2TMxRvPj658sKWDP4pds="; + }; + json2object = mkHaxeGitLib { + libname = "json2object"; + owner = "RblSb"; + repo = "json2object"; + rev = "8d949c12a93bdae010603af955a453458603cd47"; + hash = "sha256-lD1IDg6xULRwisAtSZIyBju8yIa7nmM5eSezz05udaw="; + }; + hxjsonast = mkHaxeGitLib { + libname = "hxjsonast"; + owner = "elnabo"; + repo = "hxjsonast"; + rev = "9a9544378c9517e5cf4c5fa3c092e77bec125e64"; + hash = "sha256-AvcxbksuLCKGRCHAxFYHdF7e32efBvPdXLTbHbd+q/c="; + }; + ytdlpNodejs = mkHaxeGitLib { + libname = "ytdlp-nodejs"; + owner = "haxe-externs"; + repo = "ytdlp-nodejs-externs"; + rev = "dbd476ce53a0c38db36e430ded28b2740001e8aa"; + hash = "sha256-mitC7wzZdJxt4B0UhMrnShhMd9Gup5G9EpSbUSJj8dA="; + }; + youtubeIFramePlayer = mkHaxeGitLib { + libname = "youtubeIFramePlayer"; + owner = "haxe-externs"; + repo = "youtubeIFramePlayer-externs"; + rev = "8d47d71a4e3b8030a83a2e11672f120ca9a086d4"; + hash = "sha256-ov0nbhEazVCcWHcxplCNdN0KRhxBKqsvFHjmGzvTvPI="; + }; + hlsJsExtern = mkHaxeGitLib { + libname = "hls.js-extern"; + owner = "zoldesi-andor"; + repo = "hls.js-haxe-extern"; + rev = "86448a1dad21e72126ce8cc078062648de8bc2c5"; + hash = "sha256-MnT71PwoQd66DOzHMp8X3Yt8XulUkA1tX4dgUv7JLio="; + }; + utest = mkHaxeGitLib { + libname = "utest"; + owner = "haxe-utest"; + repo = "utest"; + rev = "654d6a32cc84c81972a5d3768e400d7317fff6e5"; + hash = "sha256-3tdiEE1tXx5Jht+amAH3e5mKa5kAihJlklFaJLeTriE="; + }; + haxeLibs = pkgs.runCommand "synctube-haxelibs" { } '' + mkdir -p "$out/lib/haxe" + cp -r ${hxnodejsGit}/lib/haxe/* "$out/lib/haxe/" + cp -r ${hxnodejsWs}/lib/haxe/* "$out/lib/haxe/" + cp -r ${json2object}/lib/haxe/* "$out/lib/haxe/" + cp -r ${hxjsonast}/lib/haxe/* "$out/lib/haxe/" + cp -r ${ytdlpNodejs}/lib/haxe/* "$out/lib/haxe/" + cp -r ${youtubeIFramePlayer}/lib/haxe/* "$out/lib/haxe/" + cp -r ${hlsJsExtern}/lib/haxe/* "$out/lib/haxe/" + cp -r ${utest}/lib/haxe/* "$out/lib/haxe/" + ''; + synctubePackage = pkgs.buildNpmPackage { + pname = "synctube"; + version = "1.0.0"; + src = pkgs.fetchFromGitHub { + owner = "RblSb"; + repo = "SyncTube"; + rev = "276e12db29ab31aa002f55b1a3cc69f170c1a2c2"; + hash = "sha256-1ySSYF4DjkND1FTpn/HUtemmXVzK6+k/89HsKZ0r0PE="; + }; + npmDepsHash = "sha256-dIbBNvTQCv1fjboBC6Q8kGqcZbLNuGmgHw9DgOmVnTw="; + dontNpmBuild = true; + nativeBuildInputs = [ + pkgs.haxe + pkgs.neko + ]; + buildPhase = '' + runHook preBuild + export HAXELIB_PATH=${haxeLibs}/lib/haxe + haxe build-all.hxml + runHook postBuild + ''; + }; + synctubeImage = pkgs.dockerTools.buildImage { + name = "synctube"; + tag = "nix"; + copyToRoot = pkgs.buildEnv { + name = "synctube-root"; + paths = [ + synctubePackage + pkgs.nodejs + ]; + pathsToLink = [ + "/app" + "/bin" + ]; + }; + config = { + WorkingDir = "/app/lib/node_modules/synctube"; + Cmd = [ + "/bin/node" + "build/server.js" + ]; + Env = [ + "NODE_ENV=production" + "NODE_PATH=/app/lib/node_modules/synctube/node_modules" + "PATH=/bin" + ]; + }; + }; +in +{ + options.my.servers.synctube = setup.mkOptions "synctube" "synctube" 4200; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + virtualisation.oci-containers.containers.synctube = { + image = "synctube:nix"; + imageFile = synctubeImage; + ports = [ "${toString cfg.port}:4200" ]; + environment.TZ = config.my.timeZone; + }; + }; +}