Commit graph

6 commits

Author SHA1 Message Date
Ouroboros
7a66bbb6c8 fix(release): bind the systemd unit to package proof
Require the installed user-unit check in every native-package smoke receipt and keep the stop-timeout documentation aligned with the actual cgroup lifecycle.
2026-08-13 01:19:14 +03:00
Ouroboros
4a3916c330 fix(packaging): align systemd service with launcher 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.
2026-08-13 00:51:48 +03:00
nkolesnikov
fd72ff82cf feat(packaging): systemd-юнит для управления рантаймом
Запущенный из десктопного лаунчера 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 и
проходит валидацию после извлечения.
2026-08-13 00:46:15 +03:00
Ouroboros
057dc4e599 fix(packaging): preserve Linux desktop portability
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>
2026-08-10 18:02:34 +03:00
Ouroboros
c17993837d fix(packaging): make Linux packages release-ready
Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
2026-08-10 17:02:57 +03:00
nkolesnikov
aebacbc723 feat(packaging): нативные пакеты .deb и .rpm для Linux в релизе
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.
2026-08-10 16:46:36 +03:00