Compare commits

..

4 Commits

Author SHA1 Message Date
Patrick Neff 35c1cedbe3 change cross compile 2025-01-08 00:40:39 +01:00
Patrick Neff 965ae8944d disable remote build 2025-01-08 00:26:04 +01:00
Patrick Neff bec0f66f0d add raspberry stuff 2025-01-08 00:00:32 +01:00
Patrick Neff 036d6fdca8 add sops 2025-01-05 23:59:56 +01:00
34 changed files with 1122 additions and 548 deletions

19
.sops.yaml Normal file
View File

@ -0,0 +1,19 @@
keys:
- &admin_odie age1ac27ksfvxydn20g29s09j66mag45vee3cgk5namsnup5e4l9v3sq7kypg7
- &server_asgard age1nnx85asl5nmxmurr3g8mazcsggvtazt0hpauw42l7v4k3de74s6s649w0k
- &server_pi0 age1v522tvf0gclgjnnu8q0mekl0rcmpdk7d7lwravwazstfn9zqhecsngvhpf
#- &server_pi1 age1u6k49fuphu4n5p7hhuxd03ktwhujr55mrs72cqe6ttfagljpc5asa0jsgx
- &server_pi1 age16vz5m0stsh39ajn3zhkzj7x7zfgexlx3zzk2k9vrrrsn78tyzd2qmjkt2a
- &server_nixos age1j8wprrs23m46h7xl26su3k6uztnvza5k89c9uk9rwwzefv8a4yvqpscxun
- &workstation_wanaheim age1jerjsfhnenzzqtnuxez8g79kc0xxulxyhu2evp9p6gjyswu2syqskgt62v
creation_rules:
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
key_groups:
- age:
- *admin_odie
- *server_asgard
- *server_pi0
- *server_pi1
- *server_nixos
- *workstation_wanaheim

View File

@ -349,6 +349,32 @@
"type": "github"
}
},
"gokosync": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1736215102,
"narHash": "sha256-0aMz+9Tk/a5AxUSZLubJpuYfSdgJaCwIK/6CSwuoP2g=",
"ref": "refs/heads/master",
"rev": "ebb45e7fbbb88c16fdb9e8de0d167e6c55510600",
"revCount": 7,
"type": "git",
"url": "ssh://git@git.gaja-group.com/odie/gokosync.git"
},
"original": {
"type": "git",
"url": "ssh://git@git.gaja-group.com/odie/gokosync.git"
}
},
"guihua": {
"flake": false,
"locked": {
@ -451,6 +477,40 @@
"type": "github"
}
},
"libcamera-src": {
"flake": false,
"locked": {
"lastModified": 1725630279,
"narHash": "sha256-KH30jmHfxXq4j2CL7kv18DYECJRp9ECuWNPnqPZajPA=",
"owner": "raspberrypi",
"repo": "libcamera",
"rev": "69a894c4adad524d3063dd027f5c4774485cf9db",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"repo": "libcamera",
"rev": "69a894c4adad524d3063dd027f5c4774485cf9db",
"type": "github"
}
},
"libpisp-src": {
"flake": false,
"locked": {
"lastModified": 1724944683,
"narHash": "sha256-Fo2UJmQHS855YSSKKmGrsQnJzXog1cdpkIOO72yYAM4=",
"owner": "raspberrypi",
"repo": "libpisp",
"rev": "28196ed6edcfeda88d23cc5f213d51aa6fa17bb3",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "v1.0.7",
"repo": "libpisp",
"type": "github"
}
},
"luavit-meta": {
"flake": false,
"locked": {
@ -486,18 +546,17 @@
"vanillatweaks": "vanillatweaks"
},
"locked": {
"lastModified": 1735393933,
"narHash": "sha256-RsPZaV73pdgEvMNuKDGL+qAzSCvs1upIp5fr7583n9g=",
"ref": "master",
"rev": "c3d339a685ac9b86d8c4b8908a0fc81605d5e6b7",
"revCount": 332,
"lastModified": 1735390427,
"narHash": "sha256-M/uZbGQN2VLdr6G5ryFAaWYf+aebpckPSLiSBrYHsjE=",
"ref": "refs/heads/master",
"rev": "f2da3bd27832b7e3bb2325e1a3238a874ebd95d9",
"revCount": 331,
"type": "git",
"url": "file:///home/odie/Code/nix/minecraft-server-flake"
"url": "ssh://git@git.gaja-group.com/gaja-group/minecraft-server-flake.git"
},
"original": {
"ref": "master",
"type": "git",
"url": "file:///home/odie/Code/nix/minecraft-server-flake"
"url": "ssh://git@git.gaja-group.com/gaja-group/minecraft-server-flake.git"
}
},
"neorg": {
@ -1111,6 +1170,35 @@
"url": "https://download.gaja-group.com/LuckPerms-Fabric-PlaceholderAPI-Hook.jar"
}
},
"raspberry-pi-nix": {
"inputs": {
"libcamera-src": "libcamera-src",
"libpisp-src": "libpisp-src",
"nixpkgs": [
"nixpkgs"
],
"rpi-bluez-firmware-src": "rpi-bluez-firmware-src",
"rpi-firmware-nonfree-src": "rpi-firmware-nonfree-src",
"rpi-firmware-src": "rpi-firmware-src",
"rpi-linux-6_10_12-src": "rpi-linux-6_10_12-src",
"rpi-linux-6_6_67-src": "rpi-linux-6_6_67-src",
"rpicam-apps-src": "rpicam-apps-src",
"u-boot-src": "u-boot-src"
},
"locked": {
"lastModified": 1736181271,
"narHash": "sha256-tCxJzhFxJmRlIKjLREntBYmoQr3db9P6eOE9q6dh/HA=",
"owner": "nix-community",
"repo": "raspberry-pi-nix",
"rev": "6b63ee98284cd68e86bcdb29feeb3009896f1a6b",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "raspberry-pi-nix",
"type": "github"
}
},
"root": {
"inputs": {
"catppuccin": "catppuccin",
@ -1118,6 +1206,7 @@
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"flake-utils": "flake-utils",
"gokosync": "gokosync",
"guihua": "guihua",
"home-manager": "home-manager",
"lazydev": "lazydev",
@ -1141,10 +1230,134 @@
"nvim-spell-de-latin1-suggestions": "nvim-spell-de-latin1-suggestions",
"nvim-spell-de-utf8-dictionary": "nvim-spell-de-utf8-dictionary",
"nvim-spell-de-utf8-suggestions": "nvim-spell-de-utf8-suggestions",
"raspberry-pi-nix": "raspberry-pi-nix",
"sops-nix": "sops-nix",
"systems": "systems_2",
"vim-mcfunction": "vim-mcfunction"
}
},
"rpi-bluez-firmware-src": {
"flake": false,
"locked": {
"lastModified": 1708969706,
"narHash": "sha256-KakKnOBeWxh0exu44beZ7cbr5ni4RA9vkWYb9sGMb8Q=",
"owner": "RPi-Distro",
"repo": "bluez-firmware",
"rev": "78d6a07730e2d20c035899521ab67726dc028e1c",
"type": "github"
},
"original": {
"owner": "RPi-Distro",
"ref": "bookworm",
"repo": "bluez-firmware",
"type": "github"
}
},
"rpi-firmware-nonfree-src": {
"flake": false,
"locked": {
"lastModified": 1723266537,
"narHash": "sha256-T7eTKXqY9cxEMdab8Snda4CEOrEihy5uOhA6Fy+Mhnw=",
"owner": "RPi-Distro",
"repo": "firmware-nonfree",
"rev": "4b356e134e8333d073bd3802d767a825adec3807",
"type": "github"
},
"original": {
"owner": "RPi-Distro",
"ref": "bookworm",
"repo": "firmware-nonfree",
"type": "github"
}
},
"rpi-firmware-src": {
"flake": false,
"locked": {
"lastModified": 1727798811,
"narHash": "sha256-eavbshXGYmkYR33y9FLcQMJoAYdYTESVEy0g/RRXnb0=",
"owner": "raspberrypi",
"repo": "firmware",
"rev": "287e6a6c2d3b50eee3e2c5b2eacdd907e5cbe09a",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "1.20241001",
"repo": "firmware",
"type": "github"
}
},
"rpi-linux-6_10_12-src": {
"flake": false,
"locked": {
"lastModified": 1728305462,
"narHash": "sha256-LtvNmGD1D5YYv+C9xxxddAeHw69o3OX/H9M7F663L74=",
"owner": "raspberrypi",
"repo": "linux",
"rev": "26ee50d56618c2d98100b1bc672fd201aed4d00f",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "rpi-6.10.y",
"repo": "linux",
"type": "github"
}
},
"rpi-linux-6_6_67-src": {
"flake": false,
"locked": {
"lastModified": 1734790986,
"narHash": "sha256-q9swM2TmmuzbUuQnbLZk5PseKWD7/SNPwtth6bpGIqE=",
"owner": "raspberrypi",
"repo": "linux",
"rev": "811ff707533bcd67cdcd368bbd46223082009b12",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "rpi-6.6.y",
"repo": "linux",
"type": "github"
}
},
"rpicam-apps-src": {
"flake": false,
"locked": {
"lastModified": 1727515047,
"narHash": "sha256-qCYGrcibOeGztxf+sd44lD6VAOGoUNwRqZDdAmcTa/U=",
"owner": "raspberrypi",
"repo": "rpicam-apps",
"rev": "a8ccf9f3cd9df49875dfb834a2b490d41d226031",
"type": "github"
},
"original": {
"owner": "raspberrypi",
"ref": "v1.5.2",
"repo": "rpicam-apps",
"type": "github"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1736064798,
"narHash": "sha256-xJRN0FmX9QJ6+w8eIIIxzBU1AyQcLKJ1M/Gp6lnSD20=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "5dc08f9cc77f03b43aacffdfbc8316807773c930",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
@ -1238,6 +1451,19 @@
"type": "github"
}
},
"u-boot-src": {
"flake": false,
"locked": {
"lastModified": 1719857238,
"narHash": "sha256-mJ2TBy0Y5ZtcGFgtU5RKr0UDUp5FWzojbFb+o/ebRJU=",
"type": "tarball",
"url": "https://ftp.denx.de/pub/u-boot/u-boot-2024.07.tar.bz2"
},
"original": {
"type": "tarball",
"url": "https://ftp.denx.de/pub/u-boot/u-boot-2024.07.tar.bz2"
}
},
"vanillatweaks": {
"flake": false,
"locked": {

View File

@ -45,6 +45,8 @@
home-manager = import ./modules/nixos/home-manager;
server = import ./modules/nixos/server;
games = import ./modules/nixos/games;
sops = import ./modules/nixos/sops;
raspberry-pi = import ./modules/nixos/raspberry-pi;
};
nixosConfigurations =
flakeLib.mkNixosConfiguration
@ -62,6 +64,11 @@
system = "x86_64-linux";
hostName = "wsl-dev";
}
// flakeLib.mkNixosConfiguration {
inherit inputs outputs nixpkgs vars flakeLib overlays;
system = "aarch64-linux";
hostName = "pi0";
}
// flakeLib.mkNixosConfiguration {
inherit inputs outputs nixpkgs vars flakeLib overlays;
system = "aarch64-linux";
@ -82,6 +89,7 @@
mediacenter = import ./modules/home-manager/mediacenter;
user = import ./modules/home-manager/user;
binary-cache = import ./modules/home-manager/binary-cache;
sops = import ./modules/home-manager/sops;
};
homeConfigurations =
flakeLib.mkHomeConfiguration
@ -150,6 +158,10 @@
url = "github:numtide/flake-utils";
inputs.systems.follows = "systems";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-wsl = {
url = "github:nix-community/NixOS-WSL";
inputs = {
@ -158,6 +170,13 @@
flake-compat.follows = "flake-compat";
};
};
raspberry-pi-nix = {
url = "github:nix-community/raspberry-pi-nix";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
nixgl = {
url = "github:nix-community/nixGL";
inputs.nixpkgs.follows = "nixpkgs";
@ -271,6 +290,15 @@
};
};
gokosync = {
url = "git+ssh://git@git.gaja-group.com/odie/gokosync.git";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
systems.follows = "systems";
};
};
# Misc
csleeptimer = {
url = "git+ssh://gitea@git.niederkassel.neff-steindesign.de/odie/csleeptimer.git";

30
lib/genSslCert.nix Normal file
View File

@ -0,0 +1,30 @@
{ name, dataDir, user, domain, wantedBy ? [], Before ? [] }: { pkgs, ... }:
{
systemd.services."create-${name}-cert" = {
description = "Create a certificate for ${domain}";
script = ''
${pkgs.openssl}/bin/openssl req -x509 -newkey rsa:4096 -keyout ${domain}.key -out ${domain}.crt -nodes -subj '/CN=${domain}'
${pkgs.openssl}/bin/openssl pkcs12 -export -out ${domain}.pfx -inkey ${domain}.key -in ${domain}.crt -passout pass:
cat ${domain}.crt ${domain}.key > ${domain}.pem
chmod 644 ${domain}.crt
chmod 640 ${domain}.pfx
chmod 640 ${domain}.key
chmod 640 ${domain}.pem
'';
wantedBy = [ "multi-user.target" ] ++ wantedBy;
unitConfig = {
Before = [ "multi-user.target" ] ++ Before;
ConditionPathExists = "!${dataDir}/${domain}.pfx";
};
serviceConfig = {
User = user;
Type = "oneshot";
WorkingDirectory = dataDir;
RemainAfterExit = true;
};
};
}

View File

@ -1,3 +1,5 @@
{
nixpkgs.config.allowUnfree = true;
nixpkgs = {
config.allowUnfree = true;
};
}

View File

@ -1,74 +0,0 @@
{
vars,
mysql,
media,
...
}: let
inherit (vars) timeZone hostName domain;
datadirs = "smb://${media.host}/kodi/userdata";
in {
addons = {
unknownsources = "true";
};
services = {
devicename = "${hostName}.${domain}";
webserver = "true";
webserverauthentication = "false";
webserverusername = "kodi";
webserverpassword = "kodi";
webserverport = "8000";
webserverssl = "false";
zeroconf = "true";
wsdiscovery = "true";
upnp = "true";
upnpserver = "true";
airplay = "true";
airplayvideosupport = "true";
};
locale = {
language = "resource.language.de_de";
country = "Deutschland";
timezone = timeZone;
};
lookandfeed = {
enablerssfeeds = "false";
};
videodatabase = {
inherit (mysql) user pass host;
type = "mysql";
port = builtins.toString mysql.port;
};
musicdatabase = {
inherit (mysql) user pass host;
type = "mysql";
port = builtins.toString mysql.port;
};
videolibrary = {
importwatchedstate = "true";
importresumepoint = "true";
};
pathsubstitution = {
substitute = [
{
from = "special://profile/playlists/";
to = "${datadirs}/playlists/";
}
{
from = "special://profile/sources.xml";
to = "${datadirs}/sources.xml";
}
{
from = "special://profile/mediasources.xml";
to = "${datadirs}/mediasources.xml";
}
{
from = "special://profile/RssFeeds.xml";
to = "${datadirs}/RssFeeds.xml";
}
{
from = "special://profile/favourites.xml";
to = "${datadirs}/favourites.xml";
}
];
};
}

View File

@ -1,64 +0,0 @@
{
vars,
pkgs,
config,
lib,
...
}: let
cfg = config.mediacenter.kodi;
inherit (lib) types;
in
with lib; {
options.mediacenter.kodi = {
# enable = mkEnableOption "kodi";
media = {
host = mkOption {
type = types.str;
default = "media";
};
user = mkOption {
type = types.str;
default = "kodi";
};
pass = mkOption {
type = types.str;
default = "kodi";
};
};
mysql = {
host = mkOption {
type = types.str;
default = "localhost";
};
port = mkOption {
type = types.int;
default = 3306;
};
user = mkOption {
type = types.str;
default = "kodi";
};
pass = mkOption {
type = types.str;
default = "kodi";
};
};
};
imports = [./kodi.nix]; # import overridden kodi module
config = mkIf cfg.enable {
#programs.kodi = {
mediacenter.kodi = {
# enable = true;
package = pkgs.kodi-standalone;
settings = import ./advancedsettings.nix {inherit vars; inherit (cfg) mysql media;};
};
home.file = {
"kodi-passwords.xml" = {
target = ".kodi/userdata/passwords.xml";
text = import ./passwords.nix {
inherit (cfg) media;
};
};
};
};
}

View File

@ -1,262 +1,171 @@
{ pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
with lib; let
stylesheetCommonHeader = ''
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
'';
stylesheetCommonFooter = "</xsl:stylesheet>";
stylesheetNestedTags = ''
<xsl:template match="attr[attrs]">
<xsl:variable name="elementName" select="@name"/>
<xsl:element name="{$elementName}">
<xsl:apply-templates select="attrs" />
</xsl:element>
</xsl:template>
<xsl:template match="attr[list[attrs]]">
<xsl:variable name="elementName" select="@name"/>
<xsl:for-each select="list/attrs">
<xsl:element name="{$elementName}">
<xsl:apply-templates select="." />
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="attr[not(attrs|list)]">
<xsl:variable name="elementName" select="@name"/>
<xsl:element name="{$elementName}">
<xsl:if test="$elementName='path'">
<!-- needed in sources.xml but will be used for all "path" tags -->
<xsl:attribute name="pathversion">1</xsl:attribute>
</xsl:if>
<xsl:value-of select="*/@value" />
</xsl:element>
</xsl:template>
'';
stylesheetTagsAsSettingWithId = ''
<xsl:template match='attr'>
<setting>
<xsl:attribute name="id">
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:value-of select="*/@value" />
</setting>
</xsl:template>
'';
stylesheetAdvancedSettingsRootTag = ''
<xsl:template match='/'>
<xsl:comment> Generated by Home Manager. </xsl:comment>
<advancedsettings version="1.0">
<xsl:apply-templates/>
</advancedsettings>
</xsl:template>
'';
stylesheetSourcesRootTag = ''
<xsl:template match='/'>
<xsl:comment> Generated by Home Manager. </xsl:comment>
<sources>
<xsl:apply-templates/>
</sources>
</xsl:template>
'';
stylesheetAddonSettingsRootTag = ''
<xsl:template match='/'>
<xsl:comment> Generated by Home Manager. </xsl:comment>
<settings version="2">
<xsl:apply-templates/>
</settings>
</xsl:template>
'';
attrsetToXml = attrs: name: stylesheet:
pkgs.runCommand name {
# Package splicing for libxslt does not work correctly leading to errors
# when cross-compiling. Use the version from buildPackages explicitly to
# fix this.
nativeBuildInputs = [pkgs.buildPackages.libxslt.bin];
xml = builtins.toXML attrs;
passAsFile = ["xml"];
} ''
xsltproc ${stylesheet} - < "$xmlPath" > "$out"
'';
attrsetToAdvancedSettingsXml = attrs: name: let
stylesheet = builtins.toFile "stylesheet.xsl" ''
${stylesheetCommonHeader}
${stylesheetAdvancedSettingsRootTag}
${stylesheetNestedTags}
${stylesheetCommonFooter}
'';
in
attrsetToXml attrs name stylesheet;
attrsetToSourcesXml = attrs: name: let
stylesheet = builtins.toFile "stylesheet.xsl" ''
${stylesheetCommonHeader}
${stylesheetSourcesRootTag}
${stylesheetNestedTags}
${stylesheetCommonFooter}
'';
in
attrsetToXml attrs name stylesheet;
attrsetToAddonSettingsXml = attrs: name: let
stylesheet = builtins.toFile "stylesheet.xsl" ''
${stylesheetCommonHeader}
${stylesheetAddonSettingsRootTag}
${stylesheetTagsAsSettingWithId}
${stylesheetCommonFooter}
'';
in
attrsetToXml attrs name stylesheet;
in {
meta.maintainers = [hm.maintainers.dwagenk];
options.mediacenter.kodi = {
enable = mkEnableOption "Kodi";
package = mkOption {
type = types.package;
default = pkgs.kodi;
defaultText = literalExpression "pkgs.kodi";
example =
literalExpression
"pkgs.kodi.withPackages (exts: [ exts.pvr-iptvsimple ])";
description = ''
The `kodi` package to use.
Can be used to specify extensions.
home.file = {
aelProfiles = {
text = ''
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<advanced_emulator_launcher version="1">
<control>
<update_timestamp>1659964681.6420453</update_timestamp>
</control>
<launcher>
<id>6bc2506af9af35bc7326d70b7356af51</id>
<m_name>retroarch</m_name>
<m_year />
<m_genre />
<m_developer />
<m_rating />
<m_plot />
<platform>Unknown</platform>
<categoryID>root_category</categoryID>
<application>${pkgs.retroarch}/bin/retroarch</application>
<args />
<rompath />
<romext />
<romextrapath />
<finished>False</finished>
<toggle_window>False</toggle_window>
<non_blocking>True</non_blocking>
<multidisc>True</multidisc>
<roms_base_noext />
<audit_state>Audit OFF</audit_state>
<audit_auto_dat_file />
<audit_custom_dat_file />
<audit_display_mode>All ROMs</audit_display_mode>
<launcher_display_mode>Flat mode</launcher_display_mode>
<num_roms>0</num_roms>
<num_parents>0</num_parents>
<num_clones>0</num_clones>
<num_have>0</num_have>
<num_miss>0</num_miss>
<num_unknown>0</num_unknown>
<num_extra>0</num_extra>
<timestamp_launcher>1659942644.8321931</timestamp_launcher>
<timestamp_report>0.0</timestamp_report>
<default_icon>s_icon</default_icon>
<default_fanart>s_fanart</default_fanart>
<default_banner>s_banner</default_banner>
<default_poster>s_poster</default_poster>
<default_clearlogo>s_clearlogo</default_clearlogo>
<default_controller>s_controller</default_controller>
<Asset_Prefix />
<s_icon />
<s_fanart />
<s_banner />
<s_poster />
<s_clearlogo />
<s_controller />
<s_trailer />
<roms_default_icon>s_boxfront</roms_default_icon>
<roms_default_fanart>s_fanart</roms_default_fanart>
<roms_default_banner>s_banner</roms_default_banner>
<roms_default_poster>s_flyer</roms_default_poster>
<roms_default_clearlogo>s_clearlogo</roms_default_clearlogo>
<ROM_asset_path />
<path_3dbox />
<path_title />
<path_snap />
<path_boxfront />
<path_boxback />
<path_cartridge />
<path_fanart />
<path_banner />
<path_clearlogo />
<path_flyer />
<path_map />
<path_manual />
<path_trailer />
</launcher>
</advanced_emulator_launcher>
'';
target =
".kodi/userdata/addon_data/plugin.program.advanced.emulator.launcher/categories.xml";
};
datadir = mkOption {
type = types.path;
default = "${config.home.homeDirectory}/.kodi";
defaultText =
literalExpression ''"''${config.home.homeDirectory}/.kodi"'';
example = literalExpression ''"''${config.xdg.dataHome}/kodi"'';
description = "Directory to store configuration and metadata.";
};
settings = mkOption {
type = with types; let
valueType =
oneOf [str (attrsOf valueType) (listOf valueType)]
// {
description = "attribute sets or lists of strings";
};
in
nullOr valueType;
default = null;
example = literalExpression ''
{ videolibrary.showemptytvshows = "true"; }
germanIptv = {
text = ''
<settings version="2">
<setting id="kodi_addon_instance_name">IPTV Deutsch</setting>
<setting id="kodi_addon_instance_enabled" default="true">true</setting>
<setting id="m3uPathType" default="true">1</setting>
<setting id="m3uPath" default="true" />
<setting id="m3uUrl">https://iptv-org.github.io/iptv/languages/deu.m3u</setting>
<setting id="m3uCache" default="true">true</setting>
<setting id="startNum" default="true">1</setting>
<setting id="numberByOrder" default="true">false</setting>
<setting id="m3uRefreshMode" default="true">0</setting>
<setting id="m3uRefreshIntervalMins" default="true">60</setting>
<setting id="m3uRefreshHour" default="true">4</setting>
<setting id="defaultProviderName" default="true" />
<setting id="enableProviderMappings" default="true">false</setting>
<setting id="providerMappingFile" default="true">special://userdata/addon_data/pvr.iptvsimple/providers/providerMappings.xml</setting>
<setting id="tvGroupMode" default="true">0</setting>
<setting id="numTvGroups" default="true">1</setting>
<setting id="oneTvGroup" default="true" />
<setting id="twoTvGroup" default="true" />
<setting id="threeTvGroup" default="true" />
<setting id="fourTvGroup" default="true" />
<setting id="fiveTvGroup" default="true" />
<setting id="customTvGroupsFile" default="true">special://userdata/addon_data/pvr.iptvsimple/channelGroups/customTVGroups-example.xml</setting>
<setting id="tvChannelGroupsOnly" default="true">false</setting>
<setting id="radioGroupMode" default="true">0</setting>
<setting id="numRadioGroups" default="true">1</setting>
<setting id="oneRadioGroup" default="true" />
<setting id="twoRadioGroup" default="true" />
<setting id="threeRadioGroup" default="true" />
<setting id="fourRadioGroup" default="true" />
<setting id="fiveRadioGroup" default="true" />
<setting id="customRadioGroupsFile" default="true">special://userdata/addon_data/pvr.iptvsimple/channelGroups/customRadioGroups-example.xml</setting>
<setting id="radioChannelGroupsOnly" default="true">false</setting>
<setting id="epgPathType" default="true">1</setting>
<setting id="epgPath" default="true" />
<setting id="epgUrl">http://10.0.20.10:3000/guide.xml</setting>
<setting id="epgCache" default="true">true</setting>
<setting id="epgTimeShift" default="true">0</setting>
<setting id="epgTSOverride" default="true">false</setting>
<setting id="epgIgnoreCaseForChannelIds" default="true">true</setting>
<setting id="useEpgGenreText" default="true">false</setting>
<setting id="genresPathType" default="true">0</setting>
<setting id="genresPath" default="true">special://userdata/addon_data/pvr.iptvsimple/genres/genreTextMappings/genres.xml</setting>
<setting id="genresUrl" default="true" />
<setting id="logoPathType" default="true">1</setting>
<setting id="logoPath" default="true" />
<setting id="logoBaseUrl" default="true" />
<setting id="useLogosLocalPathOnly" default="true">false</setting>
<setting id="logoFromEpg" default="true">1</setting>
<setting id="mediaEnabled" default="true">true</setting>
<setting id="mediaGroupByTitle" default="true">true</setting>
<setting id="mediaGroupBySeason" default="true">true</setting>
<setting id="mediaTitleSeasonEpisode" default="true">false</setting>
<setting id="mediaM3UGroupPath" default="true">0</setting>
<setting id="mediaForcePlaylist" default="true">false</setting>
<setting id="mediaVODAsRecordings" default="true">true</setting>
<setting id="timeshiftEnabled" default="true">false</setting>
<setting id="timeshiftEnabledAll" default="true">true</setting>
<setting id="timeshiftEnabledHttp" default="true">true</setting>
<setting id="timeshiftEnabledUdp" default="true">true</setting>
<setting id="timeshiftEnabledCustom" default="true">false</setting>
<setting id="catchupEnabled" default="true">false</setting>
<setting id="catchupQueryFormat" default="true" />
<setting id="catchupDays" default="true">5</setting>
<setting id="allChannelsCatchupMode" default="true">0</setting>
<setting id="catchupOverrideMode" default="true">0</setting>
<setting id="catchupCorrection" default="true">0</setting>
<setting id="catchupPlayEpgAsLive" default="true">false</setting>
<setting id="catchupWatchEpgBeginBufferMins" default="true">5</setting>
<setting id="catchupWatchEpgEndBufferMins" default="true">15</setting>
<setting id="catchupOnlyOnFinishedProgrammes" default="true">false</setting>
<setting id="transformMulticastStreamUrls" default="true">false</setting>
<setting id="udpxyHost" default="true">127.0.0.1</setting>
<setting id="udpxyPort" default="true">4022</setting>
<setting id="useFFmpegReconnect" default="true">true</setting>
<setting id="useInputstreamAdaptiveforHls" default="true">false</setting>
<setting id="defaultUserAgent" default="true" />
<setting id="defaultInputstream" default="true" />
<setting id="defaultMimeType" default="true" />
</settings>
'';
description = ''
Configuration to write to the `advancedsettings.xml`
file in kodis userdata directory. Settings specified here will be
immutable from inside kodi and be hidden from the GUI settings dialog.
target = ".kodi/userdata/addon_data/pvr.iptvsimple/instance-settings-2.xml";
See <https://kodi.wiki/view/Advancedsettings.xml> as
reference for how settings need to be specified.
The innermost attributes must be of type str.
'';
};
sources = mkOption {
type = with types; let
valueType =
oneOf [str (attrsOf valueType) (listOf valueType)]
// {
description = "attribute sets or lists of strings";
};
in
nullOr valueType;
default = null;
example = literalExpression ''
{
video = {
default = "movies";
source = [
{ name = "videos"; path = "/path/to/videos"; allowsharing = "true"; }
{ name = "movies"; path = "/path/to/movies"; allowsharing = "true"; }
];
};
}
'';
description = ''
Contents to populate the file `sources.xml` in kodis
userdata directory.
See <https://kodi.wiki/view/Sources.xml> as
reference for how sources need to be specified.
Kodi will still show the dialogs to modify sources in the GUI and they
appear to be mutable. This however is not the case and the sources will
stay as specified via Home Manager.
The innermost attributes must be of type str.
'';
};
addonSettings = mkOption {
type = with types; nullOr (attrsOf (attrsOf str));
default = null;
example = literalExpression ''
{ "service.xbmc.versioncheck".versioncheck_enable = "false"; }
'';
description = ''
Attribute set with the plugin namespace as toplevel key and the plugins
settings as lower level key/value pairs.
Kodi will still show the settings of plugins configured via this
mechanism in the GUI and they appear to be mutable. This however is
not the case and the settings will stay as specified via Home Manager.
'';
};
};
config = let
cfg = config.mediacenter.kodi;
in
mkIf cfg.enable (mkMerge [
{
assertions = [
(lib.hm.assertions.assertPlatform "programs.kodi" pkgs
lib.platforms.linux)
];
home.packages = [cfg.package];
home.sessionVariables = {KODI_DATA = cfg.datadir;};
}
(mkIf (cfg.settings != null) {
home.file."${cfg.datadir}/userdata/advancedsettings.xml".source =
attrsetToAdvancedSettingsXml cfg.settings "kodi-advancedsettings.xml";
})
(mkIf (cfg.sources != null) {
home.file."${cfg.datadir}/userdata/sources.xml".source =
attrsetToSourcesXml cfg.sources "kodi-sources.xml";
})
(mkIf (cfg.addonSettings != null) {
home.file = mapAttrs' (k: v:
attrsets.nameValuePair
"${cfg.datadir}/userdata/addon_data/${k}/settings.xml" {
source = attrsetToAddonSettingsXml v "kodi-addon-${k}-settings.xml";
})
cfg.addonSettings;
})
]);
}

View File

@ -1,8 +0,0 @@
{media,...}: ''
<passwords>
<path>
<from>smb://${media.host}</from>
<to>smb://${media.user}:${media.pass}@${media.host}</to>
</path>
</passwords>
''

View File

@ -0,0 +1,20 @@
{ inputs, ... }: {
imports = [
inputs.sops-nix.homeManagerModules.sops
];
sops = {
age.keyFile = "/home/user/.age-key.txt"; # must have no password!
# It's also possible to use a ssh key, but only when it has no password:
#age.sshKeyPaths = [ "/home/user/path-to-ssh-key" ];
defaultSopsFile = ../../../secrets/general.yaml;
secrets.hello = {
# sopsFile = ./secrets.yml.enc; # optionally define per-secret files
# %r gets replaced with a runtime directory, use %% to specify a '%'
# sign. Runtime dir is $XDG_RUNTIME_DIR on linux and $(getconf
# DARWIN_USER_TEMP_DIR) on darwin.
path = "%r/hello";
};
};
}

View File

@ -3,11 +3,9 @@
nix = {
settings = {
substituters = [
"http://nixcache.odie.home.arpa"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"nixcache.odie.home.arpa:2j5qAVmtBUSZMPWlIRS8Gn0Il9tbotJ9c2y43N0RLKU="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};

View File

@ -12,11 +12,40 @@
trusted-users = [ "root" "@wheel" ];
experimental-features = [ "nix-command" "flakes" ];
auto-optimise-store = true;
substituters = [
#"http://nix-cache.gaja-group.intranet:5000"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
#"nix-cache.gaja-group.intranet:EcUsafvI9NUrnab3DA71s2PGjAYMgct0FOvCwdYuStw="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
/*
buildMachines = [
{
hostName = "nix-cache.gaja-group.intranet";
#system = "x86_64-linux";
protocol = "ssh-ng";
# if the builder supports building for multiple architectures,
# replace the previous line by, e.g.,
systems = [ "x86_64-linux" "aarch64-linux" ];
maxJobs = 4;
speedFactor = 1;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
mandatoryFeatures = [ ];
}
];
distributedBuilds = true;
# optional, useful when the builder has a faster internet connection than yours
extraOptions = ''
builders-use-substitutes = true
'';
*/
};
}

View File

@ -1,13 +1,13 @@
{
config,
lib,
pkgs,
vars,
...
}: let
inherit (vars) username name sshKeys extraGroups;
{ config
, lib
, pkgs
, vars
, ...
}:
let
inherit (vars) username name sshKeys;
baseGroups = [
extraGroups = vars.extraGroups ++ [
"users"
"wheel"
"audio"
@ -16,37 +16,32 @@
"power"
"adm"
"plugdev"
] ++ lib.optionals config.hardware.raspberry-pi.enable [
"i2c"
"spi"
];
rpiGroups =
if config.hardware.raspberry-pi.enable
then [
"i2c"
"spi"
]
else [];
allExtraGroups = baseGroups ++ rpiGroups ++ extraGroups;
basePackages = with pkgs; [home-manager];
basePackages = with pkgs; [ home-manager ];
wslPackages =
if config.wsl.enable
if ((builtins.hasAttr "wsl" config) && config.wsl.enable)
then
with pkgs; [
wslu
wsl-open
]
else [];
else [ ];
packages = basePackages ++ wslPackages;
in {
in
{
options = {
hardware.raspberry-pi.enable = lib.mkEnableOption "raspberry pi features";
};
config = {
users = {
groups.${username} = {};
groups.${username} = { };
users = {
${username} = {
inherit packages ;
extraGroups = allExtraGroups;
inherit packages extraGroups;
name = username;
uid = 1000;
isNormalUser = true;

View File

@ -2,5 +2,6 @@ _: {
imports = [
./base
./wsl
./sops
];
}

View File

@ -1,13 +1,14 @@
{
flakeLib,
inputs,
outputs,
vars,
...
}: let
{ flakeLib
, inputs
, outputs
, vars
, ...
}:
let
inherit (vars) username hostName;
profile = "${username}@${hostName}";
in {
in
{
imports = [
inputs.home-manager.nixosModules.home-manager
];
@ -24,5 +25,6 @@ in {
../../../profiles/home-manager/${profile}/home.nix
];
};
backupFileExtension = "backup";
};
}

View File

@ -1,8 +1,8 @@
{lib, ...}:
with lib; {
_:
{
imports = [
./kodi
./jellyfin
./gokosync
];
mediacenter.kodi.enable = mkDefault true;
}

View File

@ -0,0 +1,4 @@
{ inputs, ... }: {
nixpkgs.overlays = [ inputs.gokosync.overlays.default ];
imports = [ inputs.gokosync.nixosModules.default ];
}

View File

@ -0,0 +1,47 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.services.jellyfin;
extraGroups = [
"users"
"audio"
"video"
"disk"
"power"
"plugdev"
] ++ lib.optionals config.hardware.raspberry-pi.enable [
"i2c"
"spi"
];
in
{
imports = [
(import ../../../../lib/genSslCert.nix {
name = "jellyfin";
inherit (cfg) dataDir user;
domain = "pi0.odie.home.arpa";
wantedBy = [ "jellyfin.service" ];
Before = [ "jellyfin.service" ];
})
];
options = {
services.jellyfin.domain = mkOption {
type = types.str;
default = "localhost";
};
};
config = {
services.jellyfin = {
enable = true;
openFirewall = true;
};
users.users.jellyfin = {
inherit extraGroups;
};
networking.firewall = {
allowedUDPPorts = [ 1900 ];
allowedTCPPorts = [ 8920 ];
};
};
}

View File

@ -1,76 +1,69 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.mediacenter.kodi;
{ pkgs, lib, config, ... }:
let
user = "kodi";
extraGroups = [
"users"
"audio"
"video"
"disk"
"power"
"plugdev"
] ++ lib.optionals config.hardware.raspberry-pi.enable [
"i2c"
"spi"
];
in
with lib; {
options = {
mediacenter.kodi = {
enable = mkEnableOption "kodi";
};
{
services.cage = {
inherit user;
enable = true;
program = "${pkgs.kodi-standalone}/bin/kodi-standalone";
};
users.users.kodi = {
inherit extraGroups;
name = user;
isNormalUser = true;
};
sops.secrets = {
"kodi-advancedsettings" = {
owner = user;
format = "binary";
sopsFile = ./secrets/advancedsettings.xml;
path = "/home/${user}/.kodi/userdata/advancedsettings.xml";
};
config = let
user = "kodi";
starter = pkgs.callPackage (
{pkgs, kodi-standalone, ...}:
pkgs.writeShellApplication {
name = "kodi-launcher";
runtimeInputs = [kodi-standalone];
text = ''
#!/usr/bin/env bash
"kodi-passwords" = {
owner = user;
format = "binary";
sopsFile = ./secrets/passwords.xml;
path = "/home/${user}/.kodi/userdata/passwords.xml";
};
"kodi-youtube" = {
owner = user;
format = "binary";
sopsFile = ./secrets/youtube.json;
path = "/home/${user}/.kodi/userdata/addon_data/plugin.video.youtube/api_keys.json";
};
};
while true
do
ping -c1 svartalbenheim.odie.home.arpa && break
sleep 5
done
networking.firewall.allowedTCPPorts = [ 8080 9090 ];
environment.sessionVariables = {
WLR_LIBINPUT_NO_DEVICES = builtins.toString 1;
};
while true
do
sleep 1
kodi-standalone
done
'';
}
) {};
in
lib.mkIf cfg.enable {
services.cage = {
inherit user;
enable = true;
program = "${starter}/bin/kodi-launcher";
};
users.users.kodi = {
name = user;
isNormalUser = true;
extraGroups = [
"audio"
"video"
"disk"
"plugdev"
"i2c"
"spi"
"power"
];
};
networking.firewall.allowedTCPPorts = [8080 9090];
environment.systemPackages = with pkgs; [
kodi-standalone
alsa-utils
(retroarch.override {
cores = with libretro; [
snes9x
pcsx-rearmed
nestopia
];
})
];
};
}
environment.systemPackages = with pkgs; [
#kodi-standalone
alsa-utils
/*
(retroarch.override {
cores = with libretro; [
snes9x
pcsx-rearmed
nestopia
];
})
*/
];
}

View File

@ -0,0 +1,24 @@
{
"data": "ENC[AES256_GCM,data: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,iv:OFKpx7VTY03kM9Dgf/LFkhweMwJabQ/Rf6IVdIWOAVI=,tag:WMQvgxLCmIbrDCuEyyyUOQ==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1ac27ksfvxydn20g29s09j66mag45vee3cgk5namsnup5e4l9v3sq7kypg7",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvbGN4YmZ6Q1JZamNIVDd0\nblBJQ3ZyNjBkYWlMdWFZeVB3bDU2NEE2SkdNCkhqc05hbWF5Y0RVS3Jld2pPeGFw\nZ2tXbm9rekpyWDU5d2xRL1RveDBCNTQKLS0tIEZBb3FxRGZuTlZOSE1TeWtsN2pI\nOFUwUEVKTklRSXY3d09zVEs2LzdvYmMKCvbPXIPfwz9XQGG6LqjgXQF3FEwpIrQQ\nxHcCVCFtTnuePDcBpiUa0LNO7pbykTLM8QDk720lXh5YeKcJYN1+wQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1v522tvf0gclgjnnu8q0mekl0rcmpdk7d7lwravwazstfn9zqhecsngvhpf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0cGZFU3FrZTVsNFE2ZGVn\nKzRabVo4Y2tLWEZrbW1aY1oydkZWbWFxV1FFClE5dkR2N1RFaWRvYlNwaUh0VGNx\nakVnbW84T3pGc1lGNzlLNmRMdHNzN2sKLS0tIEhZbENEUTdLQ0laL1B5Tmd3UW5h\nTWtlZFp2bXFHQ0tYK1pSV2xPSHhJeGMKV2WF/21OkoIUBSViIzX5pXZX+8OIwkuP\nb/4owrDej1otYCczA7upnO8d7r9HgdzV0PohZ9ghY+L7xMDtE2Pb0A==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-01-06T09:21:00Z",
"mac": "ENC[AES256_GCM,data:fQZoXecKTIqGjah5sxkylLRE4xgj7wKKBUR4Vk5lf2PvSFyxlC1WUinjPl8ltqm/NTiHY+XeL0mkD0ODlo8LN/QOjz++coWeNHyx5Y8+pSjb6hC/RA3GVfmSeMi6oTJryMbJeZ0fpurXBT3CFlCX2iYdfFOymJcfi92mNYupENQ=,iv:431aHv9TrhPPa7PAEAcgZcyLkM4YMWw+QM8mYr1T4mo=,tag:OUbGZDEfxU9rEGD33L70Jg==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.9.1"
}
}

View File

@ -0,0 +1,24 @@
{
"data": "ENC[AES256_GCM,data:M9gOTRJvjxukwifouVoXTIcZhl2jm9xgATC/Zyo3TATDQkdtcJlzOLA8BzvVmfwYooJBdbp7WQMaxHhRuTH7zEDPv0QPvyTPc1PKqdyMsfDd20Bi0ghPIRTlXRxFOZKKUrOtWNfVx4fAYey54GvZbg18JpdmAtKFtfQtmUko7Uy/S6Ko/bQSsOofhBuCCej6XYEVst7Ukr2V4yO8GyM5U7LAolEGGhGhPZi63B1yLcNXCMeI,iv:htvA4uWnmvwA6dJt2mFf3jDuazjK8NiXakhD23dWaZE=,tag:nAI314LRj0rOEXCvEJoJuw==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1ac27ksfvxydn20g29s09j66mag45vee3cgk5namsnup5e4l9v3sq7kypg7",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETWFndzB6RjJvbTVYZTdp\nd2VDUUJkNDBDR3R4Q1hxZGhsdk9yU1NFd2pzCmUxUU45cnEzVW9XK3dhcTA0NGxk\nQUozMk5jb0xDLzJxcFFPclp4VFBlYUkKLS0tIE83a1MwL3psL3I5U0wzRHJUcGxT\nVnNkWUJpK293TTJUeDk4aEtsekg4a0UKR+Pqu+ia+Kg/bHZP6l+bfRZQ1/9O92kZ\nhrfePv7Guxd5t91x+GyKOaGa6KituX7slskcQNc7JbKxhqXgZ1sXUA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1v522tvf0gclgjnnu8q0mekl0rcmpdk7d7lwravwazstfn9zqhecsngvhpf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZTHU4SFIxamhRNkZVWmtC\ndXl0czJkMFVNZEU3Q3ZScitwNW1Qbm9RZ2xJClk0N0E1TEpxVzQyOEtuTUxZR3lF\nSmQxM1VRam9Ici9vaXBWTGdYWjAvYTgKLS0tIEFsUS9UcmZFWWY2S05BTVVZdHcr\neHpuL3dzTEh3dEQxb1B1SDFFSDBhUkUKKgF3hmHbqVZDiCdkvFf8cCI00w0AFWHG\nSMtsQ3i7IhHMLK9RAUM2hlrl4uagF0Qh5WKTX4QlsHFPQur4Qe2qpw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-01-05T05:39:59Z",
"mac": "ENC[AES256_GCM,data:hXVntaa7Tq2A4y5wp9PicERTFjeDGDduxBd321FgRgvKO+9KG6jCzLGUX+dPRQtwM2A/DqRc74yxrorDyjpg5w4JVvfgFWBA+m2Jw6ZG5K/64/VLJgaV/c5dhmaBnyXfCly3441tZuwaocGNbYt2RSHI/izcN4f91iCeTzVFSA0=,iv:qFZ4wGPzQBmL/pZLqy/TDdKobbeqHf+vm6BPSLDsD9w=,tag:7K930Ym3/TbotLioWv4K5g==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.9.0"
}
}

View File

@ -0,0 +1,40 @@
{
"data": "ENC[AES256_GCM,data:2wfDxlxAfwClaj05cKIUUW6hDhFhzcaJiPhxfGEYv/O2gAaqe2vkKhUiFU6ZivbMVx9xYFlgGvVPoBggZ9zjqzM5jcC9ggDtX2U11NAk6YEcEgrkviUTK0ddaIDsLIaSu+ih1TzYFpMvprH9jyLsR5aGxwykq21wKw61DamSfw9uJ6fzpEldNmTzzHPPUEfKmV/7NE9Tg4s0CzeQhh4GUdvF36JQfKHeDlqaW+L+u5C/HZld/EQ+71m/egwjb3+bh/iCUAO4iGXmmBnu/IM5tR0WSiR8CbwzZsoW9hE9d5Fwfbeu+kyH7Rdgd/VPXTeKyb2c47GeuEt8h7YK6PRvySorcDCCSHP5CbordQHZfsX+hWl47rb9I1dfpYgKHAU=,iv:wYyVXmb80A70Wch4dy/tu4faAjp/DTnwPGXQJxvi3/w=,tag:Gjdr7HkP3CA6em2KEpIKlA==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1ac27ksfvxydn20g29s09j66mag45vee3cgk5namsnup5e4l9v3sq7kypg7",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmZmoxZmFSb045K29wdE9P\nb2MrMENUUkkrdG1ReS93Q2tpa2pOeldETjE0CktuWHBtanVQY2VtN2NWWlNhdjJw\neDJqVGZBZlN2ZDRWNHY2QmNTbkMzdWMKLS0tIG5XQkZaTzljbXgzb3hkZUREdHVj\ncXA3RzZGT1M0OHBrK0RXNzlPeEJ5b0kKBMVfIOf87UL2iAMz3c2r4mROPBMncr5O\nSVJPGbr79iEAxvLtCJL8jDA0kUt4/L+/hGXCBgtX+VY7GD05cIeesA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1nnx85asl5nmxmurr3g8mazcsggvtazt0hpauw42l7v4k3de74s6s649w0k",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2Q3k1bW1qd3RlcGlhQkhI\nYzBLd09ZbG9yOVpGcFJ0dWs0a2p2dGEwYUFjCklpT21aTXhsclBUMUZybnI2TzF2\nYk9zTDVJQzNWSnZSU3ZCZnZPTnd3V1UKLS0tIDNuUTJzYWRwRnluR1Z0aTJRSE80\nWldmQnE5RTlkbVdidk1FMjVvVStvekUKUkY5iCm6PvY5BH696cJC8KSia2MyxM1C\nQrv79R4yZHC6pmn9/v513aiprX2GCbPyDUSMM2pOGeJZgvgfnNmlUQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1v522tvf0gclgjnnu8q0mekl0rcmpdk7d7lwravwazstfn9zqhecsngvhpf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4Q2ZsdVk4V3R2TVBadmZp\nOFN2aXg2N0owOTQxZG05RExrZ052MThDc2xZCjFhK2lmdGVibi9uMHE5dytUbEdW\nV3FndWRLbmJCZFVMRzZXMDZqU2kwRWMKLS0tIDcwTVo5bWxQcTV2Z0pQcE83Y2pD\naWJMMHFJWmtId3hqWTlUUXdQVk13U0UKlYm7hcHCu3Wmcns30u+8j6cpeK80VpR4\neocylEOaWoNNUZjU7ojWWQ6thCmJOt41o3YlX23kVDgeN4sc4FMKZw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age16vz5m0stsh39ajn3zhkzj7x7zfgexlx3zzk2k9vrrrsn78tyzd2qmjkt2a",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWQ1hESkgwSjQzaXZCWUU1\nczR0dGUvamt1aEVoaVRUS3dmaTBOL0E1RUV3CkprU3ZGcWdjSGphQ3N6MUk3cTRx\nZVA4bkN3cVErYkFxU2ZzTy9uT1BndUUKLS0tIG1aRk51UjRleWU4Ync5aGhhc1Zt\nR0hkczUydW1HMjJRZ3MrWFZEbDlsTm8Kn2HibVG1t+Z4KhJv9S8wEJqCAhLsFS6v\nSrsYbE4ignDfXf2gN05wgYnqpSXeQHiJaBhLIKhBt+toEgDAXA6d6w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j8wprrs23m46h7xl26su3k6uztnvza5k89c9uk9rwwzefv8a4yvqpscxun",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFSmxwKzU2WVFHL2xEODNL\ndWt5bVdRT2JUa1U5a3JuREc0TEF0UkdBNnlrCkdSVTVvTjBaalZhY3NHQzRhZElX\ncnJlaEVlbTZleCtIeEZxOXdldWEreWcKLS0tIGc4ajBDcGtVODJIN25qSTFUTVN4\nVzltaVN4REo2c05KSnNEZWU4cFViclEKVtUtFv8817DuI/cQRleYVtqTXuqdJzjW\nE2nRwHjRPOCIGlKinUfmdG3t5YVz0iy0YHGkpsvo+elMC/pijpcryQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1jerjsfhnenzzqtnuxez8g79kc0xxulxyhu2evp9p6gjyswu2syqskgt62v",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRUjdnbXJsWXQwb0hZTkYw\nRVYvZU5HbXZUMnY2WHNhRmFnTzQzaGZERlJFCmdIdzBocmVvSUVWUmJQK0ErNURI\nSjVWN2c3dmtwZWl3V25tV1VNMEtmZlkKLS0tIFVJR0g4NUZzcTJYUWN2QlI0WC9D\na3ZPdTRRekRlRDNFMjFPMnI4eG01TTgK7g8H2Quq1DzJYq8Im0j0bwyW5ajg0No8\njfNR05ULMPGbr4rctJ+lNTYeCWpl44eTpxFRWTe+wDSQ2XlCkp5jrA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2023-11-20T12:29:43Z",
"mac": "ENC[AES256_GCM,data:HgDwUqtV3qljKSq4Jds+57NX6unOmE7wuyDJoNkSzecNNSygXzM8qyRJwwFVfZUUpNLovNaorlHfCiDAK5y3DsbsIDabCSbI0Ch8nR8JxAFhJdKz7EzIY7mOORLPsPPb9wQ3gAC6TW1qYxEzUUrs4gUPGknQAZTlglriDC3ljtU=,iv:BpBV7/OE4v0pwYUAlrKIYDtB8jz2krnMSvd3TE299FI=,tag:NQaHzZUi6uh0l0bcqhyowg==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.8.1"
}
}

View File

@ -0,0 +1,8 @@
{inputs, ...}: {
imports = [
inputs.raspberry-pi-nix.nixosModules.raspberry-pi
];
nixpkgs.overlays = [
inputs.raspberry-pi-nix.overlays.core
];
}

View File

@ -0,0 +1,21 @@
{ inputs, ... }: {
imports = [ inputs.sops-nix.nixosModules.sops ];
# This will add secrets.yml to the nix store
# You can avoid this by adding a string to the full path instead, i.e.
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
sops = {
defaultSopsFile = ../../../secrets/general.yaml;
# This will automatically import SSH keys as age keys
age = {
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
# This is using an age key that is expected to already be in the filesystem
keyFile = "/var/lib/sops-nix/key.txt";
# This will generate a new key if the key specified above does not exist
generateKey = true;
};
# This is the actual specification of the secrets.
secrets = {
hello = { };
};
};
}

18
overlays/jellyfin.nix Normal file
View File

@ -0,0 +1,18 @@
{
jellyfin-web = final: prev:
{
jellyfin-web = prev.jellyfin-web.overrideAttrs (finalAttrs: previousAttrs: {
installPhase = ''
runHook preInstall
# this is the important line
sed -i "s#</head>#<script src=\"configurationpage?name=skip-intro-button.js\"></script></head>#" dist/index.html
mkdir -p $out/share
cp -a dist $out/share/jellyfin-web
runHook postInstall
'';
});
};
}

View File

@ -1,14 +1,6 @@
_: final: prev: {
kodi-standalone =
final.kodi-wayland.withPackages
(kodiPkgs:
with kodiPkgs; [
youtube
pvr-iptvsimple
keymap
inputstream-adaptive
inputstream-ffmpegdirect
requests-cache
inputstreamhelper
]);
kodiPackages = prev.kodiPackages // {
advanced-emulator-launcher = final.callPackage ../pkgs/kodiPackages/advanced-emulator-launcher {};
};
kodi-standalone = final.callPackage ../pkgs/kodi {};
}

14
pkgs/kodi/default.nix Normal file
View File

@ -0,0 +1,14 @@
{ callPackage, kodi-wayland, ... }:
kodi-wayland.withPackages
(kodiPkgs: with kodiPkgs; [
youtube
pvr-iptvsimple
keymap
inputstream-adaptive
inputstream-ffmpegdirect
requests-cache
inputstreamhelper
(callPackage ../../pkgs/kodiPackages/advanced-emulator-launcher { })
jellyfin
jellycon
])

View File

@ -0,0 +1,14 @@
{ pkgs, fetchFromGitHub, ... }:
pkgs.kodiPackages.buildKodiAddon {
pname = "advanced-emulator-launcher";
namespace = "plugin.program.advanced.emulator.launcher";
version = "0.10.1";
src = fetchFromGitHub {
owner = "Wintermute0110";
repo = "plugin.program.AEL.dev";
rev = "20b082d58518883384735efbd5e9123e7c6d17d8";
hash = "sha256-+9bZ2m8qSLp+ZyhQnvZUEhYXiDQZUBuG3eJwAyLJg5k=";
};
}

View File

@ -0,0 +1,11 @@
{ outputs
, ...
}:
{
imports = [
outputs.homeManagerModules.base
outputs.homeManagerModules.shell
];
home.stateVersion = "24.11";
}

View File

@ -12,6 +12,7 @@
outputs.homeManagerModules.development
outputs.homeManagerModules.games
outputs.homeManagerModules.user
outputs.homeManagerModules.sops
];
desktop = {
enable = true;

View File

@ -1,18 +1,143 @@
{ inputs
, pkgs
, outputs
, vars
, config
, lib
, ...
}:
let
haproxy = rec {
dataDir = "/var/lib/haproxy";
certDir = "${dataDir}/crt";
domains = [
"pi0.odie.home.arpa"
"jellyfin.odie.home.arpa"
"gokosync.odie.home.arpa"
];
};
in
{
outputs,
flakeLib,
vars,
...
}: {
imports = [
inputs.nixos-hardware.nixosModules.raspberry-pi-4
outputs.nixosModules.base
outputs.nixosModules.home-manager
outputs.nixosModules.mediacenter
outputs.nixosModules.sops
outputs.nixosModules.raspberry-pi
./hardware-configuration.nix
];
] ++ map (name: (import ../../../lib/genSslCert.nix {
inherit name;
inherit (config.services.haproxy) user;
dataDir = haproxy.certDir;
domain = name;
wantedBy = [ "haproxy.service" ];
Before = [ "haproxy.service" ];
})) haproxy.domains;
nixpkgs.crossSystem = {
# target platform
system = "riscv64-linux";
};
networking = {
inherit (vars) hostName domain;
};
home-manager.users = flakeLib.mkNixosHomeConfiguration {inherit vars;};
fileSystems = {
"/media/net/hel_Public" = {
device = "hel.odie.home.arpa:/nfs/Public";
fsType = "nfs";
};
"/media/net/hel_USB" = {
device = "hel.odie.home.arpa:/nfs/USB_Video";
fsType = "nfs";
};
"/media/net/svartalbenheim_Video" = {
device = "svartalbenheim.odie.home.arpa:/volume1/media/Video";
fsType = "nfs";
};
};
home-manager = {
users = {
kodi = let profile = "kodi@pi0"; in import ../../home-manager/${profile}/home.nix;
};
};
security.rtkit.enable = true;
environment.systemPackages = with pkgs; [
libraspberrypi
raspberrypi-eeprom
libcec
kitty
nfs-utils
];
programs.zsh.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
services = {
gokosync.enable = true;
haproxy = {
enable = true;
config =
let
certs = lib.strings.concatMapStrings (d: "crt ${haproxy.certDir}/${d}.pem ") haproxy.domains;
in
''
global
maxconn 256
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http
bind *:80
bind *:443 ssl ${certs} default-crt ${haproxy.certDir}/pi0.odie.home.arpa.pem
redirect scheme https code 301 if !{ ssl_fc }
use_backend be_jellyfin if { ssl_fc_sni jellyfin.odie.home.arpa }
use_backend be_gokosync if { ssl_fc_sni gokosync.odie.home.arpa }
default_backend be_null
backend be_null
http-request return status 204
backend be_jellyfin
option httpchk
option forwardfor
http-check send meth GET uri /health
http-check expect string Healthy
server server1 127.0.0.1:8920 maxconn 32 ssl verify none
server server2 127.0.0.1:8096 maxconn 32
backend be_gokosync
server server1 ${config.services.gokosync.addr}:${builtins.toString config.services.gokosync.port} maxconn 32
'';
};
udev.extraRules = ''
# allow access to raspi cec device for video group (and optionally register it as a systemd device, used below)
KERNEL=="vchiq", GROUP="video", MODE="0660", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/vchiq"
'';
};
systemd.tmpfiles.rules = [
"d ${haproxy.certDir} 0770 ${config.users.users.haproxy.name} ${config.users.groups.haproxy.name} -"
];
nixpkgs = {
overlays = [
(final: prev: {
makeModulesClosure = x: prev.makeModulesClosure (x // { allowMissing = true; });
libcec = prev.libcec.override { withLibraspberrypi = true; };
})
];
};
}

View File

@ -1,10 +1,14 @@
{ lib, pkgs, ... }: {
boot = {
loader.grub.enable = false;
loader.generic-extlinux-compatible.enable = true;
kernelPackages = pkgs.linuxPackages_rpi4;
kernelParams = [ "snd_bcm2835.enable_headphones=1" "snd_bcm2835.enable_hdmi=1" ];
initrd.availableKernelModules = lib.mkDefault [
loader = {
grub.enable = false;
systemd-boot.enable = false;
generic-extlinux-compatible.enable = false;
};
/*
kernelPackages = pkgs.linuxPackages_rpi4;
kernelParams = [ "snd_bcm2835.enable_headphones=1" "snd_bcm2835.enable_hdmi=1" "gpu_mem=128" ];
initrd.availableKernelModules = lib.mkDefault [
"vc4"
"bcm2835_dma"
"i2c_bcm2835"
@ -12,7 +16,8 @@
"xhci_pci"
"usbhid"
"usb_storage"
];
];
*/
};
swapDevices = [{
@ -28,15 +33,59 @@
};
};
raspberry-pi-nix.board = "bcm2711";
hardware = {
raspberry-pi = {
enable = true;
cec.enable = true;
"4" = {
apply-overlays-dtmerge.enable = true;
fkms-3d.enable = true;
config = {
pi4 = {
options = {
arm_boost = {
enable = true;
value = true;
};
gpu_mem = {
enable = true;
value = "256";
};
};
dt-overlays = {
vc4-kms-v3d = {
enable = true;
params = { cma-256 = { enable = true; }; };
};
};
};
all = {
options = {
arm_64bit = {
enable = true;
value = true;
};
};
base-dt-params = {
BOOT_UART = {
value = 1;
enable = true;
};
uart_2ndstage = {
value = 1;
enable = true;
};
};
dt-overlays = {
disable-bt = {
enable = true;
params = { };
};
vc4-kms-v3d = {
enable = true;
params = { };
};
};
};
};
enableRedistributableFirmware = true;
};
};
system.stateVersion = "23.11";

10
remote-deploy.sh Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env sh
set -e
HOSTNAME=$1
nix build -L ".#nixosConfigurations.${HOSTNAME}.config.system.build.toplevel"
nix copy --no-check-sigs --to "ssh-ng://root@${HOSTNAME}" "./result"
ssh "root@${HOSTNAME}" nix-env -p /nix/var/nix/profiles/system --set "$(readlink ./result)"
ssh "root@${HOSTNAME}" /nix/var/nix/profiles/system/bin/switch-to-configuration switch

66
secrets/general.yaml Normal file
View File

@ -0,0 +1,66 @@
hello: ENC[AES256_GCM,data:XWkc+qY=,iv:wgY5hrihkWjCGOBluavDO6basgTll+WukeZAzsK3SIQ=,tag:5qYd+QcKOWpyzq1c0QlZEQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1ac27ksfvxydn20g29s09j66mag45vee3cgk5namsnup5e4l9v3sq7kypg7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIOFVYT2doR05kOC9QV1JX
T0pSaEV2NVcyOElhcXE3V1d1UGIva0RxbFJNClFKTWpqSUt5L01KNnpZYnMrL0h3
OE9OU2VVMWo3Z0p5cXlhQm5FUG5Cem8KLS0tIElDOGRvcXVvY1lsMmgrTTNKSGVi
RlJCSlE2NXZSc21qV1paWVVNK1BGVTQKq6164b3zZqKSff6weDeG9Lyul81vXSWU
BNPdVR98/moEz8QfiiUCs3UQTRUOY+/muWnpn5wTD/c0PYlfFtrNsQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1nnx85asl5nmxmurr3g8mazcsggvtazt0hpauw42l7v4k3de74s6s649w0k
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaNnJjbysxWmdBb0F0MExj
cHBuMkE4bENNYUtYNWxPZ1JEVTV0NzdUdGpJCkUyd2xHVWprWXZKS2xJM3pZZFhF
N0ZZdUI2ZndRa3FLOWZRM3BnR3Y3M0kKLS0tIGZWYTc1YkZoNnNpSDBla3pSaWR5
TStTQk85STFENlVXM1RMb2c5Vjd0djAKBKswTBhTtt5K8eVqmUl0m8lG7JF++qpU
WQm22QEVZ9SW/ZI6DUFN2L4Ga1cGDXPiXxZuTSjp9WElDiLg33XHEw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1v522tvf0gclgjnnu8q0mekl0rcmpdk7d7lwravwazstfn9zqhecsngvhpf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6VEdLRnhWTnY2NCsrSlNN
QmRoY25TYnJzbnpIT2dIRi94V1dZV3JQZDM4CnlsTWlaQXFaaDFSSWFweml5NjZv
K3crc1VXakREMTlwSzEwWHo1di9LcmMKLS0tIEtzVk1STSthRVVGUGZhSnFzUmZD
M2lYbDRpWk9BaEYwcng1d2JDQ3JyQWcKkQB8k55P8xRMIix8MeI1YCOD+Uq2/z4W
Zek12JWzIFS1NMLduuO997AZk8bwF3yRqSpkYSuhx2dvxWOgusKprQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age16vz5m0stsh39ajn3zhkzj7x7zfgexlx3zzk2k9vrrrsn78tyzd2qmjkt2a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJa0FZU2FnUUQvQzZicklB
L25Gb0ZsdVlNNzV3Yld4Rzk3SG9DaUlQYWxnCjgvd2xqbEpiNjdRN1BwRk9vTllx
N1gyREMvbHFKSEh6Vi95VXYzZWNENk0KLS0tIDQzU3A0eEZtZTV0RmNVaEVXbSt6
YVNxNzBRRUpxYkVhZWFUTlBQTmUvMGMKpc9rIUi08CFS3mAI6Iz9QgiEMj0lF/dK
tM2zk2A9hJSt/ZQ59XfrQitZc5IcW52T2lq5pMM+oUbASNREdrycbg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j8wprrs23m46h7xl26su3k6uztnvza5k89c9uk9rwwzefv8a4yvqpscxun
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUNlRhYWd6SzkzTVRIUUNG
VThFSEdSdGZhOVFtNWRLK2NIQ1V3b2xiN1VRClpqUGw1b09JSU1zVzIrRlVJd0lV
R2xSK2k1K21sWkNRbk9TV2IvNm95TTgKLS0tIDZHNFhyYkx4c0FTb1I2RmVQQ2Ji
djhxdm5iV3Bwd2tsdnZUMmtFWXFLN3MKTm8Y5MT5vNBZ5Y0eSWcscTn/I4nAHnKy
Q0CK4m+HHPEikaUnd+v/bxqPwAwjZ2+R7HrR3wuEPdl0WEIbfQeRzw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jerjsfhnenzzqtnuxez8g79kc0xxulxyhu2evp9p6gjyswu2syqskgt62v
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRRnZyWGE4ZHk5dER3SHZK
bDlXb00zZmlCaC8rODcyY3laZ3Z4OStMQ0dnCk5WcUFzcDVsQmFMS2p0QTEySVhn
QlF6Nnd3anNDVG1DcGUyVGRoaGdwaXMKLS0tIGtMck1CdmNCT29PMmNNd1dyekM0
bnc0d2JDV1ZHOWM4Q2FPUit4OWgzOW8KcVjHNOD1y9NRrye3uhe7L6yWc54DtMOj
lhI75HtNIDsgxLUrtBvUHA/sNBdlIE8tHpXnwnuj7qQRiu6d3leK3A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-05T22:35:45Z"
mac: ENC[AES256_GCM,data:Aayg2XiuB3+oiS/8wesJQnn8WonNG19loLmSToSR/5B2ha2CEaS9xBJZD0OOett6mumtn70aMK75quWCYTaQzf1vTaIBt1eDVHmBN3dWaTk/an5DtYmJ5oZKUCNiIOGo8jwDbd+e+nZYQXwI1pCn8BbyopsF+AhqOpl7WX8WzyY=,iv:fvJqyWT8M+DFCtCaqVO95HTEDzaOVrg0gwNpp3NOpb0=,tag:dnYnRdRSaaMvEDCNQ+sLUQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1