modules: target $TARGET_USER (docker group, zsh/nvim/nvm homes, chown tree)

This commit is contained in:
mk 2026-07-28 05:05:03 +03:00
parent 8a516f039c
commit e7a9349292
4 changed files with 52 additions and 43 deletions

View File

@ -24,13 +24,13 @@ run_docker() {
warn "systemctl unavailable — start docker manually if needed" warn "systemctl unavailable — start docker manually if needed"
fi fi
# add current user to docker group # add the config target user to the docker group (created-user or self)
if getent group docker >/dev/null 2>&1; then if getent group docker >/dev/null 2>&1; then
if id -nG "$USER" | grep -qw docker; then if id -nG "${TARGET_USER:-$USER}" | grep -qw docker; then
ok "$USER already in docker group" ok "${TARGET_USER:-$USER} already in docker group"
else else
sudo_ usermod -aG docker "$USER" sudo_ usermod -aG docker "${TARGET_USER:-$USER}"
ok "$USER added to docker group (log out/in or 'newgrp docker' to use it)" ok "${TARGET_USER:-$USER} added to docker group (log out/in or 'newgrp docker' to use it)"
fi fi
fi fi
} }

View File

@ -5,18 +5,31 @@ step_name="shell-zsh"
step_desc="zsh + oh-my-zsh + plugins, set default shell, ship config" step_desc="zsh + oh-my-zsh + plugins, set default shell, ship config"
step_run="run_zsh" step_run="run_zsh"
ZSH="${ZSH:-$HOME/.oh-my-zsh}" # All paths resolve against the config TARGET (set by 05-create-user).
ZSH="${ZSH:-$TARGET_HOME/.oh-my-zsh}"
ZSH_CUSTOM="${ZSH_CUSTOM:-$ZSH/custom}" ZSH_CUSTOM="${ZSH_CUSTOM:-$ZSH/custom}"
ZDOTDIR_TARGET="${ZDOTDIR_TARGET:-$HOME/.config/zsh}" ZDOTDIR_TARGET="${ZDOTDIR_TARGET:-$TARGET_HOME/.config/zsh}"
run_zsh() { run_zsh() {
log "installing zsh + oh-my-zsh" log "installing zsh + oh-my-zsh"
_install_zsh _install_zsh
_install_omz _install_omz
_install_plugins _install_plugins
_chown_target_tree
_ship_config _ship_config
_set_default_shell _set_default_shell
if [[ "$TARGET_USER" != "$USER" ]]; then
log "zsh ready. Start it as $TARGET_USER: sudo -iu $TARGET_USER"
else
ok "zsh ready — start it with: exec zsh" ok "zsh ready — start it with: exec zsh"
fi
}
_chown_target_tree() {
# when running as root for a created user, make omz + plugins + config owned by them
if [[ "$TARGET_USER" == "$USER" ]]; then return; fi
local grp; grp="$(id -gn "$TARGET_USER" 2>/dev/null || echo "$TARGET_USER")"
chown -R "$TARGET_USER:$grp" "$ZSH" "$ZDOTDIR_TARGET" "$TARGET_HOME/.zshrc" 2>/dev/null || true
} }
_install_zsh() { _install_zsh() {
@ -55,7 +68,6 @@ _ship_config() {
log "shipping zsh config to $ZDOTDIR_TARGET" log "shipping zsh config to $ZDOTDIR_TARGET"
mkdir -p "$ZDOTDIR_TARGET" mkdir -p "$ZDOTDIR_TARGET"
local f local f
local f
for f in zshrc aliases.zsh functions.zsh path.zsh plugins.zsh; do for f in zshrc aliases.zsh functions.zsh path.zsh plugins.zsh; do
local src="$BOOT_DIR/config/zsh/$f" local src="$BOOT_DIR/config/zsh/$f"
[[ -f "$src" ]] || continue [[ -f "$src" ]] || continue
@ -67,8 +79,8 @@ _ship_config() {
if [[ ! -f "$ZDOTDIR_TARGET/aliases-extras.zsh" ]]; then if [[ ! -f "$ZDOTDIR_TARGET/aliases-extras.zsh" ]]; then
cp "$BOOT_DIR/config/zsh/aliases-extras.zsh" "$ZDOTDIR_TARGET/aliases-extras.zsh" cp "$BOOT_DIR/config/zsh/aliases-extras.zsh" "$ZDOTDIR_TARGET/aliases-extras.zsh"
fi fi
# ~/.zshrc shim that loads our real config via ZDOTDIR (so omz $ZSH + plugins resolve) # ~/.zshrc shim that loads our real config via ZDOTDIR
local shim="$HOME/.zshrc" local shim="$TARGET_HOME/.zshrc"
if ! grep -q 'BOOTSTRAP ZDOTDIR' "$shim" 2>/dev/null; then if ! grep -q 'BOOTSTRAP ZDOTDIR' "$shim" 2>/dev/null; then
cat >> "$shim" <<'EOF' cat >> "$shim" <<'EOF'
@ -77,7 +89,11 @@ export ZDOTDIR="${ZDOTDIR:-$HOME/.config/zsh}"
[[ -f "$ZDOTDIR/zshrc" ]] && source "$ZDOTDIR/zshrc" [[ -f "$ZDOTDIR/zshrc" ]] && source "$ZDOTDIR/zshrc"
EOF EOF
fi fi
ok "zsh config installed ($ZDOTDIR_TARGET) + ~/.zshrc shim" # ensure the whole shipped tree is owned by the target user
if [[ "$TARGET_USER" != "$USER" ]]; then
chown -R "$TARGET_USER:$(id -gn "$TARGET_USER" 2>/dev/null || echo "$TARGET_USER")" "$ZDOTDIR_TARGET" "$shim"
fi
ok "zsh config installed ($ZDOTDIR_TARGET) + $shim shim"
} }
_set_default_shell() { _set_default_shell() {
@ -87,13 +103,13 @@ _set_default_shell() {
if ! grep -qx "$zsh_bin" /etc/shells 2>/dev/null; then if ! grep -qx "$zsh_bin" /etc/shells 2>/dev/null; then
echo "$zsh_bin" | sudo_ tee -a /etc/shells >/dev/null echo "$zsh_bin" | sudo_ tee -a /etc/shells >/dev/null
fi fi
if [[ "$SHELL" != "$zsh_bin" ]] && [[ "$(getent passwd "$USER" | cut -d: -f7)" != "$zsh_bin" ]]; then if [[ "$(getent passwd "$TARGET_USER" | cut -d: -f7)" != "$zsh_bin" ]]; then
if yn "Set zsh as default login shell for $USER?" y; then if yn "Set zsh as default login shell for $TARGET_USER?" y; then
sudo_ chsh -s "$zsh_bin" "$USER" && ok "default shell set to zsh" sudo_ chsh -s "$zsh_bin" "$TARGET_USER" && ok "default shell set to zsh for $TARGET_USER"
else else
warn "zsh not set as default — run 'chsh -s $zsh_bin' later" warn "zsh not set as default — run 'chsh -s $zsh_bin' for $TARGET_USER' later"
fi fi
else else
ok "zsh already your default shell" ok "zsh already the default shell for $TARGET_USER"
fi fi
} }

View File

@ -2,30 +2,25 @@
# 35-nvm — Node Version Manager + Node LTS. # 35-nvm — Node Version Manager + Node LTS.
step_name="nvm" step_name="nvm"
step_desc="nvm into ~/.nvm, install Node LTS" step_desc="nvm into ~$TARGET_USER/.nvm, install Node LTS"
step_run="run_nvm" step_run="run_nvm"
run_nvm() { run_nvm() {
log "installing nvm" log "installing nvm for $TARGET_USER"
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" local nvm_home="$TARGET_HOME/.nvm"
export NVM_DIR="$nvm_home"
if [[ -s "$NVM_DIR/nvm.sh" ]]; then if [[ -s "$NVM_DIR/nvm.sh" ]]; then
ok "nvm already present at $NVM_DIR" ok "nvm already present at $NVM_DIR"
else else
# fetch the install script at a pinned NVM version (update here to upgrade) # fetch the install script at a pinned NVM version (update here to upgrade)
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \ as_user env NVM_DIR="$nvm_home" bash -c 'curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash' \
|| { warn "nvm install failed"; return; } || { warn "nvm install failed"; return; }
ok "nvm installed to $NVM_DIR" ok "nvm installed to $NVM_DIR"
fi fi
# shellcheck disable=SC1091 # run node/lts install as the target user so binary ownership + default are theirs
source "$NVM_DIR/nvm.sh" as_user bash -lc 'export NVM_DIR='"$NVM_DIR"'; source "$NVM_DIR/nvm.sh"; nvm install --lts && nvm use --lts && nvm alias default lts/*' \
if command -v nvm >/dev/null 2>&1; then || warn "node lts install had issues (continue; run 'nvm install --lts' as $TARGET_USER)"
log "installing Node LTS via nvm" as_user bash -lc 'export NVM_DIR='"$NVM_DIR"'; source "$NVM_DIR/nvm.sh"; command -v node >/dev/null && echo " node \$(node -v) active for $TARGET_USER"' 2>/dev/null || true
nvm install --lts || warn "nvm install --lts failed"
nvm use --lts 2>/dev/null || true
nvm alias default 'lts/*' 2>/dev/null || true
command -v node >/dev/null 2>&1 && ok "node $(node -v) active"
else
warn "nvm.sh sourced but nvm not available — check $NVM_DIR"
fi
} }

View File

@ -1,8 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# 40-nvim — clone your nvim-minimal config from gitea to ~/.config/nvim. # 40-nvim — clone your nvim-minimal config from gitea to ~$TARGET_USER/.config/nvim.
step_name="nvim" step_name="nvim"
step_desc="clone g.mk.fo/bootstrap/nvim-minimal -> ~/.config/nvim" step_desc="clone g.mk.fo/bootstrap/nvim-minimal -> ~$TARGET_USER/.config/nvim"
step_run="run_nvim" step_run="run_nvim"
NVIM_REPO_URL="${NVIM_REPO_URL:-https://g.mk.fo/bootstrap/nvim-minimal.git}" NVIM_REPO_URL="${NVIM_REPO_URL:-https://g.mk.fo/bootstrap/nvim-minimal.git}"
@ -11,24 +11,22 @@ run_nvim() {
log "installing nvim config" log "installing nvim config"
command -v nvim >/dev/null 2>&1 || warn "nvim binary not found — install the packages step first" command -v nvim >/dev/null 2>&1 || warn "nvim binary not found — install the packages step first"
local target="${XDG_CONFIG_HOME:-$HOME/.config}/nvim" local target="$TARGET_HOME/.config/nvim"
if [[ -d "$target/.git" ]]; then if [[ -d "$target/.git" ]]; then
log "existing nvim config is a git repo — pulling" log "existing nvim config is a git repo — pulling"
git -C "$target" pull --ff-only || warn "could not pull existing nvim config" as_user git -C "$target" pull --ff-only || warn "could not pull existing nvim config"
ok "nvim config updated at $target" ok "nvim config updated at $target"
return return
fi fi
if [[ -e "$target" ]]; then if [[ -e "$target" ]]; then
local bak="${target}.bak.$(date +%Y%m%d-%H%M%S)" local bak="${target}.bak.$(date +%Y%m%d-%H%M%S)"
mv "$target" "$bak" as_user mv "$target" "$bak" 2>/dev/null || sudo_ mv "$target" "$bak"
warn "backed up existing $target -> $bak" warn "backed up existing $target -> $bak"
fi fi
if git clone "$NVIM_REPO_URL" "$target"; then as_user git clone "$NVIM_REPO_URL" "$target" && ok "nvim config cloned to $target" \
ok "nvim config cloned to $target" || { err "failed to clone $NVIM_REPO_URL"; sudo_ git clone "$NVIM_REPO_URL" "$target" \
else && chown -R "$TARGET_USER:$(id -gn "$TARGET_USER" 2>/dev/null || echo "$TARGET_USER")" "$target" \
err "failed to clone $NVIM_REPO_URL" && ok "nvim config cloned to $target (as root, then chowned)"; }
return 1
fi
} }