Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
0de970239f
|
|||
|
7d6bba42b2
|
|||
|
1184ba17d9
|
|||
|
d25ab9b4da
|
+45
-20
@@ -138,7 +138,12 @@ if [ -z "$FWS_IN_CONTAINER" ] && ! host_is_arch; then
|
||||
"${SUDO[@]}" podman pull "$IMAGE"
|
||||
|
||||
echo "==> Relance dans le conteneur ($SELF)..."
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --privileged \
|
||||
# --network=host : le réseau bridge de podman ne route plus vers l'extérieur
|
||||
# sur ce wifi (firewalld/NAT cassé après changement de réseau → « core.db :
|
||||
# Resolving timed out », même avec --dns). En partageant la pile réseau de
|
||||
# l'hôte (qui, lui, a internet + DNS via 127.0.0.53/systemd-resolved joignable
|
||||
# dans son propre netns), le conteneur récupère une connectivité identique.
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --network=host --privileged \
|
||||
-e FWS_IN_CONTAINER=1 \
|
||||
-v "$REPO_DIR":"$REPO_DIR" \
|
||||
-v fws-pacman-cache:/var/cache/pacman/pkg \
|
||||
@@ -188,29 +193,49 @@ WORK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
echo "==> Dossier de travail : $WORK_DIR"
|
||||
|
||||
# ============================================================
|
||||
# Lecture et validation de la version (fichier VERSION)
|
||||
# Version (major.minor.build) + nom de la variante.
|
||||
# La version est DEMANDÉE ; le fichier VERSION sert de DÉFAUT (taper Entrée =
|
||||
# reprendre sa valeur). Produit fws-<major.minor.build>-<nom>.iso
|
||||
# (ex. fws-1.5.0-cli.iso). Nécessite un terminal (read).
|
||||
# ============================================================
|
||||
# Défaut éventuel lu dans le fichier VERSION (doit être major.minor.build).
|
||||
VERSION_FILE="$WORK_DIR/VERSION"
|
||||
[ -f "$VERSION_FILE" ] \
|
||||
|| { echo -e "\e[31mFichier VERSION introuvable : $VERSION_FILE\e[0m"; exit 1; }
|
||||
|
||||
# Trim espaces / tabulations / CR / LF
|
||||
VERSION="$(tr -d ' \t\r\n' < "$VERSION_FILE")"
|
||||
|
||||
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo -e "\e[31mVERSION invalide : '$VERSION' (attendu Major.Minor.Build, ex. 1.2.3)\e[0m"
|
||||
exit 1
|
||||
VERSION_DEFAULT=""
|
||||
if [ -f "$VERSION_FILE" ]; then
|
||||
VERSION_DEFAULT="$(tr -d ' \t\r\n' < "$VERSION_FILE")"
|
||||
[[ "$VERSION_DEFAULT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || VERSION_DEFAULT=""
|
||||
fi
|
||||
|
||||
IFS='.' read -r MAJOR MINOR BUILD <<< "$VERSION"
|
||||
BUILD_DATE="$(date +%Y.%m.%d)"
|
||||
ISO_VERSION="v${MAJOR}-${MINOR}-${BUILD}-${BUILD_DATE}"
|
||||
OUT_DIR="$WORK_DIR/out/v${MAJOR}/v${MAJOR}.${MINOR}"
|
||||
ISO_FILE="$OUT_DIR/FWS-${ISO_VERSION}-x86_64.iso"
|
||||
while :; do
|
||||
if [ -n "$VERSION_DEFAULT" ]; then
|
||||
read -rp "==> Version (major.minor.build) [Entrée = $VERSION_DEFAULT] : " VERSION \
|
||||
|| { echo -e "\e[31mEntrée requise — lance le script en interactif.\e[0m" >&2; exit 1; }
|
||||
[ -n "$VERSION" ] || VERSION="$VERSION_DEFAULT" # vide → on reprend le fichier VERSION
|
||||
else
|
||||
read -rp "==> Version (major.minor.build, ex. 1.5.0) : " VERSION \
|
||||
|| { echo -e "\e[31mEntrée requise — lance le script en interactif.\e[0m" >&2; exit 1; }
|
||||
fi
|
||||
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && break
|
||||
echo -e "\e[31m Format attendu : major.minor.build (ex. 1.5.0)\e[0m" >&2
|
||||
done
|
||||
while :; do
|
||||
read -rp "==> Nom de la variante (ex. cli, gnome, kde) : " ISO_TAG \
|
||||
|| { echo -e "\e[31mEntrée requise — lance le script en interactif.\e[0m" >&2; exit 1; }
|
||||
# normalise : minuscules, lettres / chiffres / tirets uniquement
|
||||
ISO_TAG="$(printf '%s' "$ISO_TAG" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-')"
|
||||
[ -n "$ISO_TAG" ] && break
|
||||
echo -e "\e[31m Nom requis (lettres, chiffres, tirets)\e[0m" >&2
|
||||
done
|
||||
|
||||
echo "==> Version officielle : ${MAJOR}.${MINOR}.${BUILD}"
|
||||
echo "==> Dossier de sortie : $OUT_DIR"
|
||||
echo "==> ISO finale : FWS-${ISO_VERSION}-x86_64.iso"
|
||||
IFS='.' read -r MAJOR MINOR BUILD <<< "$VERSION"
|
||||
# iso_version interne (passé à mkarchiso) ; l'ISO finale est renommée plus bas.
|
||||
ISO_VERSION="${VERSION}-${ISO_TAG}"
|
||||
OUT_DIR="$WORK_DIR/out/v${MAJOR}/v${MAJOR}.${MINOR}"
|
||||
ISO_FILE="$OUT_DIR/fws-${VERSION}-${ISO_TAG}.iso"
|
||||
|
||||
echo "==> Version : ${VERSION} · variante : ${ISO_TAG}"
|
||||
echo "==> ISO finale : fws-${VERSION}-${ISO_TAG}.iso"
|
||||
echo "==> Dossier : $OUT_DIR"
|
||||
|
||||
# pacman ≥ 7 sandboxe les ops FS via landlock, non supporté par le kernel
|
||||
# WSL ni (selon le noyau) par le conteneur → désactivation. Idempotent,
|
||||
@@ -319,4 +344,4 @@ echo "==> Nettoyage..."
|
||||
rm -rf /tmp/fws-build/work
|
||||
|
||||
echo "==> Build officiel terminé ! ISO : $FINAL"
|
||||
echo -e "\e[32mScript de build officiel (v${MAJOR}.${MINOR}.${BUILD}) terminé avec succès.\e[0m"
|
||||
echo -e "\e[32mScript de build officiel (fws-${VERSION}-${ISO_TAG}) terminé avec succès.\e[0m"
|
||||
|
||||
@@ -133,7 +133,12 @@ if [ -z "$FWS_IN_CONTAINER" ] && ! host_is_arch; then
|
||||
"${SUDO[@]}" podman pull "$IMAGE"
|
||||
|
||||
echo "==> Relance dans le conteneur ($SELF)..."
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --privileged \
|
||||
# --network=host : le réseau bridge de podman ne route plus vers l'extérieur
|
||||
# sur ce wifi (firewalld/NAT cassé après changement de réseau → « core.db :
|
||||
# Resolving timed out », même avec --dns). En partageant la pile réseau de
|
||||
# l'hôte (qui, lui, a internet + DNS via 127.0.0.53/systemd-resolved joignable
|
||||
# dans son propre netns), le conteneur récupère une connectivité identique.
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --network=host --privileged \
|
||||
-e FWS_IN_CONTAINER=1 \
|
||||
-v "$REPO_DIR":"$REPO_DIR" \
|
||||
-v fws-pacman-cache:/var/cache/pacman/pkg \
|
||||
|
||||
@@ -20,26 +20,6 @@ _OB_PID=$!
|
||||
# boucle (symptôme « fond bleu qui clignote/reboote »). On NE rend jamais la main
|
||||
# à startx : on reste sur Openbox pour lire les logs / rebooter proprement.
|
||||
if command -v liveinst >/dev/null 2>&1; then
|
||||
# Chantier D : RÉCAPITULATIF matériel AVANT de lancer l'installateur.
|
||||
# fws-hw-detect est la MÊME source de vérité que le %post du kickstart
|
||||
# (mode --env) → ce que cet écran annonce = ce que l'install appliquera
|
||||
# (drivers GPU, guest tools de l'hyperviseur, effacement des disques…).
|
||||
# « Éteindre » est le seul moyen propre d'annuler : on ne rend jamais la
|
||||
# main à startx (cf. plus bas), et liveinst n'a pas encore touché au disque.
|
||||
# Tout est best-effort : sans script ou sans zenity, on installe comme avant.
|
||||
if command -v fws-hw-detect >/dev/null 2>&1; then
|
||||
fws-hw-detect --text >/tmp/fws-hw-summary.txt 2>/dev/null || true
|
||||
if command -v zenity >/dev/null 2>&1 && [ -s /tmp/fws-hw-summary.txt ]; then
|
||||
if ! zenity --text-info --title="FWS — Récapitulatif avant installation" \
|
||||
--filename=/tmp/fws-hw-summary.txt \
|
||||
--ok-label="Lancer l'installateur" --cancel-label="Éteindre" \
|
||||
--width=800 --height=700 2>/dev/null; then
|
||||
systemctl poweroff
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
LIVEINST_LOG=/tmp/fws-liveinst.log
|
||||
liveinst >"$LIVEINST_LOG" 2>&1
|
||||
rc=$?
|
||||
@@ -86,9 +66,6 @@ if command -v liveinst >/dev/null 2>&1; then
|
||||
echo
|
||||
echo "########## %post --nochroot (/tmp/fws-post-nochroot.log) ##########"
|
||||
cat /tmp/fws-post-nochroot.log 2>/dev/null || echo "(absent)"
|
||||
echo
|
||||
echo "########## Récapitulatif matériel montré avant l'install ##########"
|
||||
cat /tmp/fws-hw-summary.txt 2>/dev/null || echo "(absent)"
|
||||
for f in /tmp/anaconda.log /tmp/syslog /tmp/program.log \
|
||||
/tmp/storage.log /tmp/dbus.log /tmp/packaging.log /tmp/X.log; do
|
||||
echo
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# fws-hw-detect — détection matériel FWS (hyperviseur + GPU).
|
||||
#
|
||||
# SOURCE UNIQUE de vérité, consommée par DEUX endroits :
|
||||
# • l'écran « Récapitulatif avant installation » du live (--text, affiché
|
||||
# par /root/.xinitrc via zenity juste avant de lancer liveinst) ;
|
||||
# • le %post chrooté du kickstart Anaconda (--env), qui APPLIQUE :
|
||||
# activation des guest tools du bon hyperviseur, purge des autres,
|
||||
# installation des drivers GPU.
|
||||
# → ce que l'écran ANNONCE = ce que l'install FERA (aucune divergence
|
||||
# possible, la détection vit ici et nulle part ailleurs).
|
||||
#
|
||||
# Fonctionne dans le LIVE comme dans le CHROOT d'Anaconda : celui-ci
|
||||
# bind-monte /sys et /proc du live → même matériel visible. Le script est
|
||||
# livré par l'airootfs (/usr/local/bin) → recopié dans la cible par le
|
||||
# payload liveimg → présent dans le chroot du %post. Aucune dépendance
|
||||
# dure : lspci (pciutils) et ip (iproute2) ne servent qu'aux libellés
|
||||
# humains de --text, avec repli si absents.
|
||||
#
|
||||
# Usage : fws-hw-detect --env lignes FWS_*='…' à eval par le kickstart
|
||||
# fws-hw-detect --text récapitulatif humain en français (zenity)
|
||||
# ============================================================================
|
||||
set -u
|
||||
MODE="${1:---text}"
|
||||
|
||||
# --- Hyperviseur --------------------------------------------------------------
|
||||
# systemd-detect-virt lit CPUID/DMI → OK en chroot, sans systemd actif.
|
||||
# ATTENTION : hors VM il AFFICHE « none » ET sort en code ≠ 0 → surtout pas de
|
||||
# « || echo none » DANS le $() (on récolterait « none » en double).
|
||||
VIRT="$(systemd-detect-virt 2>/dev/null | head -n1)"
|
||||
[ -n "$VIRT" ] || VIRT=none
|
||||
|
||||
# Les guest tools des 3 hyperviseurs sont DÉJÀ dans l'image live
|
||||
# (packages.x86_64 : open-vm-tools, virtualbox-guest-utils-nox,
|
||||
# qemu-guest-agent) → activer un service marche HORS LIGNE ; on retire ceux
|
||||
# des autres hyperviseurs (inutiles sur cette machine).
|
||||
VIRT_SVC="" VIRT_RM="" VIRT_LABEL=""
|
||||
case "$VIRT" in
|
||||
vmware)
|
||||
VIRT_LABEL="VMware"
|
||||
VIRT_SVC="vmtoolsd.service vmware-vmblock-fuse.service"
|
||||
VIRT_RM="virtualbox-guest-utils-nox qemu-guest-agent" ;;
|
||||
oracle) # = VirtualBox (nom renvoyé par systemd-detect-virt)
|
||||
VIRT_LABEL="VirtualBox"
|
||||
VIRT_SVC="vboxservice.service"
|
||||
VIRT_RM="open-vm-tools qemu-guest-agent" ;;
|
||||
kvm|qemu)
|
||||
VIRT_LABEL="QEMU/KVM"
|
||||
VIRT_SVC="qemu-guest-agent.service"
|
||||
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox" ;;
|
||||
none)
|
||||
VIRT_LABEL="aucune (machine physique)"
|
||||
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox qemu-guest-agent" ;;
|
||||
*) # Hyperviseur non géré (hyper-v…) : aucun de nos guest tools ne sert.
|
||||
VIRT_LABEL="$VIRT (intégration non gérée)"
|
||||
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox qemu-guest-agent" ;;
|
||||
esac
|
||||
|
||||
# --- GPU ----------------------------------------------------------------------
|
||||
# Classe PCI 0x03xxxx = contrôleur d'affichage ; lecture DIRECTE de /sys, pas
|
||||
# besoin de lspci. Vendors : 0x10de NVIDIA, 0x1002 AMD, 0x8086 Intel,
|
||||
# 0x15ad VMware (le VMSVGA de VirtualBox porte AUSSI 0x15ad → couvert).
|
||||
# QEMU virtio-gpu/QXL et VBoxVGA : modesetting + mesa (déjà tirés par
|
||||
# xorg-server dans l'image) suffisent → rien à installer.
|
||||
DRV_PKGS="" GPU_TEXT=""
|
||||
for _dev in /sys/bus/pci/devices/*; do
|
||||
case "$(cat "$_dev/class" 2>/dev/null)" in 0x03*) ;; *) continue ;; esac
|
||||
_vendor="$(cat "$_dev/vendor" 2>/dev/null)"
|
||||
_pkgs=""
|
||||
case "$_vendor" in
|
||||
# NVIDIA : le module des dépôts est bâti pour le NOYAU des dépôts →
|
||||
# « linux » DOIT partir dans la même transaction pacman (le noyau
|
||||
# installé est celui du live, plus vieux), sinon module ≠ noyau au
|
||||
# 1er boot. Les chemins /boot/* sont stables → grub.cfg reste bon.
|
||||
0x10de) _pkgs="linux nvidia nvidia-utils" ;;
|
||||
0x1002) _pkgs="mesa vulkan-radeon xf86-video-amdgpu" ;;
|
||||
0x8086) _pkgs="mesa vulkan-intel" ;;
|
||||
0x15ad) _pkgs="mesa xf86-video-vmware" ;;
|
||||
esac
|
||||
# Libellé humain : lspci si dispo, sinon adresse PCI + vendor brut.
|
||||
_name=""
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
_name="$(lspci -s "${_dev##*/}" 2>/dev/null | head -n1 \
|
||||
| cut -d: -f3- | sed 's/^ //')"
|
||||
fi
|
||||
[ -n "$_name" ] || _name="GPU PCI ${_dev##*/} (vendor $_vendor)"
|
||||
if [ -n "$_pkgs" ]; then
|
||||
GPU_TEXT="${GPU_TEXT} • ${_name}\n → paquets : ${_pkgs}\n"
|
||||
DRV_PKGS="$DRV_PKGS $_pkgs"
|
||||
else
|
||||
GPU_TEXT="${GPU_TEXT} • ${_name}\n → rien à installer (modesetting + mesa, déjà dans l'image)\n"
|
||||
fi
|
||||
done
|
||||
# Dédoublonnage (machine multi-GPU : « mesa » listé 2× ferait échouer pacman
|
||||
# sur « duplicate target »).
|
||||
if [ -n "$DRV_PKGS" ]; then
|
||||
DRV_PKGS="$(printf '%s\n' $DRV_PKGS | sort -u | tr '\n' ' ')"
|
||||
DRV_PKGS="${DRV_PKGS% }"
|
||||
fi
|
||||
|
||||
# --- Mode machine : sortie shell pour le kickstart ----------------------------
|
||||
if [ "$MODE" = "--env" ]; then
|
||||
printf "FWS_VIRT='%s'\n" "$VIRT"
|
||||
printf "FWS_VIRT_SVC='%s'\n" "$VIRT_SVC"
|
||||
printf "FWS_VIRT_RM='%s'\n" "$VIRT_RM"
|
||||
printf "FWS_DRV_PKGS='%s'\n" "$DRV_PKGS"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- Mode humain : récapitulatif --text (zenity, avant liveinst) ---------------
|
||||
CPU="$(awk -F': +' '/^model name/{print $2; exit}' /proc/cpuinfo)"
|
||||
[ -n "$CPU" ] || CPU="inconnu"
|
||||
case "$(awk -F': +' '/^vendor_id/{print $2; exit}' /proc/cpuinfo)" in
|
||||
GenuineIntel) UCODE="intel-ucode" ;;
|
||||
AuthenticAMD) UCODE="amd-ucode" ;;
|
||||
*) UCODE="" ;;
|
||||
esac
|
||||
RAM="$(awk '/^MemTotal/{printf "%.1f Gio", $2/1048576}' /proc/meminfo)"
|
||||
if [ -d /sys/firmware/efi ]; then
|
||||
BOOT="UEFI — GRUB x86_64-efi + entrée de secours EFI/BOOT/BOOTX64.EFI"
|
||||
else
|
||||
BOOT="BIOS hérité — GRUB i386-pc, table de partitions MBR forcée"
|
||||
fi
|
||||
if command -v ip >/dev/null 2>&1 && ip route get 1.1.1.1 >/dev/null 2>&1; then
|
||||
NET="disponible ✔"
|
||||
else
|
||||
NET="INDISPONIBLE ✖ — drivers GPU et bureau ne s'installeront PAS (rattrapable au 1er boot)"
|
||||
fi
|
||||
# Type « disk » uniquement (exclut lecteur ISO sr0/loop). La clé USB du live,
|
||||
# elle, EST un disque → il est juste qu'elle apparaisse sous l'avertissement
|
||||
# d'effacement (clearpart --all du kickstart efface bien TOUS les disques).
|
||||
DISKS="$(lsblk -dno NAME,SIZE,MODEL,TYPE 2>/dev/null \
|
||||
| awk '$NF=="disk"{NF--; print " • " $0}')"
|
||||
[ -n "$DISKS" ] || DISKS=" (aucun disque détecté)"
|
||||
[ -n "$GPU_TEXT" ] || GPU_TEXT=" (aucune carte graphique détectée)\n"
|
||||
|
||||
printf '%b' \
|
||||
"══════════════════════════════════════════════════════════
|
||||
FWS — RÉCAPITULATIF AVANT INSTALLATION
|
||||
══════════════════════════════════════════════════════════
|
||||
|
||||
MACHINE
|
||||
• Démarrage : ${BOOT}
|
||||
• Virtualisation : ${VIRT_LABEL}
|
||||
• Processeur : ${CPU}"
|
||||
[ -n "$UCODE" ] && printf '%b' "
|
||||
• Microcode : ${UCODE} — déjà intégré à l'image, rien à faire"
|
||||
printf '%b' "
|
||||
• Mémoire : ${RAM}
|
||||
• Réseau : ${NET}
|
||||
|
||||
DISQUES DÉTECTÉS
|
||||
⚠ Par défaut, TOUS les disques ci-dessous seront ENTIÈREMENT
|
||||
EFFACÉS (partitionnement automatique). Le partitionnement
|
||||
manuel reste possible dans l'installateur.
|
||||
${DISKS}
|
||||
|
||||
CARTES GRAPHIQUES → drivers installés AUTOMATIQUEMENT en fin d'install
|
||||
${GPU_TEXT}
|
||||
INTÉGRATION HYPERVISEUR (automatique, fonctionne hors ligne)
|
||||
• Services activés : ${VIRT_SVC:-aucun}
|
||||
• Guest tools retirés (inutiles) : ${VIRT_RM:-aucun}
|
||||
|
||||
DÉROULEMENT DE L'INSTALLATION
|
||||
1. Réglages dans Anaconda : langue, clavier, fuseau, disque, utilisateur
|
||||
2. Copie du système live FWS sur le disque (payload liveimg)
|
||||
3. Noyau + initramfs régénérés (mkinitcpio), GRUB installé
|
||||
4. Drivers GPU + intégration hyperviseur appliqués (voir ci-dessus)
|
||||
5. Bureau choisi installé (réseau requis)
|
||||
|
||||
« Lancer l'installateur » pour continuer — « Éteindre » pour annuler.
|
||||
"
|
||||
@@ -24,7 +24,6 @@ file_permissions=(
|
||||
["/root/.automated_script.sh"]="0:0:755"
|
||||
["/root/.gnupg"]="0:0:700"
|
||||
["/usr/local/bin/choose-mirror"]="0:0:755"
|
||||
["/usr/local/bin/fws-hw-detect"]="0:0:755"
|
||||
["/usr/local/bin/Installation_guide"]="0:0:755"
|
||||
["/usr/local/bin/livecd-sound"]="0:0:755"
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
archiso
|
||||
fws
|
||||
|
||||
@@ -5,5 +5,14 @@
|
||||
# On utilise donc un autre nom.
|
||||
_fastfetch_rc=$?
|
||||
if [ "${_fastfetch_rc}" -eq 0 ]; then
|
||||
fastfetch
|
||||
# Logo FWS maison (4 carrés + Tux) au lieu du logo Arch détecté par défaut.
|
||||
fastfetch \
|
||||
--logo-type file \
|
||||
--logo /usr/local/share/fws/logo.txt \
|
||||
--logo-color-1 '38;2;30;160;100' \
|
||||
--logo-color-2 '38;2;45;125;210' \
|
||||
--logo-color-3 '38;2;240;180;40' \
|
||||
--logo-color-4 '38;2;25;85;145' \
|
||||
--logo-color-5 '38;2;28;28;34' \
|
||||
--logo-color-6 '38;2;245;165;35'
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
$1████████ $2██$5████$2██
|
||||
$1████████ $2█$5██$2██$5██$2█
|
||||
$1████████ $2█$5██████$2█
|
||||
$1████████ $2██$6█$2██$6█$2██
|
||||
|
||||
$3████████ $4████████
|
||||
$3████████ $4████████
|
||||
$3████████ $4████████
|
||||
$3████████ $4████████
|
||||
@@ -89,6 +89,17 @@ SYSROOT=/mnt/sysroot
|
||||
# DNS pour que « pacman -S <bureau> » fonctionne dans le chroot.
|
||||
cp -f /etc/resolv.conf "$SYSROOT/etc/resolv.conf" 2>/dev/null || true
|
||||
|
||||
# --- Hostname : valeur saisie dans le champ « Nom de machine » du spoke User --
|
||||
# Anaconda ne capte PAS le hostname du spoke Réseau (→ /etc/hostname vide). On a
|
||||
# donc ajouté un champ Hostname au spoke Utilisateur (cf. patch du paquet
|
||||
# anaconda) : user.py écrit la valeur dans /tmp/fws-hostname (live). On la
|
||||
# nettoie (caractères de hostname valides) et on l'écrit dans la cible ; défaut
|
||||
# « fws » si vide/absent → plus jamais de hostname vide ni « archiso ».
|
||||
HN=""
|
||||
[ -f /tmp/fws-hostname ] && HN="$(tr -cd 'a-zA-Z0-9._-' < /tmp/fws-hostname)"
|
||||
[ -n "$HN" ] || HN="fws"
|
||||
echo "$HN" > "$SYSROOT/etc/hostname"
|
||||
|
||||
# Choix du bureau (écrit par l'addon « Choix du bureau », à venir ; valeur lue
|
||||
# par le %post chrooté ci-dessous). « cli » par défaut si absent.
|
||||
if [ -f /tmp/fws-desktop ]; then
|
||||
@@ -194,47 +205,7 @@ else
|
||||
echo "[FWS] AVERTISSEMENT : grub-install a échoué — bootloader à refaire à la main"
|
||||
fi
|
||||
|
||||
# --- 4) Drivers matériels : détection + activation/installation AUTO ----------
|
||||
# Toute la DÉTECTION vit dans /usr/local/bin/fws-hw-detect : livré par
|
||||
# l'airootfs → recopié dans la cible par le payload liveimg → présent dans ce
|
||||
# chroot. C'est la MÊME source de vérité que l'écran « Récapitulatif avant
|
||||
# installation » du live (.xinitrc, mode --text) : ce qui a été ANNONCÉ à
|
||||
# l'utilisateur = ce qu'on APPLIQUE ici. La détection marche en chroot car
|
||||
# Anaconda bind-monte le /sys et le /proc du LIVE (le code plus haut s'appuie
|
||||
# déjà dessus : /sys/firmware/efi, findmnt) → on voit le VRAI matériel.
|
||||
# Variables produites par --env :
|
||||
# FWS_VIRT hyperviseur (vmware/oracle/kvm/qemu/none…)
|
||||
# FWS_VIRT_SVC services invité à activer (paquets DÉJÀ dans l'image → OK
|
||||
# hors ligne ; c'était le chaînon manquant, rien n'activait
|
||||
# vmtoolsd & co sur le système installé)
|
||||
# FWS_VIRT_RM guest tools des AUTRES hyperviseurs, à purger
|
||||
# FWS_DRV_PKGS paquets GPU à installer, dédoublonnés. NVIDIA embarque
|
||||
# « linux » dans la même transaction : le module des dépôts
|
||||
# est bâti pour le noyau des dépôts, pas celui du live ; les
|
||||
# chemins /boot/* étant stables, le grub.cfg de l'étape 3
|
||||
# reste valable (le hook pacman de nvidia relance mkinitcpio).
|
||||
# NB : microcode CPU (amd-ucode/intel-ucode) et linux-firmware sont DÉJÀ dans
|
||||
# l'image → recopiés, et grub-mkconfig (étape 3) a généré les initrd qui vont
|
||||
# bien. Rien à faire pour eux.
|
||||
if [ -x /usr/local/bin/fws-hw-detect ]; then
|
||||
eval "$(/usr/local/bin/fws-hw-detect --env)"
|
||||
# (a) Hyperviseur : activer le bon service invité, purger les autres.
|
||||
[ -n "$FWS_VIRT_SVC" ] && { systemctl enable $FWS_VIRT_SVC || true; }
|
||||
[ -n "$FWS_VIRT_RM" ] && { pacman -Rns --noconfirm $FWS_VIRT_RM || true; }
|
||||
# (b) GPU : install réseau, NON bloquante (même philosophie que le
|
||||
# bureau). --needed : ne réinstalle pas ce que l'image a déjà (mesa…).
|
||||
if [ -n "$FWS_DRV_PKGS" ]; then
|
||||
pacman-key --init &>/dev/null || true
|
||||
pacman-key --populate archlinux &>/dev/null || true
|
||||
if ! pacman -Sy --noconfirm --needed $FWS_DRV_PKGS; then
|
||||
echo "[FWS] Drivers non installés ($FWS_DRV_PKGS) — réseau ? À refaire au 1er boot."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "[FWS] fws-hw-detect introuvable — drivers/guest tools NON configurés."
|
||||
fi
|
||||
|
||||
# --- 5) Bureau choisi : pacman -S du DE (non bloquant si pas de réseau) -------
|
||||
# --- 4) Bureau choisi : pacman -S du DE (non bloquant si pas de réseau) -------
|
||||
DESK="cli"
|
||||
[ -f /tmp/fws-desktop ] && DESK="$(tr -d '[:space:]' < /tmp/fws-desktop)"
|
||||
DM=""
|
||||
@@ -256,14 +227,14 @@ if [ -n "$PKGS" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 6) Sécurité : verrouiller root s'il est resté SANS mot de passe ----------
|
||||
# --- 5) Sécurité : verrouiller root s'il est resté SANS mot de passe ----------
|
||||
# L'airootfs live a souvent un root sans mot de passe ; si l'utilisateur n'en a
|
||||
# pas défini dans le GUI, on verrouille plutôt que de laisser le compte ouvert.
|
||||
if passwd -S root 2>/dev/null | grep -qE '\bNP\b'; then
|
||||
passwd -l root || true
|
||||
fi
|
||||
|
||||
# --- 7) Le resolv.conf du live ne doit pas rester figé -----------------------
|
||||
# --- 6) Le resolv.conf du live ne doit pas rester figé -----------------------
|
||||
# NetworkManager (activé sur le système installé) régénère /etc/resolv.conf.
|
||||
rm -f /tmp/fws-desktop /etc/resolv.conf 2>/dev/null || true
|
||||
%end
|
||||
|
||||
+102
-1
@@ -25,7 +25,7 @@
|
||||
# ============================================================================
|
||||
pkgname=anaconda
|
||||
pkgver=45.8
|
||||
pkgrel=2
|
||||
pkgrel=4
|
||||
pkgdesc="The Anaconda installer (porté sur Arch pour FWS, payload liveimg)"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/rhinstaller/anaconda"
|
||||
@@ -57,6 +57,107 @@ source=("anaconda-$pkgver.tar.gz::https://github.com/rhinstaller/anaconda/archiv
|
||||
sha256sums=('5ef1464bff7f28a4a09a821cbb0121f09ef504ec169288d742373f86807ec4ed')
|
||||
_srcdir="anaconda-anaconda-$pkgver"
|
||||
|
||||
prepare() {
|
||||
cd "$srcdir/$_srcdir"
|
||||
# ── FWS : clavier par défaut selon le TERRITOIRE de la locale ──────────────
|
||||
# set_layouts() amont fait « locale = get_language_id(self.language) » →
|
||||
# get_language_id JETTE le territoire (fr_CH.UTF-8 → 'fr') → list_keyboards('fr')
|
||||
# = 'fr(oss)' (France) au lieu de 'ch(fr)' (Suisse). On passe la LOCALE COMPLÈTE
|
||||
# (self.language) : langtable.list_keyboards('fr_CH.UTF-8') = 'ch(fr)'. La
|
||||
# validation l'accepte (is_valid_langcode → parse_locale().language non vide).
|
||||
# → le clavier du GUI ET du système installé suivent enfin la locale choisie.
|
||||
sed -i \
|
||||
's/^\(\s*\)locale = get_language_id(self\.language)/\1locale = self.language # FWS: garder le territoire (fr_CH -> ch(fr))/' \
|
||||
pyanaconda/modules/localization/localization.py
|
||||
# Garde-fou : casse le build si le motif amont a changé (le patch silencieux).
|
||||
grep -q 'locale = self.language # FWS' \
|
||||
pyanaconda/modules/localization/localization.py
|
||||
|
||||
# ── FWS : champ « Nom de machine » dans le spoke Utilisateur ───────────────
|
||||
# Anaconda ne propage PAS le hostname (le champ du spoke Réseau est perdu chez
|
||||
# nous → /etc/hostname vide). On ajoute donc un champ Hostname à l'onglet de
|
||||
# création de compte (ligne 2 de la grille, libre) ; user.py écrit la valeur
|
||||
# dans /tmp/fws-hostname, que le %post du kickstart applique à /etc/hostname.
|
||||
python3 - <<'PYEOF'
|
||||
import glob
|
||||
|
||||
# 1) user.glade : insérer label + entry "Host name" APRÈS le bloc username_entry.
|
||||
glades = [p for p in glob.glob("pyanaconda/**/user.glade", recursive=True)
|
||||
if 'username_entry' in open(p, encoding='utf-8').read()]
|
||||
assert glades, "FWS: user.glade introuvable"
|
||||
g = glades[0]
|
||||
s = open(g, encoding='utf-8').read()
|
||||
assert 'id="hostname_entry"' not in s, "FWS: glade déjà patché"
|
||||
i = s.index('id="username_entry"')
|
||||
k = s.index('</packing>', i) # fin du packing de username_entry
|
||||
j = s.index('</child>', k) + len('</child>') # fin du <child> EXTERNE (pas l'accessible)
|
||||
block = '''
|
||||
<child>
|
||||
<object class="GtkLabel" id="hostname_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="xpad">10</property>
|
||||
<property name="label" translatable="yes" context="GUI|User">_Host name</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">hostname_entry</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="hostname_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="width-chars">50</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="hostname_entry-atkobject">
|
||||
<property name="AtkObject::accessible-name" translatable="yes">Host Name</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>'''
|
||||
open(g, 'w', encoding='utf-8').write(s[:j] + block + s[j:])
|
||||
|
||||
# 2) user.py (GUI) : récupérer le widget + écrire /tmp/fws-hostname dans apply().
|
||||
pys = glob.glob("pyanaconda/ui/gui/spokes/user.py")
|
||||
assert pys, "FWS: user.py introuvable"
|
||||
p = pys[0]
|
||||
s = open(p, encoding='utf-8').read()
|
||||
anchor = 'self._username_entry = self.builder.get_object("username_entry")'
|
||||
assert anchor in s, "FWS: ancre username_entry absente"
|
||||
s = s.replace(anchor,
|
||||
anchor + '\n self._hostname_entry = self.builder.get_object("hostname_entry")',
|
||||
1)
|
||||
ap = 'set_user_list(self._users_module, self._user_list, remove_unset=True)'
|
||||
assert ap in s, "FWS: ancre apply() absente"
|
||||
s = s.replace(ap, ap + '''
|
||||
|
||||
# FWS : mémorise le nom de machine saisi (cible pas encore montée) pour
|
||||
# le %post du kickstart, qui l'écrira dans /etc/hostname.
|
||||
try:
|
||||
_hn = self._hostname_entry.get_text().strip()
|
||||
except Exception:
|
||||
_hn = ""
|
||||
try:
|
||||
with open("/tmp/fws-hostname", "w") as _f:
|
||||
_f.write(_hn)
|
||||
except OSError:
|
||||
pass''', 1)
|
||||
open(p, 'w', encoding='utf-8').write(s)
|
||||
print("FWS: champ Hostname ajouté au spoke Utilisateur (glade + user.py)")
|
||||
PYEOF
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$_srcdir"
|
||||
# Glade désactivé (catalogue designer, inutile au runtime) → pas de dép glade.
|
||||
|
||||
+4
-1
@@ -114,7 +114,10 @@ if [ -z "$FWS_IN_CONTAINER" ] && ! host_is_arch; then
|
||||
"${SUDO[@]}" podman pull "$IMAGE"
|
||||
|
||||
info "Relance dans le conteneur (setup-aur.sh)…"
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --privileged \
|
||||
# --network=host : le bridge podman ne route plus vers l'extérieur sur
|
||||
# certains réseaux (firewalld/NAT, → « Resolving timed out »). On partage la
|
||||
# pile réseau de l'hôte (internet + DNS OK) pour les pacman/makepkg/AUR.
|
||||
"${SUDO[@]}" podman run --rm "${TTY[@]}" --network=host --privileged \
|
||||
-e FWS_IN_CONTAINER=1 \
|
||||
-v "$REPO_DIR":"$REPO_DIR" \
|
||||
-v fws-pacman-cache:/var/cache/pacman/pkg \
|
||||
|
||||
Reference in New Issue
Block a user