#!/bin/bash # Развёртывание F7cloud Talk Recording на целевой машине (Debian/Ubuntu). # Запуск: sudo ./install # Секреты и адреса задайте через переменные окружения перед запуском: # F7CLOUD_NEXTCLOUD_URL — URL сервера Nextcloud (например https://forbion.f7cloud.ru) # F7CLOUD_SECRET — общий секрет (backend + nextcloud) # F7CLOUD_TALK_URL — URL signaling (HPB), например https://hpb-prod.f7cloud.ru/standalone-signaling # F7CLOUD_TALK_INTERNALSECRET — internalsecret для доступа к signaling # Пример: export F7CLOUD_NEXTCLOUD_URL=... F7CLOUD_SECRET=... F7CLOUD_TALK_URL=... F7CLOUD_TALK_INTERNALSECRET=... ; sudo -E ./install set -e if [ "$(id -u)" -ne 0 ]; then echo "Запустите скрипт с правами root: sudo $0" exit 1 fi REPO_ROOT="$(cd "$(dirname "$0")" && pwd)" echo "=== 1. Зависимости (только Python 3.12, xvfb, ffmpeg — остальное в репо) ===" NEED_PYTHON=0 NEED_XVFB=0 NEED_FFMPEG=0 if ! command -v python3.12 >/dev/null 2>&1; then NEED_PYTHON=1 fi if ! command -v Xvfb >/dev/null 2>&1 && ! command -v xvfb-run >/dev/null 2>&1; then NEED_XVFB=1 fi if ! command -v ffmpeg >/dev/null 2>&1; then NEED_FFMPEG=1 fi # Пытаемся доустановить Python 3.12, xvfb и ffmpeg из vendor/debs, если они отсутствуют if [ "$NEED_PYTHON" -eq 1 ]; then PY_DEB="$(ls "$REPO_ROOT"/vendor/debs/python3.12_[0-9]*.deb 2>/dev/null | head -n1 || true)" PY_VENV_DEB="$(ls "$REPO_ROOT"/vendor/debs/python3.12-venv_[0-9]*.deb 2>/dev/null | head -n1 || true)" if [ -n "$PY_DEB" ]; then echo "python3.12 не найден в системе. Устанавливаю из $PY_DEB ..." if dpkg -i "$PY_DEB"; then echo "python3.12 успешно установлен из vendor/debs." else echo "Не удалось установить python3.12 из $PY_DEB. Проверьте зависимости пакета." >&2 fi fi if [ -n "$PY_VENV_DEB" ]; then echo "python3.12-venv не найден в системе. Устанавливаю из $PY_VENV_DEB ..." if dpkg -i "$PY_VENV_DEB"; then echo "python3.12-venv успешно установлен из vendor/debs." else echo "Не удалось установить python3.12-venv из $PY_VENV_DEB. Проверьте зависимости пакета." >&2 fi fi if command -v python3.12 >/dev/null 2>&1; then NEED_PYTHON=0 fi fi if [ "$NEED_XVFB" -eq 1 ]; then XVFB_DEB="$(ls "$REPO_ROOT"/vendor/debs/xvfb_*.deb 2>/dev/null | head -n1 || true)" if [ -n "$XVFB_DEB" ]; then echo "Xvfb не найден в системе. Устанавливаю из $XVFB_DEB ..." if dpkg -i "$XVFB_DEB"; then echo "Xvfb успешно установлен из vendor/debs." NEED_XVFB=0 else echo "Не удалось установить Xvfb из $XVFB_DEB. Проверьте зависимости пакета." >&2 fi fi fi if [ "$NEED_FFMPEG" -eq 1 ]; then FFMPEG_DEB="$(ls "$REPO_ROOT"/vendor/debs/ffmpeg_*.deb 2>/dev/null | head -n1 || true)" if [ -n "$FFMPEG_DEB" ]; then echo "ffmpeg не найден в системе. Устанавливаю из $FFMPEG_DEB ..." if dpkg -i "$FFMPEG_DEB"; then echo "ffmpeg успешно установлен из vendor/debs." NEED_FFMPEG=0 else echo "Не удалось установить ffmpeg из $FFMPEG_DEB. Проверьте зависимости пакета." >&2 fi fi fi if [ "$NEED_PYTHON" -eq 0 ] && [ "$NEED_XVFB" -eq 0 ] && [ "$NEED_FFMPEG" -eq 0 ]; then echo "Python 3.12, Xvfb и ffmpeg уже установлены — продолжаем установку." else echo "Не найдены обязательные системные зависимости:" [ "$NEED_PYTHON" -eq 1 ] && echo " - python3.12 (и python3.12-venv)" [ "$NEED_XVFB" -eq 1 ] && echo " - Xvfb (или xvfb-run)" [ "$NEED_FFMPEG" -eq 1 ] && echo " - ffmpeg" echo "" echo "Установите их любым доступным способом (apt, локальное зеркало, deb-пакеты и т.п.)," echo "затем перезапустите ./install. Сам скрипт install не вызывает apt-get." exit 1 fi echo "" echo "=== 2. Firefox ESR и GeckoDriver (копирование из репо) ===" if [ ! -x "$REPO_ROOT/vendor/firefox-esr/firefox" ]; then echo "Ошибка: в репо не найден vendor/firefox-esr/firefox. Положите сюда установленный Firefox ESR (скопируйте с машины сборки из /opt/firefox-esr)." >&2 exit 1 fi if [ ! -x "$REPO_ROOT/vendor/geckodriver/geckodriver" ]; then echo "Ошибка: в репо не найден vendor/geckodriver/geckodriver. Положите сюда бинарь geckodriver (скопируйте с машины сборки из /usr/local/bin/geckodriver)." >&2 exit 1 fi rm -rf /opt/firefox-esr cp -r "$REPO_ROOT/vendor/firefox-esr" /opt/ ln -sf /opt/firefox-esr/firefox /usr/local/bin/firefox-esr echo "Firefox ESR скопирован из vendor/ в /opt/firefox-esr." cp "$REPO_ROOT/vendor/geckodriver/geckodriver" /usr/local/bin/geckodriver chmod +x /usr/local/bin/geckodriver echo "GeckoDriver скопирован из vendor/ в /usr/local/bin/geckodriver." echo "" echo "=== 3. Пользователь и каталоги ===" if ! getent group f7cloud-talk-recording >/dev/null 2>&1; then groupadd --system -g 989 f7cloud-talk-recording fi if ! id f7cloud-talk-recording >/dev/null 2>&1; then useradd --system -u 999 -g f7cloud-talk-recording -d /var/lib/f7cloud-talk-recording -s /usr/sbin/nologin f7cloud-talk-recording fi mkdir -p /var/lib/f7cloud-talk-recording /var/lib/f7cloud-recordings chown -R f7cloud-talk-recording:f7cloud-talk-recording /var/lib/f7cloud-talk-recording /var/lib/f7cloud-recordings echo "" echo "=== 4. Копирование systemd unit ===" cp "$REPO_ROOT/systemd/f7cloud-talk-recording.service" /etc/systemd/system/ chmod 644 /etc/systemd/system/f7cloud-talk-recording.service echo "" echo "=== 5. Конфиг приложения ===" mkdir -p /etc/f7cloud-talk-recording TEMPLATE="$REPO_ROOT/etc/f7cloud-talk-recording/server.conf.template" if [ -f "$TEMPLATE" ]; then if [ -n "$F7CLOUD_NEXTCLOUD_URL" ] && [ -n "$F7CLOUD_SECRET" ] && [ -n "$F7CLOUD_TALK_URL" ] && [ -n "$F7CLOUD_TALK_INTERNALSECRET" ]; then sed -e "s|F7CLOUD_NEXTCLOUD_URL|$F7CLOUD_NEXTCLOUD_URL|g" \ -e "s|F7CLOUD_SECRET|$F7CLOUD_SECRET|g" \ -e "s|F7CLOUD_TALK_URL|$F7CLOUD_TALK_URL|g" \ -e "s|F7CLOUD_TALK_INTERNALSECRET|$F7CLOUD_TALK_INTERNALSECRET|g" \ "$TEMPLATE" > /etc/f7cloud-talk-recording/server.conf echo "Конфиг создан из шаблона (значения из переменных окружения)." else cp "$TEMPLATE" /etc/f7cloud-talk-recording/server.conf echo "Конфиг скопирован как шаблон. Заполните вручную секреты и URL в /etc/f7cloud-talk-recording/server.conf" echo " (F7CLOUD_NEXTCLOUD_URL, F7CLOUD_SECRET, F7CLOUD_TALK_URL, F7CLOUD_TALK_INTERNALSECRET)" fi chown root:root /etc/f7cloud-talk-recording/server.conf chmod 640 /etc/f7cloud-talk-recording/server.conf else echo "Не найден шаблон $TEMPLATE" >&2 exit 1 fi echo "" echo "=== 6. Исходники и venv в /opt ===" mkdir -p /opt/f7cloud-talk-recording if [ -d "$REPO_ROOT/opt/f7cloud-talk-recording-src" ]; then cp -r "$REPO_ROOT/opt/f7cloud-talk-recording-src" /opt/ else echo "Не найдена папка opt/f7cloud-talk-recording-src" >&2 exit 1 fi if [ -f "$REPO_ROOT/opt/f7cloud-talk-recording/requirements.txt" ]; then cp "$REPO_ROOT/opt/f7cloud-talk-recording/requirements.txt" /opt/f7cloud-talk-recording/ fi echo "Создание виртуального окружения..." /usr/bin/python3.12 -m venv /opt/f7cloud-talk-recording/venv /opt/f7cloud-talk-recording/venv/bin/pip install -q -r /opt/f7cloud-talk-recording/requirements.txt /opt/f7cloud-talk-recording/venv/bin/pip install -q -e /opt/f7cloud-talk-recording-src chown -R f7cloud-talk-recording:f7cloud-talk-recording /opt/f7cloud-talk-recording /opt/f7cloud-talk-recording-src echo "" echo "=== 7. Systemd ===" systemctl daemon-reload systemctl enable f7cloud-talk-recording.service if [ -n "$F7CLOUD_NEXTCLOUD_URL" ] && [ -n "$F7CLOUD_SECRET" ] && [ -n "$F7CLOUD_TALK_URL" ] && [ -n "$F7CLOUD_TALK_INTERNALSECRET" ]; then systemctl start f7cloud-talk-recording.service echo "Сервис f7cloud-talk-recording запущен." else echo "После заполнения секретов в /etc/f7cloud-talk-recording/server.conf выполните:" echo " systemctl start f7cloud-talk-recording.service" fi echo "" echo "Готово. Логи: journalctl -u f7cloud-talk-recording.service -f"