Правка, проверка и перенос настроек

Порядок действий при правке pss.json вручную, при переносе настроек на другую версию Perfect Streamer и при повторном использовании настроек на другом узле.

Сначала прочитайте Файл настроек pss.json — по меньшей мере разделы о разреженности файла, о чтении файла и о невидимых правилах. Здесь написано, что делать; там — почему, и причины неочевидны. Коротко: в файле хранятся только отличия от значений по умолчанию, неизвестный ключ служба игнорирует, не останавливаясь, а одно неприемлемое значение отбрасывает весь файл.

Правка файла меняет следующий запуск. Чтобы изменить работающую службу, используйте веб-интерфейс или HTTP API (Управление через HTTP API).

Что понадобится

Схема

Вместе с документацией поставляются два файла: строгая схема pss.schema.json и мягкая pss.compat.schema.json. Чем они отличаются и что каждая из них проверяет — Два файла схемы; там же сказано, почему мягкой проверки самой по себе недостаточно.

Схемы — часть документации, а не продукта. На узле их нет, и копии в каталоге настроек не существует: искать её там бессмысленно. Обе лежат на сайте документации, в каталоге своей версии:

https://doc2.pstreamer.tv/schema/

Возьмите схему для своей версии и держите её на той машине, где правите файл.

Проверьте строку версии внутри схемы, прежде чем на неё полагаться. Проверка схемой другого выпуска даёт уверенные и неверные ответы.

Валидатор

Подойдёт любой валидатор JSON Schema с поддержкой draft 2020-12. Схема использует условные конструкции, поэтому валидатор, ограниченный более ранними редакциями, примет файл, который должен был отвергнуть; это стоит проверить, выбирая другой инструмент.

Рекомендуемый — jv, отдельная программа с открытым исходным кодом под лицензией Apache 2.0; сборки публикуются на странице выпусков проекта jsonschema.

Возьмите архив для своей платформы, распакуйте и положите программу в каталог, уже входящий в PATH:

$ tar xzf jv-v<версия>-linux-amd64.tar.gz
$ sudo install -m 0755 jv /usr/local/bin/jv
$ jv --version

Сборки публикуются для Linux, Windows и macOS.

Примечание

Сборка для Linux требует достаточно свежего набора системных библиотек: она работает на RHEL, AlmaLinux и Rocky 9, Debian 12, Ubuntu 22.04 и новее, а на более старом дистрибутиве не запускается вовсе. Это не помеха: проверяйте файл на рабочей станции и переносите на узел уже проверенный. Так и правильнее — файл невелик, а на узле валидатор не нужен.

Инструмент для проверок, которых схема не делает

Два правила средствами JSON Schema невыразимы вовсе: уникальность идентификаторов и равная длина парных массивов. Команды из раздела Проверки, которых схема не делает используют jq, который есть в репозитории любого дистрибутива:

В RHEL, AlmaLinux и Rocky:

$ sudo dnf install jq

В Debian и Ubuntu:

$ sudo apt install jq

Изменение параметра

Выполняйте последовательность целиком. Пропускают обычно шаги 5 и 7 — именно они ловят молчаливые ошибки.

  1. Остановите службу.

    $ sudo systemctl stop pss
    

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

  2. Сохраните копию — под именем, которого ещё нет.

    $ cp pss.json pss.json.$(date +%Y%m%d_%H%M%S)
    

    Это единственный путь назад: автоматической резервной копии работающей конфигурации служба не ведёт. Не используйте одно и то же имя копии дважды: при повторном проходе по этой последовательности вы перезапишете единственный исправный файл тем, что оставила после себя неудачная попытка.

  3. Правьте.

    Меняйте значения на месте. Не переставляйте ключи и не переставляйте записи массивов — почему, см. Порядок ключей внутри объекта значим и Порядок записей в массиве не сохраняется. Добавляя запись в массив, задайте ей явный и уникальный id: его никто не назначит за вас (Идентификаторы проставляются вручную). Задайте и опорные ключи записи — stream-name у потока, type и адрес у входа и выхода, name у платы и хранилища и так далее (Структура документа): без них файл будет отвергнут целиком.

  4. Удалите свои комментарии. Чтение допускает только блочные /* ... */, строгие инструменты JSON не принимают и их, а служба всё равно сотрёт комментарии при первом сохранении (Комментарии читаются, но не сохраняются).

  5. Проверьте файл по схеме.

    $ jv pss.schema.json pss.json
    

    Нулевой код возврата означает, что проверка пройдена. Иначе выводится по строке на каждую ошибку, и каждая называет точное место:

    jsonschema validation failed with 'pss.schema.json#'
      - at '/stream/3/input/1/passphrase': false schema
    

    Читается это так: у второго входа четвёртого потока есть ключ passphrase, не принадлежащий транспорту, который выбран его ключом type. Отсчёт позиций — с нуля.

  6. Выполните проверки из раздела Проверки, которых схема не делает.

  7. Запустите службу и прочитайте журнал.

    $ sudo systemctl start pss
    $ grep -iE 'ignore|clamped|config' /var/log/pss/main.log
    

    Служба пишет журнал в файл; каталог задаёт ключ log-dir файла pss.properties, по умолчанию — /var/log/pss. В journalctl -u pss этих строк не будет, пока в pss.properties не включён log-to-console или log-to-syslog.

    Строка о проигнорированном ключе означает, что схема не совпадает с установленной сборкой — обычно она старше или новее. Строка о приведённом к границе значении означает, что число вышло за диапазон и было молча исправлено, а файл уже пересохранён с исправленным значением.

    Если служба не запустилась, смотрите каталог bad/Восстановление после отклонённого файла.

  8. Проверяйте результат через интерфейс, а не по файлу. Файл не показывает настройки, оставшиеся в значении по умолчанию, поэтому подтвердить по нему ничего нельзя. Прочитайте конфигурацию обратно через HTTP API: там возвращаются все ключи.

Перенос настроек на другую версию

В файле нет отметки о версии, и служба не выполняет никакого преобразования. Конфигурация с другого выпуска применяется как есть: ключи, которых больше нет, игнорируются; ключи, которых ещё не было, получают значения по умолчанию. Ни о том, ни о другом не сообщается. Порядок ниже делает видимым и то, и другое.

  1. Возьмите pss.schema.json для целевой версии — той, которая будет читать файл, а не той, которая его записала.

  2. Первый проход, мягкий. Проверяет типы, диапазоны и обязательные ключи, но терпит ключи, от которых целевая версия отказалась:

    $ jv pss.compat.schema.json pss.json
    

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

  3. Второй проход, строгий. Перечисляет ключи, которых целевая версия уже не знает:

    $ jv pss.schema.json pss.json
    

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

    Строгий проход отвечает и за принадлежность ключа варианту, которую мягкая схема не проверяет, — поэтому одним мягким проходом ограничиваться нельзя.

  4. Сравните значения по умолчанию двух версий.

    В файле хранятся только отличия от умолчаний, поэтому настройка, которой вы никогда не касались, в файле отсутствует — и если её умолчание изменилось, поведение изменится вместе с обновлением, молча. Файл и схема к этому слепы по построению: схема целевой версии такое изменение не покажет.

    Видно его только в действующей конфигурации, потому что HTTP API возвращает все ключи, включая оставшиеся по умолчанию. Прочитайте её на исходном узле до обновления и на узле целевой версии: расхождения в ключах, которых вы никогда не задавали, и есть изменившиеся умолчания.

  5. Дальше — с шага 4 раздела Изменение параметра.

Предупреждение

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

Перенос настроек на другой узел

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

  1. Замените все секреты. Их перечень — Значения, которые нельзя пересылать. Не обнуляйте их: часть ключей пустое значение не принимает и отбросит весь файл. Подставьте очевидную замену правдоподобной длины, а настоящие значения задайте через веб-интерфейс после первого запуска.

  2. Смените опознавательные данные узла: имя узла должно быть уникальным в пределах домена, а примечание, роль и регион описывают эту машину, а не ту, с которой скопированы.

  3. Просмотрите всё, что называет конкретную машину: адреса прослушивания, имена интерфейсов, пути хранилищ, номера плат. Несуществующий путь и неустановленную плату схема не поймает.

  4. Просмотрите секцию Meshwork. Адреса, имена и секреты соседей — парные массивы, сопоставляемые по позиции (Парные массивы сопоставляются по позиции): удаляя запись, удалите соответствующую запись из каждого массива. Здесь расхождение длин отбрасывает файл целиком, поэтому сверьте их заранее — Равная длина парных массивов.

  5. Сверьте лицензии двух узлов. Настройки того, чего целевая лицензия не включает, окажутся неизвестными ключами: секция уйдёт из файла с одним предупреждением в журнале. Заметнее всего это на приёме DVB.

  6. Дальше — с шага 4 раздела Изменение параметра.

Проверки, которых схема не делает

Повторяющиеся идентификаторы

Две записи одного массива с одинаковым id отбрасывают весь файл. Уникальность ключа среди записей массива средствами JSON Schema невыразима, поэтому её проверяют отдельно:

$ jq '[paths(type=="array") as $p
       | {at: ($p|join(".")),
          duplicated: (getpath($p)
                       | map(select(type=="object") | (.id // 0))
                       | group_by(.) | map(select(length>1)) | map(.[0]))}
       | select(.duplicated|length>0)]' pss.json

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

Равная длина парных массивов

Там, где массивы сопоставляются по позиции, число записей в них должно совпадать. Для секции Meshwork:

$ jq '.cluster | {addresses: (.["cluster-node-address"]|length),
                  names:     (.["cluster-node-name"]|length),
                  secrets:   (.["cluster-node-secret"]|length)}' pss.json

Три числа должны быть равны. Проверка здесь не гигиеническая: расхождение длин служба обнаруживает сама и отбрасывает весь файл — и у соседей Meshwork, и у переменных окружения, и у списков «было — стало» при переназначении PID (mpegts-pid-old и mpegts-pid-new), и у списков смены языка (mpegts-lang-set-pid и mpegts-lang-set), и у пары biss-pnr и biss-key. У четвёрки адресов RIST (rist-addr-*) файл не отбрасывается, но вход не открывается, а причина уходит в журнал. Сверяйте все эти пары тем же способом.

Порядок ключей

Порядка ключей схема не видит, а он значим в трёх местах — Порядок ключей внутри объекта значим. Команды для этого нет: правило состоит в том, чтобы ничего не переставлять, а в новой записи, добавленной вручную, ставить type, mpts и mode первыми.

Ссылки между секциями

Номера, указывающие на другую часть файла — хранилище, источник телепрограммы, плату приёма, исходный поток, — схемой не проверяются. Если цель не существует, служба сообщит об этом при запуске.

Восстановление после отклонённого файла

Если pss.json прочитать не удалось, служба перемещает его в каталог bad/ под именем с датой и временем и поднимается на предыдущей восстановленной конфигурации, а при её отсутствии — на настройках по умолчанию (pss_default.json, Поведение при старте и ошибках конфигурации). Потоков они не содержат вовсе, поэтому узел в этом состоянии работает пустым. О том, что настройки загрузить не удалось и узел работает на запасных, сообщает авария при запуске.

  1. Не перезапускайте узел ещё раз. Архивной копии перезапуск не вредит, но работающая конфигурация сейчас — настройки по умолчанию, и давать ей сохраниться поверх чего-либо незачем.

  2. Найдите архивный файл в каталоге bad/. Самый свежий — ваша конфигурация.

  3. Выясните, что с ним не так:

    $ jv pss.schema.json bad/pss_20260809_101500.json
    

    Журнал неудавшегося запуска тоже называет ключ и причину.

  4. Исправьте, проверяйте до чистого результата, скопируйте обратно поверх pss.json и запускайте.

Если архивная копия пропала или тоже повреждена, последняя надежда — копия, сделанная на шаге 2 раздела Изменение параметра. Для этого шаг и существует.

Подсказки в редакторе

Большинство редакторов подскажут имена ключей, покажут допустимые значения и подчеркнут ошибку по ходу набора, если указать им схему.

Привязывайте схему по имени файла, в настройках самого редактора: в редакторах, работающих через языковой сервер JSON, это запись json.schemas, сопоставляющая имя pss.json со схемой. Схему можно указать и локальным файлом, и адресом опубликованной версии. Локальный файл предпочтительнее: он работает без сети и жёстко закрепляет версию, тогда как в адресе версию легко набрать не ту.

Предупреждение

Не добавляйте ключ $schema внутрь самого pss.json. Выглядит так, будто работает: служба принимает его как неизвестный ключ, с предупреждением в журнале, — но при первом же сохранении ключ исчезает, потому что документ формируется заново из памяти. Всё, чего продукт не объявлял, живёт в файле ровно до следующего сохранения.

Коротко

  • Останавливайте службу перед правкой: файл работающего узла будет перезаписан из памяти.

  • Сохраняйте копию: автоматической резервной копии работающей конфигурации нет.

  • Не переставляйте ключи и записи массивов.

  • Каждой добавленной записи — явный и уникальный идентификатор.

  • Проверяйте файл схемой той версии, которая будет его читать.

  • Повторяющиеся идентификаторы и длины парных массивов проверяйте отдельно.

  • Читайте журнал после первого запуска: проигнорированные ключи и приведённые к границе значения видны только там.

  • Результат подтверждайте через интерфейс, а не перечитыванием файла.