Add Steam Deck (nix-deck) configuration with Jovian-NixOS and remote building

- Add Jovian-NixOS integration for Steam Deck hardware support
- Create nix-deck machine configuration with SteamOS role
- Add jovian-compat.nix for NixOS 25.05 compatibility (remove in 25.11+)
- Create remote-build role for distributed builds
- Configure zix790prors as build host
- Configure nix-book and nix-deck to use remote builder with fallback
- Add comprehensive setup documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-17 15:42:33 -08:00
parent 4ea9437bb0
commit 2283b0a6df
12 changed files with 646 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ with lib;
./nfs-mounts
./nvidia
./printing
./remote-build
./spotifyd
./users
./virtualisation

View File

@@ -23,5 +23,6 @@ with lib;
./kde.nix
./programs.nix
./sddm.nix
./steamos.nix
];
}

47
roles/desktop/steamos.nix Normal file
View File

@@ -0,0 +1,47 @@
{ lib, config, pkgs, ... }:
with lib;
let
cfg = config.roles.desktop;
in
{
options.roles.desktop.steamos = {
enable = mkEnableOption "SteamOS (Jovian) configuration";
autoStart = mkOption {
type = types.bool;
default = false;
description = "Automatically start Steam Deck UI on boot";
};
user = mkOption {
type = types.str;
default = "johno";
description = "User to run Steam as";
};
desktopSession = mkOption {
type = types.nullOr types.str;
default = null;
description = "Desktop session to launch when switching to Desktop Mode";
};
enableDeckyLoader = mkOption {
type = types.bool;
default = true;
description = "Enable Decky Loader plugin system";
};
};
config = mkIf (cfg.enable && cfg.steamos.enable) {
jovian.steam = {
enable = true;
autoStart = cfg.steamos.autoStart;
user = cfg.steamos.user;
desktopSession = cfg.steamos.desktopSession;
};
jovian.decky-loader.enable = cfg.steamos.enableDeckyLoader;
};
}

43
roles/jovian-compat.nix Normal file
View File

@@ -0,0 +1,43 @@
{ lib, config, ... }:
# Compatibility shim to provide services.logind.settings for NixOS 25.05
# This allows Jovian-NixOS to work with stable NixOS
# REMOVE THIS FILE when upgrading to NixOS 25.11 or later
with lib;
let
nixosVersion = config.system.nixos.release;
isCompatibleVersion = versionOlder nixosVersion "25.11";
in
{
options.services.logind.settings = mkOption {
type = types.attrsOf (types.attrsOf types.anything);
default = {};
description = "systemd-logind configuration. See logind.conf(5) for available options.";
};
config = mkMerge [
{
assertions = [
{
assertion = isCompatibleVersion;
message = ''
The Jovian compatibility shim (roles/jovian-compat.nix) is only needed for NixOS 25.05 and earlier.
You are running NixOS ${nixosVersion}.
Please remove 'roles/jovian-compat.nix' from your flake.nix imports.
'';
}
];
}
(mkIf (config.services.logind.settings != {}) {
# Convert the settings to extraConfig format for older NixOS
services.logind.extraConfig = let
mkSection = section: settings:
"[${section}]\n" +
(concatStringsSep "\n" (mapAttrsToList (k: v: "${k}=${toString v}") settings));
in
concatStringsSep "\n\n" (mapAttrsToList mkSection config.services.logind.settings);
})
];
}

View File

@@ -0,0 +1,127 @@
{ lib, config, pkgs, ... }:
with lib;
let
cfg = config.roles.remote-build;
in
{
options.roles.remote-build = {
enableBuilder = mkOption {
type = types.bool;
default = false;
description = "Enable this machine as a remote build host for other machines";
};
builderUser = mkOption {
type = types.str;
default = "nix-builder";
description = "User account for remote builders to connect as";
};
builders = mkOption {
type = types.listOf (types.submodule {
options = {
hostName = mkOption {
type = types.str;
description = "Hostname or IP address of the build machine";
};
systems = mkOption {
type = types.listOf types.str;
default = [ "x86_64-linux" ];
description = "Supported systems";
};
maxJobs = mkOption {
type = types.int;
default = 8;
description = "Maximum number of parallel build jobs";
};
speedFactor = mkOption {
type = types.int;
default = 2;
description = "Speed factor compared to local building (higher = prefer remote)";
};
supportedFeatures = mkOption {
type = types.listOf types.str;
default = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
description = "Supported build features";
};
sshUser = mkOption {
type = types.str;
default = "nix-builder";
description = "SSH user for connecting to the builder";
};
sshKey = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to SSH private key for authentication";
};
};
});
default = [];
description = "List of remote build machines to use";
};
fallbackToLocalBuild = mkOption {
type = types.bool;
default = true;
description = "Fallback to local building if remote builders are unavailable";
};
};
config = mkMerge [
# Builder host configuration
(mkIf cfg.enableBuilder {
# Create dedicated builder user
users.users.${cfg.builderUser} = {
isSystemUser = true;
group = cfg.builderUser;
description = "Nix remote build user";
home = "/var/lib/${cfg.builderUser}";
createHome = true;
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keyFiles = []; # Will be populated by client machines
};
users.groups.${cfg.builderUser} = {};
# Allow builder user to perform builds
nix.settings.trusted-users = [ cfg.builderUser ];
# Allow remote builds
services.openssh.enable = true;
# Ensure nix-daemon is accessible
nix.settings.allowed-users = [ "*" ];
})
# Client configuration (machines using remote builders)
(mkIf (cfg.builders != []) {
nix.buildMachines = map (builder: {
hostName = builder.hostName;
systems = builder.systems;
maxJobs = builder.maxJobs;
speedFactor = builder.speedFactor;
supportedFeatures = builder.supportedFeatures;
sshUser = builder.sshUser;
sshKey = builder.sshKey;
}) cfg.builders;
nix.distributedBuilds = true;
# Use substitutes from remote builders
nix.extraOptions = ''
builders-use-substitutes = true
'';
# Fallback to local build if remote unavailable
nix.settings.fallback = cfg.fallbackToLocalBuild;
})
];
}