feat: Add little-rascal laptop config and lab-tool auto-update system

## New Machine: little-rascal
- Add Lenovo Yoga Slim 7 14ARE05 configuration (AMD Ryzen 7 4700U)
- Niri desktop with CLI login (greetd + tuigreet)
- zram swap configuration (25% of RAM with zstd)
- AMD-optimized hardware support and power management
- Based on congenital-optimist structure with laptop-specific additions

## Lab Tool Auto-Update System
- Implement Guile Scheme auto-update module (lab/auto-update.scm)
- Add health checks, logging, and safety features
- Integrate with existing deployment and machine management
- Update main CLI with auto-update and auto-update-status commands
- Create NixOS service module for automated updates
- Document complete implementation in simple-auto-update-plan.md

## MCP Integration
- Configure Task Master AI and Context7 MCP servers
- Set up local Ollama integration for AI processing
- Add proper environment configuration for existing models

## Infrastructure Updates
- Add little-rascal to flake.nix with deploy-rs support
- Fix common user configuration issues
- Create missing emacs.nix module
- Update package integrations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Geir Okkenhaug Jerstad 2025-06-27 22:03:54 +02:00
parent 5e1061382c
commit 6eac143f57
19 changed files with 1287 additions and 559 deletions

View file

@ -0,0 +1,28 @@
# Common Emacs Configuration
# Shared Emacs setup for all machines
{
config,
pkgs,
...
}: {
# System-wide Emacs configuration
programs.emacs = {
enable = true;
package = pkgs.emacs;
defaultEditor = true;
};
# Emacs packages and configuration
environment.systemPackages = with pkgs; [
emacs
# Basic Emacs utilities
emacsPackages.use-package
];
# Set Emacs as default editor
environment.sessionVariables = {
EDITOR = "emacs";
VISUAL = "emacs";
};
}

View file

@ -0,0 +1,44 @@
# Example configuration for enabling lab auto-update service
# Add this to your machine's configuration.nix
{
# Import the lab auto-update service module
imports = [
../services/lab-auto-update.nix
];
# Enable and configure the auto-update service
services.lab-auto-update = {
enable = true;
# Schedule updates at 2:00 AM with up to 30 minute random delay
schedule = "02:00";
randomizedDelay = "30m";
# Path to your home lab flake
flakePath = "/home/geir/Projects/home-lab";
# Keep logs for 30 days
logRetentionDays = 30;
# Persist timer across reboots
persistent = true;
};
# Optional: Enable the lab tool package system-wide
environment.systemPackages = with pkgs; [
(pkgs.callPackage ../../packages/lab-tools.nix {}).default
];
# Optional: Staggered scheduling for different machine types
# Uncomment and modify based on machine role:
# For database/storage servers (run first)
# services.lab-auto-update.schedule = "02:00";
# For application servers (run after storage)
# services.lab-auto-update.schedule = "02:30";
# For development machines (run last)
# services.lab-auto-update.schedule = "03:00";
}

View file

@ -0,0 +1,201 @@
# modules/services/lab-auto-update.nix - NixOS service for automatic lab updates
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.lab-auto-update;
# Get the lab tool from our packages
labTool = pkgs.callPackage ../../packages/lab-tools.nix {};
# Auto-update script that uses the Guile lab tool
autoUpdateScript = pkgs.writeShellScript "lab-auto-update" ''
#!/usr/bin/env bash
set -euo pipefail
LOG_FILE="/var/log/lab-auto-update.log"
LOCK_FILE="/var/run/lab-auto-update.lock"
# Ensure we don't run multiple instances
if [ -f "$LOCK_FILE" ]; then
echo "$(date): Auto-update already running (lock file exists)" >> "$LOG_FILE"
exit 1
fi
# Create lock file
echo $$ > "$LOCK_FILE"
# Cleanup function
cleanup() {
rm -f "$LOCK_FILE"
}
trap cleanup EXIT
echo "$(date): Starting lab auto-update" >> "$LOG_FILE"
# Change to the lab directory
cd "${cfg.flakePath}"
# Run the Guile lab tool auto-update command
if ${labTool}/bin/lab auto-update 2>&1 | tee -a "$LOG_FILE"; then
echo "$(date): Auto-update completed successfully" >> "$LOG_FILE"
else
echo "$(date): Auto-update failed with exit code $?" >> "$LOG_FILE"
exit 1
fi
'';
in
{
options.services.lab-auto-update = {
enable = mkEnableOption "Lab auto-update service";
schedule = mkOption {
type = types.str;
default = "02:00";
description = "Time to run updates (HH:MM format)";
};
randomizedDelay = mkOption {
type = types.str;
default = "30m";
description = "Maximum random delay before starting update";
};
flakePath = mkOption {
type = types.str;
default = "/home/geir/Projects/home-lab";
description = "Path to the home lab flake directory";
};
persistent = mkOption {
type = types.bool;
default = true;
description = "Whether the timer should be persistent across reboots";
};
logRetentionDays = mkOption {
type = types.int;
default = 30;
description = "Number of days to retain auto-update logs";
};
};
config = mkIf cfg.enable {
# Systemd service for the auto-update
systemd.services.lab-auto-update = {
description = "Home Lab Auto-Update Service";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
ExecStart = "${autoUpdateScript}";
# Security settings
PrivateTmp = true;
ProtectSystem = false; # We need to modify the system
ProtectHome = true;
NoNewPrivileges = false; # We need privileges for nixos-rebuild
# Resource limits
MemoryMax = "2G";
CPUQuota = "50%";
# Timeout settings
TimeoutStartSec = "30m";
TimeoutStopSec = "5m";
};
# Environment variables for the service
environment = {
PATH = lib.makeBinPath (with pkgs; [
nix
nixos-rebuild
git
openssh
rsync
gawk
gnused
coreutils
util-linux
systemd
]);
NIX_PATH = "nixpkgs=${pkgs.path}";
};
};
# Systemd timer for scheduling
systemd.timers.lab-auto-update = {
description = "Home Lab Auto-Update Timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = cfg.persistent;
RandomizedDelaySec = cfg.randomizedDelay;
# Run at the specified time
OnCalendar = "*-*-* ${cfg.schedule}:00";
# Accuracy settings
AccuracySec = "1min";
};
};
# Log rotation for auto-update logs
services.logrotate.settings.lab-auto-update = {
files = "/var/log/lab-auto-update.log";
frequency = "daily";
rotate = cfg.logRetentionDays;
compress = true;
delaycompress = true;
missingok = true;
notifempty = true;
create = "644 root root";
postrotate = ''
systemctl reload-or-restart rsyslog.service > /dev/null 2>&1 || true
'';
};
# Ensure log directory exists with proper permissions
systemd.tmpfiles.rules = [
"d /var/log 0755 root root -"
"f /var/log/lab-auto-update.log 0644 root root -"
];
# Add a systemd target for manual triggering
systemd.targets.lab-manual-update = {
description = "Manual Lab Update Target";
};
# Service for manual updates (without reboot)
systemd.services.lab-manual-update = {
description = "Manual Home Lab Update (No Reboot)";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
ExecStart = "${labTool}/bin/lab update";
RemainAfterExit = false;
};
environment = {
PATH = lib.makeBinPath (with pkgs; [
nix
nixos-rebuild
git
openssh
rsync
]);
};
};
};
}

View file

@ -29,12 +29,7 @@
eval "$(direnv hook zsh)"
'';
# Common environment variables
sessionVariables = {
EDITOR = "emacs";
BROWSER = "firefox";
TERMINAL = "kitty";
};
# Removed sessionVariables - moved to environment.sessionVariables
};
# Common packages for all users