Rewrite services
This commit is contained in:
@@ -1,288 +1,32 @@
|
||||
# CAN Sniffer Deployment for Raspberry Pi 5
|
||||
|
||||
Автоматическое развёртывание CAN Sniffer с systemd на Raspberry Pi 5 с 2-CH CAN HAT.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
Boot
|
||||
│
|
||||
▼
|
||||
systemd-modules-load (SPI модули)
|
||||
│
|
||||
▼
|
||||
can-setup.service (OneShot)
|
||||
│ - ip link set can0 type can bitrate 1000000
|
||||
│ - ip link set can0 up
|
||||
│ - ip link set can1 type can bitrate 1000000
|
||||
│ - ip link set can1 up
|
||||
│
|
||||
▼
|
||||
can-sniffer.service
|
||||
│ - python main.py
|
||||
│ - Чтение CAN → SQLite → PostgreSQL
|
||||
│
|
||||
▼
|
||||
Running...
|
||||
```
|
||||
|
||||
## Требования
|
||||
|
||||
### Hardware
|
||||
- Raspberry Pi 5
|
||||
- 2-CH CAN HAT (MCP2515 или MCP251xFD)
|
||||
- Flipper Zero (опционально, для мониторинга)
|
||||
|
||||
### Software
|
||||
- Raspberry Pi OS Bookworm (64-bit recommended)
|
||||
- Python 3.11+
|
||||
- Настроенный overlay для CAN HAT
|
||||
|
||||
## Настройка CAN HAT
|
||||
|
||||
Перед установкой убедитесь, что CAN HAT настроен в `/boot/firmware/config.txt`:
|
||||
|
||||
### Для MCP2515 (стандартный CAN):
|
||||
```ini
|
||||
# Enable SPI
|
||||
dtparam=spi=on
|
||||
|
||||
# Waveshare 2-CH CAN HAT (MCP2515)
|
||||
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
|
||||
dtoverlay=mcp2515-can1,oscillator=16000000,interrupt=24
|
||||
```
|
||||
|
||||
### Для MCP251xFD (CAN FD):
|
||||
```ini
|
||||
# Enable SPI
|
||||
dtparam=spi=on
|
||||
|
||||
# Waveshare 2-CH CAN FD HAT (MCP251xFD)
|
||||
dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25
|
||||
dtoverlay=mcp251xfd,spi0-1,oscillator=40000000,interrupt=24
|
||||
```
|
||||
|
||||
После изменения config.txt требуется перезагрузка:
|
||||
```bash
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
Проверка после перезагрузки:
|
||||
```bash
|
||||
ip link show | grep can
|
||||
# Должны появиться can0 и can1
|
||||
```
|
||||
|
||||
## Настройка UART для Flipper Zero
|
||||
|
||||
Для работы с Flipper Zero через UART (`/dev/ttyAMA0`) необходимо:
|
||||
|
||||
### 1. Отключить serial console
|
||||
```bash
|
||||
sudo raspi-config
|
||||
# Interface Options → Serial Port
|
||||
# - Login shell over serial: NO
|
||||
# - Serial port hardware enabled: YES
|
||||
```
|
||||
|
||||
### 2. Добавить в `/boot/firmware/config.txt`:
|
||||
```ini
|
||||
# Enable UART
|
||||
enable_uart=1
|
||||
|
||||
# На RPI5 освобождаем ttyAMA0 от Bluetooth
|
||||
# Вариант 1: Полностью отключить BT (рекомендуется)
|
||||
dtoverlay=disable-bt
|
||||
|
||||
# Вариант 2: Переместить BT на mini-UART
|
||||
# dtoverlay=miniuart-bt
|
||||
```
|
||||
|
||||
### 3. Перезагрузить и проверить:
|
||||
```bash
|
||||
sudo reboot
|
||||
|
||||
# После перезагрузки
|
||||
ls -la /dev/ttyAMA0
|
||||
# Должен показать устройство
|
||||
|
||||
# Тест чтения (Ctrl+C для выхода)
|
||||
cat /dev/ttyAMA0
|
||||
```
|
||||
|
||||
### 4. Подключение Flipper Zero
|
||||
| Flipper Pin | RPI5 Pin |
|
||||
|-------------|----------|
|
||||
| TX | GPIO15 (RXD) |
|
||||
| RX | GPIO14 (TXD) |
|
||||
| GND | GND |
|
||||
# CAN Sniffer - Deployment
|
||||
|
||||
## Установка
|
||||
|
||||
### 1. Клонирование репозитория
|
||||
```bash
|
||||
cd /home/pi
|
||||
git clone https://github.com/your-repo/carpibord.git
|
||||
cd carpibord/can_sniffer/deploy
|
||||
```
|
||||
|
||||
### 2. Запуск установщика
|
||||
```bash
|
||||
cd can_sniffer/deploy
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
Установщик автоматически:
|
||||
- Проверит зависимости (python3, can-utils)
|
||||
- Создаст директории `/opt/can_sniffer/{data,logs}`
|
||||
- Установит Python venv и зависимости
|
||||
- Скопирует production конфиг
|
||||
- Установит systemd сервисы
|
||||
- Включит автозапуск
|
||||
|
||||
### 3. Проверка статуса
|
||||
```bash
|
||||
sudo systemctl status can-setup
|
||||
sudo systemctl status can-sniffer
|
||||
```
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Основной конфиг
|
||||
```bash
|
||||
sudo nano /opt/can_sniffer/src/config.json
|
||||
```
|
||||
| Файл | Описание |
|
||||
|------|----------|
|
||||
| `/opt/can_sniffer/src/config.json` | Основной конфиг приложения |
|
||||
| `/etc/default/can-interfaces` | Настройки CAN шины (bitrate, интерфейсы) |
|
||||
|
||||
### Переопределение через environment
|
||||
Редактируйте `/etc/default/can-sniffer`:
|
||||
## Управление
|
||||
|
||||
```bash
|
||||
# CAN interfaces (для can-setup.service)
|
||||
CAN_INTERFACES="can0 can1"
|
||||
CAN_BITRATE=1000000
|
||||
|
||||
# Переопределение config.json (для can-sniffer.service)
|
||||
CAN_SNIFFER_CAN__INTERFACES="can0,can1"
|
||||
CAN_SNIFFER_POSTGRESQL__HOST="192.168.1.100"
|
||||
CAN_SNIFFER_LOGGING__LEVEL="DEBUG"
|
||||
```
|
||||
|
||||
После изменений:
|
||||
```bash
|
||||
sudo systemctl restart can-sniffer
|
||||
```
|
||||
|
||||
## Управление сервисами
|
||||
|
||||
```bash
|
||||
# Статус
|
||||
sudo systemctl status can-sniffer
|
||||
sudo systemctl status can-setup
|
||||
|
||||
# Запуск/остановка
|
||||
sudo systemctl start can-sniffer
|
||||
sudo systemctl stop can-sniffer
|
||||
|
||||
# Перезапуск
|
||||
sudo systemctl restart can-sniffer
|
||||
|
||||
# Просмотр логов
|
||||
sudo journalctl -u can-sniffer -f
|
||||
sudo journalctl -u can-sniffer --since "1 hour ago"
|
||||
|
||||
# Логи приложения
|
||||
tail -f /opt/can_sniffer/logs/can_edge.log
|
||||
systemctl start can-sniffer # Запуск
|
||||
systemctl stop can-sniffer # Остановка
|
||||
systemctl status can-sniffer # Статус
|
||||
journalctl -u can-sniffer -f # Логи
|
||||
```
|
||||
|
||||
## Диагностика
|
||||
|
||||
### Проверка CAN интерфейсов
|
||||
```bash
|
||||
# Статус интерфейсов
|
||||
ip -details link show can0
|
||||
ip -details link show can1
|
||||
|
||||
# Статистика
|
||||
ip -s link show can0
|
||||
|
||||
# Прослушивание (can-utils)
|
||||
candump can0 can1
|
||||
```
|
||||
|
||||
### Частые проблемы
|
||||
|
||||
#### 1. CAN интерфейсы не появляются
|
||||
```bash
|
||||
# Проверить overlay
|
||||
dmesg | grep -i can
|
||||
dmesg | grep -i mcp
|
||||
|
||||
# Проверить SPI
|
||||
ls /dev/spidev*
|
||||
```
|
||||
|
||||
#### 2. Ошибка "Network is down"
|
||||
```bash
|
||||
# Перезапустить can-setup
|
||||
sudo systemctl restart can-setup
|
||||
sudo ip link show can0
|
||||
```
|
||||
|
||||
#### 3. Ошибка доступа к CAN сокету
|
||||
```bash
|
||||
# Проверить capabilities в systemd
|
||||
sudo journalctl -u can-sniffer | grep -i denied
|
||||
|
||||
# Или запустить вручную для теста
|
||||
sudo /opt/can_sniffer/venv/bin/python /opt/can_sniffer/src/main.py
|
||||
```
|
||||
|
||||
#### 4. PostgreSQL недоступен
|
||||
```bash
|
||||
# Sniffer работает offline-first, данные сохраняются локально
|
||||
# Проверить SQLite
|
||||
ls -la /opt/can_sniffer/data/
|
||||
|
||||
# Синхронизация произойдёт автоматически когда PostgreSQL станет доступен
|
||||
```
|
||||
|
||||
#### 5. Flipper Zero не подключается (нет handshake)
|
||||
|
||||
**Симптомы:** `cat /dev/ttyAMA0` показывает "INIT:flipper", но ACK не отправляется.
|
||||
|
||||
**Проверки:**
|
||||
```bash
|
||||
# 1. Проверить что flipper enabled в конфиге
|
||||
grep -A5 '"flipper"' /opt/can_sniffer/src/config.json
|
||||
# Должно быть: "enabled": true
|
||||
|
||||
# 2. Проверить что pyserial установлен
|
||||
/opt/can_sniffer/venv/bin/pip show pyserial
|
||||
|
||||
# 3. Проверить права на UART
|
||||
ls -la /dev/ttyAMA0
|
||||
# crw-rw---- 1 root dialout ...
|
||||
|
||||
# 4. Проверить что пользователь в группе dialout
|
||||
groups pi
|
||||
# Должен содержать: dialout
|
||||
|
||||
# 5. Проверить что serial console отключена
|
||||
sudo dmesg | grep ttyAMA0
|
||||
# НЕ должно быть "console [ttyAMA0]"
|
||||
|
||||
# 6. Проверить логи flipper handler
|
||||
sudo journalctl -u can-sniffer | grep -i flipper
|
||||
```
|
||||
|
||||
**Типичные исправления:**
|
||||
```bash
|
||||
# Добавить в группу dialout
|
||||
sudo usermod -aG dialout pi
|
||||
|
||||
# Перезапустить после изменения групп
|
||||
sudo systemctl restart can-sniffer
|
||||
|
||||
# Или перелогиниться для применения группы
|
||||
./diagnose.sh
|
||||
```
|
||||
|
||||
## Удаление
|
||||
@@ -290,34 +34,3 @@ sudo systemctl restart can-sniffer
|
||||
```bash
|
||||
sudo ./uninstall.sh
|
||||
```
|
||||
|
||||
## Структура файлов
|
||||
|
||||
```
|
||||
/opt/can_sniffer/
|
||||
├── src/
|
||||
│ ├── main.py # Entry point
|
||||
│ ├── config.py # Configuration
|
||||
│ ├── config.json # Production config
|
||||
│ └── ...
|
||||
├── venv/ # Python virtual environment
|
||||
├── data/
|
||||
│ └── can_offline.db # SQLite database
|
||||
├── logs/
|
||||
│ └── can_edge.log # Application logs
|
||||
└── requirements.txt
|
||||
|
||||
/etc/systemd/system/
|
||||
├── can-setup.service # CAN interface setup (OneShot)
|
||||
└── can-sniffer.service # Main application service
|
||||
|
||||
/etc/default/
|
||||
└── can-sniffer # Environment overrides
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Сервис запускается от пользователя `pi` (не root)
|
||||
- Используется `ProtectSystem=strict` для защиты файловой системы
|
||||
- Capabilities ограничены `CAP_NET_RAW` и `CAP_NET_ADMIN` для CAN
|
||||
- Пароль PostgreSQL в config.json - рассмотрите использование secrets
|
||||
|
||||
10
can_sniffer/deploy/can-interfaces
Normal file
10
can_sniffer/deploy/can-interfaces
Normal file
@@ -0,0 +1,10 @@
|
||||
# /etc/default/can-interfaces
|
||||
# Настройки CAN интерфейсов для can-setup.service
|
||||
|
||||
# Список интерфейсов (через пробел)
|
||||
CAN_INTERFACES="can0 can1"
|
||||
|
||||
# Bitrate (бит/с)
|
||||
# 500000 - стандартный CAN
|
||||
# 1000000 - High-speed CAN
|
||||
CAN_BITRATE=500000
|
||||
@@ -1,49 +1,31 @@
|
||||
[Unit]
|
||||
Description=Setup CAN bus interfaces for 2ch CAN HAT
|
||||
Documentation=https://github.com/carpibord
|
||||
After=network-pre.target
|
||||
Before=network.target
|
||||
Wants=network-pre.target
|
||||
|
||||
# Ждём пока kernel загрузит модули для CAN HAT
|
||||
# MCP2515/MCP251xFD появляются после загрузки SPI overlay
|
||||
Description=Setup CAN interfaces
|
||||
After=systemd-modules-load.service
|
||||
Requires=systemd-modules-load.service
|
||||
Before=can-sniffer.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
|
||||
# Настройка CAN интерфейсов
|
||||
# Bitrate: 1000000 (1Mbps) - стандарт для автомобильной CAN шины
|
||||
# Можно изменить через /etc/default/can-sniffer
|
||||
# Конфиг CAN интерфейсов
|
||||
EnvironmentFile=/etc/default/can-interfaces
|
||||
|
||||
EnvironmentFile=-/etc/default/can-sniffer
|
||||
ExecStartPre=/usr/bin/sleep 2
|
||||
ExecStartPre=/bin/sleep 2
|
||||
ExecStart=/bin/bash -c '\
|
||||
for iface in ${CAN_INTERFACES:-can0 can1}; do \
|
||||
if ip link show "$iface" > /dev/null 2>&1; then \
|
||||
/sbin/ip link set "$iface" down 2>/dev/null || true; \
|
||||
/sbin/ip link set "$iface" type can bitrate ${CAN_BITRATE:-1000000}; \
|
||||
/sbin/ip link set "$iface" up; \
|
||||
echo "CAN interface $iface configured at ${CAN_BITRATE:-1000000} bps"; \
|
||||
else \
|
||||
echo "Warning: CAN interface $iface not found"; \
|
||||
if ip link show "$iface" 2>/dev/null; then \
|
||||
ip link set "$iface" down 2>/dev/null || true; \
|
||||
ip link set "$iface" type can bitrate ${CAN_BITRATE:-500000}; \
|
||||
ip link set "$iface" up; \
|
||||
echo "CAN $iface: UP at ${CAN_BITRATE:-500000} bps"; \
|
||||
fi; \
|
||||
done'
|
||||
done; \
|
||||
exit 0'
|
||||
|
||||
ExecStop=/bin/bash -c '\
|
||||
for iface in ${CAN_INTERFACES:-can0 can1}; do \
|
||||
if ip link show "$iface" > /dev/null 2>&1; then \
|
||||
/sbin/ip link set "$iface" down 2>/dev/null || true; \
|
||||
echo "CAN interface $iface stopped"; \
|
||||
fi; \
|
||||
ip link set "$iface" down 2>/dev/null || true; \
|
||||
done'
|
||||
|
||||
# Логирование через journald
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=can-setup
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# /etc/default/can-sniffer
|
||||
# Переменные окружения для can-setup.service и can-sniffer.service
|
||||
|
||||
# === CAN Interface Setup ===
|
||||
# Список интерфейсов через пробел
|
||||
CAN_INTERFACES="can0 can1"
|
||||
|
||||
# Bitrate (бит/с) - должен совпадать с настройками автомобиля
|
||||
# 500000 - стандартный CAN
|
||||
# 1000000 - CAN FD / High-speed CAN
|
||||
CAN_BITRATE=1000000
|
||||
|
||||
# === CAN Sniffer Overrides ===
|
||||
# Эти переменные переопределяют config.json
|
||||
# Формат: CAN_SNIFFER_<SECTION>__<KEY>
|
||||
|
||||
# Переопределение интерфейсов (через запятую)
|
||||
# CAN_SNIFFER_CAN__INTERFACES="can0,can1"
|
||||
|
||||
# Переопределение PostgreSQL хоста
|
||||
# CAN_SNIFFER_POSTGRESQL__HOST="192.168.1.100"
|
||||
|
||||
# Переопределение уровня логирования
|
||||
# CAN_SNIFFER_LOGGING__LEVEL="DEBUG"
|
||||
@@ -1,62 +1,33 @@
|
||||
[Unit]
|
||||
Description=CAN Bus Sniffer - Offline-first CAN data collector
|
||||
Documentation=https://github.com/carpibord
|
||||
After=can-setup.service network.target
|
||||
Requires=can-setup.service
|
||||
Wants=postgresql.service
|
||||
|
||||
# Restart при падении, но не слишком часто
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=5
|
||||
Description=CAN Bus Sniffer
|
||||
After=network.target can-setup.service
|
||||
Wants=can-setup.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=pi
|
||||
Group=pi
|
||||
|
||||
# Рабочая директория - где будут создаваться логи и БД
|
||||
User=root
|
||||
WorkingDirectory=/opt/can_sniffer
|
||||
|
||||
# Только PYTHONUNBUFFERED для вывода логов
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
Environment=PYTHONPATH=/opt/can_sniffer/src
|
||||
|
||||
# Загрузка переменных окружения для переопределения конфига
|
||||
EnvironmentFile=-/etc/default/can-sniffer
|
||||
|
||||
# Запуск через venv
|
||||
# Запуск - config.json читается из /opt/can_sniffer/src/
|
||||
ExecStart=/opt/can_sniffer/venv/bin/python /opt/can_sniffer/src/main.py
|
||||
|
||||
# Graceful shutdown - отправляем SIGTERM, ждём 30 секунд
|
||||
# main.py уже обрабатывает SIGTERM через signal handler
|
||||
TimeoutStopSec=30
|
||||
# Graceful shutdown
|
||||
TimeoutStopSec=15
|
||||
KillSignal=SIGTERM
|
||||
KillMode=mixed
|
||||
|
||||
# Автоматический рестарт при падении (но не при ручной остановке)
|
||||
# Рестарт при падении
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=5
|
||||
|
||||
# Логирование через journald
|
||||
# Логи
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=can-sniffer
|
||||
|
||||
# Security hardening (RPI5 совместимо)
|
||||
# NoNewPrivileges отключен для поддержки sudo (shutdown/reboot)
|
||||
NoNewPrivileges=no
|
||||
ProtectSystem=full
|
||||
ProtectHome=read-only
|
||||
PrivateTmp=yes
|
||||
ReadWritePaths=/opt/can_sniffer/data /opt/can_sniffer/logs
|
||||
|
||||
# Разрешаем доступ к CAN сокетам
|
||||
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
|
||||
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
|
||||
|
||||
# Доступ к UART для Flipper Zero (/dev/ttyAMA0) и I2C для UPS
|
||||
SupplementaryGroups=dialout i2c gpio
|
||||
DeviceAllow=/dev/ttyAMA0 rw
|
||||
DeviceAllow=/dev/i2c-1 rw
|
||||
DeviceAllow=/dev/gpiomem rw
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -1,219 +1,57 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# CAN Sniffer Diagnostic Script
|
||||
# Проверяет состояние системы и выводит полезную информацию для отладки
|
||||
# CAN Sniffer - Diagnostics
|
||||
#
|
||||
set -e
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
ok() { echo -e " ${GREEN}OK${NC} $1"; }
|
||||
fail() { echo -e " ${RED}FAIL${NC} $1"; }
|
||||
warn() { echo -e " ${YELLOW}WARN${NC} $1"; }
|
||||
section() { echo -e "\n${BLUE}=== $1 ===${NC}"; }
|
||||
ok() { echo -e "${GREEN}[OK]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
fail() { echo -e "${RED}[FAIL]${NC} $1"; }
|
||||
|
||||
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ CAN Sniffer Diagnostic Report ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
|
||||
echo "Date: $(date)"
|
||||
echo "Host: $(hostname)"
|
||||
|
||||
section "System Info"
|
||||
echo "OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
|
||||
echo "Kernel: $(uname -r)"
|
||||
echo "Architecture: $(uname -m)"
|
||||
if [[ -f /proc/device-tree/model ]]; then
|
||||
echo "Model: $(cat /proc/device-tree/model)"
|
||||
fi
|
||||
|
||||
section "CAN Kernel Modules"
|
||||
if lsmod | grep -q "can"; then
|
||||
lsmod | grep can
|
||||
ok "CAN modules loaded"
|
||||
else
|
||||
fail "No CAN modules loaded"
|
||||
echo " Try: modprobe can can_raw"
|
||||
fi
|
||||
|
||||
section "SPI Status"
|
||||
if ls /dev/spidev* 2>/dev/null; then
|
||||
ok "SPI devices found"
|
||||
else
|
||||
warn "No SPI devices found"
|
||||
echo " Check: dtparam=spi=on in /boot/firmware/config.txt"
|
||||
fi
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " CAN Sniffer Diagnostics"
|
||||
echo "========================================"
|
||||
|
||||
section "CAN Interfaces"
|
||||
CAN_FOUND=0
|
||||
for iface in can0 can1; do
|
||||
if ip link show "$iface" &>/dev/null; then
|
||||
CAN_FOUND=1
|
||||
STATE=$(ip link show "$iface" | grep -oP '(?<=state )\w+')
|
||||
if [[ "$STATE" == "UP" ]]; then
|
||||
ok "$iface: UP"
|
||||
else
|
||||
warn "$iface: $STATE"
|
||||
fi
|
||||
# Детали интерфейса
|
||||
ip -details link show "$iface" 2>/dev/null | grep -E "bitrate|state|mtu" | head -3 | sed 's/^/ /'
|
||||
STATE=$(ip link show "$iface" | grep -oP '(?<=state )\w+' || echo "?")
|
||||
[[ "$STATE" == "UP" ]] && ok "$iface: UP" || warn "$iface: $STATE"
|
||||
else
|
||||
fail "$iface: NOT FOUND"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $CAN_FOUND -eq 0 ]]; then
|
||||
warn "No CAN interfaces found"
|
||||
echo " Check CAN HAT overlay in /boot/firmware/config.txt"
|
||||
echo " Run: dmesg | grep -i mcp"
|
||||
fi
|
||||
|
||||
section "CAN Statistics"
|
||||
for iface in can0 can1; do
|
||||
if ip link show "$iface" &>/dev/null; then
|
||||
echo "$iface:"
|
||||
ip -s link show "$iface" 2>/dev/null | grep -E "RX:|TX:|errors" | sed 's/^/ /'
|
||||
fi
|
||||
done
|
||||
|
||||
section "Systemd Services"
|
||||
section "Services"
|
||||
for svc in can-setup can-sniffer; do
|
||||
if systemctl is-enabled "$svc" &>/dev/null; then
|
||||
STATUS=$(systemctl is-active "$svc" 2>/dev/null || echo "inactive")
|
||||
if [[ "$STATUS" == "active" ]]; then
|
||||
ok "$svc: $STATUS (enabled)"
|
||||
else
|
||||
warn "$svc: $STATUS (enabled)"
|
||||
fi
|
||||
[[ "$STATUS" == "active" ]] && ok "$svc: active" || warn "$svc: $STATUS"
|
||||
else
|
||||
fail "$svc: not installed or disabled"
|
||||
fail "$svc: not installed"
|
||||
fi
|
||||
done
|
||||
|
||||
section "Application Status"
|
||||
section "Files"
|
||||
INSTALL_DIR="/opt/can_sniffer"
|
||||
if [[ -d "$INSTALL_DIR" ]]; then
|
||||
ok "Installation directory exists: $INSTALL_DIR"
|
||||
[[ -d "$INSTALL_DIR" ]] && ok "Install: $INSTALL_DIR" || fail "Install dir missing"
|
||||
[[ -f "$INSTALL_DIR/venv/bin/python" ]] && ok "Python venv" || fail "venv missing"
|
||||
[[ -f "$INSTALL_DIR/src/config.json" ]] && ok "config.json" || fail "config missing"
|
||||
[[ -f "/etc/default/can-interfaces" ]] && ok "can-interfaces" || warn "can-interfaces missing"
|
||||
|
||||
# Check venv
|
||||
if [[ -f "$INSTALL_DIR/venv/bin/python" ]]; then
|
||||
ok "Python venv exists"
|
||||
PYTHON_VERSION=$("$INSTALL_DIR/venv/bin/python" --version 2>&1)
|
||||
echo " $PYTHON_VERSION"
|
||||
else
|
||||
fail "Python venv missing"
|
||||
fi
|
||||
section "UART"
|
||||
[[ -e "/dev/ttyAMA0" ]] && ok "/dev/ttyAMA0" || warn "UART not found"
|
||||
|
||||
# Check config
|
||||
if [[ -f "$INSTALL_DIR/src/config.json" ]]; then
|
||||
ok "Config file exists"
|
||||
else
|
||||
fail "Config file missing"
|
||||
fi
|
||||
section "Process"
|
||||
pgrep -f "can_sniffer.*main.py" > /dev/null && ok "Running" || warn "Not running"
|
||||
|
||||
# Check data directory
|
||||
if [[ -d "$INSTALL_DIR/data" ]]; then
|
||||
ok "Data directory exists"
|
||||
if [[ -f "$INSTALL_DIR/data/can_offline.db" ]]; then
|
||||
DB_SIZE=$(du -h "$INSTALL_DIR/data/can_offline.db" | cut -f1)
|
||||
echo " SQLite DB size: $DB_SIZE"
|
||||
fi
|
||||
else
|
||||
warn "Data directory missing"
|
||||
fi
|
||||
section "Logs (last 5)"
|
||||
journalctl -u can-sniffer --no-pager -n 5 2>/dev/null || echo " (no logs)"
|
||||
|
||||
# Check logs
|
||||
if [[ -d "$INSTALL_DIR/logs" ]]; then
|
||||
ok "Logs directory exists"
|
||||
if [[ -f "$INSTALL_DIR/logs/can_edge.log" ]]; then
|
||||
LOG_SIZE=$(du -h "$INSTALL_DIR/logs/can_edge.log" | cut -f1)
|
||||
echo " Log file size: $LOG_SIZE"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
fail "Installation directory not found: $INSTALL_DIR"
|
||||
fi
|
||||
|
||||
section "Recent Logs (last 10 lines)"
|
||||
if systemctl is-active can-sniffer &>/dev/null; then
|
||||
journalctl -u can-sniffer --no-pager -n 10 2>/dev/null || echo " (no logs available)"
|
||||
else
|
||||
echo " Service not running"
|
||||
fi
|
||||
|
||||
section "Process Check"
|
||||
if pgrep -f "can_sniffer.*main.py" > /dev/null; then
|
||||
ok "CAN Sniffer process running"
|
||||
ps aux | grep "[c]an_sniffer.*main.py" | sed 's/^/ /'
|
||||
else
|
||||
warn "CAN Sniffer process not running"
|
||||
fi
|
||||
|
||||
section "UART / Flipper Zero"
|
||||
UART_DEV="/dev/ttyAMA0"
|
||||
if [[ -e "$UART_DEV" ]]; then
|
||||
ok "UART device exists: $UART_DEV"
|
||||
ls -la "$UART_DEV" | sed 's/^/ /'
|
||||
|
||||
# Проверить права
|
||||
if [[ -r "$UART_DEV" ]] && [[ -w "$UART_DEV" ]]; then
|
||||
ok "UART readable/writable by current user"
|
||||
else
|
||||
warn "UART not accessible by current user"
|
||||
echo " Check: sudo usermod -aG dialout \$USER"
|
||||
fi
|
||||
|
||||
# Проверить serial console
|
||||
if dmesg 2>/dev/null | grep -q "console \[ttyAMA0\]"; then
|
||||
fail "Serial console is using ttyAMA0!"
|
||||
echo " Disable via: sudo raspi-config -> Interface Options -> Serial Port"
|
||||
else
|
||||
ok "Serial console not blocking ttyAMA0"
|
||||
fi
|
||||
else
|
||||
warn "UART device not found: $UART_DEV"
|
||||
echo " Check /boot/firmware/config.txt: enable_uart=1"
|
||||
fi
|
||||
|
||||
# Проверить конфиг flipper
|
||||
if [[ -f "$INSTALL_DIR/src/config.json" ]]; then
|
||||
FLIPPER_ENABLED=$(grep -A2 '"flipper"' "$INSTALL_DIR/src/config.json" | grep '"enabled"' | grep -oE '(true|false)')
|
||||
if [[ "$FLIPPER_ENABLED" == "true" ]]; then
|
||||
ok "Flipper handler enabled in config"
|
||||
else
|
||||
warn "Flipper handler DISABLED in config"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Проверить pyserial
|
||||
if [[ -f "$INSTALL_DIR/venv/bin/pip" ]]; then
|
||||
if "$INSTALL_DIR/venv/bin/pip" show pyserial &>/dev/null; then
|
||||
ok "pyserial installed"
|
||||
else
|
||||
fail "pyserial NOT installed"
|
||||
echo " Install: $INSTALL_DIR/venv/bin/pip install pyserial"
|
||||
fi
|
||||
fi
|
||||
|
||||
section "Network (PostgreSQL target)"
|
||||
# Извлекаем хост из конфига
|
||||
if [[ -f "$INSTALL_DIR/src/config.json" ]]; then
|
||||
PG_HOST=$(grep -oP '"host":\s*"\K[^"]+' "$INSTALL_DIR/src/config.json" | head -1)
|
||||
PG_PORT=$(grep -oP '"port":\s*\K\d+' "$INSTALL_DIR/src/config.json" | head -1)
|
||||
if [[ -n "$PG_HOST" ]]; then
|
||||
echo "PostgreSQL target: $PG_HOST:${PG_PORT:-5432}"
|
||||
if timeout 2 bash -c "echo >/dev/tcp/$PG_HOST/${PG_PORT:-5432}" 2>/dev/null; then
|
||||
ok "PostgreSQL port reachable"
|
||||
else
|
||||
warn "PostgreSQL port not reachable (offline mode active)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
section "dmesg CAN/SPI Errors (last 5)"
|
||||
dmesg | grep -iE "(can|mcp|spi).*error" | tail -5 || echo " (no errors found)"
|
||||
|
||||
echo -e "\n${BLUE}=== Diagnostic Complete ===${NC}\n"
|
||||
echo ""
|
||||
|
||||
@@ -1,233 +1,95 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# CAN Sniffer Installation Script for Raspberry Pi 5
|
||||
# Устанавливает сервисы автозапуска для can_sniffer
|
||||
# CAN Sniffer - Installation Script
|
||||
#
|
||||
set -e
|
||||
|
||||
# Цвета для вывода
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log() { echo -e "${GREEN}[*]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
||||
|
||||
# Проверка root прав
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "Этот скрипт должен запускаться с правами root"
|
||||
echo "Используйте: sudo $0"
|
||||
exit 1
|
||||
fi
|
||||
[[ $EUID -ne 0 ]] && error "Запустите с sudo: sudo $0"
|
||||
|
||||
# Определение директорий
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
INSTALL_DIR="/opt/can_sniffer"
|
||||
DATA_DIR="$INSTALL_DIR/data"
|
||||
LOGS_DIR="$INSTALL_DIR/logs"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
log_info "=== CAN Sniffer Installation ==="
|
||||
log_info "Source: $PROJECT_DIR"
|
||||
log_info "Target: $INSTALL_DIR"
|
||||
echo ""
|
||||
echo "=================================="
|
||||
echo " CAN Sniffer Installation"
|
||||
echo "=================================="
|
||||
echo ""
|
||||
|
||||
# === 1. Проверка системных зависимостей ===
|
||||
log_info "Checking system dependencies..."
|
||||
# 1. Системные пакеты
|
||||
log "Установка системных пакетов..."
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq python3 python3-pip python3-venv can-utils
|
||||
|
||||
# Проверка python3
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
log_error "Python3 not found. Installing..."
|
||||
apt-get update && apt-get install -y python3 python3-pip python3-venv
|
||||
fi
|
||||
# 2. Директории
|
||||
log "Создание директорий..."
|
||||
mkdir -p "$INSTALL_DIR"/{data,logs}
|
||||
|
||||
# Проверка can-utils (для диагностики)
|
||||
if ! command -v candump &> /dev/null; then
|
||||
log_warn "can-utils not found. Installing..."
|
||||
apt-get update && apt-get install -y can-utils
|
||||
fi
|
||||
|
||||
# === 2. Проверка CAN overlay в config.txt ===
|
||||
log_info "Checking CAN HAT overlay configuration..."
|
||||
|
||||
CONFIG_TXT="/boot/firmware/config.txt"
|
||||
if [[ ! -f "$CONFIG_TXT" ]]; then
|
||||
CONFIG_TXT="/boot/config.txt"
|
||||
fi
|
||||
|
||||
if [[ -f "$CONFIG_TXT" ]]; then
|
||||
# Проверяем наличие MCP2515 overlay (типичный для 2ch CAN HAT)
|
||||
if ! grep -q "mcp2515" "$CONFIG_TXT" && ! grep -q "mcp251xfd" "$CONFIG_TXT"; then
|
||||
log_warn "CAN HAT overlay not found in $CONFIG_TXT"
|
||||
log_warn "You may need to add overlay for your CAN HAT. Example for MCP2515:"
|
||||
echo ""
|
||||
echo " # For Waveshare 2-CH CAN HAT:"
|
||||
echo " dtparam=spi=on"
|
||||
echo " dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25"
|
||||
echo " dtoverlay=mcp2515-can1,oscillator=16000000,interrupt=24"
|
||||
echo ""
|
||||
echo " # Or for MCP251xFD (CAN FD):"
|
||||
echo " dtparam=spi=on"
|
||||
echo " dtoverlay=mcp251xfd,spi0-0,oscillator=40000000,interrupt=25"
|
||||
echo " dtoverlay=mcp251xfd,spi0-1,oscillator=40000000,interrupt=24"
|
||||
echo ""
|
||||
read -p "Continue installation anyway? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log_info "CAN HAT overlay found in config.txt"
|
||||
fi
|
||||
|
||||
# Проверяем UART для Flipper Zero
|
||||
if ! grep -q "enable_uart=1" "$CONFIG_TXT"; then
|
||||
log_warn "UART not enabled in $CONFIG_TXT"
|
||||
log_warn "For Flipper Zero support, add to $CONFIG_TXT:"
|
||||
echo ""
|
||||
echo " enable_uart=1"
|
||||
echo " dtoverlay=disable-bt # или dtoverlay=miniuart-bt"
|
||||
echo ""
|
||||
else
|
||||
log_info "UART enabled in config.txt"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Проверяем что serial console отключена
|
||||
if grep -q "console=serial0" /boot/firmware/cmdline.txt 2>/dev/null || \
|
||||
grep -q "console=ttyAMA0" /boot/firmware/cmdline.txt 2>/dev/null; then
|
||||
log_warn "Serial console may be using ttyAMA0!"
|
||||
log_warn "Disable via: sudo raspi-config -> Interface Options -> Serial Port"
|
||||
fi
|
||||
|
||||
# === 3. Создание директорий ===
|
||||
log_info "Creating directories..."
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
mkdir -p "$DATA_DIR"
|
||||
mkdir -p "$LOGS_DIR"
|
||||
|
||||
# === 4. Копирование файлов проекта ===
|
||||
log_info "Copying project files..."
|
||||
|
||||
# Копируем src
|
||||
# 3. Копирование проекта
|
||||
log "Копирование файлов..."
|
||||
cp -r "$PROJECT_DIR/src" "$INSTALL_DIR/"
|
||||
|
||||
# Копируем requirements.txt
|
||||
cp "$PROJECT_DIR/requirements.txt" "$INSTALL_DIR/"
|
||||
|
||||
# Копируем production config как основной
|
||||
# Используем production конфиг
|
||||
cp "$SCRIPT_DIR/config.production.json" "$INSTALL_DIR/src/config.json"
|
||||
|
||||
# === 5. Создание виртуального окружения ===
|
||||
log_info "Creating Python virtual environment..."
|
||||
# 4. Python venv
|
||||
log "Создание Python окружения..."
|
||||
python3 -m venv "$INSTALL_DIR/venv"
|
||||
"$INSTALL_DIR/venv/bin/pip" install -q --upgrade pip
|
||||
"$INSTALL_DIR/venv/bin/pip" install -q -r "$INSTALL_DIR/requirements.txt"
|
||||
|
||||
if [[ ! -d "$INSTALL_DIR/venv" ]]; then
|
||||
python3 -m venv "$INSTALL_DIR/venv"
|
||||
fi
|
||||
|
||||
# Устанавливаем зависимости
|
||||
log_info "Installing Python dependencies..."
|
||||
"$INSTALL_DIR/venv/bin/pip" install --upgrade pip
|
||||
"$INSTALL_DIR/venv/bin/pip" install -r "$INSTALL_DIR/requirements.txt"
|
||||
|
||||
# === 6. Настройка прав доступа ===
|
||||
log_info "Setting permissions..."
|
||||
|
||||
# Определяем пользователя (pi или текущий sudo user)
|
||||
if id "pi" &>/dev/null; then
|
||||
SERVICE_USER="pi"
|
||||
else
|
||||
SERVICE_USER="${SUDO_USER:-root}"
|
||||
fi
|
||||
|
||||
log_info "Service will run as user: $SERVICE_USER"
|
||||
|
||||
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
|
||||
# 5. Права
|
||||
log "Настройка прав..."
|
||||
chmod -R 755 "$INSTALL_DIR"
|
||||
chmod 700 "$DATA_DIR"
|
||||
chmod 755 "$LOGS_DIR"
|
||||
chmod 700 "$INSTALL_DIR/data"
|
||||
|
||||
# Добавляем пользователя в группы для доступа к CAN, UART и I2C
|
||||
usermod -aG dialout "$SERVICE_USER" 2>/dev/null || true
|
||||
usermod -aG plugdev "$SERVICE_USER" 2>/dev/null || true
|
||||
usermod -aG i2c "$SERVICE_USER" 2>/dev/null || true
|
||||
usermod -aG gpio "$SERVICE_USER" 2>/dev/null || true
|
||||
# 6. Systemd сервисы
|
||||
log "Установка сервисов..."
|
||||
cp "$SCRIPT_DIR/can-sniffer.service" /etc/systemd/system/
|
||||
cp "$SCRIPT_DIR/can-setup.service" /etc/systemd/system/
|
||||
|
||||
# === 6.1. Настройка sudoers для shutdown/reboot ===
|
||||
log_info "Configuring sudoers for power management..."
|
||||
# CAN интерфейсы - отдельный конфиг
|
||||
cp "$SCRIPT_DIR/can-interfaces" /etc/default/can-interfaces
|
||||
|
||||
SUDOERS_FILE="/etc/sudoers.d/can-sniffer"
|
||||
cat > "$SUDOERS_FILE" << EOF
|
||||
# Allow can_sniffer service user to run power commands without password
|
||||
$SERVICE_USER ALL=(ALL) NOPASSWD: /sbin/shutdown
|
||||
$SERVICE_USER ALL=(ALL) NOPASSWD: /sbin/reboot
|
||||
$SERVICE_USER ALL=(ALL) NOPASSWD: /usr/sbin/shutdown
|
||||
$SERVICE_USER ALL=(ALL) NOPASSWD: /usr/sbin/reboot
|
||||
EOF
|
||||
chmod 440 "$SUDOERS_FILE"
|
||||
log_info "Sudoers configured for user: $SERVICE_USER"
|
||||
|
||||
# === 7. Установка systemd сервисов ===
|
||||
log_info "Installing systemd services..."
|
||||
|
||||
# Обновляем user в service файле
|
||||
sed "s/User=pi/User=$SERVICE_USER/g; s/Group=pi/Group=$SERVICE_USER/g" \
|
||||
"$SCRIPT_DIR/can-sniffer.service" > "$SYSTEMD_DIR/can-sniffer.service"
|
||||
|
||||
# Копируем can-setup service
|
||||
cp "$SCRIPT_DIR/can-setup.service" "$SYSTEMD_DIR/"
|
||||
|
||||
# Копируем environment file
|
||||
cp "$SCRIPT_DIR/can-sniffer.env" "/etc/default/can-sniffer"
|
||||
|
||||
# Перезагрузка systemd
|
||||
systemctl daemon-reload
|
||||
|
||||
# === 8. Включение сервисов ===
|
||||
log_info "Enabling services..."
|
||||
|
||||
systemctl enable can-setup.service
|
||||
systemctl enable can-sniffer.service
|
||||
|
||||
# === 9. Итоговая информация ===
|
||||
# Готово
|
||||
echo ""
|
||||
log_info "=== Installation Complete ==="
|
||||
echo "=================================="
|
||||
echo " Установка завершена!"
|
||||
echo "=================================="
|
||||
echo ""
|
||||
echo "Installed components:"
|
||||
echo " - CAN Setup Service: $SYSTEMD_DIR/can-setup.service"
|
||||
echo " - CAN Sniffer Service: $SYSTEMD_DIR/can-sniffer.service"
|
||||
echo " - Environment config: /etc/default/can-sniffer"
|
||||
echo " - Application: $INSTALL_DIR"
|
||||
echo " - Data directory: $DATA_DIR"
|
||||
echo " - Logs directory: $LOGS_DIR"
|
||||
echo "Конфиги:"
|
||||
echo " Приложение: $INSTALL_DIR/src/config.json"
|
||||
echo " CAN шина: /etc/default/can-interfaces"
|
||||
echo ""
|
||||
echo "Configuration:"
|
||||
echo " - Main config: $INSTALL_DIR/src/config.json"
|
||||
echo " - Edit /etc/default/can-sniffer to override settings"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " sudo systemctl start can-setup # Start CAN interfaces"
|
||||
echo " sudo systemctl start can-sniffer # Start sniffer"
|
||||
echo " sudo systemctl status can-sniffer # Check status"
|
||||
echo " sudo journalctl -u can-sniffer -f # View logs"
|
||||
echo ""
|
||||
echo "To start now (without reboot):"
|
||||
echo " sudo systemctl start can-setup && sudo systemctl start can-sniffer"
|
||||
echo "Команды:"
|
||||
echo " systemctl start can-sniffer"
|
||||
echo " systemctl status can-sniffer"
|
||||
echo " journalctl -u can-sniffer -f"
|
||||
echo ""
|
||||
|
||||
# Спрашиваем о немедленном запуске
|
||||
read -p "Start services now? [y/N] " -n 1 -r
|
||||
read -p "Запустить сейчас? [Y/n] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "Starting services..."
|
||||
systemctl start can-setup
|
||||
sleep 2
|
||||
systemctl start can-sniffer
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
log "Запуск..."
|
||||
systemctl start can-setup || warn "can-setup: CAN интерфейсы не найдены"
|
||||
sleep 1
|
||||
systemctl status can-sniffer --no-pager
|
||||
systemctl start can-sniffer
|
||||
sleep 2
|
||||
systemctl status can-sniffer --no-pager || true
|
||||
fi
|
||||
|
||||
log_info "Done!"
|
||||
log "Готово!"
|
||||
|
||||
@@ -1,59 +1,45 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# CAN Sniffer Uninstallation Script
|
||||
# CAN Sniffer - Uninstall Script
|
||||
#
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log() { echo -e "${GREEN}[*]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}[ERROR]${NC} Run with sudo"
|
||||
exit 1
|
||||
fi
|
||||
[[ $EUID -ne 0 ]] && error "Запустите с sudo: sudo $0"
|
||||
|
||||
INSTALL_DIR="/opt/can_sniffer"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
log_info "=== CAN Sniffer Uninstallation ==="
|
||||
echo ""
|
||||
echo "=================================="
|
||||
echo " CAN Sniffer Uninstall"
|
||||
echo "=================================="
|
||||
echo ""
|
||||
|
||||
# Остановка сервисов
|
||||
log_info "Stopping services..."
|
||||
log "Остановка сервисов..."
|
||||
systemctl stop can-sniffer 2>/dev/null || true
|
||||
systemctl stop can-setup 2>/dev/null || true
|
||||
|
||||
# Отключение сервисов
|
||||
log_info "Disabling services..."
|
||||
log "Отключение автозапуска..."
|
||||
systemctl disable can-sniffer 2>/dev/null || true
|
||||
systemctl disable can-setup 2>/dev/null || true
|
||||
|
||||
# Удаление systemd файлов
|
||||
log_info "Removing systemd files..."
|
||||
rm -f "$SYSTEMD_DIR/can-sniffer.service"
|
||||
rm -f "$SYSTEMD_DIR/can-setup.service"
|
||||
rm -f "/etc/default/can-sniffer"
|
||||
|
||||
log "Удаление systemd файлов..."
|
||||
rm -f /etc/systemd/system/can-sniffer.service
|
||||
rm -f /etc/systemd/system/can-setup.service
|
||||
rm -f /etc/default/can-interfaces
|
||||
systemctl daemon-reload
|
||||
|
||||
# Спрашиваем про удаление данных
|
||||
echo ""
|
||||
read -p "Remove application data ($INSTALL_DIR/data)? [y/N] " -n 1 -r
|
||||
read -p "Удалить приложение ($INSTALL_DIR)? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_warn "Removing data directory..."
|
||||
rm -rf "$INSTALL_DIR/data"
|
||||
fi
|
||||
|
||||
read -p "Remove entire installation ($INSTALL_DIR)? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_warn "Removing installation directory..."
|
||||
log "Удаление $INSTALL_DIR..."
|
||||
rm -rf "$INSTALL_DIR"
|
||||
fi
|
||||
|
||||
log_info "Uninstallation complete!"
|
||||
log "Готово!"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"""
|
||||
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from config import config
|
||||
|
||||
Reference in New Issue
Block a user