diff --git a/README.md b/README.md index 34690bd..def4e60 100644 --- a/README.md +++ b/README.md @@ -77,4 +77,4 @@ nix build .#proxmox-chaosknoten-nixos-template ## License This CCCHH nix-infra repository is licensed under the [MIT License](./LICENSE). -[`librespot_PR1528_conflicts_resolved.patch`](patches/librespot_PR1528_conflicts_resolved.patch) is a modified version of [librespot PR 1528](https://github.com/librespot-org/librespot/pull/1528) and is licensed under the [MIT license](https://github.com/librespot-org/librespot/blob/dev/LICENSE). +[`0001_oidc_group_and_role_mapping_custom_pipeline.patch`](patches/0001_oidc_group_and_role_mapping_custom_pipeline.patch) is licensed under the Creative Commons: CC BY-SA 4.0 license. diff --git a/flake.lock b/flake.lock index 559f116..2ab41bb 100644 --- a/flake.lock +++ b/flake.lock @@ -7,7 +7,7 @@ "narHash": "sha256-GMU6gfG1+3OjTuoiIYQg9yefzrz+RVVesqXa8jmOuCE=", "rev": "fc95460e9e6ae759b2b08c93b10a8e010e9e14e6", "type": "tarball", - "url": "https://git.hamburg.ccc.de/api/v1/repos/CCCHH/infrastructure-authorized-keys/archive/fc95460e9e6ae759b2b08c93b10a8e010e9e14e6.tar.gz" + "url": "https://git.hamburg.ccc.de/api/v1/repos/CCCHH/infrastructure-authorized-keys/archive/fc95460e9e6ae759b2b08c93b10a8e010e9e14e6.tar.gz?rev=fc95460e9e6ae759b2b08c93b10a8e010e9e14e6" }, "original": { "type": "tarball", @@ -66,11 +66,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1753115646, - "narHash": "sha256-yLuz5cz5Z+sn8DRAfNkrd2Z1cV6DaYO9JMrEz4KZo/c=", + "lastModified": 1752620740, + "narHash": "sha256-f3pO+9lg66mV7IMmmIqG4PL3223TYMlnlw+pnpelbss=", "owner": "nixos", "repo": "nixpkgs", - "rev": "92c2e04a475523e723c67ef872d8037379073681", + "rev": "32a4e87942101f1c9f9865e04dc3ddb175f5f32e", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 39183bf..53bf4ca 100644 --- a/flake.nix +++ b/flake.nix @@ -40,29 +40,6 @@ proxmox-vm = ./config/proxmox-vm; prometheus-exporter = ./config/extra/prometheus-exporter.nix; }; - overlays = { - librespotFixOverlay = final: prev: { - librespot = (prev.librespot.override { withAvahi = true; }).overrideAttrs (finalAttrs: prevAttr: rec { - # Build dev branch. - name = "${prevAttr.pname}-${version}"; - version = "dev"; - src = prev.fetchFromGitHub { - owner = "librespot-org"; - repo = "librespot"; - rev = "dev"; - sha256 = "sha256-s9JpIbqXiVXMlhEuIuKio+rD1rM3kc7bAT0+8+5s35w="; - }; - cargoDeps = final.rustPlatform.fetchCargoVendor { - inherit src; - hash = "sha256-Lujz2revTAok9B0hzdl8NVQ5XMRY9ACJzoQHIkIgKMg="; - }; - # Fix librespot failing with "Unable to load audio item: Error { kind: Unavailable, error: StatusCode(500) }". - patches = (prevAttr.patches or []) ++ [ - ./patches/librespot_PR1528_conflicts_resolved.patch - ]; - }); - }; - }; nixosConfigurations = { audio-hauptraum-kueche = nixpkgs.lib.nixosSystem { inherit system specialArgs; @@ -79,7 +56,6 @@ self.nixosModules.common self.nixosModules.proxmox-vm ./config/hosts/audio-hauptraum-tafel - { nixpkgs.overlays = [ self.overlays.librespotFixOverlay ]; } ]; }; diff --git a/modules/services/audio/librespot.nix b/modules/services/audio/librespot.nix index 3be5c86..4c0fadb 100644 --- a/modules/services/audio/librespot.nix +++ b/modules/services/audio/librespot.nix @@ -19,11 +19,11 @@ in enable = true; description = "Spotify Connect Receiver Using librespot"; unitConfig = { - Requires = [ "network-online.target" "pipewire.service" "avahi-daemon.service" ]; - After = [ "network-online.target" "pipewire.service" "avahi-daemon.service" ]; + Requires = [ "network-online.target" "pipewire.service" ]; + After = [ "network-online.target" "pipewire.service" ]; }; serviceConfig = { - ExecStart = "${pkgs.librespot}/bin/librespot --name '${config.ccchh.services.audio.name}' --device-type speaker --bitrate 320 --enable-volume-normalisation --disable-audio-cache --disable-credential-cache --zeroconf-backend avahi"; + ExecStart = "${pkgs.librespot}/bin/librespot --name '${config.ccchh.services.audio.name}' --device-type speaker --bitrate 320 --enable-volume-normalisation --disable-audio-cache --disable-credential-cache"; User = "librespot"; Group = "librespot"; }; diff --git a/patches/librespot_PR1528_conflicts_resolved.patch b/patches/librespot_PR1528_conflicts_resolved.patch deleted file mode 100644 index f97a38a..0000000 --- a/patches/librespot_PR1528_conflicts_resolved.patch +++ /dev/null @@ -1,223 +0,0 @@ -From c4c968e594edcfce231682db5563f7186da7c6f0 Mon Sep 17 00:00:00 2001 -From: Timon de Groot -Date: Thu, 7 Aug 2025 12:22:56 +0200 -Subject: [PATCH 1/5] spclient: Specify base url for metadata requests - -This fixes #1527 ---- - core/src/spclient.rs | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/core/src/spclient.rs b/core/src/spclient.rs -index 87a6098..56c4287 100644 ---- a/core/src/spclient.rs -+++ b/core/src/spclient.rs -@@ -55,6 +55,7 @@ const CONNECTION_ID: HeaderName = HeaderName::from_static("x-spotify-connection- - const NO_METRICS_AND_SALT: RequestOptions = RequestOptions { - metrics: false, - salt: false, -+ base_url: None, - }; - - #[derive(Debug, Error)] -@@ -86,6 +87,7 @@ impl Default for RequestStrategy { - pub struct RequestOptions { - metrics: bool, - salt: bool, -+ base_url: Option, - } - - impl Default for RequestOptions { -@@ -93,6 +95,7 @@ impl Default for RequestOptions { - Self { - metrics: true, - salt: true, -+ base_url: None, - } - } - } -@@ -449,7 +452,10 @@ impl SpClient { - - // Reconnection logic: retrieve the endpoint every iteration, so we can try - // another access point when we are experiencing network issues (see below). -- let mut url = self.base_url().await?; -+ let mut url = match &options.base_url { -+ Some(base_url) => base_url.clone(), -+ None => self.base_url().await?, -+ }; - url.push_str(endpoint); - - // Add metrics. There is also an optional `partner` key with a value like -@@ -566,7 +572,12 @@ impl SpClient { - - pub async fn get_metadata(&self, scope: &str, id: &SpotifyId) -> SpClientResult { - let endpoint = format!("/metadata/4/{}/{}", scope, id.to_base16()?); -- self.request(&Method::GET, &endpoint, None, None).await -+ let options = RequestOptions { -+ base_url: Some(String::from("https://spclient.wg.spotify.com")), -+ ..Default::default() -+ }; -+ self.request_with_options(&Method::GET, &endpoint, None, None, &options) -+ .await - } - - pub async fn get_track_metadata(&self, track_id: &SpotifyId) -> SpClientResult { --- -2.49.0 - - -From 2b72f3fbdf6519321feeaaecc1ea6e1bb042074e Mon Sep 17 00:00:00 2001 -From: Timon de Groot -Date: Thu, 7 Aug 2025 13:51:55 +0200 -Subject: [PATCH 2/5] spclient: Change RequestOptions to &str - -This will allocate less strings and makes it possible to have const -request option values. - -Also document why the metadata base url workaround is needed. ---- - core/src/spclient.rs | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/core/src/spclient.rs b/core/src/spclient.rs -index 56c4287..11bcef4 100644 ---- a/core/src/spclient.rs -+++ b/core/src/spclient.rs -@@ -87,7 +87,7 @@ impl Default for RequestStrategy { - pub struct RequestOptions { - metrics: bool, - salt: bool, -- base_url: Option, -+ base_url: Option<&'static str>, - } - - impl Default for RequestOptions { -@@ -453,7 +453,7 @@ impl SpClient { - // Reconnection logic: retrieve the endpoint every iteration, so we can try - // another access point when we are experiencing network issues (see below). - let mut url = match &options.base_url { -- Some(base_url) => base_url.clone(), -+ Some(base_url) => base_url.to_owned().to_string(), - None => self.base_url().await?, - }; - url.push_str(endpoint); -@@ -572,8 +572,11 @@ impl SpClient { - - pub async fn get_metadata(&self, scope: &str, id: &SpotifyId) -> SpClientResult { - let endpoint = format!("/metadata/4/{}/{}", scope, id.to_base16()?); -+ // For unknown reasons, metadata requests must now be sent through spclient.wg.spotify.com. -+ // Otherwise, the API will respond with 500 Internal Server Error responses. -+ // Context: https://github.com/librespot-org/librespot/issues/1527 - let options = RequestOptions { -- base_url: Some(String::from("https://spclient.wg.spotify.com")), -+ base_url: Some("https://spclient.wg.spotify.com"), - ..Default::default() - }; - self.request_with_options(&Method::GET, &endpoint, None, None, &options) --- -2.49.0 - - -From 73ed5c50849bb660834cd0d7aaa7110c01397055 Mon Sep 17 00:00:00 2001 -From: Timon de Groot -Date: Sat, 9 Aug 2025 09:28:51 +0200 -Subject: [PATCH 3/5] spclient: Make const request options for get_metadata - ---- - core/src/spclient.rs | 20 ++++++++++++++------ - 1 file changed, 14 insertions(+), 6 deletions(-) - -diff --git a/core/src/spclient.rs b/core/src/spclient.rs -index 11bcef4..cbcf092 100644 ---- a/core/src/spclient.rs -+++ b/core/src/spclient.rs -@@ -58,6 +58,12 @@ const NO_METRICS_AND_SALT: RequestOptions = RequestOptions { - base_url: None, - }; - -+const SPCLIENT_FALLBACK_ENDPOINT: RequestOptions = RequestOptions { -+ metrics: true, -+ salt: true, -+ base_url: Some("https://spclient.wg.spotify.com"), -+}; -+ - #[derive(Debug, Error)] - pub enum SpClientError { - #[error("missing attribute {0}")] -@@ -575,12 +581,14 @@ impl SpClient { - // For unknown reasons, metadata requests must now be sent through spclient.wg.spotify.com. - // Otherwise, the API will respond with 500 Internal Server Error responses. - // Context: https://github.com/librespot-org/librespot/issues/1527 -- let options = RequestOptions { -- base_url: Some("https://spclient.wg.spotify.com"), -- ..Default::default() -- }; -- self.request_with_options(&Method::GET, &endpoint, None, None, &options) -- .await -+ self.request_with_options( -+ &Method::GET, -+ &endpoint, -+ None, -+ None, -+ &SPCLIENT_FALLBACK_ENDPOINT, -+ ) -+ .await - } - - pub async fn get_track_metadata(&self, track_id: &SpotifyId) -> SpClientResult { --- -2.49.0 - - -From 6adca21fdf64bd8026a2d6df04c42dd2b1239358 Mon Sep 17 00:00:00 2001 -From: Timon de Groot -Date: Sat, 9 Aug 2025 09:40:20 +0200 -Subject: [PATCH 4/5] spclient: Simplify base url init - ---- - core/src/spclient.rs | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/core/src/spclient.rs b/core/src/spclient.rs -index cbcf092..272975d 100644 ---- a/core/src/spclient.rs -+++ b/core/src/spclient.rs -@@ -458,8 +458,8 @@ impl SpClient { - - // Reconnection logic: retrieve the endpoint every iteration, so we can try - // another access point when we are experiencing network issues (see below). -- let mut url = match &options.base_url { -- Some(base_url) => base_url.to_owned().to_string(), -+ let mut url = match options.base_url { -+ Some(base_url) => base_url.to_string(), - None => self.base_url().await?, - }; - url.push_str(endpoint); --- -2.49.0 - - -From 0b5b1eb6c73a9291057b3856939f416113fdd8bb Mon Sep 17 00:00:00 2001 -From: Timon de Groot -Date: Sat, 9 Aug 2025 10:14:02 +0200 -Subject: [PATCH 5/5] Update CHANGELOG.md - ---- - CHANGELOG.md | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/CHANGELOG.md b/CHANGELOG.md -index 560de2b..b62e9f8 100644 ---- a/CHANGELOG.md -+++ b/CHANGELOG.md -@@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - [connect] Correctly apply playing/paused state when transferring playback - - [player] Saturate invalid seek positions to track duration - - [audio] Fall back to other URLs in case of a failure when downloading from CDN -+- [core] Metadata requests failing with 500 Internal Server Error - - ### Deprecated - --- -2.49.0 -