Compare commits

...
12 Commits
10 changed files with 306 additions and 79 deletions
+50
View File
@@ -0,0 +1,50 @@
name: Build and Test Custom Arch ISO
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
jobs:
build-iso:
runs-on: ubuntu-latest
container:
image: archlinux:latest
options: --privileged
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install build dependencies
run: |
pacman -Syu --noconfirm
pacman -S --noconfirm archiso git sudo base-devel fakeroot
- name: Create builder user
run: |
useradd -m -G wheel -s /bin/bash builder
echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
- name: Run ISO build script
run: |
chown -R builder:builder .
sudo -u builder bash ./build.sh
- name: Verify ISO creation
run: |
if [ -f out/*.iso ]; then
echo "ISO successfully built!"
ls -lh out/*.iso
else
echo "ISO build failed: No ISO file found in out/ directory."
exit 1
fi
- name: Upload ISO artifact
uses: actions/upload-artifact@v4
with:
name: arch-custom-iso
path: out/*.iso
retention-days: 7
+9
View File
@@ -13,6 +13,15 @@ work/
*.img
*.fs
# --- AJOUTS POUR LE HORS-LIGNE ---
# Dossiers temporaires de compilation (créés par build.sh)
offline_cache/
aur_build/
# Le cache des paquets générés dans l'arborescence de l'ISO (GROS FICHIERS)
airootfs/root/offline_cache/
# ---------------------------------
# Editor
.vscode/
.idea/
+2 -1
View File
@@ -13,6 +13,7 @@ This project allows you to generate a fully customized Arch Linux installation I
- Automated install scripts
- Custom configs (dotfiles, system settings)
- Reproducible builds
- Support for your own packages built from source
---
@@ -39,7 +40,7 @@ Run build script:
```bash
chmod +x build.sh
sudo ./build.sh
./build.sh
```
---
+8 -5
View File
@@ -216,7 +216,7 @@ hl.config({
hl.config({
input = {
kb_layout = "fr",
kb_layout = "__KB_LAYOUT__", -- MARQUEUR REMPLACÉ PAR LE SCRIPT BASH
kb_variant = "",
kb_model = "",
kb_options = "",
@@ -256,7 +256,7 @@ local mainMod = "SUPER" -- Sets "Windows" key as main modifier
hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal))
local closeWindowBind = hl.bind(mainMod .. " + W", hl.dsp.window.close())
-- closeWindowBind:set_enabled(false)
hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("command -v hyprshutdown >/dev/null 2>&1 && hyprshutdown || hyprctl dispatch 'hl.dsp.exit()'"))
hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("command -v hyprshutdown >/dev/null 2>&1 && hyprshutdown || hyprctl dispatch exit"))
hl.bind(mainMod .. " + F", hl.dsp.exec_cmd(fileManager))
hl.bind(mainMod .. " + T", hl.dsp.window.float({ action = "toggle" }))
hl.bind(mainMod .. " + SPACE", hl.dsp.exec_cmd(menu))
@@ -271,10 +271,13 @@ hl.bind(mainMod .. " + down", hl.dsp.focus({ direction = "down" }))
-- Switch workspaces with mainMod + [0-9]
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
-- CORRECTION : Utilisation des keycodes (code:10 à code:19) pour que ça marche sur AZERTY/QWERTY
for i = 1, 10 do
local key = i % 10 -- 10 maps to key 0
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i}))
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
local keycode = 9 + i -- 10=1, 11=2, 12=3 ... 18=9, 19=0
local key_str = "code:" .. keycode
hl.bind(mainMod .. " + " .. key_str, hl.dsp.exec_cmd("hyprctl dispatch workspace " .. i))
hl.bind(mainMod .. " + SHIFT + " .. key_str, hl.dsp.exec_cmd("hyprctl dispatch movetoworkspace " .. i))
end
-- Example special workspace (scratchpad)
+70 -59
View File
@@ -88,7 +88,6 @@ print_grid_menu() {
done
}
# Fonction pour échapper les caractères spéciaux JSON (Remplace jq)
json_escape() {
local s="$1"
s="${s//\\/\\\\}"
@@ -260,10 +259,7 @@ run_configurator() {
done
disk=$(echo "${DISKS[$((PAGE - 1))]}" | awk '{print $1}')
# --- 5. ENCRYPTION (FORCE ACTIVÉ) ---
local encrypt_installation="true"
# --- JSON GENERATION (100% BASH PUR) ---
# --- 5. JSON GENERATION ---
local pw_esc="\"$(json_escape "$password")\""
local hash_esc="\"$(json_escape "$password_hash")\""
local user_esc="\"$(json_escape "$username")\""
@@ -416,55 +412,60 @@ if [[ $(tty) == "/dev/tty1" ]]; then
echo "Installing base system..."
install_base_system
# --- 0. CONFIGURATION HORS-LIGNE ---
ISO_CACHE="/root/offline_cache"
# On monte le cache dans un dossier à part pour ne pas saturer la RAM
CHROOT_OFFLINE_DIR="/mnt/opt/offline_cache"
if [[ -d "$ISO_CACHE" && -n "$(ls -A $ISO_CACHE/*.pkg.tar.zst 2>/dev/null)" ]]; then
echo ">>> Mode HORS-LIGNE activé : Utilisation du cache de l'ISO"
mkdir -p "$CHROOT_OFFLINE_DIR"
mount --bind "$ISO_CACHE" "$CHROOT_OFFLINE_DIR"
else
echo ">>> Mode EN-LIGNE : Cache de l'ISO non trouvé, téléchargement depuis internet."
fi
# --- 1. INSTALLATION PACKAGES OFFICIELS ---
clear
echo "Installing Neovim, Ghostty and Hyprland..."
echo "Installing packages (Offline or Online)..."
EXTRA_PACKAGES=(
"neovim"
"ghostty"
"hyprland"
"xdg-desktop-portal-hyprland"
"git"
"yazi"
"dolphin"
"rofi"
"waybar"
"wiremix"
"impala"
"bluetui"
"btop"
"cava"
"fastfetch"
"obsidian"
"obs-studio"
"visual-studio-code-bin"
"lazygit"
"docker"
"docker-buildx"
"docker-compose"
"lazydocker"
"mpv"
"prismlauncher"
"rust"
"localsend"
"chromium"
"bat"
"base-devel"
"cmake"
"nodejs"
"npm"
"pnpm"
"python"
"python-pip"
"curl"
"wget"
"unzip"
"neovim" "ghostty" "hyprland" "xdg-desktop-portal-hyprland"
"git" "yazi" "dolphin" "rofi" "waybar" "wiremix" "impala"
"bluetui" "btop" "cava" "fastfetch" "obsidian" "obs-studio"
"lazygit" "docker" "docker-buildx" "docker-compose" "lazydocker"
"mpv" "prismlauncher" "rust" "chromium" "bat" "base-devel"
"cmake" "nodejs" "npm" "pnpm" "python" "python-pip"
"curl" "wget" "unzip"
)
arch-chroot /mnt pacman -S --noconfirm "${EXTRA_PACKAGES[@]}"
# On dit à pacman d'utiliser le disque dur pour écrire, et le dossier /opt/offline_cache pour LIRE les paquets pré-téléchargés
if [[ -d "$CHROOT_OFFLINE_DIR" ]]; then
arch-chroot /mnt pacman -S --noconfirm --cachedir /var/cache/pacman/pkg --cachedir /opt/offline_cache "${EXTRA_PACKAGES[@]}"
else
arch-chroot /mnt pacman -S --noconfirm "${EXTRA_PACKAGES[@]}"
fi
# --- 2. CONFIGURATION TTY AUTO-LOGIN ---
# --- 2. INSTALLATION PACKAGES AUR (HORS-LIGNE) ---
clear
echo "Installing pre-compiled AUR packages..."
for pkg in visual-studio-code-bin subtui-bin localsend-bin; do
# On cherche le nom exact du fichier depuis l'hôte
PKG_PATH=$(ls ${CHROOT_OFFLINE_DIR}/${pkg}*.pkg.tar.zst 2>/dev/null | head -n 1)
if [[ -n "$PKG_PATH" ]]; then
echo ">>> Installation de $pkg"
# On enlève "/mnt" du chemin pour que ça corresponde au point de vue du chroot
CHROOT_PKG_PATH="${PKG_PATH#/mnt}"
# On passe le chemin exact (sans étoile) à pacman
arch-chroot /mnt pacman -U --noconfirm "$CHROOT_PKG_PATH"
else
echo ">>> $pkg non trouvé, ignoré."
fi
done
# --- 3. CONFIGURATION TTY AUTO-LOGIN ---
echo "Configuring TTY auto-login for $username..."
mkdir -p /mnt/etc/systemd/system/getty@tty1.service.d
@@ -474,32 +475,42 @@ ExecStart=
ExecStart=-/sbin/agetty --autologin $username --noclear %I \$TERM
EOF
# --- 3. LANCEMENT AUTOMATIQUE DE HYPRLAND ---
# --- 4. LANCEMENT AUTOMATIQUE DE HYPRLAND ---
echo "Configuring auto-start Hyprland..."
cat > "/mnt/home/$username/.bash_profile" << 'EOF'
if [ -z "${DISPLAY}" ] && [ "$(tty)" = "/dev/tty1" ]; then
if [ -f /.arch-chroot ] || [ -n "$INSTALLING" ]; then
return 0 2>/dev/null || exit 0
fi
if [ -z "${DISPLAY:-}" ] && [ "$(tty 2>/dev/null)" = "/dev/tty1" ]; then
exec Hyprland
fi
EOF
chown 1000:1000 "/mnt/home/$username/.bash_profile"
# --- 4. COPIE DES DOTFILES ---
# --- 5. COPIE DES DOTFILES & INJECTION CLAVIER ---
clear
echo "Copying custom .config files..."
# On vérifie si le dossier .config existe bien à côté du script sur l'ISO
if [[ -d ".config" ]]; then
# On le copie dans le home de l'utilisateur sur le disque dur
cp -r .config "/mnt/home/$username/"
# On s'assure que l'utilisateur est bien le propriétaire (1000:1000 est le 1er user par défaut)
# On cherche dynamiquement le fichier .lua contenant le marqueur dans tout le dossier hypr
HYPRLAND_CONF=$(grep -rl "__KB_LAYOUT__" "/mnt/home/$username/.config/hypr/" 2>/dev/null | head -n 1)
if [[ -n "$HYPRLAND_CONF" ]]; then
# Utilisation de | comme délimiteur pour sed pour éviter les erreurs de parsing
sed -i "s|__KB_LAYOUT__|${keyboard}|g" "$HYPRLAND_CONF"
echo "Hyprland keyboard set to: $keyboard in $HYPRLAND_CONF"
else
echo "ERREUR: Marqueur __KB_LAYOUT__ introuvable dans les configs Hyprland !"
fi
chown -R 1000:1000 "/mnt/home/$username/.config"
echo "Dotfiles copied successfully!"
echo "Dotfiles configured successfully!"
else
echo "No .config folder found next to the script, skipping."
echo "No .config folder found, skipping."
fi
# --- REBOOT AUTOMATIQUE ---
# --- REBOOT ---
echo "Installation finished! Rebooting in 3 seconds..."
sleep 3
reboot
+114 -14
View File
@@ -1,37 +1,137 @@
#!/bin/bash
# Si l'utilisateur a oublié de mettre sudo, on redémarre le script avec sudo
if [ "$EUID" -ne 0 ]; then
echo "Le build nécessite les droits administrateur (sudo). Redémarrage..."
exec sudo bash "$0" "$@"
fi
set -e
ISO_NAME="arch-custom-iso"
# On récupère le nom de l'utilisateur normal (pas root) pour makepkg
BUILD_USER="${SUDO_USER:-root}"
CUSTOM_PKGS_DIR="$PWD/custom-pkgs"
# ==============================================================================
# LES LISTES DE PAQUETS
# ==============================================================================
EXTRA_PACKAGES=(
"neovim" "ghostty" "hyprland" "xdg-desktop-portal-hyprland"
"git" "yazi" "dolphin" "rofi" "waybar" "wiremix" "impala"
"bluetui" "btop" "cava" "fastfetch" "obsidian" "obs-studio"
"lazygit" "docker" "docker-buildx" "docker-compose" "lazydocker"
"mpv" "prismlauncher" "rust" "chromium" "bat" "base-devel"
"cmake" "nodejs" "npm" "pnpm" "python" "python-pip"
"curl" "wget" "unzip"
)
AUR_PACKAGES=(
"visual-studio-code-bin"
"subtui-bin"
"localsend-bin"
)
# ==============================================================================
# PROCESSUS DE BUILD
# ==============================================================================
echo "====================================="
echo " Building Arch Linux ISO"
echo " Project: $ISO_NAME"
echo " Build lancé par l'utilisateur: $BUILD_USER"
echo "====================================="
# Check archiso
if ! command -v mkarchiso &> /dev/null; then
echo "[ERROR] archiso is not installed"
echo "Run: sudo pacman -S archiso"
exit 1
fi
# Clean previous build
echo "[1/3] Cleaning previous build..."
rm -rf work out
echo "[1/5] Cleaning previous build..."
rm -rf work out offline_cache
# Build ISO
echo "[2/3] Building ISO..."
# --- TÉLÉCHARGEMENT DES PAQUETS OFFICIELS ---
echo "[2/6] Downloading Official Packages for offline cache..."
# On utilise /tmp pour éviter tout problème de permissions dans le Home
TMP_CACHE="/tmp/archiso_cache_$$"
mkdir -p "$TMP_CACHE"
sudo pacman -Sy --noconfirm
# On télécharge (-w) sans installer, dans le dossier temporaire
sudo pacman -Sw --noconfirm --cachedir "$TMP_CACHE" "${EXTRA_PACKAGES[@]}" || true
# On crée le vrai dossier de cache et on déplace les paquets
mkdir -p offline_cache
cp "$TMP_CACHE"/*.pkg.tar.zst offline_cache/ 2>/dev/null || true
rm -rf "$TMP_CACHE"
# --- COMPILATION DES PAQUETS PERSONNALISÉS ---
echo "[3/6] Building custom packages from custom-pkgs/..."
mkdir -p custom_pkg_build
for pkg_dir in "$CUSTOM_PKGS_DIR"/*; do
[ -d "$pkg_dir" ] || continue
[ -f "$pkg_dir/PKGBUILD" ] || continue
pkg_name=$(basename "$pkg_dir")
echo " -> Building custom package: $pkg_name"
rm -rf "custom_pkg_build/$pkg_name"
cp -a "$pkg_dir" "custom_pkg_build/$pkg_name"
chown -R "$BUILD_USER":"$BUILD_USER" "custom_pkg_build/$pkg_name"
sudo -u "$BUILD_USER" bash -lc "cd '$PWD/custom_pkg_build/$pkg_name' && makepkg -f --noconfirm --needed"
mv "custom_pkg_build/$pkg_name"/*.pkg.tar.zst offline_cache/ 2>/dev/null || true
done
rm -rf custom_pkg_build
# --- COMPILATION DES PAQUETS AUR ---
echo "[4/6] Building AUR Packages for offline cache..."
mkdir -p aur_build
for pkg in "${AUR_PACKAGES[@]}"; do
echo " -> Building AUR package: $pkg"
cd aur_build
rm -rf "$pkg"
git clone "https://aur.archlinux.org/${pkg}.git" --depth 1
# CRUCIAL : On donne les droits à l'utilisateur NORMAL pour que makepkg accepte de tourner
chown -R "$BUILD_USER":"$BUILD_USER" "$pkg"
cd "$pkg"
# CRUCIAL : On lance makepkg EN TANT QU'UTILISATEUR NORMAL (pas de -s pour éviter de reboucler sur sudo)
sudo -u "$BUILD_USER" makepkg -d -f --noconfirm --needed
# On déplace le paquet compilé dans notre cache
mv *.pkg.tar.zst ../../offline_cache/
cd ../..
done
rm -rf aur_build
# --- INJECTION DANS L'ISO ---
echo "[5/6] Injecting offline cache into ISO skeleton..."
mkdir -p airootfs/root/offline_cache
cp offline_cache/*.pkg.tar.zst airootfs/root/offline_cache/
rm -rf offline_cache
# Copier les scripts personnalisés dans la racine du live system si nécessaire
mkdir -p airootfs/usr/local/bin
for script in custom-pkgs/*/*.sh; do
[ -f "$script" ] || continue
script_name="$(basename "$script")"
target_name="${script_name%.sh}"
install -Dm0755 "$script" "airootfs/usr/local/bin/$target_name"
done
# --- CRÉATION DE L'ISO ---
echo "[6/6] Building ISO (this will take a while)..."
sudo mkarchiso -v .
# Check result
if [ -f out/*.iso ]; then
echo "[3/3] Build successful!"
echo "ISO located in: out/"
echo ""
echo "====================================="
echo " Build successful!"
echo " ISO located in: out/"
echo "====================================="
else
echo "[ERROR] ISO not found in out/"
exit 1
fi
echo "====================================="
echo "Done."
echo "====================================="
fi
+18
View File
@@ -0,0 +1,18 @@
# Paquets personnalisés
Place ici les sources de tes applications personnelles.
Structure recommandée :
- custom-pkgs/my-app/
- PKGBUILD
- .SRCINFO (généré automatiquement)
- src/
Exemple rapide :
- une application en C/C++/Rust/Go/Python
- un script shell autonome
- un binaire déjà compilé
Pour une application non disponible sur pacman/AUR, la méthode la plus propre est de la packager avec un PKGBUILD puis de la construire dans le build ISO.
+18
View File
@@ -0,0 +1,18 @@
# Maintainer: Ton Nom <ton@email>
pkgname=optifetch
pkgver=1.0
pkgrel=1
pkgdesc="Version personnalisée de fastfetch intégrée dans l'ISO"
arch=('x86_64')
url='https://example.com/ton-projet'
license=('MIT')
depends=('gcc' 'make')
source=("optifetch::git+https://github.com/arthur-pbty/optifetch.git")
sha256sums=('SKIP')
package() {
cd "$srcdir/optifetch"
make
install -Dm0755 optifetch "$pkgdir/usr/bin/optifetch"
}
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail
# Ce script est exécuté dans l'environnement du live ISO
# Il peut installer/mettre en place des éléments personnalisés.
echo "[custom] Configuration personnalisée de l'ISO"
# Exemple: créer un dossier pour tes applis perso
mkdir -p /usr/local/bin /usr/local/share/my-apps
# Si tu as déjà un binaire compilé, tu peux l'ajouter ici.
# Exemple:
# install -Dm0755 /root/custom-app /usr/local/bin/custom-app
# Si tu veux rendre un script disponible globalement:
# install -Dm0755 /root/custom-scripts/hello.sh /usr/local/bin/hello.sh