Compare commits
32 Commits
310950de42
...
main
Author | SHA1 | Date | |
---|---|---|---|
a9ea135cb9
|
|||
b8699ba0b6
|
|||
eb3c301ef6
|
|||
a75875a311
|
|||
822044423e
|
|||
63d2dd2e93
|
|||
8235bd4cdf
|
|||
492b643d8b
|
|||
6ce084b652
|
|||
c870442536
|
|||
81b3faaf3e
|
|||
2f286e25bc
|
|||
871a8dcdbf
|
|||
5191357fcd
|
|||
f1d0a8b2df
|
|||
116de857eb
|
|||
80bde87757
|
|||
82496be4b3
|
|||
fbe424384c
|
|||
3dba5ed833
|
|||
e41e8c2078
|
|||
248432b132
|
|||
3bf23f860a
|
|||
fc8e2db679
|
|||
183b5e334f
|
|||
496027b505
|
|||
35fd86138d
|
|||
88eead5aa4
|
|||
8e21efdc53
|
|||
71e13f1408
|
|||
f72943c905
|
|||
4cd670bb27
|
@@ -25,7 +25,6 @@ NixOS dotfiles and configuration for various hosts and users.
|
|||||||
- [`remove-host.sh`](./scripts/remove-host.sh): Remove references to a host.
|
- [`remove-host.sh`](./scripts/remove-host.sh): Remove references to a host.
|
||||||
- [`update-keys.sh`](./scripts/update-keys.sh): Update the encryption keys in all relevant files using `sops.yaml` configurations.
|
- [`update-keys.sh`](./scripts/update-keys.sh): Update the encryption keys in all relevant files using `sops.yaml` configurations.
|
||||||
- [`update.sh`](./scripts/update.sh): Update flake and all packages.
|
- [`update.sh`](./scripts/update.sh): Update flake and all packages.
|
||||||
- [`cache.sh`](./scripts/cache.sh): Build all `nixosConfiguration`s and push them to `attic`.
|
|
||||||
|
|
||||||
Any `options.nix` files create custom option definitions when present.
|
Any `options.nix` files create custom option definitions when present.
|
||||||
|
|
||||||
|
114
flake.lock
generated
114
flake.lock
generated
@@ -10,11 +10,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756487002,
|
"lastModified": 1759227262,
|
||||||
"narHash": "sha256-hN9RfNXy53qAkT68T+IYZpl68uE1uPOVMkw0MqC43KA=",
|
"narHash": "sha256-ibKJckw+KWH6n+pscOA7DWImanr988zKB7R2Z6ZEMLM=",
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"repo": "ags",
|
"repo": "ags",
|
||||||
"rev": "8ff792dba6cc82eed10e760f551075564dd0a407",
|
"rev": "f68a0d03fbb94f4beacedd922ffaa0bf0f10397a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -30,11 +30,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756474652,
|
"lastModified": 1759688436,
|
||||||
"narHash": "sha256-iiBU6itpEqE0spXeNJ3uJTfioSyKYjt5bNepykpDXTE=",
|
"narHash": "sha256-EfTrJse33t3RP//DqESkTMCpMSdIi/wxxfa12+eP5jo=",
|
||||||
"owner": "aylur",
|
"owner": "aylur",
|
||||||
"repo": "astal",
|
"repo": "astal",
|
||||||
"rev": "20bd8318e4136fbd3d4eb2d64dbabc3acbc915dd",
|
"rev": "12c15b44608422e494c387aba6adc1ab6315d925",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -121,11 +121,11 @@
|
|||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754487366,
|
"lastModified": 1759362264,
|
||||||
"narHash": "sha256-pHYj8gUBapuUzKV/kN/tR3Zvqc7o6gdFB9XKXIp1SQ8=",
|
"narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "af66ad14b28a127c5c0f3bbb298218fc63528a18",
|
"rev": "758cf7296bee11f1706a574c77d072b8a7baa881",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -183,11 +183,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756579987,
|
"lastModified": 1759711004,
|
||||||
"narHash": "sha256-duCce8zGsaMsrqqOmLOsuaV1PVIw/vXWnKuLKZClsGg=",
|
"narHash": "sha256-B39NxeKCnK3DJlmJKIts6njcXcVVASLUChDNmRl4dxQ=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "99a69bdf8a3c6bf038c4121e9c4b6e99706a187a",
|
"rev": "6f4021da5d2bb5ea7cb782ff413ecb7062066820",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -212,11 +212,11 @@
|
|||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754297745,
|
"lastModified": 1756744479,
|
||||||
"narHash": "sha256-aD6/scLN3L4ZszmNbhhd3JQ9Pzv1ScYFphz14wHinfs=",
|
"narHash": "sha256-EyZXusK/wRD3V9vDh00W2Re3Eg8UQ+LjVBQrrH9dq1U=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "lanzaboote",
|
"repo": "lanzaboote",
|
||||||
"rev": "892cbdca865d6b42f9c0d222fe309f7720259855",
|
"rev": "747b7912f49e2885090c83364d88cf853a020ac1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -235,11 +235,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757531256,
|
"lastModified": 1758632667,
|
||||||
"narHash": "sha256-aOqrRvKmHoPKVhEYgV/RbsMXYXy6W9Tt1uhGK3dWMlE=",
|
"narHash": "sha256-C0aBPv8vqTI1QNVhygZxL0f49UERx2UejVdtyz67jhs=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "be7b39f41a1137a68944fc73db5a24544e015eb6",
|
"rev": "5e0737c20f3c265dbff604170a6433cc1e1a4b41",
|
||||||
"revCount": 7,
|
"revCount": 8,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.karaolidis.com/karaolidis/nix-lib.git"
|
"url": "https://git.karaolidis.com/karaolidis/nix-lib.git"
|
||||||
},
|
},
|
||||||
@@ -250,11 +250,11 @@
|
|||||||
},
|
},
|
||||||
"mnw": {
|
"mnw": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748710831,
|
"lastModified": 1758834834,
|
||||||
"narHash": "sha256-eZu2yH3Y2eA9DD3naKWy/sTxYS5rPK2hO7vj8tvUCSU=",
|
"narHash": "sha256-Y7IvY4F8vajZyp3WGf+KaiIVwondEkMFkt92Cr9NZmg=",
|
||||||
"owner": "Gerg-L",
|
"owner": "Gerg-L",
|
||||||
"repo": "mnw",
|
"repo": "mnw",
|
||||||
"rev": "cff958a4e050f8d917a6ff3a5624bc4681c6187d",
|
"rev": "cfbc7d1cc832e318d0863a5fc91d940a96034001",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -289,11 +289,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756542300,
|
"lastModified": 1759381078,
|
||||||
"narHash": "sha256-tlOn88coG5fzdyqz6R93SQL5Gpq+m/DsWpekNFhqPQk=",
|
"narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d7600c775f877cd87b4f5a831c28aa94137377aa",
|
"rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -305,11 +305,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1753579242,
|
"lastModified": 1754788789,
|
||||||
"narHash": "sha256-zvaMGVn14/Zz8hnp4VWT9xVnhc8vuL3TStRqwk22biA=",
|
"narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixpkgs.lib",
|
"repo": "nixpkgs.lib",
|
||||||
"rev": "0f36c44e01a6129be94e3ade315a5883f0228a6e",
|
"rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -328,11 +328,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756630008,
|
"lastModified": 1759742968,
|
||||||
"narHash": "sha256-weZiVKbiWQzTifm6qCxzhxghEu5mbh9mWNUdkzOLCR0=",
|
"narHash": "sha256-yk56xZpanCPlhowzIEdS2GfPDG0yQ4kE/j85lJbAX1Y=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "f6a5a7b60dd6065e78ef06390767e689ffa3c23f",
|
"rev": "9ea4f672c7138273a4131dd25038da49306685b8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -358,11 +358,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755463179,
|
"lastModified": 1759469269,
|
||||||
"narHash": "sha256-5Ggb1Mhf7ZlRgGi2puCa2PvWs6KbMnWBlW6KW7Vf79Y=",
|
"narHash": "sha256-DP833ejGUNRRHsJOB3WRTaWWXLNucaDga2ju/fGe+sc=",
|
||||||
"owner": "NotAShelf",
|
"owner": "NotAShelf",
|
||||||
"repo": "nvf",
|
"repo": "nvf",
|
||||||
"rev": "03833118267ad32226b014b360692bdce9d6e082",
|
"rev": "e48638aef3a95377689de0ef940443c64f870a09",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -381,11 +381,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756052001,
|
"lastModified": 1758268943,
|
||||||
"narHash": "sha256-dlLqyHxqiFAoIwshKe9X3PzXcJ+up88Qb2JVQswFaNE=",
|
"narHash": "sha256-ufkrvMWvS+tgzs5H5iRZn/okuvmSzRLeBf+zUxES6YE=",
|
||||||
"owner": "icewind1991",
|
"owner": "icewind1991",
|
||||||
"repo": "nvidia-patch-nixos",
|
"repo": "nvidia-patch-nixos",
|
||||||
"rev": "780af7357d942fad2ddd9f325615a5f6ea7e37ee",
|
"rev": "e7358911c8f611eb1eb8e0758aa668d4d2d55cd9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -422,11 +422,11 @@
|
|||||||
},
|
},
|
||||||
"quadlet-nix": {
|
"quadlet-nix": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754008153,
|
"lastModified": 1758631655,
|
||||||
"narHash": "sha256-MYT1mDtSkiVg343agxgBFsnuNU3xS8vRy399JXX1Vw0=",
|
"narHash": "sha256-EGeZ963L7xsNAY7snvP1JHQe7LWLVCM6f49+PzWjhEE=",
|
||||||
"owner": "SEIAROTg",
|
"owner": "SEIAROTg",
|
||||||
"repo": "quadlet-nix",
|
"repo": "quadlet-nix",
|
||||||
"rev": "1b2d27d460d8c7e4da5ba44ede463b427160b5c4",
|
"rev": "2ebe01b175e2e1e6de3f172d23f0c3b88713eec9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -495,11 +495,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757531894,
|
"lastModified": 1759752146,
|
||||||
"narHash": "sha256-GwV3ES7n/2mwPeu8FGfViI6QfzbTrvNob3OZOsPQId0=",
|
"narHash": "sha256-g30leL+8jLxkYWiM5W2RjnhGyqBtErmeOX3ELK5CRAQ=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "3d069983345ea83549c641dd3f8875e54aaf1c2b",
|
"rev": "bc1564ea3eb472f7b843e3237da0d1cd2f6f8e37",
|
||||||
"revCount": 12,
|
"revCount": 14,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@karaolidis.com/karaolidis/nix-sas.git"
|
"url": "ssh://git@karaolidis.com/karaolidis/nix-sas.git"
|
||||||
},
|
},
|
||||||
@@ -511,11 +511,11 @@
|
|||||||
"secrets": {
|
"secrets": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1757873556,
|
"lastModified": 1759165833,
|
||||||
"narHash": "sha256-WYrV46if1XsiQKOQEMNtHdAPeFDeu7YBdcoNSXc3sf8=",
|
"narHash": "sha256-EYAVKr7gGY7MDmgPIYsW3yk96q51UT1vtzlupR8paKg=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "21ab0b0a59264b1da501f90725bf2c03e07ae941",
|
"rev": "a5c1c552628492281e05e99458f1ca3ec272b448",
|
||||||
"revCount": 43,
|
"revCount": 48,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@karaolidis.com/karaolidis/nix-secrets.git"
|
"url": "ssh://git@karaolidis.com/karaolidis/nix-secrets.git"
|
||||||
},
|
},
|
||||||
@@ -531,11 +531,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1754988908,
|
"lastModified": 1759635238,
|
||||||
"narHash": "sha256-t+voe2961vCgrzPFtZxha0/kmFSHFobzF00sT8p9h0U=",
|
"narHash": "sha256-UvzKi02LMFP74csFfwLPAZ0mrE7k6EiYaKecplyX9Qk=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "3223c7a92724b5d804e9988c6b447a0d09017d48",
|
"rev": "6e5a38e08a2c31ae687504196a230ae00ea95133",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -554,11 +554,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756614537,
|
"lastModified": 1759638324,
|
||||||
"narHash": "sha256-qyszmZO9CEKAlj5NBQo1AIIADm5Fgqs5ZggW1sU1TVo=",
|
"narHash": "sha256-bj0L3n2UWE/DjqFjsydWsSzO74+dqUA4tiOX4At6LbM=",
|
||||||
"owner": "Gerg-L",
|
"owner": "Gerg-L",
|
||||||
"repo": "spicetify-nix",
|
"repo": "spicetify-nix",
|
||||||
"rev": "374eb5d97092b97f7aaafd58a2012943b388c0df",
|
"rev": "c39a58510e55c4970e57176ab14b722a978e5f01",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -589,11 +589,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755934250,
|
"lastModified": 1758728421,
|
||||||
"narHash": "sha256-CsDojnMgYsfshQw3t4zjRUkmMmUdZGthl16bXVWgRYU=",
|
"narHash": "sha256-ySNJ008muQAds2JemiyrWYbwbG+V7S5wg3ZVKGHSFu8=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "74e1a52d5bd9430312f8d1b8b0354c92c17453e5",
|
"rev": "5eda4ee8121f97b218f7cc73f5172098d458f1d1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@@ -3,5 +3,6 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./cpu/options.nix
|
./cpu/options.nix
|
||||||
./impermanence/options.nix
|
./impermanence/options.nix
|
||||||
|
./networking/options.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
17
hosts/common/configs/system/networking/options.nix
Normal file
17
hosts/common/configs/system/networking/options.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
options.networking =
|
||||||
|
with lib;
|
||||||
|
with types;
|
||||||
|
{
|
||||||
|
publicIPv4 = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
description = "The public IPv4 address of this device.";
|
||||||
|
};
|
||||||
|
|
||||||
|
publicIPv6 = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
description = "The public IPv6 address of this device.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -42,9 +42,13 @@
|
|||||||
"flakes"
|
"flakes"
|
||||||
];
|
];
|
||||||
download-buffer-size = 524288000;
|
download-buffer-size = 524288000;
|
||||||
substituters = lib.mkBefore [ "https://nix.karaolidis.com/main" ];
|
substituters = lib.mkMerge [
|
||||||
|
(lib.mkBefore [ "https://nix.karaolidis.com/main" ])
|
||||||
|
(lib.mkAfter [ "https://nix-community.cachix.org/" ])
|
||||||
|
];
|
||||||
trusted-public-keys = lib.mkBefore [
|
trusted-public-keys = lib.mkBefore [
|
||||||
"nix.karaolidis.com:1yz1tIVLGDEOFC1p/uYtR4Sx+nIbdYDqsDv4kkV0uyk="
|
"nix.karaolidis.com:1yz1tIVLGDEOFC1p/uYtR4Sx+nIbdYDqsDv4kkV0uyk="
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
];
|
];
|
||||||
netrc-file = config.sops.templates.nix-netrc.path;
|
netrc-file = config.sops.templates.nix-netrc.path;
|
||||||
};
|
};
|
||||||
|
4
hosts/common/configs/system/usb/default.nix
Normal file
4
hosts/common/configs/system/usb/default.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [ usbutils ];
|
||||||
|
}
|
8
hosts/common/configs/user/console/curl/default.nix
Normal file
8
hosts/common/configs/user/console/curl/default.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
home-manager.users.${user}.home.packages = with pkgs; [
|
||||||
|
curl
|
||||||
|
httpie
|
||||||
|
];
|
||||||
|
}
|
@@ -26,7 +26,10 @@ in
|
|||||||
push.autoSetupRemote = true;
|
push.autoSetupRemote = true;
|
||||||
core.fsmonitor = true;
|
core.fsmonitor = true;
|
||||||
feature.manyFiles = true;
|
feature.manyFiles = true;
|
||||||
fetch.writeCommitGraph = true;
|
fetch = {
|
||||||
|
prune = true;
|
||||||
|
writeCommitGraph = true;
|
||||||
|
};
|
||||||
http.cookiefile = "${home}/.config/git/cookies";
|
http.cookiefile = "${home}/.config/git/cookies";
|
||||||
advice.detachedHead = false;
|
advice.detachedHead = false;
|
||||||
};
|
};
|
||||||
@@ -40,6 +43,10 @@ in
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
aliases = {
|
||||||
|
adog = "log --all --decorate --oneline --graph";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
home = {
|
home = {
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
ipset
|
ipset
|
||||||
ethtool
|
ethtool
|
||||||
tcpdump
|
tcpdump
|
||||||
|
dig
|
||||||
ipcalc
|
ipcalc
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
20
hosts/common/configs/user/console/lazygit/default.nix
Normal file
20
hosts/common/configs/user/console/lazygit/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
environment.persistence."/persist/state"."${home}/.local/state/lazygit" = { };
|
||||||
|
|
||||||
|
home-manager.users.${user}.programs.lazygit = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
gui = {
|
||||||
|
showBottomLine = false;
|
||||||
|
nerdFontsVersion = "3";
|
||||||
|
animateExplosion = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
disableStartupPopups = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -27,11 +27,15 @@
|
|||||||
vimAlias = true;
|
vimAlias = true;
|
||||||
|
|
||||||
autocomplete = {
|
autocomplete = {
|
||||||
blink-cmp.enable = true;
|
blink-cmp = {
|
||||||
|
enable = true;
|
||||||
|
setupOpts = {
|
||||||
|
signature.enabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
binds = {
|
binds = {
|
||||||
# hardtime-nvim.enable = true;
|
|
||||||
whichKey.enable = true;
|
whichKey.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,34 +49,23 @@
|
|||||||
comment-nvim.enable = true;
|
comment-nvim.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# dashboard = {
|
dashboard = {
|
||||||
# alpha.enable = true;
|
alpha.enable = true;
|
||||||
# };
|
};
|
||||||
|
|
||||||
filetree = {
|
diagnostics = {
|
||||||
neo-tree = {
|
enable = true;
|
||||||
enable = true;
|
config = {
|
||||||
setupOpts = {
|
virtual_text = true;
|
||||||
git_status_async = true;
|
signs = true;
|
||||||
|
|
||||||
window.mappings = lib.generators.mkLuaInline ''
|
|
||||||
{
|
|
||||||
["<space>"] = "noop",
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# formatter = {
|
|
||||||
# conform-nvim.enable = true;
|
|
||||||
# };
|
|
||||||
|
|
||||||
git = {
|
git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# git-conflict.enable = true;
|
git-conflict.enable = true;
|
||||||
gitsigns.enable = true;
|
gitsigns.enable = true;
|
||||||
# neogit.enable = true;
|
vim-fugitive.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
languages = {
|
languages = {
|
||||||
@@ -116,15 +109,12 @@
|
|||||||
lsp = {
|
lsp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
formatOnSave = true;
|
formatOnSave = true;
|
||||||
# nvim-docs-view.enable = true;
|
otter-nvim = {
|
||||||
# otter-nvim.enable = true;
|
enable = true;
|
||||||
# trouble.enable = true;
|
setupOpts.handle_leading_whitespace = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# minimap = {
|
|
||||||
# codewindow.enable = true;
|
|
||||||
# };
|
|
||||||
|
|
||||||
notify = {
|
notify = {
|
||||||
nvim-notify.enable = true;
|
nvim-notify.enable = true;
|
||||||
};
|
};
|
||||||
@@ -136,16 +126,8 @@
|
|||||||
smartindent = true;
|
smartindent = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# projects = {
|
|
||||||
# project-nvim.enable = true;
|
|
||||||
# };
|
|
||||||
|
|
||||||
searchCase = "smart";
|
searchCase = "smart";
|
||||||
|
|
||||||
# snippets = {
|
|
||||||
# luasnip.enable = true;
|
|
||||||
# };
|
|
||||||
|
|
||||||
tabline = {
|
tabline = {
|
||||||
nvimBufferline = {
|
nvimBufferline = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -160,20 +142,24 @@
|
|||||||
|
|
||||||
telescope = {
|
telescope = {
|
||||||
enable = true;
|
enable = true;
|
||||||
setupOpts.defaults.file_ignore_patterns = [
|
setupOpts.defaults = {
|
||||||
"node_modules"
|
wrap_results = true;
|
||||||
"%.venv/"
|
file_ignore_patterns = [
|
||||||
"%.git/"
|
"node_modules"
|
||||||
"dist/"
|
"%.venv/"
|
||||||
"build/"
|
"%.git/"
|
||||||
"target/"
|
"dist/"
|
||||||
"result/"
|
"build/"
|
||||||
];
|
"target/"
|
||||||
|
"result/"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
terminal = {
|
terminal = {
|
||||||
toggleterm = {
|
toggleterm = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
lazygit.enable = true;
|
||||||
setupOpts.winbar.enabled = false;
|
setupOpts.winbar.enabled = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -186,41 +172,39 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ui = {
|
ui = {
|
||||||
# breadcrumbs = {
|
|
||||||
# enable = true;
|
|
||||||
# navbuddy.enable = true;
|
|
||||||
# };
|
|
||||||
colorizer.enable = true;
|
colorizer.enable = true;
|
||||||
# fastaction.enable = true;
|
illuminate.enable = true;
|
||||||
# illuminate.enable = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
undoFile.enable = true;
|
undoFile.enable = true;
|
||||||
|
|
||||||
utility = {
|
utility = {
|
||||||
# diffview-nvim.enable = true;
|
images = {
|
||||||
# icon-picker.enable = true;
|
img-clip = {
|
||||||
# images = {
|
enable = true;
|
||||||
# img-clip.enable = true;
|
setupOpts.default.verbose = false;
|
||||||
# };
|
};
|
||||||
# mkdir.enable = true;
|
};
|
||||||
|
mkdir.enable = true;
|
||||||
motion = {
|
motion = {
|
||||||
precognition.enable = true;
|
precognition.enable = true;
|
||||||
};
|
};
|
||||||
# nvim-biscuits.enable = true;
|
|
||||||
# smart-splits.enable = true;
|
|
||||||
surround.enable = true;
|
surround.enable = true;
|
||||||
# undotree.enable = true;
|
undotree.enable = true;
|
||||||
# yazi-nvim.enable = true;
|
yazi-nvim = {
|
||||||
|
enable = true;
|
||||||
|
setupOpts.open_for_directories = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
visuals = {
|
visuals = {
|
||||||
# cinnamon-nvim.enable = true;
|
highlight-undo = {
|
||||||
# fidget-nvim.enable = true;
|
enable = true;
|
||||||
# highlight-undo.enable = true;
|
setupOpts.duration = 250;
|
||||||
|
};
|
||||||
indent-blankline.enable = true;
|
indent-blankline.enable = true;
|
||||||
nvim-cursorline.enable = true;
|
nvim-cursorline.enable = true;
|
||||||
# nvim-scrollbar.enable = true;
|
nvim-scrollbar.enable = true;
|
||||||
nvim-web-devicons.enable = true;
|
nvim-web-devicons.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -267,23 +251,16 @@
|
|||||||
{
|
{
|
||||||
mode = [ "n" ];
|
mode = [ "n" ];
|
||||||
key = "<leader>wq";
|
key = "<leader>wq";
|
||||||
action = "<cmd>wq<CR>";
|
action = "<cmd>x<CR>";
|
||||||
silent = true;
|
silent = true;
|
||||||
desc = "Save & Quit";
|
desc = "Save & Quit";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
mode = [ "n" ];
|
mode = [ "n" ];
|
||||||
key = "<leader>ee";
|
key = "<leader>be";
|
||||||
action = "<cmd>Neotree toggle<CR>";
|
action = "<cmd>enew<CR>";
|
||||||
silent = true;
|
silent = true;
|
||||||
desc = "Toggle Neo-tree";
|
desc = "New buffer";
|
||||||
}
|
|
||||||
{
|
|
||||||
mode = [ "n" ];
|
|
||||||
key = "<leader>ef";
|
|
||||||
action = "<cmd>Neotree reveal<CR>";
|
|
||||||
silent = true;
|
|
||||||
desc = "Reveal file in Neo-tree";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
enable = true;
|
enable = true;
|
||||||
key = config.sops.secrets."syncthing/key".path;
|
key = config.sops.secrets."syncthing/key".path;
|
||||||
cert = config.sops.secrets."syncthing/cert".path;
|
cert = config.sops.secrets."syncthing/cert".path;
|
||||||
extraOptions = [ "-no-default-folder" ];
|
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
options.urAccepted = -1;
|
options.urAccepted = -1;
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
settings = {
|
settings = {
|
||||||
theme = "matugen";
|
theme = "matugen";
|
||||||
|
|
||||||
|
default_mode = "locked";
|
||||||
|
|
||||||
pane_frames = false;
|
pane_frames = false;
|
||||||
copy_command = "wl-copy";
|
copy_command = "wl-copy";
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
home-manager.users.${user} = {
|
home-manager.users.${user} = {
|
||||||
programs.rofi.plugins = with pkgs; [ rofi-emoji-wayland ];
|
programs.rofi.plugins = with pkgs; [ rofi-emoji ];
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings.bind = [
|
wayland.windowManager.hyprland.settings.bind = [
|
||||||
# Super + Shift + :
|
# Super + Shift + :
|
||||||
|
7
hosts/common/configs/user/gui/ghidra/default.nix
Normal file
7
hosts/common/configs/user/gui/ghidra/default.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
programs.ghidra.enable = true;
|
||||||
|
|
||||||
|
environment.persistence."/persist/state"."${home}/.config/ghidra" = { };
|
||||||
|
}
|
@@ -99,6 +99,8 @@
|
|||||||
"$mod, mouse:273, resizewindow"
|
"$mod, mouse:273, resizewindow"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
gesture = [ "3, horizontal, workspace" ];
|
||||||
|
|
||||||
input = {
|
input = {
|
||||||
accel_profile = "flat";
|
accel_profile = "flat";
|
||||||
kb_layout = "us,gr";
|
kb_layout = "us,gr";
|
||||||
@@ -114,8 +116,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
gestures = {
|
gestures = {
|
||||||
workspace_swipe = true;
|
|
||||||
workspace_swipe_min_fingers = true;
|
|
||||||
workspace_swipe_forever = true;
|
workspace_swipe_forever = true;
|
||||||
workspace_swipe_cancel_ratio = 0.2;
|
workspace_swipe_cancel_ratio = 0.2;
|
||||||
};
|
};
|
||||||
|
@@ -14,7 +14,7 @@ in
|
|||||||
home-manager.users.${user} = {
|
home-manager.users.${user} = {
|
||||||
programs.rofi = {
|
programs.rofi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.rofi-wayland;
|
package = pkgs.rofi;
|
||||||
};
|
};
|
||||||
|
|
||||||
home.file.${hmConfig.programs.rofi.configPath}.enable = false;
|
home.file.${hmConfig.programs.rofi.configPath}.enable = false;
|
||||||
|
7
hosts/common/configs/user/gui/signal/default.nix
Normal file
7
hosts/common/configs/user/gui/signal/default.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.persistence."/persist/state"."${home}/.config/Signal" = { };
|
||||||
|
|
||||||
|
home-manager.users.${user}.home.packages = with pkgs; [ signal-desktop ];
|
||||||
|
}
|
17
hosts/common/configs/user/gui/wireshark/default.nix
Normal file
17
hosts/common/configs/user/gui/wireshark/default.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.wireshark = {
|
||||||
|
enable = true;
|
||||||
|
dumpcap.enable = true;
|
||||||
|
usbmon.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.kernelModules = [ "usbmon" ];
|
||||||
|
|
||||||
|
users.users.${user}.extraGroups = [ "wireshark" ];
|
||||||
|
|
||||||
|
environment.persistence."/persist/state"."${home}/.config/wireshark" = { };
|
||||||
|
|
||||||
|
home-manager.users.${user}.home.packages = with pkgs; [ wireshark ];
|
||||||
|
}
|
@@ -36,7 +36,7 @@ in
|
|||||||
programs = {
|
programs = {
|
||||||
go = {
|
go = {
|
||||||
enable = true;
|
enable = true;
|
||||||
goPath = ".local/share/go";
|
env.GOPATH = "${home}/.local/share/go";
|
||||||
};
|
};
|
||||||
|
|
||||||
gradle = {
|
gradle = {
|
||||||
|
@@ -131,6 +131,12 @@ in
|
|||||||
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"vps.karaolidis.com" = {
|
||||||
|
hostname = "vps.karaolidis.com";
|
||||||
|
user = "root";
|
||||||
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
|
};
|
||||||
|
|
||||||
"github.com" = {
|
"github.com" = {
|
||||||
hostname = "github.com";
|
hostname = "github.com";
|
||||||
user = "git";
|
user = "git";
|
||||||
|
@@ -1,36 +1,5 @@
|
|||||||
{ user, home }:
|
{ user, home }:
|
||||||
{ config, pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
|
||||||
systemctl = "${pkgs.systemd}/bin/systemctl";
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
# FIXME: https://github.com/nix-community/NixOS-WSL/issues/375
|
|
||||||
# FIXME: https://github.com/Mic92/sops-nix/issues/687
|
|
||||||
# FIXME: https://github.com/microsoft/WSL/issues/8842
|
|
||||||
# FIXME: https://github.com/microsoft/WSL/issues/10205
|
|
||||||
# Fuck Microsoft.
|
|
||||||
security.sudo.extraRules = [
|
|
||||||
{
|
|
||||||
users = [ config.users.users.${user}.name ];
|
|
||||||
commands = [
|
|
||||||
{
|
|
||||||
command = "${systemctl} restart user@${toString config.users.users.${user}.uid}.service";
|
|
||||||
options = [ "NOPASSWD" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
command = "${systemctl} restart user@${toString config.users.users.${user}.uid}";
|
|
||||||
options = [ "NOPASSWD" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
users.users.${user}.shell = pkgs.writeShellApplication {
|
|
||||||
name = "wsl-zsh";
|
|
||||||
runtimeInputs = with pkgs; [ systemd ];
|
|
||||||
text = builtins.readFile ./wsl-zsh.sh;
|
|
||||||
passthru.shellPath = "/bin/wsl-zsh";
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users.${user}.home.packages = with pkgs; [ wsl-wl-clipboard ];
|
home-manager.users.${user}.home.packages = with pkgs; [ wsl-wl-clipboard ];
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
# shellcheck shell=bash
|
|
||||||
|
|
||||||
user_bus="${DBUS_SESSION_BUS_ADDRESS#unix:path=}"
|
|
||||||
|
|
||||||
if [ -S "$user_bus" ]; then
|
|
||||||
exec zsh
|
|
||||||
fi
|
|
||||||
|
|
||||||
until [ -S /run/dbus/system_bus_socket ]; do
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
|
|
||||||
sudo systemctl restart "user@${UID}.service"
|
|
||||||
|
|
||||||
exec zsh
|
|
@@ -16,6 +16,7 @@ in
|
|||||||
|
|
||||||
(import ../../../common/configs/user/console/attic { inherit user home; })
|
(import ../../../common/configs/user/console/attic { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/btop { inherit user home; })
|
(import ../../../common/configs/user/console/btop { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/console/curl { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/dive { inherit user home; })
|
(import ../../../common/configs/user/console/dive { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/fastfetch { inherit user home; })
|
(import ../../../common/configs/user/console/fastfetch { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/ffmpeg { inherit user home; })
|
(import ../../../common/configs/user/console/ffmpeg { inherit user home; })
|
||||||
@@ -26,6 +27,7 @@ in
|
|||||||
(import ../../../common/configs/user/console/ip { inherit user home; })
|
(import ../../../common/configs/user/console/ip { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/jq { inherit user home; })
|
(import ../../../common/configs/user/console/jq { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/kubernetes { inherit user home; })
|
(import ../../../common/configs/user/console/kubernetes { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/console/lazygit { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/lsof { inherit user home; })
|
(import ../../../common/configs/user/console/lsof { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/mprocs { inherit user home; })
|
(import ../../../common/configs/user/console/mprocs { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/ncdu { inherit user home; })
|
(import ../../../common/configs/user/console/ncdu { inherit user home; })
|
||||||
|
@@ -45,6 +45,7 @@
|
|||||||
../common/configs/system/system
|
../common/configs/system/system
|
||||||
../common/configs/system/timezone
|
../common/configs/system/timezone
|
||||||
../common/configs/system/upower
|
../common/configs/system/upower
|
||||||
|
../common/configs/system/usb
|
||||||
../common/configs/system/users
|
../common/configs/system/users
|
||||||
../common/configs/system/zsh
|
../common/configs/system/zsh
|
||||||
|
|
||||||
|
@@ -62,10 +62,6 @@
|
|||||||
name = "alc285-fixup";
|
name = "alc285-fixup";
|
||||||
patch = ./gu605c-spi-cs-gpio/alc285-fixup.patch;
|
patch = ./gu605c-spi-cs-gpio/alc285-fixup.patch;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "iwlwifi-no-disable-all-chans";
|
|
||||||
patch = ./iwlwifi/iwlwifi-no-disable-all-chans.patch;
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
initrd = {
|
initrd = {
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
|
|
||||||
index 6adcfa6e214a..4512d846629c 100644
|
|
||||||
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
|
|
||||||
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
|
|
||||||
@@ -622,7 +622,7 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
|
|
||||||
cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);
|
|
||||||
|
|
||||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
|
|
||||||
- if (!ret)
|
|
||||||
+ if (!ret && value != 0xFFFFFFFF)
|
|
||||||
cmd->force_disable_channels_bitmap = cpu_to_le32(value);
|
|
||||||
|
|
||||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
|
|
||||||
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
|
|
||||||
index a75af8c1e8ab..e055a946b9e6 100644
|
|
||||||
--- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
|
|
||||||
+++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
|
|
||||||
@@ -259,7 +259,7 @@ void iwl_mld_configure_lari(struct iwl_mld *mld)
|
|
||||||
cmd.oem_uhb_allow_bitmap = cpu_to_le32(value);
|
|
||||||
|
|
||||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value);
|
|
||||||
- if (!ret)
|
|
||||||
+ if (!ret && value != 0xFFFFFFFF)
|
|
||||||
cmd.force_disable_channels_bitmap = cpu_to_le32(value);
|
|
||||||
|
|
||||||
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
|
|
@@ -75,6 +75,12 @@ in
|
|||||||
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"vps.karaolidis.com" = {
|
||||||
|
hostname = "vps.karaolidis.com";
|
||||||
|
user = "root";
|
||||||
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
|
};
|
||||||
|
|
||||||
"github.com" = {
|
"github.com" = {
|
||||||
hostname = "github.com";
|
hostname = "github.com";
|
||||||
user = "git";
|
user = "git";
|
||||||
|
@@ -18,6 +18,7 @@ in
|
|||||||
(import ../../../common/configs/user/console/attic { inherit user home; })
|
(import ../../../common/configs/user/console/attic { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/brightnessctl { inherit user home; })
|
(import ../../../common/configs/user/console/brightnessctl { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/btop { inherit user home; })
|
(import ../../../common/configs/user/console/btop { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/console/curl { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/dive { inherit user home; })
|
(import ../../../common/configs/user/console/dive { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/fastfetch { inherit user home; })
|
(import ../../../common/configs/user/console/fastfetch { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/ffmpeg { inherit user home; })
|
(import ../../../common/configs/user/console/ffmpeg { inherit user home; })
|
||||||
@@ -27,6 +28,7 @@ in
|
|||||||
(import ../../../common/configs/user/console/imagemagick { inherit user home; })
|
(import ../../../common/configs/user/console/imagemagick { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/ip { inherit user home; })
|
(import ../../../common/configs/user/console/ip { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/jq { inherit user home; })
|
(import ../../../common/configs/user/console/jq { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/console/lazygit { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/libvirt { inherit user home; })
|
(import ../../../common/configs/user/console/libvirt { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/lsof { inherit user home; })
|
(import ../../../common/configs/user/console/lsof { inherit user home; })
|
||||||
(import ../../../common/configs/user/console/mprocs { inherit user home; })
|
(import ../../../common/configs/user/console/mprocs { inherit user home; })
|
||||||
@@ -68,6 +70,7 @@ in
|
|||||||
(import ../../../common/configs/user/gui/gaming/prismlauncher { inherit user home; })
|
(import ../../../common/configs/user/gui/gaming/prismlauncher { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/gaming/proton { inherit user home; })
|
(import ../../../common/configs/user/gui/gaming/proton { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/gaming/wivrn { inherit user home; })
|
(import ../../../common/configs/user/gui/gaming/wivrn { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/gui/ghidra { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/gtk { inherit user home; })
|
(import ../../../common/configs/user/gui/gtk { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/hypridle { inherit user home; })
|
(import ../../../common/configs/user/gui/hypridle { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/hyprland { inherit user home; })
|
(import ../../../common/configs/user/gui/hyprland { inherit user home; })
|
||||||
@@ -85,11 +88,13 @@ in
|
|||||||
(import ../../../common/configs/user/gui/qt { inherit user home; })
|
(import ../../../common/configs/user/gui/qt { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/rofi { inherit user home; })
|
(import ../../../common/configs/user/gui/rofi { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/rquickshare { inherit user home; })
|
(import ../../../common/configs/user/gui/rquickshare { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/gui/signal { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/swww { inherit user home; })
|
(import ../../../common/configs/user/gui/swww { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/theme { inherit user home; })
|
(import ../../../common/configs/user/gui/theme { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/transmission { inherit user home; })
|
(import ../../../common/configs/user/gui/transmission { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/vscode { inherit user home; })
|
(import ../../../common/configs/user/gui/vscode { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/wev { inherit user home; })
|
(import ../../../common/configs/user/gui/wev { inherit user home; })
|
||||||
|
(import ../../../common/configs/user/gui/wireshark { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/wl-clipboard { inherit user home; })
|
(import ../../../common/configs/user/gui/wl-clipboard { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/x11 { inherit user home; })
|
(import ../../../common/configs/user/gui/x11 { inherit user home; })
|
||||||
(import ../../../common/configs/user/gui/xdg { inherit user home; })
|
(import ../../../common/configs/user/gui/xdg { inherit user home; })
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
../common/configs/system/sudo
|
../common/configs/system/sudo
|
||||||
../common/configs/system/system
|
../common/configs/system/system
|
||||||
../common/configs/system/timezone
|
../common/configs/system/timezone
|
||||||
|
../common/configs/system/usb
|
||||||
../common/configs/system/users
|
../common/configs/system/users
|
||||||
../common/configs/system/zsh
|
../common/configs/system/zsh
|
||||||
|
|
||||||
|
@@ -74,6 +74,12 @@ in
|
|||||||
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"vps.karaolidis.com" = {
|
||||||
|
hostname = "vps.karaolidis.com";
|
||||||
|
user = "root";
|
||||||
|
identityFile = "${home}/.ssh/ssh_personal_ed25519_key";
|
||||||
|
};
|
||||||
|
|
||||||
"github.com" = {
|
"github.com" = {
|
||||||
hostname = "github.com";
|
hostname = "github.com";
|
||||||
user = "git";
|
user = "git";
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
let
|
let
|
||||||
jupiterConfig = inputs.self.nixosConfigurations.jupiter.config;
|
jupiterConfig = inputs.self.nixosConfigurations.jupiter.config;
|
||||||
wireguardPort = 51821;
|
wireguardPort = 51821;
|
||||||
jupiterPublicIPv4 = "51.89.210.124";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
boot.kernel.sysctl = {
|
boot.kernel.sysctl = {
|
||||||
@@ -29,7 +28,7 @@ in
|
|||||||
name = "jupiter";
|
name = "jupiter";
|
||||||
allowedIPs = [
|
allowedIPs = [
|
||||||
"10.0.0.2/32"
|
"10.0.0.2/32"
|
||||||
"${jupiterPublicIPv4}/32"
|
"${jupiterConfig.networking.publicIPv4}/32"
|
||||||
];
|
];
|
||||||
publicKey = builtins.readFile "${inputs.secrets}/hosts/jupiter/wireguard_key.pub";
|
publicKey = builtins.readFile "${inputs.secrets}/hosts/jupiter/wireguard_key.pub";
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,10 @@
|
|||||||
./configs/wireguard
|
./configs/wireguard
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "jupiter-vps";
|
networking = {
|
||||||
|
hostName = "jupiter-vps";
|
||||||
|
publicIPv4 = "217.154.55.15";
|
||||||
|
};
|
||||||
|
|
||||||
environment.impermanence.enable = lib.mkForce false;
|
environment.impermanence.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
disko.devices = {
|
disko.devices = {
|
||||||
disk.main = {
|
disk.main = {
|
||||||
device = "/dev/sda";
|
device = "/dev/vda";
|
||||||
type = "disk";
|
type = "disk";
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
|
@@ -117,62 +117,87 @@ in
|
|||||||
|
|
||||||
filters = [ ];
|
filters = [ ];
|
||||||
whitelist_filters = [ ];
|
whitelist_filters = [ ];
|
||||||
user_rules = [
|
|
||||||
"||*^"
|
filtering.rewrites = [
|
||||||
# Personal
|
{
|
||||||
"@@||karaolidis.com^$important"
|
domain = "beta.media.karaolidis.com";
|
||||||
# Connectivity Check
|
answer = inboundGateway;
|
||||||
"@@||clients3.google.com^"
|
}
|
||||||
"@@||clients.l.google.com^"
|
|
||||||
"@@||connectivitycheck.gstatic.com^"
|
|
||||||
"@@||connectivitycheck.android.com^"
|
|
||||||
# NTP
|
|
||||||
"@@||pool.ntp.org^$important"
|
|
||||||
"@@||time.android.com^$important"
|
|
||||||
"@@||time.akamai.com^$important"
|
|
||||||
# Plex
|
|
||||||
"@@||plex.tv^$important"
|
|
||||||
"@@||plex.direct^$important"
|
|
||||||
# YouTube
|
|
||||||
"@@||youtube.com^$important"
|
|
||||||
"@@||yt.be^$important"
|
|
||||||
"@@||ytimg.com^$important"
|
|
||||||
"@@||googlevideo.com^$important"
|
|
||||||
# YouTube Extensions
|
|
||||||
"@@||returnyoutubedislikeapi.com^$important"
|
|
||||||
"@@||sponsor.ajay.app^$important"
|
|
||||||
# Google Misc
|
|
||||||
"@@||accounts.google.com^$important"
|
|
||||||
"@@||www.gstatic.com^$important"
|
|
||||||
"@@||content-autofill.googleapis.com^$important"
|
|
||||||
# Google Play
|
|
||||||
"@@||play.google.com^$important"
|
|
||||||
"@@||android.googleapis.com^$important"
|
|
||||||
"@@||androidtvsetupwraithfe-pa.googleapis.com^$important"
|
|
||||||
"@@||play-fe.googleapis.com^$important"
|
|
||||||
"@@||play-lh.googleusercontent.com^$important"
|
|
||||||
"@@||play.googleapis.com^$important"
|
|
||||||
"@@||android.apis.google.com^$important"
|
|
||||||
"@@||playatoms-pa.googleapis.com^$important"
|
|
||||||
"@@||gvt1.com^$important"
|
|
||||||
# Spotify
|
|
||||||
"@@||spotify.com^$important"
|
|
||||||
"@@||spotify.dev^$important"
|
|
||||||
"@@||scdn.co^$important"
|
|
||||||
"@@||tospotify.com^$important"
|
|
||||||
"@@||spotifycdn.com^$important"
|
|
||||||
# Twitch
|
|
||||||
"@@||twitch.tv^$important"
|
|
||||||
"@@||ttvnw.net^$important"
|
|
||||||
"@@||static-cdn.jtvnw.net^$important"
|
|
||||||
# Cosmote TV
|
|
||||||
"@@||account.cosmote.gr^$important"
|
|
||||||
"@@||cosmotetvott.gr^$important"
|
|
||||||
"@@||msvdn.net^$important"
|
|
||||||
"@@||theplatform.eu^$important"
|
|
||||||
"@@||theplatform.com^$important"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
user_rules =
|
||||||
|
let
|
||||||
|
domains = [
|
||||||
|
# Personal
|
||||||
|
"beta.media.karaolidis.com"
|
||||||
|
|
||||||
|
# Connectivity Check
|
||||||
|
"clients3.google.com"
|
||||||
|
"clients.l.google.com"
|
||||||
|
"connectivitycheck.gstatic.com"
|
||||||
|
"connectivitycheck.android.com"
|
||||||
|
|
||||||
|
# NTP
|
||||||
|
"pool.ntp.org"
|
||||||
|
"time.android.com"
|
||||||
|
"time.akamai.com"
|
||||||
|
|
||||||
|
# Plex
|
||||||
|
"plex.tv"
|
||||||
|
"plex.direct"
|
||||||
|
|
||||||
|
# YouTube
|
||||||
|
"youtube.com"
|
||||||
|
"yt.be"
|
||||||
|
"ytimg.com"
|
||||||
|
"googlevideo.com"
|
||||||
|
|
||||||
|
# YouTube Extensions
|
||||||
|
"returnyoutubedislikeapi.com"
|
||||||
|
"sponsor.ajay.app"
|
||||||
|
|
||||||
|
# Google Misc
|
||||||
|
"accounts.google.com"
|
||||||
|
"www.gstatic.com"
|
||||||
|
"content-autofill.googleapis.com"
|
||||||
|
|
||||||
|
# Google Play
|
||||||
|
"play.google.com"
|
||||||
|
"android.googleapis.com"
|
||||||
|
"androidtvsetupwraithfe-pa.googleapis.com"
|
||||||
|
"play-fe.googleapis.com"
|
||||||
|
"play-lh.googleusercontent.com"
|
||||||
|
"play.googleapis.com"
|
||||||
|
"android.apis.google.com"
|
||||||
|
"playatoms-pa.googleapis.com"
|
||||||
|
"gvt1.com"
|
||||||
|
|
||||||
|
# Spotify
|
||||||
|
"spotify.com"
|
||||||
|
"spotify.dev"
|
||||||
|
"scdn.co"
|
||||||
|
"tospotify.com"
|
||||||
|
"spotifycdn.com"
|
||||||
|
|
||||||
|
# Twitch
|
||||||
|
"twitch.tv"
|
||||||
|
"ttvnw.net"
|
||||||
|
"static-cdn.jtvnw.net"
|
||||||
|
|
||||||
|
# Cosmote TV
|
||||||
|
"account.cosmote.gr"
|
||||||
|
"cosmotetvott.gr"
|
||||||
|
"msvdn.net"
|
||||||
|
"theplatform.eu"
|
||||||
|
"theplatform.com"
|
||||||
|
|
||||||
|
# Releases
|
||||||
|
"github.com"
|
||||||
|
"release-assets.githubusercontent.com"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
[ "||*^" ] ++ (map (domain: "@@||${domain}^$important") domains);
|
||||||
|
|
||||||
schema_version = 29;
|
schema_version = 29;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@@ -7,8 +7,6 @@
|
|||||||
let
|
let
|
||||||
jupiterVpsConfig = inputs.self.nixosConfigurations.jupiter-vps.config;
|
jupiterVpsConfig = inputs.self.nixosConfigurations.jupiter-vps.config;
|
||||||
wireguardPort = jupiterVpsConfig.networking.wireguard.interfaces.wg0.listenPort;
|
wireguardPort = jupiterVpsConfig.networking.wireguard.interfaces.wg0.listenPort;
|
||||||
jupiterVpsPublicIPv4 = "51.75.170.190";
|
|
||||||
jupiterPublicIPv4 = "51.89.210.124";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
sops.secrets."wireguard/client/vps" = { };
|
sops.secrets."wireguard/client/vps" = { };
|
||||||
@@ -29,21 +27,21 @@ in
|
|||||||
{
|
{
|
||||||
ips = [
|
ips = [
|
||||||
"10.0.0.2/24"
|
"10.0.0.2/24"
|
||||||
"${jupiterPublicIPv4}/32"
|
"${config.networking.publicIPv4}/32"
|
||||||
];
|
];
|
||||||
|
|
||||||
privateKeyFile = config.sops.secrets."wireguard/client/vps".path;
|
privateKeyFile = config.sops.secrets."wireguard/client/vps".path;
|
||||||
|
|
||||||
inherit table;
|
inherit table;
|
||||||
postSetup = [ "${ip} rule add from ${jupiterPublicIPv4} table ${table}" ];
|
postSetup = [ "${ip} rule add from ${config.networking.publicIPv4} table ${table}" ];
|
||||||
postShutdown = [ "${ip} rule del from ${jupiterPublicIPv4} table ${table}" ];
|
postShutdown = [ "${ip} rule del from ${config.networking.publicIPv4} table ${table}" ];
|
||||||
|
|
||||||
peers = [
|
peers = [
|
||||||
{
|
{
|
||||||
name = "jupiter-vps";
|
name = "jupiter-vps";
|
||||||
allowedIPs = [ "0.0.0.0/0" ];
|
allowedIPs = [ "0.0.0.0/0" ];
|
||||||
publicKey = builtins.readFile "${inputs.secrets}/hosts/jupiter-vps/wireguard_key.pub";
|
publicKey = builtins.readFile "${inputs.secrets}/hosts/jupiter-vps/wireguard_key.pub";
|
||||||
endpoint = "${jupiterVpsPublicIPv4}:${builtins.toString wireguardPort}";
|
endpoint = "${jupiterVpsConfig.networking.publicIPv4}:${builtins.toString wireguardPort}";
|
||||||
persistentKeepalive = 25;
|
persistentKeepalive = 25;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
../common/configs/system/sshd
|
../common/configs/system/sshd
|
||||||
../common/configs/system/sudo
|
../common/configs/system/sudo
|
||||||
../common/configs/system/system
|
../common/configs/system/system
|
||||||
|
../common/configs/system/usb
|
||||||
../common/configs/system/users
|
../common/configs/system/users
|
||||||
../common/configs/system/zsh
|
../common/configs/system/zsh
|
||||||
|
|
||||||
@@ -52,7 +53,10 @@
|
|||||||
./users/tv
|
./users/tv
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "jupiter";
|
networking = {
|
||||||
|
hostName = "jupiter";
|
||||||
|
publicIPv4 = "87.106.36.59";
|
||||||
|
};
|
||||||
|
|
||||||
boot.initrd = {
|
boot.initrd = {
|
||||||
luks.devices = {
|
luks.devices = {
|
||||||
|
@@ -22,12 +22,22 @@
|
|||||||
# FIXME: https://github.com/icewind1991/nvidia-patch-nixos/issues/9
|
# FIXME: https://github.com/icewind1991/nvidia-patch-nixos/issues/9
|
||||||
package =
|
package =
|
||||||
let
|
let
|
||||||
nvidiaStable = config.boot.kernelPackages.nvidiaPackages.stable;
|
# FIXME: HDMI Crash, God knows when it will be reported and/or fixed
|
||||||
|
nvidiaStable = config.boot.kernelPackages.nvidiaPackages.mkDriver {
|
||||||
|
version = "580.82.09";
|
||||||
|
sha256_64bit = "sha256-Puz4MtouFeDgmsNMKdLHoDgDGC+QRXh6NVysvltWlbc=";
|
||||||
|
sha256_aarch64 = "sha256-6tHiAci9iDTKqKrDIjObeFdtrlEwjxOHJpHfX4GMEGQ=";
|
||||||
|
openSha256 = "sha256-YB+mQD+oEDIIDa+e8KX1/qOlQvZMNKFrI5z3CoVKUjs=";
|
||||||
|
settingsSha256 = "sha256-um53cr2Xo90VhZM1bM2CH4q9b/1W2YOqUcvXPV6uw2s=";
|
||||||
|
persistencedSha256 = "sha256-lbYSa97aZ+k0CISoSxOMLyyMX//Zg2Raym6BC4COipU=";
|
||||||
|
};
|
||||||
|
|
||||||
maybeFbc =
|
maybeFbc =
|
||||||
if builtins.hasAttr nvidiaStable.version pkgs.nvidia-patch-list.fbc then
|
if builtins.hasAttr nvidiaStable.version pkgs.nvidia-patch-list.fbc then
|
||||||
pkgs.nvidia-patch.patch-fbc nvidiaStable
|
pkgs.nvidia-patch.patch-fbc nvidiaStable
|
||||||
else
|
else
|
||||||
nvidiaStable;
|
nvidiaStable;
|
||||||
|
|
||||||
nvidiaStableFinal =
|
nvidiaStableFinal =
|
||||||
if builtins.hasAttr nvidiaStable.version pkgs.nvidia-patch-list.nvenc then
|
if builtins.hasAttr nvidiaStable.version pkgs.nvidia-patch-list.nvenc then
|
||||||
pkgs.nvidia-patch.patch-nvenc maybeFbc
|
pkgs.nvidia-patch.patch-nvenc maybeFbc
|
||||||
@@ -53,8 +63,6 @@
|
|||||||
graphics = {
|
graphics = {
|
||||||
enable32Bit = true;
|
enable32Bit = true;
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
amdvlk
|
|
||||||
driversi686Linux.amdvlk
|
|
||||||
rocmPackages.clr
|
rocmPackages.clr
|
||||||
rocmPackages.clr.icd
|
rocmPackages.clr.icd
|
||||||
];
|
];
|
||||||
@@ -92,10 +100,7 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
nixpkgs.config = {
|
nixpkgs.config.cudaSupport = true;
|
||||||
cudaSupport = true;
|
|
||||||
rocmSupport = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
xserver.videoDrivers = [ "nvidia" ];
|
xserver.videoDrivers = [ "nvidia" ];
|
||||||
|
@@ -132,11 +132,11 @@ in
|
|||||||
"media"
|
"media"
|
||||||
"vaultwarden"
|
"vaultwarden"
|
||||||
"nextcloud"
|
"nextcloud"
|
||||||
"jellyfin"
|
|
||||||
"gitea"
|
"gitea"
|
||||||
"outline"
|
"outline"
|
||||||
"shlink"
|
"shlink"
|
||||||
"comentario"
|
"comentario"
|
||||||
|
"immich"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,14 @@ in
|
|||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.blog.rule=Host(`blog.karaolidis.com`)"
|
"traefik.http.routers.blog.rule=Host(`blog.karaolidis.com`)"
|
||||||
|
|
||||||
|
"traefik.http.routers.root.rule=Host(`karaolidis.com`) || Host(`www.karaolidis.com`)"
|
||||||
|
"traefik.http.routers.root.middlewares=redirect-root-to-blog"
|
||||||
|
"traefik.http.routers.root.service=noop@internal"
|
||||||
|
|
||||||
|
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.regex=^https://(www\.)?karaolidis\.com(/.*)?$"
|
||||||
|
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.replacement=https://blog.karaolidis.com$${2}"
|
||||||
|
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.permanent=false"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,10 +55,6 @@ in
|
|||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.blog-receiver.rule=Host(`blog.karaolidis.com`) && PathPrefix(`/upload`)"
|
"traefik.http.routers.blog-receiver.rule=Host(`blog.karaolidis.com`) && PathPrefix(`/upload`)"
|
||||||
|
|
||||||
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.regex=^https://(www\.)?karaolidis\.com(/.*)?$"
|
|
||||||
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.replacement=https://blog.karaolidis.com$${2}"
|
|
||||||
"traefik.http.middlewares.redirect-root-to-blog.redirectregex.permanent=false"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ in
|
|||||||
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."comentario/postgresql"}
|
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."comentario/postgresql"}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
comentario.content = builtins.readFile (
|
comentario-secrets.content = builtins.readFile (
|
||||||
(pkgs.formats.yaml { }).generate "secrets.yaml" {
|
(pkgs.formats.yaml { }).generate "secrets.yaml" {
|
||||||
postgres = {
|
postgres = {
|
||||||
host = "comentario-postgresql";
|
host = "comentario-postgresql";
|
||||||
@@ -56,6 +56,7 @@ in
|
|||||||
];
|
];
|
||||||
key = autheliaClientId;
|
key = autheliaClientId;
|
||||||
secret = hmConfig.sops.placeholder."comentario/authelia/password";
|
secret = hmConfig.sops.placeholder."comentario/authelia/password";
|
||||||
|
superuserClaim = "is_admin";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -88,7 +89,7 @@ in
|
|||||||
"email"
|
"email"
|
||||||
"is_admin"
|
"is_admin"
|
||||||
];
|
];
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -110,16 +111,27 @@ in
|
|||||||
networks.comentario.ref
|
networks.comentario.ref
|
||||||
networks.traefik.ref
|
networks.traefik.ref
|
||||||
];
|
];
|
||||||
environments = {
|
volumes =
|
||||||
BASE_URL = "https://comments.karaolidis.com";
|
let
|
||||||
NO_COLOR = "true";
|
config = (pkgs.formats.yaml { }).generate "config.yaml" {
|
||||||
SUPERUSER_CLAIM = "is_admin";
|
baseUrl = "https://comments.karaolidis.com";
|
||||||
DYN_DEFAULT_AUTH_EMAILUPDATE_ENABLED = "true";
|
log.noColor = true;
|
||||||
DYN_DEFAULT_AUTH_SIGNUP_CONFIRM_COMMENTER = "false";
|
|
||||||
DYN_DEFAULT_AUTH_SIGNUP_ENABLED = "false";
|
dynamicConfigDefaults.auth = {
|
||||||
DYN_DEFAULT_AUTH_SIGNUP_SSO_ENABLED = "true";
|
emailUpdate.enabled = true;
|
||||||
};
|
|
||||||
volumes = [ "${hmConfig.sops.templates.comentario.path}:/etc/comentario/secrets.yaml:ro" ];
|
signup = {
|
||||||
|
confirm.commenter = false;
|
||||||
|
enabled = false;
|
||||||
|
sso.enabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
[
|
||||||
|
"${config}:/etc/comentario/config.yaml:ro"
|
||||||
|
"${hmConfig.sops.templates.comentario-secrets.path}:/etc/comentario/secrets.yaml:ro"
|
||||||
|
];
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.comentario.rule=Host(`comments.karaolidis.com`)"
|
"traefik.http.routers.comentario.rule=Host(`comments.karaolidis.com`)"
|
||||||
|
@@ -16,6 +16,7 @@ in
|
|||||||
(import ./comentario { inherit user home; })
|
(import ./comentario { inherit user home; })
|
||||||
(import ./gitea { inherit user home; })
|
(import ./gitea { inherit user home; })
|
||||||
(import ./grafana { inherit user home; })
|
(import ./grafana { inherit user home; })
|
||||||
|
(import ./immich { inherit user home; })
|
||||||
(import ./littlelink { inherit user home; })
|
(import ./littlelink { inherit user home; })
|
||||||
(import ./lore { inherit user home; })
|
(import ./lore { inherit user home; })
|
||||||
(import ./media { inherit user home; })
|
(import ./media { inherit user home; })
|
||||||
|
@@ -196,7 +196,7 @@ in
|
|||||||
client_secret = hmConfig.sops.placeholder."gitea/authelia/digest";
|
client_secret = hmConfig.sops.placeholder."gitea/authelia/digest";
|
||||||
redirect_uris = [ "https://git.karaolidis.com/user/oauth2/authelia/callback" ];
|
redirect_uris = [ "https://git.karaolidis.com/user/oauth2/authelia/callback" ];
|
||||||
authorization_policy = "gitea";
|
authorization_policy = "gitea";
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
policies:
|
||||||
|
- orgId: 1
|
||||||
|
receiver: ntfy.sh
|
||||||
|
group_by:
|
||||||
|
- grafana_folder
|
||||||
|
- alertname
|
||||||
|
group_wait: 0s
|
||||||
|
group_interval: 1m
|
||||||
|
repeat_interval: 1h
|
@@ -0,0 +1,454 @@
|
|||||||
|
apiVersion: 1
|
||||||
|
groups:
|
||||||
|
- orgId: 1
|
||||||
|
name: Default
|
||||||
|
folder: System
|
||||||
|
interval: 10s
|
||||||
|
rules:
|
||||||
|
- uid: cpu-usage
|
||||||
|
title: CPU Usage
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: 1 - avg by(hostname) (rate(node_cpu_seconds_total{mode="idle"}[1h]))
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0.9
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
for: 30m
|
||||||
|
keepFiringFor: 5m
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: memory-usage
|
||||||
|
title: Memory Usage
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: 1 - (node_memory_MemAvailable_bytes{} / node_memory_MemTotal_bytes{})
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0.9
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
for: 5m
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: cpu-temperature
|
||||||
|
title: CPU Temperature
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: node_hwmon_temp_celsius{chip="pci0000:00_0000:00:18_3", sensor="temp1"}
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 75
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
for: 30m
|
||||||
|
keepFiringFor: 5m
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: amabient-temperature
|
||||||
|
title: Ambient Temperature
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: avg(node_hwmon_temp_celsius{chip="thermal_thermal_zone0"})
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 70
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
for: 15m
|
||||||
|
keepFiringFor: 5m
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: smart-status
|
||||||
|
title: SMART Status
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: smartctl_device_smart_status
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 1
|
||||||
|
type: lt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
keepFiringFor: 1h
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: smart-errors
|
||||||
|
title: SMART Errors
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: "sum(\n increase(smartctl_device_attribute{attribute_value_type=\"raw\", attribute_name=~\"Raw_Read_Error_Rate|Seek_Error_Rate|Offline_Uncorrectable\"}[1h])\n) + \nsum(\n increase(smartctl_device_media_errors[1h])\n)"
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
keepFiringFor: 1h
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: smart-temperature
|
||||||
|
title: SMART Temperature
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: smartctl_device_temperature
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 50
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
for: 15m
|
||||||
|
keepFiringFor: 5m
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: btrfs-errors
|
||||||
|
title: BTRFS Errors
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: |-
|
||||||
|
sum by (btrfs_dev_uuid) (
|
||||||
|
increase(node_btrfs_device_errors_total[1h])
|
||||||
|
)
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
||||||
|
- uid: systemd-units
|
||||||
|
title: SystemD Units
|
||||||
|
condition: C
|
||||||
|
data:
|
||||||
|
- refId: A
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: prometheus
|
||||||
|
model:
|
||||||
|
editorMode: code
|
||||||
|
expr: node_systemd_units{state="failed"}
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: A
|
||||||
|
- refId: C
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params:
|
||||||
|
- C
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: last
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: A
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: C
|
||||||
|
type: threshold
|
||||||
|
noDataState: NoData
|
||||||
|
execErrState: Error
|
||||||
|
keepFiringFor: 1h
|
||||||
|
isPaused: false
|
||||||
|
notification_settings:
|
||||||
|
receiver: ntfy.sh
|
@@ -4859,13 +4859,6 @@
|
|||||||
},
|
},
|
||||||
"pluginVersion": "12.1.1",
|
"pluginVersion": "12.1.1",
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
|
||||||
"editorMode": "code",
|
|
||||||
"expr": "rate(podman_container_block_input_total{hostname=\"$hostname\"}[$__rate_interval]) * on(id) group_left(name) podman_container_info{hostname=\"$hostname\"}",
|
|
||||||
"legendFormat": "{{name}} (write)",
|
|
||||||
"range": true,
|
|
||||||
"refId": "A"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
@@ -4874,6 +4867,13 @@
|
|||||||
"editorMode": "code",
|
"editorMode": "code",
|
||||||
"expr": "rate(podman_container_block_output_total{hostname=\"$hostname\"}[$__rate_interval]) * on(id) group_left(name) podman_container_info{hostname=\"$hostname\"}",
|
"expr": "rate(podman_container_block_output_total{hostname=\"$hostname\"}[$__rate_interval]) * on(id) group_left(name) podman_container_info{hostname=\"$hostname\"}",
|
||||||
"hide": false,
|
"hide": false,
|
||||||
|
"legendFormat": "{{name}} (write)",
|
||||||
|
"range": true,
|
||||||
|
"refId": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"editorMode": "code",
|
||||||
|
"expr": "rate(podman_container_block_input_total{hostname=\"$hostname\"}[$__rate_interval]) * on(id) group_left(name) podman_container_info{hostname=\"$hostname\"}",
|
||||||
"legendFormat": "{{name}} (read)",
|
"legendFormat": "{{name}} (read)",
|
||||||
"range": true,
|
"range": true,
|
||||||
"refId": "B"
|
"refId": "B"
|
||||||
|
@@ -18,6 +18,7 @@ in
|
|||||||
"grafana/authelia/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"grafana/authelia/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
"grafana/authelia/digest".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"grafana/authelia/digest".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
"grafana/smtp".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"grafana/smtp".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"ntfy/tokens/jupiter/grafana".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
};
|
};
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
@@ -32,7 +33,7 @@ in
|
|||||||
authorization_policy = "admin_one_factor";
|
authorization_policy = "admin_one_factor";
|
||||||
require_pkce = true;
|
require_pkce = true;
|
||||||
pkce_challenge_method = "S256";
|
pkce_challenge_method = "S256";
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -114,6 +115,37 @@ in
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
grafana-to-ntfy-env.content = ''
|
||||||
|
BAUTH_PASS=${hmConfig.sops.placeholder."ntfy/tokens/jupiter/grafana"}
|
||||||
|
NTFY_BAUTH_PASS=${hmConfig.sops.placeholder."ntfy/tokens/jupiter/grafana"}
|
||||||
|
'';
|
||||||
|
|
||||||
|
grafana-contact-points.content = builtins.readFile (
|
||||||
|
(pkgs.formats.yaml { }).generate "contact-points.yaml" {
|
||||||
|
apiVersion = 1;
|
||||||
|
contactPoints = [
|
||||||
|
{
|
||||||
|
orgId = 1;
|
||||||
|
name = "ntfy.sh";
|
||||||
|
receivers = [
|
||||||
|
{
|
||||||
|
uid = "ntfy";
|
||||||
|
type = "webhook";
|
||||||
|
settings = {
|
||||||
|
httpMethod = "POST";
|
||||||
|
url = "http://grafana-to-ntfy:8080";
|
||||||
|
username = "jupiter";
|
||||||
|
password = hmConfig.sops.placeholder."ntfy/tokens/jupiter/grafana";
|
||||||
|
headers = { };
|
||||||
|
};
|
||||||
|
disableResolveMessage = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -136,7 +168,7 @@ in
|
|||||||
providers = [
|
providers = [
|
||||||
{
|
{
|
||||||
name = "Default";
|
name = "Default";
|
||||||
folder = "";
|
folder = "System";
|
||||||
type = "file";
|
type = "file";
|
||||||
url = "http://prometheus:9090";
|
url = "http://prometheus:9090";
|
||||||
options.path = "/var/lib/grafana/dashboards";
|
options.path = "/var/lib/grafana/dashboards";
|
||||||
@@ -148,6 +180,9 @@ in
|
|||||||
"${hmConfig.sops.templates.grafana.path}:/etc/grafana/grafana.ini:ro"
|
"${hmConfig.sops.templates.grafana.path}:/etc/grafana/grafana.ini:ro"
|
||||||
"${dashboards}:/etc/grafana/conf/provisioning/dashboards/default.yaml:ro"
|
"${dashboards}:/etc/grafana/conf/provisioning/dashboards/default.yaml:ro"
|
||||||
"${./dashboards}:/var/lib/grafana/dashboards:ro"
|
"${./dashboards}:/var/lib/grafana/dashboards:ro"
|
||||||
|
"${./alerting/policies.yaml}:/etc/grafana/conf/provisioning/alerting/policies.yaml:ro"
|
||||||
|
"${./alerting/rules.yaml}:/etc/grafana/conf/provisioning/alerting/rules.yaml:ro"
|
||||||
|
"${hmConfig.sops.templates.grafana-contact-points.path}:/etc/grafana/conf/provisioning/alerting/contact-points.yaml:ro"
|
||||||
];
|
];
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
@@ -163,6 +198,16 @@ in
|
|||||||
networks = [ networks.grafana.ref ];
|
networks = [ networks.grafana.ref ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
grafana-to-ntfy.containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.grafana-to-ntfy}";
|
||||||
|
networks = [ networks.grafana.ref ];
|
||||||
|
environments = {
|
||||||
|
"NTFY_URL" = "https://ntfy.karaolidis.com/grafana";
|
||||||
|
"BAUTH_USER" = "jupiter";
|
||||||
|
};
|
||||||
|
environmentFiles = [ hmConfig.sops.templates.grafana-to-ntfy-env.path ];
|
||||||
|
};
|
||||||
|
|
||||||
authelia.containerConfig.volumes = [
|
authelia.containerConfig.volumes = [
|
||||||
"${hmConfig.sops.templates.authelia-grafana.path}:/etc/authelia/conf.d/grafana.yaml:ro"
|
"${hmConfig.sops.templates.authelia-grafana.path}:/etc/authelia/conf.d/grafana.yaml:ro"
|
||||||
];
|
];
|
||||||
|
@@ -0,0 +1,215 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hmConfig = config.home-manager.users.${user};
|
||||||
|
inherit (hmConfig.virtualisation.quadlet) volumes containers networks;
|
||||||
|
autheliaClientId = "kwrm5k1Bgwqd4BCXiWp0feL6adpthOn0GGgQ9iIVW7IH1UIj7bA2HVj9Jv42hUheoYoE8wWJpQi8woPomrSJIauTmsBMMFTTrI6r";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
home-manager.users.${user} = {
|
||||||
|
sops = {
|
||||||
|
secrets = {
|
||||||
|
"immich/smtp".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"immich/postgresql".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"immich/admin".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"immich/authelia/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"immich/authelia/digest".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
};
|
||||||
|
|
||||||
|
templates = {
|
||||||
|
immich-postgresql-env.content = ''
|
||||||
|
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."immich/postgresql"}
|
||||||
|
'';
|
||||||
|
|
||||||
|
immich-env.content = ''
|
||||||
|
DB_PASSWORD=${hmConfig.sops.placeholder."immich/postgresql"}
|
||||||
|
IMMICH_ADMIN_PASSWORD=${hmConfig.sops.placeholder."immich/admin"}
|
||||||
|
'';
|
||||||
|
|
||||||
|
immich.content = builtins.readFile (
|
||||||
|
(pkgs.formats.json { }).generate "config.json" {
|
||||||
|
ffmpeg = {
|
||||||
|
accel = "nvenc";
|
||||||
|
accelDecode = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
oauth = {
|
||||||
|
enabled = true;
|
||||||
|
buttonText = "Login with Authelia";
|
||||||
|
clientId = autheliaClientId;
|
||||||
|
clientSecret = hmConfig.sops.placeholder."immich/authelia/password";
|
||||||
|
issuerUrl = "https://id.karaolidis.com/.well-known/openid-configuration";
|
||||||
|
scope = lib.strings.concatStringsSep " " [
|
||||||
|
"openid"
|
||||||
|
"profile"
|
||||||
|
"email"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordLogin.enabled = true;
|
||||||
|
|
||||||
|
newVersionCheck.enabled = false;
|
||||||
|
|
||||||
|
library.watch.enabled = true;
|
||||||
|
|
||||||
|
server.externalDomain = "https://photos.karaolidis.com";
|
||||||
|
|
||||||
|
notifications.smtp = {
|
||||||
|
enabled = true;
|
||||||
|
from = "jupiter@karaolidis.com";
|
||||||
|
transport = {
|
||||||
|
host = "smtp.protonmail.ch";
|
||||||
|
port = 587;
|
||||||
|
username = "jupiter@karaolidis.com";
|
||||||
|
password = hmConfig.sops.placeholder."immich/smtp";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
authelia-immich.content = builtins.readFile (
|
||||||
|
(pkgs.formats.yaml { }).generate "immich.yaml" {
|
||||||
|
identity_providers.oidc = {
|
||||||
|
authorization_policies.immich = {
|
||||||
|
default_policy = "deny";
|
||||||
|
rules = [
|
||||||
|
{
|
||||||
|
policy = "one_factor";
|
||||||
|
subject = "group:immich";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
clients = [
|
||||||
|
{
|
||||||
|
client_id = autheliaClientId;
|
||||||
|
client_name = "immich";
|
||||||
|
client_secret = hmConfig.sops.placeholder."immich/authelia/digest";
|
||||||
|
redirect_uris = [
|
||||||
|
"https://photos.karaolidis.com/auth/login"
|
||||||
|
"https://photos.karaolidis.com/user-settings"
|
||||||
|
"app.immich:///oauth-callback"
|
||||||
|
];
|
||||||
|
authorization_policy = "immich";
|
||||||
|
scopes = [
|
||||||
|
"openid"
|
||||||
|
"profile"
|
||||||
|
"email"
|
||||||
|
];
|
||||||
|
token_endpoint_auth_method = "client_secret_post";
|
||||||
|
pre_configured_consent_duration = "1 year";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.tmpfiles.rules = [
|
||||||
|
"d /mnt/storage/private/storm/containers/storage/volumes/immich/_data 700 storm storm"
|
||||||
|
];
|
||||||
|
|
||||||
|
virtualisation.quadlet = {
|
||||||
|
networks.immich = { };
|
||||||
|
|
||||||
|
volumes = {
|
||||||
|
immich-redis = { };
|
||||||
|
immich-postgresql = { };
|
||||||
|
immich-machine-learning-cache = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
immich = {
|
||||||
|
containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.immich}";
|
||||||
|
volumes =
|
||||||
|
let
|
||||||
|
postStart = pkgs.writeTextFile {
|
||||||
|
name = "post-start.sh";
|
||||||
|
executable = true;
|
||||||
|
text = builtins.readFile ./post-start.sh;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
[
|
||||||
|
"${hmConfig.sops.templates.immich.path}:/etc/immich/config.json:ro"
|
||||||
|
"${postStart}:/etc/immich/post-start.sh:ro"
|
||||||
|
"/mnt/storage/private/storm/containers/storage/volumes/immich/_data:/var/lib/immich"
|
||||||
|
];
|
||||||
|
networks = [
|
||||||
|
networks.immich.ref
|
||||||
|
networks.traefik.ref
|
||||||
|
];
|
||||||
|
labels = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.immich.rule=Host(`photos.karaolidis.com`)"
|
||||||
|
];
|
||||||
|
environments = {
|
||||||
|
DB_HOSTNAME = "immich-postgresql";
|
||||||
|
DB_USERNAME = "immich";
|
||||||
|
DB_DATABASE_NAME = "immich";
|
||||||
|
REDIS_HOSTNAME = "immich-redis";
|
||||||
|
IMMICH_ADMIN_EMAIL = "jupiter@karaolidis.com";
|
||||||
|
IMMICH_ADMIN_NAME = "Admin";
|
||||||
|
};
|
||||||
|
environmentFiles = [ hmConfig.sops.templates.immich-env.path ];
|
||||||
|
podmanArgs = [ "--cdi-spec-dir=/run/cdi" ];
|
||||||
|
devices = [ "nvidia.com/gpu=all" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig = {
|
||||||
|
After = [
|
||||||
|
"${containers.immich-postgresql._serviceName}.service"
|
||||||
|
"${containers.immich-redis._serviceName}.service"
|
||||||
|
"sops-nix.service"
|
||||||
|
];
|
||||||
|
Requires = [
|
||||||
|
"${containers.immich-postgresql._serviceName}.service"
|
||||||
|
"${containers.immich-redis._serviceName}.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
immich-machine-learning.containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.immich-machine-learning}";
|
||||||
|
volumes = [ "${volumes.immich-machine-learning-cache.ref}:/tmp/immich-machine-learning" ];
|
||||||
|
networks = [ networks.immich.ref ];
|
||||||
|
podmanArgs = [ "--cdi-spec-dir=/run/cdi" ];
|
||||||
|
devices = [ "nvidia.com/gpu=all" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
immich-postgresql = {
|
||||||
|
containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.postgresql-vectorchord}";
|
||||||
|
networks = [ networks.immich.ref ];
|
||||||
|
volumes = [ "${volumes.immich-postgresql.ref}:/var/lib/postgresql/data" ];
|
||||||
|
environments = {
|
||||||
|
POSTGRES_DB = "immich";
|
||||||
|
POSTGRES_USER = "immich";
|
||||||
|
};
|
||||||
|
environmentFiles = [ hmConfig.sops.templates.immich-postgresql-env.path ];
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig.After = [ "sops-nix.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
immich-redis.containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.redis}";
|
||||||
|
networks = [ networks.immich.ref ];
|
||||||
|
volumes = [ "${volumes.immich-redis.ref}:/var/lib/redis" ];
|
||||||
|
exec = [ "--save 60 1" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
authelia.containerConfig.volumes = [
|
||||||
|
"${hmConfig.sops.templates.authelia-immich.path}:/etc/authelia/conf.d/immich.yaml:ro"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
# shellcheck shell=sh
|
||||||
|
|
||||||
|
IMMICH_HOST="${IMMICH_HOST:-http://localhost:2283}"
|
||||||
|
IMMICH_ADMIN_NAME="${IMMICH_ADMIN_NAME:-Admin}"
|
||||||
|
|
||||||
|
until response="$(curl -sf "$IMMICH_HOST/api/server/config")"; do
|
||||||
|
echo "Waiting for Immich to be ready..."
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
is_initialized="$(echo "$response" | jq -r '.isInitialized')"
|
||||||
|
|
||||||
|
if [ "$is_initialized" = "false" ]; then
|
||||||
|
curl -sf "$IMMICH_HOST/api/auth/admin-sign-up" \
|
||||||
|
-X POST \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
--data-raw '{
|
||||||
|
"email":"'"$IMMICH_ADMIN_EMAIL"'",
|
||||||
|
"password":"'"$IMMICH_ADMIN_PASSWORD"'",
|
||||||
|
"name":"'"$IMMICH_ADMIN_NAME"'"
|
||||||
|
}'
|
||||||
|
fi
|
@@ -1,5 +1,10 @@
|
|||||||
{ user, home }:
|
{ user, home }:
|
||||||
{ config, ... }:
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
hmConfig = config.home-manager.users.${user};
|
hmConfig = config.home-manager.users.${user};
|
||||||
|
|
||||||
@@ -17,7 +22,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(import ./jellyfin { inherit user home; })
|
(import ./plex { inherit user home; })
|
||||||
(import ./jellyseerr {
|
(import ./jellyseerr {
|
||||||
inherit
|
inherit
|
||||||
user
|
user
|
||||||
@@ -56,6 +61,34 @@ in
|
|||||||
"d /mnt/storage/private/storm/containers/storage/volumes/media/_data/libraries/anime/shows 755 storm storm"
|
"d /mnt/storage/private/storm/containers/storage/volumes/media/_data/libraries/anime/shows 755 storm storm"
|
||||||
];
|
];
|
||||||
|
|
||||||
virtualisation.quadlet.networks.media = { };
|
sops.secrets."ntfy/tokens/jupiter/media".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
|
||||||
|
virtualisation.quadlet = {
|
||||||
|
networks.media = { };
|
||||||
|
|
||||||
|
containers.authelia.containerConfig.volumes =
|
||||||
|
let
|
||||||
|
mediaConfig = (pkgs.formats.yaml { }).generate "media.yaml" {
|
||||||
|
access_control.rules = [
|
||||||
|
{
|
||||||
|
domain = "beta.media.karaolidis.com";
|
||||||
|
policy = "one_factor";
|
||||||
|
resources = [ "^/manage([/?].*)?$" ];
|
||||||
|
subject = [ "group:media" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "beta.media.karaolidis.com";
|
||||||
|
policy = "deny";
|
||||||
|
resources = [ "^/manage([/?].*)?$" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "beta.media.karaolidis.com";
|
||||||
|
policy = "bypass";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
[ "${mediaConfig}:/etc/authelia/conf.d/media.yaml:ro" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,150 +0,0 @@
|
|||||||
{ user, home }:
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
hmConfig = config.home-manager.users.${user};
|
|
||||||
inherit (hmConfig.virtualisation.quadlet) volumes networks;
|
|
||||||
autheliaClientId = "59TRpNutxEeRRCAZbDsK7rsnrA5NC69HAdAO45CEfc740xl4hgIacDy2u03oiFc89Exb67udBQvmfwxgeAQtJPiNAJxA5OzGmdQf";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home-manager.users.${user} = {
|
|
||||||
sops = {
|
|
||||||
secrets = {
|
|
||||||
"jellyfin/admin".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
"jellyfin/authelia/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
"jellyfin/authelia/digest".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
"opensubtitles/username".sopsFile = "${inputs.secrets}/domains/personal/secrets.yaml";
|
|
||||||
"opensubtitles/password".sopsFile = "${inputs.secrets}/domains/personal/secrets.yaml";
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
jellyfin-env.content = ''
|
|
||||||
JELLYFIN_ADMIN_PASSWORD=${hmConfig.sops.placeholder."jellyfin/admin"}
|
|
||||||
JELLYFIN_OIDC_SECRET=${hmConfig.sops.placeholder."jellyfin/authelia/password"}
|
|
||||||
OPENSUBTITLES_USERNAME=${hmConfig.sops.placeholder."opensubtitles/username"}
|
|
||||||
OPENSUBTITLES_PASSWORD=${hmConfig.sops.placeholder."opensubtitles/password"}
|
|
||||||
'';
|
|
||||||
|
|
||||||
authelia-jellyfin.content = builtins.readFile (
|
|
||||||
(pkgs.formats.yaml { }).generate "jellyfin.yaml" {
|
|
||||||
identity_providers.oidc = {
|
|
||||||
authorization_policies.jellyfin = {
|
|
||||||
default_policy = "deny";
|
|
||||||
rules = [
|
|
||||||
{
|
|
||||||
policy = "one_factor";
|
|
||||||
subject = "group:jellyfin";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
clients = [
|
|
||||||
{
|
|
||||||
client_id = autheliaClientId;
|
|
||||||
client_name = "Jellyfin";
|
|
||||||
client_secret = hmConfig.sops.placeholder."jellyfin/authelia/digest";
|
|
||||||
redirect_uris = [ "https://media.karaolidis.com/sso/OID/redirect/authelia" ];
|
|
||||||
authorization_policy = "jellyfin";
|
|
||||||
require_pkce = true;
|
|
||||||
pkce_challenge_method = "S256";
|
|
||||||
scopes = [
|
|
||||||
"openid"
|
|
||||||
"profile"
|
|
||||||
"groups"
|
|
||||||
];
|
|
||||||
token_endpoint_auth_method = "client_secret_post";
|
|
||||||
pre_configured_consent_duration = "1 month";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.quadlet = {
|
|
||||||
networks.jellyfin = { };
|
|
||||||
|
|
||||||
volumes = {
|
|
||||||
jellyfin-config = { };
|
|
||||||
jellyfin-data = { };
|
|
||||||
jellyfin-metadata = { };
|
|
||||||
jellyfin-root = { };
|
|
||||||
jellyfin-log = { };
|
|
||||||
jellyfin-cache = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
containers = {
|
|
||||||
jellyfin = {
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker-archive:${pkgs.dockerImages.jellyfin}";
|
|
||||||
networks = [
|
|
||||||
networks.jellyfin.ref
|
|
||||||
networks.traefik.ref
|
|
||||||
];
|
|
||||||
volumes =
|
|
||||||
let
|
|
||||||
setup = pkgs.writeTextFile {
|
|
||||||
name = "setup.sh";
|
|
||||||
executable = true;
|
|
||||||
text = builtins.readFile ./setup.sh;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
[
|
|
||||||
"/mnt/storage/private/storm/containers/storage/volumes/media/_data:/var/lib/media"
|
|
||||||
"${setup}:/etc/jellyfin/setup.sh:ro"
|
|
||||||
"${./libraries}:/etc/jellyfin/libraries:ro"
|
|
||||||
"${volumes.jellyfin-config.ref}:/etc/jellyfin"
|
|
||||||
"${volumes.jellyfin-data.ref}:/var/lib/jellyfin/data"
|
|
||||||
"${volumes.jellyfin-metadata.ref}:/var/lib/jellyfin/metadata"
|
|
||||||
"${volumes.jellyfin-root.ref}:/var/lib/jellyfin/root"
|
|
||||||
"${volumes.jellyfin-log.ref}:/var/log/jellyfin"
|
|
||||||
"${volumes.jellyfin-cache.ref}:/tmp/jellyfin"
|
|
||||||
];
|
|
||||||
environments.JELLYFIN_OIDC_CLIENT_ID = autheliaClientId;
|
|
||||||
environmentFiles = [ hmConfig.sops.templates.jellyfin-env.path ];
|
|
||||||
labels = [
|
|
||||||
"traefik.enable=true"
|
|
||||||
"traefik.http.routers.jellyfin.rule=Host(`media.karaolidis.com`)"
|
|
||||||
];
|
|
||||||
podmanArgs = [ "--cdi-spec-dir=/run/cdi" ];
|
|
||||||
devices = [ "nvidia.com/gpu=all" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
unitConfig.After = [ "sops-nix.service" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
authelia.containerConfig.volumes =
|
|
||||||
let
|
|
||||||
mediaConfig = (pkgs.formats.yaml { }).generate "media.yaml" {
|
|
||||||
access_control.rules = [
|
|
||||||
{
|
|
||||||
domain = "media.karaolidis.com";
|
|
||||||
policy = "one_factor";
|
|
||||||
resources = [ "^/manage([/?].*)?$" ];
|
|
||||||
subject = [ "group:media" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
domain = "media.karaolidis.com";
|
|
||||||
policy = "deny";
|
|
||||||
resources = [ "^/manage([/?].*)?$" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
domain = "media.karaolidis.com";
|
|
||||||
policy = "bypass";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in
|
|
||||||
[
|
|
||||||
"${mediaConfig}:/etc/authelia/conf.d/media.yaml:ro"
|
|
||||||
"${hmConfig.sops.templates.authelia-jellyfin.path}:/etc/authelia/conf.d/jellyfin.yaml:ro"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,128 +0,0 @@
|
|||||||
{
|
|
||||||
"LibraryOptions": {
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableArchiveMediaFiles": false,
|
|
||||||
"EnablePhotos": true,
|
|
||||||
"EnableRealtimeMonitor": true,
|
|
||||||
"EnableLUFSScan": true,
|
|
||||||
"ExtractTrickplayImagesDuringLibraryScan": false,
|
|
||||||
"SaveTrickplayWithMedia": true,
|
|
||||||
"EnableTrickplayImageExtraction": true,
|
|
||||||
"ExtractChapterImagesDuringLibraryScan": false,
|
|
||||||
"EnableChapterImageExtraction": true,
|
|
||||||
"EnableInternetProviders": true,
|
|
||||||
"SaveLocalMetadata": true,
|
|
||||||
"EnableAutomaticSeriesGrouping": false,
|
|
||||||
"PreferredMetadataLanguage": "en",
|
|
||||||
"MetadataCountryCode": "JP",
|
|
||||||
"SeasonZeroDisplayName": "Specials",
|
|
||||||
"AutomaticRefreshIntervalDays": 30,
|
|
||||||
"EnableEmbeddedTitles": false,
|
|
||||||
"EnableEmbeddedExtrasTitles": false,
|
|
||||||
"EnableEmbeddedEpisodeInfos": false,
|
|
||||||
"AllowEmbeddedSubtitles": "AllowAll",
|
|
||||||
"SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
|
|
||||||
"SkipSubtitlesIfAudioTrackMatches": false,
|
|
||||||
"SaveSubtitlesWithMedia": true,
|
|
||||||
"SaveLyricsWithMedia": false,
|
|
||||||
"RequirePerfectSubtitleMatch": true,
|
|
||||||
"AutomaticallyAddToCollection": true,
|
|
||||||
"PreferNonstandardArtistsTag": false,
|
|
||||||
"UseCustomTagDelimiters": false,
|
|
||||||
"MetadataSavers": ["Nfo"],
|
|
||||||
"TypeOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Movie",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB"
|
|
||||||
],
|
|
||||||
"ImageFetchers": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageFetcherOrder": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "1",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LocalMetadataReaderOrder": ["Nfo"],
|
|
||||||
"SubtitleDownloadLanguages": [],
|
|
||||||
"CustomTagDelimiters": ["/", "|", ";", "\\"],
|
|
||||||
"DelimiterWhitelist": [],
|
|
||||||
"DisabledSubtitleFetchers": [],
|
|
||||||
"SubtitleFetcherOrder": [],
|
|
||||||
"DisabledLyricFetchers": [],
|
|
||||||
"LyricFetcherOrder": [],
|
|
||||||
"PathInfos": [
|
|
||||||
{
|
|
||||||
"Path": "/var/lib/media/libraries/anime/films"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,128 +0,0 @@
|
|||||||
{
|
|
||||||
"LibraryOptions": {
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableArchiveMediaFiles": false,
|
|
||||||
"EnablePhotos": true,
|
|
||||||
"EnableRealtimeMonitor": true,
|
|
||||||
"EnableLUFSScan": true,
|
|
||||||
"ExtractTrickplayImagesDuringLibraryScan": false,
|
|
||||||
"SaveTrickplayWithMedia": true,
|
|
||||||
"EnableTrickplayImageExtraction": true,
|
|
||||||
"ExtractChapterImagesDuringLibraryScan": false,
|
|
||||||
"EnableChapterImageExtraction": true,
|
|
||||||
"EnableInternetProviders": true,
|
|
||||||
"SaveLocalMetadata": true,
|
|
||||||
"EnableAutomaticSeriesGrouping": false,
|
|
||||||
"PreferredMetadataLanguage": "en",
|
|
||||||
"MetadataCountryCode": "US",
|
|
||||||
"SeasonZeroDisplayName": "Specials",
|
|
||||||
"AutomaticRefreshIntervalDays": 30,
|
|
||||||
"EnableEmbeddedTitles": false,
|
|
||||||
"EnableEmbeddedExtrasTitles": false,
|
|
||||||
"EnableEmbeddedEpisodeInfos": false,
|
|
||||||
"AllowEmbeddedSubtitles": "AllowAll",
|
|
||||||
"SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
|
|
||||||
"SkipSubtitlesIfAudioTrackMatches": false,
|
|
||||||
"SaveSubtitlesWithMedia": true,
|
|
||||||
"SaveLyricsWithMedia": false,
|
|
||||||
"RequirePerfectSubtitleMatch": true,
|
|
||||||
"AutomaticallyAddToCollection": true,
|
|
||||||
"PreferNonstandardArtistsTag": false,
|
|
||||||
"UseCustomTagDelimiters": false,
|
|
||||||
"MetadataSavers": ["Nfo"],
|
|
||||||
"TypeOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Movie",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB"
|
|
||||||
],
|
|
||||||
"ImageFetchers": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageFetcherOrder": [
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"TheTVDB",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "1",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LocalMetadataReaderOrder": ["Nfo"],
|
|
||||||
"SubtitleDownloadLanguages": [],
|
|
||||||
"CustomTagDelimiters": ["/", "|", ";", "\\"],
|
|
||||||
"DelimiterWhitelist": [],
|
|
||||||
"DisabledSubtitleFetchers": [],
|
|
||||||
"SubtitleFetcherOrder": [],
|
|
||||||
"DisabledLyricFetchers": [],
|
|
||||||
"LyricFetcherOrder": [],
|
|
||||||
"PathInfos": [
|
|
||||||
{
|
|
||||||
"Path": "/var/lib/media/libraries/films"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,204 +0,0 @@
|
|||||||
{
|
|
||||||
"LibraryOptions": {
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableArchiveMediaFiles": false,
|
|
||||||
"EnablePhotos": true,
|
|
||||||
"EnableRealtimeMonitor": true,
|
|
||||||
"EnableLUFSScan": true,
|
|
||||||
"ExtractTrickplayImagesDuringLibraryScan": false,
|
|
||||||
"SaveTrickplayWithMedia": true,
|
|
||||||
"EnableTrickplayImageExtraction": true,
|
|
||||||
"ExtractChapterImagesDuringLibraryScan": false,
|
|
||||||
"EnableChapterImageExtraction": true,
|
|
||||||
"EnableInternetProviders": true,
|
|
||||||
"SaveLocalMetadata": true,
|
|
||||||
"EnableAutomaticSeriesGrouping": true,
|
|
||||||
"PreferredMetadataLanguage": "en",
|
|
||||||
"MetadataCountryCode": "JP",
|
|
||||||
"SeasonZeroDisplayName": "Specials",
|
|
||||||
"AutomaticRefreshIntervalDays": 30,
|
|
||||||
"EnableEmbeddedTitles": false,
|
|
||||||
"EnableEmbeddedExtrasTitles": false,
|
|
||||||
"EnableEmbeddedEpisodeInfos": false,
|
|
||||||
"AllowEmbeddedSubtitles": "AllowAll",
|
|
||||||
"SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
|
|
||||||
"SkipSubtitlesIfAudioTrackMatches": false,
|
|
||||||
"SaveSubtitlesWithMedia": true,
|
|
||||||
"SaveLyricsWithMedia": false,
|
|
||||||
"RequirePerfectSubtitleMatch": true,
|
|
||||||
"AutomaticallyAddToCollection": false,
|
|
||||||
"PreferNonstandardArtistsTag": false,
|
|
||||||
"UseCustomTagDelimiters": false,
|
|
||||||
"MetadataSavers": ["Nfo"],
|
|
||||||
"TypeOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Series",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Missing Episode Fetcher"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Missing Episode Fetcher"
|
|
||||||
],
|
|
||||||
"ImageFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "1",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Season",
|
|
||||||
"MetadataFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"MetadataFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "0",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Episode",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database"
|
|
||||||
],
|
|
||||||
"ImageFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LocalMetadataReaderOrder": ["Nfo"],
|
|
||||||
"SubtitleDownloadLanguages": [],
|
|
||||||
"CustomTagDelimiters": ["/", "|", ";", "\\"],
|
|
||||||
"DelimiterWhitelist": [],
|
|
||||||
"DisabledSubtitleFetchers": [],
|
|
||||||
"SubtitleFetcherOrder": [],
|
|
||||||
"DisabledLyricFetchers": [],
|
|
||||||
"LyricFetcherOrder": [],
|
|
||||||
"PathInfos": [
|
|
||||||
{
|
|
||||||
"Path": "/var/lib/media/libraries/anime/shows"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,204 +0,0 @@
|
|||||||
{
|
|
||||||
"LibraryOptions": {
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableArchiveMediaFiles": false,
|
|
||||||
"EnablePhotos": true,
|
|
||||||
"EnableRealtimeMonitor": true,
|
|
||||||
"EnableLUFSScan": true,
|
|
||||||
"ExtractTrickplayImagesDuringLibraryScan": false,
|
|
||||||
"SaveTrickplayWithMedia": true,
|
|
||||||
"EnableTrickplayImageExtraction": true,
|
|
||||||
"ExtractChapterImagesDuringLibraryScan": false,
|
|
||||||
"EnableChapterImageExtraction": true,
|
|
||||||
"EnableInternetProviders": true,
|
|
||||||
"SaveLocalMetadata": true,
|
|
||||||
"EnableAutomaticSeriesGrouping": true,
|
|
||||||
"PreferredMetadataLanguage": "en",
|
|
||||||
"MetadataCountryCode": "US",
|
|
||||||
"SeasonZeroDisplayName": "Specials",
|
|
||||||
"AutomaticRefreshIntervalDays": 30,
|
|
||||||
"EnableEmbeddedTitles": false,
|
|
||||||
"EnableEmbeddedExtrasTitles": false,
|
|
||||||
"EnableEmbeddedEpisodeInfos": false,
|
|
||||||
"AllowEmbeddedSubtitles": "AllowAll",
|
|
||||||
"SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
|
|
||||||
"SkipSubtitlesIfAudioTrackMatches": false,
|
|
||||||
"SaveSubtitlesWithMedia": true,
|
|
||||||
"SaveLyricsWithMedia": false,
|
|
||||||
"RequirePerfectSubtitleMatch": true,
|
|
||||||
"AutomaticallyAddToCollection": false,
|
|
||||||
"PreferNonstandardArtistsTag": false,
|
|
||||||
"UseCustomTagDelimiters": false,
|
|
||||||
"MetadataSavers": ["Nfo"],
|
|
||||||
"TypeOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Series",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Missing Episode Fetcher"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Missing Episode Fetcher"
|
|
||||||
],
|
|
||||||
"ImageFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "1",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Season",
|
|
||||||
"MetadataFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"MetadataFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetchers": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageFetcherOrder": ["TheTVDB", "TheMovieDb"],
|
|
||||||
"ImageOptions": [
|
|
||||||
{
|
|
||||||
"Type": "Primary",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Art",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "BoxRear",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Banner",
|
|
||||||
"Limit": 1,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Box",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Disc",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Logo",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Menu",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Thumb",
|
|
||||||
"Limit": 0,
|
|
||||||
"MinWidth": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Backdrop",
|
|
||||||
"Limit": "0",
|
|
||||||
"MinWidth": "1280"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Type": "Episode",
|
|
||||||
"MetadataFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database"
|
|
||||||
],
|
|
||||||
"MetadataFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database"
|
|
||||||
],
|
|
||||||
"ImageFetchers": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
],
|
|
||||||
"ImageFetcherOrder": [
|
|
||||||
"TheTVDB",
|
|
||||||
"TheMovieDb",
|
|
||||||
"The Open Movie Database",
|
|
||||||
"Embedded Image Extractor",
|
|
||||||
"Screen Grabber"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"LocalMetadataReaderOrder": ["Nfo"],
|
|
||||||
"SubtitleDownloadLanguages": [],
|
|
||||||
"CustomTagDelimiters": ["/", "|", ";", "\\"],
|
|
||||||
"DelimiterWhitelist": [],
|
|
||||||
"DisabledSubtitleFetchers": [],
|
|
||||||
"SubtitleFetcherOrder": [],
|
|
||||||
"DisabledLyricFetchers": [],
|
|
||||||
"LyricFetcherOrder": [],
|
|
||||||
"PathInfos": [
|
|
||||||
{
|
|
||||||
"Path": "/var/lib/media/libraries/shows"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,214 +0,0 @@
|
|||||||
# shellcheck shell=sh
|
|
||||||
|
|
||||||
JELLYFIN_HOST="${JELLYFIN_HOST:-http://localhost:8096}"
|
|
||||||
JELLYFIN_ADMIN_USERNAME="${JELLYFIN_ADMIN_USERNAME:-admin}"
|
|
||||||
|
|
||||||
until response="$(curl -sf "$JELLYFIN_HOST/System/Info/Public")"; do
|
|
||||||
echo "Waiting for Jellyfin to be ready..."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
setup="$(echo "$response" | jq -r '.StartupWizardCompleted')"
|
|
||||||
|
|
||||||
if [ "$setup" = "false" ]; then
|
|
||||||
curl -sf "$JELLYFIN_HOST/Startup/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
--data-raw '{"UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}'
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Startup/User"
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Startup/User" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
--data-raw '{"Name":"'"$JELLYFIN_ADMIN_USERNAME"'","Password":"'"$JELLYFIN_ADMIN_PASSWORD"'"}'
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Startup/RemoteAccess" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
--data-raw '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}'
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Startup/Complete" \
|
|
||||||
-X POST
|
|
||||||
fi
|
|
||||||
|
|
||||||
token="$(curl -sf "$JELLYFIN_HOST/Users/AuthenticateByName" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Client="jellyfin-init", Device="sh", DeviceId="sh", Version="1.0"' \
|
|
||||||
--data-raw '{"Username":"'"$JELLYFIN_ADMIN_USERNAME"'","Pw":"'"$JELLYFIN_ADMIN_PASSWORD"'"}' \
|
|
||||||
| jq -r '.AccessToken')"
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/System/Configuration" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
| jq '.EnableMetrics = true
|
|
||||||
| .ServerName = "jupiter"
|
|
||||||
| .RemoteClientBitrateLimit = 1024000000
|
|
||||||
| .TrickplayOptions.EnableHwAcceleration = true
|
|
||||||
| .TrickplayOptions.EnableHwEncoding = true' \
|
|
||||||
| curl -sf "$JELLYFIN_HOST/System/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/System/Configuration/encoding" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
| jq '.EnableThrottling = true
|
|
||||||
| .HardwareAccelerationType = "nvenc"
|
|
||||||
| .EnableTonemapping = true
|
|
||||||
| .EnableDecodingColorDepth12HevcRext = true
|
|
||||||
| .AllowHevcEncoding = true
|
|
||||||
| .HardwareDecodingCodecs = ["h264", "hevc", "mpeg2video", "mpeg4", "vc1", "vp8", "vp9", "av1"]' \
|
|
||||||
| curl -sf "$JELLYFIN_HOST/System/Configuration/encoding" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Plugins/c83d86bb-a1e0-4c35-a113-e2101cf4ee6b/Configuration" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
| jq '.AnalyzeSeasonZero = true
|
|
||||||
| .AnalyzeMovies = true' \
|
|
||||||
| curl -sf "$JELLYFIN_HOST/Plugins/c83d86bb-a1e0-4c35-a113-e2101cf4ee6b/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Plugins/4b9ed42f-5185-48b5-9803-6ff2989014c4/Configuration" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
| jq --arg username "$OPENSUBTITLES_USERNAME" \
|
|
||||||
--arg password "$OPENSUBTITLES_PASSWORD" \
|
|
||||||
'.Username = $username
|
|
||||||
| .Password = $password' \
|
|
||||||
| curl -sf "$JELLYFIN_HOST/Plugins/4b9ed42f-5185-48b5-9803-6ff2989014c4/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Plugins/b8715ed1-6c47-4528-9ad3-f72deb539cd4/Configuration" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
| jq '.IncludeAdult = true' \
|
|
||||||
| curl -sf "$JELLYFIN_HOST/Plugins/b8715ed1-6c47-4528-9ad3-f72deb539cd4/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/Plugins/505ce9d1-d916-42fa-86ca-673ef241d7df/Configuration" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @- <<EOF
|
|
||||||
{
|
|
||||||
"SamlConfigs": {},
|
|
||||||
"OidConfigs": {
|
|
||||||
"authelia": {
|
|
||||||
"OidProviderName": "authelia",
|
|
||||||
"OidEndpoint": "https://id.karaolidis.com",
|
|
||||||
"OidClientId": "$JELLYFIN_OIDC_CLIENT_ID",
|
|
||||||
"OidSecret": "$JELLYFIN_OIDC_SECRET",
|
|
||||||
"RoleClaim": "groups",
|
|
||||||
"DefaultUsernameClaim": "preferred_username",
|
|
||||||
"Enabled": true,
|
|
||||||
"EnableAuthorization": true,
|
|
||||||
"EnableAllFolders": true,
|
|
||||||
"EnableFolderRoles": false,
|
|
||||||
"EnableLiveTvRoles": false,
|
|
||||||
"EnableLiveTv": false,
|
|
||||||
"EnableLiveTvManagement": false,
|
|
||||||
"DisableHttps": false,
|
|
||||||
"DoNotValidateEndpoints": false,
|
|
||||||
"DoNotValidateIssuerName": false,
|
|
||||||
"Roles": [
|
|
||||||
"jellyfin"
|
|
||||||
],
|
|
||||||
"AdminRoles": [
|
|
||||||
"admin"
|
|
||||||
],
|
|
||||||
"LiveTvRoles": [],
|
|
||||||
"LiveTvManagementRoles": [],
|
|
||||||
"OidScopes": [
|
|
||||||
"groups"
|
|
||||||
],
|
|
||||||
"EnabledFolders": [],
|
|
||||||
"FolderRoleMapping": [],
|
|
||||||
"SchemeOverride": "https"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# https://github.com/9p4/jellyfin-plugin-sso/issues/16#issuecomment-2953811762
|
|
||||||
custom_css=$(cat <<EOF
|
|
||||||
a.raised.emby-button,
|
|
||||||
.loginDisclaimerContainer,
|
|
||||||
.loginDisclaimer,
|
|
||||||
.manualLoginForm {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnQuick,
|
|
||||||
.btnSelectServer,
|
|
||||||
.btnForgotPassword,
|
|
||||||
a.raised.emby-button,
|
|
||||||
.emby-button.block,
|
|
||||||
.loginDisclaimerContainer,
|
|
||||||
.loginDisclaimer {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
color: inherit !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnForgotPassword {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.manualLoginForm > :not(:first-child) {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
login_disclaimer=$(cat <<EOF
|
|
||||||
<form action="https://media.karaolidis.com/sso/OID/start/authelia">
|
|
||||||
<button class="raised block emby-button button-submit">
|
|
||||||
Sign in with Authelia
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
curl -sf "$JELLYFIN_HOST/System/Configuration/branding" \
|
|
||||||
-H "Authorization: MediaBrowser Token=$token" |
|
|
||||||
jq --arg custom_css "$custom_css" \
|
|
||||||
--arg login_disclaimer "$login_disclaimer" \
|
|
||||||
'.CustomCss = $custom_css | .LoginDisclaimer = $login_disclaimer' |
|
|
||||||
curl -sf "$JELLYFIN_HOST/System/Configuration/branding" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H "Authorization: MediaBrowser Token=$token" \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
existing_libraries="$(curl -sf "$JELLYFIN_HOST/Library/VirtualFolders" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"')"
|
|
||||||
|
|
||||||
find /etc/jellyfin/libraries -name "*.json" | sort -V | while IFS= read -r filepath; do
|
|
||||||
collectionType=$(jq -rn --arg s "$(basename "$(dirname "$filepath")")" '$s|@uri')
|
|
||||||
name=$(jq -rn --arg s "$(basename "$filepath" .json)" '$s|@uri')
|
|
||||||
|
|
||||||
if echo "$existing_libraries" | jq -e --arg name "$name" 'any(.[]; .Name | @uri == $name)'; then
|
|
||||||
echo "Skipping existing virtual folder: $name"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Creating virtual folder: $name"
|
|
||||||
curl -sf "$JELLYFIN_HOST/Library/VirtualFolders?collectionType=$collectionType&name=$name" \
|
|
||||||
-X POST \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"' \
|
|
||||||
--data-binary @"$filepath"
|
|
||||||
done
|
|
@@ -15,22 +15,13 @@ let
|
|||||||
hmConfig = config.home-manager.users.${user};
|
hmConfig = config.home-manager.users.${user};
|
||||||
inherit (hmConfig.virtualisation.quadlet) containers volumes networks;
|
inherit (hmConfig.virtualisation.quadlet) containers volumes networks;
|
||||||
arrs = radarrs ++ sonarrs;
|
arrs = radarrs ++ sonarrs;
|
||||||
autheliaClientId = "s8QyVqBdiEStH5WXeEYNSrEh8ls2xHif0qyTGbC7V8nHNcqHi5NhqHUapCHuVFT4kEtngqgLry2SKOKepQl3AiqCWlhTjlIxr7LI";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home-manager.users.${user} = {
|
home-manager.users.${user} = {
|
||||||
sops = {
|
sops = {
|
||||||
secrets = {
|
secrets."jellyseerr/smtp".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
"jellyseerr/smtp".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
"jellyseerr/authelia/password".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
"jellyseerr/authelia/digest".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
jellyseerr-env.content = ''
|
|
||||||
JELLYFIN_ADMIN_PASSWORD=${hmConfig.sops.placeholder."jellyfin/admin"}
|
|
||||||
'';
|
|
||||||
|
|
||||||
jellyseerr.content = builtins.readFile (
|
jellyseerr.content = builtins.readFile (
|
||||||
(pkgs.formats.json { }).generate "setings.json" {
|
(pkgs.formats.json { }).generate "setings.json" {
|
||||||
main = {
|
main = {
|
||||||
@@ -42,38 +33,51 @@ in
|
|||||||
# 32 | 4194304 | 67108864
|
# 32 | 4194304 | 67108864
|
||||||
defaultPermissions = 71303200;
|
defaultPermissions = 71303200;
|
||||||
localLogin = false;
|
localLogin = false;
|
||||||
mediaServerLogin = false;
|
mediaServerLogin = true;
|
||||||
oidcLogin = true;
|
oidcLogin = false;
|
||||||
newPlexLogin = false;
|
newPlexLogin = true;
|
||||||
mediaServerType = 2;
|
mediaServerType = 1;
|
||||||
partialRequestsEnabled = true;
|
partialRequestsEnabled = true;
|
||||||
enableSpecialEpisodes = true;
|
enableSpecialEpisodes = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
jellyfin = {
|
plex = {
|
||||||
name = "jupiter";
|
name = "jupiter";
|
||||||
ip = "jellyfin";
|
ip = "beta.media.karaolidis.com";
|
||||||
port = 8096;
|
port = 443;
|
||||||
externalHostname = "https://media.karaolidis.com";
|
useSsl = true;
|
||||||
jellyfinForgotPasswordUrl = "https://id.karaolidis.com/reset-password/step1";
|
libraries = [
|
||||||
|
{
|
||||||
|
id = "1";
|
||||||
|
name = "Films";
|
||||||
|
enabled = true;
|
||||||
|
type = "movie";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = "2";
|
||||||
|
name = "Shows";
|
||||||
|
enabled = true;
|
||||||
|
type = "show";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = "3";
|
||||||
|
name = "Films (Anime)";
|
||||||
|
enabled = true;
|
||||||
|
type = "movie";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = "4";
|
||||||
|
name = "Shows (Anime)";
|
||||||
|
enabled = true;
|
||||||
|
type = "show";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
externalHostname = "https://beta.media.karaolidis.com";
|
||||||
|
webAppUrl = "https://beta.media.karaolidis.com";
|
||||||
|
machineId = hmConfig.sops.placeholder."plex/processedMachineIdentifier";
|
||||||
};
|
};
|
||||||
|
|
||||||
oidc.providers = [
|
jellyfin = { };
|
||||||
{
|
|
||||||
slug = "authelia";
|
|
||||||
name = "Authelia";
|
|
||||||
issuerUrl = "https://id.karaolidis.com";
|
|
||||||
clientId = autheliaClientId;
|
|
||||||
clientSecret = hmConfig.sops.placeholder."jellyseerr/authelia/password";
|
|
||||||
scopes = lib.strings.concatStringsSep " " [
|
|
||||||
"openid"
|
|
||||||
"profile"
|
|
||||||
"email"
|
|
||||||
"groups"
|
|
||||||
];
|
|
||||||
newUserLogin = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
radarr = [ ];
|
radarr = [ ];
|
||||||
|
|
||||||
@@ -81,49 +85,36 @@ in
|
|||||||
|
|
||||||
public.initialized = true;
|
public.initialized = true;
|
||||||
|
|
||||||
notifications.agents.email = {
|
notifications.agents = {
|
||||||
enabled = true;
|
email = {
|
||||||
options = {
|
enabled = true;
|
||||||
emailFrom = "jupiter@karaolidis.com";
|
options = {
|
||||||
smtpHost = "smtp.protonmail.ch";
|
emailFrom = "jupiter@karaolidis.com";
|
||||||
smtpPort = 587;
|
smtpHost = "smtp.protonmail.ch";
|
||||||
authUser = "jupiter@karaolidis.com";
|
smtpPort = 587;
|
||||||
authPass = hmConfig.sops.placeholder."jellyseerr/smtp";
|
authUser = "jupiter@karaolidis.com";
|
||||||
senderName = "Jellyseerr";
|
authPass = hmConfig.sops.placeholder."jellyseerr/smtp";
|
||||||
|
senderName = "Jellyseerr";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ntfy = {
|
||||||
|
enabled = true;
|
||||||
|
embedPoster = true;
|
||||||
|
types = 2970;
|
||||||
|
options = {
|
||||||
|
url = "https://ntfy.karaolidis.com";
|
||||||
|
topic = "media";
|
||||||
|
authMethodUsernamePassword = false;
|
||||||
|
authMethodToken = true;
|
||||||
|
token = hmConfig.sops.placeholder."ntfy/tokens/jupiter/media";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
network.trustProxy = true;
|
network.trustProxy = true;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
authelia-jellyseerr.content = builtins.readFile (
|
|
||||||
(pkgs.formats.yaml { }).generate "jellyseerr.yaml" {
|
|
||||||
identity_providers.oidc = {
|
|
||||||
authorization_policies.jellyseerr = {
|
|
||||||
default_policy = "deny";
|
|
||||||
rules = [
|
|
||||||
{
|
|
||||||
policy = "one_factor";
|
|
||||||
subject = "group:jellyfin";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
clients = [
|
|
||||||
{
|
|
||||||
client_id = autheliaClientId;
|
|
||||||
client_name = "jellyseerr";
|
|
||||||
client_secret = hmConfig.sops.placeholder."jellyseerr/authelia/digest";
|
|
||||||
redirect_uris = [ "https://request.karaolidis.com/login?provider=authelia&callback=true" ];
|
|
||||||
authorization_policy = "jellyseerr";
|
|
||||||
token_endpoint_auth_method = "client_secret_post";
|
|
||||||
pre_configured_consent_duration = "1 month";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// builtins.listToAttrs (
|
// builtins.listToAttrs (
|
||||||
builtins.map (arr: {
|
builtins.map (arr: {
|
||||||
@@ -138,57 +129,49 @@ in
|
|||||||
virtualisation.quadlet = {
|
virtualisation.quadlet = {
|
||||||
volumes.jellyseerr = { };
|
volumes.jellyseerr = { };
|
||||||
|
|
||||||
containers = {
|
containers.jellyseerr = {
|
||||||
jellyseerr = {
|
containerConfig = {
|
||||||
containerConfig = {
|
image = "docker-archive:${pkgs.dockerImages.jellyseerr}";
|
||||||
image = "docker-archive:${pkgs.dockerImages.jellyseerr}";
|
networks = [
|
||||||
networks = [
|
networks.media.ref
|
||||||
networks.jellyfin.ref
|
networks.traefik.ref
|
||||||
networks.media.ref
|
];
|
||||||
networks.traefik.ref
|
volumes =
|
||||||
];
|
|
||||||
volumes =
|
|
||||||
let
|
|
||||||
preStart = pkgs.writeTextFile {
|
|
||||||
name = "pre-start.sh";
|
|
||||||
executable = true;
|
|
||||||
text = builtins.readFile ./pre-start.sh;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
[
|
|
||||||
"${preStart}:/etc/jellyseerr/pre-start.sh:ro"
|
|
||||||
"${hmConfig.sops.templates.jellyseerr.path}:/etc/jellyseerr/settings.default.json:ro"
|
|
||||||
"${volumes.jellyseerr.ref}:/var/lib/jellyseerr"
|
|
||||||
]
|
|
||||||
++ builtins.map (
|
|
||||||
radarr:
|
|
||||||
"${
|
|
||||||
hmConfig.sops.templates."jellyseerr-${radarr.hostName}".path
|
|
||||||
}:/etc/jellyseerr/apps/radarr/${radarr.hostName}.json:ro"
|
|
||||||
) radarrs
|
|
||||||
++ builtins.map (
|
|
||||||
sonarr:
|
|
||||||
"${
|
|
||||||
hmConfig.sops.templates."jellyseerr-${sonarr.hostName}".path
|
|
||||||
}:/etc/jellyseerr/apps/sonarr/${sonarr.hostName}.json:ro"
|
|
||||||
) sonarrs;
|
|
||||||
environmentFiles = [ hmConfig.sops.templates.jellyseerr-env.path ];
|
|
||||||
labels = [
|
|
||||||
"traefik.enable=true"
|
|
||||||
"traefik.http.routers.jellyseerr.rule=Host(`request.karaolidis.com`)"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
unitConfig.After =
|
|
||||||
let
|
let
|
||||||
arrServices = builtins.map (arr: "${containers.${arr.hostName}._serviceName}.service") arrs;
|
preStart = pkgs.writeTextFile {
|
||||||
|
name = "pre-start.sh";
|
||||||
|
executable = true;
|
||||||
|
text = builtins.readFile ./pre-start.sh;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
[ "sops-nix.service" ] ++ arrServices;
|
[
|
||||||
|
"${preStart}:/etc/jellyseerr/pre-start.sh:ro"
|
||||||
|
"${hmConfig.sops.templates.jellyseerr.path}:/etc/jellyseerr/settings.default.json:ro"
|
||||||
|
"${volumes.jellyseerr.ref}:/var/lib/jellyseerr"
|
||||||
|
]
|
||||||
|
++ builtins.map (
|
||||||
|
radarr:
|
||||||
|
"${
|
||||||
|
hmConfig.sops.templates."jellyseerr-${radarr.hostName}".path
|
||||||
|
}:/etc/jellyseerr/apps/radarr/${radarr.hostName}.json:ro"
|
||||||
|
) radarrs
|
||||||
|
++ builtins.map (
|
||||||
|
sonarr:
|
||||||
|
"${
|
||||||
|
hmConfig.sops.templates."jellyseerr-${sonarr.hostName}".path
|
||||||
|
}:/etc/jellyseerr/apps/sonarr/${sonarr.hostName}.json:ro"
|
||||||
|
) sonarrs;
|
||||||
|
labels = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.jellyseerr.rule=Host(`request.karaolidis.com`)"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
authelia.containerConfig.volumes = [
|
unitConfig.After =
|
||||||
"${hmConfig.sops.templates.authelia-jellyseerr.path}:/etc/authelia/conf.d/jellyseerr.yaml:ro"
|
let
|
||||||
];
|
arrServices = builtins.map (arr: "${containers.${arr.hostName}._serviceName}.service") arrs;
|
||||||
|
in
|
||||||
|
[ "sops-nix.service" ] ++ arrServices;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -1,59 +1,5 @@
|
|||||||
# shellcheck shell=sh
|
# shellcheck shell=sh
|
||||||
|
|
||||||
JELLYFIN_HOST="${JELLYFIN_HOST:-http://jellyfin:8096}"
|
|
||||||
JELLYFIN_ADMIN_USERNAME="${JELLYFIN_ADMIN_USERNAME:-admin}"
|
|
||||||
|
|
||||||
until public="$(curl -sf "$JELLYFIN_HOST/System/Info/Public")"; do
|
|
||||||
echo "Waiting for Jellyfin to be ready..."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
until [ "$(echo "$public" | jq -r '.StartupWizardCompleted')" = "true" ]; do
|
|
||||||
echo "Waiting for Jellyfin setup wizard to finish..."
|
|
||||||
sleep 1
|
|
||||||
public="$(curl -sf "${JELLYFIN_HOST}/System/Info/Public")"
|
|
||||||
done
|
|
||||||
|
|
||||||
token="$(curl -sf "$JELLYFIN_HOST/Users/AuthenticateByName" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-H 'Authorization: MediaBrowser Client="jellyseerr-init", Device="sh", DeviceId="sh", Version="1.0"' \
|
|
||||||
--data-raw '{"Username":"'"$JELLYFIN_ADMIN_USERNAME"'","Pw":"'"$JELLYFIN_ADMIN_PASSWORD"'"}' \
|
|
||||||
| jq -r '.AccessToken')"
|
|
||||||
|
|
||||||
keys="$(curl -sf "$JELLYFIN_HOST/Auth/Keys" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"')"
|
|
||||||
|
|
||||||
jellyseerr_key="$(echo "$keys" | jq -r '.Items[] | select(.AppName=="Jellyseerr") | .AccessToken')"
|
|
||||||
|
|
||||||
if [ -z "$jellyseerr_key" ] || [ "$jellyseerr_key" = "null" ]; then
|
|
||||||
curl -sf "$JELLYFIN_HOST/Auth/Keys?App=Jellyseerr" \
|
|
||||||
-X POST \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"'
|
|
||||||
|
|
||||||
keys="$(curl -sf "$JELLYFIN_HOST/Auth/Keys" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"')"
|
|
||||||
|
|
||||||
jellyseerr_key="$(echo "$keys" | jq -r '.Items[] | select(.AppName=="Jellyseerr") | .AccessToken')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
serverId="$(echo "$public" | jq -r '.Id')"
|
|
||||||
|
|
||||||
libraries="$(curl -sf "$JELLYFIN_HOST/Library/VirtualFolders" \
|
|
||||||
-H 'Authorization: MediaBrowser Token="'"$token"'"')"
|
|
||||||
|
|
||||||
libraries="$(
|
|
||||||
echo "$libraries" | jq '[
|
|
||||||
.[]
|
|
||||||
| {
|
|
||||||
id: .ItemId,
|
|
||||||
name: .Name,
|
|
||||||
enabled: .LibraryOptions.Enabled,
|
|
||||||
type: ( .CollectionType | if . == "movies" then "movie" elif . == "tvshows" then "show" else . end )
|
|
||||||
}
|
|
||||||
]'
|
|
||||||
)"
|
|
||||||
|
|
||||||
try_forever() {
|
try_forever() {
|
||||||
until "$@" 2>&1; do
|
until "$@" 2>&1; do
|
||||||
echo "Try failed: $* - retrying in 1s"
|
echo "Try failed: $* - retrying in 1s"
|
||||||
@@ -129,15 +75,9 @@ done
|
|||||||
|
|
||||||
tmpfile=$(mktemp)
|
tmpfile=$(mktemp)
|
||||||
jq -s \
|
jq -s \
|
||||||
--argjson libs "$libraries" \
|
|
||||||
--argjson radarr "$radarr_json" \
|
--argjson radarr "$radarr_json" \
|
||||||
--argjson sonarr "$sonarr_json" \
|
--argjson sonarr "$sonarr_json" \
|
||||||
--arg serverId "$serverId" \
|
|
||||||
--arg apiKey "$jellyseerr_key" \
|
|
||||||
'.[0] * .[1]
|
'.[0] * .[1]
|
||||||
| .jellyfin.serverId = $serverId
|
|
||||||
| .jellyfin.apiKey = $apiKey
|
|
||||||
| .jellyfin.libraries = $libs
|
|
||||||
| .radarr = $radarr
|
| .radarr = $radarr
|
||||||
| .sonarr = $sonarr' \
|
| .sonarr = $sonarr' \
|
||||||
/var/lib/jellyseerr/settings.json \
|
/var/lib/jellyseerr/settings.json \
|
||||||
|
@@ -0,0 +1,109 @@
|
|||||||
|
{ user, home }:
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
hmConfig = config.home-manager.users.${user};
|
||||||
|
inherit (hmConfig.virtualisation.quadlet) volumes networks;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ 32400 ];
|
||||||
|
|
||||||
|
home-manager.users.${user} = {
|
||||||
|
sops = {
|
||||||
|
secrets = {
|
||||||
|
"plex/machineIdentifier".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"plex/processedMachineIdentifier".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"plex/anonymousMachineIdentifier".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"plex/certificateUuid".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"plex/plexOnlineToken".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
};
|
||||||
|
|
||||||
|
templates.plex.content = ''
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Preferences
|
||||||
|
MachineIdentifier="${hmConfig.sops.placeholder."plex/machineIdentifier"}"
|
||||||
|
ProcessedMachineIdentifier="${hmConfig.sops.placeholder."plex/processedMachineIdentifier"}"
|
||||||
|
AnonymousMachineIdentifier="${hmConfig.sops.placeholder."plex/anonymousMachineIdentifier"}"
|
||||||
|
CertificateUUID="${hmConfig.sops.placeholder."plex/certificateUuid"}"
|
||||||
|
PlexOnlineToken="${hmConfig.sops.placeholder."plex/plexOnlineToken"}"
|
||||||
|
FriendlyName="jupiter"
|
||||||
|
PlexOnlineUsername="karaolidis"
|
||||||
|
PlexOnlineMail="nick@karaolidis.com"
|
||||||
|
PlexOnlineHome="1"
|
||||||
|
PublishServerOnPlexOnlineKey="1"
|
||||||
|
AcceptedEULA="1"
|
||||||
|
DlnaEnabled="0"
|
||||||
|
customConnections="https://beta.media.karaolidis.com:443"
|
||||||
|
secureConnections="1"
|
||||||
|
IPNetworkType="v4only"
|
||||||
|
PushNotificationsEnabled="1"
|
||||||
|
logDebug="0"
|
||||||
|
sendCrashReports="0"
|
||||||
|
WanTotalMaxUploadRate="1000000"
|
||||||
|
GdmEnabled="0"
|
||||||
|
RelayEnabled="0"
|
||||||
|
FSEventLibraryPartialScanEnabled="1"
|
||||||
|
FSEventLibraryUpdatesEnabled="1"
|
||||||
|
GenerateAdMarkerBehavior="asap"
|
||||||
|
GenerateBIFBehavior="asap"
|
||||||
|
GenerateChapterThumbBehavior="asap"
|
||||||
|
GenerateVADBehavior="asap"
|
||||||
|
LoudnessAnalysisBehavior="asap"
|
||||||
|
MusicAnalysisBehavior="asap"
|
||||||
|
ScheduledLibraryUpdatesEnabled="1"
|
||||||
|
watchMusicSections="1"
|
||||||
|
HardwareDevicePath="10de:24dd:17aa:3a54@0000:01:00.0"
|
||||||
|
OptimizerTranscodeCountLimit="0"
|
||||||
|
ButlerTaskRefreshLibraries="1"
|
||||||
|
CinemaTrailersFromBluRay="1"
|
||||||
|
CinemaTrailersFromTheater="1"
|
||||||
|
CinemaTrailersType="0"
|
||||||
|
/>
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.quadlet = {
|
||||||
|
networks.plex = { };
|
||||||
|
|
||||||
|
volumes.plex = { };
|
||||||
|
|
||||||
|
containers.plex = {
|
||||||
|
containerConfig = {
|
||||||
|
image = "docker-archive:${pkgs.dockerImages.plex}";
|
||||||
|
networks = [
|
||||||
|
networks.plex.ref
|
||||||
|
networks.traefik.ref
|
||||||
|
];
|
||||||
|
volumes =
|
||||||
|
let
|
||||||
|
postStart = pkgs.writeTextFile {
|
||||||
|
name = "post-start.sh";
|
||||||
|
executable = true;
|
||||||
|
text = builtins.readFile ./post-start.sh;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
[
|
||||||
|
"${hmConfig.sops.templates.plex.path}:/etc/plex/Preferences.xml:ro"
|
||||||
|
"${postStart}:/etc/plex/post-start.sh:ro"
|
||||||
|
"/mnt/storage/private/storm/containers/storage/volumes/media/_data:/var/lib/media"
|
||||||
|
"${volumes.plex.ref}:/var/lib/plex"
|
||||||
|
];
|
||||||
|
labels = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.plex.rule=Host(`beta.media.karaolidis.com`)"
|
||||||
|
];
|
||||||
|
podmanArgs = [ "--cdi-spec-dir=/run/cdi" ];
|
||||||
|
devices = [ "nvidia.com/gpu=all" ];
|
||||||
|
addCapabilities = [ "SYS_ADMIN" ];
|
||||||
|
publishPorts = [ "32400:32400/tcp" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig.After = [ "sops-nix.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -0,0 +1,112 @@
|
|||||||
|
# shellcheck shell=sh
|
||||||
|
|
||||||
|
HOST="http://localhost:32400"
|
||||||
|
TOKEN="$(getPref "PlexOnlineToken")"
|
||||||
|
|
||||||
|
try_forever() {
|
||||||
|
until "$@" 2>&1; do
|
||||||
|
echo "Try failed: $* - retrying in 1s"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_api() {
|
||||||
|
try_forever curl -sf -H "X-Plex-Token: $TOKEN" "$HOST/identity"
|
||||||
|
echo "API is up!"
|
||||||
|
}
|
||||||
|
|
||||||
|
call() {
|
||||||
|
method="$1"
|
||||||
|
path="$2"
|
||||||
|
params="${3:-}"
|
||||||
|
|
||||||
|
curl -sf \
|
||||||
|
-X "$method" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "X-Plex-Token: $TOKEN" \
|
||||||
|
"$HOST/$path?$params"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_resources() {
|
||||||
|
endpoint="$1"
|
||||||
|
call GET "$endpoint" | jq -r '.MediaContainer.Directory // []'
|
||||||
|
}
|
||||||
|
|
||||||
|
get_resource_id() {
|
||||||
|
endpoint="$1"
|
||||||
|
ident_field="$2"
|
||||||
|
name="$3"
|
||||||
|
|
||||||
|
get_resources "$endpoint" | jq -r --arg field "$ident_field" --arg name "$name" '.[] | select(.[$field] == $name) | .key // empty'
|
||||||
|
}
|
||||||
|
|
||||||
|
upsert_resource() {
|
||||||
|
endpoint="$1"
|
||||||
|
ident_field="$2"
|
||||||
|
name="$3"
|
||||||
|
params="$4"
|
||||||
|
|
||||||
|
id="$(get_resource_id "$endpoint" "$ident_field" "$name")"
|
||||||
|
|
||||||
|
if [ -n "$id" ] && [ "$id" != "null" ]; then
|
||||||
|
echo "Updating library '$name' (id=$id)"
|
||||||
|
call PUT "$endpoint/$id" "$params"
|
||||||
|
else
|
||||||
|
echo "Creating library '$name'"
|
||||||
|
call POST "$endpoint" "$params"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prune_resources() {
|
||||||
|
endpoint="$1"
|
||||||
|
ident_field="$2"
|
||||||
|
|
||||||
|
shift 2
|
||||||
|
|
||||||
|
keep_list="$(printf '%s\n' "$@" | jq -R . | jq -s .)"
|
||||||
|
resources="$(get_resources "$endpoint")"
|
||||||
|
|
||||||
|
printf '%s' "$resources" | jq -c '.[]' | while IFS= read -r library; do
|
||||||
|
name="$(printf '%s' "$library" | jq -r --arg field "$ident_field" '.[$field]')"
|
||||||
|
id="$(printf '%s' "$library" | jq -r '.key')"
|
||||||
|
found="$(printf '%s' "$keep_list" | jq -r --arg name "$name" 'index($name)')"
|
||||||
|
|
||||||
|
if [ "$found" = "null" ]; then
|
||||||
|
echo "Deleting extra library '$name' (id=$id)"
|
||||||
|
call DELETE "$endpoint/$id" || echo "failed to delete $name, continuing"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
build_films_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
name=Films&type=movie&agent=tv.plex.agents.movie&scanner=Plex%20Movie&language=en-US&location=%2Fvar%2Flib%2Fmedia%2Flibraries%2Ffilms&prefs%5BuseRedbandTrailers%5D=1&prefs%5BincludeAdultContent%5D=1&prefs%5BautoCollectionThreshold%5D=2&prefs%5BcollectionMode%5D=1&prefs%5BenableAdMarkerGeneration%5D=2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
build_shows_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
name=Shows&type=show&agent=tv.plex.agents.series&scanner=Plex%20TV%20Series&language=en-US&location=%2Fvar%2Flib%2Fmedia%2Flibraries%2Fshows&prefs%5BshowOrdering%5D=aired&prefs%5BuseSeasonTitles%5D=1&prefs%5BuseRedbandTrailers%5D=1&prefs%5BincludeAdultContent%5D=1&prefs%5BcollectionMode%5D=1&prefs%5BenableAdMarkerGeneration%5D=2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
build_anime_films_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
name=Films%20%28Anime%29&type=movie&agent=tv.plex.agents.movie&scanner=Plex%20Movie&language=en-US&location=%2Fvar%2Flib%2Fmedia%2Flibraries%2Fanime%2Ffilms&prefs%5Bcountry%5D=JP&prefs%5BuseRedbandTrailers%5D=1&prefs%5BincludeAdultContent%5D=1&prefs%5BautoCollectionThreshold%5D=2&prefs%5BcollectionMode%5D=1&prefs%5BenableAdMarkerGeneration%5D=2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
build_anime_shows_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
name=Shows%20%28Anime%29&type=show&agent=tv.plex.agents.series&scanner=Plex%20TV%20Series&language=en-US&location=%2Fvar%2Flib%2Fmedia%2Flibraries%2Fanime%2Fshows&prefs%5Bcountry%5D=JP&prefs%5BshowOrdering%5D=aired&prefs%5BuseSeasonTitles%5D=1&prefs%5BuseRedbandTrailers%5D=1&prefs%5BincludeAdultContent%5D=1&prefs%5BcollectionMode%5D=1&prefs%5BenableAdMarkerGeneration%5D=2
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_api
|
||||||
|
|
||||||
|
try_forever upsert_resource "library/sections" "title" "Films" "$(build_films_payload)"
|
||||||
|
try_forever upsert_resource "library/sections" "title" "Shows" "$(build_shows_payload)"
|
||||||
|
try_forever upsert_resource "library/sections" "title" "Films (Anime)" "$(build_anime_films_payload)"
|
||||||
|
try_forever upsert_resource "library/sections" "title" "Shows (Anime)" "$(build_anime_shows_payload)"
|
||||||
|
|
||||||
|
prune_resources "library/sections" "title" "Films" "Shows" "Films (Anime)" "Shows (Anime)"
|
@@ -23,6 +23,7 @@ in
|
|||||||
templates = {
|
templates = {
|
||||||
prowlarr-env.content = ''
|
prowlarr-env.content = ''
|
||||||
API_KEY=${hmConfig.sops.placeholder."prowlarr/apiKey"}
|
API_KEY=${hmConfig.sops.placeholder."prowlarr/apiKey"}
|
||||||
|
NTFY_TOKEN=${hmConfig.sops.placeholder."ntfy/tokens/jupiter/media"}
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
// builtins.listToAttrs (
|
// builtins.listToAttrs (
|
||||||
@@ -77,7 +78,7 @@ in
|
|||||||
environmentFiles = [ hmConfig.sops.templates.prowlarr-env.path ];
|
environmentFiles = [ hmConfig.sops.templates.prowlarr-env.path ];
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.prowlarr.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/indexers`)"
|
"traefik.http.routers.prowlarr.rule=Host(`beta.media.karaolidis.com`) && PathPrefix(`/manage/indexers`)"
|
||||||
"traefik.http.routers.prowlarr.middlewares=authelia@docker"
|
"traefik.http.routers.prowlarr.middlewares=authelia@docker"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -205,8 +205,34 @@ build_cardigann_indexer_payload() {
|
|||||||
'
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_ntfy_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
{
|
||||||
|
"onGrab": false,
|
||||||
|
"onHealthIssue": true,
|
||||||
|
"onHealthRestored": true,
|
||||||
|
"onApplicationUpdate": false,
|
||||||
|
"includeManualGrabs": false,
|
||||||
|
"includeHealthWarnings": false,
|
||||||
|
"name": "ntfy.sh",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "serverUrl", "value": "https://ntfy.karaolidis.com" },
|
||||||
|
{ "name": "accessToken", "value": "$NTFY_TOKEN" },
|
||||||
|
{ "name": "topics", "value": "media" },
|
||||||
|
{ "name": "priority", "value": 3 },
|
||||||
|
{ "name": "tags", "value": "satellite" },
|
||||||
|
],
|
||||||
|
"implementation": "Ntfy",
|
||||||
|
"configContract": "NtfySettings"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
wait_for_api
|
wait_for_api
|
||||||
|
|
||||||
|
try_forever upsert_resource "notification" "name" "ntfy.sh" "$(build_ntfy_payload)"
|
||||||
|
prune_resources "notification" "name" "ntfy.sh"
|
||||||
|
|
||||||
try_forever upsert_resource "downloadclient" "name" "Transmission" "$(build_transmission_payload)"
|
try_forever upsert_resource "downloadclient" "name" "Transmission" "$(build_transmission_payload)"
|
||||||
prune_resources "downloadclient" "name" "Transmission"
|
prune_resources "downloadclient" "name" "Transmission"
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@ rec {
|
|||||||
activeDirectory = "/var/lib/media/libraries${mediaFolderBase}";
|
activeDirectory = "/var/lib/media/libraries${mediaFolderBase}";
|
||||||
minimumAvailability = "released";
|
minimumAvailability = "released";
|
||||||
isDefault = !isAnime;
|
isDefault = !isAnime;
|
||||||
externalUrl = "https://media.karaolidis.com${urlBase}";
|
externalUrl = "https://beta.media.karaolidis.com${urlBase}";
|
||||||
syncEnabled = true;
|
syncEnabled = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ rec {
|
|||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/radarr/templates/anime-radarr.yml
|
||||||
recyclarrConfig = mkRecyclarrConfig {
|
recyclarrConfig = mkRecyclarrConfig {
|
||||||
inherit hostName port urlBase;
|
inherit hostName port urlBase;
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ rec {
|
|||||||
|
|
||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/radarr/templates/uhd-bluray-web.yml
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
include = [
|
include = [
|
||||||
{ template = "radarr-quality-definition-movie"; }
|
{ template = "radarr-quality-definition-movie"; }
|
||||||
@@ -72,9 +73,9 @@ rec {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
trash_ids = [
|
trash_ids = [
|
||||||
"923b6abef9b17f937fab56cfcf89e1f1" # DV (WEBDL)
|
"923b6abef9b17f937fab56cfcf89e1f1" # DV (w/o HDR fallback)
|
||||||
"b17886cb4158d9fea189859409975758" # HDR10Plus Boost
|
"b337d6812e06c200ec9a2d3cfa9d20a7" # DV Boost
|
||||||
"55a5b50cb416dea5a50c4955896217ab" # DV HDR10+ Boost
|
"caa37d0df9c348912df1fb1d88f9273a" # HDR10+ Boost
|
||||||
];
|
];
|
||||||
assign_scores_to = [ { name = "UHD Bluray + WEB"; } ];
|
assign_scores_to = [ { name = "UHD Bluray + WEB"; } ];
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ rec {
|
|||||||
|
|
||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/radarr/templates/hd-bluray-web.yml
|
||||||
extraConfig = {
|
extraConfig = {
|
||||||
include = [
|
include = [
|
||||||
{ template = "radarr-quality-definition-movie"; }
|
{ template = "radarr-quality-definition-movie"; }
|
||||||
|
@@ -28,6 +28,7 @@ in
|
|||||||
name = "${radarr.hostName}-env";
|
name = "${radarr.hostName}-env";
|
||||||
value.content = ''
|
value.content = ''
|
||||||
API_KEY=${hmConfig.sops.placeholder."${radarr.hostName}/apiKey"}
|
API_KEY=${hmConfig.sops.placeholder."${radarr.hostName}/apiKey"}
|
||||||
|
NTFY_TOKEN=${hmConfig.sops.placeholder."ntfy/tokens/jupiter/media"}
|
||||||
'';
|
'';
|
||||||
}) radarrs
|
}) radarrs
|
||||||
);
|
);
|
||||||
@@ -81,7 +82,7 @@ in
|
|||||||
environmentFiles = [ hmConfig.sops.templates."${radarr.hostName}-env".path ];
|
environmentFiles = [ hmConfig.sops.templates."${radarr.hostName}-env".path ];
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.${radarr.hostName}.rule=Host(`media.karaolidis.com`) && PathPrefix(`${radarr.urlBase}`)"
|
"traefik.http.routers.${radarr.hostName}.rule=Host(`beta.media.karaolidis.com`) && PathPrefix(`${radarr.urlBase}`)"
|
||||||
"traefik.http.routers.${radarr.hostName}.middlewares=authelia@docker"
|
"traefik.http.routers.${radarr.hostName}.middlewares=authelia@docker"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -146,8 +146,41 @@ build_rootfolder_payload() {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_ntfy_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
{
|
||||||
|
"onGrab": true,
|
||||||
|
"onDownload": true,
|
||||||
|
"onUpgrade": true,
|
||||||
|
"onRename": false,
|
||||||
|
"onMovieAdded": true,
|
||||||
|
"onMovieDelete": true,
|
||||||
|
"onMovieFileDelete": true,
|
||||||
|
"onMovieFileDeleteForUpgrade": false,
|
||||||
|
"onHealthIssue": true,
|
||||||
|
"includeHealthWarnings": false,
|
||||||
|
"onHealthRestored": true,
|
||||||
|
"onApplicationUpdate": false,
|
||||||
|
"onManualInteractionRequired": true,
|
||||||
|
"name": "ntfy.sh",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "serverUrl", "value": "https://ntfy.karaolidis.com" },
|
||||||
|
{ "name": "accessToken", "value": "$NTFY_TOKEN" },
|
||||||
|
{ "name": "priority", "value": 2 },
|
||||||
|
{ "name": "topics", "value": ["media"] },
|
||||||
|
{ "name": "tags", "value": ["clapper"] }
|
||||||
|
],
|
||||||
|
"implementation": "Ntfy",
|
||||||
|
"configContract": "NtfySettings"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
wait_for_api
|
wait_for_api
|
||||||
|
|
||||||
|
try_forever upsert_resource "notification" "name" "ntfy.sh" "$(build_ntfy_payload)"
|
||||||
|
prune_resources "notification" "name" "ntfy.sh"
|
||||||
|
|
||||||
if [ -n "$ROOT_FOLDER" ]; then
|
if [ -n "$ROOT_FOLDER" ]; then
|
||||||
insert_or_skip_resource "rootfolder" "path" "$ROOT_FOLDER" "$(build_rootfolder_payload)"
|
insert_or_skip_resource "rootfolder" "path" "$ROOT_FOLDER" "$(build_rootfolder_payload)"
|
||||||
prune_resources "rootfolder" "path" "$ROOT_FOLDER"
|
prune_resources "rootfolder" "path" "$ROOT_FOLDER"
|
||||||
|
@@ -85,7 +85,7 @@ rec {
|
|||||||
activeAnimeDirectory = "/var/lib/media/libraries${mediaFolderBase}";
|
activeAnimeDirectory = "/var/lib/media/libraries${mediaFolderBase}";
|
||||||
isDefault = !isAnime;
|
isDefault = !isAnime;
|
||||||
enableSeasonFolders = true;
|
enableSeasonFolders = true;
|
||||||
externalUrl = "https://media.karaolidis.com${urlBase}";
|
externalUrl = "https://beta.media.karaolidis.com${urlBase}";
|
||||||
syncEnabled = true;
|
syncEnabled = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ rec {
|
|||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/sonarr/templates/anime-sonarr-v4.yml
|
||||||
recyclarrConfig = mkRecyclarrConfig {
|
recyclarrConfig = mkRecyclarrConfig {
|
||||||
inherit hostName port urlBase;
|
inherit hostName port urlBase;
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ rec {
|
|||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/sonarr/templates/web-2160p-v4.yml
|
||||||
recyclarrConfig = mkRecyclarrConfig {
|
recyclarrConfig = mkRecyclarrConfig {
|
||||||
inherit hostName port urlBase;
|
inherit hostName port urlBase;
|
||||||
|
|
||||||
@@ -35,9 +36,9 @@ rec {
|
|||||||
custom_formats = [
|
custom_formats = [
|
||||||
{
|
{
|
||||||
trash_ids = [
|
trash_ids = [
|
||||||
"9b27ab6498ec0f31a3353992e19434ca" # DV (WEBDL)
|
"9b27ab6498ec0f31a3353992e19434ca" # DV (w/o HDR fallback)
|
||||||
"0dad0a507451acddd754fe6dc3a7f5e7" # HDR10+ Boost
|
"0c4b99df9206d2cfac3c05ab897dd62a" # HDR10+ Boost
|
||||||
"385e9e8581d33133c3961bdcdeffb7b4" # DV HDR10+ Boost
|
"7c3a61a9c6cb04f52f1544be6d44a026" # DV Boost
|
||||||
];
|
];
|
||||||
assign_scores_to = [ { name = "WEB-2160p"; } ];
|
assign_scores_to = [ { name = "WEB-2160p"; } ];
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ rec {
|
|||||||
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
apiKey = hmConfig.sops.placeholder."${hostName}/apiKey";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/recyclarr/config-templates/blob/master/sonarr/templates/web-1080p-v4.yml
|
||||||
recyclarrConfig = mkRecyclarrConfig {
|
recyclarrConfig = mkRecyclarrConfig {
|
||||||
inherit hostName port urlBase;
|
inherit hostName port urlBase;
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ in
|
|||||||
name = "${sonarr.hostName}-env";
|
name = "${sonarr.hostName}-env";
|
||||||
value.content = ''
|
value.content = ''
|
||||||
API_KEY=${hmConfig.sops.placeholder."${sonarr.hostName}/apiKey"}
|
API_KEY=${hmConfig.sops.placeholder."${sonarr.hostName}/apiKey"}
|
||||||
|
NTFY_TOKEN=${hmConfig.sops.placeholder."ntfy/tokens/jupiter/media"}
|
||||||
'';
|
'';
|
||||||
}) sonarrs
|
}) sonarrs
|
||||||
);
|
);
|
||||||
@@ -81,7 +82,7 @@ in
|
|||||||
environmentFiles = [ hmConfig.sops.templates."${sonarr.hostName}-env".path ];
|
environmentFiles = [ hmConfig.sops.templates."${sonarr.hostName}-env".path ];
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.${sonarr.hostName}.rule=Host(`media.karaolidis.com`) && PathPrefix(`${sonarr.urlBase}`)"
|
"traefik.http.routers.${sonarr.hostName}.rule=Host(`beta.media.karaolidis.com`) && PathPrefix(`${sonarr.urlBase}`)"
|
||||||
"traefik.http.routers.${sonarr.hostName}.middlewares=authelia@docker"
|
"traefik.http.routers.${sonarr.hostName}.middlewares=authelia@docker"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -146,8 +146,42 @@ build_rootfolder_payload() {
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_ntfy_payload() {
|
||||||
|
cat <<-EOF
|
||||||
|
{
|
||||||
|
"onGrab": true,
|
||||||
|
"onDownload": true,
|
||||||
|
"onUpgrade": true,
|
||||||
|
"onImportComplete": false,
|
||||||
|
"onRename": false,
|
||||||
|
"onSeriesAdd": true,
|
||||||
|
"onSeriesDelete": true,
|
||||||
|
"onEpisodeFileDelete": true,
|
||||||
|
"onEpisodeFileDeleteForUpgrade": false,
|
||||||
|
"onHealthIssue": true,
|
||||||
|
"includeHealthWarnings": false,
|
||||||
|
"onHealthRestored": true,
|
||||||
|
"onApplicationUpdate": false,
|
||||||
|
"onManualInteractionRequired": true,
|
||||||
|
"name": "ntfy.sh",
|
||||||
|
"fields": [
|
||||||
|
{ "name": "serverUrl", "value": "https://ntfy.karaolidis.com" },
|
||||||
|
{ "name": "accessToken", "value": "$NTFY_TOKEN" },
|
||||||
|
{ "name": "priority", "value": 2 },
|
||||||
|
{ "name": "topics", "value": ["media"] },
|
||||||
|
{ "name": "tags", "value": ["tv"] }
|
||||||
|
],
|
||||||
|
"implementation": "Ntfy",
|
||||||
|
"configContract": "NtfySettings"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
wait_for_api
|
wait_for_api
|
||||||
|
|
||||||
|
try_forever upsert_resource "notification" "name" "ntfy.sh" "$(build_ntfy_payload)"
|
||||||
|
prune_resources "notification" "name" "ntfy.sh"
|
||||||
|
|
||||||
if [ -n "$ROOT_FOLDER" ]; then
|
if [ -n "$ROOT_FOLDER" ]; then
|
||||||
insert_or_skip_resource "rootfolder" "path" "$ROOT_FOLDER" "$(build_rootfolder_payload)"
|
insert_or_skip_resource "rootfolder" "path" "$ROOT_FOLDER" "$(build_rootfolder_payload)"
|
||||||
prune_resources "rootfolder" "path" "$ROOT_FOLDER"
|
prune_resources "rootfolder" "path" "$ROOT_FOLDER"
|
||||||
|
@@ -33,8 +33,7 @@ in
|
|||||||
volumes =
|
volumes =
|
||||||
let
|
let
|
||||||
config = (pkgs.formats.json { }).generate "settings.override.json" {
|
config = (pkgs.formats.json { }).generate "settings.override.json" {
|
||||||
ratio-limit-enabled = true;
|
ratio-limit-enabled = false;
|
||||||
ratio-limit = 5;
|
|
||||||
download-queue-enabled = false;
|
download-queue-enabled = false;
|
||||||
peer-limit-per-torrent = 100;
|
peer-limit-per-torrent = 100;
|
||||||
peer-limit-global = 1000;
|
peer-limit-global = 1000;
|
||||||
@@ -50,12 +49,12 @@ in
|
|||||||
"/mnt/storage/private/storm/containers/storage/volumes/media/_data:/var/lib/media"
|
"/mnt/storage/private/storm/containers/storage/volumes/media/_data:/var/lib/media"
|
||||||
];
|
];
|
||||||
environments = {
|
environments = {
|
||||||
WIREGUARD_PUBLIC_KEY = "zctOjv4DH2gzXtLQy86Tp0vnT+PNpMsxecd2vUX/i0U=";
|
WIREGUARD_PUBLIC_KEY = "jSrxQTLrvNPkljpa+F0OZT53mgTTwQA65oTMkqf382A=";
|
||||||
WIREGUARD_ENDPOINT = "146.70.179.50:51820";
|
WIREGUARD_ENDPOINT = "46.29.25.4:51820";
|
||||||
};
|
};
|
||||||
labels = [
|
labels = [
|
||||||
"traefik.enable=true"
|
"traefik.enable=true"
|
||||||
"traefik.http.routers.transmission.rule=Host(`media.karaolidis.com`) && PathPrefix(`/manage/torrents`)"
|
"traefik.http.routers.transmission.rule=Host(`beta.media.karaolidis.com`) && PathPrefix(`/manage/torrents`)"
|
||||||
"traefik.http.routers.transmission.middlewares=authelia@docker"
|
"traefik.http.routers.transmission.middlewares=authelia@docker"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -137,7 +137,7 @@ in
|
|||||||
"groups"
|
"groups"
|
||||||
"is_admin"
|
"is_admin"
|
||||||
];
|
];
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -17,6 +17,9 @@ in
|
|||||||
"ntfy/webPush/publicKey".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"ntfy/webPush/publicKey".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
"ntfy/webPush/privateKey".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"ntfy/webPush/privateKey".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
"ntfy/users/karaolidis".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
"ntfy/users/karaolidis".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"ntfy/users/jupiter".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"ntfy/tokens/jupiter/grafana".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
|
"ntfy/tokens/jupiter/media".sopsFile = "${inputs.secrets}/hosts/jupiter/secrets.yaml";
|
||||||
};
|
};
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
@@ -43,7 +46,20 @@ in
|
|||||||
auth-default-access = "deny-all";
|
auth-default-access = "deny-all";
|
||||||
auth-startup-queries = dbStartupQueries;
|
auth-startup-queries = dbStartupQueries;
|
||||||
|
|
||||||
auth-users = [ "karaolidis:${hmConfig.sops.placeholder."ntfy/users/karaolidis"}:admin" ];
|
auth-users = [
|
||||||
|
"jupiter:${hmConfig.sops.placeholder."ntfy/users/jupiter"}:user"
|
||||||
|
"karaolidis:${hmConfig.sops.placeholder."ntfy/users/karaolidis"}:admin"
|
||||||
|
];
|
||||||
|
|
||||||
|
auth-access = [
|
||||||
|
"jupiter:grafana:wo"
|
||||||
|
"jupiter:media:wo"
|
||||||
|
];
|
||||||
|
|
||||||
|
auth-tokens = [
|
||||||
|
"jupiter:${hmConfig.sops.placeholder."ntfy/tokens/jupiter/grafana"}"
|
||||||
|
"jupiter:${hmConfig.sops.placeholder."ntfy/tokens/jupiter/media"}"
|
||||||
|
];
|
||||||
|
|
||||||
behind-proxy = true;
|
behind-proxy = true;
|
||||||
|
|
||||||
|
@@ -65,7 +65,7 @@ in
|
|||||||
];
|
];
|
||||||
response_types = [ "code" ];
|
response_types = [ "code" ];
|
||||||
token_endpoint_auth_method = "client_secret_post";
|
token_endpoint_auth_method = "client_secret_post";
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -10,16 +10,10 @@ let
|
|||||||
inherit (hmConfig.virtualisation.quadlet) networks volumes containers;
|
inherit (hmConfig.virtualisation.quadlet) networks volumes containers;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
networking.firewall = {
|
networking.firewall.allowedTCPPorts = [
|
||||||
allowedTCPPorts = [
|
80
|
||||||
80
|
443
|
||||||
443
|
];
|
||||||
];
|
|
||||||
allowedUDPPorts = [
|
|
||||||
80
|
|
||||||
443
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users.${user} = {
|
home-manager.users.${user} = {
|
||||||
sops = {
|
sops = {
|
||||||
@@ -76,7 +70,7 @@ in
|
|||||||
"--entrypoints.https.http.tls=true"
|
"--entrypoints.https.http.tls=true"
|
||||||
"--entrypoints.https.http.tls.certResolver=letsencrypt"
|
"--entrypoints.https.http.tls.certResolver=letsencrypt"
|
||||||
"--entrypoints.https.http.tls.domains[0].main=karaolidis.com"
|
"--entrypoints.https.http.tls.domains[0].main=karaolidis.com"
|
||||||
"--entrypoints.https.http.tls.domains[0].sans=*.karaolidis.com,*.tunnel.karaolidis.com,*.gaming.karaolidis.com"
|
"--entrypoints.https.http.tls.domains[0].sans=*.karaolidis.com,*.tunnel.karaolidis.com,*.gaming.karaolidis.com,beta.media.karaolidis.com"
|
||||||
"--entrypoints.https.http.tls.domains[1].main=krlds.com"
|
"--entrypoints.https.http.tls.domains[1].main=krlds.com"
|
||||||
"--entrypoints.https.http.tls.domains[1].sans=*.krlds.com"
|
"--entrypoints.https.http.tls.domains[1].sans=*.krlds.com"
|
||||||
"--entryPoints.https.http3"
|
"--entryPoints.https.http3"
|
||||||
@@ -116,7 +110,7 @@ in
|
|||||||
"traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
|
"traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
|
||||||
"traefik.http.middlewares.security-headers.headers.stsPreload=true"
|
"traefik.http.middlewares.security-headers.headers.stsPreload=true"
|
||||||
"traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
|
"traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
|
||||||
"traefik.http.middlewares.security-headers.headers.frameDeny=true"
|
"traefik.http.middlewares.security-headers.headers.customFrameOptionsValue=SAMEORIGIN"
|
||||||
];
|
];
|
||||||
environmentFiles = [ hmConfig.sops.templates.traefik-env.path ];
|
environmentFiles = [ hmConfig.sops.templates.traefik-env.path ];
|
||||||
};
|
};
|
||||||
|
@@ -64,7 +64,7 @@ in
|
|||||||
"offline_access"
|
"offline_access"
|
||||||
];
|
];
|
||||||
response_types = [ "code" ];
|
response_types = [ "code" ];
|
||||||
pre_configured_consent_duration = "1 month";
|
pre_configured_consent_duration = "1 year";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@@ -3,7 +3,7 @@ final: prev:
|
|||||||
android-tools = import ./android-tools final prev;
|
android-tools = import ./android-tools final prev;
|
||||||
attic-client = import ./attic-client final prev;
|
attic-client = import ./attic-client final prev;
|
||||||
darktable = import ./darktable final prev;
|
darktable = import ./darktable final prev;
|
||||||
hyprland = import ./hyprland final prev;
|
go-swagger = import ./go-swagger final prev;
|
||||||
mpv = import ./mpv final prev;
|
mpv = import ./mpv final prev;
|
||||||
spicetify-cli = import ./spicetify-cli final prev;
|
spicetify-cli = import ./spicetify-cli final prev;
|
||||||
tea = import ./tea final prev;
|
tea = import ./tea final prev;
|
||||||
@@ -21,9 +21,11 @@ final: prev:
|
|||||||
gitea = final.docker-image-gitea;
|
gitea = final.docker-image-gitea;
|
||||||
gitea-act-runner = final.docker-image-gitea-act-runner;
|
gitea-act-runner = final.docker-image-gitea-act-runner;
|
||||||
gitea-act-runner-worker = final.docker-image-gitea-act-runner-worker;
|
gitea-act-runner-worker = final.docker-image-gitea-act-runner-worker;
|
||||||
grafana = final.docker-image-grafana;
|
|
||||||
grafana-image-renderer = final.docker-image-grafana-image-renderer;
|
grafana-image-renderer = final.docker-image-grafana-image-renderer;
|
||||||
jellyfin = final.docker-image-jellyfin;
|
grafana-to-ntfy = final.docker-image-grafana-to-ntfy;
|
||||||
|
grafana = final.docker-image-grafana;
|
||||||
|
immich = final.docker-image-immich;
|
||||||
|
immich-machine-learning = final.docker-image-immich-machine-learning;
|
||||||
jellyseerr = final.docker-image-jellyseerr;
|
jellyseerr = final.docker-image-jellyseerr;
|
||||||
littlelink-server = final.docker-image-littlelink-server;
|
littlelink-server = final.docker-image-littlelink-server;
|
||||||
mariadb = final.docker-image-mariadb;
|
mariadb = final.docker-image-mariadb;
|
||||||
@@ -34,7 +36,9 @@ final: prev:
|
|||||||
ntfy = final.docker-image-ntfy;
|
ntfy = final.docker-image-ntfy;
|
||||||
oidcwarden = final.docker-image-oidcwarden;
|
oidcwarden = final.docker-image-oidcwarden;
|
||||||
outline = final.docker-image-outline;
|
outline = final.docker-image-outline;
|
||||||
|
plex = final.docker-image-plex;
|
||||||
postgresql = final.docker-image-postgresql;
|
postgresql = final.docker-image-postgresql;
|
||||||
|
postgresql-vectorchord = final.docker-image-postgresql-vectorchord;
|
||||||
prometheus = final.docker-image-prometheus;
|
prometheus = final.docker-image-prometheus;
|
||||||
prometheus-fail2ban-exporter = final.docker-image-prometheus-fail2ban-exporter;
|
prometheus-fail2ban-exporter = final.docker-image-prometheus-fail2ban-exporter;
|
||||||
prometheus-node-exporter = final.docker-image-prometheus-node-exporter;
|
prometheus-node-exporter = final.docker-image-prometheus-node-exporter;
|
||||||
@@ -52,19 +56,6 @@ final: prev:
|
|||||||
transmission-protonvpn = final.docker-image-transmission-protonvpn;
|
transmission-protonvpn = final.docker-image-transmission-protonvpn;
|
||||||
whoami = final.docker-image-whoami;
|
whoami = final.docker-image-whoami;
|
||||||
};
|
};
|
||||||
|
|
||||||
jellyfinPlugins = prev.jellyfinPlugins or { } // {
|
|
||||||
bookshelf = final.jellyfin-plugin-bookshelf-bin;
|
|
||||||
intro-skipper = final.jellyfin-plugin-intro-skipper-bin;
|
|
||||||
opensubtitles = final.jellyfin-plugin-opensubtitles-bin;
|
|
||||||
playbackreporting = final.jellyfin-plugin-playbackreporting-bin;
|
|
||||||
reports = final.jellyfin-plugin-reports-bin;
|
|
||||||
sso = final.jellyfin-plugin-sso-bin;
|
|
||||||
subtitleextract = final.jellyfin-plugin-subtitleextract-bin;
|
|
||||||
tmdbboxsets = final.jellyfin-plugin-tmdbboxsets-bin;
|
|
||||||
tvdb = final.jellyfin-plugin-tvdb-bin;
|
|
||||||
};
|
|
||||||
|
|
||||||
obsidianPlugins = prev.obsidianPlugins or { } // {
|
obsidianPlugins = prev.obsidianPlugins or { } // {
|
||||||
better-word-count = final.obsidian-plugin-better-word-count;
|
better-word-count = final.obsidian-plugin-better-word-count;
|
||||||
dataview = final.obsidian-plugin-dataview;
|
dataview = final.obsidian-plugin-dataview;
|
||||||
|
13
overlays/go-swagger/default.nix
Normal file
13
overlays/go-swagger/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
final: prev:
|
||||||
|
# FIXME: https://github.com/go-swagger/go-swagger/issues/3220
|
||||||
|
# FIXME: https://github.com/go-swagger/go-swagger/issues/3229
|
||||||
|
prev.go-swagger.overrideAttrs (oldAttrs: {
|
||||||
|
src = final.fetchFromGitHub {
|
||||||
|
owner = "go-swagger";
|
||||||
|
repo = "go-swagger";
|
||||||
|
rev = "717e3cb29becaaf00e56953556c6d80f8a01b286";
|
||||||
|
hash = "sha256-IuIVc7NwfXSBQ2tojD4LY7I18k5MJaVeDDPsi/OBFL0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-x3fTIXmI5NnOKph1D84MHzf1Kod+WLYn1JtnWLr4x+U=";
|
||||||
|
})
|
@@ -1,4 +0,0 @@
|
|||||||
final: prev:
|
|
||||||
prev.hyprland.overrideAttrs (oldAttrs: {
|
|
||||||
patches = oldAttrs.patches or [ ] ++ [ ./fix-maxwidth-resolution-mode.patch ];
|
|
||||||
})
|
|
@@ -1,13 +0,0 @@
|
|||||||
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
|
|
||||||
index 635c7977..80093c0d 100644
|
|
||||||
--- a/src/config/ConfigManager.cpp
|
|
||||||
+++ b/src/config/ConfigManager.cpp
|
|
||||||
@@ -2091,6 +2091,8 @@ bool CMonitorRuleParser::parseMode(const std::string& value) {
|
|
||||||
m_rule.resolution = Vector2D(-1, -1);
|
|
||||||
else if (value.starts_with("highres"))
|
|
||||||
m_rule.resolution = Vector2D(-1, -2);
|
|
||||||
+ else if (value.starts_with("maxwidth"))
|
|
||||||
+ m_rule.resolution = Vector2D(-1, -3);
|
|
||||||
else if (parseModeLine(value, m_rule.drmMode)) {
|
|
||||||
m_rule.resolution = Vector2D(m_rule.drmMode.hdisplay, m_rule.drmMode.vdisplay);
|
|
||||||
m_rule.refreshRate = float(m_rule.drmMode.vrefresh) / 1000;
|
|
@@ -4,7 +4,6 @@
|
|||||||
android-tools
|
android-tools
|
||||||
attic-client
|
attic-client
|
||||||
darktable
|
darktable
|
||||||
hyprland
|
|
||||||
mpv
|
mpv
|
||||||
spicetify-cli
|
spicetify-cli
|
||||||
tea
|
tea
|
||||||
|
@@ -1,15 +1,10 @@
|
|||||||
final: prev:
|
final: prev:
|
||||||
prev.tea.overrideAttrs (oldAttrs: {
|
prev.tea.overrideAttrs (oldAttrs: {
|
||||||
patches = oldAttrs.patches or [ ] ++ [
|
patches = oldAttrs.patches or [ ] ++ [
|
||||||
# feat: add user auth via env
|
|
||||||
(builtins.fetchurl {
|
|
||||||
url = "https://gitea.com/gitea/tea/pulls/639.patch";
|
|
||||||
sha256 = "sha256:0c5gpi6aajd3h0wp7lrvj5qk9wsqhgbap7ijvl0x117v0g8mgzvs";
|
|
||||||
})
|
|
||||||
# fix: evaluate env login in repo context
|
# fix: evaluate env login in repo context
|
||||||
(builtins.fetchurl {
|
(builtins.fetchurl {
|
||||||
url = "https://gitea.com/gitea/tea/pulls/809.patch";
|
url = "https://gitea.com/gitea/tea/pulls/809.patch";
|
||||||
sha256 = "sha256:1mmsnzabcdy5lihs51kbx8r1vcr51rfj9a8gl5894jm7qvng7c5d";
|
sha256 = "sha256:1pzp4z49nzdd0rd03d6gmdrkn95vxmamykpz10giampssjn31sn3";
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
@@ -2,26 +2,19 @@
|
|||||||
# AUTO-UPDATE: nix-update --flake comentario --version=branch=dev --subpackage frontend
|
# AUTO-UPDATE: nix-update --flake comentario --version=branch=dev --subpackage frontend
|
||||||
pkgs.buildGo125Module (finalAttrs: {
|
pkgs.buildGo125Module (finalAttrs: {
|
||||||
pname = "comentario";
|
pname = "comentario";
|
||||||
version = "3.14.0-unstable-2025-09-15";
|
version = "3.14.0-unstable-2025-10-03";
|
||||||
|
|
||||||
src = pkgs.fetchFromGitLab {
|
src = pkgs.fetchFromGitLab {
|
||||||
owner = "comentario";
|
owner = "comentario";
|
||||||
repo = "comentario";
|
repo = "comentario";
|
||||||
# FIXME: Stable rev once type error is fixed
|
# FIXME: Stable rev once type error is fixed
|
||||||
rev = "d79035b41a912a432b74eb7fb0240b79cabff6bf";
|
rev = "4f493bb2a8cfe6f72dea8aeb3c13671e90c667dc";
|
||||||
hash = "sha256-nTOojxYBDeA5Z+rh+C+SbFJ4fzmr8sT2oZmO+chiXJM=";
|
hash = "sha256-L1QcDgjWin7DT3XMyTAMl4f8hnC5d7inemzBLFMppi0=";
|
||||||
};
|
};
|
||||||
|
|
||||||
patches = [
|
patches = [ ./superuser-claim.patch ];
|
||||||
# fe: dynamic configuration env vars
|
|
||||||
(builtins.fetchurl {
|
|
||||||
url = "https://gitlab.com/comentario/comentario/-/merge_requests/23.patch";
|
|
||||||
sha256 = "sha256:0ih5hwadjkh47vvji4jygpfxcfpjcarhcwazc7asxpfxc87g04pv";
|
|
||||||
})
|
|
||||||
./superuser-claim.patch
|
|
||||||
];
|
|
||||||
|
|
||||||
vendorHash = "sha256-AOI/WnVkrSgJlT2FtYOTuifOPw8sfc4C0g/prVkvJlA=";
|
vendorHash = "sha256-tnnSJN3CEDbuj4/B0PBwpYCdm3SOgSbvC7htS9+9pr4=";
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
go-swagger
|
go-swagger
|
||||||
@@ -72,13 +65,10 @@ pkgs.buildGo125Module (finalAttrs: {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/bin $out/lib/${finalAttrs.pname}
|
mkdir -p $out/bin
|
||||||
cp -r $GOPATH/bin/comentario $out/bin/${finalAttrs.pname}
|
cp -r $GOPATH/bin/comentario $out/bin/${finalAttrs.pname}
|
||||||
cp -r db templates $out/lib/${finalAttrs.pname}
|
|
||||||
|
|
||||||
wrapProgram $out/bin/${finalAttrs.pname} \
|
wrapProgram $out/bin/${finalAttrs.pname} \
|
||||||
--add-flags "--db-migration-path=$out/lib/${finalAttrs.pname}/db" \
|
|
||||||
--add-flags "--template-path=$out/lib/${finalAttrs.pname}/templates" \
|
|
||||||
--add-flags "--static-path=${finalAttrs.frontend}"
|
--add-flags "--static-path=${finalAttrs.frontend}"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@@ -144,7 +144,7 @@ index 7d3dc792..723e8149 100644
|
|||||||
[InstanceConfigItemKey.operationNewOwnerEnabled]: $localize`Non-owner users can add domains`,
|
[InstanceConfigItemKey.operationNewOwnerEnabled]: $localize`Non-owner users can add domains`,
|
||||||
// Domain defaults
|
// Domain defaults
|
||||||
diff --git a/internal/api/restapi/handlers/oauth.go b/internal/api/restapi/handlers/oauth.go
|
diff --git a/internal/api/restapi/handlers/oauth.go b/internal/api/restapi/handlers/oauth.go
|
||||||
index 0d8cd282..01324302 100644
|
index 8c5129f2..3837d229 100644
|
||||||
--- a/internal/api/restapi/handlers/oauth.go
|
--- a/internal/api/restapi/handlers/oauth.go
|
||||||
+++ b/internal/api/restapi/handlers/oauth.go
|
+++ b/internal/api/restapi/handlers/oauth.go
|
||||||
@@ -220,7 +220,7 @@ func AuthOauthCallback(params api_general.AuthOauthCallbackParams) middleware.Re
|
@@ -220,7 +220,7 @@ func AuthOauthCallback(params api_general.AuthOauthCallbackParams) middleware.Re
|
||||||
@@ -156,15 +156,26 @@ index 0d8cd282..01324302 100644
|
|||||||
|
|
||||||
} else if sso {
|
} else if sso {
|
||||||
// SSO embed signup
|
// SSO embed signup
|
||||||
@@ -248,9 +248,18 @@ func AuthOauthCallback(params api_general.AuthOauthCallbackParams) middleware.Re
|
@@ -248,9 +248,29 @@ func AuthOauthCallback(params api_general.AuthOauthCallbackParams) middleware.Re
|
||||||
return errors.New(errMessage)
|
return errors.New(errMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // Check if the superuser claim is set
|
+ // Check if the superuser claim is set
|
||||||
+ superuser := false
|
+ superuser := false
|
||||||
+ if raw, ok := fedUser.RawData[config.ServerConfig.SuperuserClaim]; ok {
|
+ if fidp, ok := config.FederatedIdProviders[models.FederatedIdpID(idpID)]; ok {
|
||||||
+ if isAdmin, ok := raw.(bool); ok && isAdmin {
|
+ if fidp.SuperuserClaim != "" {
|
||||||
+ superuser = true
|
+ if raw, ok := fedUser.RawData[fidp.SuperuserClaim]; ok {
|
||||||
|
+ switch v := raw.(type) {
|
||||||
|
+ case bool:
|
||||||
|
+ if v {
|
||||||
|
+ superuser = true
|
||||||
|
+ }
|
||||||
|
+ case string:
|
||||||
|
+ if v == "true" || v == "1" {
|
||||||
|
+ superuser = true
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@@ -173,25 +184,51 @@ index 0d8cd282..01324302 100644
|
|||||||
WithConfirmed(true). // Confirm the user right away as we trust the IdP
|
WithConfirmed(true). // Confirm the user right away as we trust the IdP
|
||||||
+ WithSuperuser(superuser).
|
+ WithSuperuser(superuser).
|
||||||
WithLangFromReq(params.HTTPRequest).
|
WithLangFromReq(params.HTTPRequest).
|
||||||
WithSignup(params.HTTPRequest, authSession.Host, !config.ServerConfig.LogFullIPs).
|
WithSignup(params.HTTPRequest, authSession.Host, !config.ServerConfig.Logging.FullIPs).
|
||||||
WithFederated(fedUser.UserID, idpID).
|
WithFederated(fedUser.UserID, idpID).
|
||||||
diff --git a/internal/config/config.go b/internal/config/config.go
|
diff --git a/internal/config/oauth.go b/internal/config/oauth.go
|
||||||
index e1292447..1715a7f6 100644
|
index 10917c44..7ba997d9 100644
|
||||||
--- a/internal/config/config.go
|
--- a/internal/config/oauth.go
|
||||||
+++ b/internal/config/config.go
|
+++ b/internal/config/oauth.go
|
||||||
@@ -36,6 +36,7 @@ type ServerConfiguration struct {
|
@@ -177,9 +177,10 @@ func oidcConfigure() error {
|
||||||
TemplatePath string `long:"template-path" description:"Path to template files" default:"./templates" env:"TEMPLATE_PATH"`
|
// Add it to the configured providers map
|
||||||
SecretsFile string `long:"secrets" description:"Path to YAML file with secrets" default:"secrets.yaml" env:"SECRETS_FILE"`
|
mid := models.FederatedIdpID(qid)
|
||||||
Superuser string `long:"superuser" description:"ID or email of user to be made superuser" default:"" env:"SUPERUSER"`
|
FederatedIdProviders[mid] = &data.FederatedIdentityProvider{
|
||||||
+ SuperuserClaim string `long:"superuser-claim" description:"Name of the OIDC claim for superusers" default:"is_superuser" env:"SUPERUSER_CLAIM"`
|
- ID: mid,
|
||||||
LogFullIPs bool `long:"log-full-ips" description:"Log IP addresses in full" env:"LOG_FULL_IPS"`
|
- Name: p.Name,
|
||||||
HomeContentURL string `long:"home-content-url" description:"URL of a HTML page to display on homepage" env:"HOME_CONTENT_URL"`
|
- GothName: qid,
|
||||||
GitLabURL string `long:"gitlab-url" description:"Custom GitLab URL for authentication" default:"" env:"GITLAB_URL"`
|
+ ID: mid,
|
||||||
|
+ Name: p.Name,
|
||||||
|
+ GothName: qid,
|
||||||
|
+ SuperuserClaim: p.SuperuserClaim,
|
||||||
|
}
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
diff --git a/internal/config/secrets.go b/internal/config/secrets.go
|
||||||
|
index d3e2af97..92f33f74 100644
|
||||||
|
--- a/internal/config/secrets.go
|
||||||
|
+++ b/internal/config/secrets.go
|
||||||
|
@@ -59,10 +59,11 @@ type APIKey struct {
|
||||||
|
|
||||||
|
// OIDCProvider stores OIDC provider configuration
|
||||||
|
type OIDCProvider struct {
|
||||||
|
- KeySecretURL `yaml:",inline"`
|
||||||
|
- ID string `yaml:"id"` // Unique provider ID, e.g. "keycloak"
|
||||||
|
- Name string `yaml:"name"` // Provider display name, e.g. "Keycloak"
|
||||||
|
- Scopes []string `yaml:"scopes"` // Additional scopes to request
|
||||||
|
+ KeySecretURL `yaml:",inline"`
|
||||||
|
+ ID string `yaml:"id"` // Unique provider ID, e.g. "keycloak"
|
||||||
|
+ Name string `yaml:"name"` // Provider display name, e.g. "Keycloak"
|
||||||
|
+ Scopes []string `yaml:"scopes"` // Additional scopes to request
|
||||||
|
+ SuperuserClaim string `yaml:"superuserClaim"` // Name of the OIDC claim for superusers
|
||||||
|
}
|
||||||
|
|
||||||
|
// QualifiedID returns the provider's ID prepended with the common OIDC prefix
|
||||||
diff --git a/internal/data/dyn_config.go b/internal/data/dyn_config.go
|
diff --git a/internal/data/dyn_config.go b/internal/data/dyn_config.go
|
||||||
index 8595ea2a..621fd132 100644
|
index 0cd0d64e..b4ff042d 100644
|
||||||
--- a/internal/data/dyn_config.go
|
--- a/internal/data/dyn_config.go
|
||||||
+++ b/internal/data/dyn_config.go
|
+++ b/internal/data/dyn_config.go
|
||||||
@@ -170,6 +170,7 @@ const (
|
@@ -171,6 +171,7 @@ const (
|
||||||
ConfigKeyAuthSignupConfirmCommenter DynConfigItemKey = "auth.signup.confirm.commenter"
|
ConfigKeyAuthSignupConfirmCommenter DynConfigItemKey = "auth.signup.confirm.commenter"
|
||||||
ConfigKeyAuthSignupConfirmUser DynConfigItemKey = "auth.signup.confirm.user"
|
ConfigKeyAuthSignupConfirmUser DynConfigItemKey = "auth.signup.confirm.user"
|
||||||
ConfigKeyAuthSignupEnabled DynConfigItemKey = "auth.signup.enabled"
|
ConfigKeyAuthSignupEnabled DynConfigItemKey = "auth.signup.enabled"
|
||||||
@@ -199,7 +236,7 @@ index 8595ea2a..621fd132 100644
|
|||||||
ConfigKeyIntegrationsUseGravatar DynConfigItemKey = "integrations.useGravatar"
|
ConfigKeyIntegrationsUseGravatar DynConfigItemKey = "integrations.useGravatar"
|
||||||
ConfigKeyOperationNewOwnerEnabled DynConfigItemKey = "operation.newOwner.enabled"
|
ConfigKeyOperationNewOwnerEnabled DynConfigItemKey = "operation.newOwner.enabled"
|
||||||
)
|
)
|
||||||
@@ -203,6 +204,7 @@ var DefaultDynInstanceConfig = DynConfigMap{
|
@@ -204,6 +205,7 @@ var DefaultDynInstanceConfig = DynConfigMap{
|
||||||
ConfigKeyAuthSignupConfirmCommenter: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
ConfigKeyAuthSignupConfirmCommenter: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
||||||
ConfigKeyAuthSignupConfirmUser: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
ConfigKeyAuthSignupConfirmUser: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
||||||
ConfigKeyAuthSignupEnabled: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
ConfigKeyAuthSignupEnabled: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionAuth},
|
||||||
@@ -207,3 +244,21 @@ index 8595ea2a..621fd132 100644
|
|||||||
ConfigKeyIntegrationsUseGravatar: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionIntegrations},
|
ConfigKeyIntegrationsUseGravatar: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionIntegrations},
|
||||||
ConfigKeyOperationNewOwnerEnabled: {DefaultValue: "false", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionMisc},
|
ConfigKeyOperationNewOwnerEnabled: {DefaultValue: "false", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionMisc},
|
||||||
ConfigKeyDomainDefaultsPrefix + DomainConfigKeyCommentDeletionAuthor: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionComments},
|
ConfigKeyDomainDefaultsPrefix + DomainConfigKeyCommentDeletionAuthor: {DefaultValue: "true", Datatype: ConfigDatatypeBool, Section: DynConfigItemSectionComments},
|
||||||
|
diff --git a/internal/data/models.go b/internal/data/models.go
|
||||||
|
index 4561fad5..0b491724 100644
|
||||||
|
--- a/internal/data/models.go
|
||||||
|
+++ b/internal/data/models.go
|
||||||
|
@@ -74,9 +74,10 @@ func (sd SortDirection) ToOrderedExpression(ident string) exp.OrderedExpression
|
||||||
|
|
||||||
|
// FederatedIdentityProvider describes a federated identity provider
|
||||||
|
type FederatedIdentityProvider struct {
|
||||||
|
- ID models.FederatedIdpID // Provider ID
|
||||||
|
- Name string // Provider name
|
||||||
|
- GothName string // Name of the corresponding goth provider
|
||||||
|
+ ID models.FederatedIdpID // Provider ID
|
||||||
|
+ Name string // Provider name
|
||||||
|
+ GothName string // Name of the corresponding goth provider
|
||||||
|
+ SuperuserClaim string // Name of the OIDC claim for superusers
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDTO converts this model into an API model
|
||||||
|
@@ -14,9 +14,11 @@
|
|||||||
docker-image-gitea = import ./docker/gitea { inherit pkgs; };
|
docker-image-gitea = import ./docker/gitea { inherit pkgs; };
|
||||||
docker-image-gitea-act-runner = import ./docker/gitea-act-runner { inherit pkgs; };
|
docker-image-gitea-act-runner = import ./docker/gitea-act-runner { inherit pkgs; };
|
||||||
docker-image-gitea-act-runner-worker = import ./docker/gitea-act-runner-worker { inherit pkgs; };
|
docker-image-gitea-act-runner-worker = import ./docker/gitea-act-runner-worker { inherit pkgs; };
|
||||||
docker-image-grafana = import ./docker/grafana { inherit pkgs; };
|
|
||||||
docker-image-grafana-image-renderer = import ./docker/grafana-image-renderer { inherit pkgs; };
|
docker-image-grafana-image-renderer = import ./docker/grafana-image-renderer { inherit pkgs; };
|
||||||
docker-image-jellyfin = import ./docker/jellyfin { inherit pkgs; };
|
docker-image-grafana-to-ntfy = import ./docker/grafana-to-ntfy { inherit pkgs; };
|
||||||
|
docker-image-grafana = import ./docker/grafana { inherit pkgs; };
|
||||||
|
docker-image-immich = import ./docker/immich { inherit pkgs; };
|
||||||
|
docker-image-immich-machine-learning = import ./docker/immich-machine-learning { inherit pkgs; };
|
||||||
docker-image-jellyseerr = import ./docker/jellyseerr { inherit pkgs; };
|
docker-image-jellyseerr = import ./docker/jellyseerr { inherit pkgs; };
|
||||||
docker-image-littlelink-server = import ./docker/littlelink-server { inherit pkgs; };
|
docker-image-littlelink-server = import ./docker/littlelink-server { inherit pkgs; };
|
||||||
docker-image-mariadb = import ./docker/mariadb { inherit pkgs; };
|
docker-image-mariadb = import ./docker/mariadb { inherit pkgs; };
|
||||||
@@ -27,7 +29,9 @@
|
|||||||
docker-image-ntfy = import ./docker/ntfy { inherit pkgs; };
|
docker-image-ntfy = import ./docker/ntfy { inherit pkgs; };
|
||||||
docker-image-oidcwarden = import ./docker/oidcwarden { inherit pkgs; };
|
docker-image-oidcwarden = import ./docker/oidcwarden { inherit pkgs; };
|
||||||
docker-image-outline = import ./docker/outline { inherit pkgs; };
|
docker-image-outline = import ./docker/outline { inherit pkgs; };
|
||||||
|
docker-image-plex = import ./docker/plex { inherit pkgs; };
|
||||||
docker-image-postgresql = import ./docker/postgresql { inherit pkgs; };
|
docker-image-postgresql = import ./docker/postgresql { inherit pkgs; };
|
||||||
|
docker-image-postgresql-vectorchord = import ./docker/postgresql-vectorchord { inherit pkgs; };
|
||||||
docker-image-prometheus = import ./docker/prometheus { inherit pkgs; };
|
docker-image-prometheus = import ./docker/prometheus { inherit pkgs; };
|
||||||
docker-image-prometheus-fail2ban-exporter = import ./docker/prometheus-fail2ban-exporter {
|
docker-image-prometheus-fail2ban-exporter = import ./docker/prometheus-fail2ban-exporter {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
@@ -51,18 +55,6 @@
|
|||||||
docker-image-transmission-protonvpn = import ./docker/transmission-protonvpn { inherit pkgs; };
|
docker-image-transmission-protonvpn = import ./docker/transmission-protonvpn { inherit pkgs; };
|
||||||
docker-image-whoami = import ./docker/whoami { inherit pkgs; };
|
docker-image-whoami = import ./docker/whoami { inherit pkgs; };
|
||||||
|
|
||||||
jellyfin-plugin-bookshelf-bin = import ./jellyfin/plugins/bookshelf { inherit pkgs; };
|
|
||||||
jellyfin-plugin-intro-skipper-bin = import ./jellyfin/plugins/intro-skipper { inherit pkgs; };
|
|
||||||
jellyfin-plugin-opensubtitles-bin = import ./jellyfin/plugins/opensubtitles { inherit pkgs; };
|
|
||||||
jellyfin-plugin-playbackreporting-bin = import ./jellyfin/plugins/playbackreporting {
|
|
||||||
inherit pkgs;
|
|
||||||
};
|
|
||||||
jellyfin-plugin-reports-bin = import ./jellyfin/plugins/reports { inherit pkgs; };
|
|
||||||
jellyfin-plugin-sso-bin = import ./jellyfin/plugins/sso { inherit pkgs; };
|
|
||||||
jellyfin-plugin-subtitleextract-bin = import ./jellyfin/plugins/subtitleextract { inherit pkgs; };
|
|
||||||
jellyfin-plugin-tmdbboxsets-bin = import ./jellyfin/plugins/tmdbboxsets { inherit pkgs; };
|
|
||||||
jellyfin-plugin-tvdb-bin = import ./jellyfin/plugins/tvdb { inherit pkgs; };
|
|
||||||
|
|
||||||
littlelink-server = import ./littlelink-server { inherit pkgs; };
|
littlelink-server = import ./littlelink-server { inherit pkgs; };
|
||||||
|
|
||||||
obsidian-plugin-better-word-count = import ./obsidian/plugins/better-word-count { inherit pkgs; };
|
obsidian-plugin-better-word-count = import ./obsidian/plugins/better-word-count { inherit pkgs; };
|
||||||
|
@@ -4,7 +4,7 @@ set -o errexit
|
|||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
atticd "$@" &
|
atticd "$@" &
|
||||||
PID=$!
|
PID="$!"
|
||||||
|
|
||||||
if [ -f /etc/attic/post-start.sh ]; then
|
if [ -f /etc/attic/post-start.sh ]; then
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
|
@@ -17,6 +17,7 @@ pkgs.dockerTools.buildImage {
|
|||||||
Env = [
|
Env = [
|
||||||
"HOST=0.0.0.0"
|
"HOST=0.0.0.0"
|
||||||
"PORT=8080"
|
"PORT=8080"
|
||||||
|
"CONFIG_FILE=/etc/comentario/config.yaml"
|
||||||
"SECRETS_FILE=/etc/comentario/secrets.yaml"
|
"SECRETS_FILE=/etc/comentario/secrets.yaml"
|
||||||
];
|
];
|
||||||
ExposedPorts = {
|
ExposedPorts = {
|
||||||
|
@@ -7,7 +7,7 @@ let
|
|||||||
text = builtins.readFile ./entrypoint.sh;
|
text = builtins.readFile ./entrypoint.sh;
|
||||||
};
|
};
|
||||||
|
|
||||||
runnerConfig = pkgs.writeTextDir "/etc/gitea-act-runner/config.yaml" (
|
config = pkgs.writeTextDir "/etc/gitea-act-runner/config.yaml" (
|
||||||
builtins.readFile (
|
builtins.readFile (
|
||||||
(pkgs.formats.yaml { }).generate "config.yaml" {
|
(pkgs.formats.yaml { }).generate "config.yaml" {
|
||||||
runner.file = "/var/lib/gitea-act-runner/registration";
|
runner.file = "/var/lib/gitea-act-runner/registration";
|
||||||
@@ -27,7 +27,7 @@ pkgs.dockerTools.buildImage {
|
|||||||
paths = with pkgs; [
|
paths = with pkgs; [
|
||||||
entrypoint
|
entrypoint
|
||||||
gitea-actions-runner
|
gitea-actions-runner
|
||||||
runnerConfig
|
config
|
||||||
curl
|
curl
|
||||||
jq
|
jq
|
||||||
];
|
];
|
||||||
|
37
packages/docker/grafana-to-ntfy/default.nix
Normal file
37
packages/docker/grafana-to-ntfy/default.nix
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
config = pkgs.writeTextDir "/etc/grafana-to-ntfy/Rocket.toml" (
|
||||||
|
builtins.readFile (
|
||||||
|
(pkgs.formats.toml { }).generate "Rocket.toml" {
|
||||||
|
global = {
|
||||||
|
port = 8080;
|
||||||
|
address = "0.0.0.0";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "grafana-to-ntfy";
|
||||||
|
fromImage = pkgs.docker-image-base;
|
||||||
|
|
||||||
|
copyToRoot = pkgs.buildEnv {
|
||||||
|
name = "root";
|
||||||
|
paths = with pkgs; [
|
||||||
|
grafana-to-ntfy
|
||||||
|
config
|
||||||
|
];
|
||||||
|
pathsToLink = [
|
||||||
|
"/bin"
|
||||||
|
"/etc"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "grafana-to-ntfy" ];
|
||||||
|
WorkingDir = "/etc/grafana-to-ntfy";
|
||||||
|
ExposedPorts = {
|
||||||
|
"8080/tcp" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
41
packages/docker/immich-machine-learning/default.nix
Normal file
41
packages/docker/immich-machine-learning/default.nix
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
entrypoint = pkgs.writeTextFile {
|
||||||
|
name = "entrypoint";
|
||||||
|
executable = true;
|
||||||
|
destination = "/bin/entrypoint";
|
||||||
|
text = builtins.readFile ./entrypoint.sh;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "immich-machine-learning";
|
||||||
|
fromImage = pkgs.docker-image-base;
|
||||||
|
|
||||||
|
copyToRoot = pkgs.buildEnv {
|
||||||
|
name = "root";
|
||||||
|
paths = with pkgs; [
|
||||||
|
entrypoint
|
||||||
|
immich-machine-learning
|
||||||
|
];
|
||||||
|
pathsToLink = [
|
||||||
|
"/bin"
|
||||||
|
"/lib"
|
||||||
|
"/share"
|
||||||
|
"/nix-support"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "entrypoint" ];
|
||||||
|
Volumes = {
|
||||||
|
"/tmp/immich-machine-learning" = { };
|
||||||
|
};
|
||||||
|
Env = [
|
||||||
|
"IMMICH_LOG_LEVEL=warn"
|
||||||
|
"MACHINE_LEARNING_CACHE_FOLDER=/tmp/immich-machine-learning"
|
||||||
|
];
|
||||||
|
ExposedPorts = {
|
||||||
|
"3003/tcp" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
19
packages/docker/immich-machine-learning/entrypoint.sh
Normal file
19
packages/docker/immich-machine-learning/entrypoint.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
LOG_PIPE="$(mktemp -u)"
|
||||||
|
mkfifo "$LOG_PIPE"
|
||||||
|
|
||||||
|
(
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if echo "$line" | grep -qEi "\[(WARN|ERROR)\]"; then
|
||||||
|
echo "$line" >&2
|
||||||
|
else
|
||||||
|
echo "$line"
|
||||||
|
fi
|
||||||
|
done < "$LOG_PIPE"
|
||||||
|
) &
|
||||||
|
|
||||||
|
exec machine-learning "$@" > "$LOG_PIPE" 2>&1
|
42
packages/docker/immich/default.nix
Normal file
42
packages/docker/immich/default.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
entrypoint = pkgs.writeTextFile {
|
||||||
|
name = "entrypoint";
|
||||||
|
executable = true;
|
||||||
|
destination = "/bin/entrypoint";
|
||||||
|
text = builtins.readFile ./entrypoint.sh;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.dockerTools.buildImage {
|
||||||
|
name = "immich";
|
||||||
|
fromImage = pkgs.docker-image-base;
|
||||||
|
|
||||||
|
copyToRoot = pkgs.buildEnv {
|
||||||
|
name = "root";
|
||||||
|
paths = with pkgs; [
|
||||||
|
entrypoint
|
||||||
|
immich
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
];
|
||||||
|
pathsToLink = [
|
||||||
|
"/bin"
|
||||||
|
"/lib"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "entrypoint" ];
|
||||||
|
Volumes = {
|
||||||
|
"/var/lib/immich" = { };
|
||||||
|
};
|
||||||
|
WorkingDir = "/var/lib/immich";
|
||||||
|
Env = [
|
||||||
|
"IMMICH_CONFIG_FILE=/etc/immich/config.json"
|
||||||
|
"IMMICH_MEDIA_LOCATION=/var/lib/immich"
|
||||||
|
];
|
||||||
|
ExposedPorts = {
|
||||||
|
"2283/tcp" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
16
packages/docker/immich/entrypoint.sh
Normal file
16
packages/docker/immich/entrypoint.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
server "$@" &
|
||||||
|
PID="$!"
|
||||||
|
|
||||||
|
if [ -f /etc/immich/post-start.sh ]; then
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /etc/immich/post-start.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap 'kill -KILL "$PID"' INT TERM
|
||||||
|
wait "$PID"
|
||||||
|
exit $?
|
@@ -1,76 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
let
|
|
||||||
jellyfin = pkgs.jellyfin.overrideAttrs (_: {
|
|
||||||
makeWrapperArgs = [
|
|
||||||
"--add-flags"
|
|
||||||
"--ffmpeg=${pkgs.jellyfin-ffmpeg}/bin/ffmpeg"
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
jellyfin-web = pkgs.runCommandLocal "jellyfin-web" { } ''
|
|
||||||
mkdir -p $out/var/www
|
|
||||||
cp -r ${pkgs.jellyfin-web}/share/jellyfin-web $out/var/www/jellyfin
|
|
||||||
'';
|
|
||||||
|
|
||||||
entrypoint = pkgs.writeTextFile {
|
|
||||||
name = "entrypoint";
|
|
||||||
executable = true;
|
|
||||||
destination = "/bin/entrypoint";
|
|
||||||
text = builtins.readFile ./entrypoint.sh;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
pkgs.dockerTools.buildImage {
|
|
||||||
name = "jellyfin";
|
|
||||||
fromImage = pkgs.docker-image-base;
|
|
||||||
|
|
||||||
copyToRoot = pkgs.buildEnv {
|
|
||||||
name = "root";
|
|
||||||
paths =
|
|
||||||
with pkgs;
|
|
||||||
[
|
|
||||||
entrypoint
|
|
||||||
jellyfin
|
|
||||||
jellyfin-web
|
|
||||||
jellyfin-ffmpeg
|
|
||||||
curl
|
|
||||||
jq
|
|
||||||
]
|
|
||||||
++ (with jellyfinPlugins; [
|
|
||||||
bookshelf
|
|
||||||
intro-skipper
|
|
||||||
opensubtitles
|
|
||||||
playbackreporting
|
|
||||||
reports
|
|
||||||
sso
|
|
||||||
subtitleextract
|
|
||||||
tmdbboxsets
|
|
||||||
tvdb
|
|
||||||
]);
|
|
||||||
pathsToLink = [
|
|
||||||
"/bin"
|
|
||||||
"/lib"
|
|
||||||
"/var"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
Entrypoint = [ "entrypoint" ];
|
|
||||||
ExposedPorts = {
|
|
||||||
"8096/tcp" = { };
|
|
||||||
};
|
|
||||||
WorkingDir = "/var/lib/jellyfin";
|
|
||||||
Volumes = {
|
|
||||||
"/etc/jellyfin" = { };
|
|
||||||
"/var/lib/jellyfin/data" = { };
|
|
||||||
"/var/lib/jellyfin/metadata" = { };
|
|
||||||
"/var/lib/jellyfin/root" = { };
|
|
||||||
"/var/log/jellyfin" = { };
|
|
||||||
"/tmp/jellyfin" = { };
|
|
||||||
};
|
|
||||||
Env = [
|
|
||||||
# FIXME: https://github.com/NixOS/nixpkgs/issues/176081
|
|
||||||
"FONTCONFIG_FILE=${pkgs.fontconfig.out}/etc/fonts/fonts.conf"
|
|
||||||
"FONTCONFIG_PATH=${pkgs.fontconfig.out}/etc/fonts/"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
|
|
||||||
start() {
|
|
||||||
jellyfin \
|
|
||||||
-w /var/www/jellyfin \
|
|
||||||
-c /etc/jellyfin \
|
|
||||||
-d /var/lib/jellyfin \
|
|
||||||
-l /var/log/jellyfin \
|
|
||||||
-C /tmp/jellyfin \
|
|
||||||
"$@" &
|
|
||||||
|
|
||||||
PID=$!
|
|
||||||
}
|
|
||||||
|
|
||||||
start "$@"
|
|
||||||
|
|
||||||
if [ -f /etc/jellyfin/setup.sh ]; then
|
|
||||||
# shellcheck disable=SC1091
|
|
||||||
. /etc/jellyfin/setup.sh
|
|
||||||
|
|
||||||
kill "$PID"
|
|
||||||
wait "$PID" 2>/dev/null || true
|
|
||||||
start "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
trap 'kill -INT "$PID"' INT TERM
|
|
||||||
wait "$PID"
|
|
||||||
exit $?
|
|
@@ -34,6 +34,6 @@ fi
|
|||||||
|
|
||||||
trap 'kill -QUIT "$PID"' INT TERM
|
trap 'kill -QUIT "$PID"' INT TERM
|
||||||
mariadbd --user=root --datadir="$DATADIR" "$@" &
|
mariadbd --user=root --datadir="$DATADIR" "$@" &
|
||||||
PID=$!
|
PID="$!"
|
||||||
wait "$PID"
|
wait "$PID"
|
||||||
exit $?
|
exit $?
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user