---
title: PSS Lic Perfect Streamer Toolkit v2.0 — лицензия узла
url: https://doc2.pstreamer.tv/ru/manual/toolkit/pss_lic.html
lang: ru
product: Perfect Streamer
version: 2.0.1.264
---

# PSS Lic Perfect Streamer Toolkit v2.0 — лицензия узла

Часть **Perfect Streamer Toolkit** — [https://pstreamer.tv](https://pstreamer.tv)

Консольная утилита управления лицензией узла: применяет присланное поставщиком обновление лицензии, выгружает состояние ключа для запроса на активацию и переносит лицензию с узла на узел.

Работает с тем же ключом системы защиты, что и сам стример, — программным (SL) или аппаратным (HL). Обращение к ключу идёт через службу системы защиты **aksusbd**, поэтому утилита работает только там, где эта служба запущена.

Инструмент входит в состав пакета **pstreamer** и после установки находится в `/opt/pss/tools/pss_lic` — отдельно устанавливать ничего не нужно.

## Когда нужна утилита

Экран [Лицензия](../webui/administration.md#webui-license) умеет выгрузить C2V и применить присланный ключ V2C, но не более того. Из консоли доступны все операции с ключом, и только отсюда делается остальное:

- активация и обновление лицензии на узле без доступа к веб-интерфейсу;
- автоматизация: развёртывание парка узлов, плановое обновление лицензий, проверки из системы мониторинга;
- перенос лицензии между узлами — постоянный или временный.

Права root утилите не нужны: запись в защищённое хранилище выполняет служба системы защиты, а не сама утилита. Root потребуется только чтобы записать выходной файл в системный каталог и чтобы перезапустить службу **pss** после смены лицензии.

Первичная активация пробной лицензии выполняется не этой утилитой, а скриптом `/opt/pss/tools/activate.sh` — см. [Временная активация и запуск](../first_start/index.md#first-start-activation). Скрипт вызывает **pss_lic** сам, а затем перезапускает службу **pss** и включает её автостарт. Порядок получения постоянной лицензии описан в [Постоянная активация](../first_start/index.md#first-start-permanent-activation).

## Использование

```
pss_lic <команда> [опции]
```

Запуск без аргументов, с `-h` или с `--help` печатает встроенную справку и завершается с кодом `0`. Опции ставятся после команды; до команды допускаются только `-h`, `--help`, `-V` и `--version`. Позиционные аргументы не принимаются — всё задаётся опциями.

### Команды

| Команда | Назначение | Обязательные опции |
| --- | --- | --- |
| `apply` | Применить к узлу обновление лицензии — файл V2C, H2R или R2H | `--in` |
| `c2v` | Выгрузить состояние ключа (C2V) для отправки поставщику | — |
| `fingerprint` | Выгрузить отпечаток узла | — |
| `recipient` | Выгрузить recipient-блок узла — описание узла как получателя переноса | — |
| `keys` | Перечислить ключи системы защиты, видимые с этого узла | — |
| `detach` | Временно передать лицензию продукта на другой узел; результат — файл H2R | `--product-id` |
| `rehost` | Перенести ключ на другой узел; результат — файл V2C, лицензия с текущего узла снимается | `--key-id` |
| `cancel` | Досрочно вернуть временно переданную лицензию; результат — файл R2H | `--key-id` |
| `version` | Показать версию утилиты и версию API системы защиты | — |
| `help` | Показать встроенную справку | — |

### Опции

| Опция | Описание | Принимают команды |
| --- | --- | --- |
| `-i, --in <файл>` | Входные данные | `apply` |
| `-o, --out <файл>` | Выходные данные; по умолчанию `-`, то есть stdout | все, кроме `version` и `help` |
| `-r, --recipient <файл>` | Recipient-блок узла-получателя | `detach`, `rehost` |
| `-k, --key-id <id>` | Идентификатор ключа, десятичный | `c2v`, `keys`, `detach`, `rehost`, `cancel` |
| `-p, --product-id <id>` | Идентификатор продукта, десятичный | `detach` |
| `--duration <сек>` | Срок временной передачи в секундах; по умолчанию `120`, максимум `31536000` | `detach` |
| `--fast` | Сокращённый слепок состояния; на аппаратном (HL) ключе — меньший файл | `c2v` |
| `--ids` | Печатать только идентификаторы ключей, по одному в строке | `keys` |
| `-y, --yes` | Не запрашивать подтверждение | `rehost`, `cancel` |
| `-q, --quiet` | Только ошибки | все |
| `-v, --verbose` | Подробный протокол обращения к системе защиты | все |
| `-V, --version` | Показать версии и выйти | все |
| `-h, --help` | Показать справку | все |

Опция, не указанная в строке своей команды, — ошибка синтаксиса, а не молчаливо игнорируемый флаг: утилита сообщает, например, `--key-id is not valid for 'fingerprint'`, и часто добавляет строку с причиной. Значения `--key-id`, `--product-id` и `--duration` — только десятичные числа, начиная с `1`; ноль недопустим.

### Ввод и вывод

Любой файловый аргумент — `--in`, `--out`, `--recipient` — принимает `-`: чтение со stdin, запись на stdout. По умолчанию вывод идёт на stdout.

На **stdout** попадают только сами данные — лицензионный блок. Сообщения об успехе, предупреждения и ошибки идут на **stderr** и начинаются с префикса `pss_lic:`. Благодаря этому любую команду можно перенаправить в файл или в конвейер, не разбирая вывод.

Если выходной файл не задан, а stdout — терминал, команды `detach`, `rehost` и `cancel` предупреждают, что результат переноса окажется на экране и будет потерян:

```
pss_lic: writing the V2C to the terminal; use --out <file> to keep it
```

Входной файл проверяется до обращения к системе защиты: пустой файл, файл, содержащий нулевой байт, и файл больше 8 МиБ отвергаются. Метка порядка байтов UTF-8 в начале файла — её добавляют некоторые почтовые клиенты и редакторы — удаляется автоматически.

## Применение обновления лицензии

Файл, присланный поставщиком, применяется одной командой:

```bash
# apply a licence update sent by the vendor
/opt/pss/tools/pss_lic apply --in license.v2c

# the same file through a pipe
cat license.v2c | /opt/pss/tools/pss_lic apply --in -
```

При успехе на stderr выводится:

```
pss_lic: update applied
```

**Утилита не перезапускает службу.** Работающий стример держит прежнюю лицензию в памяти, поэтому после смены лицензии перезапустите службу вручную:

```bash
sudo systemctl restart pss
```

Повторное применение того же файла ошибкой не считается: утилита сообщает `this V2C is already installed, nothing to do` и завершается с кодом `0`. На этом свойстве построена повторяемость скрипта `activate.sh`.

Не путайте это сообщение с отказом `the update is older than the one already installed (stale or rolled-back V2C)` (статус 54) — он означает, что применяется устаревший файл, и завершается кодом `1`. В этом случае запросите у поставщика свежий V2C.

Командой `apply` применяются все три вида обновлений: V2C от поставщика, H2R при временной передаче лицензии и R2H при её возврате.

## Выгрузка данных для поставщика

Запрос на активацию или на расширение лицензии строится из файла C2V — слепка текущего состояния ключа:

```bash
# export the key state for the vendor
/opt/pss/tools/pss_lic c2v --out host.c2v
```

Если узел видит несколько ключей, система защиты не станет угадывать нужный и ответит отказом `too many keys match the scope` (статус 37). Идентификаторы ключей перечисляет команда `keys`:

```bash
# list the key ids visible on this host, then scope the export to one of them
/opt/pss/tools/pss_lic keys --ids
/opt/pss/tools/pss_lic c2v --key-id <id> --out host.c2v
```

Команда `keys` без `--ids` печатает перечень ключей и их лицензий в том виде, в каком его отдаёт система защиты, — это XML-документ, а не таблица. Для выбора значения `--key-id` достаточно формы `--ids`.

Опция `--fast` запрашивает у ключа сокращённый слепок состояния. На аппаратном (HL) ключе такой файл получается примерно на порядок меньше полного; на программном (SL) размер тот же — отличается только состав данных.

**Содержимое C2V на узле прочитать нельзя**, поэтому идентификатор ключа берут командой `keys`, а не из самого файла.

**Один C2V — один запрос.** Не отправляйте поставщику один и тот же C2V дважды: второй выпущенный по нему V2C может примениться не полностью. Для повторного запроса выгрузите C2V заново.

Команды `fingerprint` и `recipient` выгружают отпечаток узла и recipient-блок. Отпечаток описывает машину и нужен поставщику, когда лицензии на узле ещё нет: к нему привязывается новый программный ключ. Recipient-блок описывает узел как получателя переноса и нужен не поставщику, а второму узлу — см. Перенос лицензии на другой узел. Оба относятся к узлу целиком, а не к отдельному ключу, поэтому опция `--key-id` для них недопустима.

## Перенос лицензии на другой узел

Перенос лицензии между узлами возможен только для программного (SL) ключа: аппаратный ключ переносится вместе с самим устройством, командами утилиты он не затрагивается. Пробная лицензия не переносится. Возможность переноса задаётся условиями лицензии; если она не предусмотрена, система защиты отвечает отказом `rehost is not allowed for this licence`. Уточняйте это у поставщика заранее.

> **Предупреждение**
>
> `rehost` снимает лицензию с текущего узла. Полученный файл можно применить только на том узле, чей recipient-блок был передан в `--recipient`. Если файл потерян или узел-получатель недоступен, лицензия потеряна вместе с ним: локального отката нет. Всегда указывайте `--recipient` и сохраняйте результат в файл, а не на экран.

Перенос выполняется в три шага и затрагивает оба узла. Ниже A — узел, с которого лицензия уходит, B — узел, на который она переносится.

1. На узле **B** выгрузить recipient-блок и передать файл на узел A:

   ```bash
   /opt/pss/tools/pss_lic recipient --out b.rcp
   ```
2. На узле **A** перенести ключ. Утилита запросит подтверждение:

   ```bash
   /opt/pss/tools/pss_lic rehost --key-id <id> --recipient b.rcp --out a2b.v2c
   ```

   ```
   pss_lic: about to move the licence off this host. This cannot be undone. Continue? [y/N]
   ```

   Подтверждением считается ответ, начинающийся с `y` или `Y`: `yes` подтверждает так же, как `y`. Любой другой ответ, в том числе пустая строка, отменяет операцию. Вопрос задаётся напрямую на терминал, поэтому перенаправление вывода его не скрывает. Если терминала нет — например, команда запущена из планировщика, — утилита откажется выполнять перенос и предложит указать `--yes`.
3. На узле **B** применить полученный файл и перезапустить службу:

   ```bash
   /opt/pss/tools/pss_lic apply --in a2b.v2c
   sudo systemctl restart pss
   ```

С момента, когда шаг 2 выполнен, и до того, как отработает шаг 3, лицензии нет ни на одном из узлов. Планируйте перенос так, чтобы этот промежуток был коротким.

Полученный файл бесполезен везде, кроме узла B: на другой машине он даст отказ со статусом 62. Попытка применить на узле A старый файл того же ключа даст статус 70 или 71 — ключ уже перенесён.

## Временная передача лицензии

`detach` передаёт лицензию продукта на другой узел на заданный срок, `cancel` возвращает её досрочно. Как и перенос, временная передача работает только с программным ключом и только если она разрешена условиями лицензии; иначе система защиты отвечает отказом со статусом 67. С пробной лицензией такой отказ — ожидаемый результат, а не неисправность.

Идентификатор продукта Perfect Streamer — `2`. Срок задаётся в секундах опцией `--duration`; **значение по умолчанию — 120 секунд**, поэтому в работе всегда указывайте его явно. Верхняя граница у самой утилиты — `31536000` секунд (год), но фактический предел задаётся лицензией: при слишком большом сроке система защиты отвечает отказом `invalid duration specified`. Запрошенный срок — именно запрос: окончательное значение определяет ключ, и оно может оказаться меньше.

1. На узле **B** выгрузить recipient-блок и передать файл на узел A:

   ```bash
   /opt/pss/tools/pss_lic recipient --out b.rcp
   ```
2. На узле **A** передать лицензию на сутки:

   ```bash
   /opt/pss/tools/pss_lic detach --product-id 2 --duration 86400 --recipient b.rcp --out b.h2r
   ```

   ```
   pss_lic: product 2 detached, 86400 s requested
   ```
3. На узле **B** применить полученный файл и перезапустить службу:

   ```bash
   /opt/pss/tools/pss_lic apply --in b.h2r
   sudo systemctl restart pss
   ```

По истечении срока лицензия возвращается на узел A сама. Досрочный возврат идёт в обратную сторону: файл R2H создаётся на узле-получателе и применяется на исходном узле. Если срок к этому моменту уже истёк, возвращать нечего — утилита сообщает `the R2H: nothing to write` и завершается с кодом `1`.

1. На узле **B** узнать идентификатор переданного ключа и отменить передачу:

   ```bash
   /opt/pss/tools/pss_lic keys --ids
   /opt/pss/tools/pss_lic cancel --key-id <id> --out back.r2h
   ```
2. На узле **A** применить полученный файл и перезапустить службу:

   ```bash
   /opt/pss/tools/pss_lic apply --in back.r2h
   sudo systemctl restart pss
   ```

Опция `--recipient` для `cancel` недопустима: лицензия возвращается туда, откуда пришла. Как и `rehost`, команда `cancel` запрашивает подтверждение. Сама `detach` подтверждения не запрашивает — передача ограничена сроком и обратима.

Промежуточные файлы берегите так же, как при постоянном переносе: пока H2R не применён на узле B, а R2H — на узле A, лицензия недоступна ни там, ни там и вернётся только по истечении срока передачи.

## Коды выхода

| Код | Значение |
| --- | --- |
| `0` | Операция выполнена. Этот же код возвращается, когда обновление уже было применено ранее |
| `1` | Система защиты отклонила операцию — в сообщении указан номер статуса. Этот же код возвращается, когда операция завершилась без данных, например `the R2H: nothing to write` |
| `2` | Ошибка синтаксиса: неизвестная команда, недопустимая для команды опция, пропущенная обязательная опция, недопустимое значение. Этот же код возвращается, когда оператор ответил «нет» на запрос подтверждения |
| `3` | Ошибка ввода-вывода: файл не открывается, не читается или не записывается |

Два случая стоит учесть в скриптах. Отказ оператора от подтверждения — это код `2`, а не `0`: проверка «ненулевой код — авария» примет отмену за сбой. Недоступный входной файл — это код `3`, а не `1`: до системы защиты дело не дошло.

```bash
# distinguish a refusal by the key from a bad command line or a missing file
/opt/pss/tools/pss_lic apply --in license.v2c || {
    case $? in
        1) echo "the key refused the update" >&2 ;;
        2) echo "wrong command line, or the operator declined" >&2 ;;
        3) echo "the file could not be read" >&2 ;;
    esac
}
```

## Сообщения и диагностика

Сообщения выводятся на stderr с префиксом `pss_lic:`. Отказ системы защиты печатается всегда в одном виде — что не удалось, словесное описание причины и номер статуса, а для распространённых причин добавляется строка с подсказкой:

```
pss_lic: reading the key state (C2V) failed: too many keys match the scope (status 37)
pss_lic:   hint: this host holds several keys; run 'pss_lic keys --ids' and pass --key-id
```

Опция `-q` убирает сообщения об успехе — в том числе предупреждение о выводе на терминал, — но не ошибки и не подсказки. Опция `-v` добавляет протокол обращения к системе защиты: запросы, число прочитанных и записанных байт, имя вызванной функции. При обращении в поддержку прикладывайте вывод именно с `-v`.

Самая частая группа отказов — ключ не виден или служба системы защиты не отвечает (статусы 7, 14, 33, 50 и 80). Проверьте, запущена ли служба (`systemctl status aksusbd`), подключён ли USB-ключ и на месте ли библиотеки поставщика в каталоге `/var/hasplm` — их устанавливает пакет **pstreamer**. Остальные отказы в таблице ниже; в первом столбце — номер статуса из строки отказа, во втором — её текст.

| Статус | Текст отказа | Причина и решение |
| --- | --- | --- |
| 37 | `too many keys match the scope` | Узел видит несколько ключей. Получить список командой `keys --ids` и указать `--key-id` |
| 42 | `License Manager version is too old` | Версия **aksusbd** ниже 9.12; обновить пакет системы защиты |
| 47 | `secure storage contains garbage` | Хранилище лицензии повреждено; требуется новый V2C от поставщика |
| 48 | `vendor library cannot be found` | В каталоге `/var/hasplm` нет библиотек поставщика; их устанавливает пакет **pstreamer** |
| 54 | `the update is older than the one already installed (stale or rolled-back V2C)` | Применяется устаревший V2C; запросить у поставщика свежий |
| 55 | `another update must be installed first` | Файл обновления опережает состояние ключа — пропущено промежуточное обновление; выгрузить свежий C2V и применить выпущенный по нему V2C |
| 58 | `invalid XML recipient parameter` | Recipient-блок повреждён; выгрузить его на узле-получателе заново |
| 60 | `the scope does not select a unique Product` | Проверить `--product-id`, а на узле с несколькими ключами добавить `--key-id` |
| 61 | `invalid Product information` | Проверить `--product-id`; у Perfect Streamer он равен `2` |
| 62 | `unknown recipient; this blob may only be applied on the recipient it was made for` | Файл выпущен для другой машины и применим только на ней |
| 63 | `invalid duration specified` | Срок передачи больше того, что допускает лицензия |
| 64 | `cloned secure storage detected` | Хранилище лицензии распознано как копия — следствие клонирования диска или виртуальной машины; запросить у поставщика перевыпуск лицензии для этой машины |
| 66 | `the specified key is inactive` | Ключ неактивен |
| 67 | `no detachable Feature exists` | Временная передача не разрешена условиями лицензии |
| 68 | `the scope does not select a unique host` | Узел видит несколько служб системы защиты; `fingerprint` и `recipient` относятся к службе, а не к ключу |
| 69 | `rehost is not allowed for this licence` | Перенос не разрешён условиями лицензии |
| 70 | `the licence was rehosted to another machine` | Ключ уже перенесён с этого узла |
| 71 | `an old rehost licence is being applied` | Применяется старый файл переноса; ключ уже перенесён с этого узла |
| 77 | `the recipient of the requested operation is older than expected` | На узле-получателе устаревшая служба системы защиты; обновить её |
| 78 | `secure storage ID mismatch` | Хранилище лицензии принадлежит другой машине; требуется новый V2C от поставщика |
| 79 | `duplicate host name while the key uses host name fingerprinting` | В сети есть второй узел с тем же именем; переименовать узел или перевыпустить лицензию |
| 94 | `the key and the update are out of sync (update counters diverged)` | Счётчики обновлений ключа и файла разошлись; выгрузить свежий C2V и применить выпущенный по нему V2C |

Для каждого известного статуса утилита печатает словесное описание; нераспознанный статус выводится как `unrecognised status` с номером.

Отдельный случай — команда `keys`: если система защиты не приняла подробный формат перечня, утилита печатает строку отказа, а затем повторяет запрос в кратком формате. Перечень при этом выводится, а код выхода остаётся нулевым, поэтому такую строку отказа перед нормальным результатом читать как сбой не нужно.

Команда `version` работает и при неисправной системе защиты — этим она и полезна как первый шаг диагностики. Она печатает баннер утилиты и версию API системы защиты; если служба системы защиты недоступна, вместо версии выводится `unavailable` с номером статуса, а код выхода остаётся нулевым.

## Переход с версии 1.2

В версии 2.0 позиционный синтаксис заменён командами и длинными опциями; прежние формы не поддерживаются. При их вводе утилита печатает замену и завершается с кодом `2`.

| Было в 1.2 | Стало в 2.0 |
| --- | --- |
| `pss_lic u <файл>` | `pss_lic apply --in <файл>` |
| `pss_lic i [ключ] [файл]` | `pss_lic c2v [--key-id <ключ>] [--out <файл>]` |
| `pss_lic d <продукт> [файл]` | `pss_lic detach --product-id <продукт> [--out <файл>]` |
| `pss_lic r <ключ> [файл]` | `pss_lic rehost --key-id <ключ> [--out <файл>]` |
| `pss_lic f [файл]` | `pss_lic fingerprint [--out <файл>]` |

Изменилось и поведение вывода: в 2.0 на stdout попадают только данные, а сообщения — на stderr. Скрипты, разбиравшие смешанный вывод версии 1.2, нужно поправить.
