feat(update): независимые обновления компонентов bj
- internal/release/components.go: список компонентов (ядро bj-server, криптосервис, bj-lk, bj-npr, bj-quikexport) с путём и службой, установленные версии в components.json, расчёт обновлений по версии каждого файла и sha256 (без отката, модули — только если уже установлены на сервере) - cmd/bj-component-install: root-установщик — сам перепроверяет подпись манифеста ключом /etc/bj/update.pub и sha256, копия прежнего файла, перезапуск только затронутых служб - updater: bj-server (без прав root) скачивает в update-staging и передаёт установку root-воркеру (действие component-install); установка в фоне - настройки: таблица компонентов с версиями, «Обновить» и «Обновить всё» - bj-release: версия файла из <файл>.version; bj-keymedia-worker: component-install Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/release"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -291,7 +292,9 @@ type SetupData struct {
|
||||
ReadyCount int
|
||||
TotalCount int
|
||||
Certificates []cryptocli.Certificate
|
||||
CurrentVersion string // версия bj-server (для раздела «Обновления»)
|
||||
CurrentVersion string // версия bj-server (для раздела «Обновления»)
|
||||
Components []release.ComponentState // компоненты и их версии (раздел «Обновления»)
|
||||
UpdatesAvailable bool
|
||||
License LicenseStatus // статус лицензии
|
||||
Health []HealthStatus // здоровье фоновых компонентов
|
||||
AdvancedUnlocked bool // открыты ли перспективные модули (QUIK, Fancy)
|
||||
@@ -338,8 +341,11 @@ func (h *setupHandlers) renderSetup(w http.ResponseWriter, req *http.Request, fl
|
||||
ready++
|
||||
}
|
||||
}
|
||||
comps, anyUpdate := updateComponentRows(h.rc)
|
||||
data := SetupData{
|
||||
page: nowPage("Настройка", "setup"),
|
||||
Components: comps,
|
||||
UpdatesAvailable: anyUpdate,
|
||||
Settings: s,
|
||||
Readiness: r,
|
||||
ReadyCount: ready,
|
||||
@@ -1225,11 +1231,27 @@ func (h *setupHandlers) applyUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if err := NewUpdater(h.rc).ApplyUpdate(r.Context()); err != nil {
|
||||
setupFlash(w, r, "Обновление не применено: "+err.Error())
|
||||
return
|
||||
_ = r.ParseForm()
|
||||
names := r.Form["component"]
|
||||
rc := h.rc
|
||||
// В фоне: при обновлении ядра bj-server перезапустится раньше, чем придёт ответ установщика.
|
||||
go func() {
|
||||
msg, err := NewUpdater(rc).ApplyUpdate(context.Background(), names)
|
||||
cfg := rc.Snapshot().Update
|
||||
if err != nil {
|
||||
msg = "Обновление не применено: " + err.Error()
|
||||
} else {
|
||||
msg = "Обновление: " + msg
|
||||
}
|
||||
log.Printf("lk-gateway: %s", msg)
|
||||
cfg.LastResult, cfg.LastCheck = msg, time.Now().UTC()
|
||||
_ = rc.SaveUpdateSettings(cfg)
|
||||
}()
|
||||
what := "всех компонентов с новой версией"
|
||||
if len(names) > 0 {
|
||||
what = strings.Join(names, ", ")
|
||||
}
|
||||
setupFlash(w, r, "Обновление скачано и применено — bj-server перезапускается, обновите страницу через 10 секунд")
|
||||
setupFlash(w, r, "Обновление "+what+" запущено: файлы скачиваются и проверяются, затем перезапускаются службы. Итог — в строке «Последняя проверка» через минуту; при обновлении ядра страница временно не отвечает.")
|
||||
}
|
||||
|
||||
// runTestClaim делает CreateClaim + ждёт финального состояния через GetClaim.
|
||||
|
||||
Reference in New Issue
Block a user