From 6f2b9cc0f006b3707791c394948ee0e449c34144 Mon Sep 17 00:00:00 2001 From: Alpinux Date: Thu, 24 Sep 2026 22:15:33 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Verser=20le=20relev=C3=A9=20de=20fiche=20ma?= =?UTF-8?q?t=C3=A9rielle=20dans=20le=20d=C3=A9p=C3=B4t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La demande initiale faisait télécharger un script depuis alpicache et l'exécuter en root sur la machine de chaque participant. Le relevé est désormais versionné ici, relu comme le reste, et appelé localement : rien n'est tiré du réseau, rien n'est exécuté sans avoir été publié. Le script vient de la session alpicache, éprouvé sur place. Il relève le modèle, le processeur, la mémoire et le détail de ses connecteurs, les disques et leur état SMART, puis envoie la fiche au serveur de la salle. Depuis une session live, il rend en plus un verdict — bon, avec réserves, ou ne pas installer — que le bénévole peut opposer à un disque qui faiblit pendant que la machine est encore là. install.sh l'appelle en tête de fichier, dans sa passe root, et seulement s'il le trouve à côté de lui : une machine qui rejoue le script chez son propriétaire n'envoie rien à personne. L'en-tête du relevé disait « rien qui touche à la personne ». C'était inexact : la fiche emporte le nom de la machine — souvent un prénom — et l'adresse matérielle de la carte réseau. Les deux sont maintenant nommés, dans le script comme dans le guide, avec la consigne qui va avec : le dire à la personne dont on installe l'ordinateur. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01BE4rvHVETRoWnYNDTGssdo --- code/linux/linux-mint/alpi-fiche.sh | 389 +++++++++++++++++++++++ code/linux/linux-mint/install.sh | 22 ++ docs/guides/linux-mint-depuis-windows.md | 26 ++ 3 files changed, 437 insertions(+) create mode 100755 code/linux/linux-mint/alpi-fiche.sh diff --git a/code/linux/linux-mint/alpi-fiche.sh b/code/linux/linux-mint/alpi-fiche.sh new file mode 100755 index 0000000..f9d0b45 --- /dev/null +++ b/code/linux/linux-mint/alpi-fiche.sh @@ -0,0 +1,389 @@ +#!/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 : +# +# wget https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-wiki/raw/branch/main/code/linux/linux-mint/alpi-fiche.sh +# chmod +x alpi-fiche.sh +# sudo ./alpi-fiche.sh --check # depuis la session live, avant d'installer +# sudo ./alpi-fiche.sh # après l'installation +# +# Sur le réseau de l'install party, plus court : +# +# wget http://10.0.0.1/alpi-fiche.sh && chmod +x alpi-fiche.sh && sudo ./alpi-fiche.sh --check +# +# Pourquoi la garder sur le serveur plutôt que sur le poste : trois semaines +# plus tard, quand quelqu'un rappelle parce que « ça rame », on n'a plus la +# machine sous la main. Savoir qu'elle a huit ans, quatre gigaoctets de +# 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. +# +# Ni nom d'utilisateur, ni fichiers, ni historique, ni adresse IP publique. +# +# 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** 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. +# +# alpi-fiche relève et envoie +# alpi-fiche --montrer relève et affiche, sans rien envoyer +# alpi-fiche --check relève, envoie, et rend un verdict +# +# Le mode « --check » est fait pour tourner **depuis la clé USB, avant +# d'installer** : c'est le seul moment où l'on peut encore renoncer. Un disque +# qui se déclare défaillant, on ne passe pas une heure à installer dessus — on +# le dit à son propriétaire et on cherche une autre solution. + +set -u + +SERVEUR="${ALPI_SERVEUR:-http://alpicache.lan}" +MONTRER=0 +CHECK=0 +case "${1:-}" in + --montrer) MONTRER=1 ;; + --check) CHECK=1 ;; +esac + +if [ -t 1 ]; then + V=$'\e[32m'; O=$'\e[33m'; R=$'\e[31m'; B=$'\e[1m'; D=$'\e[2m'; Z=$'\e[0m' +else + V=""; O=""; R=""; B=""; D=""; Z="" +fi + +lire_dmi() { + cat "/sys/class/dmi/id/$1" 2>/dev/null | tr -d '\n' | sed 's/^ *//; s/ *$//' +} + +echapper() { + # De quoi écrire du JSON sans rien installer : guillemets, antislashs et + # sauts de ligne, et c'est tout ce qui peut nous arriver ici. + printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g' | tr -d '\n\r' +} + +champ() { printf '"%s":"%s"' "$1" "$(echapper "${2:-}")"; } + +# --- La machine ------------------------------------------------------------ + +MODELE="$(lire_dmi product_name)" +MARQUE="$(lire_dmi sys_vendor)" +SERIE="$(lire_dmi product_serial)" +# Le numéro de série identifie un objet, pas une personne, mais il n'a rien à +# faire dans un fichier qu'on partage : on n'en garde que les quatre derniers +# caractères, assez pour distinguer deux machines du même modèle. +SERIE="${SERIE: -4}" +BIOS="$(lire_dmi bios_date)" + +PROCESSEUR="$(awk -F': ' '/^model name/{print $2; exit}' /proc/cpuinfo)" +COEURS="$(nproc 2>/dev/null || echo '?')" +MEMOIRE_KO="$(awk '/^MemTotal/{print $2}' /proc/meminfo)" + +SYSTEME="" +if [ -r /etc/os-release ]; then + SYSTEME="$(. /etc/os-release; echo "${PRETTY_NAME:-$NAME $VERSION}")" +fi +NOYAU="$(uname -r)" +ARCHITECTURE="$(uname -m)" + +# Sommes-nous sur la clé USB, ou sur le système installé ? +# +# La distinction n'est pas cosmétique : les deux relevés répondent à deux +# questions différentes. Celui de la session live dit « peut-on installer sur +# cette machine ? » et se fait avant d'effacer quoi que ce soit. Celui d'après +# dit « qu'avons-nous installé, et sur quoi ». Les garder séparés permet de +# 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 garde +# un /cdrom ou un /rofs. Aucun de ces signes n'existe sur un système installé. +MOMENT="post-installation" +if [ -d /rofs ] || [ -d /cdrom ] \ + || findmnt -n -o FSTYPE / 2>/dev/null | grep -qE '^(overlay|aufs|squashfs)$' \ + || grep -qE '(^| )(boot=casper|boot=live)( |$)' /proc/cmdline 2>/dev/null; then + MOMENT="live" +fi + +# --- La mémoire, barrette par barrette ------------------------------------ +# +# La question qu'on pose vraiment devant une machine lente : peut-on en +# ajouter ? Elle demande trois réponses — combien de connecteurs, combien +# d'occupés, et de quel type. Un slot libre en DDR3 ne se remplit pas avec ce +# qu'on a dans le tiroir. +# +# dmidecode lit cela dans la table du BIOS. Il est présent par défaut sur +# Debian, Ubuntu et Mint ; s'il manque, on ne prétend rien plutôt que de +# deviner. + +BARRETTES="[" +SLOTS_TOTAL=0 +SLOTS_PRIS=0 +TYPE_MEMOIRE="" +VITESSE_MEMOIRE="" +if command -v dmidecode >/dev/null 2>&1 && [ "$(id -u)" = "0" ]; then + premier=1 + # Chaque bloc « Memory Device » décrit un connecteur, occupé ou non. + while IFS= read -r bloc; do + emplacement="$(printf '%s' "$bloc" | sed -n 's/.*|Locator:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + taille="$(printf '%s' "$bloc" | sed -n 's/.*|Size:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + type_="$(printf '%s' "$bloc" | sed -n 's/.*|Type:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + vitesse="$(printf '%s' "$bloc" | sed -n 's/.*|Speed:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + forme="$(printf '%s' "$bloc" | sed -n 's/.*|Form Factor:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + reference="$(printf '%s' "$bloc" | sed -n 's/.*|Part Number:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + # La vitesse configurée est celle à laquelle la barrette travaille + # vraiment ; « Speed » n'est que ce dont elle serait capable. L'écart + # entre les deux explique bien des machines qui « rament » sans raison + # apparente : une DDR4-3200 bridée à 2133 par la carte mère, ou deux + # barrettes dépareillées qui s'alignent sur la plus lente. + vitesse_reelle="$(printf '%s' "$bloc" | sed -n 's/.*|Configured Memory Speed:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + fabricant="$(printf '%s' "$bloc" | sed -n 's/.*|Manufacturer:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + rang="$(printf '%s' "$bloc" | sed -n 's/.*|Rank:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + tension="$(printf '%s' "$bloc" | sed -n 's/.*|Configured Voltage:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + largeur="$(printf '%s' "$bloc" | sed -n 's/.*|Data Width:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + detail="$(printf '%s' "$bloc" | sed -n 's/.*|Type Detail:\([^|]*\).*/\1/p' | sed 's/^ *//; s/ *$//')" + [ -z "$emplacement" ] && continue + + SLOTS_TOTAL=$(( SLOTS_TOTAL + 1 )) + case "$taille" in + *"No Module"*|""|"Unknown") taille="" ;; + *) SLOTS_PRIS=$(( SLOTS_PRIS + 1 )) + [ -z "$TYPE_MEMOIRE" ] && [ "$type_" != "Unknown" ] && TYPE_MEMOIRE="$type_" + # Deux barrettes de vitesses différentes s'alignent sur la plus + # lente : c'est celle-là qu'il faut retenir pour la machine. + if [ -n "$vitesse_reelle" ] && [ "$vitesse_reelle" != "Unknown" ]; then + nombre="${vitesse_reelle%% *}" + case "$nombre" in + ''|*[!0-9]*) ;; + *) if [ -z "$VITESSE_MEMOIRE" ] || [ "$nombre" -lt "$VITESSE_MEMOIRE" ]; then + VITESSE_MEMOIRE="$nombre" + fi ;; + esac + fi ;; + esac + + [ "$premier" = 0 ] && BARRETTES="$BARRETTES," + premier=0 + BARRETTES="$BARRETTES{$(champ emplacement "$emplacement"),$(champ taille "$taille"),\ +$(champ type "$type_"),$(champ vitesse "$vitesse"),$(champ vitesse_reelle "$vitesse_reelle"),\ +$(champ forme "$forme"),$(champ reference "$reference"),$(champ fabricant "$fabricant"),\ +$(champ rang "$rang"),$(champ tension "$tension"),$(champ largeur "$largeur"),\ +$(champ detail "$detail")}" + done < <(dmidecode -t memory 2>/dev/null \ + | awk '/^Memory Device$/{bloc=""; dedans=1; next} + /^$/{if (dedans && bloc != "") print bloc; dedans=0; bloc=""} + dedans {gsub(/^[ \t]+/, ""); bloc = bloc "|" $0} + END{if (dedans && bloc != "") print bloc}') +fi +BARRETTES="$BARRETTES]" + +# --- Les disques ----------------------------------------------------------- +# +# lsblk donne la taille et le type ; le drapeau « rotational » du noyau +# distingue un disque mécanique d'un SSD sans rien installer. C'est la +# distinction qui compte : une machine lente avec un disque mécanique de dix +# ans ne s'arrangera pas avec un système plus léger. + +DISQUES="[" +premier=1 +for chemin in /sys/block/*; do + nom="$(basename "$chemin")" + case "$nom" in loop*|ram*|sr*|zram*|dm-*) continue ;; esac + [ -r "$chemin/size" ] || continue + taille=$(( $(cat "$chemin/size") * 512 )) + [ "$taille" -lt 1000000000 ] && continue # moins d'un Go : pas un disque + rotatif="$(cat "$chemin/queue/rotational" 2>/dev/null || echo '?')" + modele="$(cat "$chemin/device/model" 2>/dev/null | sed 's/ *$//')" + + # L'état SMART, s'il est lisible. Sans smartctl on ne prétend rien. + sante="" + reallocations="" + heures="" + if command -v smartctl >/dev/null 2>&1; then + sortie="$(smartctl -H -A "/dev/$nom" 2>/dev/null)" + sante="$(printf '%s' "$sortie" | grep -iE 'overall-health|SMART Health' \ + | sed 's/.*: *//' | head -1)" + reallocations="$(printf '%s' "$sortie" \ + | awk '/Reallocated_Sector_Ct|Reallocated_Event/{print $10; exit}')" + heures="$(printf '%s' "$sortie" | awk '/Power_On_Hours/{print $10; exit}')" + fi + + [ "$premier" = 0 ] && DISQUES="$DISQUES," + premier=0 + DISQUES="$DISQUES{$(champ nom "$nom"),$(champ modele "$modele"),\ +\"octets\":$taille,$(champ type "$([ "$rotatif" = 1 ] && echo mécanique || echo SSD)"),\ +$(champ sante "$sante"),$(champ reallocations "$reallocations"),$(champ heures "$heures")}" +done +DISQUES="$DISQUES]" + +# L'occupation, telle qu'elle est maintenant. +OCCUPATION="[" +premier=1 +while read -r point taille utilise dispo pourcent; do + [ "$premier" = 0 ] && OCCUPATION="$OCCUPATION," + premier=0 + OCCUPATION="$OCCUPATION{$(champ point "$point"),\"taille\":$taille,\ +\"utilise\":$utilise,$(champ pourcent "$pourcent")}" +done < <(df -B1 --output=target,size,used,avail,pcent 2>/dev/null \ + | awk 'NR>1 && $2+0 > 1000000000 {print $1, $2, $3, $4, $5}') +OCCUPATION="$OCCUPATION]" + +# --- Le rapport ------------------------------------------------------------ + +# L'adresse matérielle de l'interface par laquelle on sort — celle que le +# serveur a vue en donnant le bail, donc celle qui permettra de rapprocher +# cette fiche de la machine servie. « ip -o link » a failli nous donner +# l'adresse de diffusion, qui est la même pour tout le monde. +INTERFACE="$(ip -o -4 route show default 2>/dev/null | awk '{print $5; exit}')" +[ -z "$INTERFACE" ] && INTERFACE="$(ls /sys/class/net 2>/dev/null \ + | grep -v '^lo$' | head -1)" +MAC="$(cat "/sys/class/net/$INTERFACE/address" 2>/dev/null)" + +RAPPORT="{$(champ machine "$(hostname)"),$(champ mac "$MAC"),\ +$(champ marque "$MARQUE"),$(champ modele "$MODELE"),$(champ serie "$SERIE"),\ +$(champ bios "$BIOS"),$(champ processeur "$PROCESSEUR"),\"coeurs\":${COEURS:-0},\ +\"memoire_ko\":${MEMOIRE_KO:-0},$(champ systeme "$SYSTEME"),$(champ noyau "$NOYAU"),\ +$(champ architecture "$ARCHITECTURE"),$(champ moment "$MOMENT"),\ +$(champ type_memoire "$TYPE_MEMOIRE"),\ +$(champ vitesse_memoire "$VITESSE_MEMOIRE"),\ +\"slots_total\":$SLOTS_TOTAL,\"slots_pris\":$SLOTS_PRIS,\"barrettes\":$BARRETTES,\ +\"disques\":$DISQUES,\"occupation\":$OCCUPATION}" + +if [ "$MONTRER" = 1 ]; then + if command -v python3 >/dev/null 2>&1; then + printf '%s' "$RAPPORT" | python3 -m json.tool 2>/dev/null || printf '%s\n' "$RAPPORT" + else + printf '%s\n' "$RAPPORT" + fi + exit 0 +fi + +[ "$CHECK" = 1 ] && printf " %sLa fiche est envoyée à alpicache…%s\n\n" "$D" "$Z" +echo "Relevé : $([ "$MOMENT" = live ] && echo "session live, avant installation" \ + || echo "système installé")" +echo "Machine : $MARQUE $MODELE" +echo "Processeur : $PROCESSEUR ($COEURS cœurs)" +if [ "$SLOTS_TOTAL" -gt 0 ]; then + echo "Mémoire : $(( MEMOIRE_KO / 1024 )) Mo ${TYPE_MEMOIRE:+$TYPE_MEMOIRE }\ +${VITESSE_MEMOIRE:+à $VITESSE_MEMOIRE MT/s }· \ +$SLOTS_PRIS connecteur(s) occupé(s) sur $SLOTS_TOTAL" +else + echo "Mémoire : $(( MEMOIRE_KO / 1024 )) Mo" +fi +echo "Système : $SYSTEME" +echo + +# --- Le verdict ------------------------------------------------------------ +# +# Trois réponses possibles, et une seule question : peut-on installer sur cette +# machine ? Les seuils viennent de ce qu'on rencontre en install party, pas +# 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 + +if [ "$CHECK" = 1 ]; then + GRAVITE=0 # 0 rien à signaler · 1 à surveiller · 2 ne pas installer + REMARQUES="" + + note() { + [ "$1" -gt "$GRAVITE" ] && GRAVITE="$1" + REMARQUES="$REMARQUES$2"$'\n' + } + + # Les disques. C'est pour eux qu'on fait ce contrôle. + for chemin in /sys/block/*; do + nom="$(basename "$chemin")" + case "$nom" in loop*|ram*|sr*|zram*|dm-*) continue ;; esac + [ -r "$chemin/size" ] || continue + taille=$(( $(cat "$chemin/size") * 512 )) + [ "$taille" -lt 1000000000 ] && continue + + if ! command -v smartctl >/dev/null 2>&1; then + note 1 " ${O}?${Z} état des disques inconnu — smartmontools n'est pas installé. + ${D}sudo apt install -y smartmontools${Z} ${D}(il passera par le cache)${Z}" + break + fi + + sortie="$(smartctl -H -A "/dev/$nom" 2>/dev/null)" + if printf '%s' "$sortie" | grep -qiE 'overall-health.*(FAILED|FAILING)'; then + note 2 " ${R}✗${Z} ${B}/dev/$nom se déclare défaillant${Z} — ne pas installer dessus." + fi + for attribut in Reallocated_Sector_Ct Current_Pending_Sector Offline_Uncorrectable; do + valeur="$(printf '%s' "$sortie" | awk -v a="$attribut" '$2 == a {print $10; exit}')" + case "$valeur" in ''|*[!0-9]*) continue ;; esac + [ "$valeur" = "0" ] && continue + if [ "$valeur" -ge 50 ]; then + note 2 " ${R}✗${Z} /dev/$nom : $valeur $attribut — disque à remplacer." + else + note 1 " ${O}!${Z} /dev/$nom : $valeur $attribut — à surveiller." + fi + 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 + if [ "$taille" -lt 32000000000 ]; then + note 1 " ${O}!${Z} /dev/$nom ne fait que $(( taille / 1000000000 )) Go — c'est juste." + fi + done + + # La mémoire, le processeur. + MEMOIRE_MO=$(( MEMOIRE_KO / 1024 )) + if [ "$MEMOIRE_MO" -lt 2048 ]; then + note 2 " ${R}✗${Z} ${B}${MEMOIRE_MO} Mo de mémoire${Z} — trop peu pour Mint. + ${D}Envisager une version légère, ou ajouter de la mémoire.${Z}" + elif [ "$MEMOIRE_MO" -lt 4096 ]; then + libres=$(( SLOTS_TOTAL - SLOTS_PRIS )) + note 1 " ${O}!${Z} ${MEMOIRE_MO} Mo de mémoire — Mint tournera, mais sans aisance.$( + [ "$libres" -gt 0 ] && printf '\n %s' "${D}$libres connecteur(s) ${TYPE_MEMOIRE} libre(s) : la machine est extensible.${Z}")" + fi + if [ "$ARCHITECTURE" != "x86_64" ] && [ "$ARCHITECTURE" != "aarch64" ]; then + note 2 " ${R}✗${Z} processeur ${ARCHITECTURE} — les versions 64 bits ne s'installeront pas." + fi + + echo + case "$GRAVITE" in + 0) printf " %s%s BON POUR L'INSTALLATION %s\n" "$B$V" "✓" "$Z" ;; + 1) printf " %s%s INSTALLATION POSSIBLE, AVEC DES RÉSERVES %s\n" "$B$O" "!" "$Z" ;; + 2) printf " %s%s NE PAS INSTALLER EN L'ÉTAT %s\n" "$B$R" "✗" "$Z" ;; + 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" +fi + +if command -v curl >/dev/null 2>&1; then + reponse="$(printf '%s' "$RAPPORT" | curl -s --max-time 15 \ + -H 'Content-Type: application/json' --data-binary @- "$SERVEUR/fiche")" +elif command -v wget >/dev/null 2>&1; then + reponse="$(printf '%s' "$RAPPORT" | wget -qO- --timeout=15 \ + --header='Content-Type: application/json' --post-file=- "$SERVEUR/fiche")" +else + echo "Ni curl ni wget : la fiche n'a pas pu être envoyée." >&2 + exit 1 +fi + +if [ -n "$reponse" ]; then + echo "$reponse" +else + echo "Le serveur n'a pas répondu — la fiche n'est pas enregistrée." >&2 + exit 1 +fi diff --git a/code/linux/linux-mint/install.sh b/code/linux/linux-mint/install.sh index bb33d49..7610e4d 100644 --- a/code/linux/linux-mint/install.sh +++ b/code/linux/linux-mint/install.sh @@ -1,4 +1,26 @@ #!/bin/bash + +################################################## +# Fiche matérielle pour le serveur de l'install party +# +# Placée au début, et non à la fin : si un disque faiblit, autant le savoir +# avant d'avoir passé une heure à installer dessus — c'est le moment où l'on +# peut encore en parler à son propriétaire. Et si l'installation s'arrête en +# route, on a tout de même la fiche. +# +# Le relevé est le script voisin du dépôt, lu et versionné comme celui-ci : +# rien n'est téléchargé ni exécuté depuis le réseau. S'il n'est pas là, on +# passe — la machine d'un particulier qui rejoue ce script chez elle ne doit +# rien avoir à faire de tout ceci. +# +# C'est la seconde passe, celle que « sudo » relance, qui l'exécute : +# dmidecode et smartctl demandent les droits d'administration. +################################################## + +if [ "$(id -u)" = "0" ] && [ -x "$(dirname "$0")/alpi-fiche.sh" ]; then + "$(dirname "$0")/alpi-fiche.sh" || true +fi + # Script de post-installation pour Linux Mint 22.3 # testé le 25/03/2026 diff --git a/docs/guides/linux-mint-depuis-windows.md b/docs/guides/linux-mint-depuis-windows.md index e98ac5f..17b1aba 100644 --- a/docs/guides/linux-mint-depuis-windows.md +++ b/docs/guides/linux-mint-depuis-windows.md @@ -368,6 +368,32 @@ les vérifications qui le nécessitent, puis passe en revue : Il finit par deux listes : *à régler avant d'installer*, et *à savoir*. +### Relever la fiche de la machine + +En install party, un second script complète l'état des lieux : il relève la **fiche +matérielle** — modèle, processeur, mémoire et ses connecteurs, disques et leur santé — +et l'envoie au serveur de l'association. + +```bash +wget http://10.0.0.1/alpi-fiche.sh && chmod +x alpi-fiche.sh && sudo ./alpi-fiche.sh --check +``` + +Lancé depuis la session live, il rend en plus un verdict en trois états : **bon pour +l'installation**, **possible avec des réserves**, ou **ne pas installer en l'état** — un +disque qui se déclare défaillant, des secteurs réalloués, moins de 2 Go de mémoire, un +processeur 32 bits. C'est le dernier moment où l'on peut encore renoncer et en parler au +propriétaire. + +Le même script, relancé après l'installation (sans `--check`), enregistre ce qui a +finalement été installé. Les deux relevés se comparent : un disque qui allait bien le +matin et se plaint le soir, cela se voit. + +!!! warning "Dites-le à la personne dont vous installez la machine" + La fiche part sur le réseau local, vers le serveur de l'association, et n'en sort + pas. Elle ne contient ni fichiers, ni historique, ni nom d'utilisateur — mais elle + contient le **nom de la machine**, souvent un prénom, et l'**adresse matérielle** de + la carte réseau. C'est son ordinateur : cela se demande, cela ne se suppose pas. + !!! danger "BitLocker : ne touchez à rien" Si le script annonce une partition chiffrée par BitLocker, **arrêtez-vous là**. Le chiffrement doit être suspendu depuis Windows — *Paramètres → Confidentialité et -- 2.45.2 From 122c0f22c3d49eda46b784c3eaa95b140caf97e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Thu, 24 Sep 2026 22:34:07 +0200 Subject: [PATCH 2/2] =?UTF-8?q?Ne=20plus=20prendre=20une=20machine=20insta?= =?UTF-8?q?ll=C3=A9e=20pour=20une=20session=20live?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'installateur de Mint laisse un /cdrom vide derrière lui. Le test s'y fiait, et déclarait donc « session live » une machine parfaitement installée — constaté le 24/09/2026 sur un HP 250 G4, qui annonçait « relevé avant installation » alors que Mint 22.3 tournait dessus. Ce n'est pas anodin : la durée d'une installation se mesure entre le relevé d'avant et celui d'après, et deux relevés « avant » ne se soustraient pas. Une machine mal reconnue ne compte donc jamais dans les statistiques. Le signe qui ne trompe pas est la racine montée en overlay ou en squashfs, ce qu'aucun système installé ne fait, avec boot=casper sur la ligne du noyau. Les répertoires ne sont retenus que s'ils sont réellement montés, depuis un support en lecture seule. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XLTJ8DoPfvhZMK5Yxtrfx2 --- code/linux/linux-mint/alpi-fiche.sh | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/code/linux/linux-mint/alpi-fiche.sh b/code/linux/linux-mint/alpi-fiche.sh index f9d0b45..eee7465 100755 --- a/code/linux/linux-mint/alpi-fiche.sh +++ b/code/linux/linux-mint/alpi-fiche.sh @@ -106,12 +106,24 @@ 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 garde -# un /cdrom ou un /rofs. Aucun de ces signes n'existe sur un système installé. +# 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 de /cdrom ou de /rofs, elle, ne prouve rien : l'installateur de +# Mint laisse un /cdrom vide derrière lui. La première version de ce test a +# donc déclaré « session live » une machine parfaitement installée — constaté +# le 24/09/2026 sur un HP 250 G4. Ce n'est pas anodin : la durée d'une +# installation se mesure entre le relevé d'avant et celui d'après, et deux +# relevés « avant » ne se soustraient pas. On ne retient donc ces répertoires +# que s'ils sont réellement montés, et montés depuis un support en lecture +# seule. MOMENT="post-installation" -if [ -d /rofs ] || [ -d /cdrom ] \ - || findmnt -n -o FSTYPE / 2>/dev/null | grep -qE '^(overlay|aufs|squashfs)$' \ - || grep -qE '(^| )(boot=casper|boot=live)( |$)' /proc/cmdline 2>/dev/null; then +if findmnt -n -o FSTYPE / 2>/dev/null | grep -qE '^(overlay|aufs|squashfs)$' \ + || 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 -- 2.45.2