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.
This commit is contained in:
Geir Okkenhaug Jerstad 2025-06-30 11:40:31 +02:00
parent f42bae513c
commit 3715e542b2
6 changed files with 355 additions and 46 deletions

12
flake.lock generated
View file

@ -54,11 +54,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1750776420, "lastModified": 1751011381,
"narHash": "sha256-/CG+w0o0oJ5itVklOoLbdn2dGB0wbZVOoDm4np6w09A=", "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "30a61f056ac492e3b7cdcb69c1e6abdcf00e39cf", "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -70,11 +70,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1750838302, "lastModified": 1750969886,
"narHash": "sha256-aVkL3/yu50oQzi2YuKo0ceiCypVZpZXYd2P2p1FMJM4=", "narHash": "sha256-zW/OFnotiz/ndPFdebpo3X0CrbVNf22n4DjN2vxlb58=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7284e2decc982b81a296ab35aa46e804baaa1cfe", "rev": "a676066377a2fe7457369dd37c31fd2263b662f4",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -104,6 +104,7 @@
nixpkgs-fmt nixpkgs-fmt
git git
emacs emacs
unstable.claude-code # Claude Code CLI for AI assistance
]; ];
shellHook = '' shellHook = ''
echo "Home-lab development environment" echo "Home-lab development environment"
@ -116,6 +117,11 @@
echo "" echo ""
echo "Build with: nixos-rebuild build --flake .#<config>" echo "Build with: nixos-rebuild build --flake .#<config>"
echo "Switch with: nixos-rebuild switch --flake .#<config>" echo "Switch with: nixos-rebuild switch --flake .#<config>"
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\\\")\"" 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 # Overlays for package customizations

View file

@ -1,6 +1,5 @@
# Little Rascal - Development Laptop Configuration # Little Rascal - Development Laptop Configuration
# Based on congenital-optimist with laptop-specific adjustments # Based on congenital-optimist with laptop-specific adjustments
{ {
config, config,
pkgs, pkgs,
@ -11,38 +10,39 @@
}: { }: {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# Common modules # Common modules
../../modules/common/base.nix ../../modules/common/base.nix
../../modules/common/nix.nix ../../modules/common/nix.nix
../../modules/common/tty.nix ../../modules/common/tty.nix
../../modules/common/emacs.nix ../../modules/common/emacs.nix
# Desktop # Desktop
../../modules/desktop/niri.nix ../../modules/desktop/niri.nix
../../modules/desktop/cosmic.nix
../../modules/desktop/fonts.nix ../../modules/desktop/fonts.nix
# Development # Development
../../modules/development/tools.nix ../../modules/development/tools.nix
../../modules/ai/claude-code.nix ../../modules/ai/claude-code.nix
# Users # Users
../../modules/users/geir.nix ../../modules/users/geir.nix
../../modules/users/common.nix ../../modules/users/common.nix
../../modules/users/shell-aliases.nix ../../modules/users/shell-aliases.nix
# Virtualization # Virtualization
../../modules/virtualization/libvirt.nix ../../modules/virtualization/libvirt.nix
../../modules/virtualization/incus.nix ../../modules/virtualization/incus.nix
../../modules/virtualization/podman.nix ../../modules/virtualization/podman.nix
# Audio # Audio
../../modules/sound/pipewire.nix ../../modules/sound/pipewire.nix
# Network # Network
../../modules/network/common.nix ../../modules/network/common.nix
../../modules/network/extraHosts.nix ../../modules/network/extraHosts.nix
# Security # Security
../../modules/security/ssh-keys.nix ../../modules/security/ssh-keys.nix
]; ];
@ -50,26 +50,26 @@
networking = { networking = {
hostName = "little-rascal"; hostName = "little-rascal";
networkmanager.enable = true; networkmanager.enable = true;
# Tailscale for home lab access # Tailscale for home lab access
firewall = { firewall = {
enable = true; enable = true;
allowedUDPPorts = [ 41641 ]; # Tailscale allowedUDPPorts = [41641]; # Tailscale
allowedTCPPorts = [ 22 ]; # SSH allowedTCPPorts = [22]; # SSH
}; };
}; };
# Boot configuration # Boot configuration
boot = { boot = {
loader = { loader = {
systemd-boot.enable = true; systemd-boot.enable = true;
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
timeout = 3; timeout = 3;
}; };
kernelModules = [ "kvm-amd" "zram" ]; kernelModules = ["kvm-amd" "zram"];
tmp.cleanOnBoot = true; tmp.cleanOnBoot = true;
# zram swap like other machines # zram swap like other machines
kernel.sysctl."vm.swappiness" = 180; kernel.sysctl."vm.swappiness" = 180;
}; };
@ -92,7 +92,7 @@
# Power management for laptop # Power management for laptop
power-profiles-daemon.enable = true; power-profiles-daemon.enable = true;
upower.enable = true; upower.enable = true;
# Display manager # Display manager
greetd = { greetd = {
enable = true; enable = true;
@ -103,12 +103,12 @@
}; };
}; };
}; };
# Essential services # Essential services
tailscale.enable = true; tailscale.enable = true;
blueman.enable = true; blueman.enable = true;
printing.enable = true; printing.enable = true;
# Location services for time zone # Location services for time zone
geoclue2.enable = true; geoclue2.enable = true;
}; };
@ -123,4 +123,4 @@
# System version # System version
system.stateVersion = "25.05"; system.stateVersion = "25.05";
} }

View file

@ -1,9 +1,12 @@
# Hardware Configuration for Little Rascal # Hardware Configuration for Little Rascal
# Lenovo Yoga Slim 7 14ARE05 - AMD Ryzen 7 4700U # Lenovo Yoga Slim 7 14ARE05 - AMD Ryzen 7 4700U
{ config, lib, pkgs, modulesPath, ... }:
{ {
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [ imports = [
(modulesPath + "/installer/scan/not-detected.nix") (modulesPath + "/installer/scan/not-detected.nix")
]; ];
@ -18,25 +21,25 @@
"sd_mod" "sd_mod"
"sdhci_pci" "sdhci_pci"
]; ];
kernelModules = [ ]; kernelModules = [];
}; };
kernelModules = [ "kvm-amd" ]; # AMD Ryzen system kernelModules = ["kvm-amd"]; # AMD Ryzen system
extraModulePackages = [ ]; extraModulePackages = [];
}; };
# Filesystem configuration - TEMPLATE # Filesystem configuration - TEMPLATE
# Update these paths and UUIDs after running nixos-generate-config # Update these paths and UUIDs after running nixos-generate-config
fileSystems = { fileSystems = {
"/" = { "/" = {
device = "/dev/disk/by-uuid/REPLACE-WITH-ROOT-UUID"; device = "/dev/disk/by-label/nixos";
fsType = "ext4"; fsType = "ext4";
}; };
"/boot" = { "/boot" = {
device = "/dev/disk/by-uuid/REPLACE-WITH-BOOT-UUID"; device = "/dev/disk/by-label/BOOT";
fsType = "vfat"; fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ]; options = ["fmask=0022" "dmask=0022"];
}; };
}; };
@ -50,27 +53,27 @@
hardware = { hardware = {
# CPU configuration - AMD Ryzen 7 4700U # CPU configuration - AMD Ryzen 7 4700U
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Enable firmware updates # Enable firmware updates
enableRedistributableFirmware = true; enableRedistributableFirmware = true;
# Graphics configuration - AMD Radeon Vega (integrated) # Graphics configuration - AMD Radeon Vega (integrated)
graphics = { graphics = {
enable = true; enable = true;
enable32Bit = true; enable32Bit = true;
# AMD integrated graphics drivers # AMD integrated graphics drivers
extraPackages = with pkgs; [ extraPackages = with pkgs; [
amdvlk # AMD Vulkan driver amdvlk # AMD Vulkan driver
rocmPackages.clr.icd # OpenCL support rocmPackages.clr.icd # OpenCL support
]; ];
# 32-bit support for compatibility # 32-bit support for compatibility
extraPackages32 = with pkgs.driversi686Linux; [ extraPackages32 = with pkgs.driversi686Linux; [
amdvlk amdvlk
]; ];
}; };
# Bluetooth support for Intel AX200 # Bluetooth support for Intel AX200
bluetooth = { bluetooth = {
enable = true; enable = true;
@ -89,7 +92,7 @@
networking = { networking = {
# Enable NetworkManager for WiFi management # Enable NetworkManager for WiFi management
networkmanager.enable = true; networkmanager.enable = true;
# Disable wpa_supplicant (using NetworkManager) # Disable wpa_supplicant (using NetworkManager)
wireless.enable = false; wireless.enable = false;
}; };
@ -122,4 +125,4 @@
# - Intel Wi-Fi 6 AX200 + Bluetooth # - Intel Wi-Fi 6 AX200 + Bluetooth
# - 128GB SSD storage # - 128GB SSD storage
# - Currently running btrfs filesystem # - Currently running btrfs filesystem
} }

View file

@ -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";
}

162
scripts/deploy-little-rascal.sh Executable file
View file

@ -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!"