Update ha_automatic_packages.sh

This commit is contained in:
Alexandre
2025-06-06 14:53:03 +02:00
committed by GitHub
parent 4630266491
commit 9c5ea903c5

View File

@@ -1,221 +1,275 @@
#!/usr/bin/env bash #!/bin/bash
set -xe set -e
#################### ########
# helper functions # # INIT #
#################### ########
log() { [[ ${VERBOSE:-false} == true ]] && echo "$*"; }
die() { echo "ERROR: $*" >&2; exit 1; }
is_installed() { for c; do command -v "$c" &>/dev/null || return 1; done; return 0; }
######################### #Verbose or not
# detect package system # VERBOSE=false
######################### #Avoid fails on non declared variables
if command -v apk &>/dev/null; then set +u 2>/dev/null || true
PM=apk #If no packages, empty
INSTALL="apk add --no-cache" PACKAGES="${*:-}"
UPDATE="apk update -q" #Avoids messages if non interactive
elif command -v apt-get &>/dev/null; then (echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections) &>/dev/null || true
PM=apt
INSTALL="apt-get -yqq install --no-install-recommends" [ "$VERBOSE" = true ] && echo "ENV : $PACKAGES"
UPDATE="apt-get -qq update"
elif command -v pacman &>/dev/null; then ############################
PM=pacman # CHECK WHICH BASE IS USED #
INSTALL="pacman -Sy --noconfirm" ############################
UPDATE="pacman -Sy --noconfirm"
else if command -v "apk" &>/dev/null; then
die "No supported package manager found" # If apk based
[ "$VERBOSE" = true ] && echo "apk based"
PACKMANAGER="apk"
elif command -v "apt" &>/dev/null; then
# If apt-get based
[ "$VERBOSE" = true ] && echo "apt based"
PACKMANAGER="apt"
elif command -v "pacman" &>/dev/null; then
# If apt-get based
[ "$VERBOSE" = true ] && echo "pacman based"
PACKMANAGER="pacman"
fi fi
log "Detected package manager: $PM"
############################ ###################
# static base dependencies # # DEFINE PACKAGES #
############################ ###################
pkgs_common=(jq curl ca-certificates)
#########################################
# map tool → packages (per PM) in YAML #
#########################################
declare -A APT=(
[nginx]="nginx"
[mount]="exfat-fuse ntfs-3g squashfs-tools util-linux"
[ping]="iputils-ping"
[nmap]="nmap"
[cifs]="cifs-utils keyutils"
[smbclient]="samba smbclient ntfs-3g"
[dos2unix]="dos2unix"
[openvpn]="openvpn coreutils"
[jq]="jq"
[yamllint]="yamllint"
[git]="git"
[sponge]="moreutils"
[sqlite3]="sqlite3"
[pip]="python3-pip"
[wget]="wget"
)
declare -A APK=(
[nginx]="nginx"
[mount]="exfatprogs ntfs-3g squashfs-tools fuse lsblk"
[ping]="iputils"
[nmap]="nmap nmap-scripts"
[cifs]="cifs-utils keyutils"
[smbclient]="samba samba-client ntfs-3g"
[dos2unix]="dos2unix"
[openvpn]="openvpn coreutils"
[jq]="jq"
[yamllint]="yamllint"
[git]="git"
[sponge]="moreutils"
[sqlite3]="sqlite"
[pip]="py3-pip"
[wget]="wget"
)
declare -A PACMAN=(
[nginx]="nginx"
[mount]="exfat-utils ntfs-3g squashfs-tools util-linux fuse2fs"
[ping]="iputils"
[nmap]="nmap"
[cifs]="cifs-utils keyutils"
[smbclient]="samba smbclient"
[dos2unix]="dos2unix"
[openvpn]="openvpn coreutils"
[jq]="jq"
[yamllint]="yamllint"
[git]="git"
[sponge]="moreutils"
[sqlite3]="sqlite"
[pip]="python-pip"
[wget]="wget"
)
########################
# scan service scripts #
########################
dirs=(/etc/cont-init.d /etc/services.d)
declare -a wants=()
# 1. Add command-line arguments (if any)
for arg in "$@"; do
wants+=("$arg")
done
# 2. Add detected commands from scanning the folders
for d in "${dirs[@]}"; do
[[ -d $d ]] || continue
mapfile -d '' all_files < <(find "$d" -type f -print0)
[[ ${#all_files[@]} -eq 0 ]] && continue
for cmd in "${!APT[@]}"; do
grep -qF "$cmd" "${all_files[@]}" && wants+=("$cmd")
done
done
# ADD GENERAL ELEMENTS
###################### ######################
# build package list #
######################
declare -a pkgs=("${pkgs_common[@]}")
for cmd in $(printf '%s\n' "${wants[@]}" | sort -u); do
is_installed "$cmd" && continue
case "$PM" in
apt) pkgstr="${APT[$cmd]}";;
apk) pkgstr="${APK[$cmd]}";;
pacman) pkgstr="${PACMAN[$cmd]}";;
esac
# FIX: explicit if, safe splitting
if [[ -n $pkgstr ]]; then
read -r -a pkgarr <<< "$pkgstr"
pkgs+=("${pkgarr[@]}")
else
log "No package mapping for $cmd on $PM"
fi
done
# de-dup final list
mapfile -t pkgs < <(printf '%s\n' "${pkgs[@]}" | sort -u)
if [[ -d /etc/nginx ]]; then mv /etc/nginx /etc/nginx2; fi PACKAGES="$PACKAGES jq curl ca-certificates"
################ # FOR EACH SCRIPT, SELECT PACKAGES
# installation # ##################################
################
log "Updating package index…" # Scripts
$UPDATE for files in "/etc/cont-init.d" "/etc/services.d"; do
# Next directory if does not exists
if ! ls $files 1>/dev/null 2>&1; then continue; fi
# Test each possible command
COMMAND="nginx"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES nginx"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES nginx"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES nginx"
if ls /etc/nginx 1>/dev/null 2>&1; then mv /etc/nginx /etc/nginx2; fi
fi
COMMAND="mount"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES exfatprogs ntfs-3g ntfs-3g-progs squashfs-tools fuse lsblk"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES exfat* ntfs* squashfs-tools util-linux"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES ntfs-3g"
fi
COMMAND="ping"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES iputils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES iputils-ping"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES iputils"
fi
COMMAND="nmap"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES nmap nmap-scripts"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES nmap"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES iputils"
fi
COMMAND="cifs"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
fi
COMMAND="smbclient"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES samba samba-client ntfs-3g"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES samba smbclient ntfs-3g"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES samba smbclient"
fi
COMMAND="dos2unix"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES dos2unix"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES dos2unix"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES dos2unix"
fi
COMMAND="openvpn"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES coreutils openvpn"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES coreutils openvpn"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES coreutils openvpn"
fi
COMMAND="jq"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES jq"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES jq"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES jq"
fi
COMMAND="yamllint"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES yamllint"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES yamllint"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES yamllint"
fi
COMMAND="git"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES git"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES git"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES git"
fi
COMMAND="sponge"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES moreutils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES moreutils"
[ "$PACKMANAGER" = "pacman " ] && PACKAGES="$PACKAGES moreutils"
fi
COMMAND="sqlite3"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES sqlite"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES sqlite3"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES sqlite3"
fi
COMMAND="pip"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES py3-pip"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES pip"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES pip"
fi
COMMAND="wget"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES wget"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES wget"
[ "$PACKMANAGER" = "wget" ] && PACKAGES="$PACKAGES wget"
fi
log "Installing packages: ${pkgs[*]}"
for p in "${pkgs[@]}"; do
log "$p"
if ! $INSTALL "$p" &>/dev/null; then
log " ⚠️ $p not found"
touch /ERROR
fi
done done
if [[ -d /etc/nginx2 ]]; then ####################
log "replace nginx2" # INSTALL ELEMENTS #
rm -rf /etc/nginx ####################
# Install apps
[ "$VERBOSE" = true ] && echo "installing packages $PACKAGES"
if [ "$PACKMANAGER" = "apt" ]; then apt-get update >/dev/null; fi
if [ "$PACKMANAGER" = "pacman" ]; then pacman -Sy >/dev/null; fi
# Install apps one by one to allow failures
# shellcheck disable=SC2086
for packagestoinstall in $PACKAGES; do
[ "$VERBOSE" = true ] && echo "... $packagestoinstall"
if [ "$PACKMANAGER" = "apk" ]; then
apk add --no-cache "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
elif [ "$PACKMANAGER" = "apt" ]; then
apt-get install -yqq --no-install-recommends "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
elif [ "$PACKMANAGER" = "pacman" ]; then
pacman --noconfirm -S "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
fi
[ "$VERBOSE" = true ] && echo "... $packagestoinstall done"
done
# Clean after install
[ "$VERBOSE" = true ] && echo "Cleaning apt cache"
if [ "$PACKMANAGER" = "apt" ]; then apt-get clean >/dev/null; fi
# Replace nginx if installed
if ls /etc/nginx2 1>/dev/null 2>&1; then
[ "$VERBOSE" = true ] && echo "replace nginx2"
rm -r /etc/nginx
mv /etc/nginx2 /etc/nginx mv /etc/nginx2 /etc/nginx
mkdir -p /var/log/nginx mkdir -p /var/log/nginx
touch /var/log/nginx/error.log touch /var/log/nginx/error.log
fi fi
[[ $PM == apt ]] && apt-get clean -qq #######################
# INSTALL MANUAL APPS #
#######################
############ # Install micro texteditor
# extras # curl https://getmic.ro | bash || true
############ mv micro /usr/bin || true
if ! command -v micro &>/dev/null; then micro -plugin install bounce || true
log "Installing micro text editor" micro -plugin install filemanager || true
curl https://getmic.ro | bash || true
mv micro /usr/bin || true
micro -plugin install bounce || true
micro -plugin install filemanager || true
fi
for files in "/etc/services.d" "/etc/cont-init.d"; do for files in "/etc/services.d" "/etc/cont-init.d"; do
[[ -d $files ]] || continue
if grep -q -rnw "$files/" -e 'bashio' && [[ ! -f "/usr/bin/bashio" ]]; then # Next directory if does not exists
log "install bashio" if ! ls $files 1>/dev/null 2>&1; then continue; fi
BASHIO_VERSION="0.14.3"
mkdir -p /tmp/bashio
curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio
mv /tmp/bashio/lib /usr/lib/bashio
ln -s /usr/lib/bashio/bashio /usr/bin/bashio
rm -rf /tmp/bashio
fi
COMMAND="lastversion" # Bashio
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then if grep -q -rnw "$files/" -e 'bashio' && [ ! -f "/usr/bin/bashio" ]; then
log "install $COMMAND" [ "$VERBOSE" = true ] && echo "install bashio"
pip install $COMMAND BASHIO_VERSION="0.14.3"
fi mkdir -p /tmp/bashio
curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio
mv /tmp/bashio/lib /usr/lib/bashio
ln -s /usr/lib/bashio/bashio /usr/bin/bashio
rm -rf /tmp/bashio
fi
# Tempio # Lastversion
if grep -q -rnw "$files/" -e 'tempio' && [ ! -f "/usr/bin/tempio" ]; then COMMAND="lastversion"
[ "$VERBOSE" = true ] && echo "install tempio" if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
TEMPIO_VERSION="2021.09.0" [ "$VERBOSE" = true ] && echo "install $COMMAND"
BUILD_ARCH="$(bashio::info.arch)" pip install $COMMAND
curl -f -L -f -s -o /usr/bin/tempio "https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${BUILD_ARCH}" fi
chmod a+x /usr/bin/tempio
fi
COMMAND="mustache" # Tempio
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then if grep -q -rnw "$files/" -e 'tempio' && [ ! -f "/usr/bin/tempio" ]; then
log "$COMMAND required" [ "$VERBOSE" = true ] && echo "install tempio"
case "$PM" in TEMPIO_VERSION="2021.09.0"
apk) BUILD_ARCH="$(bashio::info.arch)"
apk add --no-cache go npm && curl -f -L -f -s -o /usr/bin/tempio "https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${BUILD_ARCH}"
chmod a+x /usr/bin/tempio
fi
# Mustache
COMMAND="mustache"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && apk add --no-cache go npm &&
apk upgrade --no-cache && apk upgrade --no-cache &&
apk add --no-cache --virtual .build-deps build-base git go && apk add --no-cache --virtual .build-deps build-base git go &&
go get -u github.com/quantumew/mustache-cli && go get -u github.com/quantumew/mustache-cli &&
cp "$GOPATH"/bin/* /usr/bin/ && cp "$GOPATH"/bin/* /usr/bin/ &&
rm -rf "$GOPATH" /var/cache/apk/* /tmp/src && rm -rf "$GOPATH" /var/cache/apk/* /tmp/src &&
apk del .build-deps xz build-base apk del .build-deps xz build-base
;; [ "$PACKMANAGER" = "apt" ] && apt-get update &&
apt)
apt-get update &&
apt-get install -yqq go npm node-mustache apt-get install -yqq go npm node-mustache
;; fi
esac
fi
done done
[[ -f /ERROR ]] && die "Some packages failed to install" if [ -f /ERROR ]; then
exit 1
fi