Require the installed user-unit check in every native-package smoke receipt and keep the stop-timeout documentation aligned with the actual cgroup lifecycle.
Keep the opt-in native-package unit on the existing launcher path, leave restart and panic policy with the launcher, correct readiness and shutdown guidance, and verify the installed unit in the package smoke.
Запущенный из десктопного лаунчера Ouroboros попадает в transient scope
systemd со сгенерированным именем вида run-p497094-i8877010.scope. Имя
меняется при каждом старте, поэтому остановку нельзя записать в скрипт:
приходится сперва выяснять имя через cgroup процесса.
Замена на pkill не годится. Лаунчер порождает server.py и пул воркеров;
если убить только родителя, воркеры остаются держать порт 8765, и
следующий старт падает с address already in use.
Юнит даёт стабильное имя: systemctl --user stop ouroboros.
Пакеты deb и rpm ставят его в /usr/lib/systemd/user, поэтому после
установки имя доступно сразу. Активации при этом нет: включать
десктопного агента за пользователя неправильно, у него уже есть запись
рабочего стола. Юнит из домашнего каталога имеет приоритет над
пакетным — это и есть поддерживаемый способ переопределить ExecStart
для headless-узла.
Выбран пользовательский юнит, а не системный: состояние живёт в домашнем
каталоге, а десктопной сборке нужна сессия пользователя. Системный
работал бы от другого пользователя и молча использовал бы другой каталог
данных.
KillMode=control-group доводит сигнал до всей группы процессов, что и
делает обычную остановку достаточной. TimeoutStopSec оставляет запас на
незавершённый вызов инструмента. Ограничение частоты перезапусков
прекращает бесконечный цикл вместо того, чтобы хоронить первую реальную
ошибку под десятками повторов; оба ключа размещены в секции Unit, где их
ожидает systemd начиная с версии 229.
Отдельно описана готовность, поскольку сигналов три и совпадают они не
всегда. Активность юнита означает лишь запуск процесса. Ответ HTTP и
даже заполненный пул воркеров готовности не означают: поданная в этот
момент задача отклоняется кодом 503. Авторитетный признак —
supervisor_ready в ответе /api/state. Скриптам, которые всё равно подают
работу, рекомендован повтор на 503: так поступает собственная обвязка
бенчмарков проекта.
Добавлен тест состава пакетов: он требует наличия юнита в обеих ветках
сборки и запрещает включение или запуск из установочных сценариев.
Проверено на живой системе: остановка снимает всю группу процессов и
освобождает порт за секунду с небольшим, запуск даёт готовность за
десять секунд, задача подаётся без отказа и доходит до completed.
Отдельно собран deb с заглушкой вместо полезной нагрузки: юнит попадает
в пакет по пути /usr/lib/systemd/user/ouroboros.service с правами 644 и
проходит валидацию после извлечения.
Build PyInstaller from a portable-Python venv, exercise the desktop launcher on Ubuntu 22.04, and keep RPM staging valid across filesystems.
Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
Linux-релиз состоял из одного .tar.gz, который пользователь распаковывал
вручную. Теперь тот же payload дополнительно поставляется как нативные
пакеты, устанавливаемые штатным пакетным менеджером.
Добавлено три ассета, собираемых из уже проверенного dist/Ouroboros:
- ouroboros_<version>_amd64.deb — Debian, Ubuntu, Astra Linux;
- ouroboros-<version>-1.x86_64.rpm — Fedora, RHEL;
- ouroboros-<version>-1.red80.x86_64.rpm — РЕД ОС 8.
Все три ставятся в /opt/ouroboros, добавляют симлинк /usr/bin/ouroboros
и desktop-запись. Payload побайтово совпадает с содержимым .tar.gz,
поэтому пакеты переиспользуют его SBOM.
scripts/build_linux_packages.sh собирает пакеты через dpkg-deb и rpmbuild.
Payload раскладывается один раз и подключается жёсткими ссылками: полная
копия многогигабайтного бандла трижды не помещается на раннере.
Сканирование зависимостей, strip и debuginfo отключены — бандл
самодостаточен, а автозависимости привязали бы пакет к набору библиотек
сборочной машины. Оба rpm собираются из одного spec, отличаясь только
release-тегом.
scripts/smoke_linux_packages.sh ставит пакеты в контейнерах и проверяет,
что CLI запускается после реальной установки. Две полосы:
- official — образы Docker Hub (ubuntu:24.04, fedora:42), блокирует релиз;
- vendor — образы Astra Linux и РЕД ОС из реестров вендоров,
информационная.
Разделение сделано намеренно: vendor-полоса обращается к сторонним
реестрам, доступность которых с раннеров не контролируется проектом.
Блокировать публикацию тега на чужом простое означало бы менять реальный
сбой публикации на чужую аварию, поэтому job vendor-package-smoke
помечен continue-on-error и не входит в needs у release. По той же
причине проверка на Astra не может быть обязательным чеком в receipt:
то, что не блокирует, не может требоваться как доказательство.
Каждый пакет получает собственный proof id, smoke-receipt, SBOM и
attestation, попадает в SHA256SUMS, release-evidence.json и список
ассетов релиза. locate по-прежнему находит ровно один платформенный
архив: суффиксы разделены на архивные и полный набор ассетов.
Проверено: сборка всех трёх пакетов в контейнере ubuntu:24.04;
установка и запуск в ubuntu:24.04, fedora:42, Astra Linux 1.8 и РЕД ОС 8.