feat(update): обновления с сервера лицензий по лицензии установки
- по умолчанию https://lic.zetit.ru/updates; клиент артефактории передаёт лицензионный токен установки (Authorization: Bearer), сервер отдаёт модули по признакам лицензии - компоненты получили признак лицензии (ядро и криптосервис — updates, ЛК — web-cabinet, НПР — npr, экспорт QUIK — quik-export) - в bj зашит открытый ключ подписи релизов (закрытый хранится вне сервера лицензий) - проверено сквозной установкой bj-lk 0.2.0 из канала beta Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,15 @@ type Client struct {
|
||||
Channel string // "stable" | "beta"
|
||||
Pub ed25519.PublicKey // публичный ключ издателя (зашит в bj-server)
|
||||
HTTP *http.Client
|
||||
// Token — лицензионный токен установки (Authorization: Bearer). Сервер обновлений на
|
||||
// lic.zetit.ru отдаёт файлы только действующим лицензиям, модули — по признакам лицензии.
|
||||
Token string
|
||||
}
|
||||
|
||||
func (c *Client) authorize(req *http.Request) {
|
||||
if c.Token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token)
|
||||
}
|
||||
}
|
||||
|
||||
// NewClient собирает клиент. pubB64 — публичный ключ в base64 (зашитый).
|
||||
@@ -51,13 +60,15 @@ func (c *Client) FetchSigned(ctx context.Context) (*SignedManifest, *Manifest, e
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
c.authorize(req)
|
||||
resp, err := c.HTTP.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("release: запрос манифеста: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, nil, fmt.Errorf("release: манифест HTTP %d", resp.StatusCode)
|
||||
msg, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
|
||||
return nil, nil, fmt.Errorf("release: манифест HTTP %d: %s", resp.StatusCode, strings.TrimSpace(string(msg)))
|
||||
}
|
||||
var sm SignedManifest
|
||||
if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&sm); err != nil {
|
||||
@@ -76,13 +87,15 @@ func (c *Client) DownloadArtifact(ctx context.Context, a Artifact, destDir strin
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.authorize(req)
|
||||
resp, err := c.HTTP.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("release: скачивание %s: %w", a.Name, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("release: %s HTTP %d", a.Name, resp.StatusCode)
|
||||
msg, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
|
||||
return "", fmt.Errorf("release: %s HTTP %d: %s", a.Name, resp.StatusCode, strings.TrimSpace(string(msg)))
|
||||
}
|
||||
|
||||
tmp, err := os.CreateTemp(destDir, "."+a.File+".dl-*")
|
||||
|
||||
@@ -21,15 +21,17 @@ type Component struct {
|
||||
Unit string // служба systemd, перезапускаемая после установки ("" — без перезапуска)
|
||||
Exec bool // исполняемый файл
|
||||
Core bool // ядро: ставится всегда; модули — только если уже установлены на этом сервере
|
||||
// Feature — признак лицензии, без которого сервер обновлений не отдаёт файл компонента.
|
||||
Feature string
|
||||
}
|
||||
|
||||
// Components — все компоненты bj. Порядок — порядок показа и установки (ядро перезапускается последним).
|
||||
var Components = []Component{
|
||||
{Name: "bj-server", Title: "Ядро bj: переводы M2M, DEPO, QUIK МНП, ЛК ЕСИА", Path: "/opt/bj/bj-server", Unit: "bj-server", Exec: true, Core: true},
|
||||
{Name: "crypto-service.jar", Title: "Криптосервис", Path: "/opt/bj/crypto-service.jar", Unit: "bj-crypto"},
|
||||
{Name: "bj-lk", Title: "Личный кабинет клиента", Path: "/opt/bj/bj-lk", Unit: "bj-lk", Exec: true},
|
||||
{Name: "bj-npr", Title: "Риск-монитор НПР / УДС", Path: "/opt/bj/bj-npr", Unit: "bj-npr", Exec: true},
|
||||
{Name: "bj-quikexport", Title: "Экспорт QUIK", Path: "/opt/bj/bj-quikexport", Unit: "bj-quikexport", Exec: true},
|
||||
{Name: "bj-server", Title: "Ядро bj: переводы M2M, DEPO, QUIK МНП, ЛК ЕСИА", Path: "/opt/bj/bj-server", Unit: "bj-server", Exec: true, Core: true, Feature: "updates"},
|
||||
{Name: "crypto-service.jar", Title: "Криптосервис", Path: "/opt/bj/crypto-service.jar", Unit: "bj-crypto", Feature: "updates"},
|
||||
{Name: "bj-lk", Title: "Личный кабинет клиента", Path: "/opt/bj/bj-lk", Unit: "bj-lk", Exec: true, Feature: "web-cabinet"},
|
||||
{Name: "bj-npr", Title: "Риск-монитор НПР / УДС", Path: "/opt/bj/bj-npr", Unit: "bj-npr", Exec: true, Feature: "npr"},
|
||||
{Name: "bj-quikexport", Title: "Экспорт QUIK", Path: "/opt/bj/bj-quikexport", Unit: "bj-quikexport", Exec: true, Feature: "quik-export"},
|
||||
}
|
||||
|
||||
// ComponentByName — компонент по имени артефакта.
|
||||
|
||||
Reference in New Issue
Block a user