diff --git a/scripts/cloudflared-ssh.sh b/scripts/cloudflared-ssh.sh index 95c87345..8069da30 100644 --- a/scripts/cloudflared-ssh.sh +++ b/scripts/cloudflared-ssh.sh @@ -42,10 +42,23 @@ # # [SSH with short-lived certificates](https://developers.cloudflare.com/cloudflare-one/tutorials/ssh-cert-bastion/) -# @description Logs with style using Gum if it is installed, otherwise it uses `echo`. It also leverages Glow to render markdown. -# When Glow is not installed, it uses `cat`. +# @description This function logs with style using Gum if it is installed, otherwise it uses `echo`. It is also capable of leveraging Glow to render markdown. +# When Glow is not installed, it uses `cat`. The following sub-commands are available: +# +# | Sub-Command | Description | +# |-------------|-----------------------------------------------------------------------------------------------------| +# | `error` | Logs a bright red error message | +# | `info` | Logs a regular informational message | +# | `md` | Tries to render the specified file using `glow` if it is installed and uses `cat` as a fallback | +# | `prompt` | Alternative that logs a message intended to describe an upcoming user input prompt | +# | `star` | Alternative that logs a message that starts with a star icon | +# | `start` | Same as `success` | +# | `success` | Logs a success message that starts with green checkmark | +# | `warn` | Logs a bright yellow warning message | # @example # logger info "An informative log" +# @example +# logger md ~/README.md logg() { TYPE="$1" MSG="$2" @@ -105,111 +118,127 @@ logg() { fi fi } -# @description Ensure dependencies like `git` and `curl` are installed (among a few other lightweight system packages) - -if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then - if command -v apt-get > /dev/null; then - ### Debian / Ubuntu - logg info 'Running sudo apt-get update' && sudo apt-get update - logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file - elif command -v dnf > /dev/null; then - ### Fedora - logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' - logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file - elif command -v yum > /dev/null; then - ### CentOS - logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' - logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file - elif command -v pacman > /dev/null; then - ### Archlinux - logg info 'Running sudo pacman update' && sudo pacman update - logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file - elif command -v zypper > /dev/null; then - ### OpenSUSE - logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis - logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file - elif command -v apk > /dev/null; then - ### Alpine - logg info 'Running apk add build-base curl expect git rsync procps file' && apk add build-base curl expect git rsync procps file - elif [ -d /Applications ] && [ -d /Library ]; then - ### macOS - logg info "Ensuring Xcode Command Line Tools are installed.." - if ! xcode-select -p >/dev/null 2>&1; then - logg info "Command Line Tools for Xcode not found" - ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools - touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; - XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" - logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" +# @description This function ensures dependencies like `git` and `curl` are installed. More specifically, this function will: +# +# 1. Check if `curl`, `git`, `expect`, `rsync`, and `unbuffer` are on the system +# 2. If any of the above are missing, it will then use the appropriate system package manager to satisfy the requirements. *Note that some of the requirements are not scanned for in order to keep it simple and fast.* +# 3. On macOS, the official Xcode Command Line Tools are installed. +ensureBasicDeps() { + if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then + if command -v apt-get > /dev/null; then + ### Debian / Ubuntu + logg info 'Running sudo apt-get update' && sudo apt-get update + logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file + elif command -v dnf > /dev/null; then + ### Fedora + logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' + logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file + elif command -v yum > /dev/null; then + ### CentOS + logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' + logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file + elif command -v pacman > /dev/null; then + ### Archlinux + logg info 'Running sudo pacman update' && sudo pacman update + logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file + elif command -v zypper > /dev/null; then + ### OpenSUSE + logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis + logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file + elif command -v apk > /dev/null; then + ### Alpine + logg info 'Running sudo apk add build-base curl expect git rsync ruby procps file' && sudo apk add build-base curl expect git rsync ruby procps file + elif [ -d /Applications ] && [ -d /Library ]; then + ### macOS + logg info "Ensuring Xcode Command Line Tools are installed.." + if ! xcode-select -p >/dev/null 2>&1; then + logg info "Command Line Tools for Xcode not found" + ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; + XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" + logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" + fi + elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then + ### Windows + logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync + elif command -v nix-env > /dev/null; then + ### NixOS + logg warn "TODO - Add support for NixOS" + elif [[ "$OSTYPE" == 'freebsd'* ]]; then + ### FreeBSD + logg warn "TODO - Add support for FreeBSD" + elif command -v pkg > /dev/null; then + ### Termux + logg warn "TODO - Add support for Termux" + elif command -v xbps-install > /dev/null; then + ### Void + logg warn "TODO - Add support for Void" fi - elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then - ### Windows - logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync - elif command -v nix-env > /dev/null; then - ### NixOS - logg warn "TODO - Add support for NixOS" - elif [[ "$OSTYPE" == 'freebsd'* ]]; then - ### FreeBSD - logg warn "TODO - Add support for FreeBSD" - elif command -v pkg > /dev/null; then - ### Termux - logg warn "TODO - Add support for Termux" - elif command -v xbps-install > /dev/null; then - ### Void - logg warn "TODO - Add support for Void" fi -fi -# @description Ensure Homebrew is installed and available in the `PATH` -if ! command -v brew > /dev/null; then - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - elif [ -d "$HOME/.linuxbrew" ]; then - logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - else - ### Installs Homebrew and addresses a couple potential issues - if command -v sudo > /dev/null && sudo -n true; then - logg info "Installing Homebrew" - echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +} +ensureBasicDeps + +# @description This function ensures Homebrew is installed and available in the `PATH`. It handles the installation of Homebrew on both **Linux and macOS**. +# It will attempt to bypass sudo password entry if it detects that it can do so. The function also has some error handling in regards to various +# directories falling out of the correct ownership and permission states. Finally, it loads Homebrew into the active profile (allowing other parts of the script +# to use the `brew` command). +# +# With Homebrew installed and available, the script finishes by installing the `gcc` Homebrew package which is a very common dependency. +ensureHomebrew() { + if ! command -v brew > /dev/null; then + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi + elif [ -d "$HOME/.linuxbrew" ]; then + logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi else - logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" - if [ -n "$BREW_EXIT_CODE" ]; then - if command -v brew > /dev/null; then - logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." - BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" - for BREW_DIR in $BREW_DIRS; do - if [ -d "$(brew --prefix)/$BREW_DIR" ]; then - logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" - fi - done - logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + ### Installs Homebrew and addresses a couple potential issues + if command -v sudo > /dev/null && sudo -n true; then + logg info "Installing Homebrew" + echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + else + logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" + if [ -n "$BREW_EXIT_CODE" ]; then + if command -v brew > /dev/null; then + logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." + BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" + for BREW_DIR in $BREW_DIRS; do + if [ -d "$(brew --prefix)/$BREW_DIR" ]; then + logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" + fi + done + logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + fi fi fi - fi - ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - elif [ -f /opt/homebrew/bin/brew ]; then - logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + elif [ -f /opt/homebrew/bin/brew ]; then + logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + fi fi fi -fi -### Ensure GCC is installed via Homebrew -if command -v brew > /dev/null; then - if ! brew list | grep gcc > /dev/null; then - logg info "Installing Homebrew gcc" && brew install gcc + ### Ensure GCC is installed via Homebrew + if command -v brew > /dev/null; then + if ! brew list | grep gcc > /dev/null; then + logg info "Installing Homebrew gcc" && brew install gcc + fi + else + logg error "Failed to initialize Homebrew" && exit 2 fi -else - logg error "Failed to initialize Homebrew" && exit 2 -fi +} +ensureHomebrew + # @description Ensures `cloudflared` is installed via Homebrew if ! command -v cloudflared > /dev/null; then brew install cloudflared diff --git a/scripts/homebrew.sh b/scripts/homebrew.sh index b020e46e..29fed6cf 100644 --- a/scripts/homebrew.sh +++ b/scripts/homebrew.sh @@ -11,53 +11,199 @@ # # **Note**: `https://install.doctor/brew` points to this file. -if ! command -v brew > /dev/null; then - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 +# @description This function logs with style using Gum if it is installed, otherwise it uses `echo`. It is also capable of leveraging Glow to render markdown. +# When Glow is not installed, it uses `cat`. The following sub-commands are available: +# +# | Sub-Command | Description | +# |-------------|-----------------------------------------------------------------------------------------------------| +# | `error` | Logs a bright red error message | +# | `info` | Logs a regular informational message | +# | `md` | Tries to render the specified file using `glow` if it is installed and uses `cat` as a fallback | +# | `prompt` | Alternative that logs a message intended to describe an upcoming user input prompt | +# | `star` | Alternative that logs a message that starts with a star icon | +# | `start` | Same as `success` | +# | `success` | Logs a success message that starts with green checkmark | +# | `warn` | Logs a bright yellow warning message | +# @example +# logger info "An informative log" +# @example +# logger md ~/README.md +logg() { + TYPE="$1" + MSG="$2" + if [ "$TYPE" == 'error' ]; then + if command -v gum > /dev/null; then + gum style --border="thick" "$(gum style --foreground="#ff0000" "✖") $(gum style --bold --background="#ff0000" --foreground="#ffffff" " ERROR ") $(gum style --bold "$MSG")" + else + echo "ERROR: $MSG" fi - elif [ -d "$HOME/.linuxbrew" ]; then - logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + elif [ "$TYPE" == 'info' ]; then + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#00ffff" "○") $(gum style --faint "$MSG")" + else + echo "INFO: $MSG" + fi + elif [ "$TYPE" == 'md' ]; then + if command -v glow > /dev/null; then + glow "$MSG" + else + cat "$MSG" + fi + elif [ "$TYPE" == 'prompt' ]; then + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#00008b" "▶") $(gum style --bold "$MSG")" + else + echo "PROMPT: $MSG" + fi + elif [ "$TYPE" == 'star' ]; then + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#d1d100" "◆") $(gum style --bold "$MSG")" + else + echo "STAR: $MSG" + fi + elif [ "$TYPE" == 'start' ]; then + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#00ff00" "▶") $(gum style --bold "$MSG")" + else + echo "START: $MSG" + fi + elif [ "$TYPE" == 'success' ]; then + if command -v gum > /dev/null; then + gum style "$(gum style --foreground="#00ff00" "✔") $(gum style --bold "$MSG")" + else + echo "SUCCESS: $MSG" + fi + elif [ "$TYPE" == 'warn' ]; then + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#d1d100" "◆") $(gum style --bold --background="#ffff00" --foreground="#000000" " WARNING ") $(gum style --bold "$MSG")" + else + echo "WARNING: $MSG" fi else - ### Installs Homebrew and addresses a couple potential issues - if command -v sudo > /dev/null && sudo -n true; then - logg info "Installing Homebrew" - echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + if command -v gum > /dev/null; then + gum style " $(gum style --foreground="#00ff00" "▶") $(gum style --bold "$TYPE")" else - logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" - if [ -n "$BREW_EXIT_CODE" ]; then - if command -v brew > /dev/null; then - logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." - BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" - for BREW_DIR in $BREW_DIRS; do - if [ -d "$(brew --prefix)/$BREW_DIR" ]; then - logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" - fi - done - logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + echo "$MSG" + fi + fi +} + +# @description This function ensures dependencies like `git` and `curl` are installed. More specifically, this function will: +# +# 1. Check if `curl`, `git`, `expect`, `rsync`, and `unbuffer` are on the system +# 2. If any of the above are missing, it will then use the appropriate system package manager to satisfy the requirements. *Note that some of the requirements are not scanned for in order to keep it simple and fast.* +# 3. On macOS, the official Xcode Command Line Tools are installed. +ensureBasicDeps() { + if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then + if command -v apt-get > /dev/null; then + ### Debian / Ubuntu + logg info 'Running sudo apt-get update' && sudo apt-get update + logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file + elif command -v dnf > /dev/null; then + ### Fedora + logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' + logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file + elif command -v yum > /dev/null; then + ### CentOS + logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' + logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file + elif command -v pacman > /dev/null; then + ### Archlinux + logg info 'Running sudo pacman update' && sudo pacman update + logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file + elif command -v zypper > /dev/null; then + ### OpenSUSE + logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis + logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file + elif command -v apk > /dev/null; then + ### Alpine + logg info 'Running sudo apk add build-base curl expect git rsync ruby procps file' && sudo apk add build-base curl expect git rsync ruby procps file + elif [ -d /Applications ] && [ -d /Library ]; then + ### macOS + logg info "Ensuring Xcode Command Line Tools are installed.." + if ! xcode-select -p >/dev/null 2>&1; then + logg info "Command Line Tools for Xcode not found" + ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; + XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" + logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" + fi + elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then + ### Windows + logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync + elif command -v nix-env > /dev/null; then + ### NixOS + logg warn "TODO - Add support for NixOS" + elif [[ "$OSTYPE" == 'freebsd'* ]]; then + ### FreeBSD + logg warn "TODO - Add support for FreeBSD" + elif command -v pkg > /dev/null; then + ### Termux + logg warn "TODO - Add support for Termux" + elif command -v xbps-install > /dev/null; then + ### Void + logg warn "TODO - Add support for Void" + fi + fi +} +ensureBasicDeps + +# @description This function ensures Homebrew is installed and available in the `PATH`. It handles the installation of Homebrew on both **Linux and macOS**. +# It will attempt to bypass sudo password entry if it detects that it can do so. The function also has some error handling in regards to various +# directories falling out of the correct ownership and permission states. Finally, it loads Homebrew into the active profile (allowing other parts of the script +# to use the `brew` command). +# +# With Homebrew installed and available, the script finishes by installing the `gcc` Homebrew package which is a very common dependency. +ensureHomebrew() { + if ! command -v brew > /dev/null; then + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi + elif [ -d "$HOME/.linuxbrew" ]; then + logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi + else + ### Installs Homebrew and addresses a couple potential issues + if command -v sudo > /dev/null && sudo -n true; then + logg info "Installing Homebrew" + echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + else + logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" + if [ -n "$BREW_EXIT_CODE" ]; then + if command -v brew > /dev/null; then + logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." + BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" + for BREW_DIR in $BREW_DIRS; do + if [ -d "$(brew --prefix)/$BREW_DIR" ]; then + logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" + fi + done + logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + fi fi fi - fi - ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - elif [ -f /opt/homebrew/bin/brew ]; then - logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + elif [ -f /opt/homebrew/bin/brew ]; then + logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + fi fi fi -fi -### Ensure GCC is installed via Homebrew -if command -v brew > /dev/null; then - if ! brew list | grep gcc > /dev/null; then - logg info "Installing Homebrew gcc" && brew install gcc + ### Ensure GCC is installed via Homebrew + if command -v brew > /dev/null; then + if ! brew list | grep gcc > /dev/null; then + logg info "Installing Homebrew gcc" && brew install gcc + fi + else + logg error "Failed to initialize Homebrew" && exit 2 fi -else - logg error "Failed to initialize Homebrew" && exit 2 -fi +} +ensureHomebrew diff --git a/scripts/partials/basic-deps b/scripts/partials/basic-deps index 31de14f4..6363b696 100644 --- a/scripts/partials/basic-deps +++ b/scripts/partials/basic-deps @@ -1,53 +1,58 @@ - - -if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then - if command -v apt-get > /dev/null; then - ### Debian / Ubuntu - logg info 'Running sudo apt-get update' && sudo apt-get update - logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file - elif command -v dnf > /dev/null; then - ### Fedora - logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' - logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file - elif command -v yum > /dev/null; then - ### CentOS - logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' - logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file - elif command -v pacman > /dev/null; then - ### Archlinux - logg info 'Running sudo pacman update' && sudo pacman update - logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file - elif command -v zypper > /dev/null; then - ### OpenSUSE - logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis - logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file - elif command -v apk > /dev/null; then - ### Alpine - logg info 'Running sudo apk add build-base curl expect git rsync ruby procps file' && sudo apk add build-base curl expect git rsync ruby procps file - elif [ -d /Applications ] && [ -d /Library ]; then - ### macOS - logg info "Ensuring Xcode Command Line Tools are installed.." - if ! xcode-select -p >/dev/null 2>&1; then - logg info "Command Line Tools for Xcode not found" - ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools - touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; - XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" - logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" +# @description This function ensures dependencies like `git` and `curl` are installed. More specifically, this function will: +# +# 1. Check if `curl`, `git`, `expect`, `rsync`, and `unbuffer` are on the system +# 2. If any of the above are missing, it will then use the appropriate system package manager to satisfy the requirements. *Note that some of the requirements are not scanned for in order to keep it simple and fast.* +# 3. On macOS, the official Xcode Command Line Tools are installed. +ensureBasicDeps() { + if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then + if command -v apt-get > /dev/null; then + ### Debian / Ubuntu + logg info 'Running sudo apt-get update' && sudo apt-get update + logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file + elif command -v dnf > /dev/null; then + ### Fedora + logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' + logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file + elif command -v yum > /dev/null; then + ### CentOS + logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' + logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file + elif command -v pacman > /dev/null; then + ### Archlinux + logg info 'Running sudo pacman update' && sudo pacman update + logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file + elif command -v zypper > /dev/null; then + ### OpenSUSE + logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis + logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file + elif command -v apk > /dev/null; then + ### Alpine + logg info 'Running sudo apk add build-base curl expect git rsync ruby procps file' && sudo apk add build-base curl expect git rsync ruby procps file + elif [ -d /Applications ] && [ -d /Library ]; then + ### macOS + logg info "Ensuring Xcode Command Line Tools are installed.." + if ! xcode-select -p >/dev/null 2>&1; then + logg info "Command Line Tools for Xcode not found" + ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; + XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" + logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" + fi + elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then + ### Windows + logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync + elif command -v nix-env > /dev/null; then + ### NixOS + logg warn "TODO - Add support for NixOS" + elif [[ "$OSTYPE" == 'freebsd'* ]]; then + ### FreeBSD + logg warn "TODO - Add support for FreeBSD" + elif command -v pkg > /dev/null; then + ### Termux + logg warn "TODO - Add support for Termux" + elif command -v xbps-install > /dev/null; then + ### Void + logg warn "TODO - Add support for Void" fi - elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then - ### Windows - logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync - elif command -v nix-env > /dev/null; then - ### NixOS - logg warn "TODO - Add support for NixOS" - elif [[ "$OSTYPE" == 'freebsd'* ]]; then - ### FreeBSD - logg warn "TODO - Add support for FreeBSD" - elif command -v pkg > /dev/null; then - ### Termux - logg warn "TODO - Add support for Termux" - elif command -v xbps-install > /dev/null; then - ### Void - logg warn "TODO - Add support for Void" fi -fi +} diff --git a/scripts/partials/homebrew b/scripts/partials/homebrew index 2ad17fd0..c1879465 100644 --- a/scripts/partials/homebrew +++ b/scripts/partials/homebrew @@ -1,50 +1,58 @@ -if ! command -v brew > /dev/null; then - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - elif [ -d "$HOME/.linuxbrew" ]; then - logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - else - ### Installs Homebrew and addresses a couple potential issues - if command -v sudo > /dev/null && sudo -n true; then - logg info "Installing Homebrew" - echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +# @description This function ensures Homebrew is installed and available in the `PATH`. It handles the installation of Homebrew on both **Linux and macOS**. +# It will attempt to bypass sudo password entry if it detects that it can do so. The function also has some error handling in regards to various +# directories falling out of the correct ownership and permission states. Finally, it loads Homebrew into the active profile (allowing other parts of the script +# to use the `brew` command). +# +# With Homebrew installed and available, the script finishes by installing the `gcc` Homebrew package which is a very common dependency. +ensureHomebrew() { + if ! command -v brew > /dev/null; then + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi + elif [ -d "$HOME/.linuxbrew" ]; then + logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi else - logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" - if [ -n "$BREW_EXIT_CODE" ]; then - if command -v brew > /dev/null; then - logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." - BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" - for BREW_DIR in $BREW_DIRS; do - if [ -d "$(brew --prefix)/$BREW_DIR" ]; then - logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" - fi - done - logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + ### Installs Homebrew and addresses a couple potential issues + if command -v sudo > /dev/null && sudo -n true; then + logg info "Installing Homebrew" + echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + else + logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" + if [ -n "$BREW_EXIT_CODE" ]; then + if command -v brew > /dev/null; then + logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." + BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" + for BREW_DIR in $BREW_DIRS; do + if [ -d "$(brew --prefix)/$BREW_DIR" ]; then + logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" + fi + done + logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + fi fi fi - fi - ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - elif [ -f /opt/homebrew/bin/brew ]; then - logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + elif [ -f /opt/homebrew/bin/brew ]; then + logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + fi fi fi -fi -### Ensure GCC is installed via Homebrew -if command -v brew > /dev/null; then - if ! brew list | grep gcc > /dev/null; then - logg info "Installing Homebrew gcc" && brew install gcc + ### Ensure GCC is installed via Homebrew + if command -v brew > /dev/null; then + if ! brew list | grep gcc > /dev/null; then + logg info "Installing Homebrew gcc" && brew install gcc + fi + else + logg error "Failed to initialize Homebrew" && exit 2 fi -else - logg error "Failed to initialize Homebrew" && exit 2 -fi +} diff --git a/scripts/partials/logg b/scripts/partials/logg index e7ad3fe7..c9c5b1eb 100644 --- a/scripts/partials/logg +++ b/scripts/partials/logg @@ -1,7 +1,20 @@ -# @description Logs with style using Gum if it is installed, otherwise it uses `echo`. It also leverages Glow to render markdown. -# When Glow is not installed, it uses `cat`. +# @description This function logs with style using Gum if it is installed, otherwise it uses `echo`. It is also capable of leveraging Glow to render markdown. +# When Glow is not installed, it uses `cat`. The following sub-commands are available: +# +# | Sub-Command | Description | +# |-------------|-----------------------------------------------------------------------------------------------------| +# | `error` | Logs a bright red error message | +# | `info` | Logs a regular informational message | +# | `md` | Tries to render the specified file using `glow` if it is installed and uses `cat` as a fallback | +# | `prompt` | Alternative that logs a message intended to describe an upcoming user input prompt | +# | `star` | Alternative that logs a message that starts with a star icon | +# | `start` | Same as `success` | +# | `success` | Logs a success message that starts with green checkmark | +# | `warn` | Logs a bright yellow warning message | # @example # logger info "An informative log" +# @example +# logger md ~/README.md logg() { TYPE="$1" MSG="$2" diff --git a/scripts/partials/pfsense b/scripts/partials/pfsense deleted file mode 100644 index 2eb1cef5..00000000 --- a/scripts/partials/pfsense +++ /dev/null @@ -1,45 +0,0 @@ - -### Enable FreeBSD package repo -logg info 'Enabling FreeBSD package repo' -FILE_PATH="/usr/local/etc/pkg/repos/pfSense.conf" -TMP_FILE=$(mktemp) -REPLACEMENT="FreeBSD: { enabled: yes }" -echo "$REPLACEMENT" > "$TMP_FILE" -tail -n +2 "$FILE_PATH" >> "$TMP_FILE" -mv -f "$TMP_FILE" "$FILE_PATH" -rm -f "$TMP_FILE" - -### Install Netdata / dependencies -logg info 'Installing Netdata system package dependencies' -pkg update -pkg install -y curl pkgconf bash e2fsprogs-libuuid libuv nano -pkg install -y json-c-0.15_1 -pkg install -y py39-certifi-2023.5.7 -pkg install -y py39-asn1crypto -pkg install -y py39-pycparser -pkg install -y py39-cffi -pkg install -y py39-six -pkg install -y py39-cryptography -pkg install -y py39-idna -pkg install -y py39-openssl -pkg install -y py39-pysocks -pkg install -y py39-urllib3 -pkg install -y py39-yaml -pkg install -y netdata - -### Modify Netdata configuration -logg info 'Configuring Netdata to work with Netdata Cloud' -# TODO: Add below to netdata.conf -# bind to = 127.0.0.1 to bind to = 0.0.0.0 -NETDATA_CLOUD_API_TOKEN="YOUR_API_TOKEN_HERE" -cat < /usr/local/etc/netdata/netdata.conf -[backend] - enabled = yes - data source = netdata - destination = https://app.netdata.cloud - api key = ${NETDATA_CLOUD_API_TOKEN} -EOF - -### Start Netdata -logg info 'Starting Netdata service' -service netdata onestart diff --git a/scripts/partials/pfsense-netdata b/scripts/partials/pfsense-netdata new file mode 100644 index 00000000..3169829b --- /dev/null +++ b/scripts/partials/pfsense-netdata @@ -0,0 +1,56 @@ +# @description This function adds Netdata to a pfSense environment. More specifically, it: +# +# 1. Enables the FreeBSD package repo +# 2. Installs Netdata system package dependencies +# 3. Configures Netdata to work with Netdata Cloud (if the `NETDATA_TOKEN` environment variable is appropriately assigned) +# 4. Starts the Netdata service +# +# **Note:** In order for Netdata to start on reboot, the shell command feature of pfSense should be configured to +# run `service netdata onestart` after reboots. +enableNetdata() { + ### Enable FreeBSD package repo + logg info 'Enabling FreeBSD package repo' + FILE_PATH="/usr/local/etc/pkg/repos/pfSense.conf" + TMP_FILE=$(mktemp) + REPLACEMENT="FreeBSD: { enabled: yes }" + echo "$REPLACEMENT" > "$TMP_FILE" + tail -n +2 "$FILE_PATH" >> "$TMP_FILE" + mv -f "$TMP_FILE" "$FILE_PATH" + rm -f "$TMP_FILE" + + ### Install Netdata / dependencies + logg info 'Installing Netdata system package dependencies' + pkg update + pkg install -y curl pkgconf bash e2fsprogs-libuuid libuv nano + pkg install -y json-c-0.15_1 + pkg install -y py39-certifi-2023.5.7 + pkg install -y py39-asn1crypto + pkg install -y py39-pycparser + pkg install -y py39-cffi + pkg install -y py39-six + pkg install -y py39-cryptography + pkg install -y py39-idna + pkg install -y py39-openssl + pkg install -y py39-pysocks + pkg install -y py39-urllib3 + pkg install -y py39-yaml + pkg install -y netdata + + ### Modify Netdata configuration + if [ -n "$NETDATA_TOKEN" ]; then + logg info 'Configuring Netdata to work with Netdata Cloud' + # TODO: Add below to netdata.conf + # bind to = 127.0.0.1 to bind to = 0.0.0.0 + cat < /usr/local/etc/netdata/netdata.conf +[backend] + enabled = yes + data source = netdata + destination = https://app.netdata.cloud + api key = ${NETDATA_TOKEN} +EOF + fi + + ### Start Netdata + logg info 'Starting Netdata service' + service netdata onestart +} diff --git a/scripts/pfsense.sh b/scripts/pfsense.sh index fe229be2..a4660d6d 100644 --- a/scripts/pfsense.sh +++ b/scripts/pfsense.sh @@ -6,10 +6,23 @@ # # 1. [Netdata Cloud](https://learn.netdata.cloud/docs/installing/pfsense) -# @description Logs with style using Gum if it is installed, otherwise it uses `echo`. It also leverages Glow to render markdown. -# When Glow is not installed, it uses `cat`. +# @description This function logs with style using Gum if it is installed, otherwise it uses `echo`. It is also capable of leveraging Glow to render markdown. +# When Glow is not installed, it uses `cat`. The following sub-commands are available: +# +# | Sub-Command | Description | +# |-------------|-----------------------------------------------------------------------------------------------------| +# | `error` | Logs a bright red error message | +# | `info` | Logs a regular informational message | +# | `md` | Tries to render the specified file using `glow` if it is installed and uses `cat` as a fallback | +# | `prompt` | Alternative that logs a message intended to describe an upcoming user input prompt | +# | `star` | Alternative that logs a message that starts with a star icon | +# | `start` | Same as `success` | +# | `success` | Logs a success message that starts with green checkmark | +# | `warn` | Logs a bright yellow warning message | # @example # logger info "An informative log" +# @example +# logger md ~/README.md logg() { TYPE="$1" MSG="$2" @@ -70,47 +83,60 @@ logg() { fi } -### Enable FreeBSD package repo -logg info 'Enabling FreeBSD package repo' -FILE_PATH="/usr/local/etc/pkg/repos/pfSense.conf" -TMP_FILE=$(mktemp) -REPLACEMENT="FreeBSD: { enabled: yes }" -echo "$REPLACEMENT" > "$TMP_FILE" -tail -n +2 "$FILE_PATH" >> "$TMP_FILE" -mv -f "$TMP_FILE" "$FILE_PATH" -rm -f "$TMP_FILE" +# @description This function adds Netdata to a pfSense environment. More specifically, it: +# +# 1. Enables the FreeBSD package repo +# 2. Installs Netdata system package dependencies +# 3. Configures Netdata to work with Netdata Cloud (if the `NETDATA_TOKEN` environment variable is appropriately assigned) +# 4. Starts the Netdata service +# +# **Note:** In order for Netdata to start on reboot, the shell command feature of pfSense should be configured to +# run `service netdata onestart` after reboots. +enableNetdata() { + ### Enable FreeBSD package repo + logg info 'Enabling FreeBSD package repo' + FILE_PATH="/usr/local/etc/pkg/repos/pfSense.conf" + TMP_FILE=$(mktemp) + REPLACEMENT="FreeBSD: { enabled: yes }" + echo "$REPLACEMENT" > "$TMP_FILE" + tail -n +2 "$FILE_PATH" >> "$TMP_FILE" + mv -f "$TMP_FILE" "$FILE_PATH" + rm -f "$TMP_FILE" -### Install Netdata / dependencies -logg info 'Installing Netdata system package dependencies' -pkg update -pkg install -y curl pkgconf bash e2fsprogs-libuuid libuv nano -pkg install -y json-c-0.15_1 -pkg install -y py39-certifi-2023.5.7 -pkg install -y py39-asn1crypto -pkg install -y py39-pycparser -pkg install -y py39-cffi -pkg install -y py39-six -pkg install -y py39-cryptography -pkg install -y py39-idna -pkg install -y py39-openssl -pkg install -y py39-pysocks -pkg install -y py39-urllib3 -pkg install -y py39-yaml -pkg install -y netdata + ### Install Netdata / dependencies + logg info 'Installing Netdata system package dependencies' + pkg update + pkg install -y curl pkgconf bash e2fsprogs-libuuid libuv nano + pkg install -y json-c-0.15_1 + pkg install -y py39-certifi-2023.5.7 + pkg install -y py39-asn1crypto + pkg install -y py39-pycparser + pkg install -y py39-cffi + pkg install -y py39-six + pkg install -y py39-cryptography + pkg install -y py39-idna + pkg install -y py39-openssl + pkg install -y py39-pysocks + pkg install -y py39-urllib3 + pkg install -y py39-yaml + pkg install -y netdata -### Modify Netdata configuration -logg info 'Configuring Netdata to work with Netdata Cloud' -# TODO: Add below to netdata.conf -# bind to = 127.0.0.1 to bind to = 0.0.0.0 -NETDATA_CLOUD_API_TOKEN="YOUR_API_TOKEN_HERE" -cat < /usr/local/etc/netdata/netdata.conf + ### Modify Netdata configuration + if [ -n "$NETDATA_TOKEN" ]; then + logg info 'Configuring Netdata to work with Netdata Cloud' + # TODO: Add below to netdata.conf + # bind to = 127.0.0.1 to bind to = 0.0.0.0 + cat < /usr/local/etc/netdata/netdata.conf [backend] enabled = yes data source = netdata destination = https://app.netdata.cloud - api key = ${NETDATA_CLOUD_API_TOKEN} + api key = ${NETDATA_TOKEN} EOF + fi -### Start Netdata -logg info 'Starting Netdata service' -service netdata onestart + ### Start Netdata + logg info 'Starting Netdata service' + service netdata onestart +} +enableNetdata diff --git a/scripts/provision.sh b/scripts/provision.sh index 0821b25d..e156cc4e 100644 --- a/scripts/provision.sh +++ b/scripts/provision.sh @@ -51,10 +51,23 @@ # [Install Doctor homepage](https://install.doctor) # [Install Doctor documentation portal](https://install.doctor/docs) (includes tips, tricks, and guides on how to customize the system to your liking) -# @description Logs with style using Gum if it is installed, otherwise it uses `echo`. It also leverages Glow to render markdown. -# When Glow is not installed, it uses `cat`. +# @description This function logs with style using Gum if it is installed, otherwise it uses `echo`. It is also capable of leveraging Glow to render markdown. +# When Glow is not installed, it uses `cat`. The following sub-commands are available: +# +# | Sub-Command | Description | +# |-------------|-----------------------------------------------------------------------------------------------------| +# | `error` | Logs a bright red error message | +# | `info` | Logs a regular informational message | +# | `md` | Tries to render the specified file using `glow` if it is installed and uses `cat` as a fallback | +# | `prompt` | Alternative that logs a message intended to describe an upcoming user input prompt | +# | `star` | Alternative that logs a message that starts with a star icon | +# | `start` | Same as `success` | +# | `success` | Logs a success message that starts with green checkmark | +# | `warn` | Logs a bright yellow warning message | # @example # logger info "An informative log" +# @example +# logger md ~/README.md logg() { TYPE="$1" MSG="$2" @@ -114,6 +127,7 @@ logg() { fi fi } + # @section Environment variables and system dependencies # @description Ensure Ubuntu / Debian run in `noninteractive` mode. Detect `START_REPO` format and determine appropriate git address, # otherwise use the master Install Doctor branch @@ -139,115 +153,122 @@ setEnvironmentVariables() { fi } -# @description Ensure dependencies like `git` and `curl` are installed (among a few other lightweight system packages) +# @description This function ensures dependencies like `git` and `curl` are installed. More specifically, this function will: +# +# 1. Check if `curl`, `git`, `expect`, `rsync`, and `unbuffer` are on the system +# 2. If any of the above are missing, it will then use the appropriate system package manager to satisfy the requirements. *Note that some of the requirements are not scanned for in order to keep it simple and fast.* +# 3. On macOS, the official Xcode Command Line Tools are installed. ensureBasicDeps() { - - -if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then - if command -v apt-get > /dev/null; then - ### Debian / Ubuntu - logg info 'Running sudo apt-get update' && sudo apt-get update - logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file - elif command -v dnf > /dev/null; then - ### Fedora - logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' - logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file - elif command -v yum > /dev/null; then - ### CentOS - logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' - logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file - elif command -v pacman > /dev/null; then - ### Archlinux - logg info 'Running sudo pacman update' && sudo pacman update - logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file - elif command -v zypper > /dev/null; then - ### OpenSUSE - logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis - logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file - elif command -v apk > /dev/null; then - ### Alpine - logg info 'Running apk add build-base curl expect git rsync procps file' && apk add build-base curl expect git rsync procps file - elif [ -d /Applications ] && [ -d /Library ]; then - ### macOS - logg info "Ensuring Xcode Command Line Tools are installed.." - if ! xcode-select -p >/dev/null 2>&1; then - logg info "Command Line Tools for Xcode not found" - ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools - touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; - XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" - logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" + if ! command -v curl > /dev/null || ! command -v git > /dev/null || ! command -v expect > /dev/null || ! command -v rsync > /dev/null || ! command -v unbuffer; then + if command -v apt-get > /dev/null; then + ### Debian / Ubuntu + logg info 'Running sudo apt-get update' && sudo apt-get update + logg info 'Running sudo apt-get install -y build-essential curl expect git rsync procps file' && sudo apt-get install -y build-essential curl expect git rsync procps file + elif command -v dnf > /dev/null; then + ### Fedora + logg info 'Running sudo dnf groupinstall -y "Development Tools"' && sudo dnf groupinstall -y 'Development Tools' + logg info 'Running sudo dnf install -y curl expect git rsync procps-ng file' && sudo dnf install -y curl expect git rsync procps-ng file + elif command -v yum > /dev/null; then + ### CentOS + logg info 'Running sudo yum groupinstall -y "Development Tools"' && sudo yum groupinstall -y 'Development Tools' + logg info 'Running sudo yum install -y curl expect git rsync procps-ng file' && sudo yum install -y curl expect git rsync procps-ng file + elif command -v pacman > /dev/null; then + ### Archlinux + logg info 'Running sudo pacman update' && sudo pacman update + logg info 'Running sudo pacman -Syu base-devel curl expect git rsync procps-ng file' && sudo pacman -Syu base-devel curl expect git rsync procps-ng file + elif command -v zypper > /dev/null; then + ### OpenSUSE + logg info 'Running sudo zypper install -yt pattern devel_basis' && sudo zypper install -yt pattern devel_basis + logg info 'Running sudo zypper install -y curl expect git rsync procps file' && sudo zypper install -y curl expect git rsync procps file + elif command -v apk > /dev/null; then + ### Alpine + logg info 'Running sudo apk add build-base curl expect git rsync ruby procps file' && sudo apk add build-base curl expect git rsync ruby procps file + elif [ -d /Applications ] && [ -d /Library ]; then + ### macOS + logg info "Ensuring Xcode Command Line Tools are installed.." + if ! xcode-select -p >/dev/null 2>&1; then + logg info "Command Line Tools for Xcode not found" + ### This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress; + XCODE_PKG="$(softwareupdate -l | grep "\*.*Command Line" | tail -n 1 | sed 's/^[^C]* //')" + logg info "Installing from softwareupdate" && softwareupdate -i "$XCODE_PKG" && logg success "Successfully installed $XCODE_PKG" + fi + elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then + ### Windows + logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync + elif command -v nix-env > /dev/null; then + ### NixOS + logg warn "TODO - Add support for NixOS" + elif [[ "$OSTYPE" == 'freebsd'* ]]; then + ### FreeBSD + logg warn "TODO - Add support for FreeBSD" + elif command -v pkg > /dev/null; then + ### Termux + logg warn "TODO - Add support for Termux" + elif command -v xbps-install > /dev/null; then + ### Void + logg warn "TODO - Add support for Void" fi - elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then - ### Windows - logg info 'Running choco install -y curl expect git rsync' && choco install -y curl expect git rsync - elif command -v nix-env > /dev/null; then - ### NixOS - logg warn "TODO - Add support for NixOS" - elif [[ "$OSTYPE" == 'freebsd'* ]]; then - ### FreeBSD - logg warn "TODO - Add support for FreeBSD" - elif command -v pkg > /dev/null; then - ### Termux - logg warn "TODO - Add support for Termux" - elif command -v xbps-install > /dev/null; then - ### Void - logg warn "TODO - Add support for Void" fi -fi } -# @description Ensure Homebrew is installed and available in the `PATH` +# @description This function ensures Homebrew is installed and available in the `PATH`. It handles the installation of Homebrew on both **Linux and macOS**. +# It will attempt to bypass sudo password entry if it detects that it can do so. The function also has some error handling in regards to various +# directories falling out of the correct ownership and permission states. Finally, it loads Homebrew into the active profile (allowing other parts of the script +# to use the `brew` command). +# +# With Homebrew installed and available, the script finishes by installing the `gcc` Homebrew package which is a very common dependency. ensureHomebrew() { if ! command -v brew > /dev/null; then - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - elif [ -d "$HOME/.linuxbrew" ]; then - logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" - if ! command -v brew > /dev/null; then - logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 - fi - else - ### Installs Homebrew and addresses a couple potential issues - if command -v sudo > /dev/null && sudo -n true; then - logg info "Installing Homebrew" - echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The /home/linuxbrew/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi + elif [ -d "$HOME/.linuxbrew" ]; then + logg info "Sourcing from $HOME/.linuxbrew/bin/brew" && eval "$($HOME/.linuxbrew/bin/brew shellenv)" + if ! command -v brew > /dev/null; then + logg error "The $HOME/.linuxbrew directory exists but something is not right. Try removing it and running the script again." && exit 1 + fi else - logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" - if [ -n "$BREW_EXIT_CODE" ]; then - if command -v brew > /dev/null; then - logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." - BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" - for BREW_DIR in $BREW_DIRS; do - if [ -d "$(brew --prefix)/$BREW_DIR" ]; then - logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" - fi - done - logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + ### Installs Homebrew and addresses a couple potential issues + if command -v sudo > /dev/null && sudo -n true; then + logg info "Installing Homebrew" + echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + else + logg info "Homebrew is not installed. The script will attempt to install Homebrew and you might be prompted for your password." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?" + if [ -n "$BREW_EXIT_CODE" ]; then + if command -v brew > /dev/null; then + logg warn "Homebrew was installed but part of the installation failed. Trying a few things to fix the installation.." + BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d" + for BREW_DIR in $BREW_DIRS; do + if [ -d "$(brew --prefix)/$BREW_DIR" ]; then + logg info "Chowning $(brew --prefix)/$BREW_DIR" && sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR" + fi + done + logg info "Running brew update --force --quiet" && brew update --force --quiet && logg success "Successfully ran brew update --force --quiet" + fi fi fi - fi - ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. - if [ -d /home/linuxbrew/.linuxbrew/bin ]; then - logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - elif [ -f /opt/homebrew/bin/brew ]; then - logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + ### Ensures the `brew` binary is available on Linux machines. macOS installs `brew` into the default `PATH` so nothing needs to be done for macOS. + if [ -d /home/linuxbrew/.linuxbrew/bin ]; then + logg info "Sourcing shellenv from /home/linuxbrew/.linuxbrew/bin/brew" && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + elif [ -f /opt/homebrew/bin/brew ]; then + logg info "Sourcing shellenv from /opt/homebrew/bin/brew" && eval "$(/opt/homebrew/bin/brew shellenv)" + fi fi fi -fi -### Ensure GCC is installed via Homebrew -if command -v brew > /dev/null; then - if ! brew list | grep gcc > /dev/null; then - logg info "Installing Homebrew gcc" && brew install gcc + ### Ensure GCC is installed via Homebrew + if command -v brew > /dev/null; then + if ! brew list | grep gcc > /dev/null; then + logg info "Installing Homebrew gcc" && brew install gcc + fi + else + logg error "Failed to initialize Homebrew" && exit 2 fi -else - logg error "Failed to initialize Homebrew" && exit 2 -fi } # @description Load default settings if it is in a CI setting @@ -546,10 +567,10 @@ provisionLogic() { logg info "Setting environment variables" && setEnvironmentVariables logg info "Handling CI variables" && setCIEnvironmentVariables logg info "Ensuring WARP is disconnected" && ensureWarpDisconnected + logg info "Applying passwordless sudo" && setupPasswordlessSudo logg info "Ensuring system Homebrew dependencies are installed" && ensureBasicDeps logg info "Ensuring Homebrew is available" && ensureHomebrew logg info "Installing Homebrew packages" && ensureHomebrewDeps - logg info "Applying passwordless sudo" && setupPasswordlessSudo logg info "Handling Qubes dom0 logic (if applicable)" && handleQubesDom0 logg info "Cloning / updating source repository" && cloneChezmoiSourceRepo logg info "Handling pre-provision logic" && initChezmoiAndPrompt diff --git a/scripts/src/cloudflared-ssh.sh.tmpl b/scripts/src/cloudflared-ssh.sh.tmpl index 83f9e22e..58444eaa 100644 --- a/scripts/src/cloudflared-ssh.sh.tmpl +++ b/scripts/src/cloudflared-ssh.sh.tmpl @@ -42,13 +42,12 @@ # # [SSH with short-lived certificates](https://developers.cloudflare.com/cloudflare-one/tutorials/ssh-cert-bastion/) -{{ include "partials" "logg" -}} - -# @description Ensure dependencies like `git` and `curl` are installed (among a few other lightweight system packages) +{{ include "partials" "logg" }} {{ include "partials" "basic-deps" -}} +ensureBasicDeps -# @description Ensure Homebrew is installed and available in the `PATH` {{ include "partials" "homebrew" -}} +ensureHomebrew # @description Ensures `cloudflared` is installed via Homebrew if ! command -v cloudflared > /dev/null; then diff --git a/scripts/src/homebrew.sh.tmpl b/scripts/src/homebrew.sh.tmpl index 4796d62c..57e685ec 100644 --- a/scripts/src/homebrew.sh.tmpl +++ b/scripts/src/homebrew.sh.tmpl @@ -11,4 +11,9 @@ # # **Note**: `https://install.doctor/brew` points to this file. +{{ include "partials" "logg" }} +{{ include "partials" "basic-deps" -}} +ensureBasicDeps + {{ include "partials" "homebrew" -}} +ensureHomebrew diff --git a/scripts/src/pfsense.sh.tmpl b/scripts/src/pfsense.sh.tmpl index 60aa866e..e7250d59 100644 --- a/scripts/src/pfsense.sh.tmpl +++ b/scripts/src/pfsense.sh.tmpl @@ -6,6 +6,6 @@ # # 1. [Netdata Cloud](https://learn.netdata.cloud/docs/installing/pfsense) -{{ include "partials" "logg" -}} - -{{ include "partials" "pfsense" -}} +{{ include "partials" "logg" }} +{{ include "partials" "pfsense-netdata" -}} +enableNetdata diff --git a/scripts/src/provision.sh.tmpl b/scripts/src/provision.sh.tmpl index 90713519..e910130b 100644 --- a/scripts/src/provision.sh.tmpl +++ b/scripts/src/provision.sh.tmpl @@ -51,8 +51,7 @@ # [Install Doctor homepage](https://install.doctor) # [Install Doctor documentation portal](https://install.doctor/docs) (includes tips, tricks, and guides on how to customize the system to your liking) -{{ include "partials" "logg" -}} - +{{ include "partials" "logg" }} # @section Environment variables and system dependencies # @description Ensure Ubuntu / Debian run in `noninteractive` mode. Detect `START_REPO` format and determine appropriate git address, # otherwise use the master Install Doctor branch @@ -78,16 +77,8 @@ setEnvironmentVariables() { fi } -# @description Ensure dependencies like `git` and `curl` are installed (among a few other lightweight system packages) -ensureBasicDeps() { - {{ include "partials" "basic-deps" -}} -} - -# @description Ensure Homebrew is installed and available in the `PATH` -ensureHomebrew() { - {{ include "partials" "homebrew" -}} -} - +{{ include "partials" "basic-deps" }} +{{ include "partials" "homebrew" }} # @description Load default settings if it is in a CI setting setCIEnvironmentVariables() { if [ -n "$CI" ]; then @@ -384,10 +375,10 @@ provisionLogic() { logg info "Setting environment variables" && setEnvironmentVariables logg info "Handling CI variables" && setCIEnvironmentVariables logg info "Ensuring WARP is disconnected" && ensureWarpDisconnected + logg info "Applying passwordless sudo" && setupPasswordlessSudo logg info "Ensuring system Homebrew dependencies are installed" && ensureBasicDeps logg info "Ensuring Homebrew is available" && ensureHomebrew logg info "Installing Homebrew packages" && ensureHomebrewDeps - logg info "Applying passwordless sudo" && setupPasswordlessSudo logg info "Handling Qubes dom0 logic (if applicable)" && handleQubesDom0 logg info "Cloning / updating source repository" && cloneChezmoiSourceRepo logg info "Handling pre-provision logic" && initChezmoiAndPrompt