Files
Button/winDeployScripts/device-install.sh
T
2026-06-25 15:28:46 +03:00

139 lines
7.5 KiB
Bash

#!/usr/bin/env bash
# device-install.sh — выполняется НА устройстве (заливается через adb).
# Offline-установка пакетов + полный провижининг по образцу README.
# Идемпотентен: повторный запуск безопасен, существующий config не трогается.
set -euo pipefail
BUNDLE_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT=/opt/buttontask
USER_NAME=buttontask
VER="$(cat "$BUNDLE_DIR/VERSION" 2>/dev/null || echo 0.0)"
log() { printf '\033[1;32m[install]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; }
die() { printf '\033[1;31m[error]\033[0m %s\n' "$*" >&2; exit 1; }
[ "$(id -u)" -eq 0 ] || die "нужны root-права (adb root или sudo на устройстве)"
# ---------------------------------------------------------------------------
# 1. Offline-пакеты
# ---------------------------------------------------------------------------
if ls "$BUNDLE_DIR"/debs/*.deb >/dev/null 2>&1; then
log "Установка пакетов offline (dpkg)..."
# Конфликтующие альтернативы (напр. *-gles, elogind) dpkg отвергнет — это нормально:
# нужное ставится, лишнее нам не нужно. Код возврата dpkg НЕ фатальный;
# реальный рантайм проверяем ниже.
dpkg -i "$BUNDLE_DIR"/debs/*.deb || true
dpkg -i "$BUNDLE_DIR"/debs/*.deb >/dev/null 2>&1 || true # второй проход — порядок
ldconfig
else
warn "каталог debs/ пуст — пропускаю установку пакетов"
fi
# --- проверяем, что РЕАЛЬНО нужное на месте (а не код возврата dpkg) ---
command -v python3 >/dev/null || die "python3 не установился"
python3 -c 'import flask' 2>/dev/null || die "python3-flask не установился"
command -v nmcli >/dev/null || warn "nmcli отсутствует — сетевые настройки из web не заработают"
ls /usr/lib/*/qt5/qml/QtQuick/Controls.2 >/dev/null 2>&1 \
|| warn "QML-модуль QtQuick.Controls 2 не найден — UI может не подняться"
# ---------------------------------------------------------------------------
# 2. Системный пользователь
# ---------------------------------------------------------------------------
id "$USER_NAME" >/dev/null 2>&1 || useradd -r -s /bin/false "$USER_NAME"
# группы для eglfs/KMS/тача
usermod -aG video,render,input "$USER_NAME" 2>/dev/null || true
# ---------------------------------------------------------------------------
# 3. Версионированная раскладка
# ---------------------------------------------------------------------------
install -d "$ROOT"/versions/"$VER" "$ROOT"/config "$ROOT"/icons "$ROOT"/run "$ROOT"/scripts
[ -f "$BUNDLE_DIR/app/ButtonTask" ] || die "нет бинарника app/ButtonTask в бандле"
install -m0755 "$BUNDLE_DIR/app/ButtonTask" "$ROOT/versions/$VER/ButtonTask"
cp -a "$BUNDLE_DIR/webconfig" "$ROOT/versions/$VER/"
ln -sfn "$ROOT/versions/$VER" "$ROOT/current"
# config — не перезатираем существующий (apgrade-safe)
if [ -f "$ROOT/config/config.json" ]; then
log "config.json уже есть — оставляю как есть"
elif [ -f "$BUNDLE_DIR/config/config.json" ]; then
cp -a "$BUNDLE_DIR/config/config.json" "$ROOT/config/"
log "config.json установлен"
else
warn "config.json нет ни на устройстве, ни в бандле — приложение создаст дефолтный при старте"
fi
# ---------------------------------------------------------------------------
# 4. Привилегированные хелперы + sudoers
# ---------------------------------------------------------------------------
install -m0755 "$BUNDLE_DIR"/scripts/bt-netconfig \
"$BUNDLE_DIR"/scripts/bt-update \
"$BUNDLE_DIR"/scripts/bt-service "$ROOT"/scripts/
sed -i 's/\r$//' "$ROOT"/scripts/bt-* 2>/dev/null || true # на случай CRLF
install -m0440 "$BUNDLE_DIR/scripts/buttontask.sudoers" /etc/sudoers.d/buttontask
sed -i 's/\r$//' /etc/sudoers.d/buttontask 2>/dev/null || true
visudo -cf /etc/sudoers.d/buttontask || die "sudoers некорректен"
# ---------------------------------------------------------------------------
# 5. Runtime-каталог (XDG_RUNTIME_DIR). /tmp очищается на ребуте —
# пересоздаём через tmpfiles, чтобы «и всё работает» после перезагрузки.
# ---------------------------------------------------------------------------
cat >/etc/tmpfiles.d/buttontask.conf <<EOF
d /tmp/runtime-buttontask 0700 $USER_NAME $USER_NAME -
EOF
systemd-tmpfiles --create /etc/tmpfiles.d/buttontask.conf || true
# ---------------------------------------------------------------------------
# 6. Владелец: всё buttontask, кроме root-хелперов
# ---------------------------------------------------------------------------
chown -R "$USER_NAME:$USER_NAME" "$ROOT"
chown root:root "$ROOT"/scripts/bt-*
# ---------------------------------------------------------------------------
# 7. systemd-юниты
# ---------------------------------------------------------------------------
# все юниты из бандла (buttontask, buttontask-web и, если есть, buttontask-network)
install -m0644 "$BUNDLE_DIR"/systemd/*.service /etc/systemd/system/
# ---------------------------------------------------------------------------
# 8. Авто-детект тачскрина -> override.conf (eventN зависит от платы)
# ---------------------------------------------------------------------------
detect_touch() {
awk 'BEGIN{RS="";FS="\n"}
{
ev=""; abs="";
for (i=1;i<=NF;i++) {
if ($i ~ /Handlers=/ && match($i,/event[0-9]+/)) ev=substr($i,RSTART,RLENGTH);
if ($i ~ /^B: ABS=/) abs=$i;
}
if (ev!="" && abs!="" && abs !~ /ABS=0+$/) { print ev; exit }
}' /proc/bus/input/devices 2>/dev/null
}
TOUCH_EV="$(detect_touch || true)"
EX="$BUNDLE_DIR/systemd/override.conf.example"
if [ -n "$TOUCH_EV" ] && [ -f "$EX" ]; then
install -d /etc/systemd/system/buttontask.service.d
sed "s/event[0-9]\+/$TOUCH_EV/g" "$EX" \
> /etc/systemd/system/buttontask.service.d/override.conf
log "тачскрин: /dev/input/$TOUCH_EV -> override.conf"
else
warn "тачскрин не определён автоматически — при необходимости задайте override.conf вручную"
fi
# ---------------------------------------------------------------------------
# 9. eglfs забирает KMS/DRM напрямую -> выключаем display-manager
# ---------------------------------------------------------------------------
systemctl disable display-manager 2>/dev/null || true
systemctl stop display-manager 2>/dev/null || true
# ---------------------------------------------------------------------------
# 10. Включаем сервисы (старт — после ребута)
# ---------------------------------------------------------------------------
systemctl daemon-reload
systemctl enable buttontask buttontask-web >/dev/null 2>&1 || \
die "не удалось включить сервисы (проверьте имена юнитов)"
log "версия $VER развёрнута"
echo "INSTALL-OK"