Когда сервис критичен, обновление "в лоб" - плохая идея. Ошибка в новом бинаре или конфиге может повалить всё. Решение? Безопасное автообновление с возможностью мгновенного отката и логированием. Всё на Bash + systemd.
🌟 Как это работает?
1. Скрипт обновляет бинарь или конфиг.
2. Перезапускает systemd-сервис.
3. Проверяет статус через systemctl и/или пользовательские тесты.
4. В случае сбоя - откатывает всё.
5. Логирует действия для аудита.
📱 Пример скрипта:
#!/bin/bash
SERVICE="myapp.service"
BIN_DIR="/opt/myapp"
NEW_BIN="/tmp/myapp-new"
BACKUP="$BIN_DIR/myapp.bak"
MAIN_BIN="$BIN_DIR/myapp"
LOG="/var/log/myapp_updater.log"
log() {
echo "[$(date +'%F %T')] $1" >> "$LOG"
}
# Резервная копия текущего бинарника
cp "$MAIN_BIN" "$BACKUP" && log "Создана резервная копия."
# Копируем новый бинарь
cp "$NEW_BIN" "$MAIN_BIN" && chmod +x "$MAIN_BIN" && log "Установлен новый бинарь."
# Перезапускаем сервис
systemctl restart "$SERVICE"
sleep 5
# Проверка статуса
if ! systemctl is-active --quiet "$SERVICE"; then
log "Ошибка! Сервис не запустился. Выполняется откат."
cp "$BACKUP" "$MAIN_BIN"
systemctl restart "$SERVICE"
if systemctl is-active --quiet "$SERVICE"; then
log "Откат успешен."
else
log "Откат не удался. Требуется ручное вмешательство!"
fi
else
log "Сервис успешно обновлён и запущен."
rm -f "$BACKUP"
fi
▪️ Подключение как systemd-timer. Чтобы запускать обновление по расписанию:
# /etc/systemd/system/myapp-updater.timer
[Unit]
Description=Update myapp binary daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/myapp-updater.service
[Unit]
Description=Update myapp safely
[Service]
ExecStart=/usr/local/bin/myapp_updater.sh
sudo systemctl daemon-reload
sudo systemctl enable --now myapp-updater.timer
🌟 Что можно улучшить:
1. Добавить интеграцию с Git или rsync для получения обновлений.
2. Хэш-сравнение файлов (md5sum) перед установкой.
3. Юнит-тест на бинарь/конфиг после замены.
BashTex 📱 #bash #utils