Add FredOS-Rescue: Claude Code rescue USB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d40d9924b2
commit
b960a6ccbf
5 changed files with 217 additions and 0 deletions
102
hosts/FredOS-Rescue.nix
Normal file
102
hosts/FredOS-Rescue.nix
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# FredOS-Rescue — live USB that boots into Claude Code for diagnosing and
|
||||
# repairing a broken Linux (or Windows) install. Built on the minimal NixOS
|
||||
# installer, which already brings NetworkManager, sshd and the usual disk
|
||||
# tools (testdisk, ddrescue, smartctl, cryptsetup, ...; profiles/base.nix).
|
||||
#
|
||||
# nix build .#rescue-iso # -> result/iso/fredos-rescue-*.iso
|
||||
#
|
||||
# On boot: type `rescue`. It gets you online (nmtui) and starts Claude as root
|
||||
# with hosts/rescue/rescue-prompt.md as its system-wide CLAUDE.md. Login is
|
||||
# the usual URL + code dance (phone works); nothing persists across reboots.
|
||||
#
|
||||
# Remote mode: sshd runs with Fred's keys + the server's for root, so Claude
|
||||
# elsewhere can `ssh root@<ip>` in (or you can run `rescue` over ssh).
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
let
|
||||
serverKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMbIdOSPjnJYQ7z7n0mHKo8T8PnAkCyIBCmT4KpsHyy/ fred@FredOS-Mediaserver";
|
||||
|
||||
# Any HTTP answer counts (no -f): the API root is a 404.
|
||||
online = "${pkgs.curl}/bin/curl -sS -m 5 -o /dev/null https://api.anthropic.com 2>/dev/null";
|
||||
rescue = pkgs.writeShellScriptBin "rescue" ''
|
||||
# Claude's binary needs AVX (2011+ CPUs); without it, it spins forever
|
||||
# instead of crashing.
|
||||
if ! grep -qw avx /proc/cpuinfo; then
|
||||
echo "This CPU is too old for Claude (no AVX)."
|
||||
echo "Use remote mode: get online with 'nmtui', run 'menu' for the"
|
||||
echo "address, then run Claude on another machine and have it ssh in."
|
||||
exit 1
|
||||
fi
|
||||
# Typed right after boot, wired may still be coming up.
|
||||
${pkgs.networkmanager}/bin/nm-online -q -t 15
|
||||
if ! ${online}; then
|
||||
echo "Not online yet. Pick a network (wired should connect by itself)."
|
||||
sleep 1
|
||||
${pkgs.networkmanager}/bin/nmtui-connect
|
||||
fi
|
||||
if ! ${online}; then
|
||||
echo "Still offline. Try 'nmtui', then run 'rescue' again."
|
||||
exit 1
|
||||
fi
|
||||
exec sudo -i ${pkgs.claude-code}/bin/claude "$@"
|
||||
'';
|
||||
menu = pkgs.writeShellScriptBin "menu" (builtins.readFile ./rescue/menu.sh);
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
|
||||
../settings/locale.nix
|
||||
../settings/users.nix # only for Fred's ssh keys below
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "claude-code";
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
networking.hostName = "FredOS-Rescue";
|
||||
image.baseName = lib.mkForce "fredos-rescue-${config.system.nixos.label}";
|
||||
isoImage.appendToMenuLabel = " - Claude Rescue"; # no apostrophes: GRUB quotes it with ''
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys =
|
||||
config.users.users.fred.openssh.authorizedKeys.keys ++ [ serverKey ];
|
||||
# The installer leaves root/nixos with empty passwords; never over ssh.
|
||||
services.openssh.settings.PasswordAuthentication = false;
|
||||
services.openssh.settings.KbdInteractiveAuthentication = false;
|
||||
|
||||
environment.etc."claude-code/CLAUDE.md".source = ./rescue/rescue-prompt.md;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
rescue
|
||||
menu
|
||||
claude-code
|
||||
# Chroot into the patient: arch-chroot does the bind mounts for any
|
||||
# distro; nixos-enter is already on the ISO for NixOS.
|
||||
arch-install-scripts
|
||||
mdadm
|
||||
chntpw # Windows: reset passwords, edit registry hives
|
||||
lsof
|
||||
file
|
||||
tree
|
||||
ripgrep
|
||||
git
|
||||
rsync
|
||||
wget
|
||||
tmux
|
||||
htop
|
||||
lm_sensors
|
||||
dmidecode
|
||||
memtester
|
||||
];
|
||||
|
||||
# The installer's getty text scrolls past under autologin; the menu replaces
|
||||
# it. Interactive only, so `sudo -i claude` inside `rescue` doesn't print it.
|
||||
services.getty.helpLine = lib.mkForce "";
|
||||
environment.loginShellInit = ''
|
||||
[[ $- == *i* ]] && menu
|
||||
'';
|
||||
|
||||
# Serial too, for headless boxes (tty0 last = it keeps the boot messages).
|
||||
boot.kernelParams = [ "console=ttyS0,115200" "console=tty0" ];
|
||||
|
||||
# Don't import ZFS pools that weren't exported cleanly; rescue asks first.
|
||||
boot.zfs.forceImportRoot = false;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue