{ description = "Simple interface for MPD services"; nixConfig = { extra-substituters = [ "https://cache.elnafo.ru" ]; extra-trusted-public-keys = [ "cache.elnafo.ru:j3VD+Hn+is2Qk3lPXDSdPwHJQSatizk7V82iJ2RP1yo=" ]; }; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; crane = { url = "github:ipetkov/crane"; }; fenix = { url = "github:nix-community/fenix"; inputs.nixpkgs.follows = "nixpkgs"; inputs.rust-analyzer-src.follows = ""; }; dream2nix = { url = "github:nix-community/dream2nix"; inputs.nixpkgs.follows = "nixpkgs"; }; advisory-db = { url = "github:rustsec/advisory-db"; flake = false; }; nix-std.url = "github:chessai/nix-std"; }; outputs = {self, ...} @ inputs: let maintainers = { L-Nafaryus = { email = "l.nafaryus@elnafo.ru"; github = "L-Nafaryus"; githubId = 37117584; name = "L-Nafaryus"; }; }; pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; lib = pkgs.lib; fenixPkgs = inputs.fenix.packages.x86_64-linux; craneLib = (inputs.crane.mkLib pkgs).overrideToolchain fenixPkgs.complete.toolchain; dreamBuildPackage = { module, meta ? {}, extraModules ? [], extraArgs ? {}, }: ( inputs.nixpkgs.lib.evalModules { modules = [module] ++ extraModules; specialArgs = { inherit (inputs) dream2nix; packageSets.nixpkgs = pkgs; } // extraArgs; } ) .config .public // {inherit meta;}; src = craneLib.cleanCargoSource ./.; cargoVendorDeps = craneLib.vendorCargoDeps { inherit src; }; commonArgs = { inherit src; strictDeps = true; }; cargoArtifacts = craneLib.buildDepsOnly commonArgs; crateArgs = { inherit cargoArtifacts; src = lib.fileset.toSource { root = ./.; fileset = lib.fileset.unions [ ./Cargo.toml ./Cargo.lock ./crates/backend ./crates/frontend ]; }; strictDeps = true; configurePhase = '' cp -rv ${self.packages.x86_64-linux.elnafo-radio-vue}/dist ./crates/frontend/ ln -sv ${cargoVendorDeps}/config.toml ./.cargo-home/config.toml ''; }; in { packages.x86_64-linux = rec { elnafo-radio-vue = dreamBuildPackage { module = { lib, config, dream2nix, ... }: { name = "elnafo-radio-vue"; version = "0.1.0"; imports = [ dream2nix.modules.dream2nix.WIP-nodejs-builder-v3 ]; mkDerivation = { src = ./crates/frontend; }; deps = {nixpkgs, ...}: { inherit (nixpkgs) fetchFromGitHub stdenv ; }; WIP-nodejs-builder-v3 = { packageLockFile = "${config.mkDerivation.src}/package-lock.json"; }; }; meta = with lib; { description = "Simple interface for MPD services (frontend)"; license = licenses.mit; maintainers = with maintainers; [L-Nafaryus]; broken = false; }; }; elnafo-radio = craneLib.buildPackage { pname = "elnafo-radio"; version = "0.1.0"; src = lib.fileset.toSource { root = ./.; fileset = lib.fileset.unions [ ./Cargo.toml ./Cargo.lock ./crates/backend ./crates/frontend ]; }; strictDeps = true; cargoExtraArgs = "-p elnafo-radio"; configurePhase = '' cp -rv ${self.packages.x86_64-linux.elnafo-radio-vue}/dist ./crates/frontend/ ln -sv ${cargoVendorDeps}/config.toml ./.cargo-home/config.toml ''; inherit cargoArtifacts; meta = with lib; { description = "Simple interface for MPD services"; license = licenses.mit; maintainers = with maintainers; [L-Nafaryus]; platforms = platforms.x86_64; mainProgram = "elnafo-radio"; }; }; default = elnafo-radio; }; checks.x86_64-linux = { inherit (self.packages.x86_64-linux) elnafo-radio-vue elnafo-radio; elnafo-radio-fmt = craneLib.cargoFmt { inherit src; }; elnafo-radio-doc = craneLib.cargoDoc crateArgs; elnafo-radio-clippy = craneLib.cargoClippy crateArgs; elnafo-radio-audit = craneLib.cargoAudit { inherit src; inherit (inputs) advisory-db; }; my-workspace-deny = craneLib.cargoDeny { inherit src; }; }; devShells.x86_64-linux = { default = pkgs.mkShell { buildInputs = [ fenixPkgs.complete.toolchain pkgs.ripgrep pkgs.cargo-watch pkgs.mold-wrapped pkgs.nodejs pkgs.cargo-release ]; }; }; nixosModules = rec { elnafo-radio = { config, lib, pkgs, ... }: with lib; let cfg = config.services.elnafo-radio; in { options.services.elnafo-radio = { enable = mkEnableOption "Enables the elnafo-radio service"; package = mkOption { type = types.package; default = self.packages.x86_64-linux.elnafo-radio; description = "The package to use."; }; dataDir = mkOption { type = types.path; default = "/var/lib/elnafo-radio"; description = lib.mdDoc "Directory to store data files"; }; base = mkOption { type = types.submodule { options = { title = mkOption { type = types.str; default = "Elnafo Radio"; description = "Title of the page"; }; meta = mkOption { type = types.nullOr (types.listOf (types.listOf types.str)); default = null; description = "List of meta tag pairs"; }; }; }; default = {title = "Elnafo Radio";}; description = "Base configuration"; }; server = mkOption { type = types.submodule { options = { address = mkOption { type = types.str; default = "127.0.0.1"; description = "Server address"; }; port = mkOption { type = types.port; default = 54605; description = "Server port"; }; }; }; default = { address = "127.0.0.1"; port = 54605; }; description = "Server configuration"; }; stations = mkOption { type = types.nullOr (types.listOf (types.submodule { options = { id = mkOption { type = types.str; description = "Station id"; }; name = mkOption { type = types.str; description = "Station name"; }; address = mkOption { type = types.str; description = "MPD service address"; }; port = mkOption { type = types.port; description = "MPD service port"; }; url = mkOption { type = types.nullOr types.str; default = null; description = "Station stream url"; }; status = mkOption { type = types.nullOr types.str; default = null; description = "Station status"; }; genre = mkOption { type = types.nullOr types.str; default = null; description = "Station genre"; }; location = mkOption { type = types.nullOr types.str; default = null; description = "Station location"; }; }; })); default = null; description = "Server configuration"; }; }; config = mkIf cfg.enable { users.users.elnafo-radio = { description = "Elnafo radio service user"; home = cfg.dataDir; createHome = true; isSystemUser = true; group = "elnafo-radio"; }; users.groups.elnafo-radio = {}; systemd.services.elnafo-radio = { description = "Elnafo radio service"; wantedBy = ["multi-user.target"]; after = ["network.target"]; serviceConfig = { Restart = "always"; ExecStart = "${lib.getExe cfg.package}"; User = "elnafo-radio"; WorkingDirectory = cfg.dataDir; }; preStart = let toTOML = inputs.nix-std.lib.serde.toTOML; configFile = pkgs.writeText "config.toml" '' ${toTOML {inherit (cfg) base server stations;}} ''; in '' ln -sf ${configFile} ./config.toml ''; }; }; }; default = elnafo-radio; }; nixosConfigurations.elnafo-radio = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ self.nixosModules.elnafo-radio ({pkgs, ...}: { boot.isContainer = true; networking.hostName = "elnafo-radio"; networking.useDHCP = false; services.elnafo-radio = { enable = true; base.meta = [ ["author" "L-Nafaryus"] ]; stations = [ { id = "test"; name = "Test"; address = "127.0.0.1"; port = 8080; } ]; }; system.stateVersion = "24.05"; }) ]; }; }; }