Кабинет `my.uaskos.com` — закрытое хранилище образов и сборок с учётом версий, доступов и заказов. Документ описывает его устройство и порядок загрузки образов. Написан так, чтобы им мог пользоваться и человек, и ИИ-агент. Машинная версия страницы: `/docs/?format=md` — отдаётся как `text/plain`. ## Что решает кабинет - Образ не теряется, даже если флешка уехала с заказом. - У каждого образа есть проект, версия, контрольная сумма и происхождение. - Клиенту выдаётся доступ к конкретному файлу, и его можно отозвать. Кабинет не собирает и не модифицирует ОС. Он хранит, версионирует и выдаёт. ## Модель данных ``` Проект «RedChairOS», «Kali autoinstall» └── Релиз версия проекта: «2026-04-25», «1.4.0» └── Артефакт файл в роли: образ, контрольные суммы, патч, исходники, заметки ``` Отдельно существуют: - **Инструкции записи** — markdown-памятки «как из этого образа сделать флешку». Привязаны к проекту, необязательно к конкретной версии. - **Заказы** — учёт того, какая версия образа уехала клиенту: номер, устройство, статус, ссылка на релиз. - **Доступы** — назначение файла пользователю. Клиент видит только назначенное ему. ### Типы проектов | Тип | Значение `kind` | Когда использовать | | --- | --- | --- | | Флешка/автоустановка | `flash-set` | дистрибутивы и установочные носители: Kali, Mint, Ubuntu, Debian | | Клиентская сборка | `customer-build` | закрытые заказные системы: IlmOS, RedChairOS | | Пробная сборка | `trial` | внутренние эксперименты UASKOS | Правило выбора: если образ снят с машины заказчика или собран под конкретного клиента — `customer-build`. Если это дистрибутив общего назначения, из которого делают установочные флешки — `flash-set`. Всё остальное — `trial`. ### Статусы релиза | Статус | Значение | Смысл | | --- | --- | --- | | Черновик | `draft` | можно прикреплять и откреплять артефакты | | Stable | `stable` | состав зафиксирован навсегда; менять можно только заметки | | Архив | `archived` | версия выведена из обращения | Перевод в stable требует хотя бы одного артефакта с ролью «Образ». Из stable можно уйти только в архив — обратно в черновик нельзя. Это гарантия того, что ссылка на версию в заказе всегда означает один и тот же набор байт. Поэтому метки-«указатели» вроде `current` допустимы только для черновиков: как только версия уехала клиенту, у неё должна быть неподвижная метка с датой или номером. ### Роли артефактов | Роль | Значение | Что кладут | | --- | --- | --- | | Образ | `image` | ISO, IMG, tar с Clonezilla-образом | | Контрольные суммы | `checksums` | SHA256SUMS и подобные файлы издателя | | Патч | `patch` | дифф, набор правок, hotfix | | Исходники | `source` | source bundle, конфигурации сборки | | Заметки | `notes` | текстовые описания, журналы, инвентарь оборудования | | Другое | `other` | всё остальное | ## Как хранятся файлы При импорте кабинет считает SHA-256 и кладёт байты в content-addressed хранилище по этому хешу. Отсюда важные свойства: - одинаковые файлы не занимают места дважды, даже если прикреплены к разным релизам; - имя файла — метаданные, его можно менять, байты не переедут; - целостность проверяема: хеш показан рядом с файлом. Байты лежат вне публичного каталога. Скачать файл можно только через `/download/` с действующей сессией и назначенным доступом; поддерживаются докачка и диапазоны байт (HTTP Range). ## Разделы интерфейса | Раздел | Назначение | | --- | --- | | Администрирование | пользователи, импорт файлов из staging, выдача и отзыв доступов | | Проекты | проекты, релизы, артефакты, инструкции записи | | Заказы | учёт заказов со ссылкой на конкретную версию | | Загрузка | загрузка файла из браузера частями | | Мои файлы | то, что видит клиент: его файлы по проектам и версиям | Вход — по email: приходит одноразовая ссылка и шестизначный код, действуют 15 минут. Пароля нет. Аккаунты создаёт только администратор. ## Подготовка файлов Один загруженный файл = один артефакт. **Clonezilla-образ** — это каталог с множеством файлов (`Info-*.txt`, `mmcblk0p*-ptcl-img.zst.*`, таблицы разделов). Каталог упаковывается целиком в один tar **без сжатия**: содержимое уже сжато zstd, повторное сжатие только тратит время. Внутри архива обязан остаться каталог верхнего уровня — без него восстановление сломается. ``` cd /путь/к/родительскому/каталогу tar -cf redchairos-2026-04-25.tar RedChair-2026-04-25 tar -tf redchairos-2026-04-25.tar | head -3 sha256sum redchairos-2026-04-25.tar ``` Первая строка вывода `tar -tf` должна быть именем каталога, а не отдельным файлом. Хеш из `sha256sum` сохраняется — по нему проверяется загрузка. **ISO и IMG** загружаются как есть, без упаковки. **Контрольные суммы и заметки** — отдельными файлами, прикрепляются к тому же релизу в своих ролях. ### Именование `<проект>-<версия>.<расширение>`, только строчные латинские буквы, цифры, дефис и точка. Пробелы, кириллица и заглавные буквы недопустимы. - Есть версия издателя — сохраните её как есть: `kali-autoinstall-2026.2.iso`. - Версии нет, есть дата снятия образа — `ГГГГ-ММ-ДД`: `redchairos-2026-04-25.tar`. - Известен только месяц — `ГГГГ-ММ`: `ilmos-2026-05.tar`. ## Два способа загрузки **Через браузер** — раздел «Загрузка». Файл режется на части по 4 МБ и собирается на сервере. Предел — 2 ГБ; всё, что больше, загружайте по SFTP. **По SFTP** — основной путь для образов. Файл кладётся в каталог staging, после чего появляется в списке импорта. Путь относительно домашнего каталога SFTP-пользователя: ``` domains/<домен кабинета>/private_data/staging/ ``` Реквизиты доступа (хост, пользователь, пароль) выдаёт владелец кабинета отдельно; в этом документе их нет. Используйте клиент с докачкой — WinSCP, FileZilla, `sftp`, `rsync` поверх SSH. Заливайте во временное имя и переименовывайте после завершения, либо проверяйте размер перед импортом: частично залитый файл выглядит в списке как обычный. Staging — перевалочный пункт. После импорта файл оттуда исчезает: байты переезжают в защищённое хранилище. ## Управление из командной строки Всё, что делает администратор в вебе, доступно через CLI по SSH — это основной интерфейс для ИИ-агента, у которого нет почтового ящика для входа. ``` php private_app/bin/portal.php <команда> [key=value ...] [--json] [--actor=] ``` Флаг `--json` даёт машиночитаемый вывод: успех `{"ok":true,...}`, ошибка `{"ok":false,"error":"..."}`. Коды выхода: `0` — успех, `1` — операция не удалась, `2` — неверные аргументы или справка. Ключи принимаются и как `key=value`, и как `--key=value`. | Команда | Назначение | | --- | --- | | `status` | место на диске, размер хранилища, счётчики, содержимое staging | | `staging` | файлы, ожидающие импорта | | `projects` | список проектов | | `project-create slug=... name=... kind=flash-set\|customer-build\|trial [description=...]` | создать проект | | `releases [project=]` | список релизов | | `release-create project= label=... [notes=...]` | создать версию | | `release-status project= label=... status=draft\|stable\|archived` | сменить статус | | `release-notes project= label=... notes=...` | изменить заметки версии | | `import name=<файл в staging> [display=...] [description=...] [sha256=<ожидаемый>]` | импорт из staging | | `files` | импортированные файлы | | `attach project= label=... file= [role=image] [artifact-label=...]` | прикрепить артефакт | | `detach project= label=... file=` | открепить артефакт | | `recipe-set project= title=... [label=...] [body-file=<путь>\|body=]` | создать или обновить инструкцию | | `recipes [project=]` | список инструкций | | `users`, `user-create email=... [role=client\|admin]` | пользователи | | `grant file=... email=...`, `revoke file=... email=...` | выдать и отозвать доступ | | `orders`, `order-create ref=... [project=...] [label=...] [device=...] [status=new]`, `order-status id=... status=...` | заказы | | `report [project=]` | сводка: проекты → релизы → артефакты с хешами | | `help` | справка по командам | Ключ `sha256=` у команды `import` — предохранитель: если посчитанный хеш не совпадёт с ожидаемым, файл не будет импортирован. Всегда указывайте его. Файл в командах `attach`, `detach`, `grant`, `revoke` можно задать идентификатором, его началом, хешем SHA-256 или исходным именем. ## Порядок действий для ИИ-агента Задача «сложить образы в кабинет» выполняется по шагам. Каждый шаг заканчивается проверкой. 1. **Инвентаризация.** Пройти по исходному диску и составить список: путь, размер, что это (ISO, IMG, каталог Clonezilla, заметки), к какому проекту и какой версии относится. Не начинать загрузку, пока список не согласован с владельцем. 2. **Проверка места.** Выполнить `portal.php status --json` и сравнить свободное место с суммарным объёмом загрузки, оставив запас. При нехватке — остановиться и сообщить, не заливать частично. 3. **Упаковка и локальный хеш.** Каталоги Clonezilla упаковать в tar по правилам выше. Для каждого готового файла посчитать `sha256sum` и записать результат — он понадобится дважды. 4. **Загрузка.** Заливать по SFTP в staging с докачкой: при обрыве продолжать с текущего смещения, а не начинать заново. Не заливать несколько гигабайтных файлов параллельно. 5. **Сверка размера.** После загрузки сравнить размер файла в staging (`portal.php staging`) с локальным. Совпал — идти дальше; не совпал — дозалить или перезалить. 6. **Импорт с проверкой хеша.** `portal.php import name=<файл> sha256=<локальный хеш> display=<название>`. Кабинет посчитает хеш сам и откажет при расхождении — это и есть настоящая проверка целостности. Отказ означает битую передачу: перезалить файл. 7. **Проект и версия.** Создать проект, если его нет (`project-create`, тип по правилу из раздела о типах проектов). Создать версию (`release-create`). Прикрепить артефакт с правильной ролью (`attach`). 8. **Фиксация.** Когда состав версии окончателен — `release-status ... status=stable`. После этого артефакты не изменить. 9. **Инструкция записи.** Для образов, из которых делают флешки, добавить инструкцию (`recipe-set`): команда записи с точными параметрами, как проверить носитель после записи, особенности оборудования. 10. **Отчёт.** Выполнить `portal.php report --json` и передать вывод владельцу вместе со списком того, что загрузить не удалось, и причинами. Отдельно сообщить обо всём, что пришлось решать по своему усмотрению. ### Чего делать нельзя - Не переводить версию в stable, пока файл не прошёл импорт с проверкой хеша. - Не удалять исходные файлы с диска-источника: удаление — решение владельца. - Не выдавать доступ к клиентским сборкам без прямого указания. - Не заливать файлы, назначение которых непонятно, и не изобретать проекты и версии: при неочевидном сопоставлении — спросить. ## Типичные ситуации **Файл не появился в списке импорта.** Проверьте, что он лежит непосредственно в staging, а не во вложенном каталоге, и что загрузка завершилась: сравните размер с исходным. SFTP-клиенты часто дают частичному файлу временное имя, но не все. **Загрузка из браузера обрывается на первой части.** Признак того, что часть не укладывается в лимит запроса. Для больших файлов используйте SFTP. **Нужно изменить состав stable-версии.** Нельзя по определению. Создайте новую версию и перенесите в неё нужные артефакты — старая остаётся следом того, что уже отдано клиентам. **Один образ нужен в двух проектах.** Прикрепите один и тот же файл к версиям обоих проектов: на диске он останется в единственном экземпляре. **Клиент не должен больше видеть файл.** Отзовите доступ (`revoke` или раздел «Администрирование») — ссылка на скачивание перестаёт работать немедленно. **Импорт отказал из-за несовпадения хеша.** Файл повреждён при передаче. Он остаётся в staging нетронутым: перезалейте и повторите импорт. ## Безопасность - Вход без пароля, одноразовыми кодами со сроком 15 минут; после шести неверных попыток код блокируется. - Все действия пишутся в журнал: вход, импорт, прикрепление артефакта, выдача и отзыв доступа, скачивание. - Страницы кабинета закрыты от индексации и встраивания в чужие сайты. - Приватность файла определяется назначением доступа в базе, а не тем, что ссылку трудно угадать.