F7_recording/install.sh
F7cloud d6a1f6432a Improve install script according to modernization guidelines
- Добавлена функция safe_copy с проверками существования файлов
- Улучшены проверки успешности операций копирования
- Добавлены проверки после установки каждого компонента
- Улучшены сообщения об успешной установке с проверкой компонентов
- Добавлены проверки статуса сервиса после установки
- Улучшена обработка ошибок на всех этапах установки
2026-02-20 09:48:36 +00:00

726 lines
26 KiB
Bash
Executable File
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
# Скрипт установки F7cloud Talk Recording Server
# Этот скрипт устанавливает все необходимые зависимости и настраивает сервер
#
# Использование:
# sudo ./install.sh [OPTIONS]
#
# Опции:
# --hpb-url URL URL сервера HPB (signaling server)
# --hpb-secret SECRET Секрет для подключения к HPB (internalsecret)
# --f7cloud-url URL URL сервера F7cloud (опционально)
# --f7cloud-secret SECRET Секрет для подключения к F7cloud (опционально)
# --listen ADDRESS:PORT Адрес и порт для прослушивания (по умолчанию: 127.0.0.1:8000)
#
# Пример:
# sudo ./install.sh --hpb-url https://hpb.example.com --hpb-secret your-secret-here
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Функция для вывода сообщений
info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Функция для безопасного копирования с проверками
safe_copy() {
local source="$1"
local dest="$2"
if [ ! -e "$source" ]; then
error "Источник не существует: $source"
return 1
fi
# Создаем целевую директорию, если её нет
local target_dir=$(dirname "$dest")
if [ ! -d "$target_dir" ]; then
mkdir -p "$target_dir"
fi
cp -a "$source" "$dest"
# Проверяем успешность копирования
if [ ! -e "$dest" ]; then
error "Не удалось скопировать $source в $dest"
return 1
fi
return 0
}
# Функция для вывода справки
show_help() {
echo "Использование: $0 [OPTIONS]"
echo ""
echo "Опции:"
echo " --hpb-url URL URL сервера HPB (signaling server) - ОБЯЗАТЕЛЬНО"
echo " --hpb-secret SECRET Секрет для подключения к HPB (internalsecret) - ОБЯЗАТЕЛЬНО"
echo " --f7cloud-url URL URL сервера F7cloud (опционально)"
echo " --f7cloud-secret SECRET Секрет для подключения к F7cloud (опционально)"
echo " --listen ADDRESS:PORT Адрес и порт для прослушивания (по умолчанию: 127.0.0.1:8000)"
echo " --help Показать эту справку"
echo ""
echo "Пример:"
echo " sudo $0 --hpb-url https://hpb.example.com --hpb-secret your-secret-here"
}
# Парсинг аргументов
HPB_URL=""
HPB_SECRET=""
F7CLOUD_URL=""
F7CLOUD_SECRET=""
LISTEN_ADDRESS="127.0.0.1:8000"
while [[ $# -gt 0 ]]; do
case $1 in
--hpb-url)
HPB_URL="$2"
shift 2
;;
--hpb-secret)
HPB_SECRET="$2"
shift 2
;;
--f7cloud-url)
F7CLOUD_URL="$2"
shift 2
;;
--f7cloud-secret)
F7CLOUD_SECRET="$2"
shift 2
;;
--listen)
LISTEN_ADDRESS="$2"
shift 2
;;
--help)
show_help
exit 0
;;
*)
error "Неизвестный параметр: $1"
show_help
exit 1
;;
esac
done
# Проверка обязательных параметров или переменных окружения
if [ -z "$HPB_URL" ]; then
HPB_URL="${HPB_URL_ENV:-}"
fi
if [ -z "$HPB_SECRET" ]; then
HPB_SECRET="${HPB_SECRET_ENV:-}"
fi
if [ -z "$F7CLOUD_URL" ]; then
F7CLOUD_URL="${F7CLOUD_URL_ENV:-}"
fi
if [ -z "$F7CLOUD_SECRET" ]; then
F7CLOUD_SECRET="${F7CLOUD_SECRET_ENV:-}"
fi
if [ -z "$HPB_URL" ] || [ -z "$HPB_SECRET" ]; then
error "Ошибка: --hpb-url и --hpb-secret являются обязательными параметрами"
error "Или используйте переменные окружения: HPB_URL_ENV и HPB_SECRET_ENV"
echo ""
show_help
exit 1
fi
# Проверка прав root
if [ "$EUID" -ne 0 ]; then
error "Пожалуйста, запустите скрипт с правами root (sudo)"
exit 1
fi
info "Начинаем установку F7cloud Talk Recording Server..."
# Определение дистрибутива
if [ -f /etc/debian_version ]; then
DISTRO="debian"
PKG_MANAGER="apt-get"
elif [ -f /etc/redhat-release ]; then
DISTRO="redhat"
PKG_MANAGER="yum"
else
error "Неподдерживаемый дистрибутив Linux"
exit 1
fi
# Получение директории скрипта
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
# 1. Установка системных зависимостей
info "Установка системных зависимостей..."
if [ "$DISTRO" = "debian" ]; then
$PKG_MANAGER update -y
$PKG_MANAGER install -y \
python3 \
python3-pip \
python3-venv \
pulseaudio \
xvfb \
ffmpeg \
libpulse0 \
libpulse-dev \
libx11-dev \
libxext-dev \
libxrender-dev \
libxtst6 \
libxi6 \
libgconf-2-4 \
libasound2-dev \
curl \
wget \
git \
bzip2 \
tar
else
error "Установка для RedHat-based дистрибутивов пока не поддерживается автоматически"
exit 1
fi
# 2. Установка Firefox ESR
info "Установка Firefox ESR..."
if [ -d "dependencies/firefox-esr" ] && [ -f "dependencies/firefox-esr/firefox" ]; then
info "Использование Firefox ESR из dependencies..."
# Проверяем существование директории перед копированием
if [ ! -d "dependencies/firefox-esr" ]; then
error "Директория dependencies/firefox-esr не найдена"
exit 1
fi
if [ ! -f "dependencies/firefox-esr/firefox" ]; then
error "Исполняемый файл Firefox не найден в dependencies/firefox-esr/firefox"
exit 1
fi
# Копируем с проверкой
if ! safe_copy "dependencies/firefox-esr" "/opt/firefox-esr"; then
error "Не удалось скопировать Firefox ESR"
exit 1
fi
ln -sf /opt/firefox-esr/firefox /usr/local/bin/firefox-esr
chmod +x /usr/local/bin/firefox-esr
# Проверяем успешность установки
if [ ! -f "/usr/local/bin/firefox-esr" ] || [ ! -L "/usr/local/bin/firefox-esr" ]; then
error "Не удалось создать символьную ссылку на Firefox ESR"
exit 1
fi
info "Firefox ESR установлен в /opt/firefox-esr"
else
warn "Firefox ESR не найден в dependencies/, пытаемся скачать..."
# Определяем архитектуру
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
FIREFOX_ARCH="linux64"
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
FIREFOX_ARCH="linux-aarch64"
else
error "Неподдерживаемая архитектура: $ARCH"
exit 1
fi
info "Скачивание Firefox ESR для $FIREFOX_ARCH..."
mkdir -p dependencies
cd dependencies
# Скачиваем последнюю версию Firefox ESR
FIREFOX_URL="https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=${FIREFOX_ARCH}&lang=en-US"
if command -v wget &> /dev/null; then
wget -q --show-progress -O firefox-esr.tar.bz2 "$FIREFOX_URL"
elif command -v curl &> /dev/null; then
curl -L -o firefox-esr.tar.bz2 "$FIREFOX_URL"
else
error "Не найден wget или curl для скачивания Firefox ESR"
exit 1
fi
if [ -f firefox-esr.tar.bz2 ]; then
info "Распаковка Firefox ESR..."
if ! tar -xjf firefox-esr.tar.bz2; then
error "Не удалось распаковать Firefox ESR"
exit 1
fi
if [ ! -d firefox ]; then
error "Директория firefox не найдена после распаковки"
exit 1
fi
mv firefox firefox-esr
rm firefox-esr.tar.bz2
if [ ! -f firefox-esr/firefox ]; then
error "Исполняемый файл Firefox не найден после распаковки"
exit 1
fi
if ! safe_copy "firefox-esr" "/opt/firefox-esr"; then
error "Не удалось скопировать Firefox ESR в /opt"
exit 1
fi
ln -sf /opt/firefox-esr/firefox /usr/local/bin/firefox-esr
chmod +x /usr/local/bin/firefox-esr
# Проверяем успешность установки
if [ ! -f "/usr/local/bin/firefox-esr" ] || [ ! -L "/usr/local/bin/firefox-esr" ]; then
error "Не удалось создать символьную ссылку на Firefox ESR"
exit 1
fi
info "Firefox ESR установлен в /opt/firefox-esr"
else
error "Не удалось скачать Firefox ESR"
exit 1
fi
cd ..
fi
# 3. Установка Geckodriver
info "Установка Geckodriver..."
if [ -f "dependencies/geckodriver" ]; then
if [ ! -f "dependencies/geckodriver" ]; then
error "Файл dependencies/geckodriver не найден"
exit 1
fi
if ! safe_copy "dependencies/geckodriver" "/usr/local/bin/geckodriver"; then
error "Не удалось скопировать Geckodriver"
exit 1
fi
chmod +x /usr/local/bin/geckodriver
# Проверяем успешность установки
if [ ! -f "/usr/local/bin/geckodriver" ]; then
error "Geckodriver не найден после установки"
exit 1
fi
info "Geckodriver установлен в /usr/local/bin/geckodriver"
elif [ -f "dependencies/geckodriver.tar.gz" ]; then
info "Распаковка geckodriver из архива..."
cd dependencies
if ! tar -xzf geckodriver.tar.gz; then
error "Не удалось распаковать Geckodriver"
exit 1
fi
if [ ! -f geckodriver ]; then
error "Файл geckodriver не найден после распаковки"
exit 1
fi
chmod +x geckodriver
if ! safe_copy "geckodriver" "/usr/local/bin/geckodriver"; then
error "Не удалось скопировать Geckodriver"
exit 1
fi
cd ..
# Проверяем успешность установки
if [ ! -f "/usr/local/bin/geckodriver" ]; then
error "Geckodriver не найден после установки"
exit 1
fi
info "Geckodriver установлен в /usr/local/bin/geckodriver"
else
warn "Geckodriver не найден в dependencies/, пытаемся скачать..."
# Определяем архитектуру
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
GECKODRIVER_ARCH="linux64"
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
GECKODRIVER_ARCH="linux-aarch64"
else
error "Неподдерживаемая архитектура: $ARCH"
exit 1
fi
info "Скачивание Geckodriver для $GECKODRIVER_ARCH..."
mkdir -p dependencies
cd dependencies
# Получаем последнюю версию geckodriver из GitHub releases
GECKODRIVER_VERSION=$(curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/v//')
if [ -z "$GECKODRIVER_VERSION" ]; then
# Fallback на известную версию
GECKODRIVER_VERSION="0.34.0"
warn "Не удалось определить версию, используем $GECKODRIVER_VERSION"
fi
GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-${GECKODRIVER_ARCH}.tar.gz"
if command -v wget &> /dev/null; then
wget -q --show-progress -O geckodriver.tar.gz "$GECKODRIVER_URL"
elif command -v curl &> /dev/null; then
curl -L -o geckodriver.tar.gz "$GECKODRIVER_URL"
else
error "Не найден wget или curl для скачивания Geckodriver"
exit 1
fi
if [ -f geckodriver.tar.gz ]; then
info "Распаковка Geckodriver..."
if ! tar -xzf geckodriver.tar.gz; then
error "Не удалось распаковать Geckodriver"
exit 1
fi
if [ ! -f geckodriver ]; then
error "Файл geckodriver не найден после распаковки"
exit 1
fi
chmod +x geckodriver
if ! safe_copy "geckodriver" "/usr/local/bin/geckodriver"; then
error "Не удалось скопировать Geckodriver в /usr/local/bin"
exit 1
fi
rm geckodriver.tar.gz
# Проверяем успешность установки
if [ ! -f "/usr/local/bin/geckodriver" ]; then
error "Geckodriver не найден после установки"
exit 1
fi
info "Geckodriver установлен в /usr/local/bin/geckodriver"
else
error "Не удалось скачать Geckodriver"
exit 1
fi
cd ..
fi
# 4. Создание виртуального окружения Python
info "Создание виртуального окружения Python..."
if [ ! -d "venv" ]; then
if ! python3 -m venv venv; then
error "Не удалось создать виртуальное окружение Python"
exit 1
fi
# Проверяем успешность создания
if [ ! -d "venv" ] || [ ! -f "venv/bin/activate" ]; then
error "Виртуальное окружение создано некорректно"
exit 1
fi
info "Виртуальное окружение создано"
else
warn "Виртуальное окружение уже существует, пропускаем создание..."
# Проверяем, что существующее окружение валидно
if [ ! -f "venv/bin/activate" ]; then
error "Существующее виртуальное окружение повреждено"
exit 1
fi
fi
# Активация виртуального окружения и установка зависимостей
info "Установка Python-зависимостей..."
source venv/bin/activate
if ! pip install --upgrade pip; then
error "Не удалось обновить pip"
exit 1
fi
if ! pip install -e .; then
error "Не удалось установить Python-зависимости"
exit 1
fi
# Проверяем успешность установки
if ! python3 -c "import f7cloud.talk.recording" 2>/dev/null; then
error "Модуль f7cloud.talk.recording не найден после установки"
exit 1
fi
info "Python-зависимости установлены"
# 5. Создание пользователя для запуска сервера
info "Создание пользователя f7cloud-talk-recording..."
if ! id "f7cloud-talk-recording" &>/dev/null; then
if ! useradd -r -s /bin/false -d /var/lib/f7cloud-talk-recording f7cloud-talk-recording; then
error "Не удалось создать пользователя f7cloud-talk-recording"
exit 1
fi
# Проверяем успешность создания
if ! id "f7cloud-talk-recording" &>/dev/null; then
error "Пользователь f7cloud-talk-recording не найден после создания"
exit 1
fi
info "Пользователь f7cloud-talk-recording создан"
else
warn "Пользователь f7cloud-talk-recording уже существует"
fi
# Создание директорий для пользователя
if ! mkdir -p /var/lib/f7cloud-talk-recording; then
error "Не удалось создать директорию /var/lib/f7cloud-talk-recording"
exit 1
fi
if ! chown f7cloud-talk-recording:f7cloud-talk-recording /var/lib/f7cloud-talk-recording; then
error "Не удалось установить права на /var/lib/f7cloud-talk-recording"
exit 1
fi
# Проверяем успешность создания директории
if [ ! -d "/var/lib/f7cloud-talk-recording" ]; then
error "Директория /var/lib/f7cloud-talk-recording не найдена после создания"
exit 1
fi
# 6. Настройка конфигурации
info "Настройка конфигурации..."
mkdir -p /etc/f7cloud-talk-recording
CONFIG_FILE="/etc/f7cloud-talk-recording/server.conf"
if [ ! -f "$CONFIG_FILE" ]; then
if [ ! -f "server.conf.in" ]; then
error "Шаблон конфигурации server.conf.in не найден"
exit 1
fi
if ! safe_copy "server.conf.in" "$CONFIG_FILE"; then
error "Не удалось создать конфигурационный файл"
exit 1
fi
# Проверяем успешность создания
if [ ! -f "$CONFIG_FILE" ]; then
error "Конфигурационный файл не найден после создания"
exit 1
fi
info "Конфигурационный файл создан в $CONFIG_FILE"
# Настройка параметров конфигурации
info "Настройка параметров конфигурации..."
# Установка адреса прослушивания
sed -i "s|#listen = 127.0.0.1:8000|listen = $LISTEN_ADDRESS|" "$CONFIG_FILE"
# Настройка HPB (signaling server)
if [ -n "$HPB_URL" ] && [ -n "$HPB_SECRET" ]; then
info "Настройка HPB (signaling server)..."
# Создаем ID для signaling сервера из URL
HPB_ID=$(echo "$HPB_URL" | sed 's|https\?://||' | sed 's|/.*||' | sed 's|[^a-zA-Z0-9]|-|g' | sed 's|--*|-|g' | sed 's|^-\||' | sed 's|-$||')
if [ -z "$HPB_ID" ]; then
HPB_ID="hpb-signaling"
fi
# Раскомментируем и настраиваем секцию signaling
sed -i "s|#signalings = signaling-id, another-signaling|signalings = $HPB_ID|" "$CONFIG_FILE"
sed -i "s|#internalsecret = the-shared-secret-for-internal-clients|internalsecret = $HPB_SECRET|" "$CONFIG_FILE"
# Добавляем секцию для конкретного signaling сервера
if ! grep -q "^\[$HPB_ID\]" "$CONFIG_FILE"; then
# Добавляем новую секцию после секции [signaling]
cat >> "$CONFIG_FILE" << EOF
[$HPB_ID]
# URL of the signaling server
url = $HPB_URL
# Shared secret for authenticating as an internal client of signaling servers.
# This must be the same value as configured in the signaling server
# configuration file.
internalsecret = $HPB_SECRET
EOF
else
# Если секция уже существует, обновляем значения
sed -i "/^\[$HPB_ID\]/,/^\[/ {
s|^#url = .*|url = $HPB_URL|
s|^url = .*|url = $HPB_URL|
s|^#internalsecret = .*|internalsecret = $HPB_SECRET|
s|^internalsecret = .*|internalsecret = $HPB_SECRET|
}" "$CONFIG_FILE"
fi
info "HPB настроен: URL=$HPB_URL, ID=$HPB_ID"
fi
# Настройка F7cloud backend (опционально)
if [ -n "$F7CLOUD_URL" ] && [ -n "$F7CLOUD_SECRET" ]; then
info "Настройка F7cloud backend..."
# Создаем ID для backend из URL
BACKEND_ID=$(echo "$F7CLOUD_URL" | sed 's|https\?://||' | sed 's|/.*||' | sed 's|[^a-zA-Z0-9]|-|g' | sed 's|--*|-|g' | sed 's|^-\||' | sed 's|-$||')
if [ -z "$BACKEND_ID" ]; then
BACKEND_ID="f7cloud-backend"
fi
# Раскомментируем и настраиваем секцию backend
sed -i "s|#backends = backend-id, another-backend|backends = $BACKEND_ID|" "$CONFIG_FILE"
# Добавляем секцию для конкретного backend
if ! grep -q "^\[$BACKEND_ID\]" "$CONFIG_FILE"; then
# Добавляем новую секцию после секции [backend]
cat >> "$CONFIG_FILE" << EOF
[$BACKEND_ID]
# URL of the F7cloud instance
url = $F7CLOUD_URL
# Shared secret for requests from and to the backend servers. This must be the
# same value as configured in the F7cloud admin ui.
secret = $F7CLOUD_SECRET
EOF
else
# Если секция уже существует, обновляем значения
sed -i "/^\[$BACKEND_ID\]/,/^\[/ {
s|^#url = .*|url = $F7CLOUD_URL|
s|^url = .*|url = $F7CLOUD_URL|
s|^#secret = .*|secret = $F7CLOUD_SECRET|
s|^secret = .*|secret = $F7CLOUD_SECRET|
}" "$CONFIG_FILE"
fi
info "F7cloud backend настроен: URL=$F7CLOUD_URL, ID=$BACKEND_ID"
fi
# Настройка путей к браузеру и драйверу
sed -i "s|#driverPath =|driverPath = /usr/local/bin/geckodriver|" "$CONFIG_FILE"
sed -i "s|#browserPath =|browserPath = /usr/local/bin/firefox-esr|" "$CONFIG_FILE"
chown f7cloud-talk-recording:f7cloud-talk-recording "$CONFIG_FILE"
chmod 600 "$CONFIG_FILE"
info "Конфигурация настроена автоматически"
else
warn "Конфигурационный файл уже существует, пропускаем создание..."
warn "Если нужно обновить конфигурацию, отредактируйте $CONFIG_FILE вручную"
fi
# 7. Создание systemd service файла
info "Создание systemd service..."
cat > /etc/systemd/system/f7cloud-talk-recording.service << EOF
[Unit]
Description=F7cloud Talk Recording Server
After=network.target
[Service]
Type=simple
User=f7cloud-talk-recording
Group=f7cloud-talk-recording
WorkingDirectory=$SCRIPT_DIR
Environment="PATH=$SCRIPT_DIR/venv/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=$SCRIPT_DIR/venv/bin/f7cloud-talk-recording --config /etc/f7cloud-talk-recording/server.conf
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
info "Systemd service создан"
# Итоговая информация
info ""
info "=========================================="
info "Установка завершена успешно!"
info "=========================================="
info ""
# Проверяем установленные компоненты
info "Установленные компоненты:"
[ -f "/usr/local/bin/firefox-esr" ] && info " ✓ Firefox ESR"
[ -f "/usr/local/bin/geckodriver" ] && info " ✓ Geckodriver"
[ -d "venv" ] && [ -f "venv/bin/activate" ] && info " ✓ Виртуальное окружение Python"
[ -d "/var/lib/f7cloud-talk-recording" ] && info " ✓ Директория пользователя"
[ -f "$CONFIG_FILE" ] && info " ✓ Конфигурационный файл"
[ -f "/etc/systemd/system/f7cloud-talk-recording.service" ] && info " ✓ Systemd service"
info ""
info "Настроенные параметры:"
info " HPB URL: $HPB_URL"
info " Listen: $LISTEN_ADDRESS"
if [ -n "$F7CLOUD_URL" ]; then
info " F7cloud URL: $F7CLOUD_URL"
fi
info ""
# Проверяем статус сервиса
if systemctl list-unit-files | grep -q "f7cloud-talk-recording.service"; then
if systemctl is-enabled --quiet f7cloud-talk-recording 2>/dev/null; then
info "✓ Сервис f7cloud-talk-recording включен для автозапуска"
else
warn "⚠ Сервис f7cloud-talk-recording не включен для автозапуска"
fi
if systemctl is-active --quiet f7cloud-talk-recording 2>/dev/null; then
info "✓ Сервис f7cloud-talk-recording запущен"
else
warn "⚠ Сервис f7cloud-talk-recording не запущен"
fi
fi
info ""
info "Следующие шаги:"
if [ -z "$F7CLOUD_URL" ] || [ -z "$F7CLOUD_SECRET" ]; then
info "1. Настройте F7cloud backend в конфигурации: $CONFIG_FILE"
info " Добавьте секцию [backend-id] с url и secret"
fi
info "2. Проверьте конфигурацию: $CONFIG_FILE"
info "3. Запустите сервис:"
info " sudo systemctl start f7cloud-talk-recording"
info "4. Включите автозапуск:"
info " sudo systemctl enable f7cloud-talk-recording"
info "5. Проверьте статус:"
info " sudo systemctl status f7cloud-talk-recording"
info ""
info "Для получения дополнительной информации см. INSTALL.md"
info ""