diff --git a/dotfiles/codex/config.toml b/dotfiles/codex/config.toml index 614a824e..c528c571 100644 --- a/dotfiles/codex/config.toml +++ b/dotfiles/codex/config.toml @@ -5,7 +5,9 @@ personality = "pragmatic" suppress_unstable_features_warning = true # Portable Codex defaults. Machine-local additions are appended from -# dotfiles/codex/config.local.toml by Home Manager. +# dotfiles/codex/config.local.toml by Home Manager. Codex-owned local +# state, including project trust settings, is harvested there before +# this file is regenerated. [mcp_servers.chrome-devtools] command = "npx" diff --git a/dotfiles/config/hypr/hyprland.lua b/dotfiles/config/hypr/hyprland.lua index 4c8973ad..ad1c1cec 100644 --- a/dotfiles/config/hypr/hyprland.lua +++ b/dotfiles/config/hypr/hyprland.lua @@ -54,20 +54,6 @@ local scratchpad_pending = {} local monitor_reserved_cache_path = (os.getenv("XDG_RUNTIME_DIR") or "/tmp") .. "/hyprland-monitor-reserved.tsv" local scratchpad_fallback_reserved_top = 60 -hl.monitor({ - output = "eDP-1", - mode = "2560x1600@240", - position = "0x0", - scale = "1.333333", -}) - -hl.monitor({ - output = "", - mode = "preferred", - position = "auto", - scale = "auto", -}) - local scratchpads = { codex = { command = "codex-desktop", @@ -2000,7 +1986,10 @@ local animations = { { leaf = "specialWorkspaceOut", enabled = true, speed = 6, bezier = "smoothOut", style = "slidevert" }, { leaf = "zoomFactor", enabled = true, speed = 7, bezier = "smoothOut" }, - { leaf = "monitorAdded", enabled = true, speed = 5, bezier = "smoothOut" }, + -- Disabled for now: Hyprland 0.54.0 can crash while damaging a monitor + -- from this startup animation's update callback during output discovery. + -- { leaf = "monitorAdded", enabled = true, speed = 5, bezier = "smoothOut" }, + { leaf = "monitorAdded", enabled = false, speed = 5, bezier = "smoothOut" }, } for _, animation in ipairs(animations) do diff --git a/dotfiles/config/taffybar/TaffybarConfig/Config.hs b/dotfiles/config/taffybar/TaffybarConfig/Config.hs index d5fba7e6..1843703e 100644 --- a/dotfiles/config/taffybar/TaffybarConfig/Config.hs +++ b/dotfiles/config/taffybar/TaffybarConfig/Config.hs @@ -4,14 +4,14 @@ module TaffybarConfig.Config where import TaffybarConfig.Host (compactBarHosts, smallBarHosts) -import TaffybarConfig.Widgets (clockWidget, endWidgetsForHost, startWidgetsForBackend) +import TaffybarConfig.Widgets (clockWidget, endWidgetsForHost, startWidgetsForHostAndBackend) import System.Taffybar.Context (Backend) import System.Taffybar.SimpleConfig mkSimpleTaffyConfig :: String -> Backend -> [FilePath] -> SimpleTaffyConfig mkSimpleTaffyConfig hostName backend cssFiles = defaultSimpleTaffyConfig - { startWidgets = startWidgetsForBackend backend, + { startWidgets = startWidgetsForHostAndBackend hostName backend, centerWidgets = [clockWidget], endWidgets = endWidgetsForHost hostName, barLevels = Nothing, diff --git a/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs b/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs index 9654c155..4b363280 100644 --- a/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs +++ b/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs @@ -5,6 +5,7 @@ module TaffybarConfig.Widgets ( clockWidget, endWidgetsForHost, startWidgetsForBackend, + startWidgetsForHostAndBackend, ) where @@ -412,7 +413,8 @@ sniTrayWidget = do prioritizedParams = defaultPrioritizedCollapsibleSNITrayParams { prioritizedCollapsibleSNITrayParams = collapsibleParams, - prioritizedCollapsibleSNITrayVisibilityThreshold = Just visibilityThreshold + prioritizedCollapsibleSNITrayVisibilityThreshold = Just visibilityThreshold, + prioritizedCollapsibleSNITrayHoverExpand = True } decorateWithClassAndBoxM "sni-tray" @@ -421,9 +423,12 @@ sniTrayWidget = do startWidgetsForBackend :: Backend -> [TaffyIO Gtk.Widget] startWidgetsForBackend backend = case backend of - BackendX11 -> [omniMenuWidget, workspacesWidget, layoutWidget, windowsWidget] + BackendX11 -> [omniMenuWidget, workspacesWidget, layoutWidget] -- These Wayland widgets are Hyprland-specific. - BackendWayland -> [omniMenuWidget, workspacesWidget, windowsWidget] + BackendWayland -> [omniMenuWidget, workspacesWidget] + +startWidgetsForHostAndBackend :: String -> Backend -> [TaffyIO Gtk.Widget] +startWidgetsForHostAndBackend _hostName = startWidgetsForBackend endWidgetsForHost :: String -> [TaffyIO Gtk.Widget] endWidgetsForHost hostName = diff --git a/dotfiles/config/taffybar/sni-priorities.yaml b/dotfiles/config/taffybar/sni-priorities.yaml index d50dddaf..c2550f72 100644 --- a/dotfiles/config/taffybar/sni-priorities.yaml +++ b/dotfiles/config/taffybar/sni-priorities.yaml @@ -3,18 +3,20 @@ max_visible_icons: 0 priorities: - key: item-id:nm-applet priority: 3 +- key: icon-name:gitea + priority: 2 - key: icon-name:github priority: 2 -- key: icon-name:gitea - priority: 1 - key: icon-name:gmail + priority: 2 +- key: icon-name:password + priority: 1 +- key: icon-name:text-org priority: 1 - key: item-id:git-sync-rs priority: 1 - key: process:slack priority: 1 -- key: icon-name:blueman-tray - priority: 0 - key: icon-name:kdeconnectindicatordark priority: 0 - key: item-id:flameshot @@ -23,8 +25,12 @@ priorities: priority: 0 - key: item-id:udiskie priority: 0 +- key: icon-name::1.89 + priority: -1 - key: icon-name:audio-volume-low priority: -1 +- key: icon-name:blueman-tray + priority: -1 - key: item-id:blueman priority: -1 - key: item-id:chrome_status_icon_1 diff --git a/dotfiles/config/taffybar/taffybar b/dotfiles/config/taffybar/taffybar index 242682ac..be3aa010 160000 --- a/dotfiles/config/taffybar/taffybar +++ b/dotfiles/config/taffybar/taffybar @@ -1 +1 @@ -Subproject commit 242682ac0b5b8d99b5ab6f4977ee1b656ae4337a +Subproject commit be3aa010f7c3938a711e9191a7c0fae342ce6f45 diff --git a/nix-shared/home-manager/codex-generated-skills.nix b/nix-shared/home-manager/codex-generated-skills.nix index 8409ee08..e4365538 100644 --- a/nix-shared/home-manager/codex-generated-skills.nix +++ b/nix-shared/home-manager/codex-generated-skills.nix @@ -73,6 +73,8 @@ in { base=${lib.escapeShellArg "${cfg.worktreeCodexDir}/config.toml"} local_config=${lib.escapeShellArg "${cfg.worktreeCodexDir}/config.local.toml"} target="$codex_home/config.toml" + begin_marker="# BEGIN AUTO-GENERATED CODEX MACHINE STATE" + end_marker="# END AUTO-GENERATED CODEX MACHINE STATE" if [ ! -r "$base" ]; then echo "Missing shared Codex config at $base" >&2 @@ -80,6 +82,96 @@ in { fi mkdir -p "$codex_home" + + if [ -r "$target" ]; then + mkdir -p "$(dirname "$local_config")" + local_state="$(mktemp "$codex_home/config.local-state.XXXXXX")" + local_tmp="$(mktemp "$codex_home/config.local.toml.XXXXXX")" + trap 'rm -f "$tmp" "$local_state" "$local_tmp"' EXIT + + ${lib.getExe pkgs.gawk} \ + -v begin_marker="$begin_marker" \ + -v end_marker="$end_marker" ' + FNR == NR { + if ($0 ~ /^\[[^]]+\]$/) { + base_sections[$0] = 1 + } + next + } + + function flush_block() { + if (keep && section != "" && !(section in base_sections)) { + if (printed) { + print "" + } + printf "%s", block + printed = 1 + } + } + + $0 == begin_marker || $0 == end_marker { + next + } + + /^\[[^]]+\]$/ { + flush_block() + section = $0 + keep = ($0 ~ /^\[projects\./ || $0 ~ /^\[tui\./) + block = $0 "\n" + next + } + + section != "" { + block = block $0 "\n" + } + + END { + flush_block() + } + ' "$base" "$target" > "$local_state" + + if [ -s "$local_state" ] || { [ -r "$local_config" ] && grep -Fqx "$begin_marker" "$local_config"; }; then + if [ -r "$local_config" ]; then + ${lib.getExe pkgs.gawk} \ + -v begin_marker="$begin_marker" \ + -v end_marker="$end_marker" ' + $0 == begin_marker { + skip = 1 + next + } + + $0 == end_marker { + skip = 0 + next + } + + !skip { + print + } + ' "$local_config" > "$local_tmp" + else + : > "$local_tmp" + fi + + if [ -s "$local_tmp" ] && [ -s "$local_state" ]; then + printf '\n' >> "$local_tmp" + fi + + if [ -s "$local_state" ]; then + printf '%s\n' "$begin_marker" >> "$local_tmp" + cat "$local_state" >> "$local_tmp" + printf '%s\n' "$end_marker" >> "$local_tmp" + fi + + chmod 600 "$local_tmp" + mv -f "$local_tmp" "$local_config" + else + rm -f "$local_tmp" + fi + + rm -f "$local_state" + fi + tmp="$(mktemp "$codex_home/config.toml.XXXXXX")" trap 'rm -f "$tmp"' EXIT chmod 600 "$tmp" diff --git a/nixos/flake.lock b/nixos/flake.lock index 53c5a28f..ab1499f5 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -163,11 +163,11 @@ ] }, "locked": { - "lastModified": 1778192811, - "narHash": "sha256-DJ/Bop/dB8Grcxsuf6/lRodF4kKN/9p31mk8tPcPvmo=", + "lastModified": 1778219402, + "narHash": "sha256-n+eS2QdBPe6DoMMCS2yTW0mwmYTEehRLVURdGmlqyfs=", "owner": "colonelpanic8", "repo": "codex-desktop-linux", - "rev": "0fbe9cc494ed2c480edf4cd3540b584e5ddff043", + "rev": "f589ba3cd6edf2407c7e2434ab28369b6c7333a5", "type": "github" }, "original": { @@ -1934,8 +1934,8 @@ ] }, "locked": { - "lastModified": 1778137135, - "narHash": "sha256-Z6QaP5ZvRhIxOygu/Oy7gje6mKAF/GR2tDU56X504UY=", + "lastModified": 1778195259, + "narHash": "sha256-exYzNU6vVQg3z1v8ZNDLMjV8+GxbubiEqndT8rFzrm0=", "path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar", "type": "path" }, diff --git a/nixos/k3s.nix b/nixos/k3s.nix index cf3d1136..a443d3c8 100644 --- a/nixos/k3s.nix +++ b/nixos/k3s.nix @@ -17,6 +17,91 @@ with lib; let pkgs.cni-plugin-flannel ]; }; + nvidia-device-plugin-version = "v0.19.1"; + nvidia-device-plugin-manifest = pkgs.writeText "nvidia-device-plugin.yaml" '' + apiVersion: node.k8s.io/v1 + handler: nvidia + kind: RuntimeClass + metadata: + name: nvidia + labels: + app.kubernetes.io/component: gpu-operator + --- + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: nvidia-device-plugin-daemonset + namespace: kube-system + labels: + app.kubernetes.io/name: nvidia-device-plugin + spec: + selector: + matchLabels: + app.kubernetes.io/name: nvidia-device-plugin + updateStrategy: + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/name: nvidia-device-plugin + spec: + runtimeClassName: nvidia + priorityClassName: system-node-critical + nodeSelector: + nvidia.com/gpu.present: "true" + tolerations: + - key: nvidia.com/gpu + operator: Exists + effect: NoSchedule + containers: + - name: nvidia-device-plugin-ctr + image: nvcr.io/nvidia/k8s-device-plugin:${nvidia-device-plugin-version} + imagePullPolicy: IfNotPresent + command: ["nvidia-device-plugin"] + env: + - name: DEVICE_ID_STRATEGY + value: uuid + - name: NVIDIA_VISIBLE_DEVICES + value: all + - name: NVIDIA_DRIVER_CAPABILITIES + value: compute,utility + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + volumeMounts: + - name: kubelet-device-plugins-dir + mountPath: /var/lib/kubelet/device-plugins + - name: cdi-specs + mountPath: /var/run/cdi + readOnly: true + volumes: + - name: kubelet-device-plugins-dir + hostPath: + path: /var/lib/kubelet/device-plugins + type: Directory + - name: cdi-specs + hostPath: + path: /var/run/cdi + type: DirectoryOrCreate + ''; + gpu-test-pod = pkgs.writeText "gpu-test-pod.yaml" '' + apiVersion: v1 + kind: Pod + metadata: + name: gpu-test + namespace: default + spec: + restartPolicy: Never + runtimeClassName: nvidia + containers: + - name: cuda-test + image: nvcr.io/nvidia/cuda:12.6.3-base-ubuntu24.04 + command: ["nvidia-smi"] + resources: + limits: + nvidia.com/gpu: 1 + ''; in { options = { myModules.railbird-k3s = { @@ -70,7 +155,11 @@ in { }; }; - hardware.nvidia-container-toolkit.enable = true; + hardware.nvidia-container-toolkit = { + enable = true; + device-name-strategy = "uuid"; + mount-nvidia-executables = true; + }; virtualisation.containers = { containersConf.cniPlugins = [ pkgs.cni-plugins @@ -152,7 +241,10 @@ in { "--tls-san biskcomp.local" "--tls-san jimi-hendnix.local" "--tls-san dev.railbird.ai" + "--disable=traefik" + "--disable=servicelb" "--node-label nixos-nvidia-cdi=enabled" + "--node-label nvidia.com/gpu.present=true" "--etcd-arg=quota-backend-bytes=8589934592" ] ++ cfg.extraFlags; @@ -163,10 +255,13 @@ in { plugins."io.containerd.grpc.v1.cri".enable_cdi = true [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] + privileged_without_host_devices = false + runtime_engine = "" + runtime_root = "" runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] - BinaryName = "/run/current-system/sw/bin/nvidia-container-runtime.cdi" + BinaryName = "${lib.getOutput "tools" config.hardware.nvidia-container-toolkit.package}/bin/nvidia-container-runtime.cdi" [debug] level = "trace" @@ -175,5 +270,43 @@ in { enable = true; }; }; + + environment.systemPackages = with pkgs; [ + kubectl + kubernetes-helm + nvidia-container-toolkit + nvidia-container-toolkit.tools + ]; + + environment.etc."k3s/gpu-test-pod.yaml".source = gpu-test-pod; + environment.etc."k3s/nvidia-device-plugin.yaml".source = nvidia-device-plugin-manifest; + + systemd.services.k3s-gpu-plugin-deploy = { + description = "Deploy NVIDIA device plugin to k3s"; + after = ["k3s.service"]; + wants = ["k3s.service"]; + wantedBy = ["multi-user.target"]; + path = [pkgs.kubectl pkgs.coreutils]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = pkgs.writeShellScript "deploy-nvidia-device-plugin" '' + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + + echo "Waiting for k3s API server..." + for i in $(seq 1 60); do + if kubectl get nodes &>/dev/null; then + echo "k3s API server is ready" + break + fi + sleep 5 + done + + kubectl delete daemonset -n kube-system generic-cdi-plugin --ignore-not-found=true + kubectl apply -f ${nvidia-device-plugin-manifest} + kubectl rollout status daemonset/nvidia-device-plugin-daemonset -n kube-system --timeout=120s || true + ''; + }; + }; }; } diff --git a/nixos/machines/railbird-sf.nix b/nixos/machines/railbird-sf.nix index 3160ce59..619227c9 100644 --- a/nixos/machines/railbird-sf.nix +++ b/nixos/machines/railbird-sf.nix @@ -49,8 +49,8 @@ myModules.postgres.enable = true; features.full.enable = true; - # Single-node k3s with GPU/CDI support - myModules.k3s-single-node.enable = true; + # Fresh single-node k3s using the existing Railbird k3s module. + myModules.k3s-single-node.enable = false; hardware.nvidia = { powerManagement.enable = false; @@ -71,8 +71,10 @@ myModules.plasma.enable = true; myModules.nvidia.enable = true; myModules.gitea-runner.enable = true; - # Disable the old multi-node railbird k3s setup - myModules.railbird-k3s.enable = false; + myModules.railbird-k3s = { + enable = true; + serverAddr = ""; + }; myModules."keepbook-sync".enable = true; myModules.remote-hyprland.enable = true;