Merge pull request #293817 from PatrickDaG/your_spotify
nixos/your_spotify: init at 1.10.1
This commit is contained in:
commit
4275fc290a
|
@ -15488,6 +15488,15 @@
|
|||
githubId = 69802930;
|
||||
name = "patka";
|
||||
};
|
||||
patrickdag = {
|
||||
email = "patrick-nixos@failmail.dev";
|
||||
github = "PatrickDaG";
|
||||
githubId = 58092422;
|
||||
name = "Patrick";
|
||||
keys = [{
|
||||
fingerprint = "5E4C 3D74 80C2 35FE 2F0B D23F 7DD6 A72E C899 617D";
|
||||
}];
|
||||
};
|
||||
patricksjackson = {
|
||||
email = "patrick@jackson.dev";
|
||||
github = "patricksjackson";
|
||||
|
|
|
@ -187,6 +187,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
|
|||
|
||||
- [xdg-terminal-exec](https://github.com/Vladimir-csp/xdg-terminal-exec), the proposed Default Terminal Execution Specification.
|
||||
|
||||
- [your_spotify](https://github.com/Yooooomi/your_spotify), a self hosted Spotify tracking dashboard. Available as [services.your_spotify](#opt-services.your_spotify.enable)
|
||||
|
||||
- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. Available as [services.rustdesk-server](#opt-services.rustdesk-server.enable).
|
||||
|
||||
- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. Available as [services.scrutiny](#opt-services.scrutiny.enable).
|
||||
|
|
|
@ -1431,6 +1431,7 @@
|
|||
./services/web-apps/windmill.nix
|
||||
./services/web-apps/wordpress.nix
|
||||
./services/web-apps/writefreely.nix
|
||||
./services/web-apps/your_spotify.nix
|
||||
./services/web-apps/youtrack.nix
|
||||
./services/web-apps/zabbix.nix
|
||||
./services/web-apps/zitadel.nix
|
||||
|
|
191
nixos/modules/services/web-apps/your_spotify.nix
Normal file
191
nixos/modules/services/web-apps/your_spotify.nix
Normal file
|
@ -0,0 +1,191 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
boolToString
|
||||
concatMapAttrs
|
||||
concatStrings
|
||||
isBool
|
||||
mapAttrsToList
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optionalAttrs
|
||||
types
|
||||
mkDefault
|
||||
;
|
||||
cfg = config.services.your_spotify;
|
||||
|
||||
configEnv = concatMapAttrs (name: value:
|
||||
optionalAttrs (value != null) {
|
||||
${name} =
|
||||
if isBool value
|
||||
then boolToString value
|
||||
else toString value;
|
||||
})
|
||||
cfg.settings;
|
||||
|
||||
configFile = pkgs.writeText "your_spotify.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv));
|
||||
in {
|
||||
options.services.your_spotify = let
|
||||
inherit (types) nullOr port str path package;
|
||||
in {
|
||||
enable = mkEnableOption "your_spotify";
|
||||
|
||||
enableLocalDB = mkEnableOption "a local mongodb instance";
|
||||
nginxVirtualHost = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
If set creates an nginx virtual host for the client.
|
||||
In most cases this should be the CLIENT_ENDPOINT without
|
||||
protocol prefix.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "your_spotify" {};
|
||||
|
||||
clientPackage = mkOption {
|
||||
type = package;
|
||||
description = "Client package to use.";
|
||||
};
|
||||
|
||||
spotifySecretFile = mkOption {
|
||||
type = path;
|
||||
description = ''
|
||||
A file containing the secret key of your Spotify application.
|
||||
Refer to: [Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application).
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
Your Spotify Configuration. Refer to [Your Spotify](https://github.com/Yooooomi/your_spotify) for definitions and values.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
CLIENT_ENDPOINT = "https://example.com";
|
||||
API_ENDPOINT = "https://api.example.com";
|
||||
SPOTIFY_PUBLIC = "spotify_client_id";
|
||||
}
|
||||
'';
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf types.str;
|
||||
options = {
|
||||
CLIENT_ENDPOINT = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The endpoint of your web application.
|
||||
Has to include a protocol Prefix (e.g. `http://`)
|
||||
'';
|
||||
example = "https://your_spotify.example.org";
|
||||
};
|
||||
API_ENDPOINT = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The endpoint of your server
|
||||
This api has to be reachable from the device you use the website from not from the server.
|
||||
This means that for example you may need two nginx virtual hosts if you want to expose this on the
|
||||
internet.
|
||||
Has to include a protocol Prefix (e.g. `http://`)
|
||||
'';
|
||||
example = "https://localhost:3000";
|
||||
};
|
||||
SPOTIFY_PUBLIC = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
The public client ID of your Spotify application.
|
||||
Refer to: [Creating the Spotify Application](https://github.com/Yooooomi/your_spotify#creating-the-spotify-application)
|
||||
'';
|
||||
};
|
||||
MONGO_ENDPOINT = mkOption {
|
||||
type = str;
|
||||
description = ''The endpoint of the Mongo database.'';
|
||||
default = "mongodb://localhost:27017/your_spotify";
|
||||
};
|
||||
PORT = mkOption {
|
||||
type = port;
|
||||
description = "The port of the api server";
|
||||
default = 3000;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.your_spotify.clientPackage = mkDefault (cfg.package.client.override {apiEndpoint = cfg.settings.API_ENDPOINT;});
|
||||
systemd.services.your_spotify = {
|
||||
after = ["network.target"];
|
||||
script = ''
|
||||
export SPOTIFY_SECRET=$(< "$CREDENTIALS_DIRECTORY/SPOTIFY_SECRET")
|
||||
${lib.getExe' cfg.package "your_spotify_migrate"}
|
||||
exec ${lib.getExe cfg.package}
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = "your_spotify";
|
||||
Group = "your_spotify";
|
||||
DynamicUser = true;
|
||||
EnvironmentFile = [configFile];
|
||||
StateDirectory = "your_spotify";
|
||||
LimitNOFILE = "1048576";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
StateDirectoryMode = "0700";
|
||||
Restart = "always";
|
||||
|
||||
LoadCredential = ["SPOTIFY_SECRET:${cfg.spotifySecretFile}"];
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
LockPersonality = true;
|
||||
#MemoryDenyWriteExecute = true; # Leads to coredump because V8 does JIT
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"@pkey"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
services.nginx = mkIf (cfg.nginxVirtualHost != null) {
|
||||
enable = true;
|
||||
virtualHosts.${cfg.nginxVirtualHost} = {
|
||||
root = cfg.clientPackage;
|
||||
locations."/".extraConfig = ''
|
||||
add_header Content-Security-Policy "frame-ancestors 'none';" ;
|
||||
add_header X-Content-Type-Options "nosniff" ;
|
||||
try_files = $uri $uri/ /index.html ;
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.mongodb = mkIf cfg.enableLocalDB {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
meta.maintainers = with lib.maintainers; [patrickdag];
|
||||
}
|
|
@ -1042,6 +1042,7 @@ in {
|
|||
yabar = handleTest ./yabar.nix {};
|
||||
ydotool = handleTest ./ydotool.nix {};
|
||||
yggdrasil = handleTest ./yggdrasil.nix {};
|
||||
your_spotify = handleTest ./your_spotify.nix {};
|
||||
zammad = handleTest ./zammad.nix {};
|
||||
zeronet-conservancy = handleTest ./zeronet-conservancy.nix {};
|
||||
zfs = handleTest ./zfs.nix {};
|
||||
|
|
33
nixos/tests/your_spotify.nix
Normal file
33
nixos/tests/your_spotify.nix
Normal file
|
@ -0,0 +1,33 @@
|
|||
import ./make-test-python.nix ({pkgs, ...}: {
|
||||
name = "your_spotify";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [patrickdag];
|
||||
};
|
||||
|
||||
nodes.machine = {
|
||||
services.your_spotify = {
|
||||
enable = true;
|
||||
spotifySecretFile = pkgs.writeText "spotifySecretFile" "deadbeef";
|
||||
settings = {
|
||||
CLIENT_ENDPOINT = "http://localhost";
|
||||
API_ENDPOINT = "http://localhost:3000";
|
||||
SPOTIFY_PUBLIC = "beefdead";
|
||||
};
|
||||
enableLocalDB = true;
|
||||
nginxVirtualHost = "localhost";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("your_spotify.service")
|
||||
|
||||
machine.wait_for_open_port(3000)
|
||||
machine.wait_for_open_port(80)
|
||||
|
||||
out = machine.succeed("curl --fail -X GET 'http://localhost:3000/'")
|
||||
assert "Hello !" in out
|
||||
|
||||
out = machine.succeed("curl --fail -X GET 'http://localhost:80/'")
|
||||
assert "<title>Your Spotify</title>" in out
|
||||
'';
|
||||
})
|
58
pkgs/by-name/yo/your_spotify/client.nix
Normal file
58
pkgs/by-name/yo/your_spotify/client.nix
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
apiEndpoint ? "http://localhost:3000",
|
||||
fetchYarnDeps,
|
||||
your_spotify,
|
||||
mkYarnPackage,
|
||||
fixup-yarn-lock,
|
||||
src,
|
||||
version,
|
||||
yarn,
|
||||
}:
|
||||
mkYarnPackage rec {
|
||||
inherit version src;
|
||||
pname = "your_spotify_client";
|
||||
name = "your_spotify_client-${version}";
|
||||
packageJSON = ./package.json;
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = src + "/yarn.lock";
|
||||
hash = "sha256-5SgknaRVzgO2Dzc8MhAaM8UERWMv+PrItzevoWHbWnA=";
|
||||
};
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
export HOME=$(mktemp -d)
|
||||
yarn config --offline set yarn-offline-mirror $offlineCache
|
||||
fixup-yarn-lock yarn.lock
|
||||
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
|
||||
patchShebangs node_modules/
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
pushd ./apps/client/
|
||||
yarn --offline run build
|
||||
export API_ENDPOINT="${apiEndpoint}"
|
||||
substituteInPlace scripts/run/variables.sh --replace-quiet '/app/apps/client/' "./"
|
||||
|
||||
chmod +x ./scripts/run/variables.sh
|
||||
patchShebangs --build ./scripts/run/variables.sh
|
||||
|
||||
./scripts/run/variables.sh
|
||||
|
||||
popd
|
||||
runHook postBuild
|
||||
'';
|
||||
nativeBuildInputs = [yarn fixup-yarn-lock];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
cp -r ./apps/client/build/* $out
|
||||
runHook postInstall
|
||||
'';
|
||||
doDist = false;
|
||||
meta = {
|
||||
inherit (your_spotify.meta) homepage changelog description license maintainers;
|
||||
};
|
||||
}
|
10
pkgs/by-name/yo/your_spotify/package.json
Normal file
10
pkgs/by-name/yo/your_spotify/package.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@your_spotify/root",
|
||||
"version": "1.10.1",
|
||||
"repository": "git@github.com:Yooooomi/your_spotify.git",
|
||||
"author": "Timothee <timothee.boussus@gmail.com>",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"apps/*"
|
||||
]
|
||||
}
|
85
pkgs/by-name/yo/your_spotify/package.nix
Normal file
85
pkgs/by-name/yo/your_spotify/package.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
callPackage,
|
||||
fetchFromGitHub,
|
||||
fetchYarnDeps,
|
||||
lib,
|
||||
makeWrapper,
|
||||
mkYarnPackage,
|
||||
nodejs,
|
||||
fixup-yarn-lock,
|
||||
yarn,
|
||||
}: let
|
||||
version = "1.10.1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "Yooooomi";
|
||||
repo = "your_spotify";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-e82j2blGxQLWAlBNuAnFvlD9vwMk4/mRI0Vf7vuaPA0=";
|
||||
};
|
||||
client = callPackage ./client.nix {inherit src version;};
|
||||
in
|
||||
mkYarnPackage rec {
|
||||
inherit version src;
|
||||
pname = "your_spotify_server";
|
||||
name = "your_spotify_server-${version}";
|
||||
packageJSON = ./package.json;
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = src + "/yarn.lock";
|
||||
hash = "sha256-5SgknaRVzgO2Dzc8MhAaM8UERWMv+PrItzevoWHbWnA=";
|
||||
};
|
||||
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
|
||||
export HOME=$(mktemp -d)
|
||||
yarn config --offline set yarn-offline-mirror $offlineCache
|
||||
fixup-yarn-lock yarn.lock
|
||||
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
|
||||
patchShebangs node_modules/
|
||||
|
||||
pushd ./apps/server/
|
||||
yarn --offline run build
|
||||
popd
|
||||
|
||||
rm -r node_modules
|
||||
export NODE_ENV="production"
|
||||
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
|
||||
patchShebangs node_modules/
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
nativeBuildInputs = [makeWrapper yarn fixup-yarn-lock];
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out/share/your_spotify
|
||||
cp -r node_modules $out/share/your_spotify/node_modules
|
||||
cp -r ./apps/server/{lib,package.json} $out
|
||||
mkdir -p $out/bin
|
||||
makeWrapper ${lib.escapeShellArg (lib.getExe nodejs)} "$out/bin/your_spotify_migrate" \
|
||||
--add-flags "$out/lib/migrations.js" --set NODE_PATH "$out/share/your_spotify/node_modules"
|
||||
makeWrapper ${lib.escapeShellArg (lib.getExe nodejs)} "$out/bin/your_spotify_server" \
|
||||
--add-flags "$out/lib/index.js" --set NODE_PATH "$out/share/your_spotify/node_modules"
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
doDist = false;
|
||||
passthru = {
|
||||
inherit client;
|
||||
};
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/Yooooomi/your_spotify";
|
||||
changelog = "https://github.com/Yooooomi/your_spotify/releases/tag/${version}";
|
||||
description = "Self-hosted application that tracks what you listen and offers you a dashboard to explore statistics about it";
|
||||
license = licenses.gpl3Only;
|
||||
maintainers = with maintainers; [patrickdag];
|
||||
mainProgram = "your_spotify_server";
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user