Compare commits

...

9 Commits

Author SHA1 Message Date
Giulio De Pasquale
c627ccf892 feat: added langtool 2025-07-14 12:06:10 +01:00
Giulio De Pasquale
690813e766 bump 2025-07-14 10:18:14 +01:00
Giulio De Pasquale
f565a9cdeb feat: added ssh keys 2025-07-14 10:11:35 +01:00
Giulio De Pasquale
e17fbd96e0 removed extra ssh conf 2025-07-14 10:00:41 +01:00
Giulio De Pasquale
f32c853637 removed script 2025-07-14 09:57:49 +01:00
Giulio De Pasquale
b4644340a4 bump 2025-07-14 09:55:52 +01:00
Giulio De Pasquale
cf04cd58d1 feat: added update app in flake 2025-07-14 09:55:43 +01:00
Giulio De Pasquale
a2eb9e1566 feat: added update.nix 2025-07-14 09:55:28 +01:00
Giulio De Pasquale
ea37aee1f9 fix: navidrome 2025-07-10 16:09:31 +01:00
25 changed files with 448 additions and 299 deletions

93
flake.lock generated
View File

@ -43,6 +43,24 @@
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -85,6 +103,25 @@
"type": "github"
}
},
"langtool-ngrams": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1752490825,
"narHash": "sha256-3TyLqwD0oWg78i5uNRdL0z/gffih/KvQRHXKmBlCRsY=",
"owner": "peperunas",
"repo": "nix-languagetool-ngram",
"rev": "33ad4c7cf3bbef86fd4f1e90d3ee1166afdf3d4e",
"type": "github"
},
"original": {
"owner": "peperunas",
"repo": "nix-languagetool-ngram",
"type": "github"
}
},
"local-unstable": {
"locked": {
"lastModified": 0,
@ -99,17 +136,17 @@
},
"nixos-unstable": {
"locked": {
"lastModified": 1751792365,
"narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=",
"lastModified": 1751984180,
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb",
"rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb",
"rev": "9807714d6944a957c2e036f84b0ff8caf9930bc0",
"type": "github"
}
},
@ -147,21 +184,37 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1751741127,
"narHash": "sha256-t75Shs76NgxjZSgvvZZ9qOmz5zuBE8buUaYD28BMTxg=",
"lastModified": 1710631334,
"narHash": "sha256-rL5LSYd85kplL5othxK5lmAtjyMOBg390sGBTb3LRMM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c75037bbf9093a2acb617804ee46320d6d1fea5a",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1752308619,
"narHash": "sha256-pzrVLKRQNPrii06Rm09Q0i0dq3wt2t2pciT/GNq5EZQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "29e290002bfff26af1db6f64d070698019460302",
"rev": "650e572363c091045cdbc5b36b0f4c1f614d3058",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "29e290002bfff26af1db6f64d070698019460302",
"rev": "650e572363c091045cdbc5b36b0f4c1f614d3058",
"type": "github"
}
},
"nixpkgs_3": {
"nixpkgs_4": {
"locked": {
"lastModified": 1735264675,
"narHash": "sha256-MgdXpeX2GuJbtlBrH9EdsUeWl/yXEubyvxM1G+yO4Ak=",
@ -200,7 +253,7 @@
},
"pepeflake": {
"inputs": {
"nixpkgs": "nixpkgs_3"
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1739457875,
@ -220,9 +273,10 @@
"inputs": {
"agenix-flake": "agenix-flake",
"home-manager": "home-manager_2",
"langtool-ngrams": "langtool-ngrams",
"local-unstable": "local-unstable",
"nixos-unstable": "nixos-unstable",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs_3",
"nixpkgs-master": "nixpkgs-master",
"nvidia-patch": "nvidia-patch",
"pepeflake": "pepeflake"
@ -258,9 +312,24 @@
"type": "github"
}
},
"systems_3": {
"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_2"
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,

View File

@ -1,7 +1,7 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/29e290002bfff26af1db6f64d070698019460302";
nixos-unstable.url = "github:NixOS/nixpkgs/1fd8bada0b6117e6c7eb54aad5813023eed37ccb";
nixpkgs.url = "github:NixOS/nixpkgs/650e572363c091045cdbc5b36b0f4c1f614d3058";
nixos-unstable.url = "github:NixOS/nixpkgs/9807714d6944a957c2e036f84b0ff8caf9930bc0";
nixpkgs-master.url = "github:NixOS/nixpkgs/master";
local-unstable.url = "path:///home/giulio/dev/nixpkgs";
pepeflake.url = "git+https://git.giugl.io/peperunas/pepeflake";
@ -14,6 +14,7 @@
url = "github:icewind1991/nvidia-patch-nixos";
inputs.nixpkgs.follows = "nixpkgs";
};
langtool-ngrams.url = "github:peperunas/nix-languagetool-ngram";
};
outputs =
@ -26,11 +27,13 @@
, nvidia-patch
, agenix-flake
, pepeflake
, langtool-ngrams
}:
let
sysLinuxX64 = "x86_64-linux";
sysDarwin = "aarch64-darwin";
sysLinuxAarch = "aarch64-linux";
forAllSystems = nixpkgs.lib.genAttrs [ sysLinuxX64 sysLinuxAarch sysDarwin ];
wrapPkgsSystem = { system, cudaSupport ? false }:
let
@ -64,6 +67,7 @@
localPkgs = importNixpkgs { flake = local-unstable; };
agenixPkgs = importNixpkgs { flake = agenix-flake; };
pepePkgs = pepeflake.packages.${system} // pepeflake.legacyPackages.${system} or { };
langtoolPkgs = langtool-ngrams.packages.${system} // langtool-ngrams.legacyPackages.${system} or { };
additionalOverlays = [
(final: prev: { inherit unstablePkgs; })
@ -71,6 +75,7 @@
(final: prev: { inherit agenixPkgs; })
(final: prev: { inherit masterPkgs; })
(final: prev: { inherit pepePkgs; })
(final: prev: { inherit langtoolPkgs; })
];
in
import nixpkgs {
@ -150,6 +155,15 @@
};
};
packages = forAllSystems (system:
let pkgs = nixpkgs.legacyPackages.${system}; in rec {
default = update;
update = pkgs.callPackage ./update.nix { };
});
defaultTemplate = self.templates.basicShell;
templates = {
basicShell = {

View File

@ -269,6 +269,20 @@ in
log.level = "debug";
};
};
navidrome = {
enable = true;
domain = "music.giugl.io";
package = pkgs.unstablePkgs.navidrome;
enableBeets = true;
beetsPackage = pkgs.unstablePkgs.beets;
};
languagetool = {
enable = true;
domain = "lang.giugl.io";
};
};
};
}

View File

@ -1,83 +0,0 @@
{ config, lib, pkgs, ... }:
let
domain = "music.giugl.io";
library_path = "/media/Music";
beets_config = "/media/beets.conf";
in
{
services.navidrome = {
enable = true;
settings = {
MusicFolder = library_path;
LastFM.enable = true;
LastFM.ApiKey = "5cef5cb5f9d31326b97d0f929ca9cf20";
LastFM.Secret = "d1296896126f4caae47407aecf080b25";
Spotify.ID = "3900c029b4f34f3fb61d554dda64794d";
Spotify.Secret = "d931ce5575a9401aa5ff8d37558cca0a";
EnableGravatar = true;
LogLevel = "WARN";
};
};
architect.vhost.${domain} = {
dnsInterfaces = [ "lan" "tailscale" ];
locations."/" = {
port = 4533;
allowLan = true;
allowWAN = true;
# allow = [ config.architect.networks."tailscale".net ];
};
};
systemd.services = {
"beets-update" = {
enable = true;
# requires = [ "remove-badmp3.service" "remove-badflac.service" ];
before = [ "beets-import.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.beets}/bin/beet -c ${beets_config} update";
};
};
"beets-import" = {
enable = true;
path = [ pkgs.imagemagick ];
requires = [ "beets-update.service" ];
after = [ "beets-update.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart =
"${pkgs.beets}/bin/beet -c ${beets_config} import --flat -q ${library_path}";
};
startAt = "weekly";
};
};
# "remove-badmp3" = {
# enable = true;
# before = [ "beets-import.service" "beets-update.service" ];
# serviceConfig = {
# Type = "oneshot";
# ExecStart = ''
# ${pkgs.findutils}/bin/find ${library_path} -name "*.mp3" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.mp3val}/bin/mp3val "{}" | grep -Pi error 1>/dev/null && ${pkgs.busybox}/bin/rm "{}"' \;
# '';
# };
# };
# "remove-badflac" = {
# enable = true;
# before = [ "beets-import.service" "beets-update.service" ];
# serviceConfig = {
# Type = "oneshot";
# ExecStart = ''
# ${pkgs.findutils}/bin/find ${library_path} -name "*.flac" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.flac}/bin/flac -st "{}" || ${pkgs.busybox}/bin/rm "{}"' \;
# '';
# };
# };
# };
users.groups.media.members = [ "navidrome" ];
}

View File

@ -16,5 +16,6 @@
./redlib
./sonarr
./headscale
./languagetool
];
}

View File

@ -0,0 +1,47 @@
{ config, pkgs, lib, ... }:
let
inherit (lib) mkIf;
cfg = config.pepe.services.languagetool;
ngramDataDir = pkgs.symlinkJoin {
name = "languagetool-ngrams";
paths = builtins.attrValues pkgs.langtoolPkgs;
};
in
{
options.pepe.services.languagetool = with lib; {
enable = mkEnableOption "Enable LanguageTool";
package = mkPackageOption pkgs "languagetool" { };
fasttextPackage = mkPackageOption pkgs "fasttext" {};
domain = mkOption {
type = types.str;
default = null;
};
};
config = mkIf cfg.enable {
pepe.core = {
vhost.hosts.${cfg.domain} = {
locations."/" = {
port = config.services.languagetool.port;
allowLAN = true;
allowVPN = true;
allowWAN = true;
};
};
};
services.languagetool = {
enable = true;
package = cfg.package;
allowOrigin = cfg.domain;
settings = {
languageModel = "${ngramDataDir}/share/languagetool/ngrams/";
fasttextModel = "${pkgs.langtoolPkgs.fasttext}/share/languagetool/fasttextmodel/lid.176.bin";
fasttextBinary = "${cfg.fasttextPackage}/bin/fasttext";
};
};
};
}

View File

@ -4,11 +4,82 @@ let
inherit (lib) mkIf;
cfg = config.pepe.services.navidrome;
beetsConfigTemplate = pkgs.writeText "beets.conf.template" ''
directory: ${cfg.musicFolder}
plugins: embedart fetchart scrub lastgenre chroma
import:
write: yes
move: yes
incremental: yes
from_scratch: yes
group_albums: yes
log: ${cfg.musicFolder}/beets.log
original_date: yes
discogs:
user_token: "__DISCOGS_TOKEN__"
paths:
default: $albumartist/$album ($original_year)/$track - $title
singleton: $artist/singles/$title
match:
strong_rec_thresh: 0.20
musicbrainz:
extra_tags: [year]
lastfm:
user: peperunas
api_key: "__LASTFM_KEY__"
embedart:
auto: yes
fetchart:
auto: yes
lastfmkey: "__LASTFM_KEY__"
enforce_ratio: 0.5%
scrub:
auto: yes
lastgenre:
auto: yes
count: 5
min_weight: 10
prefer_specific: yes
force: yes
chroma:
auto: yes
'';
preStartBeetsDecrypt = ''
set -eu
sed \
-e "s|__DISCOGS_TOKEN__|$(cat ${config.age.secrets.discogs.path})|g" \
-e "s|__LASTFM_KEY__|$(cat ${config.age.secrets.lastfmKey.path})|g" \
${beetsConfigTemplate} > /run/beets.conf
'';
navidromeWrapped = pkgs.writeShellScriptBin "navidrome-wrapped" ''
set -eu
${preStartNavidromeDecrypt}
exec ${cfg.package}/bin/navidrome "$@"
'';
preStartNavidromeDecrypt = ''
set -eu
# export ND_LASTFM_APIKEY=$(cat ${config.age.secrets.lastfmKey.path})
# export ND_LASTFM_SECRET=$(cat ${config.age.secrets.lastfmSecret.path})
# export ND_SPOTIFY_ID=$(cat ${config.age.secrets.spotifyID.path})
# export ND_SPOTIFY_SECRET=$(cat ${config.age.secrets.spotifySecret.path})
'';
in
{
options.pepe.services.navidrome = with lib; {
enable = mkEnableOption "Enable navidrome";
enableBeets = mkEnableOption "Enable beets";
package = mkPackageOption pkgs "navidrome" { };
beetsPackage = mkPackageOption pkgs "beets" { };
domain = mkOption {
type = types.str;
default = null;
@ -18,14 +89,9 @@ in
default = "/media/Music";
description = "Path to the music library";
};
beetsConfig = mkOption {
type = types.str;
default = "/media/beets.conf";
description = "Path to the beets configuration file";
};
settings = mkOption {
type = types.attrs;
default = {};
default = { };
description = "Additional settings for Navidrome";
};
};
@ -33,36 +99,56 @@ in
config = mkIf cfg.enable {
services.navidrome = {
enable = true;
package = cfg.package;
package = navidromeWrapped;
settings = {
MusicFolder = cfg.musicFolder;
LastFM.enable = true;
LastFM.ApiKey = "5cef5cb5f9d31326b97d0f929ca9cf20";
LastFM.Secret = "d1296896126f4caae47407aecf080b25";
Spotify.ID = "3900c029b4f34f3fb61d554dda64794d";
Spotify.Secret = "d931ce5575a9401aa5ff8d37558cca0a";
EnableGravatar = true;
LogLevel = "WARN";
} // cfg.settings;
};
pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network; {
dnsInterfaces = [ interfaceTypes.lan interfaceTypes.vpn ];
pepe.core.vhost.hosts.${cfg.domain} = {
locations."/" = {
port = 4533;
port = config.services.navidrome.settings.Port;
allowLAN = true;
allowVPN = true;
allowWAN = true;
};
};
age.secrets = {
discogs = mkIf cfg.enableBeets {
file = ../../../secrets/discogs.age;
};
lastfmKey = {
file = ../../../secrets/lastfm-key.age;
};
lastfmSecret = {
file = ../../../secrets/lastfm-key.age;
};
spotifyID = {
file = ../../../secrets/spotify-id.age;
};
spotifySecret = {
file = ../../../secrets/spotify-secret.age;
};
};
systemd.services = {
"navidrome".preStart = preStartNavidromeDecrypt;
} // mkIf cfg.enableBeets {
"beets-update" = {
enable = true;
preStart = preStartBeetsDecrypt;
before = [ "beets-import.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.beets}/bin/beet -c ${cfg.beetsConfig} update";
ExecStart = "${cfg.beetsPackage}/bin/beet -c /run/beets.conf update";
};
};
@ -73,7 +159,7 @@ in
after = [ "beets-update.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.beets}/bin/beet -c ${cfg.beetsConfig} import --flat -q ${cfg.musicFolder}";
ExecStart = "${cfg.beetsPackage}/bin/beet -c /run/beets.conf import --flat -q ${cfg.musicFolder}";
};
startAt = "weekly";
};

View File

@ -1,4 +1,4 @@
{ lib, pkgs, ... }:
{ pkgs, ... }:
{
programs.ssh = {
@ -6,22 +6,6 @@
compression = true;
matchBlocks = {
"giugl.io" = {
user = "root";
identityFile = "~/.ssh/architectproxy";
};
"192.35.222.32" = {
user = "giulio";
identityFile = "~/.ssh/ucsb";
};
"ucsb-reynolds" = {
hostname = "128.111.49.76";
user = "giulio";
identityFile = "~/.ssh/ucsb";
};
"tommy.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/tommypc";
@ -32,92 +16,6 @@
identityFile = "~/.ssh/dodino";
};
"pepos.devs.giugl.io" = {
user = "pepos";
identityFile = "~/.ssh/pepos";
};
"bastion.nms.kcl.ac.uk" = {
user = "k1804704";
identityFile = "~/.ssh/kcllabs";
};
"s2access" = {
hostname = "s2lab-access.nms.kcl.ac.uk";
user = "k1804704";
identityFile = "~/.ssh/kcllabs";
proxyJump = "bastion.nms.kcl.ac.uk";
};
"kcl-mtl-features" = {
hostname = "134.219.148.11";
user = "peperunas";
port = 30330;
identityFile = "~/.ssh/kcl-mtl";
};
"kcl-mtl-deeplearning" = {
hostname = "134.219.148.11";
user = "peperunas";
port = 30332;
identityFile = "~/.ssh/kcl-mtl";
};
"aws-kcl" = {
hostname = "ssh0-eu-west-2.nms.kcl.ac.uk";
user = "k1804704";
identityFile = "~/.ssh/kcllabs";
};
"ctf.mhackeroni.it" = {
user = "root";
identityFile = "~/.ssh/github";
};
"hotpottino.devs.giugl.io" = {
user = "pi";
identityFile = "~/.ssh/hotpottino";
};
"gbeast.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/gbeast";
forwardX11 = true;
};
"ctf.pnc.giugl.io" = {
hostname = "s2lab.isg.rhul.ac.uk";
user = "peperunas";
port = 38022;
identityFile = "~/.ssh/rhul_infrastructure";
};
"padulino.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/padulino";
};
"ssh.dev.azure.com" = {
user = "git";
identityFile = "~/.ssh/freta";
};
"peppiniell.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/peppiniell";
};
"broccolino.devs.giugl.io" = {
user = "pi";
port = 5541;
identityFile = "~/.ssh/broccoli";
};
"secloud-node-8" = {
user = "giulio";
identityFile = "~/.ssh/secloud-node-8";
};
"git.seclab.cs.ucsb.edu" = {
user = "peperunas";
identityFile = "~/.ssh/ucsb";
@ -147,16 +45,6 @@
identityFile = "~/.ssh/github";
};
"code.iti.illinois.edu" = {
user = "gitlab";
identityFile = "~/.ssh/github";
};
"git.ctf.necst.it" = {
user = "ctf";
identityFile = "~/.ssh/gitlab_necst";
};
"manduria.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/imacmanduria";
@ -170,21 +58,10 @@
identityFile = "~/.ssh/alain";
};
"ironman.local.necst.it" = {
user = "peperunas";
identityFile = "~/.ssh/ironman";
};
"aur.archlinux.org" = {
user = "aur";
identityFile = "~/.ssh/aur";
};
"ucsb-workstation.devs.giugl.io" = {
user = "giulio";
identityFile = "~/.ssh/ucsb";
forwardAgent = true;
};
};
extraConfig = ''

BIN
secrets/discogs.age Normal file

Binary file not shown.

28
secrets/lastfm-key.age Normal file
View File

@ -0,0 +1,28 @@
age-encryption.org/v1
-> ssh-rsa QXZdow
egfNMkr5s1byfetcNOZJtCjdsr6gGT2yostUlnWmzINU6iwymI1lvmZEYAC3jRHL
nlp1qS99HZb2hrIxS/RfWxWm8TBDwSw14755GIrUi6u2zZTdAGx90oiTolMx/Jfp
Lwk0HNohXfU7rLuUOAO4GpT1WhX1u2yKlxyS+DUtF/ayZN5cWTbQnAFrCJhH+lrY
5V1oytbel1zHOV7QpzT+sR09Z4VUqptmlIFtyleIO7ksEnZtFqYhhF+tMx/Bfxjg
BzLX8IyUOvvyMMUDeIOq5f0+QsqhTNk8BTNlRWznrNKKdS8P60a9J0flGz+dtczq
s3i8Xncx+6PliasnAkzOhxDUwU+CQUcRoFsQX+03yS2c0X/3V0OgOk74SCkrInCP
gCZfgVVm19gAQWHvRfjkw2qSVo2V1y6BsXb2RskZCF3+1ZfPv1kl9YCb0WUbEzZC
OGooxrJFa1Yub+zNG0RFAQKUA0yaWZSZBjmzQI7jjcYbGlBC8HgTir44vHWmJuz2
lp14bEPVacJcvb7aBpIuaEk0Q++DuVzVtu4U3TzEXE/ViJQjkPdzQXfhM9v6TslV
+T0ebVVm5UL745G3BGhWaAOgwSuABvufVHXVvbHfUDcpW+sDCStUyD3JOyH2VJuN
gpsuz1kFsM4eMCs9CVXFxJGDQxiLAcnRX4rngYnj+4M
-> ssh-ed25519 7eGqHw Prblc9FRLxhXxffw1D061xTl7aBVLN1qbIC6wU2lLQ8
rlifmY4sxITF3TKW6GXtGKCgyL2PZbza71mlf+pEZXo
-> ssh-rsa tO3rGg
KWwIfzOQf8ngvfmwMQzZQ7DfzMc+y7w35hZb4zmQ3YBr+Uzj9WE3MD91G63/kDjH
w9qlYrdd5FGLlPJzx3S5j9S2BAnCTQ0lgaHb3m2ta8QAnfZVNTc31uY91raZdvJ5
wEH43UsWqU7f+haakJ3PiXDrLvyDM3ZPpE3Z3JJU+ZntXrZOVBWuOYe1FcExvHyb
rIUudxeQqlIG6Jph5m8crRP+GsNL7ApJAXwMVKCuvnsDv0XYqWVN085EnLBle7ar
OIKI/Q9t5SK1Mvh9ktuojdzzRjg+HpoCpuh3AfxvmcDBmvERH96KVrB6Mi96uHxJ
ML1O2GrjT2rpIuoqskO5ofrUMjUSqEOB6+QNU9mMiDbPzabn16DsIck3iohqDWd1
HfaWeezEG/LdIsuBug9KTz+VcFLVugbdB0rpOO7CZ+EIdQb4tT2UCAjvnNaFJjQ0
j/Nnry4ocThgLNn51HTPtLtPt3yh/6e7oRMrwLFB+Al8PDHZRuTWHPBqI/EpUs2A
--- mFtuMJrCJ513/pq0hrc1f2pIoktElxa26jddGgXcje0
E|W?r¤öm3ó_<C3B3>µ^íí¬lÐpÏœ.-ȈŽ7¾#™ôÝ”ã¿ïžþ
£ÇÎÄE 3û¥¯Œ

27
secrets/lastfm-secret.age Normal file
View File

@ -0,0 +1,27 @@
age-encryption.org/v1
-> ssh-rsa QXZdow
k4xDfb04a7A3UTCe6a+rXCQuGv59nMqER6g8aAuObleC5cXI2ChH0LJO9cVCmvox
UVh7jPhqKm9b2yGRzwdvtLHwIzJwoSXiwGXgJ66qTdWyoEKHBGYncMw1khPbY2p1
TyBvd54b2fBEToGZfsrzKncDk/f75/50OAHXdWu7pOWTMnw7Q6zo7xCkkSQQ1oqQ
s3IZf82bT1fsr48OApsvAnFgjJngwXd5sCd+1n5WJXRpxlLXUp95vpKp2Wn8/0Tr
E76qBpkbxNWblqzz3ozo/WSinlUTSAKt9y3RjLHD49wXK2qAI3vyP8Eq22sqnXV9
b8n+kTNVR3+d8ojjtd2cr6krOsCagqCPm890Jqx6+H8pNuzYS+DO5r7b8nUnknPz
0HRx1h7Zc2CK85hT0NtllLqlAsp3eJSj6p3FV/mlefFw7YdFHsKLAf0rVQvcPvIa
L3EPUs0cIGt58FHz0Cyj+9vGSMtqpN9RQAaL6FKl6T4CW2lpRevyrj4Kdpb1a3mU
0HSnkoqjh39Wb34GCpq2Gcdw3m/nOTGIZkGfUuoC5rXVL5cRl8JDEm0+D2DZIsVB
eGGUogvfuuZQLCbwX5dILsC7gRDfTHgSmM7LrVj0TimVKETogz3a2vyATK7MmHCy
uhn9gp5HKYXjpjxgsRrUWl7JqZBqujyduBLu+VN/vL0
-> ssh-ed25519 7eGqHw 8FRoz15ouOkUpDc8mVoNRHVdz/jZMkiKU8JaVizTTRg
iGqUpOfnHxYMpThSf87yqqtKLyLbbANKlRxQ4DGwrjc
-> ssh-rsa tO3rGg
i9o0tQQnn4puU9d1yA9Vfy/8a2AC9MRhNZ08pd+q+YQuMLijyqD8fUuacpcoiXQj
afZgBn/x0sD6N3zx9oOrTtL+H/utsp1N6SIlx7y/3Z/65qwgPu+AiC/zAjnV+5vS
+Ny8e7VPnY0/+Jho4hTtYPFCauMFHaV1or9ShX/wTM57893oRQzuhtufsh4TwfcU
WRQKN7szRAcKnN7wB2wfcVzbGzucx+Q37Dro8qn6ZT7LIXP4qkoEmYnukkctlXDT
yxDmSE8RNr8HUZEvNdJsYTIlwjG9Vpp/EULkNfIR5oJFYr6OWjco48IWW3EaqjeV
XONL7OATIB1NUldH0C6EYNu6bHit5oe9WRUhkXpNFfsAKtLze71Rjb1ejzB1Jv5P
xRXLbzcsuisgpo/R2pIAEyG2sRozF0fQS7JipiosACWAE3ZepKIZfT2G0IfPLUkI
Z5+a7qRLw6OxUXfoLfhsFeb/tW7pFEm+oFzdGLcR06EhV0FzkkESyuTTxr8gOLKQ
--- bDIHhN9Oo1GmQR/LwfzDuCfiWi/xE40rrupqfJZfv5k
é­{<7B>ÄÖ—f€+”^` Ä¢w°ßñþ©]þVáÝ~f-{žh2ºLO]ßü}êºÞkÔ"P Â!—z†

View File

@ -12,4 +12,20 @@ in
"restic-environment.age".publicKeys = pubkeys;
"restic-passwords.age".publicKeys = pubkeys;
"cloudflare.age".publicKeys = pubkeys;
"lastfm-key.age".publicKeys = pubkeys;
"lastfm-secret.age".publicKeys = pubkeys;
"spotify-id.age".publicKeys = pubkeys;
"spotify-secret.age".publicKeys = pubkeys;
"discogs.age".publicKeys = pubkeys;
# ssh keys
"ssh/giupi.age".publicKeys = pubkeys;
"ssh/alain.age".publicKeys = pubkeys;
"ssh/bitbucket.age".publicKeys = pubkeys;
"ssh/gitea.age".publicKeys = pubkeys;
"ssh/aur.age".publicKeys = pubkeys;
"ssh/imacmanduria.age".publicKeys = pubkeys;
"ssh/lezzo.age".publicKeys = pubkeys;
"ssh/ucsb.age".publicKeys = pubkeys;
"ssh/github.age".publicKeys = pubkeys;
}

27
secrets/spotify-id.age Normal file
View File

@ -0,0 +1,27 @@
age-encryption.org/v1
-> ssh-rsa QXZdow
lBdNlqhlpJ93wZGsRug3AC0etQa13DACtAbM+xbe/weSH26kQ/ByBcx1FSdAN4A4
6yaVrpG+T1JLwUZQTGKkTAGWHOuKZ7EoN0EfYPVFjVIQfb/FUuB7ZDw9Mn+VFsgm
gO7XdEi9PYGA0eMdc1a0Pg8fXNMSo7XuXYhC3tygS25Um8hwSn/LfCCfSOKs8gL7
oXWNuemamidYrQLcDNcRKQuSkwVlUNN7C2+u7+55gYl3cCQocgxmYjF97UIwKjYp
iSjJTB9WfeFWwFq/JLcf1DmPcaFs5w1qipHCe2LfT43EMsp89cHOE7Cs2++NWZLw
iqu+IhlONAYa7dse5JbixQnD+tdfMRJFWuLZuGXvXShtYBnqTBI3d5CFuWFrdH0M
cwTXnXv47Ehai8ybI/izeqrpsceX1QR92GmsdTVbINWUewppvR9WRXCZkb5FzWNZ
jtfjxmnG/FpTqqD52+PepFsQQKULEj+iPw+XsiihnWnIw8XyclIkm7EbMSfB1jAg
3mhZYWSY92kwqPr23xg4mvQjJDEiqFbWHmhXTdMOQebRV+L8BJzdeybInm/kTn8v
avoCb7LEzji41zJW3Mc/hy5LaBslDfzk7kiXl5xn5VTYgAJbeL6ClasuQG+U7pk2
HhO1b5RvryyGpCoYWaG6Psb4pQnyXv3kneCIGX+ES8E
-> ssh-ed25519 7eGqHw PXDvB/Z6KRfKLejzDTg4W9KxbIrfPPfUJCxmRi8CuC8
zPQb2zSLvV+vWvPnI7dNjYVmT6uOfxupcVwtVdEwasE
-> ssh-rsa tO3rGg
s6NIc6yEvYKMYLXtEgMUW4DJIOmEIvytwWwrYjSZ0nf0UX3FJ/E2ClL520MIBERq
ALQWm8L0YTjPyCB1kAAHFaN7wdUyrGIjCPt5PuvNmZKvYc9MlTRLBz0dpQTBmjLY
YwFbZwNjv7kT3STAYtoZUKzMI+LH9Nkj+pX2R2U1pItKuwZdC7y6/kyLO4t3mtwl
IC6AeiVs8rEB6eUCPHqVAZbzLVUpTQiCVQYDXvaWn991lp5AsPr/wUc4pBkE6OUv
L0yT2NpodeZKj6gCgaVoq0hzVDA5YeuW2uvMTTuNar/sfpW3ffYrxSw2D/g0o2So
Z/OCzCohtQqyTzFO3vCbW2MqdtaSUkAimUZMydnua2wk0xOmMg15+1NxbIDbBKxO
lkwLgy8ip2ptFmNklKoHOTjddo3kMZFESrLn7wgJYXgjV/bxYnxvDAF8xCxEb/ut
KWgR17S0Fwtl3xsBEVQdhPH02AXQQQiDdourKKFhyJQgyKyPAjrFDglKeynwiJcg
--- m22wYScxjP5MjYujDOF+ae/4Oi06BSfF4T42kYksMCg
Xエ@|ロ臓冦籖%qサCヤ汯ア:EKサナレ既ナ9nット斃ソ鈞1サ8ノ[悪YU^レ釶。Ls(ク貲<EFBDB8>H<EFBFBD>

View File

@ -0,0 +1,27 @@
age-encryption.org/v1
-> ssh-rsa QXZdow
BfRVGeK/PkpDZLZ+t2pdV9npzaSmDNtOZ1HaKspFEi7yZi02+a4A9GHWeLU5RTmC
RYsCgsEPMvkqpPLWp1nKB6S+5B2ZrZOpq7PkRPymJ9oD+UxhmvyOB4yVihXeO34Q
d3yB6jxAN2w5lcZpgIDhwMyCl60wbcB9UfzFl9Z7qFXck07rGeigpb2SuTCz5J59
l++BRpyG8XmPc3kLTU41nKZjF9L2l5zkRyraW3GAkQc4M5MFD7Lxkfdprd/2lAiy
nQuWmp8uKRYn33oTMXSAYmtdkQ5G731OVLy8F6czKsOlg88gm2IrH642ogT1OihL
goay4V6pbcu9DlZSHZKFVrClSN1/6kYgELcbLjHimq8NU8U5rqdC+xcVRvmQATf+
tWcm9etKQ4pzfhMKaZDD+E8EVd5HF7C97TEZvkM2p7EHnz9vqXmkyZVVM2LQ3luJ
v/kz7maWcWbifKOMKIg8VsdOCt14Puvmn9H5J1YZd/vjNgZZB9hOeSXgUIfLqQ1P
HvVZiyGClgGhtNBbE0vazIXklSP2BxaorotmIlXB+KQRKjF+VLXj8svo2i1WclRe
lnoQq+bsvV+TAnFDYSj3DZ3yXZ4VN6yHkz+vBHBvWZWUi20yhR791z+QZpEX95uf
S33X+zuyyE0nyZHEOdOAy8HsNPiR1gta4f2aSU9smQk
-> ssh-ed25519 7eGqHw XeIa/7XPhmXc7iY3N3vM4DTpUycnIULk8lKebmGPVFk
hAhEikEFAMOCIT0py3Dv1Gx8LlavjvoyH7fOMVI4AwE
-> ssh-rsa tO3rGg
swqr1l/Z1zV3Z8c9hmpAAN4rOeL+HfWLqC6Y+lecg8cDgMDVxnspFChJxAcB2nVg
NRTNSiDFpohBpbg8N24FGq974bMMcdgmNZ4frL7BbFhbZvJoU2xKTuf/LZN6if60
+zSZpeRZSVB43LyicjvhxgtIJ9gxI/jHrjuEN4H1yYC/QuVMfallTvuXapC2M82h
om5k49VS0tU2rMRVAQtOoYya8DNLmvulDsr9Uj3uQvhtXawTmzQryAd+pD3KZ21L
+ugNiBD2jVSMdAHM5T7bR4/fqq0Kg2b9qh1IX0euTmaFTa4uwObgwmCNjdPN51+a
IBfSKaVD+xMNsGItZnFahhcDUntZvfsM1UPPmj4ZdvpD+WxxnDLhbwL+l/dvqEin
cfwlVQfVNkpm84ggvesQMwrHMGdfj/cROFKI6iK3xY+5sfK85lwYoEKdbRnS5WKU
o1CxOCX4Pf0kMYXsuKmOkWnydKNeN56fPIyNWHWUwgE2XxjooartoJH4fQBsJLOu
--- /+TRk43KDpHb4FrGQfhT6S1SDAoK54W770E181F+Q6M
{gZEØåZÖò/­Ž¥w œØGøìî""cÆP<7F>Ö<> øÂŸYØÄMÀ8¯a½êÆ Ñ)‡M+YѾ‡|##

BIN
secrets/ssh/alain.age Normal file

Binary file not shown.

BIN
secrets/ssh/aur.age Normal file

Binary file not shown.

BIN
secrets/ssh/bitbucket.age Normal file

Binary file not shown.

BIN
secrets/ssh/gitea.age Normal file

Binary file not shown.

BIN
secrets/ssh/github.age Normal file

Binary file not shown.

BIN
secrets/ssh/giupi.age Normal file

Binary file not shown.

Binary file not shown.

BIN
secrets/ssh/lezzo.age Normal file

Binary file not shown.

BIN
secrets/ssh/ucsb.age Normal file

Binary file not shown.

61
update.nix Normal file
View File

@ -0,0 +1,61 @@
{ writeShellApplication
, jq
, curl
, lib
, release ? "25.05"
, channels ? [
{ name = "nixos-${release}"; input = "nixpkgs"; }
{ name = "nixos-unstable"; input = "nixos-unstable"; }
]
, flakeFile ? "flake.nix"
, lockFile ? "flake.lock"
}:
writeShellApplication {
name = "nixos-updater";
runtimeInputs = [ jq curl ];
text = ''
FLAKE_FILE="${flakeFile}"
LOCK_FILE="${lockFile}"
update_channel() {
local channel_name="$1"
local flake_input_name="$2"
local new old
echo "Checking channel: $channel_name -> $flake_input_name..."
# Get latest revision from Hydra
new=$(curl -sL "https://monitoring.nixos.org/prometheus/api/v1/query?query=channel_revision" |
jq -r ".data.result[] | select(.metric.channel==\"$channel_name\") | .metric.revision")
if [ -z "$new" ]; then
echo "Failed to get revision for $channel_name"
return 1
fi
# Get current revision from flake.lock
old=$(jq -r ".nodes as \$nodes |
.nodes.root.inputs[\"$flake_input_name\"] as \$target_input |
\$nodes | to_entries[] |
select(.key == \$target_input) |
.value.locked.rev" "$LOCK_FILE")
if [ "$old" = "$new" ]; then
echo "No update needed for $flake_input_name"
return 0
fi
# Update the flake.nix file
sed -i "s|\($flake_input_name\.url = \"github:NixOS/nixpkgs/\)[^\"]*|\1$new|" "$FLAKE_FILE"
echo "Updated $flake_input_name: $old -> $new"
return 0
}
# Process channels based on parameters
${lib.concatMapStringsSep "\n" (channel: ''
update_channel "${channel.name}" "${channel.input}"
'') channels}
'';
}

View File

@ -1,62 +0,0 @@
#!/usr/bin/env bash
RELEASE=25.05
update_channel() {
local channel_name="$1" # Hydra channel name (e.g., nixos-24.11)
local flake_input_name="$2" # Flake input name (e.g., nixpkgs)
local new old
# Get latest revision from Hydra
new=$(curl -sL "https://monitoring.nixos.org/prometheus/api/v1/query?query=channel_revision" |
jq -r ".data.result[] | select(.metric.channel==\"${channel_name}\") | .metric.revision")
# Get current revision from flake.lock using input name
old=$(jq -r ".nodes as \$nodes |
.nodes.root.inputs.[\"${flake_input_name}\"] as \$target_input |
\$nodes | to_entries[] |
select(.key == \$target_input) |
.value.locked.rev" flake.lock)
if [ "${old}" == "${new}" ]; then
return
fi
replace_hash "${flake_input_name}" "${new}"
echo "${new}"
}
replace_hash() {
local name="$1" hash="$2"
sed -i "s|\(${name}\.url = \"github:NixOS/nixpkgs/\)[^\"]*|\1${hash}|" flake.nix
# sed -i "s|${name}/${old}|${name}/${new}|" flake.nix
}
update_stable() {
echo "Checking NixOS ${RELEASE}..."
new_hash=$(update_channel "nixos-${RELEASE}" "nixpkgs")
if [ -z "$new_hash" ]; then
return
fi
echo "Updated stable to: ${new_hash}"
}
update_unstable() {
echo "Checking unstable..."
new_hash=$(update_channel "nixos-unstable" "nixos-unstable")
if [ -z "$new_hash" ]; then
return
fi
echo "Updated unstable to: ${new_hash}"
}
update_stable
update_unstable