43ecf7f54f
Add PipeWire audio stack (pipewire, pipewire-pulse, wireplumber, pavucontrol) and Bluetooth support (bluez, bluez-utils, blueman) to xfce and hyprland package lists to ensure they are installed alongside the desktop environment. Enable bluetooth.service at installation time for hyprland to have Bluetooth ready at first boot. Update comments to reflect the new guaranteed installation of audio and Bluetooth components as part of the desktop environment transaction.
504 lines
28 KiB
Plaintext
504 lines
28 KiB
Plaintext
# ============================================================================
|
|
# FWS — interactive-defaults.ks
|
|
#
|
|
# Kickstart de base, lu AUTOMATIQUEMENT par Anaconda quand l'install est
|
|
# lancée en mode interactif (chemin fixe codé en dur dans Anaconda :
|
|
# /usr/share/anaconda/interactive-defaults.ks). Aucun inst.ks= n'est requis.
|
|
#
|
|
# RÔLE : finaliser une install « copie du live » (surtout pas Fedora).
|
|
# ----------------------------------------------------------------------------
|
|
# Anaconda n'a AUCUN backend pacman ; son payload par défaut (DNF) poserait
|
|
# des RPM Fedora. Ici le payload est LiveOS, imposé par « anaconda --liveinst »
|
|
# (cf. bloc « Source d'installation » ci-dessous) : il recopie le squashfs du
|
|
# live (= FWS) sur le disque, puis on finalise nous-mêmes (grub, mkinitcpio,
|
|
# bureau) en %post. C'est le modèle « Sabayon » : le système installé EST une
|
|
# copie du live.
|
|
#
|
|
# L'utilisateur garde la main dans le GUI sur tout ce qui N'EST PAS fixé ici :
|
|
# partitionnement, fuseau, clavier, langue, création d'utilisateur, mot de
|
|
# passe root, etc.
|
|
# ============================================================================
|
|
|
|
# --- Source d'installation : le payload LiveOS (surtout pas Fedora/DNF) ------
|
|
# AUCUNE directive de payload ici, et c'est VOULU. liveinst lance
|
|
# « anaconda --liveinst » et anaconda.py teste opts.liveinst AVANT le type du
|
|
# payload DBus → il crée TOUJOURS un payload LiveOS et IGNORE tout payload du
|
|
# kickstart (un « liveimg » ici serait du code mort — vérifié dans
|
|
# pyanaconda/anaconda.py, propriété payload, et reproduit hors VM).
|
|
#
|
|
# Le payload LiveOS détecte l'image live via /dev/mapper/live-base ou
|
|
# /run/rootfsbase (chemins Fedora/dracut, absents d'archiso → c'était le crash
|
|
# « SourceSetupError: No Live OS image found! » au démarrage). Le .xinitrc du
|
|
# live bind-monte donc /run/archiso/airootfs (squashfs FWS, ro) sur
|
|
# /run/rootfsbase AVANT de lancer liveinst : Anaconda monte le loop device et
|
|
# rsync son contenu vers la cible = le système installé EST une copie du live,
|
|
# puis on finalise en %post (grub, mkinitcpio, bureau, matériel).
|
|
# DNF/libdnf5 n'est jamais importé : le module DNF n'est chargé QUE si le
|
|
# payload actif est DNF (import lazy dans modules/payloads/payload/factory.py).
|
|
|
|
# --- Disque : repartir d'un disque PROPRE, même s'il a déjà servi ------------
|
|
# Sans ça, une réinstallation sur un disque déjà partitionné (typiquement une
|
|
# install FWS précédente : partitions + VG LVM « anaconda_archiso ») pose deux
|
|
# problèmes : le partitionnement auto n'a plus d'espace libre, et blivet
|
|
# rescanne/auto-active un LVM existant au boot du live → l'installateur se
|
|
# comporte mal voire plante au 2e passage (alors qu'un disque vierge passe).
|
|
# zerombr : réinitialise toute table de partitions invalide
|
|
# (répond « oui » au lieu de bloquer sur un disque
|
|
# non reconnu).
|
|
# clearpart --all : supprime TOUTES les partitions de TOUS les disques.
|
|
# --initlabel : réécrit une étiquette de disque neuve.
|
|
# --disklabel=msdos : force une table MBR (et non GPT). CRUCIAL en BIOS :
|
|
# en BIOS+GPT, GRUB i386-pc exige une partition « BIOS
|
|
# Boot » (~1 Mo, type EF02) pour embarquer core.img,
|
|
# qu'Anaconda NE crée PAS avec « bootloader --disabled
|
|
# » → « this GPT partition label contains no BIOS Boot
|
|
# Partition; embedding won't be possible » →
|
|
# grub-install échoue. En MBR, core.img se loge dans
|
|
# l'espace post-MBR, aucune partition dédiée requise.
|
|
# ⚠ Ce choix vise le BIOS (cas VMware actuel). Pour l'UEFI il faudra du GPT
|
|
# (+ ESP) — à rendre dépendant du firmware (%pre) le jour où on cible l'UEFI.
|
|
# L'utilisateur garde la main dans le GUI (il peut repasser en manuel), mais le
|
|
# DÉFAUT est désormais un disque net → réinstall fiable à chaque fois.
|
|
# ⚠ VM mono-disque : « --all » efface le seul disque, c'est voulu. Sur une
|
|
# machine multi-disques il faudrait cibler avec « --drives=sda ».
|
|
zerombr
|
|
clearpart --all --initlabel --disklabel=msdos
|
|
|
|
# --- Bootloader : géré à la main en %post ------------------------------------
|
|
# Anaconda lancerait « grub2-install » / « grub2-mkconfig » (binaires Fedora,
|
|
# préfixe grub2-) qui n'existent pas dans un rootfs Arch (lequel fournit
|
|
# grub-install / grub-mkconfig). On désactive donc l'étape native d'Anaconda.
|
|
# L'ESP (UEFI) ou la partition bios_boot (BIOS/GPT) reste créée par le
|
|
# partitionnement (auto ou manuel) car la plateforme l'impose.
|
|
bootloader --disabled
|
|
|
|
# Pas de section %packages : le payload LiveOS n'installe aucun paquet
|
|
# (il copie une image). Toute installation de paquets se fait en %post.
|
|
|
|
# --- Récapitulatif avant installation : PAGE GUI dédiée (pas de %pre-install) -
|
|
# L'écran « RÉCAPITULATIF AVANT INSTALLATION » est une standalone spoke
|
|
# Anaconda (overlay airootfs : pyanaconda/ui/gui/spokes/fws_recap.py,
|
|
# postForHub=SummaryHub, priority -10) intercalée ENTRE le hub et l'écran de
|
|
# progression : l'utilisateur clique « Commencer l'installation », voit le
|
|
# récap (bureau choisi, hostname, disques, GPU, réseau — AUCUNE écriture
|
|
# disque à ce stade), et l'installation ne démarre qu'à son clic « Lancer
|
|
# l'installation ». L'ancien récap zenity en %pre-install a été abandonné :
|
|
# le module scripts tourne avec LC_ALL=C et un env X incertain (zenity 4
|
|
# refuse les libellés UTF-8 en locale C → rc=255 pris pour « Annuler » →
|
|
# poweroff en plein install au 1er test réel).
|
|
|
|
|
|
# ============================================================================
|
|
# %post --nochroot — s'exécute dans le LIVE, la cible montée sous /mnt/sysroot
|
|
# But : déposer dans la cible ce dont le %post chrooté aura besoin (DNS pour
|
|
# pacman, choix de bureau écrit par l'addon de sélection).
|
|
# ============================================================================
|
|
%post --nochroot --log=/tmp/fws-post-nochroot.log
|
|
set -x
|
|
|
|
# Selon la version d'Anaconda la cible est sous /mnt/sysroot (récent) ou
|
|
# /mnt/sysimage (ancien).
|
|
SYSROOT=/mnt/sysroot
|
|
[ -d "$SYSROOT" ] || SYSROOT=/mnt/sysimage
|
|
|
|
# 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
|
|
cp -f /tmp/fws-desktop "$SYSROOT/tmp/fws-desktop" 2>/dev/null || true
|
|
fi
|
|
|
|
# --- Noyau : archiso RETIRE /boot/vmlinuz-linux du squashfs ------------------
|
|
# mkarchiso boote le noyau depuis l'ISO et l'EXCLUT de l'airootfs squashfs (gain
|
|
# de place). Conséquence : le payload LiveOS recopie un rootfs SANS noyau →
|
|
# « mkinitcpio: /boot/vmlinuz-linux must be readable » puis aucun OS à booter
|
|
# (« Operating System not found »). On récupère donc le noyau depuis le média
|
|
# booté (/run/archiso/bootmnt/<install_dir>/boot/<arch>/vmlinuz-linux) et on le
|
|
# dépose dans la cible. Les modules (/usr/lib/modules) sont, eux, dans le
|
|
# squashfs → déjà recopiés. Avec le noyau présent, le %post chrooté peut bâtir
|
|
# l'initramfs (mkinitcpio) et GRUB trouve de quoi booter.
|
|
SRC_KERN="$(find /run/archiso/bootmnt -name 'vmlinuz-linux' 2>/dev/null | head -1)"
|
|
if [ -n "$SRC_KERN" ]; then
|
|
cp -f "$SRC_KERN" "$SYSROOT/boot/vmlinuz-linux"
|
|
else
|
|
echo "[FWS] AVERTISSEMENT : noyau vmlinuz-linux introuvable sur le média"
|
|
fi
|
|
%end
|
|
|
|
|
|
# ============================================================================
|
|
# %post (chroot) — DANS le rootfs FWS recopié. pacman, grub-install,
|
|
# mkinitcpio existent ici : ce sont les outils Arch de l'image copiée.
|
|
# Log persistant : /var/log/fws-post.log sur le système installé.
|
|
# ============================================================================
|
|
%post --log=/var/log/fws-post.log
|
|
set -x
|
|
|
|
# --- 1) Purge des résidus « live » (modèle Sabayon = live copié tel quel) ----
|
|
# Ce qui est propre au live casserait ou pollue le système installé.
|
|
rm -f /etc/mkinitcpio.conf.d/archiso.conf
|
|
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf
|
|
for svc in choose-mirror.service pacman-init.service \
|
|
livecd-talk.service livecd-alsa-unmuter.service \
|
|
etc-pacman.d-gnupg.mount; do
|
|
rm -f "/etc/systemd/system/$svc"
|
|
rm -f /etc/systemd/system/*.target.wants/"$svc"
|
|
done
|
|
# cloud-init (présent dans l'airootfs archiso) : inutile sur un poste installé.
|
|
rm -f /etc/systemd/system/cloud-init.target.wants/* 2>/dev/null || true
|
|
# Hooks initramfs archiso, s'ils ont été recopiés en tant que paquet.
|
|
if pacman -Q mkinitcpio-archiso &>/dev/null; then
|
|
pacman -Rns --noconfirm mkinitcpio-archiso || true
|
|
fi
|
|
|
|
# --- 2) initramfs propre (preset Arch standard, sans archiso) ----------------
|
|
# Le live fournit un preset 'archiso' (/etc/mkinitcpio.d/linux.preset qui pointe
|
|
# vers conf.d/archiso.conf + hooks archiso) → inadapté à un disque normal. On
|
|
# pose un preset Arch standard (config par défaut /etc/mkinitcpio.conf).
|
|
cat > /etc/mkinitcpio.d/linux.preset <<'PRESET'
|
|
ALL_kver="/boot/vmlinuz-linux"
|
|
PRESETS=('default' 'fallback')
|
|
default_image="/boot/initramfs-linux.img"
|
|
fallback_image="/boot/initramfs-linux-fallback.img"
|
|
fallback_options="-S autodetect"
|
|
PRESET
|
|
# Le partitionnement auto d'Anaconda met « / » sur LVM (/dev/mapper/...-root).
|
|
# Sans le hook 'lvm2' dans l'initramfs, le VG n'est pas activé au boot → la
|
|
# racine est introuvable → kernel panic. On l'insère avant 'filesystems' s'il
|
|
# manque (inoffensif si la racine n'est finalement pas sur LVM).
|
|
if ! grep -qE '^HOOKS=.*\blvm2\b' /etc/mkinitcpio.conf; then
|
|
sed -i -E 's/^(HOOKS=\(.*)\bfilesystems\b/\1lvm2 filesystems/' /etc/mkinitcpio.conf
|
|
fi
|
|
mkinitcpio -P || echo "[FWS] AVERTISSEMENT : mkinitcpio a échoué"
|
|
|
|
# --- 3) GRUB installé à la main (cf. bootloader --disabled) ------------------
|
|
install_grub() {
|
|
if [ -d /sys/firmware/efi ]; then
|
|
# UEFI. efibootmgr crée l'entrée NVRAM « FWS », mais il peut MANQUER de
|
|
# l'airootfs et son install dépend du réseau → on ne BLOQUE pas dessus.
|
|
pacman -Q efibootmgr &>/dev/null || pacman -Sy --noconfirm efibootmgr || true
|
|
# (a) Entrée NVRAM dédiée (best effort, si efibootmgr dispo) :
|
|
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
|
--bootloader-id=FWS --recheck || true
|
|
# (b) Chemin de SECOURS EFI/BOOT/BOOTX64.EFI (--removable) : boote SANS
|
|
# aucune entrée NVRAM. INDISPENSABLE en VM / sans réseau / firmware
|
|
# qui « oublie » l'entrée — c'est lui qui garantit le 1er boot UEFI.
|
|
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
|
--bootloader-id=FWS --removable --recheck
|
|
else
|
|
# BIOS : installer GRUB dans le MBR du DISQUE physique (PAS une partition)
|
|
# portant « / », même quand « / » est sur du LVM (chaîne
|
|
# LV → PV partition → disque). « lsblk -s » descend vers le physique ; on
|
|
# prend la ligne de type « disk ». ATTENTION : « lsblk -s » dessine un
|
|
# ARBRE → les caractères de branche (└─) se collent au chemin (on
|
|
# obtenait disk='-/dev/sda' → « grub-install: cannot find a GRUB drive
|
|
# for `-/dev/sda' »). On EXTRAIT donc le chemin propre avec grep.
|
|
local rootsrc disk
|
|
rootsrc="$(findmnt -no SOURCE / 2>/dev/null)"
|
|
disk="$(lsblk -spno NAME,TYPE "$rootsrc" 2>/dev/null \
|
|
| awk '$2=="disk"{print $1; exit}' | grep -oE '/dev/[a-z0-9]+')"
|
|
[ -n "$disk" ] || { echo "[FWS] Disque BIOS introuvable pour '$rootsrc'"; return 1; }
|
|
grub-install --target=i386-pc --recheck "$disk"
|
|
fi
|
|
}
|
|
if install_grub; then
|
|
grub-mkconfig -o /boot/grub/grub.cfg || echo "[FWS] grub-mkconfig a échoué"
|
|
else
|
|
echo "[FWS] AVERTISSEMENT : grub-install a échoué — bootloader à refaire à la main"
|
|
fi
|
|
|
|
# --- 3bis) Clavier (X11) + LOCALE --------------------------------------------
|
|
# CLAVIER : Anaconda passe par localed et n'écrit pas fiablement la disposition X
|
|
# sur la CIBLE → SDDM / sessions X en QWERTY US. On CALCULE la disposition CHOISIE
|
|
# (kickstart généré, sinon dérivée de la locale via langtable) en XL/XV, réutilisés
|
|
# plus bas (00-keyboard.conf pour SDDM/X ET la config Hyprland qui a son propre
|
|
# kb_layout). LOCALE : le locale choisi (ex. fr_CH.UTF-8) doit être GÉNÉRÉ —
|
|
# Anaconda vient de Fedora (locales pré-générées) et ne lance pas locale-gen →
|
|
# sans ça LANG casse et tout retombe en C.
|
|
XL=""; XV=""
|
|
XKB="$(sed -n "s/.*--xlayouts=//p" /root/anaconda-ks.cfg 2>/dev/null | head -1)"
|
|
XKB="${XKB#[\'\"]}"; XKB="${XKB%%[\'\"]*}"; XKB="${XKB%%,*}" # 1re dispo, ex. « ch (fr) »
|
|
if [ -z "$XKB" ]; then
|
|
_loc="$(. /etc/locale.conf 2>/dev/null; printf '%s' "${LANG%%.*}")" # fr_CH
|
|
_lng="${_loc%%_*}"; _terr="${_loc#*_}"; [ "$_terr" = "$_loc" ] && _terr=""
|
|
[ -n "$_terr" ] && XKB="$(python3 -c "import langtable; k=langtable.list_keyboards(languageId='$_lng', territoryId='$_terr'); print(k[0] if k else '')" 2>/dev/null)"
|
|
fi
|
|
if [ -n "$XKB" ]; then
|
|
XL="${XKB%%(*}"; XL="${XL%% *}" # ch
|
|
case "$XKB" in *'('*')') XV="${XKB#*(}"; XV="${XV%)}" ;; *) XV="" ;; esac # fr
|
|
install -d /etc/X11/xorg.conf.d
|
|
cat > /etc/X11/xorg.conf.d/00-keyboard.conf <<KBEOF
|
|
Section "InputClass"
|
|
Identifier "system-keyboard"
|
|
MatchIsKeyboard "on"
|
|
Option "XkbLayout" "$XL"
|
|
Option "XkbVariant" "$XV"
|
|
EndSection
|
|
KBEOF
|
|
fi
|
|
|
|
FWSLANG="$(. /etc/locale.conf 2>/dev/null; printf '%s' "${LANG:-}")"
|
|
if [ -n "$FWSLANG" ]; then
|
|
_cs="${FWSLANG##*.}"; [ "$_cs" = "$FWSLANG" ] && _cs="UTF-8"
|
|
grep -qE "^[[:space:]]*${FWSLANG}[[:space:]]+${_cs}\b" /etc/locale.gen 2>/dev/null \
|
|
|| printf '%s %s\n' "$FWSLANG" "$_cs" >> /etc/locale.gen
|
|
locale-gen || echo "[FWS] locale-gen a échoué pour $FWSLANG"
|
|
fi
|
|
|
|
# --- 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=""
|
|
case "$DESK" in
|
|
kde) PKGS="plasma-meta sddm konsole dolphin"; DM="sddm" ;;
|
|
gnome) PKGS="gnome gdm"; DM="gdm" ;;
|
|
# noto-fonts : KDE l'a via plasma-meta et GNOME a cantarell, mais XFCE et
|
|
# Hyprland ne garantissent AUCUNE police TTF → greeter SDDM/apps illisibles.
|
|
# Hyprland : la stack des raccourcis FWS (mêmes touches que la config
|
|
# i3/sway maison) — thunar (Super+E), hyprlock (Super+L), grim+slurp+
|
|
# wl-clipboard (captures), playerctl (touches multimédia) — plus la
|
|
# plomberie de bureau : mako+libnotify (notifications), polkit-gnome
|
|
# (agent d'authentification GUI), network-manager-applet (réseau dans le
|
|
# tray), xdg-desktop-portal-hyprland (partage d'écran/portails), gvfs
|
|
# (montage USB dans thunar), ttf-nerd-fonts-symbols (icônes waybar).
|
|
# Son et Bluetooth GARANTIS avec le bureau : la stack PipeWire + le
|
|
# mixeur (pavucontrol) + bluez/blueman partent dans la MÊME transaction
|
|
# pacman que le DE — si le bureau s'installe, ses gestionnaires aussi
|
|
# (fws-setup-hardware les re-propose ensuite en --needed : sans effet
|
|
# s'ils sont déjà là, filet de secours sinon).
|
|
xfce) PKGS="xfce4 xfce4-goodies sddm noto-fonts pipewire pipewire-pulse wireplumber pavucontrol"; DM="sddm" ;;
|
|
hyprland) PKGS="hyprland kitty wofi waybar sddm noto-fonts thunar hyprlock grim slurp wl-clipboard playerctl mako libnotify polkit-gnome network-manager-applet xdg-desktop-portal-hyprland gvfs ttf-nerd-fonts-symbols pipewire pipewire-alsa pipewire-pulse wireplumber pavucontrol bluez bluez-utils blueman"; DM="sddm" ;;
|
|
cli|*) PKGS="" ;;
|
|
esac
|
|
# Navigateur de base ajouté DÈS QU'un bureau est choisi (jamais en CLI).
|
|
[ -n "$PKGS" ] && PKGS="$PKGS firefox"
|
|
if [ -n "$PKGS" ]; then
|
|
pacman-key --init &>/dev/null || true
|
|
pacman-key --populate archlinux &>/dev/null || true
|
|
if pacman -Sy --noconfirm $PKGS; then
|
|
[ -n "$DM" ] && systemctl enable "$DM" || true
|
|
systemctl set-default graphical.target || true
|
|
# SDDM (KDE / XFCE / Hyprland) : pavé numérique + écran de connexion FWS.
|
|
# Le thème « fws » (livré par l'airootfs → recopié par le payload dans
|
|
# /usr/share/sddm/themes/fws) est en pur QtQuick/Controls Basic :
|
|
# qt6-declarative, dépendance de sddm, suffit → même écran soigné pour
|
|
# les 3 DE SANS paquet de thème supplémentaire (Breeze n'existe qu'avec
|
|
# plasma). Accent adapté au bureau via theme.conf.user (mécanisme de
|
|
# surcharge standard de SDDM, lu par-dessus theme.conf du thème).
|
|
if [ "$DM" = "sddm" ]; then
|
|
install -d /etc/sddm.conf.d
|
|
cat > /etc/sddm.conf.d/10-fws.conf <<'SDDMEOF'
|
|
[General]
|
|
Numlock=on
|
|
|
|
[Theme]
|
|
Current=fws
|
|
SDDMEOF
|
|
case "$DESK" in
|
|
xfce) _ACCENT="#16a085" ;; # sarcelle (assorti à XFCE)
|
|
hyprland) _ACCENT="#89b4fa" ;; # bleu Catppuccin (assorti à Hyprland)
|
|
*) _ACCENT="#3daee9" ;; # bleu Breeze (KDE, défaut)
|
|
esac
|
|
if [ -d /usr/share/sddm/themes/fws ]; then
|
|
printf '[General]\naccent=%s\n' "$_ACCENT" \
|
|
> /usr/share/sddm/themes/fws/theme.conf.user
|
|
else
|
|
echo "[FWS] thème SDDM fws introuvable — thème par défaut conservé"
|
|
sed -i '/^Current=fws$/d' /etc/sddm.conf.d/10-fws.conf
|
|
fi
|
|
fi
|
|
# GDM (GNOME) : « la même chose » autant que possible — le greeter de
|
|
# GDM EST GNOME Shell, il ne se thème pas comme SDDM. On passe par
|
|
# dconf (base système « gdm ») : bannière d'accueil FWS, horloge avec
|
|
# date complète, pavé numérique allumé — même confort qu'avec SDDM.
|
|
if [ "$DM" = "gdm" ]; then
|
|
install -d /etc/dconf/profile /etc/dconf/db/gdm.d
|
|
cat > /etc/dconf/profile/gdm <<'GDMEOF'
|
|
user-db:user
|
|
system-db:gdm
|
|
file-db:/usr/share/gdm/greeter-dconf-defaults
|
|
GDMEOF
|
|
cat > /etc/dconf/db/gdm.d/10-fws <<'GDMEOF'
|
|
[org/gnome/login-screen]
|
|
banner-message-enable=true
|
|
banner-message-text='Bienvenue sur FWS'
|
|
|
|
[org/gnome/desktop/interface]
|
|
clock-show-date=true
|
|
clock-show-weekday=true
|
|
|
|
[org/gnome/desktop/peripherals/keyboard]
|
|
numlock-state=true
|
|
remember-numlock-state=false
|
|
GDMEOF
|
|
dconf update || echo "[FWS] dconf update a échoué (bannière GDM à refaire)"
|
|
fi
|
|
# Hyprland en VM : sur GPU virtuel (VMware/VirtualBox) le compositeur
|
|
# crashe au lancement → SDDM « remet au login ». On le lance via un
|
|
# wrapper qui force le rendu LOGICIEL UNIQUEMENT en VM (systemd-detect-virt)
|
|
# ; sur un vrai GPU le rendu matériel est conservé.
|
|
if [ "$DESK" = "hyprland" ]; then
|
|
cat > /usr/local/bin/fws-hyprland <<'HYEOF'
|
|
#!/bin/sh
|
|
if systemd-detect-virt --quiet 2>/dev/null; then
|
|
# GPU virtuel (VMware vmwgfx…) : on FORCE le chemin d'affichage 100% logiciel.
|
|
# La PIÈCE MAÎTRESSE est MESA_LOADER_DRIVER_OVERRIDE=kms_swrast : elle force
|
|
# Mesa à allouer le GBM/EGL via kms_swrast (rendu logiciel dans les « dumb
|
|
# buffers » KMS) AU LIEU du pilote vmwgfx (qui ne fournit pas le GBM dont
|
|
# aquamarine a besoin → « CBackend::create() failed »). + llvmpipe pour le GL.
|
|
export MESA_LOADER_DRIVER_OVERRIDE=kms_swrast
|
|
export GALLIUM_DRIVER=llvmpipe LIBGL_ALWAYS_SOFTWARE=1
|
|
export WLR_RENDERER_ALLOW_SOFTWARE=1 WLR_NO_HARDWARE_CURSORS=1
|
|
export AQ_NO_ATOMIC=1
|
|
fi
|
|
# Hyprland ≥ 0.53 : start-hyprland est le lanceur officiel (prépare la
|
|
# session/env systemd) — sans lui, bandeau « started without start-hyprland ».
|
|
if command -v start-hyprland >/dev/null 2>&1; then
|
|
exec start-hyprland "$@"
|
|
fi
|
|
exec Hyprland "$@"
|
|
HYEOF
|
|
chmod 755 /usr/local/bin/fws-hyprland
|
|
if [ -f /usr/share/wayland-sessions/hyprland.desktop ]; then
|
|
sed -i 's|^Exec=.*|Exec=/usr/local/bin/fws-hyprland|' \
|
|
/usr/share/wayland-sessions/hyprland.desktop
|
|
fi
|
|
# Bluetooth prêt au 1er démarrage (bluez vient d'être installé
|
|
# avec le bureau ; fws-setup-hardware le refait — idempotent).
|
|
systemctl enable bluetooth.service 2>/dev/null || true
|
|
fi
|
|
else
|
|
echo "[FWS] Bureau '$DESK' non installé (réseau ?) — à refaire après le 1er boot."
|
|
fi
|
|
fi
|
|
|
|
# --- 4quater) ADN FWS : détection matériel + drivers + stack « Windows » ------
|
|
# Script dédié (NON bloquant ; réseau requis) : drivers GPU détectés via lspci +
|
|
# outils invité VM, son/micro/casque (PipeWire), Bluetooth, Podman, et — si un
|
|
# bureau est choisi — Steam, Wine, VR (Monado/SteamVR), winboat-bin (apps
|
|
# Windows). C'est le cœur « remplacement de Windows » de FWS.
|
|
if [ -x /usr/local/bin/fws-setup-hardware ]; then
|
|
/usr/local/bin/fws-setup-hardware "$DESK" || true
|
|
fi
|
|
|
|
# --- Config Hyprland (si choisi) : clavier + apps + waybar -------------------
|
|
# Hyprland (Wayland) NE lit PAS /etc/X11/xorg.conf.d/00-keyboard.conf : sa
|
|
# disposition est dans SA config (input { kb_layout }). Sans config il démarre nu
|
|
# (QWERTY US, aucune touche utile). On déploie une config FWS (template +
|
|
# clavier XL/XV injecté) dans /etc/skel ET le home de chaque utilisateur déjà
|
|
# créé par Anaconda (le %post tourne APRÈS la création de l'utilisateur).
|
|
if [ "$DESK" = "hyprland" ] && [ -f /usr/local/share/fws/hyprland.conf.tmpl ]; then
|
|
sed -e "s/__KB_LAYOUT__/${XL:-us}/" -e "s/__KB_VARIANT__/${XV}/" \
|
|
/usr/local/share/fws/hyprland.conf.tmpl > /tmp/fws-hyprland.conf
|
|
install -Dm644 /tmp/fws-hyprland.conf /etc/skel/.config/hypr/hyprland.conf
|
|
# Waybar FWS : barre assortie + bouton « ⌨ Raccourcis » (fws-hypr-keys,
|
|
# aussi sur SUPER+K) qui liste les binds RÉELS chargés par Hyprland
|
|
# (hyprctl binds -j) — les descriptions viennent des bindd de la config.
|
|
install -Dm644 /usr/local/share/fws/waybar-config.json /etc/skel/.config/waybar/config
|
|
install -Dm644 /usr/local/share/fws/waybar-style.css /etc/skel/.config/waybar/style.css
|
|
# wofi : style du menu d'applications (Super+R) — le panneau « Raccourcis »
|
|
# a son propre style (wofi-keys.css), passé en --style par fws-hypr-keys.
|
|
install -Dm644 /usr/local/share/fws/wofi-config /etc/skel/.config/wofi/config
|
|
install -Dm644 /usr/local/share/fws/wofi-style.css /etc/skel/.config/wofi/style.css
|
|
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
|
|
[ "$_uid" -ge 1000 ] && [ "$_uid" -le 60000 ] && [ -d "$_home" ] || continue
|
|
install -Dm644 /tmp/fws-hyprland.conf "$_home/.config/hypr/hyprland.conf"
|
|
install -Dm644 /usr/local/share/fws/waybar-config.json "$_home/.config/waybar/config"
|
|
install -Dm644 /usr/local/share/fws/waybar-style.css "$_home/.config/waybar/style.css"
|
|
install -Dm644 /usr/local/share/fws/wofi-config "$_home/.config/wofi/config"
|
|
install -Dm644 /usr/local/share/fws/wofi-style.css "$_home/.config/wofi/style.css"
|
|
chown "$_u": "$_home/.config" 2>/dev/null || true
|
|
chown -R "$_u": "$_home/.config/hypr" "$_home/.config/waybar" \
|
|
"$_home/.config/wofi" 2>/dev/null || true
|
|
done < /etc/passwd
|
|
rm -f /tmp/fws-hyprland.conf
|
|
fi
|
|
|
|
# --- 4bis) Sudo : l'utilisateur créé doit pouvoir administrer -----------------
|
|
# Arch laisse « %wheel » COMMENTÉ dans sudoers → même un membre de wheel ne peut
|
|
# pas sudo. On active le groupe wheel (drop-in) ET on y ajoute tous les
|
|
# utilisateurs HUMAINS (UID 1000-60000) créés par Anaconda → ils sont sudoers.
|
|
install -d -m 750 /etc/sudoers.d
|
|
printf '%%wheel ALL=(ALL:ALL) ALL\n' > /etc/sudoers.d/10-fws-wheel
|
|
chmod 440 /etc/sudoers.d/10-fws-wheel
|
|
while IFS=: read -r _u _x _uid _rest; do
|
|
if [ "$_uid" -ge 1000 ] && [ "$_uid" -le 60000 ]; then
|
|
usermod -aG wheel "$_u" 2>/dev/null || true
|
|
fi
|
|
done < /etc/passwd
|
|
|
|
# --- 4ter) Branding FWS sur le système installé -------------------------------
|
|
# Le hook os-release du build n'est PAS sur la cible et « pacman -S » a pu
|
|
# remettre l'os-release d'Arch → d'où « Arch Linux » au menu GRUB, le logo Arch
|
|
# sur l'écran de connexion (GDM lit os-release LOGO) et le nom « Arch ». On FORCE
|
|
# donc l'os-release FWS (+ lsb-release + GRUB_DISTRIBUTOR), on RÉGÉNÈRE le menu
|
|
# GRUB (10_linux lit le NAME d'os-release), et on retire le motd « live ».
|
|
if [ -f /usr/local/share/fws/os-release ]; then
|
|
cp -f /usr/local/share/fws/os-release /usr/lib/os-release
|
|
ln -sf ../usr/lib/os-release /etc/os-release
|
|
fi
|
|
if [ -f /etc/lsb-release ]; then
|
|
sed -i 's/^DISTRIB_ID=.*/DISTRIB_ID=FWS/; s/^DISTRIB_DESCRIPTION=.*/DISTRIB_DESCRIPTION="FWS Linux"/' \
|
|
/etc/lsb-release
|
|
fi
|
|
if grep -q '^GRUB_DISTRIBUTOR=' /etc/default/grub 2>/dev/null; then
|
|
sed -i 's/^GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR="FWS"/' /etc/default/grub
|
|
else
|
|
echo 'GRUB_DISTRIBUTOR="FWS"' >> /etc/default/grub
|
|
fi
|
|
grub-mkconfig -o /boot/grub/grub.cfg 2>/dev/null || true
|
|
# motd « live » (texte inadapté + codes ANSI bruts affichés crus par GDM).
|
|
rm -f /etc/motd
|
|
|
|
# --- 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
|
|
|
|
# --- 6) DNS du système installé : NetworkManager + systemd-resolved ----------
|
|
# Le live utilise systemd-resolved (/etc/resolv.conf → stub 127.0.0.53). L'ANCIEN
|
|
# « rm /etc/resolv.conf » comptait sur NM pour recréer le fichier — MAIS avec
|
|
# systemd-resolved actif, NM ne réécrit PAS resolv.conf (il pousse les DNS vers
|
|
# resolved). Sans le lien, la résolution est MORTE → « Limited Connectivity » /
|
|
# Firefox « Server Not Found » (le réseau marche, le DNS non). Fix robuste :
|
|
# - resolv.conf → stub systemd-resolved,
|
|
# - service systemd-resolved activé,
|
|
# - on FORCE NM à utiliser resolved (dns=systemd-resolved) → il lui fournit les
|
|
# DNS DHCP, la résolution marche dès le 1er boot.
|
|
rm -f /tmp/fws-desktop 2>/dev/null || true
|
|
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
|
|
systemctl enable systemd-resolved.service 2>/dev/null || true
|
|
install -d /etc/NetworkManager/conf.d
|
|
printf '[main]\ndns=systemd-resolved\n' > /etc/NetworkManager/conf.d/dns.conf
|
|
%end
|
|
|
|
|
|
# ============================================================================
|
|
# %post --nochroot (FINAL) — exfiltre le log du %post chrooté vers le LIVE.
|
|
# À ce stade la cible est ENCORE montée sous /mnt/sysroot (l'unmount n'a pas
|
|
# encore eu lieu). On copie /var/log/fws-post.log (résultat de grub-install /
|
|
# mkinitcpio) vers le live /tmp pour que le harnais de debug (.xinitrc)
|
|
# l'affiche SANS avoir à remonter le disque démonté — c'est ce log qui dit si
|
|
# le disque va booter.
|
|
# ============================================================================
|
|
%post --nochroot
|
|
SYSROOT=/mnt/sysroot
|
|
[ -d "$SYSROOT" ] || SYSROOT=/mnt/sysimage
|
|
cp -f "$SYSROOT/var/log/fws-post.log" /tmp/fws-post-chroot.log 2>/dev/null || true
|
|
%end
|