Ctrl K
ComunidadGuías…

setup

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash

set -euo pipefail
shopt -s expand_aliases

declare -r githubUrl='https://github.com/5ouma/homelab'
declare -r homelab="$HOME/homelab"
TMPDIR="$(mktemp -d)" && declare -r TMPDIR

export GUM_CONFIRM_SELECTED_BACKGROUND='27'
export GUM_FORMAT_THEME="$TMPDIR/blue.json"
export GUM_INPUT_CURSOR_FOREGROUND='33'
export GUM_SPIN_SPINNER_FOREGROUND='27'
export GUM_WRITE_CURSOR_FOREGROUND='33'

declare executed=false
declare skipped=false
declare goThrough=false
declare pacmanArgs=(--noconfirm)

getGum() {
  declare -r gumVer='0.17.0'
  declare -r arch="$(uname -m)"
  declare -r gumDir="gum_${gumVer}_$(uname)_${arch/aarch64/arm64}"
  declare -r gumUrl="https://github.com/charmbracelet/gum/releases/download/v$gumVer/$gumDir.tar.gz"
  declare -r gumThemeUrl="https://raw.githubusercontent.com/5ouma/dotfiles/main/data/blue.json"

  printf '  🚚💨 Now delivering...'
  # shellcheck disable=SC2139
  curl -sL "$gumUrl" | tar --strip-components=1 -zxC "$TMPDIR" "$gumDir/gum" && alias gumCom="$TMPDIR/gum"
  printf '\r                        '

  curl -s "$gumThemeUrl" -o "$GUM_FORMAT_THEME"
} && getGum

gum() {
  case $1 in
  confirm) gumCom confirm "$2" --affirmative="$3" --negative="$4" ;;
  format) gumCom format "${@:2}" ;;
  input) gumCom input --placeholder="$2" ;;
  spin) gumCom spin --title="$2" -- "${@:4}" ;;
  style) gumCom style --foreground="$2" "${@:3}" ;;
  write) gumCom write --placeholder="$2" ;;
  executed)
    echo -en '\n  ' && gumCom format '✅ Done!'
    executed=true
    ;;
  skipped) echo -en '\n  ' && gumCom format '🟡 Skipped' ;;
  esac
}

alias skip='skipped=true && return'

shouldProceed() {
  ($goThrough || gum confirm 'Proceed?' 'Yes' 'No')
}

run() {
  gum format "$2"
  eval '$1'
  if ($skipped); then
    skipped=false
    gum skipped
  else
    gum executed
  fi
}

helpMsg() {
  gum format <<EOM
## Usage: setup

> 🥼 Self-hosted personal laboratory

## Commands:
-  help    Print help information

## Flags:
-  -y, --yes    Start without confirmation
EOM
}

errMsg() {
  declare -r stat=$1 func="${2/"$HOME"/~}" line=$3
  gum format <<EOM
> **$(gum style 1 'Error')**
> Unknown error has occurred!

> - Status:           $stat
> - File or Function: $func
> - Line Number:      $line
> - Process ID:       $$
EOM
} && trap 'errMsg $? "$0" $LINENO' ERR



if [[ ! -x $0 ]]; then
  gum format <<EOM
# Welcome to 🥼 Homelab setup!
> $githubUrl
---
EOM
fi

if (($# > 0)); then
  case "$1" in
  'help')
    helpMsg
    exit
    ;;
  '-y' | '--yes')
    goThrough=true
    ;;
  *)
    gum format <<EOM
> **$(gum style 1 'Error')**
> Unknown flag $1
EOM
    helpMsg
    exit 1
    ;;
  esac
fi

if (! $goThrough); then
  gum confirm "Let's start setup!" 'Yes!' 'No' || exit 1
  pacmanArgs=()
fi

if [[ ! -d "$homelab" ]]; then
  # shellcheck disable=SC2016
  gum spin 'Cloning the repository into `~/homelab`...' -- git clone "$githubUrl" "$homelab"
else
  gum spin 'Pulling the homelab repository...' -- git -C "$homelab" pull
fi

sudo -v


updateSystem() {
  gum spin 'Synchronizing package databases...' -- yay -Sy
  if (! yay -Qu &>/dev/null || ! shouldProceed); then
    skip
  fi

  yay -Su "${pacmanArgs[@]}"
} && run 'updateSystem' '## 🔧 Update system'

installPackages() {
  declare -r packages=(docker docker-compose firewalld jq pacman-contrib reflector tailscale)
  if (yay -Q "${packages[@]}" &>/dev/null || ! shouldProceed); then
    skip
  fi

  yay -S --needed "${pacmanArgs[@]}" "${packages[@]}"
} && run 'installPackages' '## 📦 Install packages'

enableServices() {
  declare -r services=(docker firewalld paccache.timer reflector.timer tailscaled)
  if (systemctl is-enabled "${services[@]}" | awk '$0 == "disabled" { exit 1 }' || ! shouldProceed); then
    skip
  fi

  gum spin 'Enabling services...' -- sudo systemctl enable --now "${services[@]}"
} && run 'enableServices' '## 🎽 Enable system services'

configureReflector() {
  declare -r country="$(curl -s https://ipapi.co/country_name)"
  if (grep -q -- "--country $country" /etc/xdg/reflector/reflector.conf && grep -q -- '--sort rate' /etc/xdg/reflector/reflector.conf || ! shouldProceed); then
    skip
  fi

  gum spin 'Setting auto country selection...' -- sudo sed -i "s/^# --country France,Germany/--country $country/" /etc/xdg/reflector/reflector.conf
  gum spin 'Setting sorting by rate...' -- sudo sed -i 's/^--sort age/--sort rate/' /etc/xdg/reflector/reflector.conf
} && run 'configureReflector' '## 🪞 Configure Reflector'

addToDockerGroup() {
  if (groups "$USER" | grep -q docker || ! shouldProceed); then
    skip
  fi

  gum spin 'Adding user to Docker group...' -- sudo usermod -aG docker "$USER"
} && run 'addToDockerGroup' '## 🐳 Add user to Docker group'

setHostname() {
  if [[ -n "$(hostnamectl status --pretty)" ]] || ! shouldProceed; then
    skip
  fi

  hostname=$(gum input 'Enter hostname')
  gum spin 'Setting hostname...' -- sudo hostnamectl set-hostname "${hostname// /-}"
  gum spin 'Setting pretty hostname...' -- sudo hostnamectl set-hostname --pretty "$hostname"
} && run 'setHostname' '## 🖥️ Set system hostname'

configureFirewall() {
  if (sudo firewall-cmd -q --query-service=mdns && sudo firewall-cmd -q --query-service=samba || ! shouldProceed); then
    skip
  fi

  gum spin 'Adding Samba and mDNS services...' -- sudo firewall-cmd --add-service={mdns,samba} --permanent
  gum spin 'Reloading firewall...' -- sudo firewall-cmd --reload
} && run 'configureFirewall' '## 🔥 Configure firewall'

configureBackupDrive() {
  if (grep -q /mnt/backup /etc/fstab || ! shouldProceed); then
    skip
  fi

  sudo blkid
  backupDriveUUID="$(gum input 'Enter backup drive UUID')"
  echo "UUID=$backupDriveUUID /mnt/backup ext4 defaults 0 0" | sudo tee -a /etc/fstab >/dev/null
} && run 'configureBackupDrive' '## 💾 Configure backup drive'

configureTailscale() {
  if (tailscale status &>/dev/null || ! shouldProceed); then
    skip
  fi

  sudo tailscale up --accept-routes --advertise-exit-node --ssh
  gum spin 'Setting Tailscale hostname...' -- sudo tailscale set --hostname="$(hostnamectl status --pretty)"
} && run 'configureTailscale' '## 🛣️ Configure Tailscale'


if ($executed); then
  gum format '# 🎉 Homelab setup completed!'
  gum confirm "Reboot the system?" 'Yes' 'No' && sudo reboot
else
  gum format '# 🧊 Nothing has changed'
fi