feat(Installer): Add Multi Desktop environnement in the installer to allow the user to choose wich desktop env

This commit is contained in:
2026-05-27 19:22:42 +02:00
parent a9d4b9ac91
commit f6ee07429b
23 changed files with 358 additions and 25 deletions
+12 -3
View File
@@ -5,7 +5,16 @@ export MSYS_NO_PATHCONV=1
set -e set -e
trap 'echo -e "\e[31mErreur lors de l execution (build.sh).\e[0m"; exit 1' ERR trap 'echo -e "\e[31mErreur lors de l execution (build.sh).\e[0m"; exit 1' ERR
DISTRO_NAME="Arch" DISTRO_NAME="${ARCH_WSL_DISTRO:-Arch}"
# Auto-détection si la distro par défaut est inaccessible
if [ -z "$IN_WSL" ] && ! wsl.exe -d "$DISTRO_NAME" -u root -- echo ok >/dev/null 2>&1; then
for _name in "Arch" "ArchLinux" "archlinux" "arch" "ArchWSL"; do
if wsl.exe -d "$_name" -u root -- echo ok >/dev/null 2>&1; then
DISTRO_NAME="$_name"; break
fi
done
fi
if [ -n "$WSL_DISTRO_NAME" ]; then if [ -n "$WSL_DISTRO_NAME" ]; then
echo -e "\e[36mBuild exécuté depuis WSL ($WSL_DISTRO_NAME) en tant que root...\e[0m" echo -e "\e[36mBuild exécuté depuis WSL ($WSL_DISTRO_NAME) en tant que root...\e[0m"
@@ -28,9 +37,9 @@ WORK_DIR="${WORK_DIR_WSL}"
echo "==> Dossier de travail : \$WORK_DIR" echo "==> Dossier de travail : \$WORK_DIR"
echo "==> Mise à jour des miroirs et installation de archiso..." echo "==> Mise à jour des miroirs et installation de archiso..."
pacman -Sy --noconfirm reflector || true pacman -Syu --noconfirm reflector || true
reflector --verbose --latest 10 --sort rate --save /etc/pacman.d/mirrorlist || true reflector --verbose --latest 10 --sort rate --save /etc/pacman.d/mirrorlist || true
pacman -Sy --noconfirm archiso pacman -Syu --noconfirm archiso
echo "==> Préparation de l'environnement de build..." echo "==> Préparation de l'environnement de build..."
rm -rf /tmp/fws-build rm -rf /tmp/fws-build
@@ -1,8 +1,65 @@
--- ---
# Minimal Calamares view module config for desktop selection # Module packagechooser : sélection d'environnement de bureau
# This tells Calamares to use our QML page from the branding folder. # Un seul choix possible (boutons radio)
module: view
name: desktop mode: required
qml: "branding/fws/desktop.qml" id: desktop
title: "Choix de l'environnement"
description: "Sélectionne le bureau à installer" items:
- id: xfce
packages: []
name:
- locale: ""
value: "Xfce (Recommandé)"
description:
- locale: ""
value: "Léger, rapide et stable — déjà inclus dans l'ISO, aucun téléchargement."
- id: kde
packages:
- plasma-meta
- konsole
- dolphin
- sddm
name:
- locale: ""
value: "KDE Plasma"
description:
- locale: ""
value: "Bureau moderne, riche en fonctionnalités et très personnalisable."
- id: gnome
packages:
- gnome
- gdm
name:
- locale: ""
value: "GNOME"
description:
- locale: ""
value: "Interface épurée centrée sur la productivité."
- id: hyprland
packages:
- hyprland
- xdg-desktop-portal-hyprland
- xdg-desktop-portal-gtk
- waybar
- wofi
- kitty
- swaybg
- swayidle
- swaylock
- xorg-xwayland
- wl-clipboard
- grim
- slurp
- qt5-wayland
- qt6-wayland
- sddm
name:
- locale: ""
value: "Hyprland"
description:
- locale: ""
value: "Compositeur Wayland dynamique — tiling Wayland (utilisateurs avancés)."
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""
Calamares job : lit le choix de bureau depuis GlobalStorage
(packagechooser_desktop) et l'écrit dans /run/fws-desktop pour
que shellprocess puisse appeler le bon fws-desktop-init-*.
"""
import libcalamares
VALID_DESKTOPS = {"xfce", "kde", "gnome", "hyprland"}
FALLBACK = "xfce"
def pretty_name():
return "Sauvegarde du choix d'environnement de bureau"
def run():
gs = libcalamares.globalstorage
raw = gs.value("packagechooser_desktop")
# packagechooser peut renvoyer une str ou une liste selon la version
if isinstance(raw, list):
choice = raw[0] if raw else FALLBACK
elif isinstance(raw, str):
choice = raw.strip()
else:
choice = FALLBACK
if choice not in VALID_DESKTOPS:
choice = FALLBACK
try:
with open("/run/fws-desktop", "w") as fh:
fh.write(choice)
except OSError as exc:
return (
"Impossible d'écrire /run/fws-desktop",
f"{exc}\nLe bureau sera xfce par défaut.",
)
libcalamares.utils.debug(f"fws-desktop-choice : bureau sélectionné = {choice}")
return None
@@ -0,0 +1,5 @@
---
type: "job"
name: "fws-desktop-choice"
interface: "python"
script: "main.py"
@@ -1,13 +1,11 @@
--- ---
# Étape post-unpackfs : retire les paquets live-only.
# Tous les paquets utiles sont déjà dans le squashfs.
# Pas besoin d'installer quoi que ce soit depuis internet.
backend: pacman backend: pacman
update_db: false update_db: true
update_system: false update_system: false
operations: operations:
- install:
- packagechooser_desktop
- remove: - remove:
- calamares - calamares
- kpmcore - kpmcore
@@ -1,21 +1,24 @@
--- ---
# Exécuté HORS chroot (live system) pour accéder à l'ISO montée. # Exécuté HORS chroot (live system) pour accéder à l'ISO montée.
# But : restaurer le kernel (retiré du squashfs par mkarchiso) et # But : restaurer le kernel, détecter le bureau installé, lancer son init.
# corriger les fichiers mkinitcpio archiso-spécifiques.
dontChroot: true dontChroot: true
script: script:
# Copie le kernel depuis l'ISO vers /boot du système cible # Copie le kernel depuis l'ISO vers /boot du système cible
- 'cp "$(find /run/archiso/bootmnt -name vmlinuz-linux 2>/dev/null | head -1)" "${ROOT}/boot/vmlinuz-linux"' - 'cp "$(find /run/archiso/bootmnt -name vmlinuz-linux 2>/dev/null | head -1)" "${ROOT}/boot/vmlinuz-linux"'
- 'DESKTOP="$(cat /run/fws-desktop 2>/dev/null || printf xfce)"'
- 'if [ -z "$DESKTOP" ]; then DESKTOP="xfce"; fi'
- 'if [ ! -f "${ROOT}/usr/local/bin/fws-desktop-init-$DESKTOP" ]; then echo "Script bureau introuvable: $DESKTOP" >&2; exit 1; fi'
- 'chroot "${ROOT}" /bin/bash "/usr/local/bin/fws-desktop-init-$DESKTOP"'
# Supprime le drop-in archiso (surcharge HOOKS avec des hooks inexistants post-install) # Détecte le bureau installé en vérifiant les binaires présents dans la cible.
# (packagechooser a déjà installé les paquets via le module packages)
# Xfce est toujours présent (squashfs) donc on le garde en fallback.
- 'if [ -f "${ROOT}/usr/bin/plasmashell" ]; then DESKTOP=kde; elif [ -f "${ROOT}/usr/bin/gnome-shell" ]; then DESKTOP=gnome; elif [ -f "${ROOT}/usr/bin/hyprland" ]; then DESKTOP=hyprland; else DESKTOP=xfce; fi'
# Lance le script d'initialisation du bureau choisi
- 'if [ ! -f "${ROOT}/usr/local/bin/fws-desktop-init-${DESKTOP}" ]; then echo "Script introuvable pour le bureau: ${DESKTOP}" >&2; exit 1; fi'
- 'chroot "${ROOT}" /bin/bash "/usr/local/bin/fws-desktop-init-${DESKTOP}"'
# Supprime le drop-in archiso (surcharge HOOKS inexistants post-install)
- 'rm -f "${ROOT}/etc/mkinitcpio.conf.d/archiso.conf"' - 'rm -f "${ROOT}/etc/mkinitcpio.conf.d/archiso.conf"'
# Remplace le linux.preset archiso par le preset standard (default + fallback) # Remplace le linux.preset archiso par le preset standard (default + fallback)
# \x27 = ' et \x22 = " pour éviter les conflits de quotes dans YAML/bash
- 'printf "PRESETS=(\x27default\x27 \x27fallback\x27)\nALL_kver=\x22/boot/vmlinuz-linux\x22\nALL_config=\x22/etc/mkinitcpio.conf\x22\nALL_microcode=(/boot/*-ucode.img)\ndefault_image=\x22/boot/initramfs-linux.img\x22\nfallback_image=\x22/boot/initramfs-linux-fallback.img\x22\nfallback_options=\x22-S autodetect\x22\n" > "${ROOT}/etc/mkinitcpio.d/linux.preset"' - 'printf "PRESETS=(\x27default\x27 \x27fallback\x27)\nALL_kver=\x22/boot/vmlinuz-linux\x22\nALL_config=\x22/etc/mkinitcpio.conf\x22\nALL_microcode=(/boot/*-ucode.img)\ndefault_image=\x22/boot/initramfs-linux.img\x22\nfallback_image=\x22/boot/initramfs-linux-fallback.img\x22\nfallback_options=\x22-S autodetect\x22\n" > "${ROOT}/etc/mkinitcpio.d/linux.preset"'
@@ -12,7 +12,7 @@ sequence:
- keyboard - keyboard
- partition - partition
- users - users
- desktop - packagechooser@desktop
- summary - summary
- exec: - exec:
- partition - partition
@@ -0,0 +1,12 @@
[Unit]
Description=FWS Installer (Calamares)
After=display-manager.service
Requires=display-manager.service
[Service]
Type=simple
ExecStartPre=/bin/sh -c 'DISPLAY=:0 xhost +local:root 2>/dev/null || true'
ExecStart=/usr/bin/calamares
[Install]
WantedBy=graphical.target
@@ -0,0 +1,33 @@
#!/bin/bash
# Sélection de l'environnement de bureau AVANT le démarrage de Calamares.
# Les services systemd n'héritent pas de $DISPLAY — on force :0 (session Xorg live).
export DISPLAY=":0"
DESKTOP="xfce" # valeur par défaut si zenity échoue
CHOICE=$(zenity \
--list \
--title="FWS — Environnement de bureau" \
--text="Quel environnement de bureau souhaitez-vous installer ?" \
--column="Environnement" \
--column="Description" \
--width=580 \
--height=340 \
"Xfce (Recommandé)" "Léger et rapide — idéal pour tous les systèmes" \
"KDE Plasma" "Moderne, riche en fonctionnalités et personnalisable" \
"GNOME" "Interface épurée centrée sur la productivité" \
"Hyprland" "Compositeur Wayland dynamique (utilisateurs avancés)" \
2>/dev/null) || true
case "${CHOICE:-}" in
"Xfce (Recommandé)") DESKTOP="xfce" ;;
"KDE Plasma") DESKTOP="kde" ;;
"GNOME") DESKTOP="gnome" ;;
"Hyprland") DESKTOP="hyprland" ;;
*) DESKTOP="xfce" ;;
esac
printf '%s' "$DESKTOP" > /run/fws-desktop
exec /usr/bin/calamares "$@"
@@ -0,0 +1,68 @@
#!/bin/bash
set -euo pipefail
fws_first_user() {
awk -F: '$3 >= 1000 && $1 != "nobody" { print $1; exit }' /etc/passwd
}
fws_install_packages() {
pacman -Sy --noconfirm --needed "$@"
}
fws_enable_services() {
for service in "$@"; do
systemctl enable "$service" >/dev/null 2>&1 || true
done
}
fws_disable_services() {
for service in "$@"; do
systemctl disable "$service" >/dev/null 2>&1 || true
done
}
fws_write_dmrc() {
local user_name="$1"
local session_name="$2"
if [ -n "$user_name" ] && [ -d "/home/$user_name" ]; then
printf '[Desktop]\nSession=%s\n' "$session_name" > "/home/$user_name/.dmrc"
fi
}
fws_write_lightdm_config() {
local user_name="$1"
local session_name="$2"
if [ -z "$user_name" ]; then
return 0
fi
mkdir -p /etc/lightdm/lightdm.conf.d
printf '[Seat:*]\nautologin-user=%s\nautologin-user-timeout=0\nuser-session=%s\nautologin-session=%s\ngreeter-hide-users=true\nallow-guest=false\n' \
"$user_name" "$session_name" "$session_name" \
> /etc/lightdm/lightdm.conf.d/50-fws.conf
}
fws_write_sddm_config() {
local user_name="$1"
local session_name="$2"
if [ -z "$user_name" ]; then
return 0
fi
mkdir -p /etc/sddm.conf.d
printf '[Autologin]\nUser=%s\nSession=%s.desktop\nRelogin=false\n' \
"$user_name" "$session_name" \
> /etc/sddm.conf.d/50-fws.conf
}
# Paquets installés par défaut sur tous les bureaux
fws_install_base_apps() {
fws_install_packages firefox libreoffice-fresh mariadb mariadb-clients
# Initialise la base de données MariaDB
mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql \
>/dev/null 2>&1 || true
fws_enable_services mariadb.service
}
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
. /usr/local/bin/fws-desktop-init-common
first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages gnome sddm
fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service
fws_write_sddm_config "$first_user" gnome
fws_write_dmrc "$first_user" gnome
@@ -0,0 +1,15 @@
#!/bin/bash
set -euo pipefail
. /usr/local/bin/fws-desktop-init-common
first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages hyprland xdg-desktop-portal-hyprland xdg-desktop-portal-gtk \
waybar wofi kitty swaybg swayidle swaylock xorg-xwayland wl-clipboard \
grim slurp qt5-wayland qt6-wayland sddm
fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service
fws_write_sddm_config "$first_user" hyprland
fws_write_dmrc "$first_user" hyprland
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
. /usr/local/bin/fws-desktop-init-common
first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages plasma-meta konsole dolphin sddm
fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service
fws_write_sddm_config "$first_user" plasma
fws_write_dmrc "$first_user" plasma
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
. /usr/local/bin/fws-desktop-init-common
first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages xfce4 xfce4-goodies lightdm lightdm-gtk-greeter
fws_disable_services sddm.service gdm.service
fws_enable_services lightdm.service
fws_write_lightdm_config "$first_user" xfce
fws_write_dmrc "$first_user" xfce
+4
View File
@@ -106,6 +106,10 @@ kpmcore
qt5-base qt5-base
qt5-svg qt5-svg
qt6-base qt6-base
# Dépendances runtime du module packagechooser de Calamares
kcoreaddons
ki18n
kwidgetsaddons
# --- Agents VM (pratique pour tester l'ISO) --- # --- Agents VM (pratique pour tester l'ISO) ---
qemu-guest-agent qemu-guest-agent
+6
View File
@@ -16,4 +16,10 @@ airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size'
bootstrap_tarball_compression=(xz -9e) bootstrap_tarball_compression=(xz -9e)
file_permissions=( file_permissions=(
["/etc/shadow"]="0:0:400" ["/etc/shadow"]="0:0:400"
["/usr/local/bin/calamares-launcher"]="0:0:755"
["/usr/local/bin/fws-desktop-init-common"]="0:0:755"
["/usr/local/bin/fws-desktop-init-xfce"]="0:0:755"
["/usr/local/bin/fws-desktop-init-kde"]="0:0:755"
["/usr/local/bin/fws-desktop-init-gnome"]="0:0:755"
["/usr/local/bin/fws-desktop-init-hyprland"]="0:0:755"
) )
@@ -54,3 +54,11 @@ fws_write_sddm_config() {
mkdir -p /etc/sddm.conf.d mkdir -p /etc/sddm.conf.d
printf '[Autologin]\nUser=%s\nSession=%s.desktop\nRelogin=false\n' "$user_name" "$session_name" > /etc/sddm.conf.d/50-fws.conf printf '[Autologin]\nUser=%s\nSession=%s.desktop\nRelogin=false\n' "$user_name" "$session_name" > /etc/sddm.conf.d/50-fws.conf
} }
# Paquets installés par défaut sur tous les bureaux
fws_install_base_apps() {
fws_install_packages firefox libreoffice-fresh mariadb mariadb-clients
mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql \
>/dev/null 2>&1 || true
fws_enable_services mariadb.service
}
@@ -5,6 +5,7 @@ set -euo pipefail
first_user="$(fws_first_user)" first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages gnome sddm fws_install_packages gnome sddm
fws_disable_services lightdm.service gdm.service fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service fws_enable_services sddm.service
@@ -5,6 +5,7 @@ set -euo pipefail
first_user="$(fws_first_user)" first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages hyprland xdg-desktop-portal-hyprland xdg-desktop-portal-gtk waybar wofi kitty swaybg swayidle swaylock xorg-xwayland wl-clipboard grim slurp qt5-wayland qt6-wayland sddm fws_install_packages hyprland xdg-desktop-portal-hyprland xdg-desktop-portal-gtk waybar wofi kitty swaybg swayidle swaylock xorg-xwayland wl-clipboard grim slurp qt5-wayland qt6-wayland sddm
fws_disable_services lightdm.service gdm.service fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service fws_enable_services sddm.service
@@ -5,6 +5,7 @@ set -euo pipefail
first_user="$(fws_first_user)" first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages plasma-meta konsole dolphin sddm fws_install_packages plasma-meta konsole dolphin sddm
fws_disable_services lightdm.service gdm.service fws_disable_services lightdm.service gdm.service
fws_enable_services sddm.service fws_enable_services sddm.service
@@ -5,6 +5,7 @@ set -euo pipefail
first_user="$(fws_first_user)" first_user="$(fws_first_user)"
fws_install_base_apps
fws_install_packages xfce4 xfce4-goodies lightdm lightdm-gtk-greeter fws_install_packages xfce4 xfce4-goodies lightdm lightdm-gtk-greeter
fws_disable_services sddm.service gdm.service fws_disable_services sddm.service gdm.service
fws_enable_services lightdm.service fws_enable_services lightdm.service
+4
View File
@@ -105,6 +105,10 @@ kpmcore
qt5-base qt5-base
qt5-svg qt5-svg
qt6-base qt6-base
# Dépendances runtime du module packagechooser de Calamares
kcoreaddons
ki18n
kwidgetsaddons
# --- Agents VM (pratique pour tester l'ISO) --- # --- Agents VM (pratique pour tester l'ISO) ---
qemu-guest-agent qemu-guest-agent
+26 -1
View File
@@ -50,7 +50,7 @@ fi
# Vérifications # Vérifications
# ============================================================ # ============================================================
command -v pacman >/dev/null || error "pacman introuvable (lance depuis Arch / WSL)" command -v pacman >/dev/null || error "pacman introuvable (lance depuis Arch / WSL)"
[ "$EUID" -eq 0 ] || exec su -c "bash $0" root [ "$EUID" -eq 0 ] || exec su -c "bash '$0'" root
success "Arch Linux (root) ✓" success "Arch Linux (root) ✓"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -120,6 +120,31 @@ for pkg in "${AUR_PACKAGES[@]}"; do
su - "$BUILD_USER" -c "git clone https://aur.archlinux.org/${pkg}.git $BUILD_DIR/$pkg" \ su - "$BUILD_USER" -c "git clone https://aur.archlinux.org/${pkg}.git $BUILD_DIR/$pkg" \
|| error "Clonage $pkg échoué" || error "Clonage $pkg échoué"
# Patch spécifique au paquet calamares :
# — s'assurer que packagechooser n'est pas dans SKIP_MODULES
# — s'assurer que le support Python est activé
if [ "$pkg" = "calamares" ]; then
info "Patch du PKGBUILD calamares (activation packagechooser)…"
PKGBUILD_FILE="$BUILD_DIR/$pkg/PKGBUILD"
# Dépendances de build pour packagechooser
pacman -S --needed --noconfirm extra-cmake-modules kcoreaddons ki18n kwidgetsaddons
# Le PKGBUILD utilise un tableau bash : local _skip_modules=(... packagechooser ...)
# On supprime simplement les mots du fichier, quelle que soit la structure.
sed -i -E 's/\bpackagechooserq\b[[:space:]]?//g' "$PKGBUILD_FILE"
sed -i -E 's/\bpackagechooser\b[[:space:]]?//g' "$PKGBUILD_FILE"
# Vérification
if grep -qE '\bpackagechooser' "$PKGBUILD_FILE"; then
warn "packagechooser encore présent dans le PKGBUILD !"
grep -n 'packagechooser' "$PKGBUILD_FILE"
else
success "packagechooser retiré du SKIP_MODULES ✓"
fi
fi
info "Build $pkg (peut prendre plusieurs minutes)…" info "Build $pkg (peut prendre plusieurs minutes)…"
su - "$BUILD_USER" -c "cd $BUILD_DIR/$pkg && makepkg -s --noconfirm" \ su - "$BUILD_USER" -c "cd $BUILD_DIR/$pkg && makepkg -s --noconfirm" \
|| error "Build $pkg échoué" || error "Build $pkg échoué"