Add altsp-download-repo.sh: build standalone offline apt-rpm repo for ALT SP Server

Downloads one or more packages together with their full dependency
closure (resolved against an empty rpm db so the result works on a
target machine with an arbitrary baseline, not just what's missing on
the machine running the script), then builds a local apt-rpm "classic"
repository via genbasedir --bloat (required: without --bloat, genbasedir
strips version data from some soname Provides, e.g. libssh2 -> mc, which
breaks dependency resolution on a truly clean target even though the
same packages resolve fine against the real upstream repo).

Verified end-to-end against a live ALT SP Server 10.2.2 test machine,
including simulating a from-scratch install using only the generated
repo (no upstream access).
This commit is contained in:
2026-09-22 03:33:52 +03:00
commit 33e8d18f94
4 changed files with 229 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
# altsp-downloader
Скрипт для ALT SP Server: скачивает один или несколько пакетов вместе со
всеми зависимостями и собирает из них автономный локальный apt-rpm
репозиторий (схема `classic`), готовый для переноса на машину без
интернета.
## Требования
- ALT Linux / ALT SP Server, apt-rpm (`apt-get`, `rpm`).
- Доступ к реальным (интернет) репозиториям на машине, где запускается
скрипт.
- root / sudo.
Пакет `apt-repo-tools` (для `genbasedir`) устанавливается скриптом
автоматически, если отсутствует.
## Использование
```bash
sudo ./altsp-download-repo.sh [-o|--output DIR] PKG1 [PKG2 ...]
```
- Пакеты передаются аргументами командной строки — можно указать сразу
несколько для batch-скачивания.
- `-o/--output DIR` — каталог репозитория (по умолчанию `./altsp-repo`).
- `--skip-update` — пропустить `apt-get update` перед скачиванием.
Пример:
```bash
sudo ./altsp-download-repo.sh -o /srv/offline-repo bash mc htop
```
Повторные запуски с другим набором пакетов дополняют существующий каталог
репозитория, не скачивая заново уже имеющиеся пакеты.
## Как это работает
Зависимости резолвятся против **пустой** rpm-базы (`rpm --initdb` во
временном fakeroot + `apt-get -o RPM::RootDir=...`), поэтому скачивается
**полное** дерево зависимостей запрошенных пакетов, а не только то, чего
не хватает на машине, где запущен скрипт. Это важно, так как репозиторий
предназначен для переноса на другую, возможно не идентичную по составу
пакетов машину.
Скачанные `.rpm` раскладываются по архитектурам
(`<repo>/<arch>/RPMS.classic/`), для каждой архитектуры генерируются
метаданные через `genbasedir` (`<repo>/<arch>/base/`).
## Установка на офлайн-машине
Результат работы скрипта (`README.txt` внутри каталога репозитория)
содержит готовые строки для `sources.list`, например:
```
rpm file:/srv/offline-repo x86_64 classic
```
Затем:
```bash
apt-get update
apt-get install <имена пакетов>
```
Подпись репозитория не требуется — тег вроде `[cert8]` указывать не нужно.