From 4893de0d2878a4161cb72c1adea7d70e7530c66c Mon Sep 17 00:00:00 2001 From: reidlab Date: Sun, 18 May 2025 23:17:32 -0700 Subject: [PATCH] nix module! --- README.md | 10 ++- flake.lock | 32 ++------ flake.nix | 230 +++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 204 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 77350b3..8b985fa 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,15 @@ most of the config is talked on in [`config.example.toml`](./config.example.toml ### running -just as easy as running `npm run build` and running the `dist/index.js` file with your javascript engine of choice +#### regular -alternatively, use the nix flake, which has the proper `mainProgram` and default package attributes to make it easy. a nixos module is on its way!! don't fret +after configuring, it's just as easy as running `npm run build` and running the `dist/index.js` file with your javascript engine of choice + +#### nix + +a system module is provided for your convenience, and the main output is `nixosModules.default` + +after importing this module, the option `services.amdl` will show up, which is documented in [`flake.nix`](./flake.nix) somewhat well. everything under the `config` tree follows the `config.toml` well, along with everything under the `env` tree. defaults are provided for everything that isn't the private keys and client ids inside of the env section. make sure to set those!! ## limitations / the formats diff --git a/flake.lock b/flake.lock index 4b40286..6bc2e86 100644 --- a/flake.lock +++ b/flake.lock @@ -1,23 +1,5 @@ { "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1739866667, @@ -36,22 +18,22 @@ }, "root": { "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "systems": "systems" } }, "systems": { "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", "type": "github" }, "original": { "owner": "nix-systems", - "repo": "default", + "repo": "default-linux", "type": "github" } } diff --git a/flake.nix b/flake.nix index 0552772..046375b 100644 --- a/flake.nix +++ b/flake.nix @@ -2,51 +2,59 @@ description = "amdl"; inputs = { - flake-utils.url = "github:numtide/flake-utils"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + systems.url = "github:nix-systems/default-linux"; }; - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; + outputs = { self, nixpkgs, systems, ... }: + let + inherit (nixpkgs) lib; + eachSystem = lib.genAttrs (import systems); + pkgsFor = eachSystem (system: import nixpkgs { inherit system; }); + package = builtins.fromJSON (builtins.readFile ./package.json); + in { + packages = eachSystem (system: let + inherit (lib) makeBinPath; + pkgs = pkgsFor.${system}; + in rec { + default = amdl; + amdl = pkgs.buildNpmPackage rec { + pname = package.name; + inherit (package) version; + + # uncomment this and let the build fail, then get the current hash + # very scuffed but endorsed! + # npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + npmDepsHash = "sha256-hMI010P3lJIMCMaj9HYUZopMAWaNQMCG1QXk/OdV1u4="; + + nativeBuildInputs = with pkgs; [ makeWrapper ]; + + buildInputs = with pkgs; [ ffmpeg yt-dlp ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out + mv node_modules dist views public $out/ + makeWrapper ${pkgs.nodejs-slim}/bin/node $out/bin/amdl \ + --prefix PATH : ${makeBinPath buildInputs} \ + --add-flags "$out/dist/index.js" \ + --set VIEWS_DIR $out/views \ + --set PUBLIC_DIR $out/public + + runHook postInstall + ''; + + src = ./.; + + meta.mainProgram = package.name; }; - package = builtins.fromJSON (builtins.readFile ./package.json); + }); + + devShells = eachSystem (system: let + pkgs = pkgsFor.${system}; in { - packages = flake-utils.lib.flattenTree rec { - default = amdl; - amdl = pkgs.buildNpmPackage { - pname = package.name; - inherit (package) version; - - # uncomment this and let the build fail, then get the current hash - # very scuffed but endorsed! - # npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - npmDepsHash = "sha256-hMI010P3lJIMCMaj9HYUZopMAWaNQMCG1QXk/OdV1u4="; - - nativeBuildInputs = with pkgs; [ makeWrapper ]; - - installPhase = '' - runHook preInstall - - mkdir -p $out - mv node_modules dist views public $out/ - makeWrapper ${pkgs.nodejs-slim}/bin/node $out/bin/amdl \ - --add-flags "$out/dist/index.js" \ - --set VIEWS_DIR $out/views \ - --set PUBLIC_DIR $out/public - - runHook postInstall - ''; - - src = ./.; - - meta.mainProgram = package.name; - }; - }; - - devShells.default = pkgs.mkShell { + default = pkgs.mkShell { packages = with pkgs; [ nodejs nodePackages.npm @@ -54,5 +62,145 @@ ffmpeg yt-dlp ]; }; - }); + }); + + nixosModules = rec { + default = amdl; + amdl = { config, lib, pkgs, ... }: let + inherit (pkgs) system; + inherit (lib) getExe mkEnableOption mkIf mkOption types; + cfg = config.services.amdl; + in { + options = { + services.amdl = { + enable = mkEnableOption "enable amdl"; + package = mkOption { + type = types.package; + default = self.packages.${system}.amdl; + }; + stateDir = mkOption { + type = types.path; + default = "/var/lib/amdl"; + }; + user = mkOption { + type = types.str; + default = "amdl"; + }; + group = mkOption { + type = types.str; + default = "amdl"; + }; + config = { + server = { + port = mkOption { + type = types.int; + default = 2000; + }; + frontend = { + search_count = mkOption { + type = types.int; + default = 5; + }; + displayed_codecs = mkOption { + type = types.listOf types.str; + default = ["aac_legacy" "aac_he_legacy"]; + }; + }; + }; + downloader = { + ffmpeg_path = mkOption { + type = types.str; + default = "ffmpeg"; + }; + ytdlp_path = mkOption { + type = types.str; + default = "yt-dlp"; + }; + cache = { + directory = mkOption { + type = types.str; + default = "cache"; + }; + ttl = mkOption { + type = types.int; + default = 3600; + }; + }; + api = { + language = mkOption { + type = types.str; + default = "en-US"; + }; + }; + }; + }; + env = { + MEDIA_USER_TOKEN = mkOption { + type = types.str; + }; + ITUA = mkOption { + type = types.str; + default = "US"; + }; + WIDEVINE_CLIENT_ID = mkOption { + type = types.str; + }; + WIDEVINE_PRIVATE_KEY = mkOption { + type = types.str; + }; + # do NOT include views/public directory here + # we set that in the wrapper script of the program, so it wouldn't even do anything + # probably shouldn't change it anyway... bad idea + }; + }; + }; + + config = let + toml = pkgs.formats.toml { }; + in mkIf cfg.enable { + systemd.services.amdl = { + description = "amdl"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + preStart = '' + config='${cfg.stateDir}/config.toml' + cp -f '${toml.generate "config.toml" cfg.config}' "$config" + ''; # TODO: symlink instead of cp, shouldn't matter for reproducibility since its preStart but whatever + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + WorkingDirectory = cfg.stateDir; + ExecStart = "${getExe cfg.package}"; + Restart = "always"; + RuntimeDirectory = "amdl"; + RuntimeDirectoryMode = "0755"; + }; + + environment = { + MEDIA_USER_TOKEN = cfg.env.MEDIA_USER_TOKEN; + ITUA = cfg.env.ITUA; + WIDEVINE_CLIENT_ID = cfg.env.WIDEVINE_CLIENT_ID; + WIDEVINE_PRIVATE_KEY = cfg.env.WIDEVINE_PRIVATE_KEY; + }; # TODO: write some function to do this, also is this safe?? + }; + + users.users = mkIf (cfg.user == "amdl") { + amdl = { + home = cfg.stateDir; + group = cfg.group; + createHome = true; + isSystemUser = true; + useDefaultShell = true; + }; + }; + users.groups = mkIf (cfg.group == "amdl") { + amdl = { }; + }; + }; + }; + }; + }; }