diff --git a/flake.lock b/flake.lock
index 8e38b44..d64428f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -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": {
@@ -1110,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",
@@ -1117,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",
@@ -1140,11 +1230,114 @@
"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": [
@@ -1258,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": {
diff --git a/flake.nix b/flake.nix
index db71828..64bce5e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -46,6 +46,7 @@
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
@@ -169,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";
@@ -282,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";
diff --git a/lib/genSslCert.nix b/lib/genSslCert.nix
new file mode 100644
index 0000000..89350cc
--- /dev/null
+++ b/lib/genSslCert.nix
@@ -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;
+ };
+ };
+}
diff --git a/modules/home-manager/base/nixpkgs.nix b/modules/home-manager/base/nixpkgs.nix
index e95ec3c..d793f95 100644
--- a/modules/home-manager/base/nixpkgs.nix
+++ b/modules/home-manager/base/nixpkgs.nix
@@ -1,3 +1,5 @@
{
- nixpkgs.config.allowUnfree = true;
+ nixpkgs = {
+ config.allowUnfree = true;
+ };
}
diff --git a/modules/home-manager/mediacenter/kodi/advancedsettings.nix b/modules/home-manager/mediacenter/kodi/advancedsettings.nix
deleted file mode 100644
index 6acd324..0000000
--- a/modules/home-manager/mediacenter/kodi/advancedsettings.nix
+++ /dev/null
@@ -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";
- }
- ];
- };
-}
diff --git a/modules/home-manager/mediacenter/kodi/default.nix b/modules/home-manager/mediacenter/kodi/default.nix
deleted file mode 100644
index 982c0ab..0000000
--- a/modules/home-manager/mediacenter/kodi/default.nix
+++ /dev/null
@@ -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;
- };
- };
- };
- };
- }
diff --git a/modules/home-manager/mediacenter/kodi/kodi.nix b/modules/home-manager/mediacenter/kodi/kodi.nix
index a8c3140..db48f49 100644
--- a/modules/home-manager/mediacenter/kodi/kodi.nix
+++ b/modules/home-manager/mediacenter/kodi/kodi.nix
@@ -1,262 +1,171 @@
+{ pkgs, ... }:
{
- config,
- lib,
- pkgs,
- ...
-}:
-with lib; let
- stylesheetCommonHeader = ''
-
-
-
-
- '';
-
- stylesheetCommonFooter = "";
-
- stylesheetNestedTags = ''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
- '';
-
- stylesheetTagsAsSettingWithId = ''
-
-
-
-
-
-
-
-
- '';
-
- stylesheetAdvancedSettingsRootTag = ''
-
- Generated by Home Manager.
-
-
-
-
- '';
-
- stylesheetSourcesRootTag = ''
-
- Generated by Home Manager.
-
-
-
-
- '';
-
- stylesheetAddonSettingsRootTag = ''
-
- Generated by Home Manager.
-
-
-
-
- '';
-
- 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 = ''
+
+
+
+ 1659964681.6420453
+
+
+ 6bc2506af9af35bc7326d70b7356af51
+ retroarch
+
+
+
+
+
+ Unknown
+ root_category
+ ${pkgs.retroarch}/bin/retroarch
+
+
+
+
+ False
+ False
+ True
+ True
+
+ Audit OFF
+
+
+ All ROMs
+ Flat mode
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1659942644.8321931
+ 0.0
+ s_icon
+ s_fanart
+ s_banner
+ s_poster
+ s_clearlogo
+ s_controller
+
+
+
+
+
+
+
+
+ s_boxfront
+ s_fanart
+ s_banner
+ s_flyer
+ s_clearlogo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
'';
+ 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 = ''
+
+ IPTV Deutsch
+ true
+ 1
+
+ https://iptv-org.github.io/iptv/languages/deu.m3u
+ true
+ 1
+ false
+ 0
+ 60
+ 4
+
+ false
+ special://userdata/addon_data/pvr.iptvsimple/providers/providerMappings.xml
+ 0
+ 1
+
+
+
+
+
+ special://userdata/addon_data/pvr.iptvsimple/channelGroups/customTVGroups-example.xml
+ false
+ 0
+ 1
+
+
+
+
+
+ special://userdata/addon_data/pvr.iptvsimple/channelGroups/customRadioGroups-example.xml
+ false
+ 1
+
+ http://10.0.20.10:3000/guide.xml
+ true
+ 0
+ false
+ true
+ false
+ 0
+ special://userdata/addon_data/pvr.iptvsimple/genres/genreTextMappings/genres.xml
+
+ 1
+
+
+ false
+ 1
+ true
+ true
+ true
+ false
+ 0
+ false
+ true
+ false
+ true
+ true
+ true
+ false
+ false
+
+ 5
+ 0
+ 0
+ 0
+ false
+ 5
+ 15
+ false
+ false
+ 127.0.0.1
+ 4022
+ true
+ false
+
+
+
+
'';
- 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 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 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;
- })
- ]);
}
diff --git a/modules/home-manager/mediacenter/kodi/passwords.nix b/modules/home-manager/mediacenter/kodi/passwords.nix
deleted file mode 100644
index 7d1d322..0000000
--- a/modules/home-manager/mediacenter/kodi/passwords.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{media,...}: ''
-
-
- smb://${media.host}
- smb://${media.user}:${media.pass}@${media.host}
-
-
-''
diff --git a/modules/nixos/base/binary-cache/default.nix b/modules/nixos/base/binary-cache/default.nix
index 798ae8d..f0c52d0 100644
--- a/modules/nixos/base/binary-cache/default.nix
+++ b/modules/nixos/base/binary-cache/default.nix
@@ -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="
];
};
diff --git a/modules/nixos/base/nixos/default.nix b/modules/nixos/base/nixos/default.nix
index 8a5f9cf..8985742 100644
--- a/modules/nixos/base/nixos/default.nix
+++ b/modules/nixos/base/nixos/default.nix
@@ -18,5 +18,34 @@
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
+ '';
+ settings = {
+ substituters = [
+ "https://nix-community.cachix.org"
+ "http://nix-cache.gaja-group.intranet:5000"
+ ];
+ trusted-public-keys = [
+ "nix-cache.gaja-group.intranet:EcUsafvI9NUrnab3DA71s2PGjAYMgct0FOvCwdYuStw="
+ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
+ ];
+ };
};
}
diff --git a/modules/nixos/base/user/default.nix b/modules/nixos/base/user/default.nix
index 4602102..b604592 100644
--- a/modules/nixos/base/user/default.nix
+++ b/modules/nixos/base/user/default.nix
@@ -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;
diff --git a/modules/nixos/home-manager/default.nix b/modules/nixos/home-manager/default.nix
index 721e661..48687be 100644
--- a/modules/nixos/home-manager/default.nix
+++ b/modules/nixos/home-manager/default.nix
@@ -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";
};
}
diff --git a/modules/nixos/mediacenter/default.nix b/modules/nixos/mediacenter/default.nix
index a4647d9..a32df78 100644
--- a/modules/nixos/mediacenter/default.nix
+++ b/modules/nixos/mediacenter/default.nix
@@ -3,5 +3,6 @@ _:
imports = [
./kodi
./jellyfin
+ ./gokosync
];
}
diff --git a/modules/nixos/mediacenter/gokosync/default.nix b/modules/nixos/mediacenter/gokosync/default.nix
new file mode 100644
index 0000000..f1abf00
--- /dev/null
+++ b/modules/nixos/mediacenter/gokosync/default.nix
@@ -0,0 +1,4 @@
+{ inputs, ... }: {
+ nixpkgs.overlays = [ inputs.gokosync.overlays.default ];
+ imports = [ inputs.gokosync.nixosModules.default ];
+}
diff --git a/modules/nixos/mediacenter/jellyfin/default.nix b/modules/nixos/mediacenter/jellyfin/default.nix
index b563577..41b038d 100644
--- a/modules/nixos/mediacenter/jellyfin/default.nix
+++ b/modules/nixos/mediacenter/jellyfin/default.nix
@@ -1,7 +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
{
- services.jellyfin = {
- enable = true;
- openFirewall = true;
+ 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 ];
+ };
};
}
diff --git a/modules/nixos/mediacenter/kodi/default.nix b/modules/nixos/mediacenter/kodi/default.nix
index b721ffa..475d1ab 100644
--- a/modules/nixos/mediacenter/kodi/default.nix
+++ b/modules/nixos/mediacenter/kodi/default.nix
@@ -1,38 +1,29 @@
-{ pkgs, ... }:
+{ pkgs, lib, config, ... }:
let
user = "kodi";
- kodi-standalone = pkgs.kodi-wayland.withPackages
- (kodiPkgs: with pkgs.kodiPackages; [
- youtube
- pvr-iptvsimple
- keymap
- inputstream-adaptive
- inputstream-ffmpegdirect
- requests-cache
- inputstreamhelper
- advanced-emulator-launcher
- jellyfin
- ]);
+ extraGroups = [
+ "users"
+ "audio"
+ "video"
+ "disk"
+ "power"
+ "plugdev"
+ ] ++ lib.optionals config.hardware.raspberry-pi.enable [
+ "i2c"
+ "spi"
+ ];
in
{
services.cage = {
inherit user;
enable = true;
- program = "${kodi-standalone}/bin/kodi-standalone";
+ program = "${pkgs.kodi-standalone}/bin/kodi-standalone";
};
users.users.kodi = {
+ inherit extraGroups;
name = user;
isNormalUser = true;
- extraGroups = [
- "audio"
- "video"
- "disk"
- "plugdev"
- "i2c"
- "spi"
- "power"
- ];
};
sops.secrets = {
@@ -65,12 +56,14 @@ in
environment.systemPackages = with pkgs; [
#kodi-standalone
alsa-utils
- (retroarch.override {
+ /*
+ (retroarch.override {
cores = with libretro; [
snes9x
pcsx-rearmed
nestopia
];
- })
+ })
+ */
];
}
diff --git a/modules/nixos/mediacenter/kodi/secrets/advancedsettings.xml b/modules/nixos/mediacenter/kodi/secrets/advancedsettings.xml
index 3e9e752..23e6f53 100644
--- a/modules/nixos/mediacenter/kodi/secrets/advancedsettings.xml
+++ b/modules/nixos/mediacenter/kodi/secrets/advancedsettings.xml
@@ -1,5 +1,5 @@
{
- "data": "ENC[AES256_GCM,data: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,iv:nFT/yFOmF81VwjM5ab5dJQYrlkDeb9Ov9dzTkMxcUqY=,tag:t2UzVTh0cbuFOZm/RWyu9A==,type:str]",
+ "data": "ENC[AES256_GCM,data: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,iv:OFKpx7VTY03kM9Dgf/LFkhweMwJabQ/Rf6IVdIWOAVI=,tag:WMQvgxLCmIbrDCuEyyyUOQ==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
@@ -15,10 +15,10 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0cGZFU3FrZTVsNFE2ZGVn\nKzRabVo4Y2tLWEZrbW1aY1oydkZWbWFxV1FFClE5dkR2N1RFaWRvYlNwaUh0VGNx\nakVnbW84T3pGc1lGNzlLNmRMdHNzN2sKLS0tIEhZbENEUTdLQ0laL1B5Tmd3UW5h\nTWtlZFp2bXFHQ0tYK1pSV2xPSHhJeGMKV2WF/21OkoIUBSViIzX5pXZX+8OIwkuP\nb/4owrDej1otYCczA7upnO8d7r9HgdzV0PohZ9ghY+L7xMDtE2Pb0A==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
- "lastmodified": "2025-01-05T05:36:06Z",
- "mac": "ENC[AES256_GCM,data:Xm8OaOdmS+XIP1vIA1XUAzM0rvoSXtVmVa3TnyCL5d0hHtJ0WHgCadiEmdngNWaizZ/HyqUipMOR5dRbZSa2KErqvtMXABT5NeoTGQOf11Ug7E+cShfMkEedFXNJ45/qntgpqcd8JqfVHHtcbSb7ccnUapMOFRygtudDb/lHADA=,iv:bVEgaFam+OC5+iGOTA4tH8vU1RRcmuc5tAT03snYgXg=,tag:VMTJjmfH7Qf1/xyQWJFEhA==,type:str]",
+ "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.0"
+ "version": "3.9.1"
}
}
\ No newline at end of file
diff --git a/modules/nixos/raspberry-pi/default.nix b/modules/nixos/raspberry-pi/default.nix
new file mode 100644
index 0000000..611a367
--- /dev/null
+++ b/modules/nixos/raspberry-pi/default.nix
@@ -0,0 +1,8 @@
+{inputs, ...}: {
+ imports = [
+ inputs.raspberry-pi-nix.nixosModules.raspberry-pi
+ ];
+ nixpkgs.overlays = [
+ inputs.raspberry-pi-nix.overlays.core
+ ];
+}
diff --git a/overlays/jellyfin.nix b/overlays/jellyfin.nix
new file mode 100644
index 0000000..5a34f6d
--- /dev/null
+++ b/overlays/jellyfin.nix
@@ -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###" dist/index.html
+
+ mkdir -p $out/share
+ cp -a dist $out/share/jellyfin-web
+
+ runHook postInstall
+ '';
+ });
+ };
+}
diff --git a/overlays/kodi.nix b/overlays/kodi.nix
index 6c9efe4..1dee6e3 100644
--- a/overlays/kodi.nix
+++ b/overlays/kodi.nix
@@ -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 {};
}
diff --git a/pkgs/kodi/default.nix b/pkgs/kodi/default.nix
new file mode 100644
index 0000000..667fec8
--- /dev/null
+++ b/pkgs/kodi/default.nix
@@ -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
+ ])
diff --git a/pkgs/kodiPackages/advanced-emulator-launcher/default.nix b/pkgs/kodiPackages/advanced-emulator-launcher/default.nix
new file mode 100644
index 0000000..92dd5c5
--- /dev/null
+++ b/pkgs/kodiPackages/advanced-emulator-launcher/default.nix
@@ -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=";
+ };
+}
diff --git a/profiles/home-manager/kodi@pi0/home.nix b/profiles/home-manager/kodi@pi0/home.nix
new file mode 100644
index 0000000..d057252
--- /dev/null
+++ b/profiles/home-manager/kodi@pi0/home.nix
@@ -0,0 +1,11 @@
+{ outputs
+, ...
+}:
+{
+ imports = [
+ outputs.homeManagerModules.base
+ outputs.homeManagerModules.shell
+ ];
+
+ home.stateVersion = "24.11";
+}
diff --git a/profiles/nixos/pi0/configuration.nix b/profiles/nixos/pi0/configuration.nix
index bc70bf0..8765416 100644
--- a/profiles/nixos/pi0/configuration.nix
+++ b/profiles/nixos/pi0/configuration.nix
@@ -1,61 +1,45 @@
-/*
- {
- outputs,
- flakeLib,
- vars,
- ...
- }: {
- imports = [
- outputs.nixosModules.base
- outputs.nixosModules.home-manager
- ./hardware-configuration.nix
- ];
-
- networking = {
- inherit (vars) hostName domain;
- };
-
- home-manager.users = flakeLib.mkNixosHomeConfiguration {inherit vars;};
- }
-*/
-
{ 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
+{
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;
networking = {
inherit (vars) hostName domain;
};
- boot = {
- kernelPackages = pkgs.linuxPackages_rpi4;
- kernelParams = [ "snd_bcm2835.enable_headphones=1" "snd_bcm2835.enable_hdmi=1" ];
- initrd.availableKernelModules = [
- # Allows early (earlier) modesetting for the Raspberry Pi
- "vc4"
- "bcm2835_dma"
- "i2c_bcm2835"
- "xhci_pci"
- "usbhid"
- "usb_storage"
- ];
- };
-
fileSystems = {
- "/" = {
- device = "/dev/disk/by-label/NIXOS_SD";
- fsType = "ext4";
- options = [ "noatime" ];
- };
"/media/net/hel_Public" = {
device = "hel.odie.home.arpa:/nfs/Public";
fsType = "nfs";
@@ -70,28 +54,9 @@
};
};
- swapDevices = [{
- device = "/var/lib/swapfile";
- size = 4 * 1024;
- }];
-
- hardware = {
- raspberry-pi."4" = {
- apply-overlays-dtmerge.enable = true;
- fkms-3d.enable = true;
- };
- enableRedistributableFirmware = true;
- };
-
home-manager = {
- extraSpecialArgs = {
- inherit inputs outputs;
- };
- useGlobalPkgs = true;
- useUserPackages = true;
users = {
- kodi = import ../../home-manager/kodi/pi0;
- odie = import ../../home-manager/odie/pi0;
+ kodi = let profile = "kodi@pi0"; in import ../../home-manager/${profile}/home.nix;
};
};
@@ -107,19 +72,62 @@
programs.zsh.enable = true;
- services.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"
- '';
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
- system = {
- stateVersion = "23.05";
+ 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 = {
- hostPlatform.system = "aarch64-linux";
- # Fix missing modules
- # https://github.com/NixOS/nixpkgs/issues/154163
overlays = [
(final: prev: {
makeModulesClosure = x: prev.makeModulesClosure (x // { allowMissing = true; });
diff --git a/profiles/nixos/pi0/hardware-configuration.nix b/profiles/nixos/pi0/hardware-configuration.nix
index 30a0f17..4efa7c8 100644
--- a/profiles/nixos/pi0/hardware-configuration.nix
+++ b/profiles/nixos/pi0/hardware-configuration.nix
@@ -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";
diff --git a/remote-deploy.sh b/remote-deploy.sh
index 80d04a6..faa5cad 100755
--- a/remote-deploy.sh
+++ b/remote-deploy.sh
@@ -5,6 +5,6 @@ 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
+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