📦 Пакетный менеджер и реестры
📌 Описание
Пакетный менеджер в духе apt/homebrew: приложения описываются манифестом asc.yaml, публикуются в реестрах, ставятся командой asc install <package>. Реестры бывают официальные и кастомные, локальные (file://) и удалённые (https://), включая GitHub-репозитории.
🎯 Сценарии использования
asc install nginx— установка из официального реестра.asc source add https://registry.example.com— подключение кастомного реестра (как apt source).asc source add https://github.com/user/my-app— приложение прямо из GitHub (asc.yaml в корне); для приватного при 404 — предложение подключить токен.asc install https://github.com/user/my-app --branch dev— установка прямо из URL репозитория, вообще без реестра (DMN-040): для форков и пакетов, которые никогда не публиковались.asc source addвыше подключает репозиторий к реестрам насовсем; это — для разовой пробы.- Магазин платформы (🛍️ app-store) — витрина над теми же реестрами.
🏗️ Техническое решение
Манифест asc.yaml (черновик)
name: my-app
version: 1.2.0
type: docker | native | utility
category: web # тема для реестра (databases, ai, bots, game-servers…)
description: "..." # EN в официальном реестре
settings: ./asc.settings.yaml # необязательно: файл настроек приложения (см. ниже)
runtime:
image: nginx:1.27 # для docker
stdin: true # docker, необязательно: держать stdin открытым (docker run -i) — ввод из `asc attach` доходит до приложения
tty: true # docker, необязательно: выделить псевдо-TTY (docker run -t)
# или install/start/stop команды для native
requirements: { ram: 256M, disk: 1G }
healthcheck: { http: /health }ℹ️ В манифесте нет секций
env:,ports:иvolumes:(DMN-027/030): environment-переменные, публикуемые порты и тома объявляются вasc.settings.yaml— настройками с ключомenv:и типамиports/volumes(см. ниже). Один источник истины: что пользователь может настроить — то приложение и получает.
ℹ️ Каждый контейнер
type: dockerполучает повышенный лимит открытых файлов (ulimit nofile, 10240 soft/hard) вместо дефолта самого движка в 1024 — некоторые игровые серверы (задокументированный случай — EOS SDK в 7 Days to Die) виснут или падают при старте на этом дефолте, причём без внятного симптома, кроме тишины в логе после первой же строчки.
🏗️ Локальная сборка образа: image-build (DMN-050)
Приложение type: docker может поставлять собственный Dockerfile и собирать образ локально движком вместо (или наряду с) скачиванием готового:
runtime:
image-build:
context: . # каталог контекста сборки относительно манифеста (по умолчанию '.')
dockerfile: Dockerfile # относительно контекста (по умолчанию 'Dockerfile')
args: # необязательные значения --build-arg
VERSION: "1.0"
tag: asc-local/my-app # необязательно; по умолчанию 'asc-local/<app>:latest'- Только
image→ скачивается, как раньше. - Только
image-build→ образ собирается из Dockerfile пакета при установке (и пересобирается при upgrade / пересоздании контейнера из-за дрейфа настроек; кэш слоёв делает это дёшево). Контекст сборки упаковывается из репозитория пакета и не выходит за его пределы. - И
image, иimage-build→ установщик предлагает выбор: интерактивноasc install <app>печатает два варианта и спрашивает; неинтерактивно (или чтобы пропустить вопрос) передайте--image(скачать готовый) или--build(собрать локально). Выбранный источник записывается вmeta.json, чтобы последующее пересоздание или upgrade использовали тот же вариант без повторного вопроса.
⚠️ Сборка выполняется от демона (root). До появления пер-пользовательской политики контейнеров (DMN-043) сборка рассчитана на доверенные пакеты; базовый образ из
FROMдвижок тянет анонимно (приватные базовые образы для локальной сборки — следующий инкремент).
Сборка всегда идёт через бэкенд BuildKit движка, а не через старый билдер — синтаксис Dockerfile вроде COPY --chmod/--chown требует BuildKit, иначе старый билдер падает с ошибкой «the --chmod option requires BuildKit». В терминале каждый шаг сборки отображается отдельным прогресс-баром в стиле docker build (как и полосы по слоям при docker pull), независимо от уровня логирования.
📐 JSON-схемы манифестов: asc.schema.json, asc.stack.schema.json и asc.settings.schema.json в репозитории
registry.
Настройки приложения: asc.settings.yaml
Настройки приложения выносятся в отдельный файл, на который ссылается asc.yaml (settings: ./asc.settings.yaml). В нём описываются параметры: тип, лимиты, перечисления, значения по умолчанию — при установке пользователь заполняет их (UI платформы рисует форму, CLI задаёт вопросы; в silent-режиме берутся дефолты):
settings:
- key: server_name
type: string # string | number | boolean | enum | secret
title: "Server name"
default: "My Server"
required: true
env: SERVER_NAME # пробрасывается приложению этой env-переменной
- key: max_players
type: number
default: 10
limits: { min: 1, max: 200 } # лимиты значений
- key: difficulty
type: enum # перечисление
values: [peaceful, easy, normal, hard]
default: normal
- key: game_version
type: enum # пресеты, но допускается и своё значение
values: [public, latest_experimental]
default: public
allow_custom: true # любая другая ветка/build id принимается как есть
- key: rcon_password
type: secret # хранится как секрет, маскируется
required: true
- key: enable_backups
type: boolean
default: true
- key: game_port
type: ports # публикуемые порты контейнера (список)
default: [27015]
limits: { min: 1024, max: 65535 }
env: CS2_PORT # в env — через запятую; один порт — как есть
protocol: both # tcp (по умолчанию) | udp | both
- key: game_data
type: volumes # тома приложения (список, формы — ниже)
default: [/home/steam/cs2-dedicated]- Значения настроек сохраняются в
/asc/apps/<id>/config/settings.json(0600 — файл может содержать секреты); при установке заполняются дефолтами, при обновлении новые ключи получают дефолты, а выбор пользователя не трогается. - Проброс в env: каждая настройка с
env: VAR_NAMEпопадает в окружение приложения (секреты тоже — для этого ихenv:и нужен). Для Docker-приложений переменные записываются в env контейнера при создании. Списковые значения (ports,volumes) пробрасываются через запятую. type: ports— публикуемые порты контейнера (порт хоста == порту контейнера). Настройка сenv:держит приложение и Docker синхронными: сервер слушает ровно там, куда проброшен порт.protocolзадаёт транспорт:tcp(по умолчанию),udpилиboth(один и тот же порт хоста==контейнера пробрасывается и на TCP, и на UDP).type: volumes— тома приложения; каждая запись — одна из трёх форм:/путь/в/контейнере— приватные данные приложения: в этот путь контейнера монтируется папка data приложения (/asc/apps/<id>/data). Папка создаётся world-writable (0777): образы работают от произвольных непривилегированных пользователей, а bind-монтирование сохраняет владельца хоста; каталог приложения выше остаётся закрытым. Если образ объявляет числовойUSER uid:gid, папка дополнительно chown'ится под него (DMN-038) — непривилегированный процесс может сделать chown только пути, которым уже владеет, поэтому образу, который при первом старте сам меняет владельца своей папки данных (а не только пишет в неё), без этого падает с EPERM; именованный (steam) или голый числовойUSERбез группы оставляет только world-writable — его группа известна лишь/etc/passwdсамого образа;/путь/в/контейнере:хост— то же, но вместоdataиспользуется указанное после двоеточия: простое имя папки — внутри каталога приложения (/asc/apps/<id>/<папка>;repository,configиmeta.jsonзарезервированы), абсолютный путь — путь хостовой машины, монтируется как есть (существующий каталог сохраняет владельца и права);имя:/путь/в/контейнере[:ro|:rw]— именованный том Docker, Engine создаёт его при первом использовании. Именованные тома — способ разделить данные между приложениями: одно приложение пишет в том, остальные монтируют его:ro(см. стек cs2 в asc-example-apps). Именованные тома не удаляются вместе с приложением.
- Применение изменений: конфигурация контейнера фиксируется при создании, поэтому при следующем
asc app start/asc app restartдемон сравнивает желаемое состояние — env, публикуемые порты, тома, квоту, команду запуска — с фактическим состоянием контейнера и пересоздаёт контейнер при расхождении (или если контейнер пропал). Данные приложения живут в томах и переживают пересоздание. Если желаемое состояние вычислить не удалось (например, источник реестра удалён) — приложение всё равно стартует как есть, с предупреждением в логе: доступность важнее. - Изменение настроек —
asc app settings <id>: интерактивный редактор в терминале. Сначала показываются категории —environments(настройки string/number/boolean/enum/secret),ports,volumes,quota,start_command— затем настройки выбранной категории: выбираете по номеру, вводите значение, оно валидируется по описанию (тип,limits, значенияvaluesу enum; секреты в списке маскируются; порты и тома вводятся списком через пробел). Также через UI платформы. После изменения — перезапуск приложения (asc app restart <id>). allow_custom(только type: enum) — принимает любое значение вне спискаvaluesкак свободный текст, вместо отклонения. Используйте для перечислений, где перечислены частые пресеты, но пользователя не должно ограничивать значение, которое автор не предусмотрел (ветка/build id игры, своё имя мира). Пронумерованный список вasc app settingsпо-прежнему показывает пресеты; ввод чего-то другого просто принимается.
📏 Квоты ресурсов (quota)
Секция quota: в asc.settings.yaml ограничивает ресурсы инстанса приложения (DMN-021):
quota:
max_cpu: 2 # лимит CPU в ядрах (0.5, 2, …)
max_ram: 1G # лимит памяти: 512M, 2G, … (двоичные единицы, как docker -m)
max_disk: 10G # лимит места на диске- Значения нормализуются при установке/обновлении и записываются в
meta.json;asc app info <id>показывает их (quota: cpu ≤ 2, ram ≤ 1.0 GiB, …). - Docker-приложения: применяются при создании контейнера через Engine API (
NanoCpus,Memory). - native/process: записываются в
meta.json; применение через cgroups — следующий инкремент. max_diskзаписывается для всех рантаймов; дисковое ограничение per-runtime (Docker storage-opt / квоты ФС) — инкрементально.- Пользовательские переопределения (DMN-030): категория
quotaвasc app settingsпереопределяет отдельные поля поверх значений пакета ('-'сбрасывает поле обратно); переопределение хранится вsettings.jsonи применяется через пересоздание контейнера при следующем перезапуске.
🚀 Команда запуска (start_command)
Команда запуска приложения настраивается в asc.settings.yaml. В строку можно подставлять environment-переменные пакета — синтаксис ${VAR}:
start_command: "steamcmd +force_install_dir /data +login anonymous +app_update ${STEAM_APP_ID} validate +quit"- Подстановка выполняется демоном при установке/обновлении из env приложения — значений настроек с ключами
env:, включая дефолты. Неразрешённая переменная — ошибка установки с указанием имени переменной. - Docker-приложения: команда заменяет то, что запустил бы образ (entrypoint становится
/bin/sh -c, поэтому аргументы и кавычки работают как в shell). - native-приложения: команда переопределяет
runtime.startизasc.yaml. - Подстановка из итогового окружения приложения (env-уровни организации/ноды/приложения — 🌱 environments) и предпросмотр команды в UI — следующий инкремент; значения настроек уже доходят до приложения env-переменными (см. раздел настроек выше).
- Пользовательское переопределение (DMN-030): категория
start_commandвasc app settingsзаменяет команду пакета для этого инстанса ('-'сбрасывает обратно); ссылки${VAR}разрешаются из env настроек при применении.
🐳 Скрипты install/update: native или docker
Скрипты install и update пакета могут исполняться как нативно на хосте, так и в docker — управляется полем run_in в блоке scripts: манифеста:
scripts:
install:
run: ./scripts/install.sh
run_in: native # native | docker
update:
run: ./scripts/update.sh
run_in: docker # одноразовый контейнер
image: debian:12 # образ для docker-исполнения (опционально)native— скрипт исполняется на хосте от пользователя приложения.docker— скрипт исполняется в одноразовом контейнере с примонтированным каталогом/asc/apps/<id>/(изоляция зависимостей сборки от хоста).- По умолчанию
run_inнаследуетtypeпакета:docker→ docker,native/utility→ native.
Механика установки: клонирование репозитория
Установка приложения = клонирование его репозитория:
asc install <package>→ демон клонирует репозиторий пакета в/asc/apps/<id>/repository/.- Версии приложения = git-теги (GitHub tags), берутся из репозитория, а не из реестра (DMN-047): установка конкретной версии —
asc install <package>@1.2.0(checkout тега);asc install <package>без версии резолвит последний тег репозитория черезgit ls-remote(нет тегов → HEAD ветки по умолчанию);asc install <package>@(пустой@) показывает теги и ветки репозитория для интерактивного выбора (DMN-048), либо неинтерактивно возвращает список доступных версий ошибкой. Обновление —asc app upgrade <name>(checkout нового тега). Поэтому индекс реестра не хранит поле версии — версии пакета это то, чем протегирован его репозиторий. - Согласие с лицензией (DMN-028, DMN-032): если клонированный пакет содержит лицензию (
LICENSE.md/LICENSE/LICENSE.txt), CLI показывает, откуда ставится пакет (источник реестра + репозиторий), выводит текст лицензии и спрашивает согласие — отказ прерывает установку, не оставляя следов. Лицензия сначала ищется в каталоге самого пакета (пакет монорепозитория может иметь свою лицензию), затем в корне репозитория. Неинтерактивный ввод принимает лицензию автоматически с печатным уведомлением; вызовы через API получают структурированную ошибку с источником, репозиторием и текстом лицензии (UI платформы отрисует свой диалог согласия). Для стека вопрос задаётся один раз на репозиторий. Пакеты без файла лицензии ставятся без вопроса. - Пользовательское название и несколько инстансов (DMN-024, DMN-033): в терминале
asc installспрашивает название приложения — Enter оставляет значение по умолчанию, любой другой ввод становится названием приложения. Неинтерактивно — флаг--name "My Server". Установка уже установленного пакета больше не завершается ошибкой: создаётся новый инстанс со следующим свободным id (<пакет>-2,<пакет>-3, …), который становится и егоcustom_name, если--nameего не переопределяет. Название хранится вmeta.json(custom_name), должно быть уникально среди приложений пользователя, переживает обновления, и все команды принимают его наравне с id. Суффиксированный инстанс запоминает пакет реестра, из которого он поставлен (meta.package), поэтомуasc app upgradeпродолжает резолвить его корректно. - Дальше демон работает с локальной копией: читает
asc.yaml/asc.settings.yaml, собирает/запускает по типу приложения. - Для Docker-приложений контейнер создаётся через Engine API; отсутствующий на хосте образ скачивается автоматически из его реестра (
runtime.image; имя без тега означаетlatest) — и при установке, и при обновлении. - Прогресс-бары: в терминале клонирование репозитория (
git clone --progress) и скачивание Docker-образа отображаются живыми полосами прогресса (в стилеdocker pull/docker-compose pull— по одной полосе на слой образа) — включены по умолчанию, независимо отasc config debug. При неинтерактивном вызове (перенаправленный вывод, API демона) полос нет — те же события всегда доступны как debug-логи (asc config debug on).
Requirements при запуске (DMN-029): requirements манифеста (ram, disk, cpu) сравниваются с тем, что свободно на хосте в момент запуска приложения. При нехватке asc app start предупреждает с точными цифрами и — в терминале — спрашивает, запускать ли всё равно на свой страх и риск; неинтерактивные вызовы получают предупреждение в stderr и продолжают. Проверка — совет, а не запрет: ошибки чтения никогда не блокируют запуск.
Обновление (asc app upgrade <name>[@версия], синоним — asc upgrade): приложение должно быть остановлено; новый тег клонируется рядом с текущей копией (repository.new), манифест валидируется, и только затем каталоги меняются местами и рантайм пересоздаётся (для Docker — контейнер пересоздаётся с новым образом). Ошибка до подмены не трогает установленное приложение; ошибка пересоздания рантайма откатывает на предыдущую версию. Без явной версии берётся последний тег репозитория (DMN-047); репозиторий без тегов нельзя обновить без явной @версии.
Прямая установка из git-репозитория (asc install <url> [--branch <имя>|--tag <имя>], DMN-040): если спецификация — git-URL (https://, ssh:// или scp-подобный git@хост:путь), а не имя пакета, демон полностью пропускает реестр и клонирует репозиторий напрямую — тот же конвейер клонирование/манифест/провижининг, что и при установке из реестра, минус шаг резолвинга. asc.yaml должен лежать в корне репозитория (без пути монорепозитория — резолвить его неоткуда, нет записи реестра). --branch/--tag выбирают ref для checkout; без флагов клонируется HEAD ветки по умолчанию. Id приложения по умолчанию — имя самого репозитория (bar и для https://github.com/foo/bar.git, и для git@github.com:foo/bar); --name переопределяет его, как и при установке из реестра. Приватные репозитории используют ровно ту же авторизацию asc auth, что и ниже — установка по URL это установка из реестра с выброшенным шагом резолвинга. asc upgrade пока не резолвит приложения, установленные так (резолвить не из чего — нет записи реестра); повторный asc install с тем же URL создаёт новый инстанс, а не обновляет существующий.
Учётные данные (DMN-045/046): единый пользовательский стор хранит авторизацию и для приватных репозиториев (git clone), и для приватных реестров образов (pull через Engine), различая их полем type (repo | registry). Записи ключуются на хост или префикс (github.com/myorg, ghcr.io/myorg) и хранятся отдельно от списков источников, в JSON: /etc/asc/auth.json (root) и ~/.asc/auth.json (пользователь, рядом с остальным пер-пользовательским деревом DMN-041), оба файла 0600. Секреты не попадают ни в world-readable файлы, ни в argv git-процессов (argv виден всем пользователям через /proc).
{
"credentials": [
{ "type": "repo", "pattern": "github.com/myorg", "token": "ghp_xxx" },
{ "type": "registry", "pattern": "ghcr.io/myorg", "username": "me", "token": "ghp_yyy" },
{ "type": "repo", "pattern": "github.com/myorg/secret-app", "app": "6f8a…uuid", "key": "/home/me/.ssh/id_ed25519" }
]
}- Типы:
repoавторизует git clone — токен дляhttps://-URL (черезGIT_ASKPASS+ переменную окружения процесса git) или SSH-ключ дляgit@/ssh://-URL (GIT_SSH_COMMANDc-i <ключ> -o IdentitiesOnly=yes).registryавторизует pull образа — токен вместе с username, уходит в Docker Engine заголовкомX-Registry-Auth(с реестром связывается Engine, а не демон, поэтому TLS-стек на стороне демона не нужен). Registry-запись отвергает SSH-ключ и требует--username. - Привязка к приложению (
app, DMN-044): учётные данные можно ограничить одним приложением по его uuid или id (--app) — токен обслуживает ровно нужное приложение и никакое другое. Привязанная запись невидима для остальных приложений и для «своего» приложения побеждает равную по длине непривязанную; безappучётные данные применяются ко всем приложениям, чей URL/образ совпал с префиксом. В остальном правило совпадения одинаково для обоих типов: выбирается самый длинный префикс на границе пути, записи пользователя приоритетнее системных. - Детекция: git всегда запускается с
GIT_TERMINAL_PROMPT=0иBatchMode=yes— клонирование приватного репозитория без настроенной авторизации не подвисает на запросе пароля, а падает с распознаваемой ошибкой (включая «Repository not found», который GitHub отдаёт для приватных репозиториев без доступа). Pull приватного образа показывает собственную ошибку авторизации Engine. - Интерактивная настройка: обнаружив приватный репозиторий, CLI в терминале спрашивает разрешение настроить авторизацию сразу: для https — ввод токена, для ssh — выбор из найденных приватных ключей
~/.ssh; выбор сохраняется, установка повторяется автоматически. Неинтерактивный вызов (API, скрипты) получает структурированную ошибку с подсказкойasc auth add .... - Миграция: старые TOML-файлы (
/etc/asc/git-auth.toml,~/.config/asc/git-auth.toml) до DMN-045 по-прежнему читаются, если JSON-стора ещё нет — их записи безtypeгрузятся какrepo— и мигрируют вauth.jsonпри первой записи черезasc auth, так что настроенная авторизация переживает обновление. - CLI:
asc auth add <хост|префикс> [--type repo|registry] --token <токен> [--username <user>] [--app <uuid|id>]·asc auth add <хост> --ssh-key [путь](без пути — интерактивный выбор ключа) ·asc auth list(типы и методы без секретов) ·asc auth remove <хост> [--type repo|registry].
Несколько приложений в одном репозитории: asc.stack.yaml
Правило корня: репозиторий-пакет может содержать сколько угодно asc.yaml в подкаталогах, но в его корне обязан лежать ровно один манифест — либо asc.yaml (одиночное приложение), либо asc.stack.yaml (стек), который соединяет все вложенные asc.yaml. Вложенные манифесты без корневого не индексируются.
Манифест-стек asc.stack.yaml перечисляет приложения и пути к их asc.yaml:
name: my-stack
version: 1.0.0
description: "..."
apps:
- name: web
path: ./web # каталог с asc.yaml
- name: worker
path: ./worker
- name: db
path: ./db
optional: true # необязательный компонент стекаasc install my-stack— установка всего стека;asc install my-stack/web— только одного приложения из него.- Переименование стека при установке (DMN-034):
asc install my-stack --name prod— это префикс, применяемый ко всем устанавливаемым приложениям —prod-web,prod-worker,prod-db— так как у стека нет собственной сущности, только приложения-участники.asc install my-stack/web --name prod-webназывает только запрошенное приложение, как при установке одиночного приложения. - Стек может объявлять зависимости между приложениями (
depends_on— порядок запуска), компоненты могут бытьoptional. Environment-переменные живут вasc.settings.yamlкаждого приложения. - Реестры и магазин платформы индексируют как одиночные
asc.yaml, так и стекиasc.stack.yaml. - Примеры — в репозитории asc-example-apps.
Механика установки стека: репозиторий клонируется один раз для чтения asc.stack.yaml, затем каждое выбранное приложение устанавливается как обычное — со своим клоном репозитория, каталогом /asc/apps/<id>/ и meta.json:
- id приложения — это
nameиз его собственногоasc.yaml(в примере выше приложениеwebстека может называтьсяmy-stack-web); происхождение записывается в meta.json какpackage: "my-stack/web"— по немуasc app upgradeзаново резолвит пакет. - Порядок: зависимости (
depends_on) устанавливаются первыми; циклы отклоняются при валидации.asc install my-stackставит все компоненты кромеoptional;asc install my-stack/dbставит запрошенный компонент (в том числеoptional) и его зависимости. - Повторная установка: запрошенное приложение (то, что указано явно, а не подтянутая зависимость), если оно уже установлено, становится новым инстансом (DMN-033) вместо пропуска; уже установленная зависимость по-прежнему переиспользуется, а не дублируется. Каждое приложение ставится атомарно (ошибка убирает только его каталог, ранее установленные компоненты остаются).
- Согласие с лицензией запрашивается один раз на репозиторий (один репозиторий = одна лицензия), а не на каждое приложение стека.
Реестры
- Формат реестра (repo
registry) — иерархия JSON-файлов: корневой индексregistry.json→ файлы категорийcategories/<тема>.json(databases, ai, bots, game-servers, system-utilities, web…) → опциональные подкатегории (children). Пакеты бывают двух типов:app(asc.yaml) иstack(asc.stack.yaml). Схемы валидации — вregistry/schema/. Описания — на английском. - Дерево источников: sourcelist демона → из всех реестров строится дерево (по ссылкам
index/childrenкорневого индекса), затем объединённый список приложений (для каждого пользователя); в результатах поиска конфликт имён решает приоритет источника. - Конфликт имён при установке: если пакет предоставляют несколько источников,
asc installв терминале выводит список кандидатов (имя источника + репозиторий) и спрашивает, какой использовать (выбор номера); неинтерактивные вызовы получают ошибку с тем же списком — реестр указывается явно:asc install <пакет> --source <имя>(API: полеsourceв InstallAppRequest).asc app upgradeпредпочитает источник, из которого приложение было установлено. - Типы источников:
file://(локальный каталог) иhttps://(реестр, GitHub raw). - Устойчивость загрузки (DMN-036): каждый файл индекса реестра (
registry.json, файлы категорий) — отдельный вызовcurlбез переиспользования соединения между ними, то есть весьasc update/asc search— это короткая серия из нескольких мелких HTTPS-запросов к одному хосту. Раньше зависшее соединение на любом из них (throttling CDN, временный сетевой сбой) вешало всю команду на срок до 5 минут без единого вывода. Теперь запросы к реестру используют короткий таймаут на запрос (20с) и пару ретраев на транзиентные ошибки — вместо щедрого бюджета в 300с, зарезервированного для больших загрузок (релизные файлыasc-updater). - Прогресс
asc update(DMN-037): в терминале на каждый файл индекса выводится своя строка прогресса, в стилеdocker pull/git clone— спиннер, пока запрос выполняется, и заморозка на размере в байтах при успехе или на тексте ошибки при провале. Поскольку реестр забирается по одному мелкому файлу за раз, это превращает застрявшую загрузку в видимо застрявший спиннер вместо молчаливого ожидания. - Source list по пользователям: два уровня списков —
- системный
/etc/asc/sources.toml— правит root (sudo asc source add|remove), источники видны всем пользователям сервера; - пользовательский
~/.config/asc/sources.toml— каждый пользователь ведёт свой список (asc source add|removeбез sudo), он дополняет системный. - Эффективный список = системные источники (приоритетнее) + свои; затенять и удалять системные источники пользователь не может (
asc source listпоказывает происхождение каждого источника). Кэш индексов у root — вdata_dir, у пользователя — в~/.cache/asc/.
- системный
- Политика установки (
[policy]в/etc/asc/config.toml, правит root):user_install = "all"(по умолчанию — пользователи ставят любые пакеты: Docker, нативные, утилиты) илиuser_install = "docker"(пользователям — только Docker-приложения; нативные и утилиты ставит только root). Применяется приasc install; на root не действует. - Кэш индексов с TTL +
asc updateдля принудительного обновления. - CLI:
asc install|remove|upgrade <pkg>(илиasc install <git-url> [--branch|--tag]),asc search <query>,asc source add|remove|list,asc update.
🔗 Связанные задачи
DMN-003, DMN-018, DMN-038, DMN-040, DMN-045, DMN-046, DMN-047, DMN-048, REG-001, REG-002, BE-002, BE-003 в ROADMAP.md; GRW-011 в ROADMAP-GROWTH.md.