Moin Leute,
Ich wollte mir ein Script erstellen, welches mir ein Arch-Install in den Calamares Installer einbaut (um es mal vereinfacht zu beschreiben). Ihr könnt die Paketlisten anpassen, von Zeile 224 - 467.
Bitte und wichtig !!! Probiert die ISO erstmal nur in der VM aus die ihr erstellt habt. Was auf einem physischen System passiert, habe ich noch nicht probiert. Ich will nur wissen, ob das bei euch so durchläuft. Also wenn ihr die ISO mit dem Script erstellt, und ob sie sich ohne Probleme installieren lässt in der VM. Geschrieben für Arch-basierte Systeme
Es wird erstmal nur den KDE DE unterstützen. Ich bin jetzt dran, via Netinstall die anderen DE's mit einzubauen. Das wird aber noch einige Zeit in Anspruch nehmen.
Ich danke für jeglichen Support ![]()
#!/usr/bin/env bash
# =============================================================================
# Custom Arch Linux ISO Builder v0.2_beta
# - KDE Plasma Live-Desktop
# - KDE Plasma System-Desktop
# - Installation im BIOS & UEFI möglich
# - Dateisystem-Auswahl: btrfs, ext4, xfs, f2fs
# - OS-Erkennung + Dual-Boot via os-prober
# - Alle Treiber (GPU, WLAN, Sound, BT, Drucker)
# - Calamares grafischer Installer (via lokalem AUR-Build)
# =============================================================================
set -euo pipefail
# ── Echter User auch unter sudo ───────────────────────────────────────────────
REAL_USER="${SUDO_USER:-$USER}"
REAL_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6)
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
WORK_DIR="$SCRIPT_DIR/archiso-build"
PROFILE_DIR="$WORK_DIR/myarchiso"
OUT_DIR="$SCRIPT_DIR/archiso-out"
CAL_REPO="$SCRIPT_DIR/archiso-local-repo"
ARCHISO_TEMPLATE="/usr/share/archiso/configs/releng"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[FEHLER]${NC} $*"; exit 1; }
step() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n $*\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; }
# ─────────────────────────────────────────────────────────────────────────────
check_deps() {
step "Abhängigkeiten prüfen"
[[ $EUID -eq 0 ]] || error "Bitte als root ausführen: sudo $0"
# sudo-Timestamp verlängern – verhindert mehrfache Passwortabfragen
echo "Defaults timestamp_timeout=60" > /etc/sudoers.d/archiso-build-tmp
chmod 440 /etc/sudoers.d/archiso-build-tmp
# sudo-Timestamp für REAL_USER verlängern damit keine mehrfachen Passwortabfragen kommen
sudo -u "$REAL_USER" sudo -v 2>/dev/null || true
# Timestamp-Timeout auf 60 Minuten setzen
for dep in mkarchiso mksquashfs xorriso; do
command -v "$dep" &>/dev/null || error "$dep fehlt → sudo pacman -S archiso squashfs-tools libisoburn"
done
info "Alle Abhängigkeiten vorhanden"
}
# ─────────────────────────────────────────────────────────────────────────────
build_calamares() {
step "Calamares aus AUR bauen"
mkdir -p "$CAL_REPO"
# Immer neu bauen – verhindert yaml-cpp/Bibliotheks-Versionskonflikte
rm -f "$CAL_REPO"/calamares-*.pkg.tar.zst 2>/dev/null || true
info "Baue Calamares aus AUR (~10 Min.)..."
local build_dir="/tmp/calamares-aur-build"
rm -rf "$build_dir"
mkdir -p "$build_dir"
chown "$REAL_USER:$REAL_USER" "$build_dir"
sudo -u "$REAL_USER" bash << BUILDSCRIPT
set -e
cd "$build_dir"
git clone https://aur.archlinux.org/calamares.git
cd calamares
# Abhängigkeiten installieren (inkl. aktuelle yaml-cpp-Version)
sudo pacman -S --noconfirm --needed \
cmake extra-cmake-modules ninja \
qt6-base qt6-declarative qt6-svg qt6-tools qt6-webengine \
kpmcore python python-jsonschema python-yaml \
icu boost boost-libs yaml-cpp \
kconfig kcoreaddons ki18n kio kwidgetsaddons \
solid kparts kservice
makepkg -s --noconfirm --noprogressbar
BUILDSCRIPT
find "$build_dir" -name "calamares-*.pkg.tar.zst" ! -name "*debug*" -exec cp {} "$CAL_REPO/" \;
rm -rf "$build_dir"
info "Calamares gebaut"
cd "$CAL_REPO"
# repo-add: Datenbankname muss exakt dem [local-repo]-Eintrag in pacman.conf entsprechen
repo-add local-repo.db.tar.gz *.pkg.tar.zst
# Symlinks erstellen die pacman erwartet
ln -sf local-repo.db.tar.gz local-repo.db
ln -sf local-repo.files.tar.gz local-repo.files 2>/dev/null || true
ls -la "$CAL_REPO"
cd - >/dev/null
info "Lokales Repo bereit: $CAL_REPO"
}
# ─────────────────────────────────────────────────────────────────────────────
setup_profile() {
step "Basisprofil aufsetzen"
# Alte Mounts aufräumen – direkt alle bekannten Pfade unmounten
local airootfs="$WORK_DIR/work/x86_64/airootfs"
for mnt in proc/irq proc/sys proc/sysrq-trigger proc sys/fs/cgroup sys dev/pts dev run; do
umount -l "$airootfs/$mnt" 2>/dev/null || true
done
sleep 1
# Alte ISO und Build-Verzeichnis löschen
rm -f "$OUT_DIR"/*.iso 2>/dev/null || true
rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR" "$OUT_DIR"
cp -r "$ARCHISO_TEMPLATE" "$PROFILE_DIR"
# Lokales Calamares-Repo oben in pacman.conf eintragen
{
echo "[local-repo]"
echo "SigLevel = Optional TrustAll"
echo "Server = file://$(echo "$CAL_REPO" | sed 's/ /%20/g')"
echo ""
cat "$PROFILE_DIR/pacman.conf"
} > "$PROFILE_DIR/pacman.conf.tmp"
mv "$PROFILE_DIR/pacman.conf.tmp" "$PROFILE_DIR/pacman.conf"
info "Lokales Calamares-Repo in pacman.conf eingetragen"
# Chaotic-AUR ins ISO-Profil eintragen (für Calamares)
if grep -q "chaotic-aur" /etc/pacman.conf; then
CHAOTIC_MIRRORLIST=$(grep -A2 "chaotic-aur" /etc/pacman.conf | grep Include | awk '{print $3}')
# Repo-Block als Datei schreiben und dann in pacman.conf einfügen
{
echo "[chaotic-aur]"
echo "Include = $CHAOTIC_MIRRORLIST"
echo ""
cat "$PROFILE_DIR/pacman.conf"
} > "$PROFILE_DIR/pacman.conf.tmp"
mv "$PROFILE_DIR/pacman.conf.tmp" "$PROFILE_DIR/pacman.conf"
mkdir -p "$PROFILE_DIR/airootfs/etc/pacman.d"
[ -f "$CHAOTIC_MIRRORLIST" ] && cp "$CHAOTIC_MIRRORLIST" "$PROFILE_DIR/airootfs/etc/pacman.d/chaotic-mirrorlist" || true
info "Chaotic-AUR ins ISO-Profil eingetragen"
fi
# multilib aktivieren
sed -i '/^#\[multilib\]/,/^#Include/{
s/^#\[multilib\]/[multilib]/
s/^#Include/Include/
}' "$PROFILE_DIR/pacman.conf"
grep -q "^\[multilib\]" "$PROFILE_DIR/pacman.conf" || \
printf '\n[multilib]\nInclude = /etc/pacman.d/mirrorlist\n' >> "$PROFILE_DIR/pacman.conf"
# NoProgressBar für unbeaufsichtigten Build
sed -i '/^\[options\]/a NoProgressBar' "$PROFILE_DIR/pacman.conf"
# Xorg-Konfiguration für VM: nvidia blacklisten, vesa/fbdev/modesetting erzwingen
mkdir -p "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d"
cat > "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d/10-vm-display.conf" << 'XORGEOF'
# Modesetting erzwingen – verhindert Xorg-Crash durch nvidia/nouveau in VM
Section "Device"
Identifier "GPU"
Driver "modesetting"
EndSection
XORGEOF
# Deutsches Tastaturlayout als Standard ins airootfs
cat > "$PROFILE_DIR/airootfs/etc/vconsole.conf" << 'VCEOF'
KEYMAP=de-latin1
XKBLAYOUT=de
XKBMODEL=pc105
XKBOPTIONS=
VCEOF
# nvidia-Module blacklisten
mkdir -p "$PROFILE_DIR/airootfs/etc/modprobe.d"
cat > "$PROFILE_DIR/airootfs/etc/modprobe.d/blacklist-nvidia.conf" << 'MODEOF'
blacklist nvidia
blacklist nouveau
blacklist nvidia_drm
blacklist nvidia_modeset
blacklist nvidia_uvm
MODEOF
# mkinitcpio: PXE-Hooks entfernen (brechen den Build)
local mkinit="$PROFILE_DIR/airootfs/etc/mkinitcpio.conf.d/archiso.conf"
mkdir -p "$(dirname "$mkinit")"
cat > "$mkinit" << 'EOF'
HOOKS=(base udev microcode modconf kms memdisk archiso archiso_loop_mnt block filesystems keyboard)
MODULES=(virtio virtio_pci virtio_blk virtio_scsi)
COMPRESSION="zstd"
EOF
# Xorg modesetting ins airootfs – wird beim Install mitkopiert
mkdir -p "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d"
cat > "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d/10-modesetting.conf" << 'XEOF'
Section "Device"
Identifier "GPU"
Driver "modesetting"
EndSection
XEOF
# Xorg modesetting ins airootfs fuer installiertes System
mkdir -p "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d"
cat > "$PROFILE_DIR/airootfs/etc/X11/xorg.conf.d/10-modesetting.conf" << 'XEOF'
Section "Device"
Identifier "GPU"
Driver "modesetting"
EndSection
XEOF
# SDDM-Config und X11-Session direkt ins airootfs – wird beim Install mitkopiert
mkdir -p "$PROFILE_DIR/airootfs/etc/sddm.conf.d"
cat > "$PROFILE_DIR/airootfs/etc/sddm.conf.d/kde.conf" << 'SDDMEOF'
[General]
DefaultSession=plasma.desktop
[Theme]
Current=breeze
SDDMEOF
mkdir -p "$PROFILE_DIR/airootfs/usr/share/xsessions"
cat > "$PROFILE_DIR/airootfs/usr/share/xsessions/plasma.desktop" << 'XEOF'
[Desktop Entry]
Type=XSession
Exec=startplasma-x11
TryExec=startplasma-x11
Name=KDE Plasma
Comment=KDE Plasma Desktop (X11)
XEOF
# SDDM-Config direkt ins airootfs – wird beim Install mitkopiert
mkdir -p "$PROFILE_DIR/airootfs/etc/sddm.conf.d"
printf "[General]\nDefaultSession=plasma.desktop\n\n[Theme]\nCurrent=breeze\n" > "$PROFILE_DIR/airootfs/etc/sddm.conf.d/kde.conf"
mkdir -p "$PROFILE_DIR/airootfs/usr/share/xsessions"
printf "[Desktop Entry]\nType=XSession\nExec=startplasma-x11\nTryExec=startplasma-x11\nName=KDE Plasma\n" > "$PROFILE_DIR/airootfs/usr/share/xsessions/plasma.desktop"
info "Profil aufgesetzt"
}
# ─────────────────────────────────────────────────────────────────────────────
write_packages() {
step "Paketliste schreiben"
cat > "$PROFILE_DIR/packages.x86_64" << 'EOF'
# ── Provider-Defaults ─────────────────────────────────────────────────────────
iptables-nft
qt6-multimedia-ffmpeg
pyside6
cronie
tesseract-data-deu
tesseract-data-eng
mesa
lib32-mesa
# ── Basis ─────────────────────────────────────────────────────────────────────
base
base-devel
linux
linux-headers
linux-firmware
linux-firmware-qlogic
mkinitcpio
mkinitcpio-archiso
squashfs-tools
cryptsetup
lvm2
# ── Bootloader ────────────────────────────────────────────────────────────────
grub
efibootmgr
os-prober
grub-btrfs
dosfstools
intel-ucode
amd-ucode
syslinux
memtest86+
memtest86+-efi
edk2-shell
# ── Dateisysteme ─────────────────────────────────────────────────────────────
btrfs-progs
e2fsprogs
exfatprogs
f2fs-tools
jfsutils
ntfs-3g
xfsprogs
nilfs-utils
# ── Grafiktreiber ─────────────────────────────────────────────────────────────
mesa-utils
xf86-video-amdgpu
xf86-video-ati
xf86-video-intel
xf86-video-vesa
xf86-video-fbdev
vulkan-intel
vulkan-radeon
lib32-vulkan-intel
lib32-vulkan-radeon
intel-media-driver
libva-intel-driver
libva-utils
# ── Xorg ──────────────────────────────────────────────────────────────────────
xorg-server
xorg-xinit
xorg-xrandr
xorg-xdpyinfo
xorg-xhost
xorg-xauth
xorg-xkbcomp
xorg-xkbutils
xorg-xkill
xorg-xprop
xorg-xrdb
xorg-xset
xorg-xsetroot
xorg-xwininfo
xorg-xinput
xterm
xdg-user-dirs
xdg-utils
# ── Wayland ───────────────────────────────────────────────────────────────────
wayland
wayland-utils
xorg-xwayland
wl-clipboard
# ── Netzwerk / WLAN ───────────────────────────────────────────────────────────
networkmanager
network-manager-applet
nm-connection-editor
iwd
wpa_supplicant
wireless_tools
iw
net-tools
nmap
dhcpcd
# ── Bluetooth ─────────────────────────────────────────────────────────────────
bluez
bluez-utils
blueman
# ── Sound ─────────────────────────────────────────────────────────────────────
pipewire
pipewire-alsa
pipewire-pulse
pipewire-jack
wireplumber
alsa-utils
alsa-firmware
sof-firmware
pavucontrol
# ── Drucker / Scanner ─────────────────────────────────────────────────────────
cups
cups-pdf
system-config-printer
sane
sane-airscan
# ── USB / Speicher ────────────────────────────────────────────────────────────
usbutils
udisks2
gvfs
gvfs-mtp
gvfs-smb
gvfs-nfs
mtpfs
libmtp
fuse3
nfs-utils
# ── Display Manager ───────────────────────────────────────────────────────────
sddm
# ── KDE Plasma ────────────────────────────────────────────────────────────────
bluedevil
breeze
breeze-gtk
discover
drkonqi
kactivitymanagerd
kde-cli-tools
kde-gtk-config
kdecoration
kdeplasma-addons
kgamma
kglobalacceld
kinfocenter
kmenuedit
kpipewire
kscreen
kscreenlocker
ksshaskpass
ksystemstats
kwallet-pam
kwin
kwin-x11
kwrited
libkscreen
libksysguard
libplasma
milou
ocean-sound-theme
oxygen
oxygen-sounds
plasma-activities
plasma-activities-stats
plasma-browser-integration
plasma-desktop
plasma-disks
plasma-firewall
plasma-integration
plasma-nm
plasma-pa
plasma-systemmonitor
plasma-workspace
plasma-workspace-wallpapers
plasma5support
polkit-kde-agent
polkit
powerdevil
power-profiles-daemon
plasma-thunderbolt
fwupd
packagekit-qt6
qt6-tools
qt5-tools
print-manager
qqc2-breeze-style
sddm-kcm
spectacle
systemsettings
xdg-desktop-portal-kde
ark
dolphin
gwenview
kate
kcalc
kdeconnect
konsole
kwalletmanager
okular
partitionmanager
yakuake
# ── Calamares ─────────────────────────────────────────────────────────────────
calamares
python-pyqt5
# ── Fonts / Icons / Themes ────────────────────────────────────────────────────
ttf-dejavu
ttf-liberation
ttf-font-awesome
noto-fonts
noto-fonts-emoji
noto-fonts-cjk
papirus-icon-theme
# ── Anwendungen ───────────────────────────────────────────────────────────────
firefox
vlc
gparted
timeshift
nano
vim
git
wget
curl
rsync
openssh
htop
fastfetch
p7zip
unrar
unzip
zip
bash-completion
man-db
man-pages
archinstall
arch-install-scripts
EOF
info "Paketliste geschrieben"
}
# ─────────────────────────────────────────────────────────────────────────────
setup_calamares() {
step "Calamares konfigurieren"
local cal="$PROFILE_DIR/airootfs/etc/calamares"
mkdir -p "$cal/modules" "$cal/branding/archlinux"
# Logo generieren
pacman -S --noconfirm --needed imagemagick 2>/dev/null || true
if command -v convert &>/dev/null; then
convert -size 200x200 xc:"#1793d1" \
-fill white -font DejaVu-Sans-Bold -pointsize 120 \
-gravity center -annotate 0 "A" \
"$cal/branding/archlinux/arch-logo.png" 2>/dev/null || \
convert -size 200x200 xc:"#1793d1" \
"$cal/branding/archlinux/arch-logo.png" 2>/dev/null || true
fi
# Python-Fallback falls convert fehlt
[[ -f "$cal/branding/archlinux/arch-logo.png" ]] || python3 -c "
import struct, zlib
def png(w,h,r,g,b):
def c(t,d):
x=zlib.crc32(t+d)&0xffffffff
return struct.pack('>I',len(d))+t+d+struct.pack('>I',x)
raw=b''.join(b'\x00'+bytes([r,g,b,255]*w) for _ in range(h))
return b'\x89PNG\r\n\x1a\n'+c(b'IHDR',struct.pack('>IIBBBBB',w,h,8,2,0,0,0))+c(b'IDAT',zlib.compress(raw))+c(b'IEND',b'')
open('$cal/branding/archlinux/arch-logo.png','wb').write(png(200,200,23,147,209))
"
info "Logo erstellt"
# settings.conf
cat > "$cal/settings.conf" << 'EOF'
---
modules-search: [ local, /usr/lib/calamares/modules ]
sequence:
- show:
- welcome
- locale
- keyboard
- partition
- users
- summary
- exec:
- partition
- mount
- unpackfs
- machineid
- fstab
- locale
- keyboard
- localecfg
- users
- networkcfg
- hwclock
- services-systemd
- packages
- shellprocess
- umount
- show:
- finished
branding: archlinux
prompt-install: false
dont-chroot: false
EOF
# fstab.conf
cat > "$cal/modules/fstab.conf" << 'EOF'
---
EOF
# keyboard.conf – Deutsch als Standard
cat > "$cal/modules/keyboard.conf" << 'EOF'
---
xorgConfDir: "/etc/X11/xorg.conf.d"
EOF
# locale.conf – Deutsch vorauswählen
cat > "$cal/modules/locale.conf" << 'EOF'
---
region: "Europe"
zone: "Berlin"
locales:
- de_DE.UTF-8 UTF-8
- en_US.UTF-8 UTF-8
keyboardLayout: "de"
keyboardModel: "pc105"
keyboardVariant: ""
keytable: "de-latin1"
EOF
# HINWEIS: Bei btrfs empfehlen wir eine separate /boot-Partition (ext4)
# damit GRUB grub.cfg korrekt findet
cat > "$cal/modules/partition.conf" << 'EOF'
---
efiSystemPartition: "/boot/efi"
efiSystemPartitionSize: "512MiB"
efiSystemPartitionName: "EFI"
defaultFileSystemType: "ext4"
availableFileSystemTypes:
- ext4
- btrfs
- xfs
- f2fs
userSwapChoices:
- none
- small
- suspend
- file
- partition
EOF
# unpackfs.conf – squashfs + Kernel einzeln kopieren (sourcefs: file)
cat > "$cal/modules/unpackfs.conf" << 'EOF'
---
unpack:
- source: "/run/archiso/bootmnt/arch/x86_64/airootfs.sfs"
sourcefs: "squashfs"
destination: ""
- source: "/run/archiso/bootmnt/arch/boot/x86_64/vmlinuz-linux"
sourcefs: "file"
destination: "/boot/vmlinuz-linux"
- source: "/run/archiso/bootmnt/arch/boot/x86_64/initramfs-linux.img"
sourcefs: "file"
destination: "/boot/initramfs-linux.img"
EOF
# shellprocess.conf – läuft vom Live-Host (dontChroot: true), ROOT via @@ROOT@@
cat > "$cal/modules/shellprocess.conf" << 'SHELLEOF'
---
dontChroot: true
timeout: 1200
script:
- "/usr/bin/bash /usr/lib/calamares-postinstall.sh"
SHELLEOF
# Das Postinstall-Skript wird ins airootfs gelegt und von Calamares
# ins Zielsystem übertragen (unpackfs kopiert alles aus airootfs).
# Es läuft per chroot direkt im installierten System.
mkdir -p "$PROFILE_DIR/airootfs/usr/lib"
cat > "$PROFILE_DIR/airootfs/usr/lib/calamares-postinstall.sh" << 'POSTINSTALL'
#!/bin/bash
# Läuft auf dem Live-Host (dontChroot: true).
# Schreibt grub.cfg direkt – kein grub-mkconfig, kein Calamares-Modul.
set -e
# ROOT ermitteln: Calamares mountet das Zielsystem nach /tmp/calamares-root-*
# Wir suchen den Mount-Punkt zuverlässig
ROOT=""
# 1. Versuch: Calamares-Umgebungsvariable (neuere Versionen)
[ -n "${ROOT:-}" ] || ROOT="${CALAMARES_ROOT:-}"
# 2. Versuch: /tmp/calamares-root-* Verzeichnis
if [ -z "$ROOT" ]; then
ROOT=$(ls -d /tmp/calamares-root-* 2>/dev/null | head -1)
fi
# 3. Versuch: lsblk nach dem größten ext4/btrfs/xfs Mount unter /tmp
if [ -z "$ROOT" ]; then
ROOT=$(findmnt -rno TARGET | grep "^/tmp/" | grep -v "^/tmp/$" | head -1)
fi
[ -n "$ROOT" ] || { echo "FEHLER: ROOT nicht ermittelbar"; exit 1; }
echo "==> Postinstall gestartet, ROOT=$ROOT"
# Geräte ermitteln – funktioniert mit vda, sda, nvme0n1, mmcblk0 usw.
ROOT_DEV=$(lsblk -rno NAME,MOUNTPOINT | awk -v r="$ROOT" '$2==r {print "/dev/"$1}' | head -1)
EFI_DEV=$(lsblk -rno NAME,MOUNTPOINT | awk -v r="$ROOT/boot/efi" '$2==r {print "/dev/"$1}' | head -1)
ROOT_UUID=$(blkid -s UUID -o value "$ROOT_DEV")
EFI_UUID=$(blkid -s UUID -o value "$EFI_DEV" 2>/dev/null || true)
FSTYPE=$(blkid -s TYPE -o value "$ROOT_DEV")
DISK=$(lsblk -ndo PKNAME "$ROOT_DEV" | head -1)
[ -n "$DISK" ] && DISK="/dev/$DISK"
echo "==> ROOT_DEV=$ROOT_DEV DISK=$DISK FSTYPE=$FSTYPE UUID=$ROOT_UUID"
[ -n "$ROOT_UUID" ] || { echo "FEHLER: ROOT_UUID leer"; exit 1; }
[ -n "$DISK" ] || { echo "FEHLER: Festplatte nicht ermittelbar"; exit 1; }
# Mounts für chroot
mount --bind /proc "$ROOT/proc"
mount --bind /sys "$ROOT/sys"
mount --bind /dev "$ROOT/dev"
mount --bind /dev/pts "$ROOT/dev/pts"
cleanup() {
umount -l "$ROOT/sys/firmware/efi/efivars" 2>/dev/null || true
umount -l "$ROOT/dev/pts" 2>/dev/null
umount -l "$ROOT/dev" 2>/dev/null
umount -l "$ROOT/sys" 2>/dev/null
umount -l "$ROOT/proc" 2>/dev/null
}
trap cleanup EXIT
# 1. fstab mit UUIDs schreiben
{
echo "# /etc/fstab"
echo "UUID=$ROOT_UUID / $FSTYPE defaults,noatime 0 1"
[ -n "$EFI_UUID" ] && echo "UUID=$EFI_UUID /boot/efi vfat defaults,umask=0077 0 2"
} > "$ROOT/etc/fstab"
echo "==> fstab:"; cat "$ROOT/etc/fstab"
# 2. mkinitcpio: archiso-Hooks deaktivieren, Standard-Preset setzen
# archiso.conf überschreiben (leer) damit mkinitcpio keine archiso-Hooks lädt
mkdir -p "$ROOT/etc/mkinitcpio.conf.d"
# archiso.conf komplett leeren - verhindert dass mkinitcpio den archiso-Hook lädt
> "$ROOT/etc/mkinitcpio.conf.d/archiso.conf"
# Zusätzlich: archiso Hook-Dateien aus dem Zielsystem entfernen
rm -f "$ROOT/usr/lib/initcpio/hooks/archiso" 2>/dev/null || true
rm -f "$ROOT/usr/lib/initcpio/install/archiso" 2>/dev/null || true
rm -f "$ROOT/usr/lib/initcpio/hooks/archiso_loop_mnt" 2>/dev/null || true
rm -f "$ROOT/usr/lib/initcpio/install/archiso_loop_mnt" 2>/dev/null || true
# Saubere mkinitcpio.conf
cat > "$ROOT/etc/mkinitcpio.conf" << 'MKINIT'
MODULES=(virtio virtio_pci virtio_blk virtio_scsi virtio_net)
BINARIES=()
FILES=()
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck)
COMPRESSION="zstd"
MKINIT
# linux.preset ohne archiso-Referenzen
mkdir -p "$ROOT/etc/mkinitcpio.d"
cat > "$ROOT/etc/mkinitcpio.d/linux.preset" << 'PRESET'
ALL_config="/etc/mkinitcpio.conf"
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
# Nur linux-Preset bauen (nicht -P = alle Presets inkl. archiso)
chroot "$ROOT" mkinitcpio -p linux --nocolor
echo "==> mkinitcpio fertig"
# 3. grub-install: UEFI oder BIOS je nach Boot-Modus
mkdir -p "$ROOT/boot/grub"
if [ -d /sys/firmware/efi ]; then
echo "==> UEFI-Modus erkannt"
mkdir -p "$ROOT/boot/efi/EFI/BOOT"
chroot "$ROOT" grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --no-nvram --removable --recheck
echo "==> grub-install UEFI OK"
ls -la "$ROOT/boot/efi/EFI/BOOT/" 2>/dev/null || true
else
echo "==> BIOS-Modus erkannt"
# Root-Disk ermitteln (Disk auf der / liegt)
ROOT_DISK=$(lsblk -no PKNAME $(findmnt -n -o SOURCE "$ROOT" 2>/dev/null || echo "") 2>/dev/null | head -1)
[ -z "$ROOT_DISK" ] && ROOT_DISK=$(lsblk -rno NAME,MOUNTPOINT | awk '$2=="/" {print $1}' | sed 's/[0-9]*$//' | head -1)
echo "==> GRUB BIOS auf /dev/$ROOT_DISK"
chroot "$ROOT" grub-install --target=i386-pc --recheck "/dev/$ROOT_DISK"
echo "==> grub-install BIOS OK"
fi
echo "==> grub-install fertig"
# 4. grub.cfg direkt schreiben – kein grub-mkconfig
# GRUB_FS_MOD je nach Dateisystem wählen
case "$FSTYPE" in
btrfs) FS_MOD="btrfs" ;;
xfs) FS_MOD="xfs" ;;
f2fs) FS_MOD="f2fs" ;;
*) FS_MOD="ext2" ;;
esac
cat > "$ROOT/boot/grub/grub.cfg" << GRUBCFG
set default=0
set timeout=10
insmod part_gpt
insmod part_msdos
insmod $FS_MOD
search --no-floppy --fs-uuid --set=root $ROOT_UUID
menuentry "Arch Linux" {
linux /boot/vmlinuz-linux root=UUID=$ROOT_UUID rw quiet
initrd /boot/initramfs-linux.img
}
menuentry "Arch Linux (Fallback)" {
linux /boot/vmlinuz-linux root=UUID=$ROOT_UUID rw
initrd /boot/initramfs-linux-fallback.img
}
GRUBCFG
echo "==> grub.cfg:"; cat "$ROOT/boot/grub/grub.cfg"
# 5. SDDM korrekt konfigurieren im installierten System
# Autologin-Config vom Live-ISO entfernen
rm -f "$ROOT/etc/sddm.conf.d/autologin.conf"
mkdir -p "$ROOT/etc/sddm.conf.d"
# Normalen Login-Screen mit KDE Plasma als Standard
# X11-Session für KDE Plasma anlegen (Wayland funktioniert nicht in QEMU/KVM)
mkdir -p "$ROOT/usr/share/xsessions"
cat > "$ROOT/usr/share/xsessions/plasma.desktop" << 'XSESSION'
[Desktop Entry]
Type=XSession
Exec=startplasma-x11
TryExec=startplasma-x11
Name=KDE Plasma
Comment=KDE Plasma Desktop
XSESSION
# SDDM: X11 + Plasma als Standard
cat > "$ROOT/etc/sddm.conf.d/kde.conf" << 'SDDMEOF'
[General]
DefaultSession=plasma.desktop
[Theme]
Current=breeze
SDDMEOF
# Calamares-Desktop-Icon vom installierten System entfernen
rm -f "$ROOT/home/"*"/Desktop/install-arch.desktop" 2>/dev/null || true
rm -f "$ROOT/root/Desktop/install-arch.desktop" 2>/dev/null || true
# Calamares-Autostart entfernen
rm -f "$ROOT/home/"*"/.config/autostart/trust-desktop.sh" 2>/dev/null || true
rm -f "$ROOT/home/"*"/.config/autostart/trust-desktop.desktop" 2>/dev/null || true
rm -f "$ROOT/home/"*"/.config/autostart/disable-screensaver.desktop" 2>/dev/null || true
# liveuser direkt aus passwd/shadow/group entfernen
sed -i '/^liveuser:/d' "$ROOT/etc/passwd"
sed -i '/^liveuser:/d' "$ROOT/etc/shadow"
sed -i '/^liveuser:/d' "$ROOT/etc/group"
sed -i 's/,liveuser//g; s/liveuser,//g' "$ROOT/etc/group"
rm -rf "$ROOT/home/liveuser"
echo "==> liveuser entfernt"
# /etc/skel mit sauberer KDE-Basis befuellen
mkdir -p "$ROOT/etc/skel/.config"
mkdir -p "$ROOT/etc/skel/.local/share"
mkdir -p "$ROOT/etc/skel/.cache"
echo "==> /etc/skel initialisiert"
# /etc/skel mit sauberer KDE-Basis befüllen
# Diese Dateien werden für jeden neuen Benutzer verwendet
mkdir -p "$ROOT/etc/skel/.config"
mkdir -p "$ROOT/etc/skel/.local/share"
mkdir -p "$ROOT/etc/skel/.cache"
# Plasma ohne Crash-Handler starten
cat > "$ROOT/etc/skel/.config/ksmserverrc" << 'KSMEOF'
[General]
loginMode=default
KSMEOF
echo "==> /etc/skel initialisiert"
# KDE Plasma als Standard-Session setzen
mkdir -p "$ROOT/etc/sddm.conf.d"
# X11-Session für KDE Plasma anlegen (Wayland funktioniert nicht in QEMU/KVM)
mkdir -p "$ROOT/usr/share/xsessions"
cat > "$ROOT/usr/share/xsessions/plasma.desktop" << 'XSESSION'
[Desktop Entry]
Type=XSession
Exec=startplasma-x11
TryExec=startplasma-x11
Name=KDE Plasma
Comment=KDE Plasma Desktop
XSESSION
# SDDM: X11 + Plasma als Standard
cat > "$ROOT/etc/sddm.conf.d/kde.conf" << 'SDDMEOF'
[General]
DefaultSession=plasma.desktop
[Theme]
Current=breeze
SDDMEOF
# Sicherstellen dass plasma.desktop Session-Datei existiert
ls "$ROOT/usr/share/wayland-sessions/plasma.desktop" 2>/dev/null || ls "$ROOT/usr/share/xsessions/plasma.desktop" 2>/dev/null || echo "WARNUNG: plasma.desktop nicht gefunden"
# 5. Services aktivieren
chroot "$ROOT" systemctl enable sddm NetworkManager bluetooth cups fstrim.timer power-profiles-daemon sshd || true
chroot "$ROOT" systemctl --global enable pipewire pipewire-pulse wireplumber || true
# Berechtigungen für alle Benutzer-Home-Verzeichnisse korrigieren
for user_home in "$ROOT/home"/*/; do
username=$(basename "$user_home")
uid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f3)
gid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f4)
if [ -n "$uid" ]; then
chown -R "$uid:$gid" "$user_home"
chmod 700 "$user_home"
echo "==> Berechtigungen gesetzt für $username ($uid:$gid)"
fi
done
# Berechtigungen fuer Home-Verzeichnisse korrigieren
for user_home in "$ROOT/home"/*/; do
username=$(basename "$user_home")
uid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f3)
gid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f4)
if [ -n "$uid" ]; then
chown -R "$uid:$gid" "$user_home"
chmod 700 "$user_home"
echo "==> Berechtigungen: $username ($uid:$gid)"
fi
done
# Plasma-Konfiguration für neuen Benutzer initialisieren
for user_home in "$ROOT/home"/*/; do
[ -d "$user_home" ] || continue
username=$(basename "$user_home")
uid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f3)
gid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f4)
[ -n "$uid" ] || continue
mkdir -p "$user_home/.config"
mkdir -p "$user_home/.cache"
mkdir -p "$user_home/.local/share"
# Plasma Shell nicht crashen lassen
cat > "$user_home/.config/plasmashellrc" << 'PLASMAEOF'
[PlasmaViews][Panel 1][Defaults]
thickness=44
PLASMAEOF
chown -R "${uid}:${gid}" "$user_home"
chmod 700 "$user_home"
echo "==> Plasma-Config für $username initialisiert"
done
# Benutzer Home-Verzeichnisse und Plasma-Config initialisieren
for user_home in "$ROOT/home"/*/; do
[ -d "$user_home" ] || continue
username=$(basename "$user_home")
uid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f3)
gid=$(grep "^${username}:" "$ROOT/etc/passwd" | cut -d: -f4)
[ -n "$uid" ] || continue
mkdir -p "$user_home/.config" "$user_home/.cache" "$user_home/.local/share"
chown -R "${uid}:${gid}" "$user_home"
chmod 700 "$user_home"
echo "==> Home initialisiert fuer $username"
done
echo "==> Postinstall abgeschlossen"
POSTINSTALL
chmod +x "$PROFILE_DIR/airootfs/usr/lib/calamares-postinstall.sh"
# packages.conf – NUR calamares entfernen (calamares-libs existiert nicht!)
cat > "$cal/modules/packages.conf" << 'EOF'
---
backend: pacman
operations:
- remove:
- calamares
EOF
# users.conf
cat > "$cal/modules/users.conf" << 'EOF'
---
defaultGroups:
- users
- lp
- video
- network
- storage
- wheel
- audio
- optical
- scanner
- power
- input
autologinGroup: autologin
doAutologin: false
sudoersGroup: wheel
setRootPassword: true
passwordRequirements:
nonempty: true
minLength: 2
userShell: /bin/bash
EOF
# services-systemd.conf
cat > "$cal/modules/services-systemd.conf" << 'EOF'
---
services:
- name: NetworkManager
mandatory: true
- name: bluetooth
- name: cups
- name: sshd
- name: fstrim.timer
targets: []
EOF
# branding.desc
cat > "$cal/branding/archlinux/branding.desc" << 'EOF'
---
componentName: archlinux
strings:
productName: "Arch Linux"
shortProductName: "Arch"
version: "Rolling Release"
shortVersion: "Rolling"
versionedName: "Arch Linux Rolling"
shortVersionedName: "Arch"
bootloaderEntryName: "Arch Linux"
productUrl: "https://archlinux.org"
supportUrl: "https://wiki.archlinux.org"
knownIssuesUrl: "https://bugs.archlinux.org"
releaseNotesUrl: "https://archlinux.org/releng/releases"
images:
productLogo: "arch-logo.png"
productIcon: "arch-logo.png"
productWelcome: "arch-logo.png"
slideshowAPI: 1
slideshow: "show.qml"
style:
sidebarBackground: "#1793d1"
sidebarText: "#FFFFFF"
sidebarTextSelect: "#1a1a2e"
EOF
# show.qml
cat > "$cal/branding/archlinux/show.qml" << 'EOF'
import QtQuick 2.0
import calamares.slideshow 1.0
Presentation {
id: presentation
Timer {
interval: 5000
running: presentation.activatedInCalamares
repeat: true
onTriggered: presentation.goToNextSlide()
}
Slide {
anchors.fill: parent
Rectangle { anchors.fill: parent; color: "#1793d1" }
Text {
anchors.centerIn: parent
text: "Arch Linux wird installiert..."
font.pixelSize: 28; font.bold: true; color: "white"
}
}
Slide {
anchors.fill: parent
Rectangle { anchors.fill: parent; color: "#1a1a2e" }
Text {
anchors.centerIn: parent
text: "Fast fertig..."
font.pixelSize: 28; color: "white"
}
}
}
EOF
info "Calamares konfiguriert"
}
# ─────────────────────────────────────────────────────────────────────────────
setup_live_environment() {
step "Live-Umgebung einrichten (KDE Plasma)"
local airootfs="$PROFILE_DIR/airootfs"
mkdir -p "$airootfs/etc/sddm.conf.d" "$airootfs/etc/default"
# SDDM Autologin
cat > "$airootfs/etc/sddm.conf.d/autologin.conf" << 'EOF'
[Autologin]
User=liveuser
Session=plasma
EOF
# GRUB mit os-prober
cat > "$airootfs/etc/default/grub" << 'EOF'
GRUB_DEFAULT=0
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR="Arch Linux"
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash rootwait"
GRUB_CMDLINE_LINUX=""
GRUB_DISABLE_OS_PROBER=false
EOF
# customize_airootfs.sh
cat > "$airootfs/root/customize_airootfs.sh" << 'SCRIPT'
#!/bin/bash
set -e
# Locale
sed -i 's/#de_DE.UTF-8/de_DE.UTF-8/' /etc/locale.gen
sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
locale-gen
echo "LANG=de_DE.UTF-8" > /etc/locale.conf
echo "KEYMAP=de-latin1" > /etc/vconsole.conf
echo "XKBLAYOUT=de" >> /etc/vconsole.conf
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
# Live-User
useradd -m -G wheel,audio,video,optical,storage,network,input,lp \
-s /bin/bash liveuser
echo "liveuser:liveuser" | chpasswd
echo "root:root" | chpasswd
echo "%wheel ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# Nvidia-Pakete deinstallieren – verursachen Xorg-Crash in VM/ohne nvidia-HW
# Alle nvidia/nouveau-Pakete entfernen – Standard-Treiber (modesetting) reicht
for pkg in $(pacman -Qq 2>/dev/null | grep -E "nvidia|nouveau|340xx"); do
pacman -Rns --noconfirm "$pkg" 2>/dev/null || true
done
# Xorg: modesetting erzwingen
mkdir -p /etc/X11/xorg.conf.d
cat > /etc/X11/xorg.conf.d/10-modesetting.conf << 'XEOF'
Section "Device"
Identifier "GPU"
Driver "modesetting"
EndSection
XEOF
# Nvidia-Pakete deinstallieren – Xorg-Crash in VM
# Services
systemctl enable sddm NetworkManager bluetooth cups fstrim.timer power-profiles-daemon
# Pipewire
systemctl --global enable pipewire pipewire-pulse wireplumber
# Kernel + initramfs mit virtio-Modulen für VM-Kompatibilität
cat > /etc/mkinitcpio.conf.d/virtio.conf << 'EOF'
MODULES=(virtio virtio_pci virtio_blk virtio_scsi virtio_net)
EOF
mkinitcpio -P
ls -la /boot/vmlinuz-linux /boot/initramfs-linux.img || echo "WARNUNG: Kernel fehlt!"
# Desktop-Verknüpfung
mkdir -p /home/liveuser/Desktop
mkdir -p /home/liveuser/.config/autostart
printf '[Desktop Entry]\nType=Application\nName=Arch Linux installieren\nExec=sudo -E calamares\nIcon=calamares\nTerminal=false\nCategories=System;\nStartupNotify=true\n' \
> /home/liveuser/Desktop/install-arch.desktop
chmod 755 /home/liveuser/Desktop/install-arch.desktop
# KDE: Desktop-Datei beim Login als vertrauenswürdig markieren
cat > /home/liveuser/.config/autostart/trust-desktop.sh << 'TRUST'
#!/bin/bash
sleep 3
gio set ~/Desktop/install-arch.desktop metadata::trusted true 2>/dev/null || true
rm -- "$0"
TRUST
chmod +x /home/liveuser/.config/autostart/trust-desktop.sh
cat > /home/liveuser/.config/autostart/trust-desktop.desktop << 'AUTOSTART'
[Desktop Entry]
Type=Application
Name=Trust Desktop Icons
Exec=/home/liveuser/.config/autostart/trust-desktop.sh
Hidden=false
NoDisplay=true
X-GNOME-Autostart-enabled=true
AUTOSTART
# KDE Bildschirmsperre und Energiesparen deaktivieren
mkdir -p /home/liveuser/.config
cat > /home/liveuser/.config/kscreenlockerrc << 'KLOCK'
[Daemon]
Autolock=false
LockOnResume=false
Timeout=0
KLOCK
cat > /home/liveuser/.config/powermanagementprofilesrc << 'POWER'
[AC][DimDisplay]
enabled=false
[AC][DPMSControl]
enabled=false
[AC][SuspendSession]
enabled=false
suspendType=0
[AC][HandleButtonEvents]
lidAction=0
powerButtonAction=0
[Battery][DimDisplay]
enabled=false
[Battery][DPMSControl]
enabled=false
[Battery][SuspendSession]
enabled=false
suspendType=0
[LowBattery][SuspendSession]
enabled=false
suspendType=0
POWER
# KDE: kein Bildschirmschoner via kded
cat > /home/liveuser/.config/kded5rc << 'KDED'
[Module-screenlocker]
autoload=false
KDED
# Alle Einstellungen beim Login per kwriteconfig5 erzwingen
cat > /home/liveuser/.config/autostart/disable-screensaver.desktop << 'AUTOSTART'
[Desktop Entry]
Type=Application
Name=Disable Screensaver
Exec=bash -c "xset s off; xset -dpms; xset s noblank; kwriteconfig5 --file kscreenlockerrc --group Daemon --key Autolock false; kwriteconfig5 --file kscreenlockerrc --group Daemon --key Timeout 0; kwriteconfig5 --file powermanagementprofilesrc --group 'AC][SuspendSession' --key suspendType 0; kwriteconfig5 --file powermanagementprofilesrc --group 'AC][DimDisplay' --key idleTime 2147483647; kwriteconfig5 --file powermanagementprofilesrc --group 'AC][DPMSControl' --key idleTime 2147483647"
Hidden=false
NoDisplay=true
X-GNOME-Autostart-enabled=true
AUTOSTART
# SDDM: kein Bildschirmschoner
mkdir -p /etc/sddm.conf.d
cat >> /etc/sddm.conf.d/autologin.conf << 'SDDM'
[General]
HaltCommand=/usr/bin/systemctl poweroff
RebootCommand=/usr/bin/systemctl reboot
SDDM
chown -R liveuser:liveuser /home/liveuser
echo "==> Live-Umgebung OK"
echo "==> Kernel-Check:"
ls -lh /boot/
SCRIPT
chmod +x "$airootfs/root/customize_airootfs.sh"
# Firstboot-Service: schreibt fstab korrekt beim ersten Boot des installierten Systems
# Dieser Service wird von Calamares mit ins System kopiert (via airootfs)
mkdir -p "$airootfs/etc/systemd/system"
cat > "$airootfs/etc/systemd/system/fix-fstab.service" << 'EOF'
[Unit]
Description=Fix /etc/fstab on first boot
DefaultDependencies=no
Before=local-fs-pre.target
ConditionPathExists=/etc/fix-fstab-needed
[Service]
Type=oneshot
ExecStart=/bin/bash /etc/fix-fstab.sh
RemainAfterExit=yes
[Install]
WantedBy=sysinit.target
EOF
cat > "$airootfs/etc/fix-fstab.sh" << 'EOF'
#!/bin/bash
# Schreibt /etc/fstab neu mit korrekten UUIDs
ROOT_UUID=$(blkid -s UUID -o value $(findmnt -n -o SOURCE / 2>/dev/null) 2>/dev/null)
ROOT_FS=$(blkid -s TYPE -o value $(findmnt -n -o SOURCE / 2>/dev/null) 2>/dev/null)
EFI_UUID=$(blkid -s UUID -o value $(findmnt -n -o SOURCE /boot/efi 2>/dev/null) 2>/dev/null)
if [ -n "$ROOT_UUID" ] && [ -z "$(grep -v '^#' /etc/fstab | grep -v '^$')" ]; then
echo "# /etc/fstab - generiert beim ersten Boot" > /etc/fstab
echo "UUID=$ROOT_UUID / $ROOT_FS defaults,noatime 0 1" >> /etc/fstab
[ -n "$EFI_UUID" ] && echo "UUID=$EFI_UUID /boot/efi vfat defaults,umask=0077 0 2" >> /etc/fstab
fi
rm -f /etc/fix-fstab-needed
systemctl disable fix-fstab.service
EOF
chmod +x "$airootfs/etc/fix-fstab.sh"
# Marker-Datei damit der Service weiß dass er laufen soll
touch "$airootfs/etc/fix-fstab-needed"
# Service aktivieren
mkdir -p "$airootfs/etc/systemd/system/sysinit.target.wants"
ln -sf /etc/systemd/system/fix-fstab.service \
"$airootfs/etc/systemd/system/sysinit.target.wants/fix-fstab.service"
info "Live-Umgebung konfiguriert"
}
# ─────────────────────────────────────────────────────────────────────────────
write_profiledef() {
step "profiledef.sh schreiben"
cat > "$PROFILE_DIR/profiledef.sh" << 'EOF'
#!/usr/bin/env bash
iso_name="archlinux-custom"
iso_label="ARCH_CUSTOM"
iso_publisher="Custom Arch Linux"
iso_application="Custom Arch Linux – Full DE/WM Live/Install"
iso_version="$(date --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y.%m.%d)"
install_dir="arch"
buildmodes=('iso')
bootmodes=('bios.syslinux' 'uefi.grub')
arch="x86_64"
pacman_conf="pacman.conf"
airootfs_image_type="squashfs"
airootfs_image_tool_options=('-comp' 'zstd' '-b' '1M' '-Xcompression-level' '19')
file_permissions=(
["/etc/shadow"]="0:0:400"
["/root"]="0:0:750"
["/root/.ssh"]="0:0:700"
["/root/customize_airootfs.sh"]="0:0:755"
["/usr/lib/calamares-postinstall.sh"]="0:0:755"
["/etc/fix-fstab.sh"]="0:0:755"
)
EOF
}
# ─────────────────────────────────────────────────────────────────────────────
build_iso() {
step "ISO bauen"
mkarchiso -v -w "$WORK_DIR/work" -o "$OUT_DIR" "$PROFILE_DIR"
chown -R "$REAL_USER:$REAL_USER" "$OUT_DIR" "$WORK_DIR" 2>/dev/null || true
echo ""
info "✓ ISO fertig in: $OUT_DIR"
ls -lh "$OUT_DIR"/*.iso
# Temporäre sudoers-Regel entfernen
rm -f /etc/sudoers.d/archiso-build-timeout
}
# ─────────────────────────────────────────────────────────────────────────────
main() {
echo ""
echo "╔══════════════════════════════════════════════════════════════════╗"
echo "║ Custom Arch Linux ISO Builder v0.1_beta ║"
echo "║ KDE Live · 18 DEs/WMs · 4 Dateisysteme · Dual-Boot ║"
echo "╚══════════════════════════════════════════════════════════════════╝"
echo ""
check_deps
build_calamares
setup_profile
write_packages
setup_calamares
setup_live_environment
write_profiledef
build_iso
}
rm -f /etc/sudoers.d/archiso-build-tmp
main "$@"
Display More