diff --git a/poste/alpi-fiche.sh b/poste/alpi-fiche.sh index 19082bc..c457ccc 100755 --- a/poste/alpi-fiche.sh +++ b/poste/alpi-fiche.sh @@ -1,7 +1,8 @@ #!/bin/bash # Relève la fiche d'une machine, et l'envoie au serveur de l'install party. # -# À récupérer depuis le dépôt du wiki, comme les autres scripts d'Alpinux : +# Ce script vit dans le dépôt du wiki, à côté d'install.sh : il est lu et +# versionné comme lui, et c'est de là qu'il faut le prendre. # # wget https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-wiki/raw/branch/main/code/linux/linux-mint/alpi-fiche.sh # chmod +x alpi-fiche.sh @@ -18,25 +19,22 @@ # mémoire et un disque mécanique qui commence à réallouer des secteurs répond # à la question avant de l'avoir posée. # -# Ce qui est envoyé, et rien d'autre : le modèle et la marque, les quatre -# derniers caractères du numéro de série, la date du BIOS, le processeur, la -# mémoire et le détail de ses connecteurs, les disques avec leur santé SMART, -# l'occupation des systèmes de fichiers, le système installé, l'architecture, -# l'adresse matérielle de l'interface réseau et le nom de la machine. +# Ce qui est envoyé : le modèle, le processeur, la mémoire, les disques et +# leur santé, le système installé. # -# Ni nom d'utilisateur, ni fichiers, ni historique, ni adresse IP publique. +# Deux de ces champs touchent à la personne, et il faut le dire plutôt que de +# prétendre le contraire — la première version de cet en-tête annonçait « rien +# qui touche à la personne », ce qui était faux : # -# Deux réserves à connaître avant de s'en servir, parce qu'elles concernent -# des gens et pas des machines : +# · le NOM DE LA MACHINE, choisi pendant l'installation, contient très +# souvent un prénom ; +# · l'ADRESSE MATÉRIELLE de la carte réseau identifie durablement l'appareil. # -# - le **nom de la machine** est celui choisi pendant l'installation, et il -# contient souvent un prénom (« portable-jean ») ; -# - l'**adresse matérielle** identifie durablement la carte réseau ; elle -# sert ici à rapprocher la fiche du bail DHCP, rien de plus. -# -# Le relevé part en clair sur le réseau local de la salle, vers le serveur de -# l'association, et n'en sort pas. Prévenez-en la personne dont vous installez -# la machine : c'est la sienne. +# Les deux servent : le nom pour s'y retrouver, l'adresse pour rapprocher la +# fiche du bail DHCP. Mais ils appartiennent à la personne dont on installe +# l'ordinateur — il faut le lui dire. Ne sont en revanche jamais envoyés : son +# nom d'utilisateur, ses fichiers, son historique, ni rien de ce qu'elle a +# installé. Le numéro de série est tronqué à quatre caractères. # # alpi-fiche relève et envoie # alpi-fiche --montrer relève et affiche, sans rien envoyer @@ -49,6 +47,11 @@ set -u +# smartctl et dmidecode vivent dans /usr/sbin, que le PATH d'un shell ordinaire +# ne contient pas toujours — un « command -v » y échouait alors que le binaire +# était là. +PATH="$PATH:/usr/sbin:/sbin" + SERVEUR="${ALPI_SERVEUR:-http://alpicache.lan}" MONTRER=0 CHECK=0 @@ -63,6 +66,41 @@ else V=""; O=""; R=""; B=""; D=""; Z="" fi +# Ce dont le relevé a besoin, et qu'il installe lui-même plutôt que de rendre +# un verdict à trous. +# +# « état des disques inconnu » n'aide personne : c'est précisément la réponse +# qu'on était venu chercher. Les deux paquets pèsent moins de deux mégaoctets, +# ils sont dans le cache, et l'installation prend deux secondes sur le réseau +# de l'install party. On ne le fait qu'en root, qu'avec apt, et sans rien +# demander d'autre. +completer_outils() { + [ "$(id -u)" = "0" ] || return 0 + command -v apt-get >/dev/null 2>&1 || return 0 + + local manquants="" + command -v smartctl >/dev/null 2>&1 || manquants="$manquants smartmontools" + command -v dmidecode >/dev/null 2>&1 || manquants="$manquants dmidecode" + [ -z "$manquants" ] && return 0 + + echo "==> Installation de ce qui manque au relevé :$manquants" + # Par le cache s'il répond, directement sinon. « -qq » pour ne pas noyer + # l'écran : ce n'est pas l'objet de la manœuvre. + local proxy="" + if command -v wget >/dev/null 2>&1 \ + && wget -q --spider --timeout=3 "$SERVEUR/" 2>/dev/null; then + proxy="-o Acquire::http::Proxy=http://apt-proxy:3142" + fi + DEBIAN_FRONTEND=noninteractive apt-get $proxy -qq -y install $manquants \ + >/dev/null 2>&1 \ + || echo " (échec — le relevé se fera sans)" + # Ce qui vient d'arriver est dans /usr/sbin, que le PATH d'un shell + # ordinaire ne contient pas toujours. + PATH="$PATH:/usr/sbin:/sbin" +} + +completer_outils + lire_dmi() { cat "/sys/class/dmi/id/$1" 2>/dev/null | tr -d '\n' | sed 's/^ *//; s/ *$//' } @@ -106,18 +144,20 @@ ARCHITECTURE="$(uname -m)" # comparer — un disque qui allait bien le matin et qui se plaint le soir, cela # se voit. # -# Une session live monte sa racine en overlay au-dessus d'un squashfs, et -# démarre avec « boot=casper » sur la ligne du noyau. Ces deux signes-là ne -# mentent pas. +# Le signe qui ne trompe pas est la racine : une session live la monte en +# overlay au-dessus d'un squashfs, ce qu'aucun système installé ne fait. S'y +# ajoute « boot=casper » ou « boot=live » sur la ligne de commande du noyau. # -# L'existence d'un /cdrom, en revanche, n'est pas un signe : l'installateur de -# Mint en laisse un derrière lui, vide, sur la machine installée. S'y fier -# faisait déclarer « session live » des machines parfaitement installées — et -# comme le chronométrage se calcule entre les deux relevés, la mesure partait -# avec. Constat de la session alpicache, sur une machine réelle. +# L'existence de /cdrom ou de /rofs, elle, ne prouve rien : l'installateur de +# Mint laisse un /cdrom vide derrière lui, et la première version de ce script +# a donc déclaré « session live » une machine parfaitement installée. On ne les +# retient que s'ils sont réellement montés. MOMENT="post-installation" if findmnt -n -o FSTYPE / 2>/dev/null | grep -qE '^(overlay|aufs|squashfs)$' \ - || grep -qE '(^| )(boot=casper|boot=live)( |$)' /proc/cmdline 2>/dev/null; then + || grep -qE '(^| )boot=(casper|live)( |$)' /proc/cmdline 2>/dev/null \ + || mountpoint -q /rofs 2>/dev/null \ + || { mountpoint -q /cdrom 2>/dev/null \ + && findmnt -n -o FSTYPE /cdrom 2>/dev/null | grep -qE '^(iso9660|squashfs)$'; }; then MOMENT="live" fi @@ -296,9 +336,11 @@ echo # d'un idéal — une machine de dix ans avec 4 Go et un disque sain fait très # bien l'affaire, et c'est souvent celle qu'on nous apporte. -# Depuis une session live, le verdict est tout l'intérêt de l'exercice : on -# le rend sans qu'on ait à le demander. -[ "$MOMENT" = "live" ] && CHECK=1 +# Le verdict sort toujours, live ou non. C'est l'information qu'on est venu +# chercher : la première version ne le rendait qu'en session live, et le +# relevé d'après installation défilait sans rien dire de l'état des disques — +# précisément ce dont on voulait parler au propriétaire. +[ "$MONTRER" = 1 ] || CHECK=1 if [ "$CHECK" = 1 ]; then GRAVITE=0 # 0 rien à signaler · 1 à surveiller · 2 ne pas installer @@ -339,13 +381,23 @@ if [ "$CHECK" = 1 ]; then done heures="$(printf '%s' "$sortie" | awk '/Power_On_Hours/{print $10; exit}')" rotatif="$(cat "$chemin/queue/rotational" 2>/dev/null)" - case "$heures" in - ''|*[!0-9]*) ;; - *) if [ "$rotatif" = "1" ] && [ "$heures" -gt 43800 ]; then - note 1 " ${O}!${Z} /dev/$nom : disque mécanique de $(( heures / 8760 )) ans. - ${D}Un SSD changerait tout sur cette machine.${Z}" - fi ;; - esac + # Un disque mécanique se signale toujours, et pas seulement quand il + # est vieux. C'est le premier frein d'une machine par ailleurs + # correcte : remplacer un plateau par un SSD fait plus pour elle que + # n'importe quel réglage, et c'est le genre de conseil qu'on donne + # pendant qu'on a la machine ouverte devant soi. + if [ "$rotatif" = "1" ]; then + age="" + case "$heures" in + ''|*[!0-9]*) ;; + *) annees=$(( heures / 8760 )) + [ "$annees" -gt 0 ] && age=" de $annees an$([ "$annees" -gt 1 ] && echo s)" + [ "$annees" = "0" ] && age=" ($heures h de marche)" ;; + esac + note 1 " ${O}!${Z} /dev/$nom est un ${B}disque mécanique${Z}$age. + ${D}Le remplacer par un SSD ferait plus pour cette machine que + tout le reste réuni — démarrage, ouverture des programmes, réactivité.${Z}" + fi if [ "$taille" -lt 32000000000 ]; then note 1 " ${O}!${Z} /dev/$nom ne fait que $(( taille / 1000000000 )) Go — c'est juste." fi @@ -373,7 +425,22 @@ if [ "$CHECK" = 1 ]; then esac echo [ -n "$REMARQUES" ] && printf "%s\n" "$REMARQUES" - [ "$GRAVITE" = 2 ] && printf " %sEn parler au propriétaire avant de toucher à quoi que ce soit.%s\n\n" "$D" "$Z" + + # Une pause, sans quoi tout cela défile et personne ne le lit. Sa durée + # suit la gravité, et l'on n'attend jamais indéfiniment : le script tourne + # aussi sans personne devant l'écran, appelé par install.sh. + if [ -t 0 ]; then + case "$GRAVITE" in + 2) printf " %sEn parler au propriétaire AVANT de toucher à quoi que ce soit.%s\n" "$D" "$Z" + printf " %sEntrée pour continuer malgré tout%s " "$B" "$Z" + read -r -t "${ALPI_PAUSE_ALERTE:-120}" _ || echo ;; + 1) printf " %sEntrée pour continuer (reprise automatique dans %ss)%s " \ + "$D" "${ALPI_PAUSE:-20}" "$Z" + read -r -t "${ALPI_PAUSE:-20}" _ || echo ;; + *) sleep "${ALPI_PAUSE_OK:-3}" ;; + esac + echo + fi fi if command -v curl >/dev/null 2>&1; then