Мастер по порядку без пропусков; шаг 5 — ключ организации и автообновление сертификатов НРД; в образ кладутся все файлы ядра

- мастер запоминает пройденный шаг и продолжает со следующего, выполненные шаги показываются с пояснением;
- шаг 5: мастер установки ключа + описание автоматического ведения сертификатов НРД (контуры не смешиваются);
- образ: bj-installer и crypto-service.jar в комплекте; установщик пропускает недостающие файлы, кроме ядра.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-09-24 18:10:10 +03:00
parent 9ed5b037a8
commit ce98ca137f
4 changed files with 55 additions and 91 deletions
+26 -44
View File
@@ -238,30 +238,21 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
d.Done.NSD = s.NSD.IGWBaseURL != "" && s.NSD.Profile != ""
d.Done.TestRun = s.LastTest != nil || (!d.DevMode && d.Done.NSD) // вне режима разработки тестовой заявки нет
// Определяем текущий шаг.
step := 1
// Мастер идёт по порядку: каждый шаг показывается, даже если он уже выполнен (установщиком,
// лицензией) — на нём написано, что сделано, и пользователь сам нажимает «Далее». Без ?step
// продолжаем со следующего за последним пройденным шагом.
progress := wizardProgress()
step := progress + 1
if v := r.URL.Query().Get("step"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n >= 1 && n <= 7 {
step = n
if n-1 > progress {
setWizardProgress(n - 1)
}
}
} else {
// Авто: первый незавершённый.
switch {
case !d.Done.License:
step = 1
case !d.Done.Postgres:
step = 2
case !d.Done.Depo:
step = 3
case !d.Done.Crypto:
step = 4
case !d.Done.Certs:
step = 5
case !d.Done.NSD:
step = 6
default:
step = 7
}
}
if step > 7 {
step = 7
}
d.Step = step
if step == 1 && d.Done.License {
@@ -273,35 +264,26 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
}
cancel()
}
d.AutoDone = wizardAutoDone(&d)
render(w, h.tpl.a.wizard, d)
}
// wizardAutoDone — пояснения к шагам до текущего, которые уже выполнены: мастер переходит к первому
// незавершённому шагу сам, и без пояснения непонятно, почему предыдущие отмечены галочкой.
func wizardAutoDone(d *WizardData) []string {
var out []string
if d.Step > 1 && d.Done.License {
out = append(out, "1. Лицензия — активирована: "+d.Lic.Tenant+".")
// wizardProgressFile — номер последнего пройденного шага мастера (переход «Далее» на шаг N
// означает, что шаги до N пройдены).
const wizardProgressFile = "/var/lib/bj/.bj/wizard-progress"
func wizardProgress() int {
b, err := os.ReadFile(wizardProgressFile)
if err != nil {
return 0
}
if d.Step > 2 && d.Done.Postgres {
t := "2. База bj — готова"
if d.PGSummary != "" {
t += " (" + d.PGSummary + ")"
}
out = append(out, t+": её создал установщик, настраивать ничего не нужно.")
n, _ := strconv.Atoi(strings.TrimSpace(string(b)))
return n
}
func setWizardProgress(n int) {
if err := os.WriteFile(wizardProgressFile, []byte(strconv.Itoa(n)+"\n"), 0o600); err != nil {
log.Printf("wizard: прогресс мастера не сохранён: %v", err)
}
if d.Step > 3 && d.Done.Depo {
if !d.DepoLicensed {
out = append(out, "3. Учёт DEPO — не нужен: модуль обмена с DEPO и QUIK не входит в лицензию. Когда модуль добавят, шаг станет доступен.")
} else {
out = append(out, "3. Учёт DEPO — подключение уже сохранено ("+d.Settings.Fancy.Server+").")
}
}
if d.Step > 4 && d.Done.Crypto && d.ValidataVer != "" {
out = append(out, "4. Валидата — установлена вместе с bj (версия "+d.ValidataVer+").")
}
return out
}
// dsnSummary — «host:port, база name» из строки подключения PostgreSQL, без логина и пароля.