Lm-devices: Liste der Schulrechner mit Image-Versionen und veralteten Hosts

Wir haben ein kleines Bash-Skript erstellt, um die Geräte unserer Schule übersichtlich zu listen – inklusive Image-Versionen und einer Markierung veralteter Rechner. Ideal, um schnell zu sehen, welche Hosts ein Update benötigen.

Cool wäre es, wenn davon Ansätze an verschiedene Stellen einfließen:

  • im Linbo ggf. die Imageversion anzeigen
  • im WebGUI auch eine Spalte mit der Image-Version
  • sortierbare Tabelle unter Sync-Status
  • ggf. teile des Skripts in linbo-tools übernehmen

Pfad und Aufruf

/usr/local/sbin/lm-devices [OPTIONEN]

Beispiele:

lm-devices --hosts --show-version
lm-devices --hosts --outdated --image UbuntuV2
lm-devices --rooms --room N102

Features

  1. Geräteliste aus Sophomorix

    • Liest /etc/linuxmuster/sophomorix/default-school/devices.csv.
    • Filtert optional nach Raum (--room) oder Gerätetyp (--type).
    • Blendet versteckte Geräte aus (byod, ipad, server, switch, printer, staffcomputer etc.) oder zeigt sie mit --all an.
  2. Anzeige der Image-Versionen

    • Extrahiert den Timestamp des gewählten Images aus der .info-Datei.
    • Vergleicht mit dem letzten Linbo-Log /var/log/linuxmuster/linbo/hostname_image.status.
    • Markiert veraltete Hosts rot, aktuelle grün.
  3. Nur veraltete Hosts anzeigen

    • Mit --outdated werden nur Rechner ausgegeben, deren Image nicht aktuell ist.
  4. Flexible Image-Auswahl

    • Standardmäßig UbuntuV2, kann aber mit --image <ImageName> geändert werden.

Farben in der Ausgabe

  • Grün: aktuelles Image
  • Rot: veraltet oder keine Info vorhanden

Beispielausgabe

n102-fj-p601 | 202511032352
n102-fj-p602 | 202511010845   # rot = veraltet
n102-fj-p603 | keine info      # rot = kein Timestamp im Log

/usr/local/sbin/lm-devices

#!/bin/bash

# ==========================================
# lm-devices: Liste von Rechnern aus sophomorix/devices.csv
# Erweiterung: Image-Version anzeigen, veraltete Hosts markieren
# ==========================================

CSV="/etc/linuxmuster/sophomorix/default-school/devices.csv"
HIDDEN="byod|ipad|server|admin|switch|router|printer|staffcomputer|iponly|shelly"
LINBO_LOG="/var/log/linuxmuster/linbo"
DEFAULT_IMAGE="UbuntuV2"

MODE="hosts"
ROOM=""
TYPE=""
SHOW_HIDDEN=0
SHOW_VERSION=0
ONLY_OUTDATED=0
IMAGE="$DEFAULT_IMAGE"

# Farben
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

# ===============================
# Parameter auswerten
# ===============================
while [[ $# -gt 0 ]]; do
    case "$1" in
        --hosts|--rooms|--types|--ips) MODE="${1#--}" ;;
        --room) ROOM="$2"; shift ;;
        --type) TYPE="$2"; shift ;;
        --all|--hidden) SHOW_HIDDEN=1 ;;
        --show-version) SHOW_VERSION=1 ;;
        --outdated) ONLY_OUTDATED=1 ;;
        --image) IMAGE="$2"; shift ;;
        *) echo "Usage: $0 [--hosts|--rooms|--types|--ips] [--room ROOM] [--type TYPE] [--all|--hidden] [--image IMAGE] [--show-version] [--outdated]"; exit 1 ;;
    esac
    shift
done

# ===============================
# Image-Timestamp aus .info nur prüfen, wenn gewünscht
# ===============================
if [[ $SHOW_VERSION -eq 1 || $ONLY_OUTDATED -eq 1 ]]; then
    IMAGE_FOLDER=$(basename "$IMAGE" .qcow2)
    IMAGE_FILE="$IMAGE_FOLDER.qcow2"
    IMAGE_INFO="/srv/linbo/images/$IMAGE_FOLDER/$IMAGE_FOLDER.qcow2.info"

    if [[ -f "$IMAGE_INFO" ]]; then
        # Timestamp aus info-Datei extrahieren
        CURRENT_IMAGE_TIMESTAMP=$(grep -oP 'timestamp="([0-9]+)"' "$IMAGE_INFO" | head -n1 | sed 's/timestamp="//;s/"//')

        echo "Die aktuelle Imageversion '${IMAGE_FOLDER}' ist: $CURRENT_IMAGE_TIMESTAMP"

        if [[ -z "$CURRENT_IMAGE_TIMESTAMP" ]]; then
            echo "Kein Timestamp für Image $IMAGE_FILE in $IMAGE_INFO gefunden!"
            exit 1
        fi
    else
        echo "Image info file für $IMAGE_FOLDER nicht gefunden!"
        exit 1
    fi
fi

# ===============================
# Devices filtern
# ===============================
if [[ $SHOW_HIDDEN -eq 0 ]]; then
    FILTER="(^(#|$))|${HIDDEN}"
else
    FILTER="^(#|$)"
fi

DEVICES=$(grep -viE "$FILTER" "$CSV" \
    | awk -F';' -v room="$ROOM" -v type="$TYPE" '
        !/^#/ &amp;&amp; NF {
            if(room!="" &amp;&amp; $1!=room) next
            if(type!="" &amp;&amp; $10!=type) next
            print $2
        }')

# ===============================
# Ausgabe
# ===============================
for HOST in $DEVICES; do
    OUT_STR="$HOST"

    if [[ $SHOW_VERSION -eq 1 || $ONLY_OUTDATED -eq 1 ]]; then
        LOG_FILE="$LINBO_LOG/${HOST}_image.status"

        if [[ -f "$LOG_FILE" ]]; then
            # Letzte Zeile mit dem Image-Namen
            LINE=$(grep "$IMAGE_FILE" "$LOG_FILE" | tail -n1)
            if [[ -n "$LINE" ]]; then
                IMAGE_TS_IN_LOG=$(echo "$LINE" | awk -F'"' '{print $2}') # Version im Log
            else
                IMAGE_TS_IN_LOG=""
            fi
        else
            IMAGE_TS_IN_LOG=""
        fi

        # Veraltet prüfen &amp; Farbe setzen
        if [[ "$IMAGE_TS_IN_LOG" != "$CURRENT_IMAGE_TIMESTAMP" ]]; then
            OUT_STR="$HOST | ${RED}${IMAGE_TS_IN_LOG:-"keine info"}${NC}"  # rot für veraltet
        else
            OUT_STR="$HOST | ${GREEN}${IMAGE_TS_IN_LOG}${NC}"  # grün für aktuell
        fi

        # ONLY_OUTDATED filtern
        if [[ $ONLY_OUTDATED -eq 1 &amp;&amp; "$IMAGE_TS_IN_LOG" == "$CURRENT_IMAGE_TIMESTAMP" ]]; then
            continue
        fi
    fi

    echo -e "$OUT_STR"
done | sort -u
1 „Gefällt mir“

Hallo hightower!
Ich habe es mal ausprobiert … läuft hier leider nicht.
Meldung:

awk: cmd. line:2:         !/^#/ &amp;&amp; NF {
awk: cmd. line:2:               ^ syntax error
awk: cmd. line:2:         !/^#/ &amp;&amp; NF {
awk: cmd. line:2:                    ^ syntax error
awk: cmd. line:3:             if(room!="" &amp;&amp; $1!=room) next
awk: cmd. line:3:                         ^ syntax error
awk: cmd. line:3:             if(room!="" &amp;&amp; $1!=room) next
awk: cmd. line:3:                              ^ syntax error
awk: cmd. line:3:             if(room!="" &amp;&amp; $1!=room) next
awk: cmd. line:3:                                            ^ syntax error
awk: cmd. line:4:             if(type!="" &amp;&amp; $10!=type) next
awk: cmd. line:4:                         ^ syntax error
awk: cmd. line:4:             if(type!="" &amp;&amp; $10!=type) next
awk: cmd. line:4:                              ^ syntax error
awk: cmd. line:4:             if(type!="" &amp;&amp; $10!=type) next
awk: cmd. line:4:                                             ^ syntax error

Woran kann das liegen?

Viele Grüße,
Michael

Abend,
Du musst alle &amp; durch ein & ersetzen, copy&pasta von Quellcode aus Webseiten geht gerne in die Hosen, hier wurde das & beim Einfügen durch die Entitaet &amp; ersetzt/umkodiert beim Kopieren nimmst Du den Scheiss dann mit in den Quellcode und der Parser stolpert zu recht drueber.

Gruss Harry