Rebase to flake parts #7

This commit is contained in:
2026-05-08 19:12:16 -03:00
parent 1015cf4577
commit f98606dcce
23 changed files with 1060 additions and 11 deletions
+50
View File
@@ -0,0 +1,50 @@
{ ... }: {
flake.nixosModules.systemBluetooth =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.bluetooth;
d = config.chiasson.desktop or { };
guiEnabled =
((d.hyprland or { }).enable or false)
|| ((d.niri or { }).enable or false)
|| ((d.plasma or { }).enable or false);
in
{
options.chiasson.system.bluetooth = {
enable = lib.mkEnableOption ''
BlueZ defaults (power on boot, experimental, fast connectable). Pull via `client-services` or direct import; off on BT-less boxes.
'' // {
default = true;
};
installBluejay = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
[Bluejay](https://invent.kde.org/plasma/bluejay) on GUI hosts with BT. False `bluetoothctl` only.
'';
};
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Experimental = true;
FastConnectable = true;
};
Policy = {
AutoEnable = true;
};
};
};
})
(lib.mkIf (cfg.enable && cfg.installBluejay && guiEnabled) {
environment.systemPackages = [ pkgs.bluejay ];
})
];
};
}
-1
View File
@@ -5,7 +5,6 @@
self.nixosModules.systemLocalization
self.nixosModules.systemFonts
self.nixosModules.systemNetworking
self.nixosModules.systemRemoteDesktop
self.nixosModules.systemLocalsend
self.nixosModules.systemMonitorInput
self.nixosModules.systemSpotify
+36
View File
@@ -0,0 +1,36 @@
{ ... }: {
flake.nixosModules.systemDocker =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.docker;
in
{
options.chiasson.system.docker = {
enable = lib.mkEnableOption ''
`virtualisation.docker` add users to `docker` if they need the socket.
'';
compose.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Install `docker-compose` in `environment.systemPackages`.";
};
daemonSettings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Merged into `virtualisation.docker.daemon.settings`.";
};
};
config = lib.mkIf cfg.enable {
virtualisation.docker = {
enable = true;
enableOnBoot = true;
daemon.settings = cfg.daemonSettings;
};
environment.systemPackages = lib.optionals cfg.compose.enable [ pkgs.docker-compose ];
};
};
}
+125
View File
@@ -0,0 +1,125 @@
{ ... }: {
flake.nixosModules.systemFlatpak =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.flatpak;
flathubForSystem =
lib.filter
(
app:
if lib.elem app cfg.flathub.x86Only
then pkgs.stdenv.hostPlatform.system == "x86_64-linux"
else true
)
cfg.flathub.appIds;
allowedAppIds = cfg.flathub.appIds ++ cfg.unmanaged.appIds;
# Bump in Nix when allowlists change; used to skip slow `flatpak update` / `uninstall --unused` on no-op rebuilds.
declarativeHash = builtins.hashString "sha256" (
lib.concatStringsSep "\n" (
[ "allowed" ]
++ lib.sort lib.lessThan allowedAppIds
++ [ "flathub" ]
++ lib.sort lib.lessThan flathubForSystem
)
);
stateFile = "/var/lib/nixos/flatpak-declarative.hash";
in
{
options.chiasson.system.flatpak = {
enable = lib.mkEnableOption ''
System Flatpak (`services.flatpak`) plus an activation script: Flathub remote, allowlisted apps,
and removals for anything else. User Flatpak stays in Home Manager.
'';
runHeavyMaintenanceEverySwitch = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
When false (default), `flatpak update` and `flatpak uninstall --unused` run only if the
allowlists changed (hash in `/var/lib/nixos/flatpak-declarative.hash`). Remotes, removals,
and per-app `install` still run every activation. True = full update/unused every switch.
'';
};
flathub.appIds = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Flathub app IDs to install system-wide.";
};
flathub.x86Only = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Subset of `flathub.appIds` only installed on x86_64-linux.";
};
unmanaged.appIds = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "com.hypixel.HytaleLauncher" ];
description = ''
Installed from elsewhere (not Flathub); never auto-installed and never removed by the script.
'';
};
};
config = lib.mkIf cfg.enable {
services.flatpak.enable = true;
system.activationScripts.flatpakManagement = {
text = ''
STATE_FILE=${lib.escapeShellArg stateFile}
WANT_HASH=${lib.escapeShellArg declarativeHash}
HEAVY=${if cfg.runHeavyMaintenanceEverySwitch then "1" else "0"}
mkdir -p /var/lib/nixos
# Never remote-delete flathub here interactive and breaks unattended rebuilds.
${pkgs.flatpak}/bin/flatpak --system remote-add --if-not-exists flathub \
https://flathub.org/repo/flathub.flatpakrepo || true
${pkgs.flatpak}/bin/flatpak --system remote-modify flathub \
--url=https://flathub.org/repo/flathub.flatpakrepo 2>/dev/null || true
allowed=( ${lib.concatStringsSep " " (map lib.escapeShellArg allowedAppIds)} )
installedFlatpaks=$(${pkgs.flatpak}/bin/flatpak --system list --app --columns=application)
for installed in $installedFlatpaks; do
keep=0
for a in "''${allowed[@]}"; do
if [ "$installed" = "$a" ]; then
keep=1
break
fi
done
if [ "$keep" -eq 0 ]; then
echo "flatpak: removing $installed (not in allowed list)."
${pkgs.flatpak}/bin/flatpak --system uninstall -y --noninteractive "$installed"
fi
done
for app in ${lib.escapeShellArgs flathubForSystem}; do
echo "flatpak: ensuring $app (Flathub)."
if ! ${pkgs.flatpak}/bin/flatpak --system install -y --noninteractive flathub "$app"; then
echo "flatpak: WARN failed to install $app (skip)." >&2
fi
done
run_heavy=0
if [ "$HEAVY" -eq 1 ]; then
run_heavy=1
elif [ ! -f "$STATE_FILE" ] || [ "$(cat "$STATE_FILE")" != "$WANT_HASH" ]; then
run_heavy=1
fi
if [ "$run_heavy" -eq 1 ]; then
${pkgs.flatpak}/bin/flatpak --system uninstall --unused -y --noninteractive || true
${pkgs.flatpak}/bin/flatpak --system update -y --noninteractive || true
printf '%s' "$WANT_HASH" > "$STATE_FILE"
else
echo "flatpak: allowlists unchanged skipping update and uninstall --unused."
fi
'';
};
};
};
}
+128
View File
@@ -0,0 +1,128 @@
{ ... }: {
flake.nixosModules.systemGaming =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.gaming;
launcherPkgs =
with pkgs;
[
lutris
bottles
wine
winetricks
gamemode
mangohud
goverlay
]
++ lib.optionals pkgs.stdenv.isx86_64 [ heroic ];
steamExtraPkgs =
if !cfg.steam.steamTinkerLaunch.enable then
[ ]
else
lib.optional (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.steamtinkerlaunch) pkgs.steamtinkerlaunch;
in
{
options.chiasson.system.gaming = {
enable = lib.mkEnableOption ''
Steam (+ firewall toggles), 32-bit GL/Vulkan, gamemode, JACK via PipeWire, launcher bundle.
'';
steam = {
remotePlay.openFirewall = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Open firewall for Steam Remote Play.";
};
dedicatedServer.openFirewall = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Open firewall for Steam dedicated servers.";
};
steamTinkerLaunch.enable = lib.mkEnableOption ''
[SteamTinkerLaunch](https://github.com/frostworx/steamtinkerlaunch) Steam wrapper for
custom launch options, Proton helpers, and third-party tools. Adds `pkgs.steamtinkerlaunch`
next to the launcher package set (`environment.systemPackages` or `launchers.forUsers`).
'';
};
graphics = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "`hardware.graphics.enable` (Vulkan/GL stack).";
};
enable32Bit = lib.mkOption {
type = lib.types.bool;
default = true;
description = "`hardware.graphics.enable32Bit` (Steam / Proton 32-bit).";
};
};
gamemode.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "`programs.gamemode` (Feral GameMode).";
};
jack.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Set `chiasson.system.audio.pipewire.jack.enable` (PipeWire JACK). Requires
`chiasson.system.audio.enable` on the host.
'';
};
launchers = {
forUsers = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
default = null;
description = ''
Per-user `packages` for launchers; `null` `environment.systemPackages`.
'';
};
extraPackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
description = "Additional packages merged with the default launcher set.";
};
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
programs.steam = {
enable = true;
remotePlay.openFirewall = cfg.steam.remotePlay.openFirewall;
dedicatedServer.openFirewall = cfg.steam.dedicatedServer.openFirewall;
};
hardware.graphics = lib.mkIf cfg.graphics.enable {
enable = true;
enable32Bit = cfg.graphics.enable32Bit;
};
programs.gamemode.enable = cfg.gamemode.enable;
chiasson.system.audio.pipewire.jack.enable = lib.mkIf (cfg.jack.enable) (lib.mkDefault true);
assertions = [
{
assertion = !cfg.enable || !cfg.jack.enable || config.chiasson.system.audio.enable;
message = "chiasson.system.gaming with JACK requires `chiasson.system.audio.enable` (PipeWire).";
}
];
}
(lib.mkIf (cfg.launchers.forUsers == null) {
environment.systemPackages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
})
(lib.mkIf (cfg.launchers.forUsers != null) {
users.users = lib.genAttrs cfg.launchers.forUsers (_: {
packages = launcherPkgs ++ steamExtraPkgs ++ cfg.launchers.extraPackages;
});
})
]);
};
}
+43
View File
@@ -0,0 +1,43 @@
# Mobile NixOS mruby fails tests in sandbox — strip checks + rebuild script-loader. Import before device config.
{ inputs, ... }: {
flake.nixosModules.systemIdeapadMrubyOverlay =
{ config, lib, ... }:
let
cfg = config.chiasson.system.ideapadMrubyOverlay;
mobileNixosSrc = inputs.mobile-nixos;
in
{
options.chiasson.system.ideapadMrubyOverlay = {
enable = lib.mkEnableOption ''
Fix mruby for Mobile NixOS (no tests) + script-loader rebuild. Needs `mobile-nixos` input.
'';
};
config = lib.mkIf cfg.enable {
nixpkgs.overlays = lib.mkOrder 1000 [
(final: prev:
let
fixMruby =
drv:
drv.overrideAttrs (old: {
doCheck = false;
preCheck = (old.preCheck or "") + ''
export SHELL="${final.bash}/bin/bash"
unset SOURCE_DATE_EPOCH
'';
});
mrubyFixed =
prev.lib.makeOverridable (args: fixMruby (prev.mruby.override args)) { };
in
{
mruby = mrubyFixed;
mobile-nixos = (prev.mobile-nixos or { }) // {
script-loader = final.callPackage "${mobileNixosSrc}/boot/script-loader" {
mruby = mrubyFixed;
};
};
})
];
};
};
}
+19
View File
@@ -0,0 +1,19 @@
# LibrePods from NUR (nur.repos.chiasson) + Apple-ish BlueZ DeviceID for AirPods.
{ ... }: {
flake.nixosModules.systemLibrepods =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.librepods;
librepodsPkg = pkgs.nur.repos.chiasson.librepods;
in
{
options.chiasson.system.librepods.enable = lib.mkEnableOption ''
LibrePods (NUR chiasson) + BlueZ DeviceID tweak. Needs working Bluetooth.
'';
config = lib.mkIf cfg.enable {
hardware.bluetooth.settings.General.DeviceID = lib.mkDefault "bluetooth:004C:0000:0000";
environment.systemPackages = [ librepodsPkg ];
};
};
}
+48
View File
@@ -0,0 +1,48 @@
{ self, lib, ... }: {
flake.nixosModules.systemLocalization = {
config,
...
}:
let
cfg = config.chiasson.system.localization;
in
{
options.chiasson.system.localization = {
timeZone = lib.mkOption {
type = lib.types.str;
default = "America/Moncton";
description = "Default system timezone.";
};
defaultLocale = lib.mkOption {
type = lib.types.str;
default = "en_CA.UTF-8";
description = "Default system locale.";
};
xkb = {
layout = lib.mkOption {
type = lib.types.str;
default = "ca";
description = "Default XKB layout.";
};
variant = lib.mkOption {
type = lib.types.str;
default = "";
description = "Default XKB variant.";
};
};
consoleKeyMap = lib.mkOption {
type = lib.types.str;
default = "cf";
description = "Default Linux console keymap.";
};
};
config = {
time.timeZone = lib.mkDefault cfg.timeZone;
i18n.defaultLocale = lib.mkDefault cfg.defaultLocale;
services.xserver.xkb.layout = lib.mkDefault cfg.xkb.layout;
services.xserver.xkb.variant = lib.mkDefault cfg.xkb.variant;
console.keyMap = lib.mkDefault cfg.consoleKeyMap;
};
};
}
+90
View File
@@ -0,0 +1,90 @@
{ ... }: {
flake.nixosModules.systemNetworking = {
config,
lib,
pkgs,
...
}:
let
cfg = config.chiasson.system.networking;
in
{
options.chiasson.system.networking = {
hostName = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "t2mbp";
description = "System hostname.";
};
networkManager = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable NetworkManager.";
};
unmanaged = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Interfaces/patterns for NetworkManager to leave unmanaged.";
};
};
wifi.tools = {
enabled = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Install Wi-Fi troubleshooting tools.";
};
packages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = with pkgs; [
iw
wirelesstools
];
description = "Wi-Fi troubleshooting packages.";
};
};
firewall = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable host firewall.";
};
allowedTCPPorts = lib.mkOption {
type = lib.types.listOf lib.types.port;
default = [ ];
description = "TCP ports allowed through firewall.";
};
allowedUDPPorts = lib.mkOption {
type = lib.types.listOf lib.types.port;
default = [ ];
description = "UDP ports allowed through firewall.";
};
};
};
config = lib.mkMerge [
(lib.mkIf (cfg.hostName != null) {
networking.hostName = cfg.hostName;
})
(lib.mkIf cfg.networkManager.enable {
networking.networkmanager.enable = true;
networking.networkmanager.unmanaged = cfg.networkManager.unmanaged;
})
(lib.mkIf cfg.wifi.tools.enabled {
environment.systemPackages = cfg.wifi.tools.packages;
})
{
networking.firewall.enable = cfg.firewall.enable;
}
(lib.mkIf (cfg.firewall.allowedTCPPorts != [ ]) {
networking.firewall.allowedTCPPorts = cfg.firewall.allowedTCPPorts;
})
(lib.mkIf (cfg.firewall.allowedUDPPorts != [ ]) {
networking.firewall.allowedUDPPorts = cfg.firewall.allowedUDPPorts;
})
];
};
}
@@ -0,0 +1,30 @@
{ ... }: {
flake.nixosModules.systemUconsoleKernelBuilder =
{ config, lib, pkgs, ... }:
let
cfg = config.chiasson.system.uconsoleKernelBuilder;
in
{
options.chiasson.system.uconsoleKernelBuilder = {
enable = lib.mkEnableOption ''
x86_64 box: binfmt aarch64, looser sandbox, uConsole cache, ccache for building the Pi image. Not for the device.
'';
};
config = lib.mkIf cfg.enable {
nix.settings = {
extra-platforms = lib.mkDefault [ "aarch64-linux" ];
# Cross builds hit seccomp weirdness — turn sandbox off on this role.
sandbox = lib.mkDefault false;
filter-syscalls = lib.mkDefault false;
extra-sandbox-paths = [ config.programs.ccache.cacheDir ];
};
boot.binfmt.emulatedSystems = lib.mkDefault [ "aarch64-linux" ];
programs.ccache.enable = true;
};
};
}
+76
View File
@@ -0,0 +1,76 @@
# Shared user definitions for all hosts that import `nixosModules.users`.
# Module (not bare attrset) so catalog entries can use `config.*` for sops paths etc.
{ ... }: {
flake.nixosModules.usersCatalogDefaults =
{ config, ... }:
{
config.chiasson.users.catalog = {
olivier = {
isNormalUser = true;
description = "Olivier";
extraGroups = [
"networkmanager"
"wheel"
"libvirtd"
"docker"
"fuse"
"uinput"
"kvm"
];
# Host must set `sops.secrets."users/olivier/hashedPassword".neededForUsers = true`.
# With that, `.path` is under /run/secrets-for-users/… (sops-nix README).
hashedPasswordFile = config.sops.secrets."users/olivier/hashedPassword".path;
homeManager = {
enable = true;
module =
{ ... }:
{
home.username = "olivier";
home.homeDirectory = "/home/olivier";
home.stateVersion = "25.11";
programs.home-manager.enable = true;
};
};
ssh = {
inbound = {
enable = true;
authorizedHosts = "all";
};
outbound = {
rbw = {
enable = true;
hosts = "all";
};
};
};
};
server = {
isNormalUser = true;
description = "Server user";
extraGroups = [ "wheel" ];
homeManager = {
enable = false;
module = null;
};
ssh = {
inbound = {
enable = true;
authorizedHosts = "all";
};
outbound = {
rbw = {
enable = false;
hosts = "all";
};
};
};
};
};
};
}