diff --git a/internal/lkgateway/updater.go b/internal/lkgateway/updater.go index c9e8f63..af16a59 100644 --- a/internal/lkgateway/updater.go +++ b/internal/lkgateway/updater.go @@ -279,15 +279,28 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro progressNote(strings.TrimPrefix(unlicensedNote(off), "; ")) progressStage(2, "Скачивание файлов") stopWatch := progressWatchDir(staging, total) + refused := false for _, c := range selected { + skip := false for _, a := range m.Artifacts { if a.Name == c.Name { if _, err := cl.DownloadArtifact(ctx, a, staging); err != nil { + // Модуль сняли с лицензии, а bj ещё помнит прежний её состав (узнаёт при продлении): + // сервер обновлений файл не отдаёт — пропускаем модуль, остальное ставим. + if !c.Core && c.Feature != "updates" && strings.Contains(err.Error(), "HTTP 403") { + off = append(off, "«"+c.Title+"»") + refused, skip = true, true + _ = os.Remove(filepath.Join(staging, filepath.Base(a.File))) + continue + } stopWatch() return "", fmt.Errorf("скачивание %s: %w", c.Name, err) } } } + if skip { + continue + } req.Names = append(req.Names, c.Name) if c.New { req.New = append(req.New, c.Name) @@ -295,6 +308,19 @@ func (u *Updater) applyUpdate(ctx context.Context, names []string) (string, erro list = append(list, c.Name+" "+c.Available) } stopWatch() + if refused { + // состав лицензии устарел — обновляем сразу, чтобы разделы снятых модулей пропали + lctx, lcancel := context.WithTimeout(ctx, 30*time.Second) + if err := LicenseRenew(lctx, u.rc); err != nil { + log.Printf("lk-gateway: продление лицензии после отказа в модуле: %v", err) + } + lcancel() + progressNote(strings.TrimPrefix(unlicensedNote(off), "; ")) + if len(req.Names) == 0 { + _ = os.RemoveAll(staging) + return "обновлять нечего: компоненты лицензии актуальны (релиз " + m.Version + ")" + unlicensedNote(off), nil + } + } rb, _ := json.Marshal(req) if err := os.WriteFile(filepath.Join(staging, "request.json"), rb, 0o640); err != nil { return "", err