Обновление: модули вне лицензии пропускаются с пояснением «не входит в лицензию — свяжитесь с ZETIT», а не срывают обновление

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 22:17:29 +03:00
parent f1df6b529b
commit 86c48288a0
3 changed files with 50 additions and 2 deletions
+40
View File
@@ -97,6 +97,7 @@ func (u *Updater) CheckForUpdate(ctx context.Context) (UpdateStatus, error) {
st.Available, st.Notes = m.Version, m.Notes
st.Components = release.Plan("", m, release.LoadInstalled(release.InstalledFile), BuildVersion)
release.MarkSplitModules(st.Components, u.allowed)
off := markUnlicensed(st.Components, u.allowed)
var upd []string
avail := map[string]string{}
for _, c := range st.Components {
@@ -115,10 +116,39 @@ func (u *Updater) CheckForUpdate(ctx context.Context) (UpdateStatus, error) {
} else {
st.Message = "все установленные компоненты актуальны (релиз " + m.Version + ")"
}
st.Message += unlicensedNote(off)
u.saveCheckResult(st, avail)
return st, nil
}
// markUnlicensed — модули, установленные на сервере, но снятые с лицензии: не обновляются (сервер
// обновлений их файлы не отдаёт), в списке — с пояснением. Возвращает названия таких модулей.
func markUnlicensed(states []release.ComponentState, allowed func(string) bool) []string {
var off []string
for i := range states {
c := &states[i]
if c.Core || c.Feature == "" || c.Feature == "updates" || allowed(c.Feature) {
continue
}
c.Update, c.New = false, false
if c.Present {
c.Blocked = "не входит в лицензию — модуль отключён и не обновляется; чтобы подключить, свяжитесь с ZETIT"
off = append(off, "«"+c.Title+"»")
}
}
return off
}
func unlicensedNote(off []string) string {
if len(off) == 0 {
return ""
}
if len(off) == 1 {
return "; модуль " + off[0] + " не входит в лицензию — отключён и не обновлялся; чтобы подключить, свяжитесь с ZETIT"
}
return "; модули " + strings.Join(off, ", ") + " не входят в лицензию — отключены и не обновлялись; чтобы подключить, свяжитесь с ZETIT"
}
// updateChannel — канал обновлений установки (пусто = stable).
func updateChannel(s UpdateSettings) string {
if c := strings.TrimSpace(s.Channel); c != "" {
@@ -174,6 +204,7 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
}
plan := release.Plan("", m, release.LoadInstalled(release.InstalledFile), BuildVersion)
release.MarkSplitModules(plan, u.allowed)
off := markUnlicensed(plan, u.allowed)
want := map[string]bool{}
for _, n := range names {
want[n] = true
@@ -184,11 +215,16 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
case len(want) > 0 && !want[c.Name]:
case c.Update:
selected = append(selected, c)
case want[c.Name] && c.Blocked != "":
return "", fmt.Errorf("%s: %s", c.Title, c.Blocked)
case want[c.Name]:
return "", fmt.Errorf("%s: обновление не требуется (установлена %s, в релизе %s)", c.Title, pickVersion(c.Installed), pickVersion(c.Available))
}
}
if len(selected) == 0 {
if len(off) > 0 {
return "обновлять нечего: компоненты лицензии актуальны (релиз " + m.Version + ")" + unlicensedNote(off), nil
}
return "", fmt.Errorf("нечего обновлять: все установленные компоненты актуальны (релиз %s)", m.Version)
}
// Прежний root-установщик не умеет впервые ставить выделенные из ядра модули: пока он сам не
@@ -240,6 +276,7 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
progressTarget(c.Available)
}
}
progressNote(strings.TrimPrefix(unlicensedNote(off), "; "))
progressStage(2, "Скачивание файлов")
stopWatch := progressWatchDir(staging, total)
for _, c := range selected {
@@ -282,6 +319,7 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro
if len(deferred) > 0 {
msg += "; модули " + strings.Join(deferred, ", ") + " будут установлены после перезапуска bj-server новым установщиком"
}
msg += unlicensedNote(off)
return msg, nil
}
@@ -355,6 +393,7 @@ func updateComponentRows(rc *RuntimeConfig) ([]release.ComponentState, bool) {
}
}
release.MarkSplitModules(out, func(f string) bool { return moduleAllowed(rc, f) })
markUnlicensed(out, func(f string) bool { return moduleAllowed(rc, f) })
// Последняя проверка не удалась — предлагать установку по старым данным нельзя:
// кнопка ушла бы в тот же отказ. Показываем причину и просим проверить заново.
if updateResultFailed(set.LastResult) {
@@ -475,6 +514,7 @@ func (u *Updater) applyBundle(ctx context.Context, zipPath string) (string, erro
}
plan := release.Plan("", m, release.LoadInstalled(release.InstalledFile), BuildVersion)
release.MarkSplitModules(plan, u.allowed)
markUnlicensed(plan, u.allowed)
var req struct {
Names []string `json:"names"`
New []string `json:"new,omitempty"`