diff --git a/cmd/bj-installer/main.go b/cmd/bj-installer/main.go
index 4d1ce9e..36ff6d2 100644
--- a/cmd/bj-installer/main.go
+++ b/cmd/bj-installer/main.go
@@ -81,6 +81,8 @@ func main() {
switch os.Args[1] {
case "install":
cmdInstall(os.Args[2:])
+ case "refresh-system":
+ os.Exit(refreshSystem())
case "first-run-code":
cmdFirstRunCode(os.Args[2:])
case "version":
@@ -93,6 +95,7 @@ func main() {
func usage() {
fmt.Fprintln(os.Stderr, "bj-installer install --code BJ-XXXX-XXXX-XXXX [--server https://lic.zetit.ru] [--channel stable] [--dry-run]")
fmt.Fprintln(os.Stderr, "bj-installer first-run-code")
+ fmt.Fprintln(os.Stderr, "bj-installer refresh-system (переписать службы и скрипты из этой версии установщика)")
fmt.Fprintln(os.Stderr, "bj-installer version")
os.Exit(2)
}
@@ -742,6 +745,26 @@ func (in *installer) stepServices() (string, error) {
return strings.Join(files, ", ") + "; криптосервис включается после настройки ключей в bj", nil
}
+// refreshSystem — «bj-installer refresh-system»: переписать службы systemd и служебные скрипты
+// из этой версии установщика (вызывается root-установщиком обновлений после обновления самого
+// bj-installer). Работающие службы не перезапускаются: ядро перезапустит обновление, а служба
+// root-операций bj-keymedia — через минуту, когда обновление, которое она выполняет, закончится.
+func refreshSystem() int {
+ if os.Geteuid() != 0 {
+ fmt.Fprintln(os.Stderr, "refresh-system: нужны права root")
+ return 1
+ }
+ in := &installer{}
+ msg, err := in.stepServices()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "refresh-system:", err)
+ return 1
+ }
+ _, _ = run("systemd-run", "--on-active=60", "--unit=bj-keymedia-refresh", "systemctl", "try-restart", "bj-keymedia.service")
+ fmt.Println("системные файлы обновлены:", msg)
+ return 0
+}
+
func (in *installer) stepFirstRun() (string, error) {
code, err := in.newFirstRunCode()
if err != nil {
diff --git a/internal/lkgateway/setup.go b/internal/lkgateway/setup.go
index 4d32867..dab39bf 100644
--- a/internal/lkgateway/setup.go
+++ b/internal/lkgateway/setup.go
@@ -169,10 +169,11 @@ type WizardData struct {
Lic LicenseStatus
DepoLicensed bool
DepoDB string
- ValidataVer string // версия установленной «Валидаты Клиент L» (пусто — не установлена)
- CryptoSvc string // состояние службы bj-crypto (systemctl is-active)
- PGSummary string // куда подключена база bj, без пароля
- AutoDone []string // шаги до текущего, уже выполненные без участия пользователя, — с пояснением
+ ValidataVer string // версия установленной «Валидаты Клиент L» (пусто — не установлена)
+ CryptoSvc string // состояние службы bj-crypto (systemctl is-active)
+ PGSummary string // куда подключена база bj, без пароля
+ Update *UpdateStatus // шаг 1: есть ли на сервере обновлений версия новее, чем в образе
+ AutoDone []string // шаги до текущего, уже выполненные без участия пользователя, — с пояснением
Certs []cryptocli.Certificate
Flash string
Done struct {
@@ -263,6 +264,15 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
}
}
d.Step = step
+ if step == 1 && d.Done.License {
+ // Образ ставит ядро той версии, с которой собран; всё, что вышло позже (исправления ядра,
+ // установщика и служб), приезжает обновлением — предлагаем его сразу после ввода ключа.
+ ctx, cancel := context.WithTimeout(r.Context(), 8*time.Second)
+ if st, err := NewUpdater(h.rc).CheckForUpdate(ctx); err == nil {
+ d.Update = &st
+ }
+ cancel()
+ }
d.AutoDone = wizardAutoDone(&d)
render(w, h.tpl.a.wizard, d)
}
diff --git a/internal/lkgateway/updater.go b/internal/lkgateway/updater.go
index 2774cb5..3782b2c 100644
--- a/internal/lkgateway/updater.go
+++ b/internal/lkgateway/updater.go
@@ -195,7 +195,7 @@ func (u *Updater) ApplyUpdate(ctx context.Context, names []string) (string, erro
if installerOutdated {
kept := selected[:0]
for _, c := range selected {
- if c.New {
+ if c.New || c.Name == "bj-installer" { // bj-installer прежний установщик обновлений не знает
deferred = append(deferred, c.Name)
continue
}
@@ -269,11 +269,24 @@ func (u *Updater) allowed(feature string) bool { return moduleAllowed(u.rc, feat
// этих модулей в bj не работают. Раз за запуск bj-server; ошибки — только в журнал и «Последнюю проверку».
func (u *Updater) ensureSplitModules(ctx context.Context) {
var names []string
- for _, c := range release.Plan("", nil, release.LoadInstalled(release.InstalledFile), BuildVersion) {
+ installed := release.LoadInstalled(release.InstalledFile)
+ for _, c := range release.Plan("", nil, installed, BuildVersion) {
if c.FromCore && !c.Present && u.allowed(c.Feature) {
names = append(names, c.Name)
}
}
+ // bj-installer обновлением ещё не ставился (сервер с образа или обновлён прежним установщиком
+ // обновлений): ставим сразу — с ним приезжают свежие службы и скрипты. Только если на сервере
+ // обновлений он новее, иначе ApplyUpdate вернёт «обновление не требуется» — это не ошибка.
+ if _, ok := installed["bj-installer"]; !ok && licenseStatus(u.rc).AllowsUpdates {
+ if st, err := u.CheckForUpdate(ctx); err == nil {
+ for _, c := range st.Components {
+ if c.Name == "bj-installer" && c.Update {
+ names = append(names, c.Name)
+ }
+ }
+ }
+ }
if len(names) == 0 {
return
}
diff --git a/internal/lkgateway/web/templates/admin_wizard.html b/internal/lkgateway/web/templates/admin_wizard.html
index d59a130..3f62de2 100644
--- a/internal/lkgateway/web/templates/admin_wizard.html
+++ b/internal/lkgateway/web/templates/admin_wizard.html
@@ -55,6 +55,16 @@
Зачем. От лицензии зависят модули (обмен с DEPO и QUIK, личный кабинет, НПР/УДС) и получение обновлений: bj скачает и поставит модули, входящие в лицензию, автоматически.
Где взять. Портал клиента lic.zetit.ru/portal или письмо от ZETIT.
{{if .Done.License}}
✓ Лицензия активна: {{.Lic.Tenant}}, план {{.Lic.Plan}}, модули: {{if .Lic.Features}}{{range $i, $f := .Lic.Features}}{{if $i}}, {{end}}{{$f}}{{end}}{{else}}только ядро{{end}}; {{.Lic.Message}}
{{end}} + {{with .Update}}{{if .HasUpdate}} +Есть обновление: версия {{.Available}}
+Образ установил ту версию bj, с которой был собран. На сервере лицензий есть более новая — с исправлениями ядра, установщика и служб. Поставьте её сейчас, до настройки: bj перезапустится примерно на 10 секунд, затем обновите страницу.
{{.Message}}
✓ Установлена последняя версия bj ({{.Available}}).
{{end}}{{end}}