mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
refactor: host profiles; give ruby, kana and aquamarine the TUI home (#512)
- Add the agent profile (modules/nixos/agent.nix: rootless Podman, linger, nix-ld) with home/linux/tui.nix as its home role; ruby, kana and aquamarine use it, so hosts no longer import from hosts/idols-ruby. - Gate nushell's ~/.secrets source behind modules.shell.secrets.enable, off on agent hosts. - Persist the TUI home state on aquamarine's tmpfs root. - Document host profiles in hosts/README.md; add tests/agent-profile and drop the x86_64 colmena-parity test, which needs mysecrets. Assisted-by: Claude Code (claude-opus-5-5)
This commit is contained in:
1 parent
eb6f6c34f0
commit
9a307b313d
31 files changed
+301
-147
No files matched your search
+1
-1
@@ -15,7 +15,7 @@ home/
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── hosts/ # Host-specific home manager entry modules
|
||||
│ ├── linux/ # Linux host home modules (idols-ai, 12kingdoms-shoukei, idols-kana, idols-ruby)
|
||||
│ ├── linux/ # Linux host home modules (idols-ai, 12kingdoms-shoukei, idols-aquamarine, idols-kana, idols-ruby)
|
||||
│ └── darwin/ # macOS host home modules (fern, frieren)
|
||||
└── darwin/ # macOS-specific home manager configurations
|
||||
├── proxy/ # Proxy configurations
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
nu_scripts,
|
||||
...
|
||||
}:
|
||||
{
|
||||
programs.nushell = {
|
||||
options.modules.shell.secrets.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Source ~/.secrets/nushell-secrets.nu, which only the desktops sync.";
|
||||
};
|
||||
|
||||
config.programs.nushell = {
|
||||
# the file must exist, otherwise nushell will complain about it!
|
||||
#
|
||||
# currently, nushell does not support conditional sourcing of files
|
||||
# https://github.com/nushell/nushell/issues/8214
|
||||
extraConfig = ''
|
||||
# decrypted secret: AI agents must not read it
|
||||
source ${config.home.homeDirectory}/.secrets/nushell-secrets.nu
|
||||
${lib.optionalString config.modules.shell.secrets.enable ''
|
||||
# decrypted secret: AI agents must not read it
|
||||
source ${config.home.homeDirectory}/.secrets/nushell-secrets.nu
|
||||
''}
|
||||
|
||||
# Directories in this constant are searched by the
|
||||
# `use` and `source` commands.
|
||||
|
||||
@@ -10,8 +10,9 @@ This directory contains host-specific Home Manager entry modules.
|
||||
## Conventions
|
||||
|
||||
1. Each host output should reference only one file under `home/hosts/...`.
|
||||
2. Shared home module imports should be handled in the host file itself.
|
||||
- Linux hosts usually import `../../linux/core.nix` or `../../linux/gui.nix`.
|
||||
2. The host file imports its profile's home role, see
|
||||
[Host Profiles](../../hosts/README.md#host-profiles).
|
||||
- `desktop` hosts import `../../linux/gui.nix`; `agent` hosts import `../../linux/tui.nix`.
|
||||
- Darwin hosts import `../../darwin`.
|
||||
3. Host-specific overrides (SSH keys, desktop toggles, host-local config links) live in the same
|
||||
host file.
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
imports = [
|
||||
../../linux/tui.nix
|
||||
];
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
imports = [
|
||||
../../linux/core.nix
|
||||
../../linux/gui/i3
|
||||
../../linux/tui.nix
|
||||
];
|
||||
|
||||
# Headless X11/i3 session for computer use.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
imports = [
|
||||
../../linux/core.nix
|
||||
../../linux/gui/i3
|
||||
../../linux/tui.nix
|
||||
];
|
||||
|
||||
# Headless X11/i3 session for computer use.
|
||||
|
||||
@@ -46,8 +46,9 @@ tree the agent reads, so it stays.
|
||||
the systemd user manager, clears any stale `WAYLAND_DISPLAY`, and enables the AT-SPI bridge via a
|
||||
gsettings key.
|
||||
- Drivers come from the nur-ryan4yin overlay (`overlays/nur-ryan4yin.nix`).
|
||||
- Host wiring: `home/hosts/linux/idols-ruby.nix`, `home/hosts/linux/idols-kana.nix`,
|
||||
`hosts/idols-ruby/computer-use.nix`.
|
||||
- Wiring: the `agent` profile imports both sides, off by default
|
||||
([Host Profiles](../../../../hosts/README.md#host-profiles));
|
||||
`hosts/idols-{ruby,kana}/default.nix` and `home/hosts/linux/idols-{ruby,kana}.nix` turn them on.
|
||||
|
||||
## The i3 config
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Home role of the `agent` profile (hosts/README.md#host-profiles): the full
|
||||
# TUI stack for a headless host.
|
||||
{
|
||||
imports = [
|
||||
../base/core
|
||||
@@ -5,5 +7,10 @@
|
||||
../base/home.nix
|
||||
|
||||
./base
|
||||
# off by default; a host turns it on with modules.desktop.computerUse.enable
|
||||
./gui/i3
|
||||
];
|
||||
|
||||
# ~/.secrets is synced to the desktops only.
|
||||
modules.shell.secrets.enable = false;
|
||||
}
|
||||
@@ -5,6 +5,53 @@ This directory contains all host-specific configurations for my NixOS and macOS
|
||||
Manual firmware settings are recorded in [`docs/bios.md`](../docs/bios.md), and the shared
|
||||
Wake-on-LAN workflow is in [`docs/wake-on-lan.md`](../docs/wake-on-lan.md).
|
||||
|
||||
## Host Profiles
|
||||
|
||||
Every host is exactly one profile. The profile fixes the system module that
|
||||
`outputs/<system>/src/<host>.nix` imports and the Home Manager role that
|
||||
`home/hosts/<platform>/<host>.nix` imports. A host directory only adds hardware, networking,
|
||||
persisted paths and feature switches on top.
|
||||
|
||||
| Profile | System module (in outputs) | Home role (in home/hosts) | Hosts |
|
||||
| --------- | --------------------------------- | ------------------------- | ------------------------------------------- |
|
||||
| `desktop` | `modules/nixos/desktop.nix` | `home/linux/gui.nix` | `ai`, `shoukei` |
|
||||
| `agent` | `modules/nixos/agent.nix` | `home/linux/tui.nix` | `aquamarine`, `ruby`, `kana` |
|
||||
| `server` | `modules/nixos/server/server.nix` | none | `shoryu`, `shushou`, `youko`, k3s, `akane`¹ |
|
||||
| `darwin` | `modules/darwin` | `home/darwin` | `fern`, `frieren` |
|
||||
|
||||
¹ `akane` (aarch64) uses `server-aarch64.nix`; the k3s nodes import `server.nix` from their host
|
||||
directory.
|
||||
|
||||
- **desktop**: Niri session and GUI apps on top of the full TUI stack.
|
||||
- **agent**: headless, with the full TUI stack from Home Manager (shell, editors, dev toolchains,
|
||||
cloud CLIs, AI agents with their rules and skills), and nix-ld, rootless Podman and linger from
|
||||
the system. Computer use (Xvfb + i3, VNC) is part of the profile but off by default.
|
||||
- **server**: system services only, no Home Manager.
|
||||
|
||||
The `agent` hosts differ only in:
|
||||
|
||||
| | `aquamarine` | `ruby` | `kana` |
|
||||
| ------------ | ------------------------------------------ | ------------------- | ------------- |
|
||||
| Computer use | off | on, with cua-driver | on |
|
||||
| Hardware | physical; 2x R9700, NPU speech recognition | libvirt guest | libvirt guest |
|
||||
| Root | tmpfs; `preservation.nix` keeps home state | disk | disk |
|
||||
|
||||
`outputs/x86_64-linux/tests/agent-profile` checks the `agent` rows.
|
||||
|
||||
### Where a new piece of configuration goes
|
||||
|
||||
1. A tool you run from a shell goes to the Home Manager role (`home/base/core`, `home/base/tui`),
|
||||
never to a host's `environment.systemPackages`.
|
||||
2. Anything that needs root or a system service (nix-ld, Podman, drivers, systemd units) goes to the
|
||||
profile's system module, or to a `modules/nixos` module the profile imports.
|
||||
3. Hardware, networking, the hostname, persisted paths and feature switches go to the host
|
||||
directory.
|
||||
|
||||
A host does not import files from another host's directory; shared code moves under `modules/` or
|
||||
`home/` instead. Existing exceptions, between machines on identical hardware: `shushou` and `youko`
|
||||
reuse `12kingdoms-shoryu`'s hardware and preservation files, and `shoukei` reuses `idols-ai`'s
|
||||
preservation file.
|
||||
|
||||
## Current Host Inventory
|
||||
|
||||
### Physical Machines
|
||||
|
||||
@@ -15,9 +15,6 @@ in
|
||||
{
|
||||
imports = (mylib.scanPaths ./.) ++ [
|
||||
disko.nixosModules.default
|
||||
|
||||
../idols-ruby/packages.nix
|
||||
../idols-ruby/oci-containers
|
||||
];
|
||||
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
|
||||
@@ -67,14 +67,9 @@ in
|
||||
# VictoriaMetrics.
|
||||
services.smartd.enable = true;
|
||||
|
||||
# The inference engine ships as an OCI image and is meant to run rootless, so
|
||||
# `podman` is what this host uses to build and start it from the `~/src` checkout
|
||||
# that ./preservation.nix keeps.
|
||||
virtualisation.podman.enable = true;
|
||||
|
||||
# Keep the user systemd manager running after logout and start it at boot,
|
||||
# so enabled user services can run without an active login session.
|
||||
users.users."${myvars.username}".linger = true;
|
||||
# The inference engine ships as an OCI image and runs under the agent
|
||||
# profile's rootless Podman (modules/nixos/agent.nix), built from the `~/src`
|
||||
# checkout that ./preservation.nix keeps.
|
||||
|
||||
# Speech recognition runs on the NPU, see ./asr.nix. The driver and the
|
||||
# compiler it loads come from NixOS/nixpkgs#570230, which is unmerged, so they
|
||||
|
||||
@@ -85,6 +85,84 @@ in
|
||||
|
||||
".config/systemd/user"
|
||||
".config/containers/systemd"
|
||||
|
||||
# ======================================
|
||||
# Home Manager TUI role (home/linux/tui.nix); the same paths `ai` keeps
|
||||
# ======================================
|
||||
".local/state/home-manager"
|
||||
".local/state/nix/profiles"
|
||||
".local/share/nix"
|
||||
".config/nushell" # history
|
||||
|
||||
# ai agents
|
||||
".agents" # skills for all agents
|
||||
".config/agents"
|
||||
".codex"
|
||||
".dsh" # DeepSeek Harness
|
||||
".pi"
|
||||
".config/opencode"
|
||||
".local/share/opencode"
|
||||
".local/state/opencode"
|
||||
# ctx7 docs lookup login
|
||||
{
|
||||
directory = ".config/context7";
|
||||
mode = "0700";
|
||||
}
|
||||
|
||||
# editors
|
||||
".local/share/nvim"
|
||||
".local/state/nvim"
|
||||
".local/share/jupyter"
|
||||
|
||||
# tuios session state, project-tape trust store and layout templates
|
||||
{
|
||||
directory = ".local/state/tuios";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".local/share/tuios";
|
||||
mode = "0700";
|
||||
}
|
||||
".config/tuios"
|
||||
|
||||
# cloud native
|
||||
{
|
||||
directory = ".aws";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".aliyun";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".config/gcloud";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".config/gh";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".kube";
|
||||
mode = "0700";
|
||||
}
|
||||
".terraform.d/plugin-cache"
|
||||
|
||||
# language package managers
|
||||
".npm"
|
||||
"go"
|
||||
".cargo"
|
||||
".local/bin"
|
||||
".local/share/uv"
|
||||
|
||||
{
|
||||
directory = ".gnupg";
|
||||
mode = "0700";
|
||||
}
|
||||
{
|
||||
directory = ".ssh";
|
||||
mode = "0700";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
@@ -123,6 +201,21 @@ in
|
||||
group = lib.mkForce username;
|
||||
mode = lib.mkForce "0750";
|
||||
};
|
||||
"/home/${username}/.local/state".d = {
|
||||
user = username;
|
||||
group = lib.mkForce username;
|
||||
mode = lib.mkForce "0750";
|
||||
};
|
||||
"/home/${username}/.local/state/nix".d = {
|
||||
user = username;
|
||||
group = lib.mkForce username;
|
||||
mode = lib.mkForce "0750";
|
||||
};
|
||||
"/home/${username}/.terraform.d".d = {
|
||||
user = username;
|
||||
group = lib.mkForce username;
|
||||
mode = lib.mkForce "0750";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Idols - Kana
|
||||
|
||||
NixOS VM running under libvirt on `shoryu`, used to run AI agents. It imports the agent and
|
||||
computer-use modules from [`idols-ruby`](../idols-ruby/).
|
||||
NixOS VM running under libvirt on `shoryu`, used to run AI agents. Profile: `agent`, see
|
||||
[Host Profiles](../README.md#host-profiles).
|
||||
|
||||
- Deploy from the VM with `just local`.
|
||||
- Host inventory and role context: [`../README.md`](../README.md).
|
||||
@@ -16,11 +16,8 @@ let
|
||||
ipv4WithMask = "${ipv4}/24";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../idols-ruby/packages.nix
|
||||
../idols-ruby/computer-use.nix
|
||||
../idols-ruby/oci-containers
|
||||
];
|
||||
# Headless computer-use environment (Xvfb + i3 + desktop automation + browser).
|
||||
modules.desktop.computerUse.enable = true;
|
||||
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
boot.supportedFilesystems = [
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# Idols - Ruby
|
||||
|
||||
NixOS VM running under libvirt on `shoryu`, used to run AI agents. It owns the shared agent and
|
||||
computer-use modules (`packages.nix`, `computer-use.nix`, `oci-containers/`) that
|
||||
[`idols-kana`](../idols-kana/) imports.
|
||||
NixOS VM running under libvirt on `shoryu`, used to run AI agents. Profile: `agent`, see
|
||||
[Host Profiles](../README.md#host-profiles).
|
||||
|
||||
- Deploy from the VM with `just local`.
|
||||
- Host inventory and role context: [`../README.md`](../README.md).
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
# Headless computer-use environment (sway + desktop automation + browser).
|
||||
modules.desktop.computerUse.enable = true;
|
||||
}
|
||||
@@ -16,11 +16,8 @@ let
|
||||
ipv4WithMask = "${ipv4}/24";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./packages.nix
|
||||
./computer-use.nix
|
||||
./oci-containers
|
||||
];
|
||||
# Headless computer-use environment (Xvfb + i3 + desktop automation + browser).
|
||||
modules.desktop.computerUse.enable = true;
|
||||
|
||||
# Enable binfmt emulation of aarch64-linux, this is required for cross compilation.
|
||||
boot.binfmt.emulatedSystems = [
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
mylib,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = mylib.scanPaths ./.;
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = true;
|
||||
|
||||
oci-containers = {
|
||||
backend = "docker";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -43,6 +43,7 @@ modules/
|
||||
│ ├── trash.nix # Trash retention cleanup
|
||||
│ ├── user-group.nix # User and group management
|
||||
│ └── zram.nix # ZRAM swap configuration
|
||||
├── agent.nix # `agent` profile: headless host with the TUI home role
|
||||
├── desktop.nix # Desktop environment configuration
|
||||
├── desktop/ # Desktop-specific modules
|
||||
│ ├── canokey.nix # CanoKey hardware token
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
{
|
||||
pkgs,
|
||||
llm-agents,
|
||||
myvars,
|
||||
...
|
||||
}:
|
||||
let
|
||||
agentPackages = llm-agents.packages.${pkgs.stdenv.hostPlatform.system};
|
||||
in
|
||||
#############################################################
|
||||
#
|
||||
# The `agent` profile (hosts/README.md#host-profiles): a headless
|
||||
# host whose user tools come from the Home Manager TUI role
|
||||
# (home/linux/tui.nix). This module only carries what needs root.
|
||||
#
|
||||
#############################################################
|
||||
{
|
||||
imports = [
|
||||
./server/server.nix
|
||||
# off by default; a host turns it on with modules.desktop.computerUse.enable
|
||||
./desktop/computer-use.nix
|
||||
];
|
||||
|
||||
# Rootless Podman for agents and the images they build.
|
||||
virtualisation.podman.enable = true;
|
||||
|
||||
# Keep the user systemd manager running after logout and start it at boot,
|
||||
# so agent and computer-use user services run without a login session.
|
||||
users.users."${myvars.username}".linger = true;
|
||||
|
||||
# https://github.com/Mic92/nix-ld
|
||||
#
|
||||
# nix-ld will install itself at `/lib64/ld-linux-x86-64.so.2` so that
|
||||
@@ -32,60 +49,4 @@ in
|
||||
stdenv.cc.cc
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages =
|
||||
with pkgs;
|
||||
[
|
||||
nodejs_24
|
||||
pnpm
|
||||
|
||||
#-- python
|
||||
uv # python project package manager
|
||||
(python313.withPackages (
|
||||
ps: with ps; [
|
||||
pandas
|
||||
requests
|
||||
pyquery
|
||||
pyyaml
|
||||
numpy
|
||||
|
||||
# model downloaders
|
||||
huggingface-hub
|
||||
]
|
||||
))
|
||||
|
||||
rustc
|
||||
cargo # rust package manager
|
||||
go
|
||||
|
||||
# cryptography
|
||||
age
|
||||
sops
|
||||
rclone
|
||||
gnupg
|
||||
|
||||
# cloud-native
|
||||
kubectl
|
||||
istioctl
|
||||
kubernetes-helm
|
||||
fluxcd
|
||||
terraform
|
||||
|
||||
# db related
|
||||
pgcli
|
||||
mongosh
|
||||
sqlite
|
||||
|
||||
yt-dlp # youtube/bilibili/soundcloud/... video/music downloader
|
||||
]
|
||||
# AI Agent Tools
|
||||
++ [
|
||||
# Agents
|
||||
agentPackages.codex
|
||||
agentPackages.opencode2
|
||||
agentPackages.pi
|
||||
# dsh from nur-packages: llm-agents.nix's dsh cannot boot on nixpkgs node
|
||||
# (node-addon-require-builtin probe), this one shims it.
|
||||
pkgs.dsh
|
||||
];
|
||||
}
|
||||
+4
-4
@@ -47,10 +47,10 @@ Some tests iterate over every configuration, so a new host is covered automatica
|
||||
them. Others name specific hosts — or a name prefix, like `k3s-api-endpoint`, which covers every
|
||||
`k3s-test-1-*` configuration — and only cover a new host if you add it.
|
||||
|
||||
| Kind | Tests |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Every configuration | `hostname`, `kernel`, `nix-system-features`, `security-apparmor`, `security-container-groups`, `security-exporters`, `security-firewall`, `security-k3s-kubeconfig`, `security-k3s-pod-firewall`, `security-kernel`, `security-ssh-x11` |
|
||||
| Named hosts only | `btrbk`, `cpu-power`, `home-manager`, `home-manager-xdg`, `computer-use-headless`, `k3s-api-endpoint`, `k3s-node-home-manager`, `idols-ai-gpu`, `idols-ai-net`, `idols-ai-voice-input`, `idols-aquamarine`, `security-postgres-auth`, `youko-metrics`, `ups-metrics`, `shoukei-logind`, `mihomo-dns`, `colmena-parity`, `microvm-guest-parity` |
|
||||
| Kind | Tests |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Every configuration | `hostname`, `kernel`, `nix-system-features`, `security-apparmor`, `security-container-groups`, `security-exporters`, `security-firewall`, `security-k3s-kubeconfig`, `security-k3s-pod-firewall`, `security-kernel`, `security-ssh-x11` |
|
||||
| Named hosts only | `btrbk`, `cpu-power`, `home-manager`, `home-manager-xdg`, `computer-use-headless`, `agent-profile`, `k3s-api-endpoint`, `k3s-node-home-manager`, `idols-ai-gpu`, `idols-ai-net`, `idols-ai-voice-input`, `idols-aquamarine`, `security-postgres-auth`, `youko-metrics`, `ups-metrics`, `shoukei-logind`, `mihomo-dns`, `colmena-parity`, `microvm-guest-parity` |
|
||||
|
||||
`hostname` expects each configuration's `networking.hostName` to equal its name. Niri desktop
|
||||
configurations are the exception (`ai-niri` → `ai`, `shoukei-niri` → `shoukei`) and are listed in
|
||||
|
||||
@@ -3,4 +3,7 @@
|
||||
inputs,
|
||||
}:
|
||||
# Colmena must deploy the system that nixosConfigurations evaluates and builds.
|
||||
# Every node comes out of the same rawColmenaHive code in outputs/default.nix, so
|
||||
# akane covers the x86_64 nodes too; those all read the private mysecrets input,
|
||||
# which CI cannot fetch.
|
||||
lib.genAttrs [ "akane" ] (name: inputs.self.colmenaHive.toplevel.${name}.drvPath)
|
||||
@@ -22,8 +22,8 @@ let
|
||||
modules = {
|
||||
nixos-modules =
|
||||
(map mylib.relativeToRoot [
|
||||
# common
|
||||
"modules/nixos/server/server.nix"
|
||||
# profile: agent (hosts/README.md#host-profiles)
|
||||
"modules/nixos/agent.nix"
|
||||
# host specific
|
||||
"hosts/idols-${name}"
|
||||
])
|
||||
@@ -32,6 +32,10 @@ let
|
||||
# until its new host key is a recipient in nix-secrets. Enabling one is
|
||||
# the last step in hosts/idols-aquamarine/README.md.
|
||||
];
|
||||
home-modules = map mylib.relativeToRoot [
|
||||
# host specific
|
||||
"home/hosts/linux/idols-${name}.nix"
|
||||
];
|
||||
};
|
||||
|
||||
systemArgs = modules // args;
|
||||
|
||||
@@ -24,10 +24,9 @@ let
|
||||
(map mylib.relativeToRoot [
|
||||
# common
|
||||
"secrets/nixos.nix"
|
||||
"modules/nixos/server/server.nix"
|
||||
# profile: agent (hosts/README.md#host-profiles)
|
||||
"modules/nixos/agent.nix"
|
||||
"modules/nixos/server/qemu-guest-hardware-configuration.nix"
|
||||
# headless computer-use environment (sway + desktop automation)
|
||||
"modules/nixos/desktop/computer-use.nix"
|
||||
# host specific
|
||||
"hosts/idols-${name}"
|
||||
])
|
||||
|
||||
@@ -24,10 +24,9 @@ let
|
||||
(map mylib.relativeToRoot [
|
||||
# common
|
||||
"secrets/nixos.nix"
|
||||
"modules/nixos/server/server.nix"
|
||||
# profile: agent (hosts/README.md#host-profiles)
|
||||
"modules/nixos/agent.nix"
|
||||
"modules/nixos/server/qemu-guest-hardware-configuration.nix"
|
||||
# headless computer-use environment (sway + desktop automation)
|
||||
"modules/nixos/desktop/computer-use.nix"
|
||||
# host specific
|
||||
"hosts/idols-${name}"
|
||||
])
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{ ... }:
|
||||
let
|
||||
common = {
|
||||
agentsFromHome = true;
|
||||
devToolsFromHome = true;
|
||||
nushellSecrets = false;
|
||||
nixLd = true;
|
||||
rootlessPodman = true;
|
||||
docker = false;
|
||||
linger = true;
|
||||
agentsInSystem = false;
|
||||
};
|
||||
in
|
||||
{
|
||||
aquamarine = common // {
|
||||
computerUse = false;
|
||||
};
|
||||
ruby = common // {
|
||||
computerUse = true;
|
||||
};
|
||||
kana = common // {
|
||||
computerUse = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# The `agent` profile (hosts/README.md#host-profiles): every agent host gets
|
||||
# the full TUI home role, and the system side only carries what needs root.
|
||||
{
|
||||
myvars,
|
||||
lib,
|
||||
outputs,
|
||||
}:
|
||||
let
|
||||
username = myvars.username;
|
||||
hosts = [
|
||||
"aquamarine"
|
||||
"ruby"
|
||||
"kana"
|
||||
];
|
||||
hasPackage = name: lib.any (package: (package.pname or "") == name);
|
||||
in
|
||||
lib.genAttrs hosts (
|
||||
name:
|
||||
let
|
||||
system = outputs.nixosConfigurations.${name}.config;
|
||||
home = system.home-manager.users.${username};
|
||||
in
|
||||
{
|
||||
# home role: home/linux/tui.nix
|
||||
agentsFromHome = hasPackage "codex" home.home.packages;
|
||||
devToolsFromHome = hasPackage "kubectl" home.home.packages;
|
||||
# ~/.secrets is synced to the desktops only; sourcing it would break nushell.
|
||||
nushellSecrets = home.modules.shell.secrets.enable;
|
||||
|
||||
# system module: modules/nixos/agent.nix
|
||||
nixLd = system.programs.nix-ld.enable;
|
||||
rootlessPodman = system.virtualisation.podman.enable;
|
||||
docker = system.virtualisation.docker.enable;
|
||||
linger = system.users.users.${username}.linger;
|
||||
# User tools stay out of the system profile.
|
||||
agentsInSystem = hasPackage "codex" system.environment.systemPackages;
|
||||
|
||||
# host switch
|
||||
computerUse = system.modules.desktop.computerUse.enable;
|
||||
}
|
||||
)
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
outputs,
|
||||
}:
|
||||
lib.genAttrs [ "kana" ] (
|
||||
name: outputs.nixosConfigurations.${name}.config.system.build.toplevel.drvPath
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
inputs,
|
||||
}:
|
||||
# Colmena must deploy the system that nixosConfigurations evaluates and builds.
|
||||
lib.genAttrs [ "kana" ] (name: inputs.self.colmenaHive.toplevel.${name}.drvPath)
|
||||
@@ -21,7 +21,7 @@
|
||||
raplPermissionsExposed = true;
|
||||
collectorFlagsUnique = true;
|
||||
inferenceUserCanRender = true;
|
||||
noHomeManager = true;
|
||||
homeManagerStatePersistent = true;
|
||||
pythonInstalled = true;
|
||||
staticAddressMatchesWiredInterface = true;
|
||||
rootIsTmpfs = true;
|
||||
|
||||
@@ -92,8 +92,18 @@ in
|
||||
== builtins.length (lib.unique cfg.services.prometheus.exporters.node.enabledCollectors);
|
||||
inferenceUserCanRender = builtins.elem "render" cfg.users.users.${myvars.username}.extraGroups;
|
||||
|
||||
# Headless: no desktop session, no Home Manager.
|
||||
noHomeManager = !cfg ? home-manager.users;
|
||||
# Home Manager's own state has to survive the tmpfs root; the agent profile
|
||||
# itself is covered by ../agent-profile.
|
||||
homeManagerStatePersistent =
|
||||
let
|
||||
dirs = cfg.preservation.preserveAt."/persistent".users.${myvars.username}.directories;
|
||||
in
|
||||
builtins.all (path: builtins.any (d: d.directory == "/home/${myvars.username}/${path}") dirs) [
|
||||
".local/state/home-manager"
|
||||
".local/state/nix/profiles"
|
||||
".codex"
|
||||
".config/opencode"
|
||||
];
|
||||
pythonInstalled = builtins.any (
|
||||
package: lib.hasPrefix "python3-" (package.name or "")
|
||||
) cfg.environment.systemPackages;
|
||||
|
||||
Reference in new issue
Block a user