From 3ce79d65f99d9e08968f83582d768dc003df929b Mon Sep 17 00:00:00 2001 From: Tomo <68489118+Tomodachi94@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:54:26 -0700 Subject: [PATCH] Add NixOS module --- flake.lock | 60 +++++++++++++++++++++ flake.nix | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..2507fb2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1690881714, + "narHash": "sha256-h/nXluEqdiQHs1oSgkOOWF+j8gcJMWhwnZ9PFabN6q0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9e1960bc196baf6881340d53dccb203a951745a2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..6a7239f --- /dev/null +++ b/flake.nix @@ -0,0 +1,152 @@ +{ + description = "The Heart of YouCube. See the documentation at https://youcube.madefor.cc."; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils, }: + utils.lib.eachSystem [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ] + (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + version = builtins.substring 0 8 self.lastModifiedDate; + deps = with pkgs.python3Packages; [ + sanic + yt-dlp + ujson + spotipy + ]; + in + { + packages = { + default = pkgs.python3Packages.buildPythonApplication { + pname = "youcube"; + inherit version; + src = ./.; + format = "pyproject"; + patchPhase = "rm src/requirements.txt"; + buildInputs = [ pkgs.python3Packages.setuptools ]; + nativeBuildInputs = [ pkgs.makeWrapper ]; + propagatedBuildInputs = deps; + pythonImportsCheck = [ "youcube" ]; + postInstall = '' + mkdir -p $out/bin + makeWrapper ${pkgs.python3}/bin/python3 $out/bin/youcube-server \ + --add-flags "$out/lib/${pkgs.python3.libPrefix}/site-packages/youcube/__main__.py" \ + --set PYTHONPATH "${pkgs.python3.pkgs.makePythonPath deps}" \ + --set PATH "${pkgs.lib.makeBinPath [ pkgs.sanjuuni pkgs.ffmpeg ]}" + ''; + }; + + docker = + let server = self.packages.${system}.default; + in pkgs.dockerTools.buildLayeredImage { + name = server.pname; + tag = server.version; + contents = [ server pkgs.sanjuuni pkgs.ffmpeg ] ++ self.packages.${system}.default.propagatedBuildInputs; + + config = { + Cmd = + let pkg = self.packages.${system}.default; + in [ "${pkg}/bin/youcube-server" ]; + WorkingDir = "/"; + }; + }; + }; + + defaultApp = utils.lib.mkApp { drv = self.packages.${system}.default; }; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ python3 python3Packages.pip sanjuuni ffmpeg ]; + }; + + }) // { + + nixosModules.default = { config, lib, pkgs, ... }: + with lib; + let + cfg = config.services.youcube-server; + in + { + options.services.youcube-server = { + enable = mkOption { + type = types.bool; + default = false; + }; + packages = { + type = types.submodule; + description = lib.mdDoc "Packages used by YouCube"; + options = { + sanjuuni = mkPackageOptionMD pkgs "sanjuuni" { }; + ffmpeg = mkPackageOptionMD pkgs "ffmpeg" { }; + }; + }; + + spotify = { + type = types.submodule; + description = "Spotify support"; + options = { + credentialsFile = mkOption { + type = types.path; + description = lib.mdDoc '' + File containing the SPOTIFY_CLIENT_ID and + SPOTIFY_CLIENT_SECRET in the format of + an EnvironmentFile=, as described by systemd.exec(5). + ''; + example = "/etc/nixos/youcube-spotify-credentials"; + default = null; + }; + }; + }; + + host = mkOption { + description = lib.mdDoc "The host of the YouCube server."; + default = "0.0.0.0"; + type = types.string; + }; + + port = mkOption { + description = lib.mdDoc "YouCube server port."; + default = 5000; + type = types.port; + }; + }; + + config = mkIf cfg.enable { + systemd.services."youcube.youcube-server" = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = + let + pkg = self.packages.${system}.default; + in + { + Restart = "on-failure"; + ExecStart = "python3 ${pkg}/${pkgs.python3.sitePackages}/youcube/__main__.py"; + DynamicUser = "yes"; + RuntimeDirectory = "youcube.youcube-server"; + RuntimeDirectoryMode = "0755"; + StateDirectory = "youcube.youcube-server"; + StateDirectoryMode = "0700"; + CacheDirectory = "youcube.youcube-server"; + CacheDirectoryMode = "0750"; + EnvironmentFile = [ (cfg.spotify.credentialsFile || "/dev/null") ]; + }; + environment = { + SANJUUNI_PATH = "${cfg.packages.sanjuuni}/bin/sanjuuni"; + FFMPEG_PATH = "${cfg.packages.ffmpeg}/bin/ffmpeg"; + HOST = "${cfg.host}"; + PORT = "${cfg.port}"; + }; + }; + }; + }; + }; +}