mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:36 +01:00
docs: review and correct comments and documentation (#436)
This commit is contained in:
1 parent
f32d67a5cc
commit
9c38819517
50 files changed
+148
-148
No files matched your search
@@ -35,7 +35,7 @@ projects live in [agents/](./agents/README.md).
|
||||
## Validation
|
||||
|
||||
- For Nix changes, run `just fmt` and inspect the diff: it formats all Nix files. Nix style is
|
||||
`nixfmt` with width 100.
|
||||
`nixfmt`, whose default width is 100.
|
||||
- For supported non-Nix files, use `prettier --write <file>` and `prettier --check <file>`;
|
||||
configuration lives in `.prettierrc.yaml`. Spelling checks use `typos` and `.typos.toml`.
|
||||
- Run `just test` for configuration changes; it evaluates `.#evalTests` across Linux and Darwin and
|
||||
|
||||
@@ -125,7 +125,7 @@ verify-store:
|
||||
repair-store *paths:
|
||||
nix store repair {{paths}}
|
||||
|
||||
# Update all Nixpkgs inputs
|
||||
# Update the secondary nixpkgs inputs (the primary `nixpkgs` needs `just up`)
|
||||
[group('nix')]
|
||||
up-nix:
|
||||
nix flake update --commit-lock-file nixpkgs-stable nixpkgs-master nixpkgs-darwin nixpkgs-patched
|
||||
|
||||
@@ -140,7 +140,7 @@ For macOS (nix-darwin):
|
||||
# If you are deploying for the first time,
|
||||
# 1. install nix & homebrew manually.
|
||||
# 2. prepare the deployment environment with essential packages available
|
||||
nix-shell -p just nushell
|
||||
nix shell nixpkgs#just nixpkgs#nushell
|
||||
# 3. comment home-manager's code in lib/macosSystem.nix to speed up the first deployment.
|
||||
|
||||
# Deploy the darwinConfiguration by hostname match (fern, frieren)
|
||||
|
||||
+20
-20
@@ -33,18 +33,18 @@ small, reversible controls and narrow exceptions; benchmark before adopting expe
|
||||
|
||||
## Architecture and trust boundaries
|
||||
|
||||
| Boundary | Current design | Limitation |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Administration | Key-based SSH; root key login retained for Colmena/MicroVM deployment | Deployment credentials are root-equivalent; password login being disabled does not restrict stolen keys |
|
||||
| Host network | Shared nftables firewall trusts the home LAN, tailnet interface and local Podman bridge; IPv6 link-local is accepted | These are broad trust zones, not service-level least privilege; router exposure and tailnet ACLs require separate verification |
|
||||
| Monitoring | node/smartctl exporters bind the host LAN IPv4 (9100/9633); firewall rules restrict exporter ports 9100, 9835 and 9633 to the monitoring host over IPv4 | nvidia_gpu_exporter (9835) still binds wildcard; IPv6 denial is planned in the baseline implementation; current running hosts require separate verification |
|
||||
| VM hosts | shoryu, shushou and youko run guests behind `br0`; ruby/kana are libvirt guests | A bridge is not network isolation; host compromise affects its guests |
|
||||
| k3s | Three control-plane and three worker MicroVMs; Cilium, API VIP and NFS CSI | Cluster-admin, privileged/host-mounted pods and writable NFS data are powerful trust boundaries |
|
||||
| MicroVM storage | Host store shared read-only through virtiofs; guest `/etc`, `/var` and `/home` persisted in separate images | Read-only store does not isolate the host-side virtiofs implementation or protect writable guest state |
|
||||
| Desktop apps | Selected apps use nixpak/bubblewrap; Podman is rootless | Rules and shared directories vary per app; user namespaces are needed for these sandboxes |
|
||||
| Secrets | agenix declarations here, encrypted data in the private nix-secrets repository | Recipients and plaintext file permissions must be reviewed; root on a recipient can read its decrypted secrets |
|
||||
| Supply chain | Locked flake inputs; explicit binary-cache trust keys; normal user is not a Nix trusted-user | A trusted cache or imported Nix module can supply code executed as root; a lock file is not a security audit |
|
||||
| Recovery | NixOS generations, btrbk/restic, hourly read-only snapshots of the REST store, and documented backup procedures | A rollback does not undo compromised data or secrets; backup configuration alone does not prove restore works; the offsite immutable copy is still planned |
|
||||
| Boundary | Current design | Limitation |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Administration | Key-based SSH; root key login retained for Colmena/MicroVM deployment | Deployment credentials are root-equivalent; password login being disabled does not restrict stolen keys |
|
||||
| Host network | Shared nftables firewall trusts the home LAN, tailnet interface and local Podman bridge; IPv6 link-local is accepted | These are broad trust zones, not service-level least privilege; router exposure and tailnet ACLs require separate verification |
|
||||
| Monitoring | node/smartctl exporters bind the host LAN IPv4 (9100/9633); firewall rules restrict exporter ports 9100, 9835 and 9633 to the monitoring host over IPv4 | nvidia_gpu_exporter (9835) still binds wildcard; the IPv6 denial for those three ports is in the shared firewall; current running hosts require separate verification |
|
||||
| VM hosts | shoryu, shushou and youko run guests behind `br0`; ruby/kana are libvirt guests | A bridge is not network isolation; host compromise affects its guests |
|
||||
| k3s | Three control-plane and three worker MicroVMs; Cilium, API VIP and NFS CSI | Cluster-admin, privileged/host-mounted pods and writable NFS data are powerful trust boundaries |
|
||||
| MicroVM storage | Host store shared read-only through virtiofs; guest `/etc`, `/var` and `/home` persisted in separate images | Read-only store does not isolate the host-side virtiofs implementation or protect writable guest state |
|
||||
| Desktop apps | Selected apps use nixpak/bubblewrap; Podman is rootless | Rules and shared directories vary per app; user namespaces are needed for these sandboxes |
|
||||
| Secrets | agenix declarations here, encrypted data in the private nix-secrets repository | Recipients and plaintext file permissions must be reviewed; root on a recipient can read its decrypted secrets |
|
||||
| Supply chain | Locked flake inputs; explicit binary-cache trust keys; normal user is not a Nix trusted-user | A trusted cache or imported Nix module can supply code executed as root; a lock file is not a security audit |
|
||||
| Recovery | NixOS generations, btrbk/restic, hourly read-only snapshots of the REST store, and documented backup procedures | A rollback does not undo compromised data or secrets; backup configuration alone does not prove restore works; the offsite immutable copy is still planned |
|
||||
|
||||
Sources: [host layout](hosts/README.md), [k3s deployment](hosts/k8s/README.md),
|
||||
[firewall](modules/nixos/base/networking/firewall.nix), [SSH](modules/nixos/base/ssh.nix),
|
||||
@@ -153,14 +153,14 @@ configuration and certificate lifecycle procedures. Never bypass TLS verificatio
|
||||
hostname mismatch. Eval tests protect the domain join endpoint and server SAN declarations; live TLS
|
||||
checks remain necessary after deployment.
|
||||
|
||||
## Implementation plan and completed audit findings
|
||||
## Implementation status and completed audit findings
|
||||
|
||||
### Implementation status
|
||||
|
||||
| Component | Status | Runtime verification |
|
||||
| ---------------------------------------------------------------- | ------------------------------------- | --------------------------------------------------- |
|
||||
| Architecture, agent-first policy, audits and canonical API tests | Included in this documentation change | Only the dated observations below were checked live |
|
||||
| Explicit sysctl baseline and IPv6 exporter defence | Implemented in this baseline change | Not deployed or verified on running hosts |
|
||||
| Component | Status | Runtime verification |
|
||||
| ---------------------------------------------------------------- | --------------------------------------- | --------------------------------------------------- |
|
||||
| Architecture, agent-first policy, audits and canonical API tests | In this repository | Only the dated observations below were checked live |
|
||||
| Explicit sysctl baseline and IPv6 exporter defence | In `hardening/` and the shared firewall | Not deployed or verified on running hosts |
|
||||
|
||||
### Baseline implementation checks
|
||||
|
||||
@@ -168,11 +168,11 @@ checks remain necessary after deployment.
|
||||
- IPv6 exporter denial precedes broad LAN/tailnet/container rules. The monitoring configuration uses
|
||||
IPv4 targets for these ports, so no scrape endpoint migration is needed.
|
||||
- x86_64/aarch64 eval checks cover baseline values, normal host overrides and generated exporter
|
||||
rules. Canonical API endpoint checks for all six cluster nodes already accompany this document.
|
||||
rules. Canonical API endpoint checks cover all six cluster nodes.
|
||||
- A reusable isolated VM check exercises allowed monitoring IPv4 access, denied other IPv4/IPv6
|
||||
access to all three exporter ports, retained IPv6 loopback and a reachable ordinary IPv4/IPv6
|
||||
service. Run `nix build .#checks.x86_64-linux.security-exporters`, importing only the shared
|
||||
firewall, not real-host secrets or workloads, and does not replace deployment-time checks.
|
||||
service. Run it with `nix build .#checks.x86_64-linux.security-exporters`. It imports only the
|
||||
shared firewall, not real-host secrets or workloads, and does not replace deployment-time checks.
|
||||
|
||||
### Read-only audit snapshot — 2026-10-03
|
||||
|
||||
|
||||
+6
-5
@@ -48,7 +48,8 @@ A setting that works around a bug or a hardware quirk.
|
||||
| WA-029 | mihomo `fake-ip-range6` is `2001:2::/64`, not the shipped ULA default — `modules/nixos/desktop/networking/mihomo/generate.nu` | the default `fdfe:dcba:9876::/64` sits in `fc00::/7`, which Local Network Access calls local, so a public page loaded over the v4 fake pool and pulling a dual-stack subresource prompts for local-network access (Chrome 154, Firefox). The same range also stalled ssh: a session to a fake AAAA authenticated and then never closed, on both `gvisor` and `mips`. `2001:2::/48` is RFC 5180 benchmarking -- the v6 twin of the `198.18.0.0/15` v4 default, absent from that table -- and both symptoms went with the move | Go back to the upstream default once mihomo ships a pool outside the LNA non-public table; the ULA default brings the ssh stall back | 2026-10-09 | on a browser or mihomo bump -- that table already grew to cover `2001:db8::/32` and `198.18.0.0/15` | active |
|
||||
| WA-030 | mihomo unit sets `SKIP_SYSTEM_IPV6_CHECK=1` — `modules/nixos/desktop/networking/mihomo/default.nix` | mihomo checks at startup whether another NIC already holds an IPv6 address and, finding none, skips the TUN's v6 half -- but `strict-route` still installs its v6 blackhole (`ip -6 rule add priority 9000 unreachable`). On a cold boot that rule lands before networkd's Router Solicitation is answered, so the host can never send RS/NS, never gets a GUA, and mihomo never re-checks: self-locking until the core restarts. The env var forces the TUN v6 address up, which installs mihomo's normal v6 rules whose `lookup main suppress_prefixlength 0` keeps on-link neighbor discovery and the RA default route off the TUN | Drop once mihomo either re-runs the IPv6 check or skips the v6 strict-route blackhole when the v6 TUN is disabled | 2026-10-10 | on a mihomo bump | active |
|
||||
|
||||
If WA-008 freezes recur, the fallback is to restore
|
||||
If WA-008 freezes recur, the fallback is to restore the parameters commented out in
|
||||
`hosts/idols-ai/hardware-configuration.nix` —
|
||||
`nvme_core.default_ps_max_latency_us=0 nvme_core.io_timeout=4294967295 pcie_aspm=off`; this is a
|
||||
recovery procedure, not its removal condition.
|
||||
|
||||
@@ -71,10 +72,10 @@ A known limitation with no fix yet.
|
||||
|
||||
An unfinished feature or gap.
|
||||
|
||||
| ID | What & where | Why | Removal condition | Added | Revisit | Status |
|
||||
| ------ | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------- | ----------------------- | ------ |
|
||||
| WA-013 | NixOS tests — `outputs/README.md` | full-host tests still rebuild custom packages (no private cache) and need the host ssh key to decrypt agenix; the shared-firewall security-exporters VM test now runs in CI (KVM) | Resolve when a private cache exists and tests can run per-service | 2024-03-13 | quarterly | active |
|
||||
| WA-027 | NFS golden store `no_root_squash` — `hosts/12kingdoms-youko/nfs-golden.nix` | the existing PVC subdirectories are root-owned, so enabling `root_squash` would break running workloads until they are migrated; the CSI node plugin is hostNetwork and sources from the allowlisted node IPs | Drop when the PVC subdirectories are migrated and `root_squash` is enabled | 2026-10-07 | next maintenance window | active |
|
||||
| ID | What & where | Why | Removal condition | Added | Revisit | Status |
|
||||
| ------ | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | ---------- | ----------------------- | ------ |
|
||||
| WA-013 | NixOS tests — `outputs/README.md` | full-host tests still rebuild custom packages (no private cache) and need the host ssh key to decrypt agenix; the shared-firewall security-exporters VM test now runs in CI (KVM); `outputs/x86_64-linux/nixos-tests/idols-ruby.nix` is exposed as `packages.x86_64-linux.ruby-nixos-tests` but is not in `checks` or CI | Resolve when a private cache exists and tests can run per-service | 2024-03-13 | quarterly | active |
|
||||
| WA-027 | NFS golden store `no_root_squash` — `hosts/12kingdoms-youko/nfs-golden.nix` | the existing PVC subdirectories are root-owned, so enabling `root_squash` would break running workloads until they are migrated; the CSI node plugin is hostNetwork and sources from the allowlisted node IPs | Drop when the PVC subdirectories are migrated and `root_squash` is enabled | 2026-10-07 | next maintenance window | active |
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
+5
-5
@@ -102,11 +102,11 @@ recorded in [#428](https://github.com/ryan4yin/nix-config/pull/428).
|
||||
door, and blast radius for PR bodies.
|
||||
- **Write a `testing-strategy` skill**: E2E of real workflows first, unit tests for logic and edge
|
||||
cases E2E cannot reach.
|
||||
- **Merge `ponytail-review` with a comment and doc pruning pass** (reference:
|
||||
`MidAutumnMoon/TaysiTsuki` `home/agents/skills/prune-comments-and-docs`). Worth borrowing from
|
||||
`garrytan/gstack` `review/checklist.md`: a critical pass before an informational one, reading
|
||||
consumers outside the diff for a new enum value or loosened validator, a do-not-flag list, and
|
||||
"zero findings is valid". Keep review report-only.
|
||||
- **Merge `ponytail-review` into the shipped `review-comments-and-docs` skill** (its doc-pruning
|
||||
half came from `MidAutumnMoon/TaysiTsuki` `home/agents/skills/prune-comments-and-docs`). Worth
|
||||
borrowing from `garrytan/gstack` `review/checklist.md`: a critical pass before an informational
|
||||
one, reading consumers outside the diff for a new enum value or loosened validator, a do-not-flag
|
||||
list, and "zero findings is valid". Keep review report-only.
|
||||
- **Adapt `wayfinder` in the fork** so its map and tickets default to local Markdown and research
|
||||
stays local, instead of GitHub issues and pushed `research/` branches.
|
||||
- **Adapt `domain-modeling` in the fork** to record decisions in the repository's existing documents
|
||||
|
||||
@@ -25,7 +25,7 @@ repository already runs** or **unlocks a concrete need**. "It exists and is newe
|
||||
|
||||
## A1. Tailscale Serve instead of caddy vhosts
|
||||
|
||||
**Current:** one caddy instance on `youko` fronts 12 vhosts on `*.writefor.fun` by Host/SNI, with
|
||||
**Current:** one caddy instance on `youko` fronts 17 vhosts on `*.writefor.fun` by Host/SNI, with
|
||||
two TLS chains — a private `ecc-ca` (only repo machines trust it) and a lego/Cloudflare DNS-01
|
||||
wildcard for phone/TV clients — plus `file_server`, `header_up Host` (SigV4), a wildcard 404
|
||||
fallback, and a root-readable Cloudflare token in agenix.
|
||||
@@ -56,8 +56,9 @@ LAN-only client can run Tailscale.
|
||||
|
||||
## A2. systemd-resolved
|
||||
|
||||
**Current:** `services.resolved.enable` is set **nowhere**; hosts use dhcpcd or static config and
|
||||
the default `/etc/resolv.conf`. Note `modules/nixos/base/networking/mdns.nix` already sets
|
||||
**Current:** `services.resolved.enable` is set **nowhere**; hosts get DNS from systemd-networkd or
|
||||
NetworkManager (or static config) and use the default `/etc/resolv.conf`. Note
|
||||
`modules/nixos/base/networking/mdns.nix` already sets
|
||||
`services.resolved.settings.Resolve.MulticastDNS = false` — currently inert, and it will activate
|
||||
the moment resolved is enabled. mDNS itself is provided by avahi.
|
||||
|
||||
@@ -83,14 +84,16 @@ changes.
|
||||
|
||||
## A3. systemd-networkd instead of dhcpcd
|
||||
|
||||
**Current:** physical hosts use `networking.useDHCP` (dhcpcd script); VM hosts and MicroVM guests
|
||||
use static config with `useDHCP = false`; the `br0` bridge on VM hosts is declared through
|
||||
**Current:** dhcpcd is not used anywhere in this repo. `ai`, `kana` and `ruby` already set
|
||||
`networking.useNetworkd = true`; `shoukei` and `akane` run NetworkManager; VM hosts and MicroVM
|
||||
guests use static config with `useDHCP = false`. The `br0` bridge on VM hosts is declared through
|
||||
`systemd.network.netdevs/networks` already.
|
||||
|
||||
**Proposed:** `networking.networkd.enable = true` with `networking.networks`/`networkdOptions`.
|
||||
|
||||
**Pros:** declarative per-interface config, one implementation for stage 1 and stage 2, no dhcpcd
|
||||
shell script in the path, and VM hosts already speak `systemd.network` for the bridge.
|
||||
anywhere in the path (nothing in this repo uses it), and VM hosts already speak `systemd.network`
|
||||
for the bridge.
|
||||
|
||||
**Cons:** bigger blast radius than any other item — a mistake on a `br0` VM host cuts the guests and
|
||||
possibly remote reachability; migration touches every DHCP host; behaviour differences around
|
||||
@@ -152,8 +155,10 @@ the gain over a working `zramSwap` is mostly cosmetic.
|
||||
|
||||
## A6. nixos-facter instead of hand-written hardware-configuration.nix
|
||||
|
||||
**Current:** 8 hosts carry hand-written `hardware-configuration.nix` (plus deliberate per-host
|
||||
quirks such as the NVMe APST workaround WA-008 and USB-SATA mitigations WA-009).
|
||||
**Current:** 3 hosts carry hand-written `hardware-configuration.nix` (`shoryu`, `shoukei`, `ai`;
|
||||
`shushou` and `youko` import `shoryu`'s, and the qemu guests use the shared
|
||||
`modules/nixos/server/qemu-guest-hardware-configuration.nix`), plus deliberate per-host quirks such
|
||||
as the NVMe APST workaround WA-008 and USB-SATA mitigations WA-009.
|
||||
|
||||
**Proposed:** `hardware.facter` from nixpkgs (nixos-facter-modules upstreamed), report generated on
|
||||
the machine.
|
||||
@@ -294,8 +299,9 @@ validates); no benefit for hosts without Secure Boot.
|
||||
|
||||
## B3. Declarative images with systemd-repart
|
||||
|
||||
**Current:** guest images come from the existing pipeline (nixos-generators / disko-based); k8s
|
||||
guests are MicroVMs booting declared state images.
|
||||
**Current:** libvirt guest images are one-time reflink copies of the VMs' former KubeVirt disks
|
||||
(`hosts/12kingdoms-shoryu/libvirtd.nix`); k8s guests are MicroVMs booting declared state images
|
||||
against a read-only host store, with no OS image built at all.
|
||||
|
||||
**Proposed:** `image.repart.enable` + `system.build.images.{qemu,raw-efi,raw,sd-card}`.
|
||||
|
||||
@@ -479,7 +485,7 @@ only.
|
||||
| B5 | sysupdate | | | |
|
||||
| B6 | measured boot / FIDO2 | | | |
|
||||
| B7 | systemd-vmspawn | | | |
|
||||
| C1–C4 | tooling + cleanups | | | |
|
||||
| C1–C5 | tooling + cleanups | | | |
|
||||
| D1–D7 | lab-only group | | | |
|
||||
| E | rejected set | | | |
|
||||
|
||||
|
||||
+2
-2
@@ -72,8 +72,8 @@ hardening/
|
||||
- https://gitlab.com/apparmor/apparmor/-/wikis/Documentation
|
||||
- AppArmor.d is a set of over 1500 AppArmor profiles whose aim is to confine most Linux based
|
||||
applications and processes.
|
||||
- But all the profiles of AppArmor assume a FHS filesystem, which caused all apparmor policies
|
||||
takes no effect on NixOS.
|
||||
- But its profiles assume an FHS filesystem, so most of them never match the Nix store paths a
|
||||
NixOS system actually executes.
|
||||
- Apparmor on NixOS Roadmap:
|
||||
- https://discourse.nixos.org/t/apparmor-on-nixos-roadmap/57217
|
||||
- https://github.com/LordGrimmauld/aa-alias-manager
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
...
|
||||
}:
|
||||
{
|
||||
# AppArmor in complain mode: log violations instead of blocking.
|
||||
# AppArmor policy for D-Bus.
|
||||
services.dbus.apparmor = "enabled";
|
||||
|
||||
security.apparmor = {
|
||||
|
||||
@@ -36,7 +36,8 @@ appimageTools.wrapAppImage {
|
||||
substituteInPlace $out/share/applications/wechat.desktop --replace-fail AppRun wechat
|
||||
'';
|
||||
|
||||
# Add these root paths to FHS sandbox to prevent WeChat from accessing them by default
|
||||
# Prepare the WeChat data dirs before the sandbox starts. The isolation itself
|
||||
# is the `--tmpfs /home` / `--tmpfs /root` in `extraBwrapArgs` below.
|
||||
# Adapted from https://aur.archlinux.org/cgit/aur.git/tree/wechat-universal.sh?h=wechat-universal-bwrap
|
||||
extraPreBwrapCmds = ''
|
||||
XDG_DOCUMENTS_DIR="''${XDG_DOCUMENTS_DIR:-$(xdg-user-dir DOCUMENTS)}"
|
||||
|
||||
@@ -78,7 +78,7 @@ let
|
||||
# Shared NSS client-certificate store (imported outside Firefox).
|
||||
(sloth.concat' sloth.homeDir "/.pki/nssdb")
|
||||
|
||||
# Unsure
|
||||
# dconf settings. Not verified as needed; candidate for removal.
|
||||
(sloth.concat' sloth.xdgConfigHome "/dconf")
|
||||
];
|
||||
};
|
||||
|
||||
+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, k3s-test-1-worker-*, etc.)
|
||||
│ ├── linux/ # Linux host home modules (idols-ai, 12kingdoms-shoukei, idols-kana, idols-ruby)
|
||||
│ └── darwin/ # macOS host home modules (fern, frieren)
|
||||
└── darwin/ # macOS-specific home manager configurations
|
||||
├── proxy/ # Proxy configurations
|
||||
|
||||
@@ -38,7 +38,7 @@ Run `:tutor` inside Helix, or `hx --tutor` from the shell
|
||||
|
||||
### Terminal related
|
||||
|
||||
tuios shortcuts used often (leader is `Ctrl + B`; same idea as in the Neovim notes):
|
||||
tuios shortcuts used often (leader is `Ctrl + B`):
|
||||
|
||||
| Action | tuios shortcut |
|
||||
| ----------------- | -------------------------- |
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
min-release-age=2
|
||||
'';
|
||||
|
||||
# npm - set min release age (in minutes) for supply-chain security
|
||||
# pnpm - same supply-chain policy as the npm setting above; its value is in minutes, not days
|
||||
xdg.configFile."pnpm/config.yaml".text = ''
|
||||
minimumReleaseAge: 2880
|
||||
'';
|
||||
|
||||
@@ -22,7 +22,6 @@ in
|
||||
# `work` for the ~/work tree, `personal` for everything else (a host with no
|
||||
# ~/work gets `personal` everywhere).
|
||||
programs.nushell.extraConfig = ''
|
||||
# auto start tuios
|
||||
if $nu.is-interactive and (not ("TUIOS_SESSION" in $env)) {
|
||||
# Exit 3 means the daemon is stopped; stdout still lists saved sessions.
|
||||
let listing = (^tuios ls --json | complete)
|
||||
|
||||
@@ -83,8 +83,7 @@ Noctalia consolidates functionality that previously required multiple tools:
|
||||
- **[`desktop-tools.nix`](./desktop-tools.nix)**: Wayland session tools (clipboard, brightness,
|
||||
screen recording, auto-mount, virt-manager/virt-viewer, `wlogout` emergency fallback)
|
||||
- **[`browsers.nix`](./browsers.nix)**: Web browsers
|
||||
- **[`vscode.nix`](./vscode.nix)**: VS Code (GUI editor; the primary Zed config is shared from
|
||||
[`home/base/gui/zed-editor.nix`](../../../base/gui/zed-editor.nix))
|
||||
- **[`vscode.nix`](./vscode.nix)**: VS Code
|
||||
- **[`media.nix`](./media.nix)**: Media players
|
||||
- **[`gaming.nix`](./gaming.nix)**: Gaming applications
|
||||
- **[`creative.nix`](./creative.nix)**: Creative software
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
# discord # update too frequently, use the web version instead
|
||||
];
|
||||
|
||||
# allow fontconfig to discover fonts and configurations installed through home.packages
|
||||
# Install fonts at system-level, not user-level
|
||||
# Fonts install at system level, not user level, so fontconfig does not
|
||||
# scan home.packages for them.
|
||||
fonts.fontconfig.enable = false;
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
# XDG stands for "Cross-Desktop Group", with X used to mean "cross".
|
||||
# XDG stands for "X Desktop Group", the former name of freedesktop.org.
|
||||
# It's a bunch of specifications from freedesktop.org intended to standardize desktops and
|
||||
# other GUI applications on various systems (primarily Unix-like) to be interoperable:
|
||||
# https://www.freedesktop.org/wiki/Specifications/
|
||||
|
||||
@@ -88,13 +88,11 @@ in
|
||||
"/home/${username}/.terraform.d".d = permission;
|
||||
};
|
||||
|
||||
# systemd-machine-id-commit.service would fail but it is not relevant
|
||||
# in this specific setup for a persistent machine-id so we disable it
|
||||
#
|
||||
# see the firstboot example below for an alternative approach
|
||||
# Mask the commit service: /etc/machine-id is persisted by preservation
|
||||
# (see the `files` entry above), so there is no transient ID to commit.
|
||||
systemd.suppressedSystemUnits = [ "systemd-machine-id-commit.service" ];
|
||||
|
||||
# let the service commit the transient ID to the persistent volume
|
||||
# Inert while the unit is masked above; kept as the alternative approach.
|
||||
systemd.services.systemd-machine-id-commit = {
|
||||
unitConfig.ConditionPathIsMountPoint = [
|
||||
""
|
||||
|
||||
@@ -47,7 +47,8 @@ in
|
||||
})
|
||||
];
|
||||
|
||||
# supported file systems, so we can mount any removable disks with these filesystems
|
||||
# supported file systems, so we can mount any removable disks with these filesystems.
|
||||
# mkForce replaces the whole list, so entries added by any other module are lost here.
|
||||
boot.supportedFilesystems = lib.mkForce [
|
||||
"ext4"
|
||||
"btrfs"
|
||||
|
||||
@@ -57,10 +57,10 @@ in
|
||||
keyFile = cryptKeyFile;
|
||||
# The maximum size of the keyfile is 8192 KiB
|
||||
# type `cryptsetup --help` to see the compiled-in key and passphrase maximum sizes
|
||||
# to generate a key file:
|
||||
# The key file must be at least keyFileOffset + keyFileSize bytes.
|
||||
# dd bs=512 count=1024 iflag=fullblock if=/dev/random of=./hdd-luks-crypt-key
|
||||
keyFileSize = 512 * 64; # match the `bs * count` of the `dd` command
|
||||
keyFileOffset = 512 * 128; # match the `bs * skip` of the `dd` command
|
||||
keyFileSize = 512 * 64;
|
||||
keyFileOffset = 512 * 128;
|
||||
fallbackToPassword = true;
|
||||
allowDiscards = true;
|
||||
};
|
||||
|
||||
@@ -95,6 +95,8 @@ document is the agreed design and the rationale.
|
||||
|
||||
## Rollout
|
||||
|
||||
Applied — immich runs on youko. The steps below are the procedure as deployed:
|
||||
|
||||
1. `../valkey.nix`: the shared Valkey instance.
|
||||
2. `./default.nix`: the `services.immich` configuration (server, database, machine-learning,
|
||||
tmpfiles).
|
||||
|
||||
@@ -30,15 +30,15 @@ in
|
||||
# HDR/DoVi transcoding needs OpenCL for `tonemap_opencl`. With only Mesa
|
||||
# installed, ffmpeg cannot create an OpenCL device (`Failed to get number of
|
||||
# OpenCL platforms: -1001`) and the transcode aborts with exit code 237, so
|
||||
# HDR titles fail to play. ROCm's clr provides the ICD for the Barceló iGPU
|
||||
# (reported as `gfx90c`); `ocl-icd` finds it under
|
||||
# HDR titles fail to play. ROCm's clr provides the ICD for the AMD Radeon iGPU
|
||||
# (Vega, `gfx90c`); `ocl-icd` finds it under
|
||||
# /run/opengl-driver/etc/OpenCL/vendors.
|
||||
hardware.graphics.extraPackages = [ pkgs.rocmPackages.clr.icd ];
|
||||
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
|
||||
# AMD Barceló iGPU: VA-API hardware transcoding. renderD128 is world
|
||||
# AMD Radeon iGPU (Vega, `gfx90c`): VA-API hardware transcoding. renderD128 is world
|
||||
# readable/writable, and the user is in `render`/`video` as well.
|
||||
hardwareAcceleration = {
|
||||
enable = true;
|
||||
@@ -55,7 +55,7 @@ in
|
||||
# for decode/scale and falls back to the CPU `libx264`, which pins
|
||||
# several cores per stream.
|
||||
enableHardwareEncoding = true;
|
||||
# Vega (Barceló) decodes these.
|
||||
# Vega decodes these.
|
||||
hardwareDecodingCodecs = {
|
||||
h264 = true;
|
||||
hevc = true;
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
chat_id = 586169186; # My Telegram ID
|
||||
# Whether to notify about resolved alerts.
|
||||
send_resolved = true;
|
||||
# Disable notifications for resolved alerts
|
||||
# Not disabled: resolved alerts are still notified (see send_resolved).
|
||||
disable_notifications = false;
|
||||
# Telegram's MarkdownV2 & Markdown are all very painful, we use html instead.
|
||||
# https://core.telegram.org/bots/api#formatting-options
|
||||
|
||||
+7
-6
@@ -20,9 +20,9 @@ Named after characters from "Oshi no Ko":
|
||||
On 2026-04-27 `ai` was rebuilt on a new platform. The MSI board and i5-13600KF it was added with in
|
||||
2023-05 (the host was originally named `msi-rtx4090`) gave way to the Colorful CVN Z890 ARK FROZEN +
|
||||
Intel Core Ultra 7 270K Plus. The traces in the history are PR #257 (the NIC moved from `enp5s0` to
|
||||
`enp130s0`) and PR #258 (Niri output names renamed, `hardware-intel.nix` added with the Arrow Lake
|
||||
NPU, kernel moved to `linuxPackages_latest`). The 2×48G DDR5 kit was already in place at that point;
|
||||
the repo has no record of when it went in.
|
||||
`enp130s0`) and PR #258 (Niri output names renamed, `hardware-intel.nix` added). The kernel moved to
|
||||
`linuxPackages_latest` in `77ca37ea`, the same day but outside #258. The 2×48G DDR5 kit was already
|
||||
in place at that point; the repo has no record of when it went in.
|
||||
|
||||
On 2026-10-06 `ai` grew from 2×48G (96G) to 2×48G + 2×16G (128G) across all four DIMM slots, at
|
||||
DDR5-4800 with XMP off — the only stable setting with four DIMMs on this board. The 16G pair must be
|
||||
@@ -71,7 +71,8 @@ disks.
|
||||
|
||||
#### `k8s` - Kubernetes Infrastructure
|
||||
|
||||
- **VM Cluster**: 3 physical mini PCs (shoryu, shushou, youko) running all VMs
|
||||
- **VM Cluster**: 3 physical mini PCs (shoryu, shushou, youko) run the k3s VMs; `akane` is a NixOS
|
||||
VM under UTM on macOS
|
||||
- **K3s Testing**: `k3s-test-1` control plane and workers, running as microVMs; placement and
|
||||
rollout are documented in [`k8s/README.md`](./k8s/README.md)
|
||||
|
||||
@@ -122,8 +123,8 @@ just build-host <host>
|
||||
```
|
||||
|
||||
`eval-host` only evaluates the configuration. `build-host` builds the system closure without
|
||||
activating it. Host activation remains an explicit Colmena operation such as `just shoryu`,
|
||||
`just shushou`, or `just youko`.
|
||||
activating it. Host activation is always explicit: Colmena (`just shoryu`, `just shushou`,
|
||||
`just youko`) from another machine, or `just local` on the machine itself.
|
||||
|
||||
## Distributed Building
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
#############################################################
|
||||
#
|
||||
# Fern - MacBook Pro 2024 14-inch M4 Pro 48G, mainly for business.
|
||||
# Frieren - MacBook Pro 2024 14-inch M4 Pro 48G, mainly for business.
|
||||
#
|
||||
#############################################################
|
||||
let
|
||||
|
||||
@@ -6,10 +6,10 @@ to run, but compatibility still depends on the game and translation layer.
|
||||
|
||||
## First activation and persistence
|
||||
|
||||
Run `just niri` on idols-ai from this branch's worktree, or after merging it. Log out and back in so
|
||||
Steam sees `PRESSURE_VESSEL_IMPORT_OPENXR_1_RUNTIMES=1`. That variable is what makes pressure-vessel
|
||||
mount WiVRn's `$XDG_RUNTIME_DIR/wivrn/comp_ipc` socket into a game's container; without it the
|
||||
game's OpenXR client fails with `ERROR_RUNTIME_UNAVAILABLE` and the headset stays black.
|
||||
Run `just niri` on idols-ai. Log out and back in so Steam sees
|
||||
`PRESSURE_VESSEL_IMPORT_OPENXR_1_RUNTIMES=1`. That variable is what makes pressure-vessel mount
|
||||
WiVRn's `$XDG_RUNTIME_DIR/wivrn/comp_ipc` socket into a game's container; without it the game's
|
||||
OpenXR client fails with `ERROR_RUNTIME_UNAVAILABLE` and the headset stays black.
|
||||
|
||||
The root filesystem is a 4 GiB tmpfs. These directories are preserved with mode 0700:
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ in
|
||||
];
|
||||
|
||||
# Zram consumes physical memory for compression, which can cause a deadlock and system hang if the model size approaches the physical memory limit.
|
||||
# Disable the whole module (zram device + its swappiness=180 sysctl tunings); this host uses a disk swapfile instead.
|
||||
# Disable the whole module (zram device + its swappiness=180 sysctl tunings); this host uses a
|
||||
# disk swapfile instead, created by disko at /swap (see ./disko-fs.nix). The two must move together.
|
||||
modules.zram.enable = false;
|
||||
|
||||
# zswap: compressed writeback cache in front of the disk swapfile.
|
||||
@@ -93,8 +94,9 @@ in
|
||||
networking = {
|
||||
inherit hostName;
|
||||
|
||||
# we use networkd instead
|
||||
networkmanager.enable = false; # provides nmcli/nmtui for wifi adjustment
|
||||
# off: this host uses networkd (below). NetworkManager would otherwise
|
||||
# provide nmcli/nmtui for wifi adjustment.
|
||||
networkmanager.enable = false;
|
||||
useDHCP = false;
|
||||
};
|
||||
|
||||
@@ -117,7 +119,7 @@ in
|
||||
];
|
||||
DNS = nameservers;
|
||||
DHCP = "ipv6"; # enable DHCPv6 only, so we can get a GUA.
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguraton (SLAAC)
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguration (SLAAC)
|
||||
LinkLocalAddressing = "ipv6";
|
||||
# r8169 drops carrier on S3 resume; without this, networkd tears down the
|
||||
# static address/route and mihomo's TUN auto-detect briefly loses its
|
||||
|
||||
@@ -469,13 +469,11 @@ in
|
||||
"D! /var/lib/systemd/coredump 0755 root root"
|
||||
];
|
||||
|
||||
# systemd-machine-id-commit.service would fail but it is not relevant
|
||||
# in this specific setup for a persistent machine-id so we disable it
|
||||
#
|
||||
# see the firstboot example below for an alternative approach
|
||||
# Mask the commit service: /etc/machine-id is persisted by preservation
|
||||
# (see the `files` entry above), so there is no transient ID to commit.
|
||||
systemd.suppressedSystemUnits = [ "systemd-machine-id-commit.service" ];
|
||||
|
||||
# let the service commit the transient ID to the persistent volume
|
||||
# Inert while the unit is masked above; kept as the alternative approach.
|
||||
systemd.services.systemd-machine-id-commit = {
|
||||
unitConfig.ConditionPathIsMountPoint = [
|
||||
""
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Part 1 of the backup plan: a local restic repository on this machine.
|
||||
# The off-machine target (youko, or a cloud) is a later step.
|
||||
#
|
||||
# Be specific here and keep `exclude` minimal: an allowlist of the
|
||||
# irreplaceable directories beats backing up a broad tree and excluding half
|
||||
# of it. Large files anywhere are skipped by size (excludeLargerThan), which
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"auto" # Mount automatically with -a
|
||||
|
||||
# Ownership mapping - all files appear as specified user/group
|
||||
"uid=1000" # Map to user ID 1000
|
||||
"gid=1000" # Map to group ID 100
|
||||
"uid=1000"
|
||||
"gid=1000"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -52,10 +52,12 @@ in
|
||||
matchConfig.Name = [ iface ];
|
||||
networkConfig = {
|
||||
Address = [ ipv4WithMask ];
|
||||
# DNS goes to the proxy gateway, which resolves through the proxy;
|
||||
# `nameservers` is the plain upstream-DNS alternative.
|
||||
# DNS = nameservers;
|
||||
DNS = [ proxyGateway ];
|
||||
DHCP = "ipv6"; # enable DHCPv6 only, so we can get a GUA.
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguraton (SLAAC)
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguration (SLAAC)
|
||||
LinkLocalAddressing = "ipv6";
|
||||
};
|
||||
routes = [
|
||||
|
||||
@@ -61,10 +61,12 @@ in
|
||||
matchConfig.Name = [ iface ];
|
||||
networkConfig = {
|
||||
Address = [ ipv4WithMask ];
|
||||
# DNS goes to the proxy gateway, which resolves through the proxy;
|
||||
# `nameservers` is the plain upstream-DNS alternative.
|
||||
# DNS = nameservers;
|
||||
DNS = [ proxyGateway ];
|
||||
DHCP = "ipv6"; # enable DHCPv6 only, so we can get a GUA.
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguraton (SLAAC)
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguration (SLAAC)
|
||||
LinkLocalAddressing = "ipv6";
|
||||
};
|
||||
routes = [
|
||||
|
||||
@@ -7,25 +7,8 @@
|
||||
{
|
||||
imports = mylib.scanPaths ./.;
|
||||
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# podman-compose
|
||||
# ];
|
||||
|
||||
virtualisation = {
|
||||
docker.enable = true;
|
||||
# podman = {
|
||||
# enable = true;
|
||||
# # Create a `docker` alias for podman, to use it as a drop-in replacement
|
||||
# dockerCompat = true;
|
||||
# # Required for containers under podman-compose to be able to talk to each other.
|
||||
# defaultNetwork.settings.dns_enabled = true;
|
||||
# # Periodically prune Podman resources
|
||||
# autoPrune = {
|
||||
# enable = true;
|
||||
# dates = "weekly";
|
||||
# flags = [ "--all" ];
|
||||
# };
|
||||
# };
|
||||
|
||||
oci-containers = {
|
||||
backend = "docker";
|
||||
|
||||
@@ -31,8 +31,8 @@ let
|
||||
|
||||
# k3sExtraArgs = [
|
||||
# # IPv4 Private CIDR(full) - 172.16.0.0/12
|
||||
# # IPv4 Pod CIDR(full) - fdfd:cafe:00:0000::/64 ~ fdfd:cafe:00:7fff::/64
|
||||
# # IPv4 Service CIDR(full) - fdfd:cafe:00:8000::/64 ~ fdfd:cafe:00:ffff::/64
|
||||
# # IPv6 Pod CIDR(full) - fdfd:cafe:00:0000::/64 ~ fdfd:cafe:00:7fff::/64
|
||||
# # IPv6 Service CIDR(full) - fdfd:cafe:00:8000::/64 ~ fdfd:cafe:00:ffff::/64
|
||||
# "--cluster-cidr=172.18.0.0/16,fdfd:cafe:00:0002::/64"
|
||||
# "--service-cidr=172.19.0.0/16,fdfd:cafe:00:8002::/112"
|
||||
# ];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
etcSize ? 64,
|
||||
varSize ? 4096,
|
||||
homeSize ? 4096,
|
||||
# extra stateful mounts (e.g. aquamarine's /data on the passed-through HDDs)
|
||||
# extra stateful mounts, e.g. a guest's /data on passed-through HDDs
|
||||
extraVolumes ? [ ],
|
||||
...
|
||||
}:
|
||||
|
||||
@@ -23,9 +23,10 @@ in
|
||||
"nfs"
|
||||
];
|
||||
|
||||
# KVM for the microVMs and the libvirt domains.
|
||||
# KVM for the microVMs and the libvirt domains. AMD-specific: an Intel VM host
|
||||
# would need kvm-intel instead (see hosts/idols-ai/hardware-intel.nix).
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModprobeConfig = "options kvm_amd nested=1"; # for amd cpu
|
||||
boot.extraModprobeConfig = "options kvm_amd nested=1";
|
||||
|
||||
boot.kernel.sysctl = {
|
||||
# --- filesystem --- #
|
||||
@@ -92,10 +93,11 @@ in
|
||||
matchConfig.Name = [ "br0" ];
|
||||
networkConfig = {
|
||||
Address = [ ipv4WithMask ];
|
||||
# DNS = nameservers;
|
||||
# DNS goes to the proxy gateway, which resolves through the proxy; plain
|
||||
# upstream DNS would be myvars.networking.nameservers.
|
||||
DNS = [ proxyGateway ];
|
||||
DHCP = "ipv6"; # enable DHCPv6 only, so we can get a GUA.
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguraton (SLAAC)
|
||||
IPv6AcceptRA = true; # for Stateless IPv6 Autoconfiguration (SLAAC)
|
||||
LinkLocalAddressing = "ipv6";
|
||||
};
|
||||
routes = [
|
||||
|
||||
+5
-4
@@ -102,8 +102,9 @@ Platform-specific NixOS configuration:
|
||||
|
||||
## Usage
|
||||
|
||||
Modules are imported based on platform detection:
|
||||
There is no automatic platform detection. Each host's entry under `outputs/<system>/src/` lists its
|
||||
imports explicitly:
|
||||
|
||||
- **NixOS Systems**: Import `nixos/` modules
|
||||
- **macOS Systems**: Import `darwin/` modules
|
||||
- **All Systems**: Import `base/` modules for shared configuration
|
||||
- **NixOS Systems**: import `nixos/` modules
|
||||
- **macOS Systems**: import `darwin/` modules
|
||||
- **Both**: import `base/` modules for shared configuration
|
||||
@@ -4,8 +4,7 @@
|
||||
users.users."${myvars.username}" = {
|
||||
home = "/Users/${myvars.username}";
|
||||
|
||||
# set user's default shell back to zsh
|
||||
# `chsh -s /bin/zsh`
|
||||
# The login shell is set imperatively (`chsh -s /bin/zsh`), not declaratively here.
|
||||
# DO NOT change the system's default shell to nushell! it will break some apps!
|
||||
# It's better to change only kitty/wezterm & other terminal emulator's shell to nushell!
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ let
|
||||
lanAddr = if hostAddr.homeOnly or false then null else hostAddr.ipv4 or null;
|
||||
in
|
||||
{
|
||||
# enable the node exporter on all nixos hosts
|
||||
# node_exporter on every host that has a static LAN IPv4 (see `lanAddr` above)
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-26.05/nixos/modules/services/monitoring/prometheus/exporters/node.nix
|
||||
services.prometheus.exporters.node = lib.mkIf (lanAddr != null) {
|
||||
enable = true;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# Secure by default: X11 forwarding off everywhere; desktops re-enable it
|
||||
# in modules/nixos/desktop/ssh.nix (needed for GUI forwarding).
|
||||
X11Forwarding = lib.mkDefault false;
|
||||
# root user is used for remote deployment, so we need to allow it
|
||||
# root login stays available for Colmena/MicroVM deployment, keys only
|
||||
PermitRootLogin = lib.mkDefault "prohibit-password";
|
||||
PasswordAuthentication = false; # disable password login
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# misc
|
||||
uinput = { };
|
||||
# shared group for services that read/write the same data directory
|
||||
# (e.g. sftpgo + transmission on aquamarine)
|
||||
# (e.g. sftpgo + transmission on youko)
|
||||
fileshare = { };
|
||||
};
|
||||
|
||||
|
||||
@@ -54,9 +54,8 @@ in
|
||||
"vm.watermark_boost_factor" = lib.mkDefault 0;
|
||||
|
||||
# vm.watermark_scale_factor - Controls kswapd wakeup frequency (range: 1-1000, default: 10)
|
||||
# A higher value triggers background memory reclamation earlier (at 12.5% memory pressure).
|
||||
# Value 125 means kswapd becomes active when free memory drops below 1/125 of total memory,
|
||||
# balancing memory more proactively to prevent sudden swap storms at high swappiness values.
|
||||
# Units are 1/10000 of total memory: the value below widens the low-to-min watermark gap and
|
||||
# makes kswapd reclaim earlier, which avoids swap storms at the high swappiness above.
|
||||
"vm.watermark_scale_factor" = lib.mkDefault 125;
|
||||
|
||||
# vm.page-cluster - Controls swap readahead (range: 0-6, default: 3)
|
||||
|
||||
@@ -46,7 +46,7 @@ in
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = {
|
||||
# Wayland Desktop Manager is installed only for user ryan via home-manager!
|
||||
# The Wayland session is installed for this user only, via home-manager.
|
||||
user = myvars.username;
|
||||
# .wayland-session is a script generated by home-manager, which links to the current wayland compositor(sway/hyprland or others).
|
||||
# with such a vendor-no-locking script, we can switch to another wayland compositor without modifying greetd's config here.
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
# security with gnome-kering
|
||||
services.gnome = {
|
||||
gnome-keyring.enable = true;
|
||||
# Use gnome keyring's SSH Agent
|
||||
# Not gcr's SSH agent: OpenSSH's own agent runs instead
|
||||
# (programs.ssh.startAgent below).
|
||||
# https://wiki.gnome.org/Projects/GnomeKeyring/Ssh
|
||||
gcr-ssh-agent.enable = false;
|
||||
};
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#
|
||||
# We write our hardware-configuration.nix, so that we can do some customization more easily.
|
||||
#
|
||||
# the url above is used by `nixos-generator` to generate the guest's qcow2 image file.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
imports = [
|
||||
|
||||
@@ -249,8 +249,8 @@ cd ~/nix-config/nixos-installer/
|
||||
rm -rf /mnt/etc
|
||||
|
||||
# install nixos
|
||||
# NOTE: --no-root-password leaves root locked; log in as ryan with the password from
|
||||
# vars/default.nix
|
||||
# NOTE: --no-root-password leaves root locked; log in as ryan with the password whose hash is
|
||||
# `initialHashedPassword` in vars/default.nix
|
||||
nixos-install --root /mnt --flake .#shoukei --no-root-password --show-trace --verbose # install-1
|
||||
|
||||
# if you want to use a cache mirror, run this command instead
|
||||
@@ -259,7 +259,8 @@ nixos-install --root /mnt --flake .#shoukei --no-root-password --show-trace --ve
|
||||
|
||||
# enter into the installed system, check password & users
|
||||
# `su ryan` => `sudo -i` => enter ryan's password => successfully login
|
||||
# if login failed, check ryan's initial password in vars/default.nix, and try again
|
||||
# if login failed, check that the password you typed is the one hashed by
|
||||
# `initialHashedPassword` in vars/default.nix, and try again
|
||||
nixos-enter
|
||||
|
||||
|
||||
@@ -327,7 +328,8 @@ cd ~/nix-config
|
||||
just niri
|
||||
```
|
||||
|
||||
Finally, to enable secure boot, follow the instructions in
|
||||
Secure Boot is not configured for `shoukei` (Apple Silicon, Asahi firmware). The links below are the
|
||||
setup for `ai`, kept here as a reference:
|
||||
[lanzaboote - Quick Start](https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md)
|
||||
and
|
||||
[hosts/idols-ai/secureboot.nix](https://github.com/ryan4yin/nix-config/blob/main/hosts/idols-ai/secureboot.nix)
|
||||
+7
-3
@@ -44,7 +44,8 @@ suite passes when every `expr` equals its `expected`.
|
||||
#### Which tests cover a new host
|
||||
|
||||
Some tests iterate over every configuration, so a new host is covered automatically and must satisfy
|
||||
them. Others name specific hosts and only cover a new host if you add it.
|
||||
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 |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -71,8 +72,11 @@ Problems:
|
||||
agenix secrets.
|
||||
- [ ] Maybe it's better to test every service separately, not the whole host?
|
||||
|
||||
No host defines a NixOS integration test yet: full-host tests are tracked as WA-013 in
|
||||
[WORKAROUNDS.md](../WORKAROUNDS.md). What runs today is the eval set above, with `just test`.
|
||||
Full-host tests are tracked as WA-013 in [WORKAROUNDS.md](../WORKAROUNDS.md).
|
||||
`outputs/x86_64-linux/nixos-tests/idols-ruby.nix` is exported as
|
||||
`packages.x86_64-linux.ruby-nixos-tests`, but it is not a `checks` entry, so CI never builds it and
|
||||
nothing else runs it. What runs today is the eval set above with `just test`, plus one NixOS-driver
|
||||
check of the shared firewall — `checks.x86_64-linux.security-exporters`, built in CI.
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
+2
-1
@@ -142,7 +142,8 @@ in
|
||||
# Packages
|
||||
packages = forAllSystems (system: allSystems.${system}.packages or { });
|
||||
|
||||
# Eval Tests for all NixOS & darwin systems.
|
||||
# Eval Tests for all NixOS & darwin systems. Each system's `evalTests` lists its
|
||||
# failures, so an empty attrset means that system passed.
|
||||
evalTests = lib.lists.all (it: it.evalTests == { }) allSystemValues;
|
||||
|
||||
checks = forAllSystems (
|
||||
|
||||
+2
-1
@@ -65,7 +65,8 @@ Placing a secret under `/etc/agenix/` with `environment.etc` has one trap: setti
|
||||
`environment.etc` **copy** the file instead of symlinking it, and the copy is owned by root unless
|
||||
`user` is set too. Widening the mode so the user can read a root-owned copy makes it readable by
|
||||
every local account. Always set `user` together with `mode`. nix-darwin ignores both on
|
||||
`environment.etc`, so `secrets/darwin.nix` chowns `/etc/agenix/*` after activation instead.
|
||||
`environment.etc`, so `secrets/darwin.nix` re-applies each secret's owner and mode after activation;
|
||||
a blanket chown over `/etc/agenix/*` would make the root-only secrets readable by the login user.
|
||||
|
||||
## Adding or Updating Secrets
|
||||
|
||||
|
||||
Reference in new issue
Block a user