refactor: Fully modularize the working system components to be more

reuasable
This commit is contained in:
2025-12-09 17:38:41 -05:00
committed by Hunter Halloran
parent 0e5c993a26
commit ebb70eca07
31 changed files with 923 additions and 754 deletions

69
sw/default.nix Normal file
View File

@@ -0,0 +1,69 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.sw;
in
{
imports = [
./python.nix
];
options.modules.sw = {
enable = mkEnableOption "Standard Workstation Configuration";
type = mkOption {
type = types.enum [ "desktop" "kiosk" ];
default = "desktop";
description = "Type of system configuration: 'desktop' for normal OS, 'kiosk' for tablet/kiosk mode.";
};
extraPackages = mkOption {
type = types.listOf types.package;
default = [];
description = "Extra packages to install.";
};
excludePackages = mkOption {
type = types.listOf types.package;
default = [];
description = "Packages to exclude from the default list.";
};
};
config = mkIf cfg.enable (mkMerge [
{
nixpkgs.config.allowUnfree = true;
programs.zsh.enable = true;
programs.nix-ld.enable = true;
environment.systemPackages = with pkgs; subtractLists cfg.excludePackages [
htop
binutils
zsh
git
oh-my-posh
inputs.lazyvim-nixvim.packages.${stdenv.hostPlatform.system}.nvim
(writeShellScriptBin "update-system" ''
HOSTNAME=$(hostname)
FLAKE_URI="github:UGA-Innovation-Factory/nixos-systems"
# Pass arguments like --impure to nixos-rebuild
EXTRA_ARGS="$@"
if [[ "$HOSTNAME" == nix-surface* ]]; then
echo "Detected Surface tablet. Using remote build host."
sudo nixos-rebuild switch --flake "$FLAKE_URI" --build-host engr-ugaif@192.168.11.133 --refresh $EXTRA_ARGS
else
echo "Updating local system..."
sudo nixos-rebuild switch --flake "$FLAKE_URI" --refresh $EXTRA_ARGS
fi
'')
];
}
(mkIf (cfg.type == "desktop") (import ./desktop { inherit config lib pkgs inputs; }))
(mkIf (cfg.type == "kiosk") (import ./kiosk { inherit config lib pkgs inputs; }))
]);
}

5
sw/desktop/default.nix Normal file
View File

@@ -0,0 +1,5 @@
{ config, lib, pkgs, inputs, ... }:
lib.mkMerge [
(import ./programs.nix { inherit config lib pkgs inputs; })
(import ./services.nix { inherit config lib pkgs inputs; })
]

29
sw/desktop/programs.nix Normal file
View File

@@ -0,0 +1,29 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.sw;
basePackages = with pkgs; [
tmux
man
(chromium.override {
commandLineArgs = [ "--enable-features=TouchpadOverscrollHistoryNavigation" ];
})
lm_sensors
zoom-us
teams-for-linux
wpsoffice
];
in {
environment.systemPackages = subtractLists cfg.excludePackages (basePackages ++ cfg.extraPackages);
programs.mtr.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
programs.firefox.enable = true;
programs.virt-manager.enable = true;
}

51
sw/desktop/services.nix Normal file
View File

@@ -0,0 +1,51 @@
{ config, lib, pkgs, ... }:
{
modules.sw.python.enable = lib.mkDefault true;
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
services.printing.enable = true;
networking.networkmanager.enable = true;
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
fonts.packages = with pkgs; [
nerd-fonts.fira-code
corefonts
noto-fonts
];
fonts.fontconfig = {
enable = true;
defaultFonts.monospace = [ "FiraCode Nerd Font Mono" ];
};
hardware.bluetooth.enable = true;
services.blueman.enable = true;
networking.firewall.enable = true;
services.flatpak.enable = true;
xdg.portal.enable = true;
xdg.portal.extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde ];
virtualisation.libvirtd.enable = true;
services.thermald.enable = true;
services.fwupd.enable = true;
services.openssh = {
enable = true;
settings.PermitRootLogin = "no";
};
}

6
sw/kiosk/default.nix Normal file
View File

@@ -0,0 +1,6 @@
{ config, lib, pkgs, inputs, ... }:
lib.mkMerge [
(import ./programs.nix { inherit config lib pkgs inputs; })
(import ./services.nix { inherit config lib pkgs inputs; })
(import ./gsettings.nix { inherit config lib pkgs inputs; })
]

50
sw/kiosk/gsettings.nix Normal file
View File

@@ -0,0 +1,50 @@
{ config, lib, inputs, ... }:
let
cfg = config.modules.sw;
in {
programs.dconf = {
enable = true;
profiles.user = {
databases = [{
settings = {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
clock-format = "12h";
clock-show-weekday = true;
show-battery-percentage = true;
};
"org/gnome/desktop/media-handling" = {
automount = false;
automount-open = false;
autorun-never = true;
};
"org/gnome/settings-daemon/plugins/power" = {
sleep-inactive-ac-type = "nothing";
};
"org/gnome/desktop/lockdown" = {
disable-lock-screen = true;
};
"org/gnome/desktop/screensaver" = {
lock-enabled = false;
};
"org/gnome/desktop/session" = {
idle-delay = inputs.nixpkgs.lib.gvariant.mkUint32 0;
};
"org/gnome/desktop/input-sources" = {
sources = "[('ibus', 'xkb:us::eng')]";
};
"org/gnome/desktop/mru-sources" = {
sources = "[('ibus', 'xkb:us::eng')]";
};
"sm/puri/phosh" = {
lock-enabled = false;
};
"org/gnome/desktop/a11y/applications" = {
screen-keyboard-enabled = true;
};
};
}];
};
};
}

22
sw/kiosk/programs.nix Normal file
View File

@@ -0,0 +1,22 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.sw;
basePackages = with pkgs; [
libcamera
chromium
glib
squeekboard
dconf
phoc
gsettings-desktop-schemas
];
in {
environment.systemPackages = subtractLists cfg.excludePackages (basePackages ++ cfg.extraPackages);
programs.chromium = {
enable = true;
};
}

156
sw/kiosk/services.nix Normal file
View File

@@ -0,0 +1,156 @@
{ config, lib, pkgs, ... }:
{
services.xserver = {
enable = true;
desktopManager.phosh = {
enable = true;
user = "engr-ugaif";
group = "users";
};
};
services.displayManager.gdm = {
enable = true;
autoSuspend = false;
};
services.displayManager.autoLogin = {
enable = true;
user = "engr-ugaif";
};
services.dbus.enable = true;
services.fwupd.enable = true;
i18n.inputMethod = {
type = "ibus";
enable = true;
ibus.engines = [ pkgs.ibus-engines.m17n ];
};
services.gnome.gnome-keyring.enable = lib.mkForce false;
environment.sessionVariables = {
GDK_SCALE = "1.25";
GDK_DPI_SCALE = "0.5";
# Make GLib / gsettings actually see schemas
XDG_DATA_DIRS = [ "/run/current-system/sw/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}" ];
GSETTINGS_SCHEMA_DIR =
"/run/current-system/sw/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}/glib-2.0/schemas";
};
environment.etc."machine-info".text = ''
CHASSIS=handset
'';
services.logind.settings.Login = {
HandlePowerKey="ignore";
HandleSuspendKey="ignore";
HandleHibernateKey="ignore";
HandleLidSwitch="ignore";
HandleLidSwitchExternalPower="ignore";
IdleAction="ignore";
};
# Enable networking
networking.networkmanager.enable = false;
networking.wireless = {
enable = true;
networks = {
"IOT_vr" = {
ssid = "IOT_vr";
pskRaw = "849a13f095b73a3d038a904576fd8ad4b83da81d285acaf435b545c1560c7e27";
authProtocols = [ "WPA-PSK" ];
};
"IOT_sensors".psk = "aaaaaaaa";
};
};
# Enable sound with pipewire.
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
wireplumber.enable = true;
};
fonts.packages = with pkgs; [
nerd-fonts.fira-code
];
fonts.fontconfig = {
enable = true;
defaultFonts.monospace = [ "FiraCode Nerd Font Mono" ];
};
systemd.user.services.squeekboard = {
description = "Squeekboard on-screen keyboard";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.squeekboard}/bin/squeekboard";
Restart = "on-failure";
};
};
systemd.user.services."force-osk" = {
description = "Force the OSK to Enable";
wantedBy = [ "chromium-kiosk.service" ];
partOf = [ "chromium-kiosk.service" ];
serviceConfig = {
ExecStartPre = ''
/run/current-system/sw/bin/sleep 5
'';
ExecStart = ''
/run/current-system/sw/bin/dconf reset /org/gnome/desktop/a11y/applications/screen-keyboard-enabled
'';
Type = "simple";
};
};
systemd.user.services."force-input-sources" = {
description = "Force the Gsettings Input Sources";
wantedBy = [ "chromium-kiosk.service" ];
partOf = [ "chromium-kiosk.service" ];
serviceConfig = {
ExecStartPre = ''
/run/current-system/sw/bin/sleep 5
'';
ExecStart = ''
/run/current-system/sw/bin/dconf reset /org/gnome/desktop/input-sources/sources
'';
ExecStartPost = ''
/run/current-system/sw/bin/dconf reset /org/gnome/desktop/mru-sources/sources
'';
Type = "simple";
};
};
systemd.user.services."chromium-kiosk" = {
description = "Chromium kiosk";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = ''
${pkgs.chromium}/bin/chromium \
--enable-features=UseOzonePlatform,TouchpadOverscrollHistoryNavigation,PullToRefresh \
--ozone-platform=wayland \
--kiosk \
--start-fullscreen \
--noerrdialogs \
--disable-session-crashed-bubble \
--disable-infobars \
https://ha.factory.uga.edu
'';
};
};
}

15
sw/nvim.nix Normal file
View File

@@ -0,0 +1,15 @@
{ pkgs, ... }:
{
# https://github.com/nvim-treesitter/nvim-treesitter#i-get-query-error-invalid-node-type-at-position
xdg.configFile."nvim/parser".source =
let
parsers = pkgs.symlinkJoin {
name = "treesitter-parsers";
paths = (pkgs.vimPlugins.nvim-treesitter.withPlugins (plugins: with plugins; [
c
lua
])).dependencies;
};
in
"${parsers}/parser";
}

22
sw/python.nix Normal file
View File

@@ -0,0 +1,22 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.modules.sw.python;
in {
options.modules.sw.python = {
enable = mkEnableOption "Python development tools (pixi, uv)";
};
config = mkIf cfg.enable {
environment.systemPackages = [
(pkgs.buildFHSEnv {
name = "pixi";
runScript = "pixi";
targetPkgs = pkgs: with pkgs; [ pixi ];
})
pkgs.uv
];
};
}

71
sw/theme.nix Normal file
View File

@@ -0,0 +1,71 @@
{ pkgs, config, osConfig, lib, ... }:
let
# Fetch upstream OMP theme once
jyumppTheme = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Jyumpp/jyumpp-zsh-theme/refs/heads/master/.jyumpp.omp.json";
hash = "sha256-jsN3hkyT0dJNTYEmDHQPp++oscQLgYGNj7PZAcIW2TA=";
};
# Make a root variant with red username (wraps {{ .UserName }} with ANSI red)
jyumppRootTheme = pkgs.runCommand "jyumpp-root.omp.json" {} ''
sed -E 's|\{\{[[:space:]]*\.UserName[[:space:]]*\}\}|<#FF3B30>{{ .UserName }}</>|g' \
${jyumppTheme} > $out
'';
isRoot = config.home.username == "root";
themeFile = if isRoot then jyumppRootTheme else jyumppTheme;
isZsh = osConfig.modules.users.shell == pkgs.zsh;
in
{
config = lib.mkIf isZsh {
programs.zsh = {
enable = true;
# Plugins
historySubstringSearch = {
enable = true;
searchDownKey = "^[[B";
searchUpKey = "^[[A";
};
zplug = lib.mkIf (!isRoot) {
enable = true;
plugins = [
{
name = "jeffreytse/zsh-vi-mode";
}
{
name = "BronzeDeer/zsh-completion-sync";
}
];
};
history = {
append = true;
};
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
};
programs.zoxide = lib.mkIf (!isRoot) {
enable = true;
enableZshIntegration = true;
};
programs.lsd = lib.mkIf (!isRoot) {
enable = true;
enableZshIntegration = true;
};
programs.oh-my-posh = {
enable = true;
enableZshIntegration = true;
enableBashIntegration = true;
settings = builtins.fromJSON (builtins.unsafeDiscardStringContext (builtins.readFile themeFile));
};
};
}