Compare commits

...
2 Commits
Author SHA1 Message Date
oqyude b88c8ebce0 remote building off 2026-10-04 18:34:39 +03:00
oqyude cc20ee637d opencode oom fixes 2026-10-04 17:41:32 +03:00
3 changed files with 97 additions and 41 deletions
+50 -40
View File
@@ -73,46 +73,56 @@
# `proxyCommand` is what marks this builder as needing the SSH matchBlock # `proxyCommand` is what marks this builder as needing the SSH matchBlock
# (see modules/server/builder.nix). A builder reachable directly would # (see modules/server/builder.nix). A builder reachable directly would
# omit it. # omit it.
host.builder.clients = [ #
{ # ---- DISABLED 2026-10-04 ----
hostName = "vetymae-nix"; # Remote building temporarily turned off coordinator-side. `host.builder.clients`
sshUser = "oqyude"; # falls back to its default `[]` (declared in modules/options.nix), so
sshKey = "/root/.ssh/id_ed25519"; # modules/server/builder.nix's `lib.mkIf (clients != [])` never fires and no
# NixOS calls this `systems` (plural), not `systemTypes`. The # buildMachines / SSH blocks / distributedBuilds override get generated.
# default is empty — every derivation is rejected. The WSL NixOS # All builds run locally on sapphira's 2 cores. Re-enable by removing the
# runs on x86_64-linux, matching sapphira. # Nix comments on the block below (and on `host.builder.enable = true;`
systems = [ "x86_64-linux" ]; # in configurations/wsl.nix).
# vetymae-nix drops kvm + nixos-test from its advertised #
# system-features (see modules/wsl/builder.nix). Listing them here # host.builder.clients = [
# would not break anything (Nix intersects), but listing the # {
# features the WSL actually has is the documented contract. # hostName = "vetymae-nix";
supportedFeatures = [ # sshUser = "oqyude";
"benchmark" # sshKey = "/root/.ssh/id_ed25519";
"big-parallel" # # NixOS calls this `systems` (plural), not `systemTypes`. The
]; # # default is empty — every derivation is rejected. The WSL NixOS
mandatoryFeatures = [ ]; # # runs on x86_64-linux, matching sapphira.
maxJobs = 24; # systems = [ "x86_64-linux" ];
speedFactor = 0.5; # # vetymae-nix drops kvm + nixos-test from its advertised
# Keep the SSH session alive across many small builds in one daemon # # system-features (see modules/wsl/builder.nix). Listing them here
# session — compile-heavy workloads spam the daemon with hundreds of # # would not break anything (Nix intersects), but listing the
# derivations and ControlMaster collapses those into one Windows hop. # # features the WSL actually has is the documented contract.
# NB: `nix.buildMachines` has no `sshOptions` attribute, so the # supportedFeatures = [
# ControlMaster directive lives in the SSH matchBlock instead (see # "benchmark"
# modules/server/builder.nix). # "big-parallel"
# # ];
# The OpenSSH alias for this host (matches the user's # mandatoryFeatures = [ ];
# ~/.ssh/config so known_hosts entries do not collide with the # maxJobs = 24;
# Windows OpenSSH entry on 127.0.0.1/vetymae) is consumed only by # speedFactor = 0.5;
# the SSH matchBlock below — not by `nix.buildMachines`, which has # # Keep the SSH session alive across many small builds in one daemon
# no such attribute. # # session — compile-heavy workloads spam the daemon with hundreds of
hostKeyAlias = "wsl-nixos-on-vetymae"; # # derivations and ControlMaster collapses those into one Windows hop.
# Use the Windows host's IP directly so the nix-daemon (running as # # NB: `nix.buildMachines` has no `sshOptions` attribute, so the
# root, without the user's ~/.ssh/config) does not need a separate # # ControlMaster directive lives in the SSH matchBlock instead (see
# `vetymae` host alias. With StrictHostKeyChecking=accept-new the # # modules/server/builder.nix).
# first connection adds the Windows host key to /root/.ssh/known_hosts. # #
proxyCommand = "ssh oqyude@192.168.1.100 'wsl -d NixOS -- nc 127.0.0.1 22'"; # # The OpenSSH alias for this host (matches the user's
} # # ~/.ssh/config so known_hosts entries do not collide with the
]; # # Windows OpenSSH entry on 127.0.0.1/vetymae) is consumed only by
# # the SSH matchBlock below — not by `nix.buildMachines`, which has
# # no such attribute.
# hostKeyAlias = "wsl-nixos-on-vetymae";
# # Use the Windows host's IP directly so the nix-daemon (running as
# # root, without the user's ~/.ssh/config) does not need a separate
# # `vetymae` host alias. With StrictHostKeyChecking=accept-new the
# # first connection adds the Windows host key to /root/.ssh/known_hosts.
# proxyCommand = "ssh oqyude@192.168.1.100 'wsl -d NixOS -- nc 127.0.0.1 22'";
# }
# ];
networking = { networking = {
networkmanager.enable = true; networkmanager.enable = true;
+10 -1
View File
@@ -45,7 +45,16 @@
# cores, the bottleneck host). All builder wiring — fixing the # cores, the bottleneck host). All builder wiring — fixing the
# `system-features` to drop the unsupported `kvm`, and adding the SSH # `system-features` to drop the unsupported `kvm`, and adding the SSH
# user `oqyude` to trusted-users — lives in modules/wsl/builder.nix. # user `oqyude` to trusted-users — lives in modules/wsl/builder.nix.
host.builder.enable = true; #
# ---- DISABLED 2026-10-04 ----
# Remote building temporarily turned off builder-side. The default of
# `host.builder.enable` is `false` (modules/options.nix), so
# modules/wsl/builder.nix's `lib.mkIf enable` block is skipped: WSL
# keeps its default system-features and trusted-users, and no SSH-side
# state changes. Re-enable by uncommenting the assignment below and
# removing the DISABLED banner in configurations/server.nix.
#
# host.builder.enable = true;
system.stateVersion = "24.11"; system.stateVersion = "24.11";
} }
+37
View File
@@ -306,6 +306,43 @@ in
]; ];
}; };
# RAM constraints for the opencode-web user service.
#
# Sapphira has 5.6 GiB RAM with a ~1 GiB baseline (syncthing + immich + gitea
# + x-ui + nextcloud php-fpm). When something else spikes (immich-ml jobs,
# syncthing indexer, etc.) the system OOM killer activates and picks the
# largest cgroup — opencode at ~260 MiB – 1.4 GiB peak was being chosen and
# systemd then restarted it every few seconds (`RestartSec=5`), masking the
# real cause as a "service crash". The 2026-10-04 incident was exactly this.
#
# Three knobs together make opencode stop being an OOM victim AND stop being
# the source of an OOM:
#
# MemoryHigh soft pressure threshold: kernel reclaims aggressively
# once the cgroup hits this. Process keeps running.
# MemoryMax hard cap: cgroup-local OOM kills Node if exceeded. The
# HOST survives — only this process dies, no restart storm.
# OOMScoreAdjust negative bias for the system-wide OOM killer: opencode
# is killed last, after syncthing/immich/etc.
# OOMPolicy "continue" — systemd does NOT auto-restart on cgroup
# OOM-kill. Without this, a spike triggers the same
# restart-loop the host saw today.
#
# Sizes are derived from observed peak (1.4 GiB at 16:36, 1.1 GiB at 16:59).
# MemoryHigh = 1G gives headroom for normal runs; MemoryMax = 2G caps
# pathological growth. Tweak both together if a workload legitimately
# needs more.
#
# Refs:
# https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html
# https://www.freedesktop.org/software/systemd/man/systemd.exec.html#OOMScoreAdjust=
systemd.user.services.opencode-web.serviceConfig = {
MemoryHigh = "1G";
MemoryMax = "2G";
OOMScoreAdjust = -900;
OOMPolicy = "continue";
};
# Workaround: home-manager activation updates the GC root `current-home` # Workaround: home-manager activation updates the GC root `current-home`
# only at the very end (line 358 of the generated activate script), AFTER all # only at the very end (line 358 of the generated activate script), AFTER all
# `home.activation.*` dag entries have run. So we cannot read current-home # `home.activation.*` dag entries have run. So we cannot read current-home