diff --git a/airootfs/usr/local/bin/alvin-install b/airootfs/usr/local/bin/alvin-install index e600cef..973e43c 100755 --- a/airootfs/usr/local/bin/alvin-install +++ b/airootfs/usr/local/bin/alvin-install @@ -539,8 +539,15 @@ install_end4_dots() { local dots_ok=true local setups_done=true + # These chowns run on the live medium, whose /etc/passwd has no + # $USERNAME — the user exists only inside $TARGET — so name lookup fails + # ("chown: invalid user"). Resolve the numeric ids from the target and + # chown by number; the catch-all at the end of this function does the same. + local owner + owner="$(arch-chroot "$TARGET" id -u "$USERNAME"):$(arch-chroot "$TARGET" id -g "$USERNAME")" + cp -a /opt/dots-hyprland "$repo_on_host" - chown -R "${USERNAME}:${USERNAME}" "$repo_on_host" + chown -R "$owner" "$repo_on_host" echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > "${TARGET}/etc/sudoers.d/99-end4-install" chmod 440 "${TARGET}/etc/sudoers.d/99-end4-install" @@ -597,10 +604,18 @@ install_end4_dots() { arch-chroot "$TARGET" systemctl enable bluetooth.service >>"$LOG" 2>&1 \ || warn "Could not enable bluetooth.service (see $LOG)." fi + # `systemctl --user` cannot work in this chroot either: it needs + # /run/user/UID/bus, which does not exist until the target boots (it only + # ever reports "Failed to connect to user scope bus"). Write the symlink + # `enable` would write — the same absolute link systemctl produces. if [[ -f "${TARGET}/usr/lib/systemd/user/ydotool.service" ]]; then - arch-chroot "$TARGET" runuser -u "$USERNAME" -- env HOME="$home_in_target" \ - systemctl --user enable ydotool.service >>"$LOG" 2>&1 \ - || warn "Could not enable ydotool.service for ${USERNAME} (see $LOG)." + local yd_wants="${TARGET}${home_in_target}/.config/systemd/user/default.target.wants" + if mkdir -p "$yd_wants" \ + && ln -sfn /usr/lib/systemd/user/ydotool.service "$yd_wants/ydotool.service"; then + log "ydotool.service enabled for ${USERNAME} (symlinked in user unit dir)." + else + warn "Could not enable ydotool.service for ${USERNAME} (see $LOG)." + fi fi # Everything end-4 answered "i" to. systemctl/gsettings are the lines known @@ -640,7 +655,6 @@ install_end4_dots() { mkdir -p "$(dirname "$fork_dst")" rm -rf "$fork_dst" cp -a "$fork_src" "$fork_dst" - chown -R "${USERNAME}:${USERNAME}" "$fork_dst" fi # Same for fish: end-4 syncs ~/.config/fish with rsync --delete, keeping @@ -659,7 +673,6 @@ install_end4_dots() { grep -qF "alias q 'qs -c end4-pC'" "${fish_dst}/config.fish" \ || warn "fish 'q' alias still points at the upstream ii config (see $LOG)." fi - chown -R "${USERNAME}:${USERNAME}" "$fish_dst" fi local configs_ok=true @@ -681,7 +694,6 @@ install_end4_dots() { if [[ -d /etc/skel/.config/hypr/custom ]]; then cp -rfT /etc/skel/.config/hypr/custom "${TARGET}${home_in_target}/.config/hypr/custom" - chown -R "${USERNAME}:${USERNAME}" "${TARGET}${home_in_target}/.config/hypr/custom" fi # Presets ship with absolute paths from the build machine; repoint them at @@ -693,6 +705,12 @@ install_end4_dots() { sed -i "s|/home/alvin/|/home/${USERNAME}/|g" "$preset" done + # Everything above that ran as root from the live medium (repo copy, + # fork/fish/hypr restores, and the presets sed -i just rewrote through a + # temp file) left root-owned files in the home — one pass fixes them all. + # Numeric ids again: this chown also runs on the medium, not in the chroot. + chown -R "$owner" "${TARGET}${home_in_target}" + if $dots_ok && $configs_ok; then log "end-4 dotfiles installed for ${USERNAME} (setups_done=${setups_done} skipped=${#ignored[@]})." ok "end-4 dotfiles installed."