From f8827f3da3b37e90e22ad8449b38e7d7aed0a6e1 Mon Sep 17 00:00:00 2001 From: Yan Lin Date: Sun, 12 Oct 2025 11:25:46 +0200 Subject: [PATCH] Remove container updater --- README.md | 3 - hosts/nixos/hs/system.nix | 10 --- modules/container-updater.nix | 83 ------------------- modules/login-display.nix | 150 ---------------------------------- scripts/container-update.sh | 120 --------------------------- 5 files changed, 366 deletions(-) delete mode 100644 modules/container-updater.nix delete mode 100755 scripts/container-update.sh diff --git a/README.md b/README.md index cba968e..77ac754 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,6 @@ Modules are self-contained and handle both package installation and configuratio - `borg-server.nix` - Backup server configuration - `btop.nix` - System monitor with vim navigation - `claude-code.nix` - AI coding assistant with permissions config -- `container-updater.nix` - Automated container updates - `dictionary.nix` - Offline dictionary system (sdcv) - `firefox.nix` - Browser with extensions and bookmarks - `ghostty.nix` - GPU-accelerated terminal emulator @@ -97,7 +96,6 @@ Modules are self-contained and handle both package installation and configuratio ## Scripts -- `container-update.sh` - Update container images safely - `project-launcher.sh` - Tmux session manager for projects ## Custom Workflows @@ -141,7 +139,6 @@ systemctl list-timers ### Manual Timer Service Execution - `dl-subs-yt` - Check YouTube subscriptions and download new videos -- `container-update-now` - Update container images manually - `borg-backup-now` - Run backup manually ## Notes diff --git a/hosts/nixos/hs/system.nix b/hosts/nixos/hs/system.nix index 48020d5..33fd48e 100644 --- a/hosts/nixos/hs/system.nix +++ b/hosts/nixos/hs/system.nix @@ -10,7 +10,6 @@ ../../../modules/samba.nix ../../../modules/borg-client.nix ../../../modules/webdav.nix - ../../../modules/container-updater.nix ../../../modules/login-display.nix ]; @@ -110,14 +109,6 @@ ]; }; - - # Container auto-updater configuration - services.containerUpdater = { - enable = true; - schedule = "*-*-* 03:00:00"; # Daily at 3 AM - excludeContainers = []; # Update all containers - }; - # Host-specific packages environment.systemPackages = with pkgs; [ smartmontools # For monitoring disk health @@ -231,7 +222,6 @@ showDiskUsage = true; diskUsagePaths = [ "/" "/mnt/storage" "/mnt/parity" ]; showSnapraidStatus = true; - showContainerUpdater = true; showBorgStatus = true; }; diff --git a/modules/container-updater.nix b/modules/container-updater.nix deleted file mode 100644 index 2862d52..0000000 --- a/modules/container-updater.nix +++ /dev/null @@ -1,83 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.services.containerUpdater; -in -{ - options.services.containerUpdater = { - enable = mkEnableOption "automatic container updates"; - - schedule = mkOption { - type = types.str; - default = "*-*-* 03:00:00"; - example = "daily"; - description = '' - Systemd timer schedule for container updates. - Can be a systemd time specification or alias like "daily", "weekly". - ''; - }; - - excludeContainers = mkOption { - type = types.listOf types.str; - default = []; - example = [ "traefik" "wireguard" ]; - description = '' - List of container names to exclude from automatic updates. - ''; - }; - }; - - config = mkIf cfg.enable { - # Ensure the update script exists and is executable - system.activationScripts.container-updater = '' - chmod +x /home/yanlin/.config/nix/scripts/container-update.sh - ''; - - # Shell alias for manual execution - environment.shellAliases = { - container-update-now = "sudo systemctl start container-updater.service"; - }; - - # Systemd service for container updates - systemd.services.container-updater = { - description = "Update podman containers to latest images"; - after = [ "network-online.target" ]; - wants = [ "network-online.target" ]; - - environment = { - EXCLUDE_CONTAINERS = concatStringsSep "," cfg.excludeContainers; - }; - - path = [ pkgs.podman pkgs.curl pkgs.coreutils pkgs.nettools ]; - - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.bash}/bin/bash /home/yanlin/.config/nix/scripts/container-update.sh"; - User = "root"; - StandardOutput = "journal"; - StandardError = "journal"; - - # Restart policy - Restart = "on-failure"; - RestartSec = "5min"; - - # Timeout for the update process (30 minutes should be enough) - TimeoutStartSec = "30min"; - }; - }; - - # Systemd timer for scheduled updates - systemd.timers.container-updater = { - description = "Timer for automatic container updates"; - wantedBy = [ "timers.target" ]; - - timerConfig = { - OnCalendar = cfg.schedule; - Persistent = true; - RandomizedDelaySec = "5min"; - }; - }; - }; -} \ No newline at end of file diff --git a/modules/login-display.nix b/modules/login-display.nix index ebfcaf0..b685095 100644 --- a/modules/login-display.nix +++ b/modules/login-display.nix @@ -49,12 +49,6 @@ in description = "Show last borg backup status"; }; - showContainerUpdater = mkOption { - type = types.bool; - default = false; - description = "Show last container updater status"; - }; - showSnapraidStatus = mkOption { type = types.bool; default = false; @@ -324,146 +318,6 @@ in fi ''; - # Build container updater status display - containerUpdaterStatusCode = optionalString cfg.showContainerUpdater '' - # Query journalctl for container-updater.service - CONTAINER_LOG=$(journalctl -u container-updater.service -n 150 --no-pager --output=cat 2>/dev/null || echo "") - - if [[ -z "$CONTAINER_LOG" ]]; then - # Service never ran - printf " \\033[38;2;250;189;47m⚠\\033[0m \\033[2mNever run\\033[0m\n" - else - # Check if last update completed - if echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -q "Container update completed successfully"; then - STATUS_SYMBOL="\\033[38;2;184;187;38m✓\\033[0m" - STATUS_COLOR="\\033[38;2;184;187;38m" - STATUS_TEXT="SUCCESS" - - # Get timestamp of last successful update - LAST_TIMESTAMP=$(journalctl -u container-updater.service --output=short-iso -n 150 --no-pager 2>/dev/null | ${pkgs.gnugrep}/bin/grep "Container update completed successfully" | tail -1 | ${pkgs.gawk}/bin/awk '{print $1}') - - if [[ -n "$LAST_TIMESTAMP" ]]; then - # Calculate time ago - LAST_EPOCH=$(date -d "$LAST_TIMESTAMP" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%S%z" "$LAST_TIMESTAMP" +%s 2>/dev/null || echo "0") - NOW_EPOCH=$(date +%s) - DIFF_SECONDS=$((NOW_EPOCH - LAST_EPOCH)) - - if [[ $DIFF_SECONDS -lt 3600 ]]; then - TIME_AGO="$((DIFF_SECONDS / 60))m ago" - elif [[ $DIFF_SECONDS -lt 86400 ]]; then - TIME_AGO="$((DIFF_SECONDS / 3600))h ago" - else - TIME_AGO="$((DIFF_SECONDS / 86400))d ago" - fi - - # Adjust color based on age - if [[ $DIFF_SECONDS -gt 172800 ]]; then - # > 48h - red - STATUS_SYMBOL="\\033[38;2;251;73;52m✗\\033[0m" - STATUS_COLOR="\\033[38;2;251;73;52m" - elif [[ $DIFF_SECONDS -gt 86400 ]]; then - # 24-48h - yellow - STATUS_SYMBOL="\\033[38;2;250;189;47m⚠\\033[0m" - STATUS_COLOR="\\033[38;2;250;189;47m" - fi - else - TIME_AGO="Unknown" - fi - - # Extract container counts from summary - UPDATED_COUNT=$(echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -oP "✅ Updated \(\K[0-9]+" | tail -1) - FAILED_COUNT=$(echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -oP "❌ Failed \(\K[0-9]+" | tail -1) - SKIPPED_COUNT=$(echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -oP "⏭️ No updates \(\K[0-9]+" | tail -1) - - # Build summary text - SUMMARY_PARTS=() - [[ -n "$UPDATED_COUNT" && "$UPDATED_COUNT" != "0" ]] && SUMMARY_PARTS+=("$UPDATED_COUNT updated") - [[ -n "$FAILED_COUNT" && "$FAILED_COUNT" != "0" ]] && SUMMARY_PARTS+=("$FAILED_COUNT failed") - [[ -n "$SKIPPED_COUNT" && "$SKIPPED_COUNT" != "0" ]] && SUMMARY_PARTS+=("$SKIPPED_COUNT skipped") - - SUMMARY=$(IFS=", "; echo "''${SUMMARY_PARTS[*]}") - [[ -z "$SUMMARY" ]] && SUMMARY="No containers" - - # Display main status line - printf " %b \\033[2mLast update\\033[0m %b%s\\033[0m \\033[2m%s\\033[0m\n" "$STATUS_SYMBOL" "$STATUS_COLOR" "$TIME_AGO" "$SUMMARY" - - # Extract and display updated containers (only those actually updated, not skipped) - if [[ -n "$UPDATED_COUNT" && "$UPDATED_COUNT" != "0" ]]; then - UPDATED_LIST=$(echo "$CONTAINER_LOG" | ${pkgs.gawk}/bin/awk '/✅ Updated \([0-9]+\):/,/^(❌|⏭️|=|$)/ {if ($0 ~ /^ • / && $0 !~ /\(no update\)/) {gsub(/^ • /, ""); print}}' | tr '\n' ', ' | sed 's/, $//') - if [[ -n "$UPDATED_LIST" ]]; then - printf " \\033[2m Updated: %s\\033[0m\n" "$UPDATED_LIST" - fi - fi - - # Extract and display failed containers - if [[ -n "$FAILED_COUNT" && "$FAILED_COUNT" != "0" ]]; then - FAILED_LIST=$(echo "$CONTAINER_LOG" | ${pkgs.gawk}/bin/awk '/❌ Failed \([0-9]+\):/,/^(✅|⏭️|=|$)/ {if ($0 ~ /^ • /) {gsub(/^ • /, ""); print}}' | tr '\n' ', ' | sed 's/, $//') - if [[ -n "$FAILED_LIST" ]]; then - printf " \\033[38;2;251;73;52m Failed: %s\\033[0m\n" "$FAILED_LIST" - fi - fi - - elif echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -q "ERROR: Some containers failed to update"; then - # Update ran but had failures - STATUS_SYMBOL="\\033[38;2;251;73;52m✗\\033[0m" - STATUS_COLOR="\\033[38;2;251;73;52m" - - # Get timestamp - LAST_TIMESTAMP=$(journalctl -u container-updater.service --output=short-iso -n 150 --no-pager 2>/dev/null | ${pkgs.gnugrep}/bin/grep "ERROR: Some containers failed to update" | tail -1 | ${pkgs.gawk}/bin/awk '{print $1}') - - if [[ -n "$LAST_TIMESTAMP" ]]; then - LAST_EPOCH=$(date -d "$LAST_TIMESTAMP" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%S%z" "$LAST_TIMESTAMP" +%s 2>/dev/null || echo "0") - NOW_EPOCH=$(date +%s) - DIFF_SECONDS=$((NOW_EPOCH - LAST_EPOCH)) - - if [[ $DIFF_SECONDS -lt 3600 ]]; then - TIME_AGO="$((DIFF_SECONDS / 60))m ago" - elif [[ $DIFF_SECONDS -lt 86400 ]]; then - TIME_AGO="$((DIFF_SECONDS / 3600))h ago" - else - TIME_AGO="$((DIFF_SECONDS / 86400))d ago" - fi - else - TIME_AGO="Unknown" - fi - - # Extract counts - UPDATED_COUNT=$(echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -oP "✅ Updated \(\K[0-9]+" | tail -1) - FAILED_COUNT=$(echo "$CONTAINER_LOG" | ${pkgs.gnugrep}/bin/grep -oP "❌ Failed \(\K[0-9]+" | tail -1) - - SUMMARY_PARTS=() - [[ -n "$FAILED_COUNT" && "$FAILED_COUNT" != "0" ]] && SUMMARY_PARTS+=("$FAILED_COUNT failed") - [[ -n "$UPDATED_COUNT" && "$UPDATED_COUNT" != "0" ]] && SUMMARY_PARTS+=("$UPDATED_COUNT updated") - - SUMMARY=$(IFS=", "; echo "''${SUMMARY_PARTS[*]}") - - printf " %b \\033[2mLast update\\033[0m %b%s\\033[0m \\033[38;2;251;73;52m%s\\033[0m\n" "$STATUS_SYMBOL" "$STATUS_COLOR" "$TIME_AGO" "$SUMMARY" - - # Show updated containers - if [[ -n "$UPDATED_COUNT" && "$UPDATED_COUNT" != "0" ]]; then - UPDATED_LIST=$(echo "$CONTAINER_LOG" | ${pkgs.gawk}/bin/awk '/✅ Updated \([0-9]+\):/,/^(❌|⏭️|=|$)/ {if ($0 ~ /^ • / && $0 !~ /\(no update\)/) {gsub(/^ • /, ""); print}}' | tr '\n' ', ' | sed 's/, $//') - if [[ -n "$UPDATED_LIST" ]]; then - printf " \\033[2m Updated: %s\\033[0m\n" "$UPDATED_LIST" - fi - fi - - # Show failed containers - if [[ -n "$FAILED_COUNT" && "$FAILED_COUNT" != "0" ]]; then - FAILED_LIST=$(echo "$CONTAINER_LOG" | ${pkgs.gawk}/bin/awk '/❌ Failed \([0-9]+\):/,/^(✅|⏭️|=|$)/ {if ($0 ~ /^ • /) {gsub(/^ • /, ""); print}}' | tr '\n' ', ' | sed 's/, $//') - if [[ -n "$FAILED_LIST" ]]; then - printf " \\033[38;2;251;73;52m Failed: %s\\033[0m\n" "$FAILED_LIST" - fi - fi - - else - # Unknown or no completion message - STATUS_SYMBOL="\\033[38;2;250;189;47m⚠\\033[0m" - STATUS_TEXT="Unknown" - printf " %b \\033[2mLast update\\033[0m \\033[38;2;250;189;47m%s\\033[0m\n" "$STATUS_SYMBOL" "$STATUS_TEXT" - fi - fi - ''; - # Build borg backup status display borgStatusCode = optionalString cfg.showBorgStatus '' # Query journalctl for borg-backup.service @@ -577,10 +431,6 @@ in printf "\\033[38;2;131;165;152m━━ SnapRAID ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" ${snapraidStatusCode} ''} - ${optionalString cfg.showContainerUpdater '' - printf "\\033[38;2;131;165;152m━━ Containers ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" - ${containerUpdaterStatusCode} - ''} ${optionalString cfg.showBorgStatus '' printf "\\033[38;2;131;165;152m━━ Backup ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" ${borgStatusCode} diff --git a/scripts/container-update.sh b/scripts/container-update.sh deleted file mode 100755 index 6e7ebb8..0000000 --- a/scripts/container-update.sh +++ /dev/null @@ -1,120 +0,0 @@ -# Container update script -# Updates all podman containers to latest images - -set -euo pipefail - -# Configuration from environment (set by systemd service) -EXCLUDE_CONTAINERS="${EXCLUDE_CONTAINERS:-}" - -# Convert excluded containers to array -IFS=',' read -ra EXCLUDED <<< "$EXCLUDE_CONTAINERS" - -# Get all running containers -echo "Getting list of running containers..." -containers=$(podman ps --format "{{.Names}}") - -if [[ -z "$containers" ]]; then - echo "No running containers found" - exit 0 -fi - -# Arrays to track updates -updated_containers=() -failed_containers=() -skipped_containers=() - -# Update each container -for container in $containers; do - # Check if container is in exclude list - skip=false - for excluded in "${EXCLUDED[@]}"; do - if [[ "$container" == "$excluded" ]]; then - echo "Skipping excluded container: $container" - skipped_containers+=("$container") - skip=true - break - fi - done - - if [[ "$skip" == true ]]; then - continue - fi - - echo "Processing container: $container" - - # Get current image - image=$(podman inspect "$container" --format '{{.ImageName}}') - - if [[ -z "$image" ]]; then - echo "ERROR: Could not get image for container $container" - failed_containers+=("$container (no image)") - continue - fi - - echo " Current image: $image" - - # Get current image ID before pull - old_image_id=$(podman inspect "$container" --format '{{.Image}}') - - # Pull latest image - echo " Pulling latest image..." - if podman pull "$image" 2>&1; then - echo " Image pulled successfully" - - # Get new image ID after pull - new_image_id=$(podman inspect "$image" --format '{{.Id}}') - - # Check if image actually changed - if [[ "$old_image_id" != "$new_image_id" ]]; then - echo " New image detected, restarting container..." - - # Restart container - if podman restart "$container" 2>&1; then - echo " Container updated successfully" - updated_containers+=("$container") - else - echo " ERROR: Failed to restart container" - failed_containers+=("$container (restart failed)") - fi - else - echo " Image unchanged, skipping restart" - skipped_containers+=("$container (no update)") - fi - else - echo " ERROR: Failed to pull image" - failed_containers+=("$container (pull failed)") - fi - - echo "" -done - -# Print summary -echo "=== Update Summary ===" -if [[ ${#updated_containers[@]} -gt 0 ]]; then - echo "✅ Updated (${#updated_containers[@]}):" - for container in "${updated_containers[@]}"; do - echo " • $container" - done -fi - -if [[ ${#failed_containers[@]} -gt 0 ]]; then - echo "❌ Failed (${#failed_containers[@]}):" - for container in "${failed_containers[@]}"; do - echo " • $container" - done -fi - -if [[ ${#skipped_containers[@]} -gt 0 ]]; then - echo "⏭️ No updates (${#skipped_containers[@]}):" - for container in "${skipped_containers[@]}"; do - echo " • $container" - done -fi - -# Exit with error if any containers failed -if [[ ${#failed_containers[@]} -gt 0 ]]; then - echo "ERROR: Some containers failed to update" - exit 1 -fi - -echo "Container update completed successfully"