From f42bae513c6a2f3ffc9bf742cf550d866b996dfc Mon Sep 17 00:00:00 2001 From: Geir Okkenhaug Jerstad Date: Mon, 30 Jun 2025 11:40:10 +0200 Subject: [PATCH 1/2] feat(lab-tool): integrate little-rascal laptop into Home Lab management - Add little-rascal to lab-tool configuration with proper attributes - Include little-rascal in machine management, SSH connectivity, and deployment targets - Update README.md with examples including little-rascal - Verify full integration: machines listing, status monitoring, SSH access, deployment ready The little-rascal laptop is now fully managed through the unified lab-tool interface alongside other Home Lab machines (congenital-optimist, sleeper-service, grey-area, reverse-proxy). --- packages/lab-tool/README.md | 32 +++++++++++++++++++++++++----- packages/lab-tool/utils/config.scm | 7 ++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/lab-tool/README.md b/packages/lab-tool/README.md index 38662c7..f781455 100644 --- a/packages/lab-tool/README.md +++ b/packages/lab-tool/README.md @@ -224,6 +224,21 @@ Provides structured configuration handling: (hostname . "sleeper-service.tail807ea.ts.net") (ssh-alias . "admin-sleeper") (services . (nfs zfs storage))) + (grey-area + (type . remote) + (hostname . "grey-area.tail807ea.ts.net") + (ssh-alias . "admin-grey") + (services . (ollama forgejo git))) + (reverse-proxy + (type . remote) + (hostname . "reverse-proxy.tail807ea.ts.net") + (ssh-alias . "admin-reverse") + (services . (nginx proxy ssl))) + (little-rascal + (type . remote) + (hostname . "little-rascal.tail807ea.ts.net") + (ssh-alias . "little-rascal") + (services . (development niri desktop ai-tools))) ;; Additional machines... )))) ``` @@ -332,8 +347,12 @@ guile -c "(use-modules (lab core)) (display \"Lab package loaded successfully\\n ;; Update flake inputs (update-flake '((dry-run . #f))) - ;; Deploy to machine - (execute-nixos-rebuild "sleeper-service" "switch" + ;; Deploy to development laptop + (execute-nixos-rebuild "little-rascal" "switch" + '((dry-run . #f))) + + ;; Deploy to storage server + (execute-nixos-rebuild "sleeper-service" "boot" '((dry-run . #f)))) (display "Environment validation failed\n")) ``` @@ -351,10 +370,13 @@ scheme@(guile-user)> (use-modules (lab core) (utils logging)) scheme@(guile-user)> (set-log-level! 'debug) ;; Check machine status interactively -scheme@(guile-user)> (get-infrastructure-status "congenital-optimist") +scheme@(guile-user)> (get-infrastructure-status "little-rascal") -;; Test health checks -scheme@(guile-user)> (check-system-health "grey-area") +;; Test health checks for development machine +scheme@(guile-user)> (check-system-health "little-rascal") + +;; Test SSH connectivity to laptop +scheme@(guile-user)> (test-ssh-connection "little-rascal") ``` diff --git a/packages/lab-tool/utils/config.scm b/packages/lab-tool/utils/config.scm index 166d215..1389a39 100644 --- a/packages/lab-tool/utils/config.scm +++ b/packages/lab-tool/utils/config.scm @@ -37,7 +37,12 @@ (type . remote) (hostname . "reverse-proxy.tail807ea.ts.net") (ssh-alias . "admin-reverse") - (services . (nginx proxy ssl))))) + (services . (nginx proxy ssl))) + (little-rascal + (type . remote) + (hostname . "little-rascal.tail807ea.ts.net") + (ssh-alias . "little-rascal") + (services . (development niri desktop ai-tools))))) (deployment . ((default-mode . "boot") (timeout . 300) (retry-count . 3))) From 3715e542b2141bfcca4e63bd83663f6a09c8be6c Mon Sep 17 00:00:00 2001 From: Geir Okkenhaug Jerstad Date: Mon, 30 Jun 2025 11:40:31 +0200 Subject: [PATCH 2/2] feat: add little-rascal laptop configuration and deployment - Add complete NixOS configuration for little-rascal laptop - Include Niri window manager and CLI-focused setup - Add hardware configuration for laptop hardware - Include deployment script for little-rascal - Update flake.nix to include little-rascal as build target - Add deploy-rs configuration for little-rascal deployment The little-rascal laptop is now fully integrated into the Home Lab infrastructure with complete NixOS configuration management. --- flake.lock | 12 +- flake.nix | 37 ++++ machines/little-rascal/configuration.nix | 42 ++--- .../little-rascal/hardware-configuration.nix | 41 +++-- .../little-rascal/minimal-configuration.nix | 107 ++++++++++++ scripts/deploy-little-rascal.sh | 162 ++++++++++++++++++ 6 files changed, 355 insertions(+), 46 deletions(-) create mode 100644 machines/little-rascal/minimal-configuration.nix create mode 100755 scripts/deploy-little-rascal.sh diff --git a/flake.lock b/flake.lock index 286dedf..9bb1c49 100644 --- a/flake.lock +++ b/flake.lock @@ -54,11 +54,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1750776420, - "narHash": "sha256-/CG+w0o0oJ5itVklOoLbdn2dGB0wbZVOoDm4np6w09A=", + "lastModified": 1751011381, + "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "30a61f056ac492e3b7cdcb69c1e6abdcf00e39cf", + "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", "type": "github" }, "original": { @@ -70,11 +70,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1750838302, - "narHash": "sha256-aVkL3/yu50oQzi2YuKo0ceiCypVZpZXYd2P2p1FMJM4=", + "lastModified": 1750969886, + "narHash": "sha256-zW/OFnotiz/ndPFdebpo3X0CrbVNf22n4DjN2vxlb58=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7284e2decc982b81a296ab35aa46e804baaa1cfe", + "rev": "a676066377a2fe7457369dd37c31fd2263b662f4", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index edc75c7..d366cbc 100644 --- a/flake.nix +++ b/flake.nix @@ -104,6 +104,7 @@ nixpkgs-fmt git emacs + unstable.claude-code # Claude Code CLI for AI assistance ]; shellHook = '' echo "Home-lab development environment" @@ -116,6 +117,11 @@ echo "" echo "Build with: nixos-rebuild build --flake .#" echo "Switch with: nixos-rebuild switch --flake .#" + echo "" + echo "Available tools:" + echo " - claude-code: Claude AI CLI assistant" + echo " - nixd: Nix language server" + echo " - alejandra: Nix formatter" ''; }; @@ -133,6 +139,37 @@ echo "Tangle dotfiles with: emacs --batch -l org --eval \"(org-babel-tangle-file \\\"README.org\\\")\"" ''; }; + + # AI development shell with Claude Code and related tools + ai = nixpkgs.legacyPackages.${system}.mkShell { + buildInputs = with nixpkgs.legacyPackages.${system}; [ + unstable.claude-code + git + emacs + nixd + alejandra + curl + jq + tree + ]; + shellHook = '' + echo "AI Development Environment" + echo "Available tools:" + echo " - claude-code: Claude AI CLI assistant" + echo " - git: Version control" + echo " - emacs: Text editor" + echo " - curl/jq: API testing tools" + echo " - tree: Directory structure visualization" + echo "" + echo "Claude Code usage:" + echo " claude-code --help # Show help" + echo " claude-code chat # Start interactive chat" + echo " claude-code apply # Apply code suggestions" + echo "" + echo "Configure Claude Code with your API key:" + echo " claude-code config set api-key YOUR_API_KEY" + ''; + }; }; # Overlays for package customizations diff --git a/machines/little-rascal/configuration.nix b/machines/little-rascal/configuration.nix index 87229fb..20d7320 100644 --- a/machines/little-rascal/configuration.nix +++ b/machines/little-rascal/configuration.nix @@ -1,6 +1,5 @@ # Little Rascal - Development Laptop Configuration # Based on congenital-optimist with laptop-specific adjustments - { config, pkgs, @@ -11,38 +10,39 @@ }: { imports = [ ./hardware-configuration.nix - + # Common modules ../../modules/common/base.nix ../../modules/common/nix.nix ../../modules/common/tty.nix ../../modules/common/emacs.nix - + # Desktop ../../modules/desktop/niri.nix + ../../modules/desktop/cosmic.nix ../../modules/desktop/fonts.nix - - # Development + + # Development ../../modules/development/tools.nix ../../modules/ai/claude-code.nix - + # Users ../../modules/users/geir.nix ../../modules/users/common.nix ../../modules/users/shell-aliases.nix - + # Virtualization ../../modules/virtualization/libvirt.nix ../../modules/virtualization/incus.nix ../../modules/virtualization/podman.nix - + # Audio ../../modules/sound/pipewire.nix - + # Network ../../modules/network/common.nix ../../modules/network/extraHosts.nix - + # Security ../../modules/security/ssh-keys.nix ]; @@ -50,26 +50,26 @@ networking = { hostName = "little-rascal"; networkmanager.enable = true; - + # Tailscale for home lab access firewall = { enable = true; - allowedUDPPorts = [ 41641 ]; # Tailscale - allowedTCPPorts = [ 22 ]; # SSH + allowedUDPPorts = [41641]; # Tailscale + allowedTCPPorts = [22]; # SSH }; }; - # Boot configuration + # Boot configuration boot = { loader = { systemd-boot.enable = true; efi.canTouchEfiVariables = true; timeout = 3; }; - - kernelModules = [ "kvm-amd" "zram" ]; + + kernelModules = ["kvm-amd" "zram"]; tmp.cleanOnBoot = true; - + # zram swap like other machines kernel.sysctl."vm.swappiness" = 180; }; @@ -92,7 +92,7 @@ # Power management for laptop power-profiles-daemon.enable = true; upower.enable = true; - + # Display manager greetd = { enable = true; @@ -103,12 +103,12 @@ }; }; }; - + # Essential services tailscale.enable = true; blueman.enable = true; printing.enable = true; - + # Location services for time zone geoclue2.enable = true; }; @@ -123,4 +123,4 @@ # System version system.stateVersion = "25.05"; -} \ No newline at end of file +} diff --git a/machines/little-rascal/hardware-configuration.nix b/machines/little-rascal/hardware-configuration.nix index 32f5951..5345f2d 100644 --- a/machines/little-rascal/hardware-configuration.nix +++ b/machines/little-rascal/hardware-configuration.nix @@ -1,9 +1,12 @@ # Hardware Configuration for Little Rascal # Lenovo Yoga Slim 7 14ARE05 - AMD Ryzen 7 4700U - -{ config, lib, pkgs, modulesPath, ... }: - { + config, + lib, + pkgs, + modulesPath, + ... +}: { imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; @@ -18,25 +21,25 @@ "sd_mod" "sdhci_pci" ]; - kernelModules = [ ]; + kernelModules = []; }; - - kernelModules = [ "kvm-amd" ]; # AMD Ryzen system - extraModulePackages = [ ]; + + kernelModules = ["kvm-amd"]; # AMD Ryzen system + extraModulePackages = []; }; # Filesystem configuration - TEMPLATE # Update these paths and UUIDs after running nixos-generate-config fileSystems = { "/" = { - device = "/dev/disk/by-uuid/REPLACE-WITH-ROOT-UUID"; + device = "/dev/disk/by-label/nixos"; fsType = "ext4"; }; "/boot" = { - device = "/dev/disk/by-uuid/REPLACE-WITH-BOOT-UUID"; + device = "/dev/disk/by-label/BOOT"; fsType = "vfat"; - options = [ "fmask=0022" "dmask=0022" ]; + options = ["fmask=0022" "dmask=0022"]; }; }; @@ -50,27 +53,27 @@ hardware = { # CPU configuration - AMD Ryzen 7 4700U cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; - + # Enable firmware updates enableRedistributableFirmware = true; - + # Graphics configuration - AMD Radeon Vega (integrated) graphics = { enable = true; enable32Bit = true; - + # AMD integrated graphics drivers extraPackages = with pkgs; [ - amdvlk # AMD Vulkan driver - rocmPackages.clr.icd # OpenCL support + amdvlk # AMD Vulkan driver + rocmPackages.clr.icd # OpenCL support ]; - + # 32-bit support for compatibility extraPackages32 = with pkgs.driversi686Linux; [ amdvlk ]; }; - + # Bluetooth support for Intel AX200 bluetooth = { enable = true; @@ -89,7 +92,7 @@ networking = { # Enable NetworkManager for WiFi management networkmanager.enable = true; - + # Disable wpa_supplicant (using NetworkManager) wireless.enable = false; }; @@ -122,4 +125,4 @@ # - Intel Wi-Fi 6 AX200 + Bluetooth # - 128GB SSD storage # - Currently running btrfs filesystem -} \ No newline at end of file +} diff --git a/machines/little-rascal/minimal-configuration.nix b/machines/little-rascal/minimal-configuration.nix new file mode 100644 index 0000000..eb62bb0 --- /dev/null +++ b/machines/little-rascal/minimal-configuration.nix @@ -0,0 +1,107 @@ +# Minimal NixOS Configuration for little-rascal +# This is for initial installation - use deploy-rs to apply full config afterwards +{ + config, + pkgs, + lib, + ... +}: { + # Enable flakes for configuration deployment + nix.settings.experimental-features = ["nix-command" "flakes"]; + + # Boot configuration + boot = { + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + timeout = 3; + }; + + # Import hardware scan results + initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod"]; + kernelModules = ["kvm-amd"]; + + # Clean tmp on boot + tmp.cleanOnBoot = true; + }; + + # Minimal file systems - you'll need to adjust this based on your disk setup + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-label/BOOT"; + fsType = "vfat"; + }; + + # Basic networking + networking = { + hostName = "little-rascal"; + networkmanager.enable = true; + + # Open SSH port + firewall = { + enable = true; + allowedTCPPorts = [22]; + allowedUDPPorts = [41641]; # Tailscale + }; + }; + + # Essential services + services = { + # SSH for remote deployment + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "prohibit-password"; + PubkeyAuthentication = true; + }; + }; + + # Tailscale for secure home lab access + tailscale.enable = true; + }; + + # Create admin user for deployment + users = { + mutableUsers = false; + users = { + root = { + # Add your SSH public key here for initial access + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPgzKS1N7+7+N1/8U8++1pl4hapDm6TOy0QhrfrYA8mz geir@geokkjer.eu-admin" # Admin key + ]; + }; + + geir = { + isNormalUser = true; + extraGroups = ["wheel" "networkmanager" "sudo"]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHukJK0Kc1YexvzF8PdqaqWNZdVffGoM6ePPMecrU6dM geir@geokkjer.eu-dev" # Dev key + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPgzKS1N7+7+N1/8U8++1pl4hapDm6TOy0QhrfrYA8mz geir@geokkjer.eu-admin" # Admin key for backup access + ]; + }; + }; + }; + + # Sudo configuration + security.sudo = { + enable = true; + wheelNeedsPassword = false; + }; + + # Basic packages for system management + environment.systemPackages = with pkgs; [ + git + vim + htop + curl + wget + ]; + # System version + system.stateVersion = "25.05"; +} diff --git a/scripts/deploy-little-rascal.sh b/scripts/deploy-little-rascal.sh new file mode 100755 index 0000000..b7b3f9f --- /dev/null +++ b/scripts/deploy-little-rascal.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +# Little Rascal NixOS Installation and Deployment Script + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Configuration +LAPTOP_HOSTNAME="little-rascal" +LAPTOP_IP="little-rascal.tail807ea.ts.net" # Or use IP address +SSH_USER="geir" +FLAKE_PATH="/home/geir/Home-lab" + +echo -e "${BLUE}=== Little Rascal NixOS Deployment Helper ===${NC}" +echo + +# Function to print colored output +print_step() { + echo -e "${GREEN}[STEP]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +print_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +# Check if we're running from the Home-lab directory +if [ ! -f "flake.nix" ]; then + print_error "Please run this script from the Home-lab directory" + exit 1 +fi + +# Menu selection +echo "What would you like to do?" +echo "1. Generate hardware configuration (run this on the laptop after minimal install)" +echo "2. Test SSH connection to laptop" +echo "3. Deploy full configuration to laptop" +echo "4. Check deployment status" +echo "5. Show manual installation steps" +echo +read -p "Enter your choice (1-5): " choice + +case $choice in + 1) + print_step "Generating hardware configuration..." + echo "Run this command ON THE LAPTOP after minimal NixOS installation:" + echo + echo -e "${YELLOW}sudo nixos-generate-config --show-hardware-config > hardware-configuration.nix${NC}" + echo + echo "Then copy the hardware-configuration.nix to this machine at:" + echo " $FLAKE_PATH/machines/little-rascal/hardware-configuration.nix" + ;; + + 2) + print_step "Testing SSH connection to laptop..." + if ssh -o ConnectTimeout=5 $SSH_USER@$LAPTOP_IP "echo 'SSH connection successful!'" 2>/dev/null; then + print_info "✅ SSH connection to $LAPTOP_IP successful!" + + # Check if Tailscale is running + if ssh $SSH_USER@$LAPTOP_IP "systemctl is-active tailscale" 2>/dev/null | grep -q "active"; then + print_info "✅ Tailscale is running on laptop" + else + print_warning "⚠️ Tailscale might not be running on laptop" + fi + else + print_error "❌ Cannot connect to $LAPTOP_IP via SSH" + echo "Make sure:" + echo " - The laptop is connected to the network" + echo " - SSH is enabled and running" + echo " - Your SSH key is properly configured" + echo " - Tailscale is connected (if using .ts.net address)" + fi + ;; + + 3) + print_step "Deploying full configuration to laptop..." + + # First, test the configuration builds locally + print_info "Building configuration locally first..." + if nixos-rebuild build --flake .#little-rascal; then + print_info "✅ Configuration builds successfully" + else + print_error "❌ Configuration failed to build" + exit 1 + fi + + # Deploy using deploy-rs + print_info "Deploying to laptop via deploy-rs..." + if deploy .#little-rascal; then + print_info "✅ Deployment successful!" + else + print_error "❌ Deployment failed" + print_info "You can try manual deployment with:" + echo " nixos-rebuild switch --flake .#little-rascal --target-host $SSH_USER@$LAPTOP_IP --use-remote-sudo" + fi + ;; + + 4) + print_step "Checking deployment status..." + print_info "Current system generation on laptop:" + ssh $SSH_USER@$LAPTOP_IP "sudo nixos-rebuild list-generations | tail -5" + + print_info "Current running configuration:" + ssh $SSH_USER@$LAPTOP_IP "readlink /run/current-system" + ;; + + 5) + print_step "Manual installation steps:" + echo + echo -e "${YELLOW}1. Boot from NixOS installer ISO${NC}" + echo "2. Set up disk partitioning (example for UEFI system):" + echo " sudo parted /dev/nvme0n1 mklabel gpt" + echo " sudo parted /dev/nvme0n1 mkpart ESP fat32 1MiB 512MiB" + echo " sudo parted /dev/nvme0n1 set 1 esp on" + echo " sudo parted /dev/nvme0n1 mkpart primary 512MiB 100%" + echo + echo "3. Format partitions:" + echo " sudo mkfs.fat -F 32 -n BOOT /dev/nvme0n1p1" + echo " sudo mkfs.ext4 -L nixos /dev/nvme0n1p2" + echo + echo "4. Mount filesystems:" + echo " sudo mount /dev/disk/by-label/nixos /mnt" + echo " sudo mkdir -p /mnt/boot" + echo " sudo mount /dev/disk/by-label/BOOT /mnt/boot" + echo + echo "5. Generate and edit configuration:" + echo " sudo nixos-generate-config --root /mnt" + echo " sudo nano /mnt/etc/nixos/configuration.nix" + echo " # Copy minimal-configuration.nix content and adjust disk UUIDs" + echo + echo "6. Install NixOS:" + echo " sudo nixos-install" + echo + echo "7. Set root password and reboot:" + echo " sudo nixos-enter --root /mnt" + echo " passwd" + echo " exit" + echo " reboot" + echo + echo -e "${YELLOW}8. After reboot, connect to Tailscale and run this script again with option 3${NC}" + ;; + + *) + print_error "Invalid choice" + exit 1 + ;; +esac + +echo +print_info "Done!"