«Подготовка модулей» между ключом продукта и мастером: bj узнаёт состав лицензии, ставит модули, которые в неё входят (из комплекта образа, если там тот же выпуск, — без скачивания), запускает их службы и открывает мастер; после активации ключа и при изменении состава лицензии модули ставятся сразу, а не при следующем запуске bj
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/release"
|
||||
@@ -340,6 +341,10 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
|
||||
skip := false
|
||||
for _, a := range m.Artifacts {
|
||||
if a.Name == c.Name {
|
||||
if fromLocalBundle(a, staging) {
|
||||
log.Printf("lk-gateway: %s %s — из комплекта образа, без скачивания", c.Name, pickVersion(c.Available))
|
||||
continue
|
||||
}
|
||||
if _, err := cl.DownloadArtifact(ctx, a, staging); err != nil {
|
||||
// Модуль сняли с лицензии, а bj ещё помнит прежний её состав (узнаёт при продлении):
|
||||
// сервер обновлений файл не отдаёт — пропускаем модуль, остальное ставим.
|
||||
@@ -408,10 +413,14 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
|
||||
// allowed — разрешён ли лицензией признак компонента.
|
||||
func (u *Updater) allowed(feature string) bool { return moduleAllowed(u.rc, feature) }
|
||||
|
||||
var splitModulesMu sync.Mutex
|
||||
|
||||
// ensureSplitModules — выделенные из ядра модули, которые входят в лицензию, но ещё не стоят на этом
|
||||
// сервере (например, ядро обновилось прежним установщиком), ставятся сами: без своих служб разделы
|
||||
// этих модулей в bj не работают. Раз за запуск bj-server; ошибки — только в журнал и «Последнюю проверку».
|
||||
func (u *Updater) ensureSplitModules(ctx context.Context) {
|
||||
func (u *Updater) ensureSplitModules(ctx context.Context) (string, error) {
|
||||
splitModulesMu.Lock() // запуск bj, активация ключа и «Подготовка модулей» — по очереди: второй увидит, что всё уже стоит
|
||||
defer splitModulesMu.Unlock()
|
||||
var names []string
|
||||
installed := release.LoadInstalled(release.InstalledFile)
|
||||
for _, c := range release.Plan("", nil, installed, BuildVersion) {
|
||||
@@ -432,7 +441,7 @@ func (u *Updater) ensureSplitModules(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
if len(names) == 0 {
|
||||
return
|
||||
return "", nil
|
||||
}
|
||||
cctx, cancel := context.WithTimeout(ctx, 10*time.Minute)
|
||||
defer cancel()
|
||||
@@ -446,6 +455,36 @@ func (u *Updater) ensureSplitModules(ctx context.Context) {
|
||||
cfg := u.rc.Snapshot().Update
|
||||
cfg.LastResult, cfg.LastCheck = msg, time.Now().UTC()
|
||||
_ = u.rc.SaveUpdateSettings(cfg)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// localBundleDir — комплект компонентов, с которого сервер ставился с образа (bj-firstboot).
|
||||
var localBundleDir = "/var/lib/bj/bundle"
|
||||
|
||||
// fromLocalBundle — файл компонента из комплекта образа, если это тот же файл, что в выпуске (совпадает
|
||||
// sha256): модуль, который уже лежит на диске, не качается заново — после ввода ключа он ставится сразу.
|
||||
func fromLocalBundle(a release.Artifact, staging string) bool {
|
||||
src := filepath.Join(localBundleDir, filepath.Base(a.File))
|
||||
sum, _, err := release.HashFile(src)
|
||||
if err != nil || !strings.EqualFold(sum, a.SHA256) {
|
||||
return false
|
||||
}
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer in.Close()
|
||||
dst := filepath.Join(staging, filepath.Base(a.File))
|
||||
out, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o640)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if _, err := io.Copy(out, in); err != nil {
|
||||
out.Close()
|
||||
_ = os.Remove(dst)
|
||||
return false
|
||||
}
|
||||
return out.Close() == nil
|
||||
}
|
||||
|
||||
// updateComponentRows — компоненты для раздела «Обновления» без обращения к артефактории:
|
||||
@@ -536,7 +575,7 @@ func (u *Updater) updateLoop(ctx context.Context) {
|
||||
case <-time.After(time.Minute):
|
||||
cleanupStaging(time.Hour)
|
||||
enforceModuleLicense(ctx, u.rc)
|
||||
u.ensureSplitModules(ctx)
|
||||
_, _ = u.ensureSplitModules(ctx)
|
||||
check()
|
||||
}
|
||||
for {
|
||||
|
||||
Reference in New Issue
Block a user