v2.4.6: universal apt_lock_wait helper (fix nginx install on fresh VPS)

- lib/common.sh: add apt_lock_wait + apt_install + apt_update helpers
  * waits up to 300s for dpkg lock held by unattended-upgrades
  * uses DPkg::Lock::Timeout=120 native flag
  * captures stderr to show real error if install fails
- lib/website.sh: install_nginx/install_certbot use apt_install
  (fixes "Could not get lock /var/lib/dpkg/lock-frontend" during Pro setup)
- install.sh: bot_install uses apt_install (removes duplicated lock logic)
- lib/common.sh: ensure_deps uses apt_update + apt_install
This commit is contained in:
anten-ka
2026-04-10 20:01:20 +03:00
parent 3403975636
commit eb5175ccab
4 changed files with 77 additions and 49 deletions

66
lib/common.sh Normal file → Executable file
View File

@@ -3,7 +3,7 @@
# Colors, logging, spinner, system helpers, v1 compat, i18n-aware
# ── Version ───────────────────────────────────────────────────────────────────
GOTELEGRAM_VERSION="2.4.5"
GOTELEGRAM_VERSION="2.4.6"
GOTELEGRAM_NAME="GoTelegram"
# ── Пути ──────────────────────────────────────────────────────────────────────
@@ -240,13 +240,68 @@ get_pkg_manager() {
install_pkg() {
local pkg="$1"
case "$(get_pkg_manager)" in
apt) apt-get install -y -qq "$pkg" ;;
apt) apt_install "$pkg" ;;
dnf) dnf install -y -q "$pkg" ;;
yum) yum install -y -q "$pkg" ;;
*) log_error "$(_t_or err_bad_pkg_mgr 'Unknown package manager')"; return 1 ;;
esac
}
# ── apt lock wait + install ─────────────────────────────────────────────────
# На свежих Ubuntu/Debian unattended-upgrades часто держит dpkg lock на старте
# → любой apt-get install падает с "Could not get lock /var/lib/dpkg/lock-frontend".
# Эти функции ждут освобождения лока до 300с, потом запускают apt с нативным
# таймаутом DPkg::Lock::Timeout. Использовать везде, где раньше был
# "apt-get install ...".
apt_lock_wait() {
local max_wait="${1:-300}"
local waited=0
local warned=0
while fuser /var/lib/dpkg/lock-frontend &>/dev/null \
|| fuser /var/lib/dpkg/lock &>/dev/null \
|| fuser /var/lib/apt/lists/lock &>/dev/null \
|| pgrep -f '^/usr/bin/unattended-upgrade' &>/dev/null; do
if [ "$warned" = "0" ]; then
log_warning "apt/dpkg locked by unattended-upgrades, waiting up to ${max_wait}s..."
warned=1
fi
sleep 3
waited=$((waited + 3))
if [ "$waited" -ge "$max_wait" ]; then
log_error "apt lock not released after ${max_wait}s"
log_dim "Manual fix: systemctl stop unattended-upgrades && killall -9 unattended-upgr 2>/dev/null; dpkg --configure -a"
return 1
fi
done
[ "$warned" = "1" ] && log_success "apt lock released (waited ${waited}s)"
return 0
}
# apt_install <pkg> [pkg2 ...] — ждёт lock + ставит пакеты + показывает ошибку
apt_install() {
[ $# -eq 0 ] && return 0
apt_lock_wait || return 1
export DEBIAN_FRONTEND=noninteractive
local opts="-o DPkg::Lock::Timeout=120"
local err_file; err_file=$(mktemp 2>/dev/null || echo /tmp/apt_err.$$)
if ! apt-get $opts install -y -qq "$@" 2>"$err_file"; then
log_error "apt-get install failed: $*"
[ -s "$err_file" ] && tail -n 5 "$err_file" | sed 's/^/ /' >&2
rm -f "$err_file"
return 1
fi
rm -f "$err_file"
return 0
}
# apt_update — тихий update с ожиданием лока
apt_update() {
apt_lock_wait || return 1
export DEBIAN_FRONTEND=noninteractive
apt-get -o DPkg::Lock::Timeout=120 update -qq 2>/dev/null || true
return 0
}
# ── Зависимости GoTelegram ──────────────────────────────────────────────────
# Полный список внешних команд, которые скрипт использует. Для каждой команды
# указан пакет на apt и dnf/yum (имена различаются: например dig = dnsutils на
@@ -344,9 +399,8 @@ ensure_deps() {
case "$pkg_mgr" in
apt)
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq 2>/dev/null
apt-get install -y -qq "${uniq_pkgs[@]}" 2>/dev/null
apt_update
apt_install "${uniq_pkgs[@]}" || true
;;
dnf) dnf install -y -q "${uniq_pkgs[@]}" 2>/dev/null ;;
yum) yum install -y -q "${uniq_pkgs[@]}" 2>/dev/null ;;
@@ -358,7 +412,7 @@ ensure_deps() {
# Фолбэки для xxd: на некоторых системах нужен vim-common вместо xxd
if ! command -v xxd &>/dev/null && [ "$pkg_mgr" = "apt" ]; then
apt-get install -y -qq vim-common 2>/dev/null
apt_install vim-common || true
fi
# Повторная проверка критических команд

View File

@@ -9,9 +9,9 @@ install_nginx() {
fi
log_info "Установка nginx..."
case "$(get_pkg_manager)" in
apt) apt-get update -qq && apt-get install -y -qq nginx ;;
dnf) dnf install -y -q nginx ;;
yum) yum install -y -q nginx ;;
apt) apt_update && apt_install nginx || return 1 ;;
dnf) dnf install -y -q nginx || return 1 ;;
yum) yum install -y -q nginx || return 1 ;;
esac
systemctl enable nginx 2>/dev/null
}
@@ -24,9 +24,9 @@ install_certbot() {
fi
log_info "Установка certbot..."
case "$(get_pkg_manager)" in
apt) apt-get install -y -qq certbot python3-certbot-nginx ;;
dnf) dnf install -y -q certbot python3-certbot-nginx ;;
yum) yum install -y -q certbot python3-certbot-nginx ;;
apt) apt_install certbot python3-certbot-nginx || return 1 ;;
dnf) dnf install -y -q certbot python3-certbot-nginx || return 1 ;;
yum) yum install -y -q certbot python3-certbot-nginx || return 1 ;;
esac
}