9737c787f9
Инфраструктура M2M (живой обмен с НРД через ИШ): - обработка M2MTransferResponse: ERROR(M2Mxx) → заявка Отклонена, сохранение ответа; INFO → ждём Decision; идемпотентность поллера - fallback-корреляция ответов с нулевым GUID (M2M14/M2M17) по FIFO - сырой XML ответа НРД в карточке заявки (для пересылки в ТП) - тестовый пакет роботу приведён к эталону m2m_robot_samples (CostInfo=Yes, 4 бумаги, IsolationStatus, DocumentSeries=сценарий); override паспорта - редирект из теста сразу в карточку заявки Мастер установки ключа Валидаты на флешку (admin/setup/keywizard): - пошаговый: загрузка .7z+пароль → выбор флешки → запись → справочник сертификатов (CRL) → перезапуск+проверка ИШ → готово - привилегированный воркер (bj-keymedia) в host-namespace через файл-обмен, bj-server остаётся в песочнице - сохранение структуры профиля архива (spr<N>), перечисление съёмных USB Прочее: - пакет-доказательство для ТП НРД + форма регистрации участника M2M - эталонные образцы робота (DOC/m2m_robot_samples) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
3.6 KiB
Go
85 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Step — описание одного шага установки. Run выполняет шаг, может
|
|
// проверить idempotency и вернуть Skipped. Логи прокидываются через
|
|
// log-функцию, которая публикует event в SSE.
|
|
type Step struct {
|
|
ID string
|
|
Title string
|
|
Run func(s *State, log func(string)) (StepStatus, error)
|
|
}
|
|
|
|
// buildStepList — фиксированный порядок шагов установки. Соответствует
|
|
// install-validata.sh + установка bj-server/crypto-service/ИШ. Меняется
|
|
// атомарно (если что-то добавляется — добавляем сюда).
|
|
func buildStepList() []StepState {
|
|
steps := allSteps()
|
|
out := make([]StepState, len(steps))
|
|
for i, s := range steps {
|
|
out[i] = StepState{ID: s.ID, Title: s.Title, Status: StepPending}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func allSteps() []Step {
|
|
return []Step{
|
|
{ID: "deps", Title: "Установка системных зависимостей", Run: stepInstallDeps},
|
|
{ID: "validata-deb", Title: "Установка пакетов Валидаты (zpki + zsdk)", Run: stepInstallValidataDebs},
|
|
{ID: "execstack", Title: "execstack -c libvdcsp.so", Run: stepExecstack},
|
|
{ID: "bj-user", Title: "Создание пользователя bj и каталогов", Run: stepCreateBJUser},
|
|
{ID: "pcscd-dropin", Title: "Настройка pcscd (always-on)", Run: stepPcscdDropin},
|
|
{ID: "bj-crypto-dropins", Title: "Drop-ins для bj-crypto sandbox", Run: stepBJCryptoDropins},
|
|
{ID: "bj-server-dropin", Title: "Drop-in для bj-server", Run: stepBJServerDropin},
|
|
{ID: "spki-ini", Title: "Создание spki.ini", Run: stepSPKIIni},
|
|
{ID: "pki1-prep", Title: "Подготовка pki1.conf для bj", Run: stepPKI1Prep},
|
|
{ID: "usb-mount", Title: "Авто-mount USB через udev + systemd", Run: stepUSBMount},
|
|
{ID: "bj-server-binary", Title: "Установка bj-server бинаря в /opt/bj/", Run: stepInstallBJServer},
|
|
{ID: "crypto-jar", Title: "Установка crypto-service.jar", Run: stepInstallCryptoJar},
|
|
{ID: "systemd-units", Title: "systemd unit bj-crypto.service + bj-server.service", Run: stepSystemdUnits},
|
|
{ID: "ish-install", Title: "Установка ИШ НРД (если есть .deb)", Run: stepInstallISH},
|
|
{ID: "save-config", Title: "Сохранение setup.json", Run: stepSaveConfig},
|
|
{ID: "systemd-start", Title: "Запуск сервисов (pcscd, bj-crypto, bj-server)", Run: stepStartServices},
|
|
{ID: "health", Title: "Финальный health-check", Run: stepHealthCheck},
|
|
}
|
|
}
|
|
|
|
// runInstallation — основной цикл установки. Перебирает шаги, обновляет
|
|
// статусы через State, прокидывает логи в SSE. Останавливается при первой
|
|
// ошибке (UI покажет какой шаг + сообщение).
|
|
func runInstallation(s *State) error {
|
|
steps := allSteps()
|
|
for _, step := range steps {
|
|
now := time.Now()
|
|
s.updateStep(step.ID, func(ss *StepState) {
|
|
ss.Status = StepRunning
|
|
ss.Started = &now
|
|
ss.Message = ""
|
|
})
|
|
|
|
logFn := func(line string) {
|
|
s.updateStep(step.ID, func(ss *StepState) {
|
|
ss.Message = line
|
|
})
|
|
}
|
|
|
|
status, err := step.Run(s, logFn)
|
|
finished := time.Now()
|
|
s.updateStep(step.ID, func(ss *StepState) {
|
|
ss.Status = status
|
|
ss.Finished = &finished
|
|
if err != nil {
|
|
ss.Message = err.Error()
|
|
}
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("шаг %q: %w", step.Title, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|