ИШ 110.0.997 в обновлении + полный бэкап и откат ИШ
- Одобрен дистрибутив ИШ 110.0.997 (deploy/release/igate-approved): клиенты получают его компонентом igate-dist, bj-server обновляет ИШ сам (igateAutoUpgrade) после применения обновления. Проверено на 28: установка 107.0.930 → 110.0.997 штатным bj-igate-admin, каналы сохранены, круг #M2MHR → #M2MTH с НРД TEST3 и приём ответа поллером bj — работают. - Бэкап перед установкой/обновлением ИШ стал полным: кроме /opt/nsd/igate и дампа базы — данные /var/lib/igate (без флешки с ключом и кэша), юнит, обёртка запуска, версия. Раньше откатиться было нечем: igate-dist.zip перезаписывается новой версией. - bj-igate-admin rollback / rollback-now: возврат программы, данных и базы ИШ из последнего бэкапа (pg_restore от postgres — с мандатными метками Astra). После отката пришедшая версия не ставится автоматически (/var/lib/bj/igate-autoupgrade-skip), следующая — снова да. Проверено на 28: 110.0.997 → 107.0.930 за 40 с, обмен с НРД работает. - «Шлюз НРД»: кнопка «Откатить ИШ к <версия>», когда есть полная резервная копия. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
@@ -86,7 +86,9 @@ case "$cmd" in
|
||||
'deponent',(select value from parameters p where p.chanel_id=c.id and p.name='repositoryCode'),
|
||||
'dir',(select value from parameters p where p.chanel_id=c.id and p.name='dir')) order by c.id),'[]') from channels c" 2>/dev/null || echo "[]")
|
||||
fi
|
||||
echo "{\"ok\":true,\"installed\":$inst,\"version\":$(q "$(igate_version)"),\"service\":$(q "$svc"),\"engine\":$(q "$st"),\"channels\":${chans:-[]}}" ;;
|
||||
rb=""; BK=$(cat /var/backups/ish-last-backup.txt 2>/dev/null)
|
||||
[ -n "$BK" ] && [ -s "$BK/version" ] && [ -s "$BK/opt-nsd-igate.tar.gz" ] && [ -s "$BK/igate-db.dump" ] && [ -s "$BK/var-lib-igate.tar.gz" ] && rb=$(cat "$BK/version")
|
||||
echo "{\"ok\":true,\"installed\":$inst,\"version\":$(q "$(igate_version)"),\"service\":$(q "$svc"),\"engine\":$(q "$st"),\"rollback\":$(q "$rb"),\"channels\":${chans:-[]}}" ;;
|
||||
|
||||
install)
|
||||
if pgrep -f "bj-igate-admin install-now" >/dev/null; then
|
||||
@@ -173,7 +175,11 @@ PY
|
||||
BK=/var/backups/ish-$(date +%Y%m%d-%H%M%S); mkdir -p "$BK"
|
||||
tar czf "$BK/opt-nsd-igate.tar.gz" -C "$(dirname "$IGATE_DIR")" "$(basename "$IGATE_DIR")" 2>/dev/null
|
||||
runuser -u postgres -- pg_dump -Fc "$DB" > "$BK/igate-db.dump" 2>/dev/null
|
||||
echo "$BK" > /var/backups/ish-last-backup.txt; echo "резервная копия прежнего ИШ: $BK"
|
||||
# для отката: данные ИШ (без флешки с ключом и кэша), юнит, обёртка запуска, версия
|
||||
tar czf "$BK/var-lib-igate.tar.gz" --exclude="${HOME_DIR#/}/keymedia" --exclude="${HOME_DIR#/}/.cache" -C / "${HOME_DIR#/}" 2>/dev/null
|
||||
cp -a "$UNIT" "$BK/" 2>/dev/null; cp -a "$UNIT.d" "$BK/" 2>/dev/null; cp -a "$WRAPPER" "$BK/" 2>/dev/null
|
||||
igate_version > "$BK/version"
|
||||
echo "$BK" > /var/backups/ish-last-backup.txt; echo "резервная копия прежнего ИШ $(cat "$BK/version"): $BK"
|
||||
fi
|
||||
echo "igate igate/service boolean false" | debconf-set-selections
|
||||
echo "igate igate/shortcut boolean false" | debconf-set-selections
|
||||
@@ -253,6 +259,49 @@ SQL
|
||||
case "$(j file)" in /var/lib/bj/igate-upload/*) rm -f "$(j file)" ;; esac # загруженный архив больше не нужен (с образа — остаётся)
|
||||
st done "ИШ $(igate_version) установлен и работает; дальше — канал контура (TEST3 или боевой)" ;;
|
||||
|
||||
rollback)
|
||||
pgrep -f "bj-igate-admin (install|rollback)-now" >/dev/null && err "установка или откат ИШ уже идёт"
|
||||
BK=$(cat /var/backups/ish-last-backup.txt 2>/dev/null)
|
||||
[ -n "$BK" ] && [ -s "$BK/version" ] && [ -s "$BK/var-lib-igate.tar.gz" ] || err "нет полной резервной копии прежнего ИШ — откатить нельзя"
|
||||
echo '{"stage":"queued","msg":"откат запущен"}' > "$STATUS"; chown bj:bj "$STATUS" 2>/dev/null
|
||||
systemd-run --unit="bj-igate-rollback-$(date +%s)" --collect -p RuntimeMaxSec=1800 /usr/local/sbin/bj-igate-admin rollback-now >/dev/null 2>&1 || err "не удалось запустить откат"
|
||||
ok "откат ИШ к $(cat "$BK/version") запущен" ;;
|
||||
|
||||
rollback-now)
|
||||
LOG=/var/log/bj-igate-install.log; : > "$LOG"
|
||||
st() { python3 - "$STATUS" "$1" "$2" "$LOG" <<'PY'
|
||||
import json,sys,datetime
|
||||
tail=open(sys.argv[4],errors='replace').read()[-1500:]
|
||||
json.dump({"at":datetime.datetime.now().astimezone().isoformat(timespec="seconds"),"stage":sys.argv[2],"msg":sys.argv[3],"log":tail},open(sys.argv[1],"w"),ensure_ascii=False)
|
||||
PY
|
||||
chown bj:bj "$STATUS" 2>/dev/null; echo "== $2" >> "$LOG"; }
|
||||
die() { st error "$1"; exit 1; }
|
||||
exec >>"$LOG" 2>&1
|
||||
BK=$(cat /var/backups/ish-last-backup.txt 2>/dev/null); old=$(cat "$BK/version" 2>/dev/null); cur=$(igate_version)
|
||||
[ -n "$old" ] || die "нет резервной копии прежнего ИШ"
|
||||
st stop "остановка ИШ $cur"
|
||||
systemctl stop igate >/dev/null 2>&1 || true
|
||||
pkill -9 -u "$SVC_USER" -f igate-svc 2>/dev/null; pkill -9 -u "$SVC_USER" -f Xvfb 2>/dev/null; rm -f /tmp/CoreFxPipe_NSD.IGate.*
|
||||
st files "возврат программы и данных ИШ $old"
|
||||
rm -rf "$IGATE_DIR" && tar xzf "$BK/opt-nsd-igate.tar.gz" -C "$(dirname "$IGATE_DIR")" || die "не распаковалась программа ИШ из $BK"
|
||||
find "$HOME_DIR" -mindepth 1 -maxdepth 1 ! -name keymedia ! -name .cache -exec rm -rf {} + 2>/dev/null
|
||||
tar xzf "$BK/var-lib-igate.tar.gz" -C / || die "не распаковались данные ИШ из $BK"
|
||||
[ -f "$BK/$(basename "$UNIT")" ] && cp -a "$BK/$(basename "$UNIT")" "$UNIT"
|
||||
[ -d "$BK/$(basename "$UNIT").d" ] && { rm -rf "$UNIT.d"; cp -a "$BK/$(basename "$UNIT").d" "$UNIT.d"; }
|
||||
[ -f "$BK/$(basename "$WRAPPER")" ] && cp -a "$BK/$(basename "$WRAPPER")" "$WRAPPER"
|
||||
st db "возврат базы ИШ"
|
||||
runuser -u postgres -- dropdb --if-exists "$DB" && runuser -u postgres -- createdb -O "$SVC_USER" "$DB" || die "не пересоздана база ИШ"
|
||||
runuser -u postgres -- pg_restore -d "$DB" "$BK/igate-db.dump" || true
|
||||
psqlq -c "select to_regclass('public.parameters') is not null" | grep -q t || die "база ИШ не восстановилась из $BK/igate-db.dump"
|
||||
# пришедший с обновлением дистрибутив больше не ставить сам (иначе bj вернёт версию сразу); новая версия — снова автоматически
|
||||
dv=$(python3 -c "import json;print(json.load(open('/var/lib/bj/.bj/components.json')).get('igate-dist',{}).get('version',''))" 2>/dev/null)
|
||||
[ -n "$dv" ] && { printf '%s
|
||||
' "$dv" > /var/lib/bj/igate-autoupgrade-skip; chown bj:bj /var/lib/bj/igate-autoupgrade-skip 2>/dev/null; }
|
||||
st start "запуск ИШ $old"
|
||||
systemctl daemon-reload; systemctl restart igate || die "служба igate не запустилась"
|
||||
wait_engine 120 || die "ИШ $old запущен, но движок не перешёл в Running за 2 минуты. Журнал ИШ: $DATA_DIR/logs-svc/log.txt"
|
||||
st done "ИШ откатан с $cur к $old и работает" ;;
|
||||
|
||||
contour)
|
||||
contour=$(j contour); crypto=$(j crypto); dep=$(j deponent); prof=$(j profile)
|
||||
crypto=${crypto:-gost}
|
||||
|
||||
@@ -12,7 +12,7 @@ process_one(){
|
||||
quikexport-*) out=$(BJ_EXTRA="$extra" /usr/local/sbin/bj-quikexport-admin "${action#quikexport-}" "$staging" 2>&1) ;;
|
||||
component-install) out=$(/usr/local/sbin/bj-component-install "$staging" 2>&1) ;;
|
||||
# интеграционный шлюз НРД: состояние, установка, канал контура (TEST3 | боевой); параметры — JSON в extra
|
||||
igate-status|igate-install|igate-contour|igate-share) out=$(BJ_EXTRA="$extra" /usr/local/sbin/bj-igate-admin "${action#igate-}" 2>&1) ;;
|
||||
igate-status|igate-install|igate-contour|igate-share|igate-rollback) out=$(BJ_EXTRA="$extra" /usr/local/sbin/bj-igate-admin "${action#igate-}" 2>&1) ;;
|
||||
# датчик случайных чисел Валидаты: проверка и сеанс «двигайте мышью» (движения — из мастера bj)
|
||||
rng-status|rng-start|rng-cancel) out=$(/usr/local/sbin/bj-validata-rng "${action#rng-}" 2>&1) ;;
|
||||
# системные настройки сервера: серверы времени (NTP)
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
"version": "2026.10.21.6"
|
||||
},
|
||||
"bj-server": {
|
||||
"fingerprint": "98167dc3f6c196784867f7eb88e091c693b160277f09735971e44e2c18f21a61",
|
||||
"version": "2026.10.21.15"
|
||||
"fingerprint": "5617c24adb2d2392aecdfe6711bff54e8936688c249408c22042174511f258ba",
|
||||
"version": "2026.10.21.16"
|
||||
},
|
||||
"crypto-service.jar": {
|
||||
"fingerprint": "2c4fd536bc9b1c20c69a70e8dcd374a61847b263aeb2e474c45debb01fbd8233",
|
||||
|
||||
@@ -1 +1 @@
|
||||
107.0.930 996bcf9f8f0001dc0e73b9582a5ebc0fa05bda264bc8e8b1785d069ed07f13c3
|
||||
110.0.997 430934886e1ce1b10edba285615a0e65551514a6229f8439446344f9a6278b78
|
||||
|
||||
@@ -215,6 +215,16 @@ func registerIgateAdmin(mux *http.ServeMux, rc *RuntimeConfig) {
|
||||
defer cancel()
|
||||
jsonOut(w, opResult(runKeymediaOp(ctx, "igate-install", map[string]string{"extra": string(extra)})))
|
||||
})
|
||||
// откат ИШ к версии из последней резервной копии (её делает каждая установка/обновление)
|
||||
mux.HandleFunc("/admin/setup/igate/rollback", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
|
||||
defer cancel()
|
||||
jsonOut(w, opResult(runKeymediaOp(ctx, "igate-rollback", nil)))
|
||||
})
|
||||
// ход установки: этап, сообщение, журнал и сколько секунд идёт текущий этап (по времени записи файла)
|
||||
mux.HandleFunc("/admin/setup/igate/install-status", func(w http.ResponseWriter, r *http.Request) {
|
||||
raw, err := os.ReadFile(igateInstallStatusPath)
|
||||
@@ -461,12 +471,19 @@ func igateInstallDist(ctx context.Context) error {
|
||||
// igateAutoUpgrade — ИШ на сервере старее дистрибутива, пришедшего с обновлением bj: обновить (настройки,
|
||||
// каналы и база ИШ сохраняются; прежняя версия копируется в /var/backups). Вызывается после обновления bj
|
||||
// и при запуске bj-server (обновление ядра перезапускает его до того, как успел бы сработать первый вызов).
|
||||
// igateAutoUpgradeSkipPath — версия дистрибутива, с которой ИШ откатили (её автоматически не ставим).
|
||||
var igateAutoUpgradeSkipPath = "/var/lib/bj/igate-autoupgrade-skip"
|
||||
|
||||
func igateAutoUpgrade(ctx context.Context, rc *RuntimeConfig) {
|
||||
cur := ishInstalledVersion()
|
||||
_, dist := igateDistFile()
|
||||
if !igateInstalled() || cur == "" || dist == "" || !release.IsNewer(dist, cur) || igateInstallStatus().Busy {
|
||||
return
|
||||
}
|
||||
// ИШ откатили с этой версии вручную — сам не ставим, пока не придёт следующая
|
||||
if b, err := os.ReadFile(igateAutoUpgradeSkipPath); err == nil && strings.TrimSpace(string(b)) == dist {
|
||||
return
|
||||
}
|
||||
log.Printf("lk-gateway: ИШ %s старее проверенного дистрибутива %s — обновляю", cur, dist)
|
||||
if err := igateInstallDist(ctx); err != nil {
|
||||
raiseSystemAlert(rc, "ИШ не обновлён до "+dist, "Пришёл дистрибутив ИШ "+dist+", но обновление не запустилось: "+err.Error()+". Повторить — мастер, шаг «Шлюз НРД».")
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
<div id="ig-head" class="muted">Проверяю…</div>
|
||||
<p class="muted" style="font-size:12px;margin:4px 0 0">Версию ИШ проверяет ZETIT; новые приходят с обновлением bj.</p>
|
||||
<div id="ig-reinst" style="display:none;margin-top:10px"><button type="button" class="btn" id="ig-bnd">Установить ИШ</button> <span class="muted" id="ig-bnd-v" style="font-size:12.5px"></span></div>
|
||||
<div id="ig-rb" style="display:none;margin-top:8px"><button type="button" class="btn" id="ig-rb-btn" style="background:var(--card);color:var(--text);border:1px solid var(--border-strong,#c9cdd8)">Откатить ИШ к <span id="ig-rb-v"></span></button> <span class="muted" style="font-size:12.5px">вернуть версию, которая стояла до последнего обновления (программа, данные, база ИШ)</span></div>
|
||||
<ol class="ig-steps" id="ig-steps" hidden></ol>
|
||||
<div id="ig-out" style="margin-top:8px;font-size:13px"></div>
|
||||
<details id="ig-logbox" hidden style="margin-top:6px;font-size:12.5px"><summary style="cursor:pointer;color:var(--accent)">Журнал установки</summary>
|
||||
@@ -250,6 +251,7 @@
|
||||
if(!d.ok){ head.innerHTML=bad(d.error); return; }
|
||||
var ri=document.getElementById('ig-reinst'), bb=document.getElementById('ig-bnd'), bv=document.getElementById('ig-bnd-v');
|
||||
var running=d.installed&&d.engine==='Running';
|
||||
var rb=document.getElementById('ig-rb'); if(rb){ var can=d.rollback&&d.rollback!==d.version; rb.style.display=can?'block':'none'; if(can) document.getElementById('ig-rb-v').textContent=d.rollback; }
|
||||
if(!d.installed) head.innerHTML=bad('ИШ на этом сервере не установлен');
|
||||
else head.innerHTML=(running?ok('ИШ '+d.version+' установлен и работает'):bad('ИШ '+d.version+' установлен, но не работает: движок '+(d.engine||'не отвечает')+', служба '+d.service));
|
||||
if(d.busy) head.innerHTML='<span style="color:var(--accent)">⟳ Шлюз перезапускается — '+esc(d.busy)+'; состояние — последнее известное</span>';
|
||||
@@ -347,6 +349,9 @@
|
||||
if(Date.now()-t0>2700000){ clearInterval(iv); clearInterval(tick); } },3000); }
|
||||
document.getElementById('ig-bnd').onclick=function(){ var p=new URLSearchParams(); p.set('bundled','1');
|
||||
out.textContent='Запускаю…'; cur={key:'',since:0,s:null}; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
document.getElementById('ig-rb-btn').onclick=function(){ var v=document.getElementById('ig-rb-v').textContent;
|
||||
if(!confirm('Откатить ИШ к версии '+v+'? Шлюз остановится на 1–3 минуты; программа, данные и база ИШ вернутся к состоянию до обновления. Пришедшую версию bj сам ставить больше не будет, пока не выйдет следующая.')) return;
|
||||
out.textContent='Запускаю откат…'; cur={key:'',since:0,s:null}; post('/admin/setup/igate/rollback',new URLSearchParams()).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
if(document.getElementById('ig-dl')) document.getElementById('ig-dl').onclick=function(){ var p=new URLSearchParams(); p.set('version',document.getElementById('ig-ver').value.trim());
|
||||
out.textContent='Запускаю…'; cur={key:'',since:0,s:null}; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
if(document.getElementById('ig-up')) document.getElementById('ig-up').onclick=function(){ var f=document.getElementById('ig-file').files[0]; if(!f){ out.textContent='Выберите файл igate-…-amd64.zip'; return; }
|
||||
|
||||
Reference in New Issue
Block a user