Gitea API runner inventory вернул 403 для текущего principal; это не подтверждает отсутствие instance/org runner.
Перед завершением
Владелец проверяет root audit, ставит root-owned checkout и выполняет sudo bash /opt/akyldash/current/infra/runner/install-runner.sh.
В Settings → Actions → Runners создаёт runner именно для admin/akyldash, затем выполняет интерактивную регистрацию без передачи токена в чат/Git.
Включает akyldash-act-runner.service и health timer; подтверждает Online и успешный Runner smoke test на этом runner.
Отдельно завершает root audit, production env/data, HTTPS/origin, backup baseline, test restore/rollback и ограниченный deploy-helper review. Production deployment не включён.
PR не следует считать production readiness.
## Что сделано
- Обновлены inventory, CURRENT_STATE, ACCESS, AGENTS и инструкции production/CI.
- Добавлены read-only root audit и безопасное создание production env без перезаписи файлов.
- Добавлен ограниченный Compose helper только для `config`/`status`; `codex` не получает полный sudo или Docker socket.
- Подготовлена установка официального `act_runner` 0.2.13 с проверкой SHA-256, repository-level регистрацией, отдельным rootless Docker, лимитом 1 job, ограничением CPU/RAM/диска, systemd restart/healthcheck и ротацией логов.
- Добавлен runner smoke workflow на метке `akyldash-ci`. Автоматического production deployment нет.
## Проверки
- VPS: Ubuntu 24.04.5; Docker Engine 29.9.0/Compose 5.6.0; `codex` не имеет sudo/Docker group; `/` ext4, около 92 GiB свободно по предыдущему аудиту.
- VPS разрешает `git.vakanaut.ru` и получает Gitea 1.25.5 по HTTPS. Runner registration protocol не проверен.
- Unprivileged checks не обнаружили ISPmanager package/service, runner binary/user/service или listener на TCP 1500. UFW не менялся.
- Локально: backend 37 (1 OpenSearch integration пропущен без URL), Telegram 6, backup/restore 16, rollback 3; shell guards/syntax/YAML parse прошли.
- Gitea API runner inventory вернул 403 для текущего principal; это не подтверждает отсутствие instance/org runner.
## Перед завершением
1. Владелец проверяет root audit, ставит root-owned checkout и выполняет `sudo bash /opt/akyldash/current/infra/runner/install-runner.sh`.
2. В Settings → Actions → Runners создаёт runner именно для `admin/akyldash`, затем выполняет интерактивную регистрацию без передачи токена в чат/Git.
3. Включает `akyldash-act-runner.service` и health timer; подтверждает Online и успешный Runner smoke test на этом runner.
4. Отдельно завершает root audit, production env/data, HTTPS/origin, backup baseline, test restore/rollback и ограниченный deploy-helper review. Production deployment не включён.
PR не следует считать production readiness.
Независимо проверил PR 43. Нужны исправления установщика runner и guard-теста перед запуском owner-run процедуры. Локально прошли backend (37, 1 skip), Telegram (6), backup/restore (16), rollback (3), shell guards и синтаксис, YAML parse и git diff --check. SHA-256 официального act_runner 0.2.13 совпал; конфигурацию сверил с сгенерированным образцом. Запуск runner на VPS не выполнялся: в текущей среде отсутствует SSH-конфигурация/ключ к этому хосту, а root-установка требует владельца.
Независимо проверил PR 43. Нужны исправления установщика runner и guard-теста перед запуском owner-run процедуры. Локально прошли backend (37, 1 skip), Telegram (6), backup/restore (16), rollback (3), shell guards и синтаксис, YAML parse и `git diff --check`. SHA-256 официального act_runner 0.2.13 совпал; конфигурацию сверил с сгенерированным образцом. Запуск runner на VPS не выполнялся: в текущей среде отсутствует SSH-конфигурация/ключ к этому хосту, а root-установка требует владельца.
P1 — фиксированный subordinate UID/GID блокирует установку на типовой Ubuntu и не имеет предусмотренного обхода. Скрипт отказывает, если 100000–165535 уже занят, но ниже безусловно назначает именно этот диапазон. Для обычного пользователя codex Ubuntu часто выделяет первый блок с 100000 (см. useradd/login.defs для Ubuntu); в таком состоянии установка завершится до apt-get, а сообщение «assign a free range» не помогает, пока диапазон жёстко зашит. Сначала определите свободные 65536 UID и GID по /etc/subuid и /etc/subgid и используйте найденные значения в usermod, либо сделайте явно документированную настройку диапазона с проверкой. Фактическое содержимое этих файлов на VPS текущей сессией не подтверждено.
**P1 — фиксированный subordinate UID/GID блокирует установку на типовой Ubuntu и не имеет предусмотренного обхода.** Скрипт отказывает, если `100000–165535` уже занят, но ниже безусловно назначает именно этот диапазон. Для обычного пользователя `codex` Ubuntu часто выделяет первый блок с `100000` (см. [useradd/login.defs для Ubuntu](https://manpages.ubuntu.com/manpages/noble/man8/useradd.8.html)); в таком состоянии установка завершится до `apt-get`, а сообщение «assign a free range» не помогает, пока диапазон жёстко зашит. Сначала определите свободные 65536 UID и GID по `/etc/subuid` и `/etc/subgid` и используйте найденные значения в `usermod`, либо сделайте явно документированную настройку диапазона с проверкой. Фактическое содержимое этих файлов на VPS текущей сессией не подтверждено.
P2 — отрицательные guard-проверки в этом тесте не работают. В Bash set -e не прерывает сценарий при ошибке команды с !: текущий runner-smoke.yaml уже содержит production.env, review_secret и docker.sock, однако bash infra/runner/test-runner-config.sh выводит runner configuration guards passed. То же относится к строкам 11 и 15. Я воспроизвёл это локально. Проверяйте запрет через явный if grep ...; then exit 1; fi и отделите проверки обращения к секретам от безопасных проверок их отсутствия.
**P2 — отрицательные guard-проверки в этом тесте не работают.** В Bash `set -e` не прерывает сценарий при ошибке команды с `!`: текущий `runner-smoke.yaml` уже содержит `production.env`, `review_secret` и `docker.sock`, однако `bash infra/runner/test-runner-config.sh` выводит `runner configuration guards passed`. То же относится к строкам 11 и 15. Я воспроизвёл это локально. Проверяйте запрет через явный `if grep ...; then exit 1; fi` и отделите проверки обращения к секретам от безопасных проверок их отсутствия.
Повторно проверил PR 43 на текущем head. Оба исходных замечания исправлены: диапазон теперь выбирается динамически, отрицательные guard-проверки реально завершаются ошибкой. При проверке нового AWK-аллокатора нашёл крайний случай, в котором корректный пустой файл subuid/subgid блокирует установку. Остальные локальные suites прошли: backend 37 (1 skip), Telegram 6, backup/restore 16, rollback 3; shell guards, синтаксис, YAML parse и git diff --check прошли. На VPS установка не запускалась.
Повторно проверил PR 43 на текущем head. Оба исходных замечания исправлены: диапазон теперь выбирается динамически, отрицательные guard-проверки реально завершаются ошибкой. При проверке нового AWK-аллокатора нашёл крайний случай, в котором корректный пустой файл subuid/subgid блокирует установку. Остальные локальные suites прошли: backend 37 (1 skip), Telegram 6, backup/restore 16, rollback 3; shell guards, синтаксис, YAML parse и `git diff --check` прошли. На VPS установка не запускалась.
P2 — пустой корректный /etc/subuid или /etc/subgid ошибочно считается отсутствующим.files[FILENAME] устанавливается только при чтении записи (строка 7), поэтому length(files) != 2 срабатывает для пустого файла и аллокатор возвращает 2, хотя диапазон свободен. Воспроизвёл с /etc/subuid-аналогом codex:100000:65536 и пустым /etc/subgid-аналогом: allocator_exit=2; при двух пустых файлах та же проблема. Установщик уже проверяет наличие и читаемость обоих файлов, поэтому здесь достаточно обрабатывать отсутствие записей как пустой набор; добавьте тест для пустого файла.
**P2 — пустой корректный `/etc/subuid` или `/etc/subgid` ошибочно считается отсутствующим.** `files[FILENAME]` устанавливается только при чтении записи (строка 7), поэтому `length(files) != 2` срабатывает для пустого файла и аллокатор возвращает 2, хотя диапазон свободен. Воспроизвёл с `/etc/subuid`-аналогом `codex:100000:65536` и пустым `/etc/subgid`-аналогом: `allocator_exit=2`; при двух пустых файлах та же проблема. Установщик уже проверяет наличие и читаемость обоих файлов, поэтому здесь достаточно обрабатывать отсутствие записей как пустой набор; добавьте тест для пустого файла.
Проверил исправление на head 52027ec. Пустые /etc/subuid и /etc/subgid теперь считаются корректным отсутствием выделений: аллокатор выбирает первый свободный общий блок. Проверил случаи с одним и двумя пустыми файлами, новые runner guard-тесты, shell-синтаксис и git diff --check. Прежние замечания закрыты; локальная установка runner на production VPS не выполнялась.
Проверил исправление на head 52027ec. Пустые `/etc/subuid` и `/etc/subgid` теперь считаются корректным отсутствием выделений: аллокатор выбирает первый свободный общий блок. Проверил случаи с одним и двумя пустыми файлами, новые runner guard-тесты, shell-синтаксис и `git diff --check`. Прежние замечания закрыты; локальная установка runner на production VPS не выполнялась.
admin
merged commit 223e06ee77 into main2026-10-11 21:57:02 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что сделано
config/status;codexне получает полный sudo или Docker socket.act_runner0.2.13 с проверкой SHA-256, repository-level регистрацией, отдельным rootless Docker, лимитом 1 job, ограничением CPU/RAM/диска, systemd restart/healthcheck и ротацией логов.akyldash-ci. Автоматического production deployment нет.Проверки
codexне имеет sudo/Docker group;/ext4, около 92 GiB свободно по предыдущему аудиту.git.vakanaut.ruи получает Gitea 1.25.5 по HTTPS. Runner registration protocol не проверен.Перед завершением
sudo bash /opt/akyldash/current/infra/runner/install-runner.sh.admin/akyldash, затем выполняет интерактивную регистрацию без передачи токена в чат/Git.akyldash-act-runner.serviceи health timer; подтверждает Online и успешный Runner smoke test на этом runner.PR не следует считать production readiness.
Независимо проверил PR 43. Нужны исправления установщика runner и guard-теста перед запуском owner-run процедуры. Локально прошли backend (37, 1 skip), Telegram (6), backup/restore (16), rollback (3), shell guards и синтаксис, YAML parse и
git diff --check. SHA-256 официального act_runner 0.2.13 совпал; конфигурацию сверил с сгенерированным образцом. Запуск runner на VPS не выполнялся: в текущей среде отсутствует SSH-конфигурация/ключ к этому хосту, а root-установка требует владельца.@@ -0,0 +28,4 @@unsafe=$(find "$checkout" -xdev \( ! -user root -o -perm /022 \) -print -quit)[[ -z $unsafe ]] || die 'the repository checkout contains files writable by non-root users'git -C "$checkout" diff --quiet HEAD -- infra/runner || die 'runner files differ from the reviewed Git revision'if awk -F: '$2 <= 165535 && $2 + $3 - 1 >= 100000 { found=1 } END { exit !found }' /etc/subuid; thenP1 — фиксированный subordinate UID/GID блокирует установку на типовой Ubuntu и не имеет предусмотренного обхода. Скрипт отказывает, если
100000–165535уже занят, но ниже безусловно назначает именно этот диапазон. Для обычного пользователяcodexUbuntu часто выделяет первый блок с100000(см. useradd/login.defs для Ubuntu); в таком состоянии установка завершится доapt-get, а сообщение «assign a free range» не помогает, пока диапазон жёстко зашит. Сначала определите свободные 65536 UID и GID по/etc/subuidи/etc/subgidи используйте найденные значения вusermod, либо сделайте явно документированную настройку диапазона с проверкой. Фактическое содержимое этих файлов на VPS текущей сессией не подтверждено.@@ -0,0 +14,4 @@grep -Fq 'runner_sha256=3acac8b506ac8cadc88a55155b5d6378f0fab0b8f62d1e0c0450f4ccd69733e2' "$installer"! grep -Eq 'usermod.*(sudo|docker)|/var/run/docker.sock|/etc/sudoers' "$installer"grep -Fq 'runs-on: akyldash-ci' .gitea/workflows/runner-smoke.yaml! grep -Eq 'deploy|production.env|review_secret|docker.sock' .gitea/workflows/runner-smoke.yamlP2 — отрицательные guard-проверки в этом тесте не работают. В Bash
set -eне прерывает сценарий при ошибке команды с!: текущийrunner-smoke.yamlуже содержитproduction.env,review_secretиdocker.sock, однакоbash infra/runner/test-runner-config.shвыводитrunner configuration guards passed. То же относится к строкам 11 и 15. Я воспроизвёл это локально. Проверяйте запрет через явныйif grep ...; then exit 1; fiи отделите проверки обращения к секретам от безопасных проверок их отсутствия.Повторно проверил PR 43 на текущем head. Оба исходных замечания исправлены: диапазон теперь выбирается динамически, отрицательные guard-проверки реально завершаются ошибкой. При проверке нового AWK-аллокатора нашёл крайний случай, в котором корректный пустой файл subuid/subgid блокирует установку. Остальные локальные suites прошли: backend 37 (1 skip), Telegram 6, backup/restore 16, rollback 3; shell guards, синтаксис, YAML parse и
git diff --checkпрошли. На VPS установка не запускалась.@@ -0,0 +7,4 @@files[FILENAME] = 1}END {if (invalid || length(files) != 2) exit 2P2 — пустой корректный
/etc/subuidили/etc/subgidошибочно считается отсутствующим.files[FILENAME]устанавливается только при чтении записи (строка 7), поэтомуlength(files) != 2срабатывает для пустого файла и аллокатор возвращает 2, хотя диапазон свободен. Воспроизвёл с/etc/subuid-аналогомcodex:100000:65536и пустым/etc/subgid-аналогом:allocator_exit=2; при двух пустых файлах та же проблема. Установщик уже проверяет наличие и читаемость обоих файлов, поэтому здесь достаточно обрабатывать отсутствие записей как пустой набор; добавьте тест для пустого файла.Проверил исправление на head
52027ec. Пустые/etc/subuidи/etc/subgidтеперь считаются корректным отсутствием выделений: аллокатор выбирает первый свободный общий блок. Проверил случаи с одним и двумя пустыми файлами, новые runner guard-тесты, shell-синтаксис иgit diff --check. Прежние замечания закрыты; локальная установка runner на production VPS не выполнялась.