Files
gotelegram_pro/lib/telemt.sh

328 lines
11 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# GoTelegram v2.2 — Управление telemt binary
# Скачивание, обновление, запуск, остановка через systemd
TELEMT_GITHUB="telemt/telemt"
TELEMT_RELEASE_API="https://api.github.com/repos/${TELEMT_GITHUB}/releases/latest"
TELEMT_USER="telemt"
TELEMT_GROUP="telemt"
# ── Получение последней версии ───────────────────────────────────────────────
get_latest_telemt_version() {
local resp
resp=$(curl -s --max-time 10 "$TELEMT_RELEASE_API" 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$resp" ]; then
log_error "Не удалось получить информацию о релизах telemt"
return 1
fi
echo "$resp" | jq -r '.tag_name // empty'
}
get_telemt_download_url() {
local arch
arch=$(get_arch)
local resp
resp=$(curl -s --max-time 10 "$TELEMT_RELEASE_API" 2>/dev/null)
if [ -z "$resp" ]; then return 1; fi
# URL format: telemt-x86_64-linux-gnu.tar.gz (arch BEFORE linux)
local arch_pattern
case "$arch" in
amd64) arch_pattern="(amd64|x86_64)" ;;
arm64) arch_pattern="(arm64|aarch64)" ;;
armv7) arch_pattern="(armv7|arm)" ;;
*) arch_pattern="${arch}" ;;
esac
echo "$resp" | jq -r ".assets[].browser_download_url" 2>/dev/null \
| grep -iE "$arch_pattern" \
| grep -i "linux" \
| grep -v "sha256" \
| grep "gnu" \
| head -1
}
# ── Установленная версия ─────────────────────────────────────────────────────
get_installed_telemt_version() {
if [ -x "$TELEMT_BIN" ]; then
"$TELEMT_BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
else
echo ""
fi
}
is_telemt_installed() {
[ -x "$TELEMT_BIN" ]
}
# ── Скачивание и установка ───────────────────────────────────────────────────
download_telemt() {
local url
url=$(get_telemt_download_url)
if [ -z "$url" ]; then
log_error "Не найден бинарник telemt для архитектуры $(get_arch)"
return 1
fi
local tmp_file="/tmp/telemt_download_$$"
local extract_dir="/tmp/telemt_extract_$$"
log_info "Скачивание: $url"
if ! curl -L -s --max-time 120 -o "$tmp_file" "$url"; then
log_error "Ошибка скачивания telemt"
rm -f "$tmp_file"
return 1
fi
# Проверяем что файл не пустой и не HTML
local file_size
file_size=$(stat -c%s "$tmp_file" 2>/dev/null || echo 0)
if [ "$file_size" -lt 1000 ]; then
log_error "Скачанный файл слишком маленький ($file_size байт) — возможна ошибка сети"
rm -f "$tmp_file"
return 1
fi
# Определяем тип файла и распаковываем
local mime extracted=""
mime=$(file -b --mime-type "$tmp_file" 2>/dev/null)
rm -rf "$extract_dir"
mkdir -p "$extract_dir"
case "$mime" in
application/gzip|application/x-gzip)
tar xzf "$tmp_file" -C "$extract_dir" 2>/dev/null
extracted=$(find "$extract_dir" -name "telemt" -type f 2>/dev/null | head -1)
if [ -z "$extracted" ]; then
# Может быть просто gzip без tar
gunzip -c "$tmp_file" > "$extract_dir/telemt_bin" 2>/dev/null
extracted="$extract_dir/telemt_bin"
fi
;;
application/x-tar)
tar xf "$tmp_file" -C "$extract_dir" 2>/dev/null
extracted=$(find "$extract_dir" -name "telemt" -type f 2>/dev/null | head -1)
;;
application/zip)
unzip -o "$tmp_file" -d "$extract_dir" 2>/dev/null
extracted=$(find "$extract_dir" -name "telemt" -type f 2>/dev/null | head -1)
;;
application/octet-stream|application/x-executable)
extracted="$tmp_file"
;;
*)
# Пробуем определить по содержимому
if file "$tmp_file" 2>/dev/null | grep -q "ELF"; then
extracted="$tmp_file"
else
# Пробуем как tar.gz
tar xzf "$tmp_file" -C "$extract_dir" 2>/dev/null
extracted=$(find "$extract_dir" -name "telemt" -type f 2>/dev/null | head -1)
fi
;;
esac
if [ -z "$extracted" ] || [ ! -f "$extracted" ]; then
log_error "Не удалось извлечь бинарник telemt (mime: $mime)"
rm -f "$tmp_file"
rm -rf "$extract_dir"
return 1
fi
# Устанавливаем
cp "$extracted" "$TELEMT_BIN"
chmod 755 "$TELEMT_BIN"
rm -f "$tmp_file"
rm -rf "$extract_dir"
# Проверяем
if "$TELEMT_BIN" --version &>/dev/null; then
log_success "telemt $(get_installed_telemt_version) установлен в $TELEMT_BIN"
return 0
else
log_error "Бинарник telemt не запускается ($(file -b "$TELEMT_BIN" 2>/dev/null))"
return 1
fi
}
# ── Системный пользователь ───────────────────────────────────────────────────
create_telemt_user() {
if ! id "$TELEMT_USER" &>/dev/null; then
useradd -r -s /usr/sbin/nologin -d /etc/telemt "$TELEMT_USER" 2>/dev/null
log_dim "Создан системный пользователь: $TELEMT_USER"
fi
}
# ── Systemd сервис ───────────────────────────────────────────────────────────
install_telemt_service() {
local config_path="${1:-$TELEMT_CONFIG}"
cat > "/etc/systemd/system/${TELEMT_SERVICE}.service" << EOF
[Unit]
Description=GoTelegram MTProxy (telemt engine)
Documentation=https://github.com/telemt/telemt
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=$TELEMT_BIN run $config_path
Restart=always
RestartSec=5
LimitNOFILE=65535
# Безопасность
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
log_success "Systemd сервис $TELEMT_SERVICE создан"
}
# ── Управление сервисом ──────────────────────────────────────────────────────
start_telemt() {
systemctl start "$TELEMT_SERVICE" 2>/dev/null
sleep 2
if systemctl is-active --quiet "$TELEMT_SERVICE"; then
log_success "telemt запущен"
return 0
else
log_error "telemt не запустился"
journalctl -u "$TELEMT_SERVICE" --no-pager -n 10 2>/dev/null
return 1
fi
}
stop_telemt() {
if systemctl is-active --quiet "$TELEMT_SERVICE" 2>/dev/null; then
systemctl stop "$TELEMT_SERVICE"
log_success "telemt остановлен"
else
log_dim "telemt уже остановлен"
fi
}
restart_telemt() {
systemctl restart "$TELEMT_SERVICE" 2>/dev/null
sleep 2
if systemctl is-active --quiet "$TELEMT_SERVICE"; then
log_success "telemt перезапущен"
return 0
else
log_error "telemt не перезапустился"
return 1
fi
}
enable_telemt() {
systemctl enable "$TELEMT_SERVICE" 2>/dev/null
}
telemt_status() {
if ! is_telemt_installed; then
echo "not_installed"
return
fi
if systemctl is-active --quiet "$TELEMT_SERVICE" 2>/dev/null; then
echo "running"
elif systemctl is-enabled --quiet "$TELEMT_SERVICE" 2>/dev/null; then
echo "stopped"
else
echo "disabled"
fi
}
telemt_logs() {
local lines="${1:-40}"
journalctl -u "$TELEMT_SERVICE" --no-pager -n "$lines" 2>/dev/null
}
telemt_uptime() {
local started
started=$(systemctl show "$TELEMT_SERVICE" --property=ActiveEnterTimestamp --value 2>/dev/null)
if [ -n "$started" ] && [ "$started" != "" ]; then
echo "$started"
else
echo "N/A"
fi
}
# ── Обновление ───────────────────────────────────────────────────────────────
check_telemt_update() {
local current latest
current=$(get_installed_telemt_version)
latest=$(get_latest_telemt_version)
if [ -z "$current" ] || [ -z "$latest" ]; then
return 1
fi
if [ "$current" != "$latest" ]; then
echo "$latest"
return 0 # есть обновление
fi
return 1 # актуально
}
update_telemt() {
local latest
latest=$(check_telemt_update)
if [ $? -ne 0 ]; then
log_info "telemt уже последней версии ($(get_installed_telemt_version))"
return 0
fi
log_info "Доступно обновление: $(get_installed_telemt_version)$latest"
if ! confirm "Обновить telemt?"; then
return 0
fi
stop_telemt
if download_telemt; then
start_telemt
log_success "telemt обновлён до $latest"
else
start_telemt # запускаем старую версию обратно
log_error "Обновление не удалось"
return 1
fi
}
# ── Полная установка telemt ──────────────────────────────────────────────────
install_telemt_full() {
log_step "Установка telemt"
# Создаём директории
mkdir -p /etc/telemt
# Скачиваем бинарник
run_with_spinner "Скачивание telemt" download_telemt || return 1
# Устанавливаем systemd сервис
install_telemt_service
# Включаем автозапуск
enable_telemt
log_success "telemt готов к работе"
return 0
}
# ── Удаление telemt ──────────────────────────────────────────────────────────
remove_telemt() {
stop_telemt
systemctl disable "$TELEMT_SERVICE" 2>/dev/null
rm -f "/etc/systemd/system/${TELEMT_SERVICE}.service"
systemctl daemon-reload
rm -f "$TELEMT_BIN"
rm -rf /etc/telemt
log_success "telemt полностью удалён"
}