Skip to content

refactor: consolidate NixOS hosts into shared builder - #1473

Merged
shunkakinoki merged 10 commits into
mainfrom
refactor/consolidate-nixos-hosts
Apr 14, 2026
Merged

refactor: consolidate NixOS hosts into shared builder#1473
shunkakinoki merged 10 commits into
mainfrom
refactor/consolidate-nixos-hosts

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Apr 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • All NixOS hosts (matic, viper, ISOs) now call hosts/nixos/default.nix with a modules param instead of duplicating pkgs/user/nix setup
  • Removed named-hosts/shared/linux-base.nix and named-hosts/shared/live-iso.nix (absorbed into hosts/nixos base)
  • Removed redundant environment.systemPackages from hosts that have home-manager (kept for viper and ISOs with comments explaining why)
  • Added isViper to lib/host.nix + nodeName + test

Structure

Host Has home-manager environment.systemPackages
x86_64-linux yes no (home-manager provides)
runner yes no (home-manager provides)
matic yes no (home-manager provides)
viper no yes (no home-manager)
viperIso no yes (bootstrap ISO)
maticIso no yes (bootstrap ISO)

Test plan

  • nix flake check passes on a NixOS host
  • nix build .#nixosConfigurations.matic.config.system.build.toplevel evaluates
  • nix build .#nixosConfigurations.viper.config.system.build.toplevel evaluates
  • ISO builds still work

Summary by cubic

Consolidated all NixOS hosts into a shared builder in hosts/nixos/default.nix to remove duplicate config and standardize setup. Also added a Slack-only xremap block and silenced read-only pkg and nixpkgs.pkgs warnings.

  • Refactors

    • Shared builder with modules, specialArgs, stateVersion, userExtraGroups, userInitialPassword; pins nixpkgs in /etc/nix, disables channels, sets nix-path, and adds trusted users (root, username, @wheel).
    • Fallback to generic x86_64-linux/runner config with home-manager when modules is null.
    • Recursion/warnings: set nixpkgs.pkgs via its own module; removed pkgs from specialArgs; pass pkgs to home-manager only where needed; import nixosModules.readOnlyPkgs.
    • Removed named-hosts/shared/linux-base.nix and named-hosts/shared/live-iso.nix.
    • Host updates: matic uses builder with extra groups (no initialPassword); viper uses builder with initialPassword and minimal system packages (no home-manager); ISOs use installer modules, minimal packages, set image.fileName, clear getty help line, set initialPassword.
    • flake.nix: passes stateVersion for x86_64-linux and runner. lib/host.nix: restored isDev, added isViper, expanded nodeName; tests updated.
    • home-manager: added a Slack-specific xremap block to isolate app workarounds; removed _pixelh_function.fish.
  • Migration

    • New hosts: import ./hosts/nixos { username; stateVersion; modules = [ ... ]; }.
    • Only set environment.systemPackages on hosts without home-manager (e.g., viper, ISOs).
    • Only set userInitialPassword for ISOs or test VMs; not for real machines like matic.

Written for commit b8e186d. Summary will update on new commits.

All NixOS hosts (matic, viper, ISOs) now inherit from hosts/nixos/default.nix
instead of duplicating pkgs setup, user config, and nix settings. Adds isViper
to lib/host.nix. Removes redundant environment.systemPackages from hosts with
home-manager.
@mesa-dot-dev

mesa-dot-dev Bot commented Apr 14, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@mesa-dot-dev

mesa-dot-dev Bot commented Apr 14, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Consolidated NixOS host configurations into a shared builder in hosts/nixos/default.nix to eliminate duplication and standardize setup across all NixOS hosts, including matic, viper, and various ISOs.

What changed?

  • hosts/nixos/default.nix: Refactored into a shared NixOS system builder with new parameters (modules, specialArgs, stateVersion, userExtraGroups, userInitialPassword), streamlining base configurations, conditionally applying generic modules, and improving home-manager integration.
  • flake.nix: Updated to explicitly set stateVersion for the x86_64-linux and runner NixOS hosts.
  • lib/host.nix: Introduced a new isViper host detection mechanism and expanded the nodeName attribute logic.
  • named-hosts/matic/default.nix: Refactored to utilize the shared ../../hosts/nixos module, centralizing its configuration.
  • named-hosts/matic/iso.nix: Simplified to use the shared ../../hosts/nixos import and standard NixOS installation modules, replacing the custom live-iso.nix module.
  • named-hosts/shared/linux-base.nix: Deleted, as its functionality is now absorbed by the shared NixOS builder.
  • named-hosts/shared/live-iso.nix: Removed entirely, replaced by the consolidated hosts/nixos module for ISO configurations.
  • named-hosts/viper/default.nix: Refactored to import the shared ../../hosts/nixos module, replacing its previous inline definition and direct linux-base.nix import.
  • named-hosts/viper/iso.nix: Updated to use the generic ../../hosts/nixos configuration, replacing a custom live ISO module.
  • tests/lib.nix: Added a new test to validate the host.isViper attribute.
  • home-manager/modules/xremap/default.nix: Introduced a dedicated slackRemap configuration block for Slack-specific key remappings.
  • home-manager/programs/fish/functions/_pixelh_function.fish: Deleted.

Description generated by Mesa. Update settings

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the NixOS configuration by introducing a more flexible and modular shared system builder in hosts/nixos/default.nix, which is now utilized by the matic and viper host configurations to reduce redundancy. Additionally, it introduces environment detection for the viper VM, updates the stateVersion for several hosts, and removes the isDev attribute. Feedback was provided regarding an orphaned comment in lib/host.nix that remained after the removal of isDev and should be deleted for better code clarity.

Comment thread lib/host.nix Outdated
# Install language server packages
isDev = true;

# Install language server package

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This comment appears to be orphaned and misplaced after the removal of the isDev attribute. It should be removed to maintain code clarity.

  # Get the node name for OpenClaw remote mode

@coderabbitai

coderabbitai Bot commented Apr 14, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@shunkakinoki has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 43 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 53 minutes and 43 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8420b2d8-7e61-4b89-aa70-cc676a8f66f9

📥 Commits

Reviewing files that changed from the base of the PR and between 6915b54 and b8e186d.

📒 Files selected for processing (1)
  • hosts/nixos/default.nix
📝 Walkthrough

Walkthrough

Centralized NixOS host construction into hosts/nixos/default.nix with new parameters (system, stateVersion, user options, modules, specialArgs); migrated named-hosts (matic, viper) and ISO builds to this wrapper, added isViper detection and test, removed two shared host modules, and adjusted flake imports to pass stateVersion.

Changes

Cohort / File(s) Summary
Core Host Builder Refactor
flake.nix, hosts/nixos/default.nix
Added a parameterizable host builder (system, stateVersion, userExtraGroups, userInitialPassword, modules, specialArgs); flake now passes stateVersion = "24.05" when importing hosts. BaseModule + conditional genericModules split and specialArgs extended.
Named Hosts → Central Wrapper
named-hosts/matic/default.nix, named-hosts/matic/iso.nix, named-hosts/viper/default.nix, named-hosts/viper/iso.nix
Replaced direct nixosSystem invocations with import ../../hosts/nixos { ... }; moved per-host configuration into modules passed to the shared builder; ISO files now include upstream installer modules and inline package/module overrides.
Removed Shared Modules
named-hosts/shared/linux-base.nix, named-hosts/shared/live-iso.nix
Deleted previously shared modules for base host config and live ISO; their behavior is migrated into the centralized host builder or inlined in host ISO modules.
Host Detection & Tests
lib/host.nix, tests/lib.nix
Added exported isViper (env HOSTNAME/HOST == "viper") and updated nodeName mapping; added test validation ensuring host.isViper is a boolean.
Home Manager / Misc
home-manager/modules/xremap/default.nix, home-manager/programs/fish/functions/_pixelh_function.fish
Added Slack-specific xremap keymap (application-scoped remap). Removed _pixelh_function Fish function file.

Sequence Diagram(s)

sequenceDiagram
  participant Flake as flake.nix
  participant Builder as hosts/nixos/default.nix
  participant Named as named-hosts/*/{default,iso}.nix
  participant Nixpkgs as inputs.nixpkgs

  Flake->>Builder: import with inputs, username, stateVersion
  Named->>Builder: import with hostname, userInitialPassword, modules
  Builder->>Nixpkgs: include inputs.nixpkgs.nixosModules and nixpkgs.pkgs
  Builder->>Named: apply baseModule + conditional genericModules -> resulting NixOS module set
  Builder->>Flake: returns constructed system/iso derivation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 I hopped through Nix files, tidy and spry,
Merged hosts in one burrow where duplicates lie,
Viper and Matic now call the same den,
ISO seeds planted — hop, build again! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: consolidate NixOS hosts into shared builder' directly and concisely describes the main change: consolidating NixOS host definitions into a shared builder module.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description provides comprehensive details about the refactoring: consolidating NixOS hosts into a shared builder, removing duplicate configuration files, adding lib/host.nix changes, and specifying host-specific behavior.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/consolidate-nixos-hosts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="hosts/nixos/default.nix">

<violation number="1" location="hosts/nixos/default.nix:10">
P2: Default `stateVersion` changed from `"24.05"` to `"24.11"`. NixOS `stateVersion` gates backward-compatibility migrations and should not change after initial installation. The `tests/eval.nix` evaluations for `eval-nixos-default` and `eval-nixos-runner` don't pass `stateVersion`, so they now evaluate `"24.11"` while production uses `"24.05"` — meaning tests no longer match deployed config. Consider keeping the default as `"24.05"` to match the existing hosts.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread hosts/nixos/default.nix
hostname ? "x86_64-linux",
isRunner ? false,
system ? "x86_64-linux",
stateVersion ? "24.11",

@cubic-dev-ai cubic-dev-ai Bot Apr 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Default stateVersion changed from "24.05" to "24.11". NixOS stateVersion gates backward-compatibility migrations and should not change after initial installation. The tests/eval.nix evaluations for eval-nixos-default and eval-nixos-runner don't pass stateVersion, so they now evaluate "24.11" while production uses "24.05" — meaning tests no longer match deployed config. Consider keeping the default as "24.05" to match the existing hosts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At hosts/nixos/default.nix, line 10:

<comment>Default `stateVersion` changed from `"24.05"` to `"24.11"`. NixOS `stateVersion` gates backward-compatibility migrations and should not change after initial installation. The `tests/eval.nix` evaluations for `eval-nixos-default` and `eval-nixos-runner` don't pass `stateVersion`, so they now evaluate `"24.11"` while production uses `"24.05"` — meaning tests no longer match deployed config. Consider keeping the default as `"24.05"` to match the existing hosts.</comment>

<file context>
@@ -1,134 +1,151 @@
   hostname ? "x86_64-linux",
   isRunner ? false,
+  system ? "x86_64-linux",
+  stateVersion ? "24.11",
+  userExtraGroups ? [ ],
+  userInitialPassword ? null,
</file context>
Suggested change
stateVersion ? "24.11",
stateVersion ? "24.05",
Fix with Cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hosts/nixos/default.nix`:
- Around line 83-86: The file sets both GRUB and a systemd-boot option; remove
or reconcile the conflicting setting by either deleting the systemd-boot line
(boot.loader.systemd-boot.configurationLimit) if you intend to use GRUB
(boot.loader.grub.enable, boot.loader.grub.device,
boot.loader.grub.useOSProber), or conversely disable GRUB and keep the
systemd-boot configuration if you intend to use systemd-boot; update the file so
only the intended boot loader’s options remain.

In `@lib/host.nix`:
- Line 17: Remove or update the orphaned comment "# Install language server
package" that no longer applies; either delete it entirely or replace it with a
concise, accurate comment describing the following symbol (nodeName) or the
restored isDev logic if you intend to reintroduce it. Locate the stray comment
near the nodeName definition and ensure comments accurately reflect the
surrounding code (e.g., describe nodeName's purpose or restore isDev-related
logic if that was meant to be documented).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8bcb0bca-580f-41ab-a9f9-e9f9465797eb

📥 Commits

Reviewing files that changed from the base of the PR and between d05903a and 61e5111.

📒 Files selected for processing (10)
  • flake.nix
  • hosts/nixos/default.nix
  • lib/host.nix
  • named-hosts/matic/default.nix
  • named-hosts/matic/iso.nix
  • named-hosts/shared/linux-base.nix
  • named-hosts/shared/live-iso.nix
  • named-hosts/viper/default.nix
  • named-hosts/viper/iso.nix
  • tests/lib.nix
💤 Files with no reviewable changes (2)
  • named-hosts/shared/live-iso.nix
  • named-hosts/shared/linux-base.nix

Comment thread hosts/nixos/default.nix
Comment on lines +83 to +86
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.useOSProber = true;
boot.loader.systemd-boot.configurationLimit = 10;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Conflicting boot loader configuration.

boot.loader.grub.enable = true and boot.loader.systemd-boot.configurationLimit are set together, but GRUB and systemd-boot are mutually exclusive boot loaders. The systemd-boot.configurationLimit setting has no effect when GRUB is enabled.

Either remove line 86 since it's ineffective with GRUB, or clarify the intent if this is meant as a fallback configuration.

Proposed fix
         boot.loader.grub.enable = true;
         boot.loader.grub.device = "/dev/sda";
         boot.loader.grub.useOSProber = true;
-        boot.loader.systemd-boot.configurationLimit = 10;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.useOSProber = true;
boot.loader.systemd-boot.configurationLimit = 10;
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.useOSProber = true;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hosts/nixos/default.nix` around lines 83 - 86, The file sets both GRUB and a
systemd-boot option; remove or reconcile the conflicting setting by either
deleting the systemd-boot line (boot.loader.systemd-boot.configurationLimit) if
you intend to use GRUB (boot.loader.grub.enable, boot.loader.grub.device,
boot.loader.grub.useOSProber), or conversely disable GRUB and keep the
systemd-boot configuration if you intend to use systemd-boot; update the file so
only the intended boot loader’s options remain.

Comment thread lib/host.nix Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@named-hosts/matic/default.nix`:
- Around line 9-17: The matic host import call is missing an explicit
stateVersion, causing it to inherit the wrapper default; update the call where
you import ../../hosts/nixos for hostname "matic" (the matic host definition in
default.nix) to include a stateVersion attribute (e.g. stateVersion = "24.05" to
match talismand and runner, or "24.11" if matic needs the newer version) so the
host is pinned and won’t silently drift.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ac28efac-3e05-4050-82bc-bc7ce5063800

📥 Commits

Reviewing files that changed from the base of the PR and between 61e5111 and 6915b54.

📒 Files selected for processing (5)
  • home-manager/modules/xremap/default.nix
  • home-manager/programs/fish/functions/_pixelh_function.fish
  • hosts/nixos/default.nix
  • lib/host.nix
  • named-hosts/matic/default.nix
💤 Files with no reviewable changes (1)
  • home-manager/programs/fish/functions/_pixelh_function.fish
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/host.nix
  • hosts/nixos/default.nix

Comment on lines +9 to +17
import ../../hosts/nixos {
inherit inputs username;
hostname = "matic";
userExtraGroups = [
"input"
"video"
"audio"
"docker"
];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e

echo "== matic host wrapper call =="
sed -n '1,80p' named-hosts/matic/default.nix

echo
echo "== shared host wrapper stateVersion handling =="
sed -n '1,220p' hosts/nixos/default.nix | rg -n -C2 'stateVersion|system\.stateVersion' || true

echo
echo "== other host/stateVersion pins =="
rg -n -C2 'system\.stateVersion|stateVersion\s*=' flake.nix hosts named-hosts

Repository: shunkakinoki/dotfiles

Length of output: 3862


🏁 Script executed:

sed -n '135,145p' flake.nix

Repository: shunkakinoki/dotfiles

Length of output: 481


🏁 Script executed:

# Check git history for matic's previous stateVersion
git log --all --oneline -- named-hosts/matic/default.nix | head -5

# Check if there are any comments in the file about stateVersion
rg -n 'stateVersion|state.version' named-hosts/matic/default.nix

# Check other named-hosts to see pattern
rg -n 'stateVersion|state.version' named-hosts/

Repository: shunkakinoki/dotfiles

Length of output: 405


🏁 Script executed:

# Search for any stateVersion references in the entire flake context
rg 'stateVersion' flake.nix --color=never -n

# Check if matic's hardware-configuration might have stateVersion
rg 'stateVersion|system\.stateVersion' named-hosts/matic/

# Look at the actual wrapper again to understand the design
sed -n '1,20p' hosts/nixos/default.nix

Repository: shunkakinoki/dotfiles

Length of output: 698


Explicitly pin stateVersion for matic in flake.nix.

matic does not pass stateVersion at its call site (unlike talismand and runner, which are both pinned to "24.05"). As a result, it uses the wrapper default of "24.11", creating inconsistency and exposing it to silent drift if the wrapper default changes. Pin matic to "24.05" to match the other hosts, or to "24.11" if it requires the newer version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@named-hosts/matic/default.nix` around lines 9 - 17, The matic host import
call is missing an explicit stateVersion, causing it to inherit the wrapper
default; update the call where you import ../../hosts/nixos for hostname "matic"
(the matic host definition in default.nix) to include a stateVersion attribute
(e.g. stateVersion = "24.05" to match talismand and runner, or "24.11" if matic
needs the newer version) so the host is pinned and won’t silently drift.

@shunkakinoki
shunkakinoki merged commit f54622b into main Apr 14, 2026
31 of 33 checks passed
@shunkakinoki
shunkakinoki deleted the refactor/consolidate-nixos-hosts branch April 14, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant