Upload files to "/"

This commit is contained in:
2026-03-25 15:22:34 +01:00
parent 073c73dad8
commit d572d37aa7
5 changed files with 739 additions and 0 deletions

459
uninstall.sh Normal file
View File

@@ -0,0 +1,459 @@
#!/bin/bash
# =============================================================================
# 🗑️ StianNOR — COMPLETE UNINSTALLER v1.0
# Uninstalls everything installed by:
# - setup_zsh_font.sh (Zsh, Oh My Zsh, p10k, plugins, colorls, fastfetch, Hack Nerd Font)
# - portainerup.sh (Portainer CE, Docker, Docker Compose)
# =============================================================================
set -uo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
LINE="────────────────────────────────────────────────────────────────────────────"
info() { echo -e "${CYAN} $*${RESET}"; }
success() { echo -e "${GREEN}$*${RESET}"; }
warn() { echo -e "${YELLOW}$*${RESET}"; }
error() { echo -e "${RED}$*${RESET}"; }
step() { echo -e "\n${BOLD}${BLUE}$*${RESET}"; echo -e "${BLUE}${LINE}${RESET}"; }
skip() { echo -e " ${BLUE}$* — not found, skipping${RESET}"; }
# =============================================================================
# DETECT PACKAGE MANAGER
# =============================================================================
detect_pm() {
if command -v pacman >/dev/null 2>&1; then PM="pacman"
elif command -v apt >/dev/null 2>&1; then PM="apt"
elif command -v dnf >/dev/null 2>&1; then PM="dnf"
elif command -v zypper >/dev/null 2>&1; then PM="zypper"
elif command -v apk >/dev/null 2>&1; then PM="apk"
else PM="unknown"; fi
}
detect_pm
pkg_remove() {
case "$PM" in
pacman) sudo pacman -Rns --noconfirm "$@" 2>/dev/null || true ;;
apt) sudo apt remove -y --purge "$@" 2>/dev/null || true; sudo apt autoremove -y 2>/dev/null || true ;;
dnf) sudo dnf remove -y "$@" 2>/dev/null || true ;;
zypper) sudo zypper remove -y "$@" 2>/dev/null || true ;;
apk) sudo apk del "$@" 2>/dev/null || true ;;
esac
}
# =============================================================================
# CONFIRM — show full plan before doing anything
# =============================================================================
clear
echo -e "${LINE}"
echo -e "${BOLD}${RED} 🗑️ StianNOR COMPLETE UNINSTALLER${RESET}"
echo -e "${LINE}"
echo ""
echo -e " This will remove the following — ${BOLD}select what to uninstall:${RESET}"
echo ""
echo -e " ${BOLD}${CYAN}[A] ZSH + FONT SETUP${RESET}"
echo -e " • Hack Nerd Font (system-wide)"
echo -e " • fontconfig monospace alias (/etc/fonts/local.conf)"
echo -e " • Oh My Zsh + Powerlevel10k + all plugins"
echo -e " • colorls Ruby gem"
echo -e " • fastfetch"
echo -e " • ~/.zshrc and ~/.p10k.zsh"
echo -e " • Default shell reverted to bash"
echo ""
echo -e " ${BOLD}${CYAN}[B] PORTAINER + DOCKER${RESET}"
echo -e " • Portainer CE container + data volume"
echo -e " • Docker CE + Docker Compose"
echo -e " • docker group membership for $USER"
echo -e " • Docker config dir (~/.docker)"
echo ""
echo -e " ${BOLD}${CYAN}[C] BOTH (full wipe)${RESET}"
echo ""
echo -e "${LINE}"
echo -e " ${YELLOW}[q]${RESET} cancel and exit"
echo -e "${LINE}"
echo ""
printf " Choice: "
read -r CHOICE
echo ""
case "${CHOICE,,}" in
a) DO_ZSH=true; DO_DOCKER=false ;;
b) DO_ZSH=false; DO_DOCKER=true ;;
c) DO_ZSH=true; DO_DOCKER=true ;;
q|"") echo -e " ${YELLOW}Cancelled.${RESET}"; exit 0 ;;
*) echo -e " ${RED}Invalid choice. Exiting.${RESET}"; exit 1 ;;
esac
# Final confirm
echo -e "${LINE}"
echo -e " ${BOLD}${RED}This is destructive and cannot be undone.${RESET}"
printf " Type ${BOLD}YES${RESET} to confirm: "
read -r CONFIRM
echo ""
[[ "$CONFIRM" != "YES" ]] && echo -e " ${YELLOW}Aborted.${RESET}" && exit 0
# =============================================================================
# LOG FILE
# =============================================================================
LOG_DIR="$HOME/Homelab/logs"
mkdir -p "$LOG_DIR" 2>/dev/null || LOG_DIR="/tmp"
LOG_FILE="$LOG_DIR/uninstall-$(date +%Y%m%d-%H%M%S).log"
exec > >(tee -a "$LOG_FILE") 2>&1
info "Logging to $LOG_FILE"
# =============================================================================
# A — UNINSTALL ZSH + FONT SETUP
# =============================================================================
uninstall_zsh_font() {
# ── 1. Revert default shell to bash ──────────────────────────────────────
step "Reverting default shell to bash"
BASH_PATH=$(command -v bash 2>/dev/null || echo "/bin/bash")
CURRENT_SHELL=$(getent passwd "$USER" | cut -d: -f7)
if [[ "$CURRENT_SHELL" == *zsh* ]]; then
grep -qxF "$BASH_PATH" /etc/shells || echo "$BASH_PATH" | sudo tee -a /etc/shells
if chsh -s "$BASH_PATH" 2>/dev/null; then
success "Default shell reverted to $BASH_PATH"
else
warn "Could not change shell automatically — run: chsh -s $BASH_PATH"
fi
else
skip "Shell was not zsh ($CURRENT_SHELL)"
fi
# ── 2. Remove Oh My Zsh ──────────────────────────────────────────────────
step "Removing Oh My Zsh"
if [[ -d "$HOME/.oh-my-zsh" ]]; then
rm -rf "$HOME/.oh-my-zsh"
success "Oh My Zsh removed"
else
skip "~/.oh-my-zsh"
fi
# ── 3. Remove Powerlevel10k (standalone clone, if outside OMZ) ───────────
step "Removing Powerlevel10k"
for p10k_path in \
"$HOME/.oh-my-zsh/custom/themes/powerlevel10k" \
"$HOME/powerlevel10k" \
"${ZSH_CUSTOM:-}/themes/powerlevel10k"; do
if [[ -d "$p10k_path" ]]; then
rm -rf "$p10k_path"
success "Removed $p10k_path"
fi
done
# ── 4. Remove Zsh plugin dirs ─────────────────────────────────────────────
step "Removing Zsh plugins"
for plugin in zsh-autosuggestions zsh-syntax-highlighting zsh-completions; do
PLUGIN_DIR="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/$plugin"
if [[ -d "$PLUGIN_DIR" ]]; then
rm -rf "$PLUGIN_DIR"
success "Removed plugin: $plugin"
else
skip "Plugin $plugin"
fi
done
# ── 5. Remove colorls gem ─────────────────────────────────────────────────
step "Removing colorls Ruby gem"
if gem list -i colorls >/dev/null 2>&1; then
gem uninstall colorls -a -x 2>/dev/null && success "colorls removed" \
|| warn "colorls uninstall had warnings"
else
skip "colorls gem"
fi
# Clean up gem home if empty
GEM_HOME_DIR="$HOME/.gem"
if [[ -d "$GEM_HOME_DIR" ]]; then
REMAINING=$(find "$GEM_HOME_DIR" -name "*.gemspec" 2>/dev/null | wc -l)
if [[ "$REMAINING" -eq 0 ]]; then
rm -rf "$GEM_HOME_DIR"
success "Removed empty ~/.gem"
else
info "$REMAINING other gems remain in ~/.gem — leaving it"
fi
fi
# ── 6. Remove fastfetch ───────────────────────────────────────────────────
step "Removing fastfetch"
if command -v fastfetch >/dev/null 2>&1; then
FF_PATH=$(command -v fastfetch)
# If installed via package manager
removed=false
case "$PM" in
pacman) sudo pacman -Rns --noconfirm fastfetch 2>/dev/null && removed=true ;;
apt) sudo apt remove -y --purge fastfetch 2>/dev/null && removed=true ;;
dnf) sudo dnf remove -y fastfetch 2>/dev/null && removed=true ;;
zypper) sudo zypper remove -y fastfetch 2>/dev/null && removed=true ;;
apk) sudo apk del fastfetch 2>/dev/null && removed=true ;;
esac
# If it was a manually installed binary
if [[ "$removed" == false ]] || command -v fastfetch >/dev/null 2>&1; then
sudo rm -f /usr/local/bin/fastfetch /usr/bin/fastfetch 2>/dev/null || true
fi
command -v fastfetch >/dev/null 2>&1 \
&& warn "fastfetch still found at $(command -v fastfetch) — remove manually" \
|| success "fastfetch removed"
else
skip "fastfetch"
fi
# ── 7. Remove Zsh itself ──────────────────────────────────────────────────
step "Removing Zsh"
if command -v zsh >/dev/null 2>&1; then
printf " Remove zsh package itself? (leaves system zsh on some distros) [y/N]: "
read -r yn
if [[ "${yn,,}" == "y" ]]; then
pkg_remove zsh
command -v zsh >/dev/null 2>&1 \
&& warn "zsh still present (may be a system dependency)" \
|| success "zsh removed"
else
info "Zsh package kept (shell reverted to bash above)"
fi
else
skip "zsh (not installed)"
fi
# ── 8. Remove dot files ───────────────────────────────────────────────────
step "Removing ~/.zshrc and ~/.p10k.zsh"
for f in "$HOME/.zshrc" "$HOME/.p10k.zsh" "$HOME/.zsh_history"; do
if [[ -f "$f" ]]; then
# Back up before deleting
cp "$f" "${f}.uninstall-backup-$(date +%Y%m%d)" 2>/dev/null || true
rm -f "$f"
success "Removed $f (backup saved as ${f}.uninstall-backup-*)"
else
skip "$f"
fi
done
# ── 9. Remove Hack Nerd Font ──────────────────────────────────────────────
step "Removing Hack Nerd Font"
FONT_DIR="/usr/local/share/fonts/nerd-fonts"
if [[ -d "$FONT_DIR" ]]; then
sudo rm -rf "$FONT_DIR"
sudo fc-cache -f 2>/dev/null || true
success "Hack Nerd Font removed from $FONT_DIR"
else
skip "$FONT_DIR"
fi
# Also check user font dir
USER_FONT_DIR="$HOME/.local/share/fonts/nerd-fonts"
if [[ -d "$USER_FONT_DIR" ]]; then
rm -rf "$USER_FONT_DIR"
fc-cache -f "$HOME/.local/share/fonts" 2>/dev/null || true
success "Removed user font dir $USER_FONT_DIR"
fi
# ── 10. Remove fontconfig override ───────────────────────────────────────
step "Removing fontconfig monospace alias"
if [[ -f /etc/fonts/local.conf ]]; then
if grep -q "Hack Nerd Font" /etc/fonts/local.conf 2>/dev/null; then
sudo rm -f /etc/fonts/local.conf
sudo fc-cache -f 2>/dev/null || true
success "Removed /etc/fonts/local.conf"
else
info "/etc/fonts/local.conf exists but doesn't contain Hack Nerd Font — leaving it"
fi
else
skip "/etc/fonts/local.conf"
fi
# ── 11. Clean up PATH entries added to shell rc files ────────────────────
step "Cleaning gem PATH entries from shell rc files"
for rc in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.profile"; do
if [[ -f "$rc" ]]; then
if grep -q "\.gem" "$rc" 2>/dev/null; then
sed -i '/\.gem\/ruby/d' "$rc" 2>/dev/null || true
sed -i '/GEM_HOME/d' "$rc" 2>/dev/null || true
success "Cleaned gem PATH from $rc"
fi
fi
done
}
# =============================================================================
# B — UNINSTALL PORTAINER + DOCKER
# =============================================================================
uninstall_docker_portainer() {
# ── 1. Stop and remove Portainer ─────────────────────────────────────────
step "Removing Portainer CE"
if command -v docker >/dev/null 2>&1; then
DOCKER_CMD="docker"
docker info >/dev/null 2>&1 || DOCKER_CMD="sudo docker"
if $DOCKER_CMD ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^portainer$"; then
$DOCKER_CMD stop portainer 2>/dev/null || true
$DOCKER_CMD rm portainer 2>/dev/null || true
success "Portainer container stopped and removed"
else
skip "Portainer container"
fi
# Remove portainer data volume
if $DOCKER_CMD volume ls --format '{{.Name}}' 2>/dev/null | grep -q "^portainer_data$"; then
printf " Remove portainer_data volume? This deletes all Portainer settings [y/N]: "
read -r yn
if [[ "${yn,,}" == "y" ]]; then
$DOCKER_CMD volume rm portainer_data 2>/dev/null || true
success "portainer_data volume removed"
else
info "portainer_data volume kept"
fi
else
skip "portainer_data volume"
fi
# Remove the image
if $DOCKER_CMD image ls --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q "portainer/portainer-ce"; then
printf " Remove Portainer CE docker image? [y/N]: "
read -r yn
if [[ "${yn,,}" == "y" ]]; then
$DOCKER_CMD rmi portainer/portainer-ce:latest 2>/dev/null || true
success "Portainer CE image removed"
else
info "Portainer CE image kept"
fi
fi
else
skip "Docker not installed — Portainer check skipped"
fi
# ── 2. Remove Docker ──────────────────────────────────────────────────────
step "Removing Docker"
if command -v docker >/dev/null 2>&1; then
printf " ${BOLD}${RED}Remove Docker CE completely?${RESET} This removes ALL containers, images and volumes [y/N]: "
read -r yn
if [[ "${yn,,}" != "y" ]]; then
info "Docker kept — only Portainer was removed"
return
fi
# Stop daemon first
sudo systemctl stop docker docker.socket 2>/dev/null || sudo service docker stop 2>/dev/null || true
sudo systemctl disable docker docker.socket 2>/dev/null || true
case "$PM" in
pacman)
sudo pacman -Rns --noconfirm docker docker-compose 2>/dev/null || true
;;
apt)
sudo apt remove -y --purge \
docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin \
docker-compose 2>/dev/null || true
sudo apt autoremove -y 2>/dev/null || true
# Remove Docker apt repo
sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /etc/apt/keyrings/docker.gpg
sudo apt update -qq 2>/dev/null || true
;;
dnf)
sudo dnf remove -y \
docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin 2>/dev/null || true
sudo rm -f /etc/yum.repos.d/docker-ce.repo 2>/dev/null || true
;;
zypper)
sudo zypper remove -y docker docker-compose 2>/dev/null || true
;;
apk)
sudo apk del docker docker-compose 2>/dev/null || true
sudo rc-update del docker boot 2>/dev/null || true
;;
esac
# Remove standalone docker-compose binary if present
[[ -f /usr/local/bin/docker-compose ]] && sudo rm -f /usr/local/bin/docker-compose \
&& success "Removed standalone docker-compose"
success "Docker CE removed"
else
skip "Docker (not installed)"
fi
# ── 3. Remove Docker data directories ────────────────────────────────────
step "Removing Docker data directories"
for dir in /var/lib/docker /var/lib/containerd /etc/docker; do
if [[ -d "$dir" ]]; then
printf " Remove %s? [y/N]: " "$dir"
read -r yn
if [[ "${yn,,}" == "y" ]]; then
sudo rm -rf "$dir"
success "Removed $dir"
else
info "Kept $dir"
fi
else
skip "$dir"
fi
done
# Remove user docker config
if [[ -d "$HOME/.docker" ]]; then
rm -rf "$HOME/.docker"
success "Removed ~/.docker"
fi
# ── 4. Remove user from docker group ─────────────────────────────────────
step "Removing $USER from docker group"
if getent group docker >/dev/null 2>&1; then
if groups "$USER" | grep -qw docker; then
sudo gpasswd -d "$USER" docker 2>/dev/null \
&& success "$USER removed from docker group" \
|| warn "Could not remove $USER from docker group"
else
skip "$USER was not in docker group"
fi
printf " Delete the docker group itself? [y/N]: "
read -r yn
if [[ "${yn,,}" == "y" ]]; then
sudo groupdel docker 2>/dev/null && success "docker group deleted" \
|| warn "Could not delete docker group"
fi
else
skip "docker group (does not exist)"
fi
# ── 5. Remove Docker socket and service files (if any remain) ────────────
step "Cleaning up Docker service files"
for f in \
/lib/systemd/system/docker.service \
/lib/systemd/system/docker.socket \
/etc/systemd/system/docker.service \
/etc/systemd/system/docker.socket; do
if [[ -f "$f" ]]; then
sudo rm -f "$f"
success "Removed $f"
fi
done
sudo systemctl daemon-reload 2>/dev/null || true
}
# =============================================================================
# RUN SELECTED SECTIONS
# =============================================================================
[[ "$DO_ZSH" == true ]] && uninstall_zsh_font
[[ "$DO_DOCKER" == true ]] && uninstall_docker_portainer
# =============================================================================
# DONE
# =============================================================================
echo ""
echo -e "${LINE}"
echo -e "${BOLD}${GREEN} ✅ Uninstall complete!${RESET}"
echo -e "${LINE}"
[[ "$DO_ZSH" == true ]] && echo -e " ${CYAN}Zsh/Font:${RESET} removed — default shell reverted to bash"
[[ "$DO_DOCKER" == true ]] && echo -e " ${CYAN}Docker:${RESET} removed — log out and back in to clear group session"
echo -e " ${YELLOW}Log:${RESET} $LOG_FILE"
echo -e "${LINE}"
echo ""
if [[ "$DO_ZSH" == true ]]; then
echo -e " ${YELLOW}Note:${RESET} Log out and back in for shell change to take full effect."
fi
if [[ "$DO_DOCKER" == true ]]; then
echo -e " ${YELLOW}Note:${RESET} Log out and back in to clear docker group from your session."
fi
echo ""