refactor whole tools.func

This commit is contained in:
CanbiZ
2025-10-14 20:57:35 +02:00
parent f303b5e3ef
commit a0ee5c315f

View File

@@ -37,8 +37,8 @@ check_for_gh_release() {
# jq check
if ! command -v jq &>/dev/null; then
$STD apt-get update -qq
$STD apt-get install -y jq || {
$STD apt update -qq
$STD apt install -y jq || {
msg_error "Failed to install jq"
return 1
}
@@ -134,12 +134,27 @@ check_for_gh_release() {
# Variables:
# APP - Application name (default: $APPLICATION variable)
# ------------------------------------------------------------------------------
function create_selfsigned_certs() {
local app=${APP:-$(echo "${APPLICATION,,}" | tr -d ' ')}
$STD openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
-keyout /etc/ssl/private/"$app"-selfsigned.key \
-out /etc/ssl/certs/"$app"-selfsigned.crt \
-subj "/C=US/O=$app/OU=Domain Control Validated/CN=localhost"
create_self_signed_cert() {
local APP_NAME="${1:-${APPLICATION}}"
local CERT_DIR="/etc/ssl/${APP_NAME}"
local CERT_KEY="${CERT_DIR}/${APP_NAME}.key"
local CERT_CRT="${CERT_DIR}/${APP_NAME}.crt"
if [[ -f "$CERT_CRT" && -f "$CERT_KEY" ]]; then
return 0
fi
$STD apt update
$STD apt install -y openssl
mkdir -p "$CERT_DIR"
$STD openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=${APP_NAME}" \
-keyout "$CERT_KEY" \
-out "$CERT_CRT"
chmod 600 "$CERT_KEY"
chmod 644 "$CERT_CRT"
}
# ------------------------------------------------------------------------------
@@ -156,7 +171,7 @@ function download_with_progress() {
if [ -n "$SPINNER_PID" ] && ps -p "$SPINNER_PID" >/dev/null; then kill "$SPINNER_PID" >/dev/null; fi
if ! command -v pv &>/dev/null; then
$STD apt-get install -y pv
$STD apt install -y pv
fi
set -o pipefail
@@ -255,7 +270,7 @@ function fetch_and_deploy_gh_release() {
[[ -f "$version_file" ]] && current_version=$(<"$version_file")
if ! command -v jq &>/dev/null; then
$STD apt-get install -y jq &>/dev/null
$STD apt install -y jq &>/dev/null
fi
local api_url="https://api.github.com/repos/$repo/releases"
@@ -387,7 +402,7 @@ function fetch_and_deploy_gh_release() {
}
chmod 644 "$tmpdir/$filename"
$STD apt-get install -y "$tmpdir/$filename" || {
$STD apt install -y "$tmpdir/$filename" || {
$STD dpkg -i "$tmpdir/$filename" || {
msg_error "Both apt and dpkg installation failed"
rm -rf "$tmpdir"
@@ -438,7 +453,7 @@ function fetch_and_deploy_gh_release() {
if [[ "$filename" == *.zip ]]; then
if ! command -v unzip &>/dev/null; then
$STD apt-get install -y unzip
$STD apt install -y unzip
fi
unzip -q "$tmpdir/$filename" -d "$unpack_tmp"
elif [[ "$filename" == *.tar.* || "$filename" == *.tgz ]]; then
@@ -605,7 +620,7 @@ function setup_adminer() {
msg_ok "Adminer available at /adminer (Alpine)"
else
msg_info "Setup Adminer (Debian/Ubuntu)"
$STD apt-get install -y adminer
$STD apt install -y adminer
$STD a2enconf adminer
$STD systemctl reload apache2
msg_ok "Adminer available at /adminer (Debian/Ubuntu)"
@@ -699,8 +714,8 @@ function setup_ffmpeg() {
fi
if ! command -v jq &>/dev/null; then
$STD apt-get update
$STD apt-get install -y jq
$STD apt update
$STD apt install -y jq
fi
# Auto-detect latest stable version if none specified
@@ -744,8 +759,8 @@ function setup_ffmpeg() {
;;
esac
$STD apt-get update
$STD apt-get install -y "${DEPS[@]}"
$STD apt update
$STD apt install -y "${DEPS[@]}"
curl -fsSL "https://github.com/${GITHUB_REPO}/archive/refs/tags/${VERSION}.tar.gz" -o "$TMP_DIR/ffmpeg.tar.gz"
tar -xzf "$TMP_DIR/ffmpeg.tar.gz" -C "$TMP_DIR"
@@ -915,7 +930,7 @@ function setup_gs() {
msg_error "Failed to enter Ghostscript source directory."
rm -rf "$TMP_DIR"
}
$STD apt-get install -y build-essential libpng-dev zlib1g-dev
$STD apt install -y build-essential libpng-dev zlib1g-dev
$STD ./configure >/dev/null
$STD make
$STD sudo make install
@@ -960,8 +975,8 @@ function setup_imagemagick() {
fi
msg_info "Setup ImageMagick (Patience)"
$STD apt-get update
$STD apt-get install -y \
$STD apt update
$STD apt install -y \
build-essential \
libtool \
libjpeg-dev \
@@ -1019,41 +1034,57 @@ function setup_imagemagick() {
function setup_java() {
local JAVA_VERSION="${JAVA_VERSION:-21}"
local DISTRO_CODENAME
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/VERSION_CODENAME/ { print $2 }' /etc/os-release)
local DESIRED_PACKAGE="temurin-${JAVA_VERSION}-jdk"
# Add Adoptium repo if missing
if [[ ! -f /etc/apt/sources.list.d/adoptium.list ]]; then
$STD msg_info "Setting up Adoptium Repository"
# Add repo nur wenn nötig
if [[ ! -f /etc/apt/sources.list.d/adoptium.sources ]]; then
msg_info "Setting up Adoptium Repository"
mkdir -p /etc/apt/keyrings
curl -fsSL "https://packages.adoptium.net/artifactory/api/gpg/key/public" | gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg
echo "deb [signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb ${DISTRO_CODENAME} main" \
>/etc/apt/sources.list.d/adoptium.list
$STD apt-get update
$STD msg_ok "Set up Adoptium Repository"
curl -fsSL "https://packages.adoptium.net/artifactory/api/gpg/key/public" | gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "https://packages.adoptium.net/artifactory/deb/dists/$DISTRO_CODENAME/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian) SUITE="bookworm" ;;
ubuntu) SUITE="jammy" ;;
esac
fi
cat <<EOF >/etc/apt/sources.list.d/adoptium.sources
Types: deb
URIs: https://packages.adoptium.net/artifactory/deb
Suites: $SUITE
Components: main
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/adoptium.gpg
EOF
$STD apt update
msg_ok "Set up Adoptium Repository"
fi
# Detect currently installed temurin version
local INSTALLED_VERSION=""
if dpkg -l | grep -q "temurin-.*-jdk"; then
INSTALLED_VERSION=$(dpkg -l | awk '/temurin-.*-jdk/{print $2}' | grep -oP 'temurin-\K[0-9]+')
fi
if [[ "$INSTALLED_VERSION" == "$JAVA_VERSION" ]]; then
$STD msg_info "Upgrading Temurin JDK $JAVA_VERSION"
$STD apt-get update
$STD apt-get install --only-upgrade -y "$DESIRED_PACKAGE"
$STD msg_ok "Upgraded Temurin JDK $JAVA_VERSION"
msg_info "Upgrading Temurin JDK $JAVA_VERSION"
$STD apt update
$STD apt install --only-upgrade -y "$DESIRED_PACKAGE"
msg_ok "Upgraded Temurin JDK $JAVA_VERSION"
else
if [[ -n "$INSTALLED_VERSION" ]]; then
$STD msg_info "Removing Temurin JDK $INSTALLED_VERSION"
$STD apt-get purge -y "temurin-${INSTALLED_VERSION}-jdk"
msg_info "Removing old Temurin JDK $INSTALLED_VERSION"
$STD apt purge -y "temurin-${INSTALLED_VERSION}-jdk"
msg_ok "Removed old Temurin JDK"
fi
msg_info "Setup Temurin JDK $JAVA_VERSION"
$STD apt-get install -y "$DESIRED_PACKAGE"
msg_ok "Setup Temurin JDK $JAVA_VERSION"
msg_info "Installing Temurin JDK $JAVA_VERSION"
$STD apt install -y "$DESIRED_PACKAGE"
msg_ok "Installed Temurin JDK $JAVA_VERSION"
fi
}
@@ -1075,8 +1106,8 @@ function setup_local_ip_helper() {
# Install networkd-dispatcher if not present
if ! dpkg -s networkd-dispatcher >/dev/null 2>&1; then
$STD apt-get update
$STD apt-get install -y networkd-dispatcher
$STD apt update
$STD apt install -y networkd-dispatcher
fi
# Write update_local_ip.sh
@@ -1149,17 +1180,15 @@ EOF
setup_mariadb() {
local MARIADB_VERSION="${MARIADB_VERSION:-latest}"
local DISTRO_CODENAME
DISTRO_CODENAME="$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)"
CURRENT_OS="$(awk -F= '/^ID=/{print $2}' /etc/os-release)"
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
if ! curl -fsI http://mirror.mariadb.org/repo/ >/dev/null; then
msg_error "MariaDB mirror not reachable"
return 1
fi
msg_info "Setting up MariaDB $MARIADB_VERSION"
# Grab dynamic latest LTS version
if [[ "$MARIADB_VERSION" == "latest" ]]; then
MARIADB_VERSION=$(curl -fsSL http://mirror.mariadb.org/repo/ |
grep -Eo '[0-9]+\.[0-9]+\.[0-9]+/' |
@@ -1179,54 +1208,56 @@ setup_mariadb() {
fi
if [[ "$CURRENT_VERSION" == "$MARIADB_VERSION" ]]; then
$STD msg_info "MariaDB $MARIADB_VERSION, upgrading"
$STD apt-get update
$STD apt-get install --only-upgrade -y mariadb-server mariadb-client
$STD msg_ok "MariaDB upgraded to $MARIADB_VERSION"
msg_info "Upgrading MariaDB $MARIADB_VERSION"
$STD apt update
$STD apt install --only-upgrade -y mariadb-server mariadb-client
msg_ok "Upgraded MariaDB $MARIADB_VERSION"
return 0
fi
msg_info "Installing MariaDB $MARIADB_VERSION"
if [[ -n "$CURRENT_VERSION" ]]; then
$STD msg_info "Upgrading MariaDB $CURRENT_VERSION to $MARIADB_VERSION"
$STD systemctl stop mariadb >/dev/null 2>&1 || true
$STD apt-get purge -y 'mariadb*' || true
rm -f /etc/apt/sources.list.d/mariadb.list /etc/apt/trusted.gpg.d/mariadb.gpg
else
$STD msg_info "Setup MariaDB $MARIADB_VERSION"
$STD apt purge -y 'mariadb*' || true
rm -f /etc/apt/sources.list.d/mariadb.* /etc/apt/keyrings/mariadb.gpg
fi
curl -fsSL "https://mariadb.org/mariadb_release_signing_key.asc" |
gpg --dearmor -o /etc/apt/trusted.gpg.d/mariadb.gpg
gpg --dearmor -o /etc/apt/keyrings/mariadb.gpg
echo "deb [signed-by=/etc/apt/trusted.gpg.d/mariadb.gpg] http://mirror.mariadb.org/repo/${MARIADB_VERSION}/${CURRENT_OS} ${DISTRO_CODENAME} main" \
>/etc/apt/sources.list.d/mariadb.list
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "http://mirror.mariadb.org/repo/${MARIADB_VERSION}/${DISTRO_ID}/dists/$DISTRO_CODENAME/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian) SUITE="bookworm" ;;
ubuntu) SUITE="jammy" ;;
esac
fi
$STD apt-get update
cat <<EOF >/etc/apt/sources.list.d/mariadb.sources
Types: deb
URIs: http://mirror.mariadb.org/repo/${MARIADB_VERSION}/${DISTRO_ID}
Suites: $SUITE
Components: main
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/mariadb.gpg
EOF
$STD apt update
local MARIADB_MAJOR_MINOR
MARIADB_MAJOR_MINOR=$(echo "$MARIADB_VERSION" | awk -F. '{print $1"."$2}')
if [[ -n "$MARIADB_MAJOR_MINOR" ]]; then
echo "mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/feedback boolean false" | debconf-set-selections
else
for ver in 12.1 12.0 11.4 11.3 11.2 11.1 11.0 10.11 10.6 10.5 10.4 10.3; do
echo "mariadb-server-$ver mariadb-server/feedback boolean false" | debconf-set-selections
done
fi
DEBIAN_FRONTEND=noninteractive $STD apt-get install -y mariadb-server mariadb-client || {
msg_warn "Failed to install MariaDB ${MARIADB_VERSION} from upstream repo trying distro package as fallback..."
# Cleanup, remove upstream repo to avoid conflicts
rm -f /etc/apt/sources.list.d/mariadb.list /etc/apt/trusted.gpg.d/mariadb.gpg
$STD apt-get update
# Final fallback: distro package
DEBIAN_FRONTEND=noninteractive $STD apt-get install -y mariadb-server mariadb-client || {
msg_error "MariaDB installation failed even with distro fallback!"
return 1
}
msg_ok "Setup MariaDB (distro fallback)"
return 0
DEBIAN_FRONTEND=noninteractive $STD apt install -y mariadb-server mariadb-client || {
rm -f /etc/apt/sources.list.d/mariadb.sources /etc/apt/keyrings/mariadb.gpg
$STD apt update
DEBIAN_FRONTEND=noninteractive $STD apt install -y mariadb-server mariadb-client
}
msg_ok "Setup MariaDB $MARIADB_VERSION"
msg_ok "Installed MariaDB $MARIADB_VERSION"
}
# ------------------------------------------------------------------------------
@@ -1242,7 +1273,7 @@ setup_mariadb() {
function setup_mongodb() {
local MONGO_VERSION="${MONGO_VERSION:-8.0}"
local DISTRO_ID DISTRO_CODENAME MONGO_BASE_URL
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{ gsub(/"/,"",$2); print $2 }' /etc/os-release)
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{ print $2 }' /etc/os-release)
@@ -1270,40 +1301,64 @@ function setup_mongodb() {
;;
esac
local REPO_LIST="/etc/apt/sources.list.d/mongodb-org-${MONGO_VERSION}.list"
local INSTALLED_VERSION=""
if command -v mongod >/dev/null; then
INSTALLED_VERSION=$(mongod --version | awk '/db version/{print $3}' | cut -d. -f1,2)
fi
if [[ "$INSTALLED_VERSION" == "$MONGO_VERSION" ]]; then
$STD msg_info "Upgrading MongoDB $MONGO_VERSION"
$STD apt-get update
$STD apt-get install --only-upgrade -y mongodb-org
$STD msg_ok "Upgraded MongoDB $MONGO_VERSION"
msg_info "Upgrading MongoDB $MONGO_VERSION"
$STD apt update
$STD apt install --only-upgrade -y mongodb-org
msg_ok "Upgraded MongoDB $MONGO_VERSION"
return 0
fi
if [[ -n "$INSTALLED_VERSION" ]]; then
$STD systemctl stop mongod || true
$STD apt-get purge -y mongodb-org || true
rm -f /etc/apt/sources.list.d/mongodb-org-*.list
rm -f /etc/apt/trusted.gpg.d/mongodb-*.gpg
$STD apt purge -y mongodb-org || true
rm -f /etc/apt/sources.list.d/mongodb-org-*.* /etc/apt/keyrings/mongodb-*.gpg
else
msg_info "Setup MongoDB $MONGO_VERSION"
fi
curl -fsSL "https://pgp.mongodb.com/server-${MONGO_VERSION}.asc" | gpg --dearmor -o "/etc/apt/trusted.gpg.d/mongodb-${MONGO_VERSION}.gpg"
echo "deb [signed-by=/etc/apt/trusted.gpg.d/mongodb-${MONGO_VERSION}.gpg] ${MONGO_BASE_URL} ${DISTRO_CODENAME}/mongodb-org/${MONGO_VERSION} ${REPO_COMPONENT}" \
>"$REPO_LIST"
curl -fsSL "https://pgp.mongodb.com/server-${MONGO_VERSION}.asc" | gpg --dearmor -o "/etc/apt/keyrings/mongodb-${MONGO_VERSION}.gpg"
$STD apt-get update || {
# Fallback logic for MongoDB repos
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "${MONGO_BASE_URL}/dists/${DISTRO_CODENAME}/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian)
case "$DISTRO_CODENAME" in
trixie) SUITE="bookworm" ;;
*) SUITE="bookworm" ;;
esac
;;
ubuntu)
case "$DISTRO_CODENAME" in
oracular | noble) SUITE="jammy" ;;
*) SUITE="jammy" ;;
esac
;;
esac
msg_info "Using fallback suite: $SUITE (original: $DISTRO_CODENAME)"
fi
cat <<EOF >/etc/apt/sources.list.d/mongodb-org-${MONGO_VERSION}.sources
Types: deb
URIs: ${MONGO_BASE_URL}
Suites: ${SUITE}/mongodb-org/${MONGO_VERSION}
Components: ${REPO_COMPONENT}
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/mongodb-${MONGO_VERSION}.gpg
EOF
$STD apt update || {
msg_error "APT update failed — invalid MongoDB repo for ${DISTRO_ID}-${DISTRO_CODENAME}?"
return 1
}
$STD apt-get install -y mongodb-org
$STD apt install -y mongodb-org
mkdir -p /var/lib/mongodb
chown -R mongodb:mongodb /var/lib/mongodb
@@ -1329,20 +1384,21 @@ function setup_mysql() {
local MYSQL_VERSION="${MYSQL_VERSION:-8.0}"
local CURRENT_VERSION=""
local NEED_INSTALL=false
CURRENT_OS="$(awk -F= '/^ID=/{print $2}' /etc/os-release)"
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
if command -v mysql >/dev/null; then
CURRENT_VERSION="$(mysql --version | grep -oP '[0-9]+\.[0-9]+' | head -n1)"
if [[ "$CURRENT_VERSION" != "$MYSQL_VERSION" ]]; then
$STD msg_info "MySQL $CURRENT_VERSION will be upgraded to $MYSQL_VERSION"
msg_info "MySQL $CURRENT_VERSION will be upgraded to $MYSQL_VERSION"
NEED_INSTALL=true
else
# Check for patch-level updates
if apt list --upgradable 2>/dev/null | grep -q '^mysql-server/'; then
$STD msg_info "MySQL $CURRENT_VERSION available for upgrade"
$STD apt-get update
$STD apt-get install --only-upgrade -y mysql-server
$STD msg_ok "MySQL upgraded"
msg_info "MySQL $CURRENT_VERSION available for upgrade"
$STD apt update
$STD apt install --only-upgrade -y mysql-server
msg_ok "MySQL upgraded"
fi
return
fi
@@ -1353,18 +1409,43 @@ function setup_mysql() {
if [[ "$NEED_INSTALL" == true ]]; then
$STD systemctl stop mysql || true
$STD apt-get purge -y "^mysql-server.*" "^mysql-client.*" "^mysql-common.*" || true
rm -f /etc/apt/sources.list.d/mysql.list /etc/apt/trusted.gpg.d/mysql.gpg
$STD apt purge -y "^mysql-server.*" "^mysql-client.*" "^mysql-common.*" || true
rm -f /etc/apt/sources.list.d/mysql.* /etc/apt/keyrings/mysql.gpg
local DISTRO_CODENAME
DISTRO_CODENAME="$(awk -F= '/VERSION_CODENAME/ { print $2 }' /etc/os-release)"
curl -fsSL https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 | gpg --dearmor -o /etc/apt/trusted.gpg.d/mysql.gpg
echo "deb [signed-by=/etc/apt/trusted.gpg.d/mysql.gpg] https://repo.mysql.com/apt/${CURRENT_OS}/ ${DISTRO_CODENAME} mysql-${MYSQL_VERSION}" \
>/etc/apt/sources.list.d/mysql.list
# Fallback logic for MySQL repos
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "https://repo.mysql.com/apt/${DISTRO_ID}/dists/$DISTRO_CODENAME/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian)
case "$DISTRO_CODENAME" in
trixie) SUITE="bookworm" ;;
*) SUITE="bookworm" ;;
esac
;;
ubuntu)
case "$DISTRO_CODENAME" in
oracular | noble) SUITE="jammy" ;;
*) SUITE="jammy" ;;
esac
;;
esac
msg_info "Using fallback suite: $SUITE (original: $DISTRO_CODENAME)"
fi
curl -fsSL https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 | gpg --dearmor -o /etc/apt/keyrings/mysql.gpg
cat <<EOF >/etc/apt/sources.list.d/mysql.sources
Types: deb
URIs: https://repo.mysql.com/apt/${DISTRO_ID}
Suites: ${SUITE}
Components: mysql-${MYSQL_VERSION}
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/mysql.gpg
EOF
export DEBIAN_FRONTEND=noninteractive
$STD apt-get update
$STD apt-get install -y mysql-server
$STD apt update
$STD apt install -y mysql-server
msg_ok "Setup MySQL $MYSQL_VERSION"
fi
}
@@ -1386,8 +1467,10 @@ function setup_nodejs() {
local NODE_MODULE="${NODE_MODULE:-}"
local CURRENT_NODE_VERSION=""
local NEED_NODE_INSTALL=false
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
# Check if Node.js is already installed
if command -v node >/dev/null; then
CURRENT_NODE_VERSION="$(node -v | grep -oP '^v\K[0-9]+')"
if [[ "$CURRENT_NODE_VERSION" != "$NODE_VERSION" ]]; then
@@ -1400,102 +1483,101 @@ function setup_nodejs() {
fi
if ! command -v jq &>/dev/null; then
$STD apt-get update
$STD apt-get install -y jq || {
$STD apt update
$STD apt install -y jq || {
msg_error "Failed to install jq"
return 1
}
fi
# Install Node.js if required
if [[ "$NEED_NODE_INSTALL" == true ]]; then
$STD apt-get purge -y nodejs
rm -f /etc/apt/sources.list.d/nodesource.list /etc/apt/keyrings/nodesource.gpg
$STD apt purge -y nodejs
rm -f /etc/apt/sources.list.d/nodesource.* /etc/apt/keyrings/nodesource.gpg
mkdir -p /etc/apt/keyrings
if ! curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key |
gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; then
msg_error "Failed to download or import NodeSource GPG key"
exit 1
return 1
fi
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" \
>/etc/apt/sources.list.d/nodesource.list
# NodeSource uses 'nodistro' for all distributions
cat <<EOF >/etc/apt/sources.list.d/nodesource.sources
Types: deb
URIs: https://deb.nodesource.com/node_${NODE_VERSION}.x
Suites: nodistro
Components: main
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/nodesource.gpg
EOF
sleep 2
if ! apt-get update >/dev/null 2>&1; then
if ! $STD apt update; then
msg_warn "APT update failed retrying in 5s"
sleep 5
if ! apt-get update >/dev/null 2>&1; then
if ! $STD apt update; then
msg_error "Failed to update APT repositories after adding NodeSource"
exit 1
return 1
fi
fi
if ! apt-get install -y nodejs >/dev/null 2>&1; then
if ! $STD apt install -y nodejs; then
msg_error "Failed to install Node.js ${NODE_VERSION} from NodeSource"
exit 1
return 1
fi
# Update to latest npm
$STD npm install -g npm@latest || {
msg_error "Failed to update npm to latest version"
msg_warn "Failed to update npm to latest version"
}
msg_ok "Setup Node.js ${NODE_VERSION}"
fi
export NODE_OPTIONS="--max-old-space-size=4096"
# Ensure valid working directory for npm (avoids uv_cwd error)
if [[ ! -d /opt ]]; then
mkdir -p /opt
fi
cd /opt || {
msg_error "Failed to set safe working directory before npm install"
exit 1
return 1
}
# Install global Node modules
if [[ -n "$NODE_MODULE" ]]; then
IFS=',' read -ra MODULES <<<"$NODE_MODULE"
for mod in "${MODULES[@]}"; do
local MODULE_NAME MODULE_REQ_VERSION MODULE_INSTALLED_VERSION
if [[ "$mod" == @*/*@* ]]; then
# Scoped package with version, e.g. @vue/cli-service@latest
MODULE_NAME="${mod%@*}"
MODULE_REQ_VERSION="${mod##*@}"
elif [[ "$mod" == *"@"* ]]; then
# Unscoped package with version, e.g. yarn@latest
MODULE_NAME="${mod%@*}"
MODULE_REQ_VERSION="${mod##*@}"
else
# No version specified
MODULE_NAME="$mod"
MODULE_REQ_VERSION="latest"
fi
# Check if the module is already installed
if npm list -g --depth=0 "$MODULE_NAME" >/dev/null 2>&1; then
MODULE_INSTALLED_VERSION="$(npm list -g --depth=0 "$MODULE_NAME" | grep "$MODULE_NAME@" | awk -F@ '{print $2}' | tr -d '[:space:]')"
if [[ "$MODULE_REQ_VERSION" != "latest" && "$MODULE_REQ_VERSION" != "$MODULE_INSTALLED_VERSION" ]]; then
msg_info "Updating $MODULE_NAME from v$MODULE_INSTALLED_VERSION to v$MODULE_REQ_VERSION"
if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then
msg_error "Failed to update $MODULE_NAME to version $MODULE_REQ_VERSION"
exit 1
return 1
fi
elif [[ "$MODULE_REQ_VERSION" == "latest" ]]; then
msg_info "Updating $MODULE_NAME to latest version"
if ! $STD npm install -g "${MODULE_NAME}@latest"; then
msg_error "Failed to update $MODULE_NAME to latest version"
exit 1
return 1
fi
fi
else
msg_info "Installing $MODULE_NAME@$MODULE_REQ_VERSION"
if ! $STD npm install -g "${MODULE_NAME}@${MODULE_REQ_VERSION}"; then
msg_error "Failed to install $MODULE_NAME@$MODULE_REQ_VERSION"
exit 1
return 1
fi
fi
done
@@ -1527,8 +1609,9 @@ function setup_php() {
local PHP_MODULE="${PHP_MODULE:-}"
local PHP_APACHE="${PHP_APACHE:-NO}"
local PHP_FPM="${PHP_FPM:-NO}"
local DISTRO_CODENAME
DISTRO_CODENAME=$(awk -F= '/VERSION_CODENAME/ { print $2 }' /etc/os-release)
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
local DEFAULT_MODULES="bcmath,cli,curl,gd,intl,mbstring,opcache,readline,xml,zip"
local COMBINED_MODULES
@@ -1558,16 +1641,43 @@ function setup_php() {
msg_info "Setup PHP $PHP_VERSION"
elif [[ "$CURRENT_PHP" != "$PHP_VERSION" ]]; then
msg_info "Old PHP $CURRENT_PHP detected, Setup new PHP $PHP_VERSION"
$STD apt-get purge -y "php${CURRENT_PHP//./}"* || true
$STD apt purge -y "php${CURRENT_PHP//./}"* || true
fi
# Ensure Sury repo is available
if [[ ! -f /etc/apt/sources.list.d/php.list ]]; then
if [[ ! -f /etc/apt/sources.list.d/php.sources ]]; then
$STD curl -fsSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
$STD dpkg -i /tmp/debsuryorg-archive-keyring.deb
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ ${DISTRO_CODENAME} main" \
>/etc/apt/sources.list.d/php.list
$STD apt-get update
# Fallback logic for PHP repos
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "https://packages.sury.org/php/dists/$DISTRO_CODENAME/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian)
case "$DISTRO_CODENAME" in
trixie) SUITE="bookworm" ;;
*) SUITE="bookworm" ;;
esac
;;
ubuntu)
case "$DISTRO_CODENAME" in
oracular | noble) SUITE="jammy" ;;
*) SUITE="jammy" ;;
esac
;;
esac
msg_info "Using fallback suite: $SUITE (original: $DISTRO_CODENAME)"
fi
cat <<EOF >/etc/apt/sources.list.d/php.sources
Types: deb
URIs: https://packages.sury.org/php/
Suites: $SUITE
Components: main
Architectures: amd64 arm64
Signed-By: /usr/share/keyrings/deb.sury.org-php.gpg
EOF
$STD apt update
fi
# Build module list
@@ -1588,14 +1698,14 @@ function setup_php() {
if [[ "$PHP_APACHE" == "YES" ]]; then
if ! dpkg -l | grep -q "libapache2-mod-php${PHP_VERSION}"; then
msg_info "Installing Apache with PHP${PHP_VERSION} support"
$STD apt-get install -y apache2 libapache2-mod-php${PHP_VERSION}
$STD apt install -y apache2 libapache2-mod-php${PHP_VERSION}
else
msg_info "Apache with PHP${PHP_VERSION} already installed skipping install"
fi
fi
# setup / update PHP modules
$STD apt-get install -y $MODULE_LIST
$STD apt install -y $MODULE_LIST
msg_ok "Setup PHP $PHP_VERSION"
# optional stop old PHP-FPM service
@@ -1610,12 +1720,12 @@ function setup_php() {
[[ "$PHP_APACHE" == "YES" ]] && PHP_INI_PATHS+=("/etc/php/${PHP_VERSION}/apache2/php.ini")
for ini in "${PHP_INI_PATHS[@]}"; do
if [[ -f "$ini" ]]; then
$STD msg_info "Patching $ini"
msg_info "Patching $ini"
sed -i "s|^memory_limit = .*|memory_limit = ${PHP_MEMORY_LIMIT}|" "$ini"
sed -i "s|^upload_max_filesize = .*|upload_max_filesize = ${PHP_UPLOAD_MAX_FILESIZE}|" "$ini"
sed -i "s|^post_max_size = .*|post_max_size = ${PHP_POST_MAX_SIZE}|" "$ini"
sed -i "s|^max_execution_time = .*|max_execution_time = ${PHP_MAX_EXECUTION_TIME}|" "$ini"
$STD msg_ok "Patched $ini"
msg_ok "Patched $ini"
fi
done
@@ -1660,60 +1770,85 @@ function setup_postgresql() {
local PG_VERSION="${PG_VERSION:-16}"
local PG_MODULES="${PG_MODULES:-}"
local CURRENT_PG_VERSION=""
local DISTRO
local DISTRO_ID DISTRO_CODENAME
local NEED_PG_INSTALL=false
DISTRO="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
if command -v psql >/dev/null; then
CURRENT_PG_VERSION="$(psql -V | awk '{print $3}' | cut -d. -f1)"
if [[ "$CURRENT_PG_VERSION" == "$PG_VERSION" ]]; then
: # PostgreSQL is already at the desired version no action needed
: # PostgreSQL is already at the desired version
else
$STD msg_info "Detected PostgreSQL $CURRENT_PG_VERSION, preparing upgrade to $PG_VERSION"
msg_info "Detected PostgreSQL $CURRENT_PG_VERSION, preparing upgrade to $PG_VERSION"
NEED_PG_INSTALL=true
fi
else
NEED_PG_INSTALL=true
fi
if [[ "$NEED_PG_INSTALL" == true ]]; then
if [[ -n "$CURRENT_PG_VERSION" ]]; then
$STD msg_info "Dumping PostgreSQL $CURRENT_PG_VERSION data"
msg_info "Dumping PostgreSQL $CURRENT_PG_VERSION data"
su - postgres -c "pg_dumpall > /var/lib/postgresql/backup_$(date +%F)_v${CURRENT_PG_VERSION}.sql"
$STD msg_ok "Data dump completed"
msg_ok "Data dump completed"
systemctl stop postgresql
fi
rm -f /etc/apt/sources.list.d/pgdg.list /etc/apt/trusted.gpg.d/postgresql.gpg
rm -f /etc/apt/sources.list.d/pgdg.* /etc/apt/keyrings/postgresql.gpg
$STD msg_info "Adding PostgreSQL PGDG repository"
msg_info "Adding PostgreSQL PGDG repository"
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc |
gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg
echo "deb https://apt.postgresql.org/pub/repos/apt ${DISTRO}-pgdg main" \
>/etc/apt/sources.list.d/pgdg.list
# Fallback logic for PostgreSQL repos
local SUITE="$DISTRO_CODENAME"
if ! curl -fsSL "https://apt.postgresql.org/pub/repos/apt/dists/${DISTRO_CODENAME}-pgdg/Release" &>/dev/null; then
case "$DISTRO_ID" in
debian)
case "$DISTRO_CODENAME" in
trixie) SUITE="bookworm" ;;
*) SUITE="bookworm" ;;
esac
;;
ubuntu)
case "$DISTRO_CODENAME" in
oracular | noble) SUITE="jammy" ;;
*) SUITE="jammy" ;;
esac
;;
esac
msg_info "Using fallback suite: $SUITE (original: $DISTRO_CODENAME)"
fi
$STD apt-get update
$STD msg_ok "Repository added"
cat <<EOF >/etc/apt/sources.list.d/pgdg.sources
Types: deb
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: ${SUITE}-pgdg
Components: main
Architectures: amd64 arm64
Signed-By: /etc/apt/keyrings/postgresql.gpg
EOF
$STD apt update
msg_ok "Repository added"
msg_info "Setup PostgreSQL $PG_VERSION"
$STD apt-get install -y "postgresql-${PG_VERSION}" "postgresql-client-${PG_VERSION}"
$STD apt install -y "postgresql-${PG_VERSION}" "postgresql-client-${PG_VERSION}"
if [[ -n "$CURRENT_PG_VERSION" ]]; then
$STD apt-get purge -y "postgresql-${CURRENT_PG_VERSION}" "postgresql-client-${CURRENT_PG_VERSION}" || true
$STD apt purge -y "postgresql-${CURRENT_PG_VERSION}" "postgresql-client-${CURRENT_PG_VERSION}" || true
fi
systemctl enable -q --now postgresql
if [[ -n "$CURRENT_PG_VERSION" ]]; then
$STD msg_info "Restoring dumped data"
msg_info "Restoring dumped data"
su - postgres -c "psql < /var/lib/postgresql/backup_$(date +%F)_v${CURRENT_PG_VERSION}.sql"
$STD msg_ok "Data restored"
msg_ok "Data restored"
fi
$STD msg_ok "PostgreSQL $PG_VERSION installed"
msg_ok "PostgreSQL $PG_VERSION installed"
fi
# Install optional PostgreSQL modules
@@ -1721,13 +1856,13 @@ function setup_postgresql() {
IFS=',' read -ra MODULES <<<"$PG_MODULES"
for module in "${MODULES[@]}"; do
local pkg="postgresql-${PG_VERSION}-${module}"
$STD msg_info "Setup PostgreSQL module/s: $pkg"
$STD apt-get install -y "$pkg" || {
msg_info "Setup PostgreSQL module/s: $pkg"
$STD apt install -y "$pkg" || {
msg_error "Failed to install $pkg"
continue
}
done
$STD msg_ok "Setup PostgreSQL modules"
msg_ok "Setup PostgreSQL modules"
fi
}
@@ -1801,7 +1936,7 @@ function setup_ruby() {
if [[ "$RUBY_INSTALL_RAILS" == "true" ]]; then
msg_info "Setup Rails via gem"
gem install rails
$STD gem install rails
msg_ok "Setup Rails $(rails -v)"
fi
@@ -2013,8 +2148,8 @@ function setup_yq() {
local GITHUB_REPO="mikefarah/yq"
if ! command -v jq &>/dev/null; then
$STD apt-get update
$STD apt-get install -y jq || {
$STD apt update
$STD apt install -y jq || {
msg_error "Failed to install jq"
rm -rf "$TMP_DIR"
return 1