fix(archiso): source dotfiles from a single live-env clone, not skel-only

The dotfiles clone used to land directly in /mnt/etc/skel, gated solely by
clone_skel_dotfiles. That meant run_tui=YES + clone_skel_dotfiles=NO cloned
nothing anywhere, so tui-install.sh (which only exists inside the repo, not
in the embedded live-ISO scripts) had nothing to run and the TUI step always
failed.

Clone the repo once into the live environment ($HOME/Dotfiles) whenever
either toggle is YES, then serve both the skel copy and — as a fallback
right before the TUI runs — a direct copy into the new user's home from
that single clone, no extra network fetch needed. arch-autoinstall.sh's
skel clone also moved out of the chroot heredoc so it can share the same
live clone.

When clone_skel_dotfiles=NO, the fallback copy in the new user's home is
transient: after tui-install.sh finishes, materialize every symlink that
shell-setup.sh/hyprlua/hyprland/niri point into ~/Dotfiles (shell rc's,
nvim/starship/alot/yazi/spotify-tui configs, config-updater scripts) into
real copies, then remove the checkout — so declining skel persistence
doesn't leave a system full of dangling symlinks.
main
Amir Alexander Abdelbaki 2026-07-13 14:27:12 +02:00
parent 3b67b23944
commit a24a27fff6
2 changed files with 175 additions and 25 deletions

View File

@ -532,6 +532,58 @@ fi
# outside the chroot, so env vars must be in the environment, not inline.
export HOSTNAME USERNAME USERPASS ROOT_PART KERNEL FIDO_ROOT FIDO_USER ENCRYPT_DISK KEYMAP RUN_TUI CLONE_SKEL_DOTFILES
############################################
# DOTFILES CLONE (live environment, with retry)
############################################
# The live ISO only embeds the top-level installer scripts (see build.sh) —
# tui-install.sh, its modules/, and desktopenvs/ configs exist only inside the
# full repo. Clone it ONCE into the live environment whenever either RUN_TUI
# or CLONE_SKEL_DOTFILES is YES, so both consumers below (the skel copy, and
# the fallback copy straight into the new user's home when skel is skipped
# but the TUI still needs to run) are served from one clone instead of each
# needing its own network fetch — and so a bare install genuinely fetches
# nothing at all. Done here (outside the chroot) because a clone made inside
# the chroot heredoc lives only under /mnt and can't be reused for the skel
# copy that must happen before useradd -m runs inside that same heredoc.
LIVE_DOTFILES_DIR="$HOME/Dotfiles"
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" || "${RUN_TUI^^}" == "YES" ]]; then
echo "Cloning dotfiles into the live environment ($LIVE_DOTFILES_DIR)..."
_clone_ok=false
while ! $_clone_ok; do
if [[ -d "$LIVE_DOTFILES_DIR/.git" ]]; then
_clone_ok=true
elif git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git "$LIVE_DOTFILES_DIR"; then
_clone_ok=true
else
if $AF_MODE; then
echo "Warning: dotfiles clone failed — continuing without dotfiles."
RUN_TUI="NO"; CLONE_SKEL_DOTFILES="NO"
_clone_ok=true
else
read -rp "Clone failed — retry? [y/N]: " _retry
[[ "${_retry,,}" == "y" ]] || { echo "Skipping dotfiles — clone manually after first boot."; RUN_TUI="NO"; CLONE_SKEL_DOTFILES="NO"; _clone_ok=true; }
fi
fi
done
fi
############################################
# DOTFILES CLONE TO SKEL (local copy from the live clone, gated by its own toggle)
############################################
# Independent of RUN_TUI: declining this means the new user gets a bare
# /etc/skel (system defaults) rather than a clone of the dotfiles repo sitting
# in their home directory. Copy (not clone) before entering the chroot so
# useradd -m inside will copy Dotfiles to the new user's home — no network
# needed here since the live clone above already has it.
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" ]]; then
echo "Copying dotfiles into /mnt/etc/skel..."
mkdir -p /mnt/etc/skel
cp -r "$LIVE_DOTFILES_DIR" /mnt/etc/skel/Dotfiles
mkdir -p /mnt/etc/skel/{Desktop,Documents,Downloads,Music,Pictures,Public,Templates,Videos}
else
echo "Skipping dotfiles clone to skel — clone_skel_dotfiles=NO."
fi
############################################
# CHROOT CONFIGURATION
############################################
@ -566,18 +618,9 @@ systemctl enable sshd
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
echo "root:${USERPASS}" | chpasswd
# Populate /etc/skel before user creation so useradd -m copies everything.
# Gated by its own toggle, independent of RUN_TUI: declining it means the new
# user gets a bare /etc/skel (system defaults) instead of a clone of the
# dotfiles repo sitting in their home directory.
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" ]]; then
echo "Cloning dotfiles into /etc/skel..."
git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git /etc/skel/Dotfiles \
|| echo "Warning: dotfiles clone failed — clone manually after first boot."
mkdir -p /etc/skel/{Desktop,Documents,Downloads,Music,Pictures,Public,Templates,Videos}
else
echo "Skipping dotfiles clone — clone_skel_dotfiles=NO."
fi
# /etc/skel was already populated (or intentionally left bare) from the live
# environment's dotfiles clone before this chroot — see "DOTFILES CLONE TO
# SKEL" above.
# User
# -m: create home dir (from /etc/skel above); -G wheel: add to sudoers group.
@ -692,6 +735,24 @@ if [[ "$FIDO_USER" == "YES" ]]; then
echo "FIDO2 key enrolled for $USERNAME."
fi
############################################
# ENSURE ~/Dotfiles EXISTS FOR THE TUI (fallback when skel didn't provide it)
############################################
# tui-install.sh is invoked below at /home/$USERNAME/Dotfiles/setup/tui-install.sh.
# That path only exists already if CLONE_SKEL_DOTFILES put Dotfiles in /etc/skel
# (copied into the new home by useradd -m inside the chroot). When that toggle
# was NO but RUN_TUI is YES, copy the live clone straight into the new user's
# home now so the TUI has something to run — this is what makes the two
# toggles genuinely independent instead of RUN_TUI silently depending on
# CLONE_SKEL_DOTFILES.
if [[ "${RUN_TUI^^}" == "YES" && ! -d "/mnt/home/${USERNAME}/Dotfiles" ]]; then
echo "Copying dotfiles into /home/${USERNAME} for the TUI (not persisted to skel)..."
cp -r "$LIVE_DOTFILES_DIR" "/mnt/home/${USERNAME}/Dotfiles"
_NEWUID=$(arch-chroot /mnt id -u "$USERNAME" 2>/dev/null || echo "1000")
_NEWGID=$(arch-chroot /mnt id -g "$USERNAME" 2>/dev/null || echo "1000")
chown -R "${_NEWUID}:${_NEWGID}" "/mnt/home/${USERNAME}/Dotfiles"
fi
############################################
# DOTFILES TUI SETUP (in-chroot, optional)
############################################
@ -718,6 +779,26 @@ if [[ "${RUN_TUI^^}" == "YES" ]]; then
bash "/home/${USERNAME}/Dotfiles/setup/tui-install.sh" \
|| echo "Warning: tui-install exited with errors — check ~/dotfiles-install.log in the new system."
# If clone_skel_dotfiles was declined, ~/Dotfiles only exists because of the
# fallback copy earlier and should not be left on disk. But shell-setup.sh
# and the hyprlua/hyprland/niri DE modules symlink several files straight
# into it (.bashrc/.zshrc/.vimrc, starship/nvim/alot/yazi/spotify-tui
# configs, config-updater scripts) — deleting the checkout as-is would
# leave those as dangling links. Materialize each such symlink into a real
# copy of its target first, then remove the checkout.
if [[ "${CLONE_SKEL_DOTFILES^^}" != "YES" ]]; then
echo "Materializing dotfiles symlinks and removing the transient ~/Dotfiles checkout..."
arch-chroot /mnt runuser -u "${USERNAME}" -- bash -c '
find "$HOME" -maxdepth 3 -type l 2>/dev/null | while IFS= read -r link; do
target=$(readlink -f "$link") || continue
case "$target" in
"$HOME"/Dotfiles/*) rm -f "$link"; cp -r "$target" "$link" ;;
esac
done
rm -rf "$HOME/Dotfiles"
'
fi
# Remove the temporary no-password sudoers drop-in after setup is done.
arch-chroot /mnt rm -f /etc/sudoers.d/99-setup-nopasswd
fi
@ -775,4 +856,10 @@ if [[ "${RUN_TUI^^}" != "YES" ]]; then
echo "Bare install — no dotfiles were cloned. To set up dotfiles/DE later, run:"
echo " git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git ~/Dotfiles && ~/Dotfiles/setup/tui-install.sh"
fi
elif [[ "${CLONE_SKEL_DOTFILES^^}" != "YES" ]]; then
echo
echo "~/Dotfiles was used to run setup and then removed (clone_skel_dotfiles=NO)."
echo "Configured files were copied in place, so nothing is broken — but re-clone"
echo "the repo if you want to edit dotfiles or pull updates:"
echo " git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git ~/Dotfiles"
fi

View File

@ -512,33 +512,53 @@ if $AF_MODE; then
fi
############################################
# DOTFILES CLONE TO SKEL (with retry, gated by its own toggle)
# DOTFILES CLONE (live environment, with retry)
############################################
# Independent of RUN_TUI: declining this means the new user gets a bare
# /etc/skel (system defaults) rather than a clone of the dotfiles repo sitting
# in their home directory.
# Clone before entering the chroot so useradd -m inside will copy Dotfiles to
# the new user's home. Interactive retry is available so a transient network
# failure doesn't silently leave the system without dotfiles.
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" ]]; then
echo "Cloning dotfiles into /mnt/etc/skel..."
# The live ISO only embeds the top-level installer scripts (see build.sh) —
# tui-install.sh, its modules/, and desktopenvs/ configs exist only inside the
# full repo. Clone it ONCE into the live environment whenever either RUN_TUI
# or CLONE_SKEL_DOTFILES is YES, so both consumers below (the skel copy, and
# the fallback copy straight into the new user's home when skel is skipped
# but the TUI still needs to run) are served from one clone instead of each
# needing its own network fetch — and so a bare install genuinely fetches
# nothing at all.
LIVE_DOTFILES_DIR="$HOME/Dotfiles"
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" || "${RUN_TUI^^}" == "YES" ]]; then
echo "Cloning dotfiles into the live environment ($LIVE_DOTFILES_DIR)..."
_clone_ok=false
while ! $_clone_ok; do
if git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git /mnt/etc/skel/Dotfiles; then
mkdir -p /mnt/etc/skel/{Desktop,Documents,Downloads,Music,Pictures,Public,Templates,Videos}
if [[ -d "$LIVE_DOTFILES_DIR/.git" ]]; then
_clone_ok=true
elif git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git "$LIVE_DOTFILES_DIR"; then
_clone_ok=true
else
if $AF_MODE; then
echo "Warning: dotfiles clone failed — continuing without dotfiles."
RUN_TUI="NO"; CLONE_SKEL_DOTFILES="NO"
_clone_ok=true
else
read -rp "Clone failed — retry? [y/N]: " _retry
[[ "${_retry,,}" == "y" ]] || { echo "Skipping dotfiles — clone manually after first boot."; _clone_ok=true; }
[[ "${_retry,,}" == "y" ]] || { echo "Skipping dotfiles — clone manually after first boot."; RUN_TUI="NO"; CLONE_SKEL_DOTFILES="NO"; _clone_ok=true; }
fi
fi
done
fi
############################################
# DOTFILES CLONE TO SKEL (local copy from the live clone, gated by its own toggle)
############################################
# Independent of RUN_TUI: declining this means the new user gets a bare
# /etc/skel (system defaults) rather than a clone of the dotfiles repo sitting
# in their home directory. Copy (not clone) before entering the chroot so
# useradd -m inside will copy Dotfiles to the new user's home — no network
# needed here since the live clone above already has it.
if [[ "${CLONE_SKEL_DOTFILES^^}" == "YES" ]]; then
echo "Copying dotfiles into /mnt/etc/skel..."
mkdir -p /mnt/etc/skel
cp -r "$LIVE_DOTFILES_DIR" /mnt/etc/skel/Dotfiles
mkdir -p /mnt/etc/skel/{Desktop,Documents,Downloads,Music,Pictures,Public,Templates,Videos}
else
echo "Skipping dotfiles clone — clone_skel_dotfiles=NO."
echo "Skipping dotfiles clone to skel — clone_skel_dotfiles=NO."
fi
############################################
@ -691,6 +711,23 @@ if [[ "$ENABLE_FIDO_USER" == "YES" ]]; then
echo "FIDO2 key enrolled for $USERNAME."
fi
############################################
# ENSURE ~/Dotfiles EXISTS FOR THE TUI (fallback when skel didn't provide it)
############################################
# tui-install.sh is invoked below at /home/$USERNAME/Dotfiles/setup/tui-install.sh.
# That path only exists already if CLONE_SKEL_DOTFILES put Dotfiles in /etc/skel
# (copied into the new home by useradd -m earlier). When that toggle was NO but
# RUN_TUI is YES, copy the live clone straight into the new user's home now so
# the TUI has something to run — this is what makes the two toggles genuinely
# independent instead of RUN_TUI silently depending on CLONE_SKEL_DOTFILES.
if [[ "${RUN_TUI^^}" == "YES" && ! -d "/mnt/home/${USERNAME}/Dotfiles" ]]; then
echo "Copying dotfiles into /home/${USERNAME} for the TUI (not persisted to skel)..."
cp -r "$LIVE_DOTFILES_DIR" "/mnt/home/${USERNAME}/Dotfiles"
_NEWUID=$(arch-chroot /mnt id -u "$USERNAME" 2>/dev/null || echo "1000")
_NEWGID=$(arch-chroot /mnt id -g "$USERNAME" 2>/dev/null || echo "1000")
chown -R "${_NEWUID}:${_NEWGID}" "/mnt/home/${USERNAME}/Dotfiles"
fi
############################################
# DOTFILES SETUP (in-chroot, optional)
############################################
@ -715,6 +752,26 @@ if [[ "${_DO_TUI^^}" == "YES" ]]; then
bash "/home/${USERNAME}/Dotfiles/setup/tui-install.sh" \
|| echo "Warning: tui-install exited with errors — check ~/dotfiles-install.log in the new system."
# If clone_skel_dotfiles was declined, ~/Dotfiles only exists because of the
# fallback copy above and should not be left on disk. But shell-setup.sh and
# the hyprlua/hyprland/niri DE modules symlink several files straight into
# it (.bashrc/.zshrc/.vimrc, starship/nvim/alot/yazi/spotify-tui configs,
# config-updater scripts) — deleting the checkout as-is would leave those
# as dangling links. Materialize each such symlink into a real copy of its
# target first, then remove the checkout.
if [[ "${CLONE_SKEL_DOTFILES^^}" != "YES" ]]; then
echo "Materializing dotfiles symlinks and removing the transient ~/Dotfiles checkout..."
arch-chroot /mnt runuser -u "${USERNAME}" -- bash -c '
find "$HOME" -maxdepth 3 -type l 2>/dev/null | while IFS= read -r link; do
target=$(readlink -f "$link") || continue
case "$target" in
"$HOME"/Dotfiles/*) rm -f "$link"; cp -r "$target" "$link" ;;
esac
done
rm -rf "$HOME/Dotfiles"
'
fi
# Remove the temporary no-password sudoers drop-in after setup completes.
arch-chroot /mnt rm -f /etc/sudoers.d/99-setup-nopasswd
fi
@ -739,6 +796,12 @@ if [[ "${_DO_TUI^^}" != "YES" ]]; then
echo "Bare install — no dotfiles were cloned. To set up dotfiles/DE later, run:"
echo " git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git ~/Dotfiles && ~/Dotfiles/setup/tui-install.sh"
fi
elif [[ "${CLONE_SKEL_DOTFILES^^}" != "YES" ]]; then
echo
echo "~/Dotfiles was used to run setup and then removed (clone_skel_dotfiles=NO)."
echo "Configured files were copied in place, so nothing is broken — but re-clone"
echo "the repo if you want to edit dotfiles or pull updates:"
echo " git clone https://git.abdelbaki.eu/The_miro/Dotfiles.git ~/Dotfiles"
fi
if [[ "$ENCRYPT_DISK" == "YES" ]]; then
echo