Files
Das-OS/docs/how-to-build-a-distro_ua.md

653 lines
71 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Як створити власний дистрибутив Linux
Докладна інструкція: від вибору основи до опублікованого релізу. Загальні поради підкріплено прикладами з Das OS (Void Linux + Xfce): шляхи на кшталт `scripts/container/build-iso.sh` ведуть до файлів цього репозиторію, а позначка **«Досвід Das OS»** — до реальних помилок, на які ми натрапили.
## Зміст
1. [Що таке «власний дистрибутив»](#1-що-таке-власний-дистрибутив)
2. [Планування перед першим рядком коду](#2-планування-перед-першим-рядком-коду)
3. [Вибір основи](#3-вибір-основи)
4. [Середовище збирання](#4-середовище-збирання)
5. [Власні пакети й репозиторій](#5-власні-пакети-й-репозиторій)
6. [Як влаштований live-образ](#6-як-влаштований-live-образ)
7. [Збирання ISO](#7-збирання-iso)
8. [Налаштування за замовчуванням і оформлення](#8-налаштування-за-замовчуванням-і-оформлення)
9. [Інсталятор](#9-інсталятор)
10. [Завантажувач, initramfs і розмітка диска](#10-завантажувач-initramfs-і-розмітка-диска)
11. [Оновлення, знімки й відкат](#11-оновлення-знімки-й-відкат)
12. [Тестування](#12-тестування)
13. [CI і релізи](#13-ci-і-релізи)
14. [Безпека](#14-безпека)
15. [Ліцензії й торгові марки](#15-ліцензії-й-торгові-марки)
16. [Локалізація й доступність](#16-локалізація-й-доступність)
17. [Документація та спільнота](#17-документація-та-спільнота)
18. [Типові пастки](#18-типові-пастки)
19. [Покроковий план з нуля](#19-покроковий-план-з-нуля)
20. [Чекліст перед релізом](#20-чекліст-перед-релізом)
21. [Корисні посилання](#21-корисні-посилання)
---
## 1. Що таке «власний дистрибутив»
Дистрибутив — це не ядро і не набір програм, а **рішення**: які пакети встановлені, як вони налаштовані, як система завантажується, встановлюється й оновлюється. Залежно від того, скільки рішень ви берете на себе, розрізняють кілька рівнів:
| Рівень | Що ви робите | Приклади | Складність |
|---|---|---|---|
| **Ремікс (респін)** | Готовий дистрибутив + свої пакети й налаштування, той самий репозиторій | Ремікси Ubuntu через Cubic, Fedora Remix | Низька |
| **Похідний дистрибутив** | Основа upstream + власний репозиторій пакетів, оформлення, інсталятор, утиліти | Linux Mint, Pop!_OS, EndeavourOS, **Das OS** | Середня |
| **Форк** | Власна копія всього дерева пакетів, власний цикл випусків | Devuan, Rocky Linux | Висока |
| **З нуля** | Збираєте кожен пакет самі, власний менеджер пакетів | Linux From Scratch, Void, Alpine | Дуже висока |
**Рекомендація:** починайте з похідного дистрибутива. Upstream дає безпекові оновлення тисяч пакетів, а ви зосереджуєтеся на тому, що відрізняє ваш дистрибутив. Кожен пакет, який ви «забираєте» собі, — це назавжди ваш обов'язок стежити за його CVE.
Головний принцип, який варто прийняти з першого дня: **усі зміни постачаються пакетами**. Не правте файли в образі руками й не «доналаштовуйте» систему скриптом після встановлення. Пакет можна оновити, відкотити, подивитися його вміст (`xbps-query -f das-settings`, `dpkg -L`, `pacman -Ql`), а скрипт — лише запустити ще раз і сподіватися.
---
## 2. Планування перед першим рядком коду
Запишіть відповіді на ці запитання в README або окремий документ. Без них проєкт розповзається.
### 2.1. Для кого і навіщо
- Хто користувач: новачок, розробник, адміністратор серверів, старий ноутбук, вбудована система?
- Яку конкретну проблему ви вирішуєте, якої не вирішує основа? «Гарніші шпалери» — не причина для дистрибутива, а «Void, готовий до роботи за 10 хвилин замість кількох годин налаштувань» — так.
- Які варіанти образів: десктоп, сервер, мінімальний, ARM? Кожен варіант множить тестування.
### 2.2. Технічні рішення, які важко змінити потім
| Рішення | Варіанти | Наслідки |
|---|---|---|
| Основа | Debian, Ubuntu, Fedora, Arch, Void, Alpine, NixOS… | Менеджер пакетів, цикл випусків, інструменти збирання |
| Модель випусків | Rolling / фіксовані версії / LTS | Rolling ламається частіше; фіксовані вимагають гілок і бекпортів |
| init | systemd / runit / OpenRC / s6 | Багато програм (GNOME, частина Flatpak-порталів, snap) очікують systemd |
| libc | glibc / musl | musl менший, але ламає бінарні програми (Steam, драйвери NVIDIA, частину Python-коліс) |
| Архітектури | x86_64, aarch64, i686… | Кожна — окреме збирання й тестування |
| Файлова система | ext4 / Btrfs / XFS / ZFS | Btrfs дає знімки й відкат; ZFS — ліцензійно складний |
| Середовище | Xfce, KDE, GNOME, без графіки | Розмір образу, вимоги до пам'яті, кількість налаштувань |
| Завантаження | UEFI, BIOS, Secure Boot | Secure Boot потребує підписаного ланцюжка (див. [10.5](#105-secure-boot)) |
**Das OS:** Void (rolling, runit, glibc), x86_64, Btrfs зі знімками, Xfce; окремий консольний серверний образ на тих самих пакетах.
### 2.3. Назва й ідентифікатори
- Перевірте назву: DistroWatch, GitHub, пошук торгових марок, домен. Назва не повинна містити чужих марок («Ubuntu», «Fedora», «Windows»).
- Оберіть короткий машинний ідентифікатор (`dasos`): він піде в `ID=` у `/etc/os-release`, імена пакетів (`das-*`), мітку ISO, ім'я файлу образу, теку бренду Calamares.
- Префікс для власних пакетів (`das-`) одразу показує, що пакет ваш, і не перетинається з upstream.
### 2.4. Версіонування
- Одна версія дистрибутива в одному місці (`VERSION`), з якої беруться ім'я ISO, меню завантаження, інсталятор і тег релізу.
- Версії власних пакетів незалежні від версії дистрибутива; підвищуйте їх при кожній зміні пакета, інакше менеджер пакетів не оновить установлені системи.
- Узгодьте правило: SemVer (`0.9.1`), календарні версії (`24.04`) або кодові імена. Головне — не змінювати схему посеред шляху.
---
## 3. Вибір основи
| Основа | Інструмент live-образу | Збирання пакетів | Сильні сторони | На що зважати |
|---|---|---|---|---|
| **Debian** | `live-build` (`lb config`, `lb build`) | `dpkg-buildpackage`, `sbuild`, `reprepro`/`aptly` для репозиторію | Стабільність, величезний вибір пакетів, дозвільна політика назв | Пакети «старі»; оформлення deb-пакетів багатослівне |
| **Ubuntu** | `livecd-rootfs`, для реміксів — Cubic | Launchpad PPA, `sbuild` | Драйвери, підтримка заліза, Secure Boot «з коробки» | Суворі правила торгових марок, snap |
| **Fedora** | KIWI, `livemedia-creator` + kickstart, `lorax` | `rpmbuild`, `mock`, COPR | Свіжий стек, SELinux, Secure Boot | Короткий цикл (≈13 міс. підтримки), треба замінити `fedora-logos` на `generic-logos` |
| **openSUSE** | KIWI | Open Build Service (OBS) | OBS збирає пакети й образи для багатьох дистрибутивів | Більше інфраструктури |
| **Arch** | `archiso` (`mkarchiso`) | `makepkg`, `repo-add` | Простий PKGBUILD, rolling, AUR | Часті ламкі оновлення; Secure Boot вручну |
| **Void** | `void-mklive` (`mklive.sh`) | `xbps-src`, `xbps-rindex` | Швидкий, простий, runit, чисті шаблони | Менша спільнота, немає Secure Boot з коробки |
| **Alpine** | `aports/scripts/mkimage.sh` | `abuild` | Дуже маленький, musl | musl: не всі бінарні програми працюють |
| **NixOS** | `nixos-generators`, `isoImage` у flake | Nix-вирази | Повністю декларативна й відтворювана система | Інша модель мислення, свій шлях до всього |
| **Gentoo** | `catalyst` | ebuild | Повний контроль над прапорцями збирання | Збирання з вихідних кодів займає години |
Критерії вибору:
1. **Ви вже знаєте цю систему?** Найважливіший критерій: налагоджувати доведеться саме менеджер пакетів і процес завантаження.
2. **Чи є інструмент для live-образу,** який підтримує upstream? Писати свій з нуля — тижні роботи.
3. **Чи легко зібрати власний пакет** і підключити свій репозиторій поруч з основним?
4. **Політика назв і логотипів** основи (див. [15](#15-ліцензії-й-торгові-марки)).
5. **Життєвий цикл:** скільки часу основу підтримують і як часто доведеться переходити на нову версію.
---
## 4. Середовище збирання
### 4.1. Збирайте в контейнері
Збирання на робочій машині з «чимось, що колись встановили» не відтворюється на іншому комп'ютері. Контейнер з основою дистрибутива вирішує це:
- інструменти (`xbps-src`, `mklive`, `live-build`, `archiso`) працюють у «рідній» системі, хост може бути будь-яким Linux із Docker;
- пакети збираються проти тієї самої glibc і бібліотек, з якими поставляються.
**Das OS:** `docker/builder/Dockerfile` — образ на основі `void-glibc-full`, `scripts/builder.sh` запускає в ньому будь-яку команду, проєкт змонтовано в `/work`.
> Вимоги до образу збирача беруться з основи дистрибутива, а не з загальних звичок. Наприклад, для Void це образ Void, а не Alpine: `xbps-src` і `mklive` потребують `xbps`.
### 4.2. Привілеї
Збирання live-образу монтує `/proc`, `/sys`, `/dev`, loop-пристрої та chroot, тому контейнер запускається з `--privileged` (або з `CAP_SYS_ADMIN` і доступом до `/dev/loop*`). Наслідки:
- не запускайте збирання на спільному сервері з недовіреним кодом;
- перерване збирання може лишити змонтовані файлові системи й файли, що належать root (`make clean` у Das OS прибирає їх зсередини контейнера);
- інструменти пакетування часто **відмовляються працювати від root** (`xbps-src`, `makepkg`): створіть у контейнері непривілейованого користувача з UID хоста, щоб файли в `out/` належали вам (`scripts/container/build-packages.sh`).
### 4.3. Закріплюйте версії інструментів
- Інструмент live-образу — на конкретному коміті (`ARG MKLIVE_COMMIT=8ca31d1`), оновлюйте свідомо й перевіряйте.
- Базовий образ контейнера бажано закріпити за дайджестом (`image@sha256:…`), а не `:latest`, якщо потрібна точна відтворюваність.
- Якщо ви **латаєте** upstream-інструмент (`sed` по скрипту mklive), спершу перевіряйте, що шуканий рядок існує, і падайте з помилкою, якщо його немає. Інакше після оновлення інструмента латка тихо перестане застосовуватися (так зроблено в `build-iso.sh`).
### 4.4. Кеші й місце на диску
- Кеш завантажених пакетів (`/var/cache/xbps`, `/var/cache/apt/archives`, `/var/cache/pacman/pkg`) монтуйте з хоста: повторне збирання не качатиме гігабайти.
- Дерево збирання пакетів (`void-packages`, `masterdir`/chroot) теж зберігайте між запусками.
- Закладіть **30–50 ГБ** вільного місця: chroot збирача, кеш, робоча коренева система образу, squashfs і сам ISO.
- SSD суттєво пришвидшує збирання (Das OS: перехід CI на SSD скоротив збирання ISO з ~45 до ~22 хв).
### 4.5. Відтворюваність
- `SOURCE_DATE_EPOCH` фіксує дати у файлах, які це підтримують.
- Не використовуйте в збиранні мережеві ресурси без версії («завантаж останній реліз з GitHub»).
- Збирайте з чистого дерева git; версію образу беріть із файлу в репозиторії, а не з дати.
---
## 5. Власні пакети й репозиторій
### 5.1. Що оформлювати пакетами
| Пакет | Вміст | Приклад у Das OS |
|---|---|---|
| Налаштування | Конфіги за замовчуванням, служби, drop-in файли | `das-settings` |
| Оформлення | Тема GTK/Qt, іконки, шпалери, логотипи, шрифти | `das-theme`, `font-jetbrains-mono`, `adw-gtk3` |
| Утиліти | Ваші програми | `das-tools`, `das-helpers`, `das-shell` |
| Інсталятор | Конфіги Calamares, скрипти | `das-installer`, `das-server-installer`, `das-install-common` |
| Метапакет | Лише залежності: «що входить у варіант» | `das-server` |
| Пакети з upstream | Новіша або перезібрана версія чужого пакета | `calamares` |
### 5.2. Правила гарного пакета
1. **Не перезаписуйте файли інших пакетів.** Менеджер пакетів або відмовиться, або наступне оновлення upstream поверне все назад. Замість цього:
- використовуйте каталоги drop-in: `/etc/sudoers.d/`, `/etc/sysctl.d/`, `/etc/xbps.d/`, `/etc/ssh/sshd_config.d/`, `/usr/share/lightdm/lightdm.conf.d/`, `/etc/profile.d/`, `/etc/bash/bashrc.d/`;
- для XDG-налаштувань — окремий каталог, доданий **на початок** `XDG_CONFIG_DIRS` (Das OS: `/etc/xdg/das` через `/etc/profile.d/das-xdg.sh`): стандартні файли лишаються недоторканими, а налаштування користувача в `~/.config` все одно мають пріоритет;
- для GNOME — dconf-профілі й `*.gschema.override`, для KDE — `/etc/xdg/kdeglobals`.
2. **Позначайте конфігураційні файли** (`conf_files` у xbps, `backup=()` у pacman, conffiles у deb), щоб оновлення не стерло зміни адміністратора.
3. **Не чіпайте `/home` і `/etc/skel` без потреби.** `/etc/skel` копіюється лише при створенні користувача, тож оновлення до вже створених користувачів не дійдуть. Краще системні значення за замовчуванням, які користувач може перевизначити.
4. **Залежності — явно.** Метапакет перелічує все, що потрібно варіанту; пакет налаштувань залежить від програм, які він налаштовує.
5. **Підвищуйте версію або ревізію** при кожній зміні. Інакше `xbps-install -Su`/`apt upgrade` нічого не побачить.
6. **Тести під час збирання** (`go test`, `python -m unittest`) ловлять помилки до того, як вони потраплять в образ.
7. **Ліцензія** в кожному пакеті (`vlicense`), навіть у пакеті з конфігами.
### 5.3. Збирання поверх дерева upstream
Інструменти пакетування зазвичай очікують повне дерево пакетів (спільні build-style, хуки, залежності). Робочий підхід:
- неглибокий клон дерева upstream (`git clone --depth 1 void-packages`);
- ваші шаблони копіюються поверх (`srcpkgs/<назва>`);
- збирання й публікація у власний локальний репозиторій (`out/hostdir/binpkgs`).
Нюанси, які ми врахували в `build-packages.sh`:
- **Інкрементальне збирання.** Пакет перезбирається лише тоді, коли змінився його каталог (хеш файлів), зник бінарний пакет або upstream оновив бібліотеку, з якою пакет зв'язаний (зміна soname). Інакше кожен коміт збирав би Calamares 17 хвилин.
- **Зміна soname в rolling-основі.** Якщо upstream оновив, скажімо, `libicu`, ваш старий бінарний пакет посилається на бібліотеку, якої вже немає. Перевірка «чи встановиться пакет у порожній корінь» (`xbps-install -n`) ловить це автоматично.
- **Залишки перерваного збирання** (`destdir`) потрапляють у наступний пакет. Чистіть їх перед збиранням.
- **Пакет з'явився в upstream.** Попереджайте, коли ваш шаблон має таку саму назву, як новий пакет upstream: можливо, свій уже можна прибрати.
### 5.4. Репозиторій
- Індекс репозиторію: `xbps-rindex -a`, `repo-add`, `reprepro`/`aptly`, `createrepo_c`.
- **Підпис:** `xbps-rindex --sign`, `gpg` для apt/pacman/rpm. Приватний ключ — поза репозиторієм і поза образом, у CI — лише як секрет. Публічний ключ — у пакеті, що підключає репозиторій.
- **Підключення в установленій системі:** окремий пакет або файл (`/etc/xbps.d/das.conf`, `/etc/apt/sources.list.d/`, `/etc/pacman.conf`). Без цього система після встановлення бачить лише upstream, і ваші пакети ніколи не оновляться (саме ця задача відкрита в TODO Das OS).
- **Пріоритет репозиторіїв:** якщо пакет є і у вас, і в upstream, визначте, чий важливіший (порядок `repository=` у xbps, pinning в apt). Інакше upstream може «оновити» ваш пакет своєю версією.
- **Хостинг:** будь-який статичний HTTPS-сервер (nginx, Gitea/GitHub Releases, S3, Cloudflare R2). Плануйте дзеркала, якщо користувачів стане багато.
- **Ігнорування пакетів:** якщо варіант свідомо не містить пакетів (Das OS Server — без `linux-firmware-nvidia`, `sof-firmware`), пропишіть це і для збирання образу (`mklive -g`), і для встановленої системи (`ignorepkg` в `/etc/xbps.d/`), інакше перше ж оновлення поверне їх.
---
## 6. Як влаштований live-образ
Щоб налагоджувати завантаження, треба розуміти ланцюжок:
```
Прошивка (UEFI або BIOS)
└─ завантажувач з ISO (GRUB для UEFI, isolinux/syslinux для BIOS)
└─ ядро vmlinuz + initramfs, параметри з меню (root=live:CDLABEL=..., quiet, nomodeset...)
└─ initramfs шукає носій за міткою тому → монтує ISO
└─ монтує squashfs з кореневою системою (лише читання)
└─ overlayfs: зверху tmpfs для запису (зміни зникають після вимкнення)
└─ switch_root → init (runit/systemd) → служби → вхід/робочий стіл
```
Що з цього випливає:
- **Мітка тому ISO** (volume label) — ключ, за яким initramfs шукає носій. Змінили мітку, але не параметри ядра → «не знайдено кореневу систему». Мітка ISO9660 обмежена 32 символами; уникайте пробілів і нелатинських літер.
- **Гібридний ISO** (UEFI + BIOS, CD + USB) складається з El Torito для BIOS, образу EFI-розділу (FAT) для UEFI та MBR/GPT для запису на флешку через `dd`. Інструменти (`xorriso`, mklive, live-build, archiso) роблять це самі — не збирайте ISO вручну без потреби.
- **initramfs live-образу** має лише знайти й змонтувати носій. Драйвери GPU і їхні прошивки (≈150 МБ) можна прибрати з нього: вони завантажаться з кореневої системи після `switch_root` (Das OS: `--omit-drivers "amdgpu radeon nouveau i915 xe"`, initrd 245 → 89 МБ). Перевіряйте на реальному залізі з різними відеокартами.
- **Режим копіювання в RAM** (`rd.live.ram`, `toram`) дозволяє вийняти флешку; потребує пам'яті більше за розмір squashfs.
- **Пункт `nomodeset`** у меню рятує на машинах, де екран лишається чорним.
- **Live-користувач** створюється під час завантаження (у Void це робить dracut-модуль mklive) і не повинен потрапити у встановлену систему.
### 6.1. Стиснення squashfs
| Алгоритм | Розмір | Швидкість розпакування | Коли |
|---|---|---|---|
| xz (+ BCJ x86, блок 1 МБ) | Найменший | Повільніше | Образи для завантаження/розповсюдження |
| zstd (рівень 15–19) | Трохи більший | Швидко | Коли важлива швидкість завантаження live |
| lz4 | Великий | Дуже швидко | Налагодження, швидкі ітерації |
**Das OS:** `-b 1M -Xbcj x86` дав −5 % на десктопі.
### 6.2. Що займає місце (для оптимізації)
- Прошивки (`linux-firmware*`) — сотні мегабайтів; мережеві не прибирайте, без них не буде Wi-Fi.
- Переклади `/usr/share/locale` (у Das OS — 265 МБ). Можна лишити лише потрібні мови (`noextract` у xbps, `path-exclude` у dpkg), але тоді інші мови інтерфейсу доведеться доставляти окремо.
- Дублікати тем іконок, документація (`/usr/share/doc`, `man`), заголовки.
- Подивитися найбільші пакети: `xbps-query -m | ...`, `expac -H M '%m %n' | sort -h`, `dpkg-query -Wf '${Installed-Size} ${Package}\n' | sort -n`.
---
## 7. Збирання ISO
### 7.1. Профіль образу
Тримайте опис кожного варіанта образу окремим каталогом, а не в скрипті:
```
live/ server/
├── packages.x86_64 ├── packages.x86_64 # список пакетів, коментарі через '#'
├── services ├── services # служби, увімкнені в live
├── branding/ └── branding/
│ ├── issue └── issue
│ ├── splash.svg
│ └── ventoy/dasos.png
└── include/ # файли, що накладаються на корінь образу
└── etc/...
```
Аналоги в інших основах: `config/package-lists/*.list.chroot` та `config/includes.chroot/` у live-build; `packages.x86_64`, `airootfs/`, `profiledef.sh` в archiso; `%packages` у kickstart.
### 7.2. Що класти в `include/`, а що — у пакет
- `include/` — лише те, що потрібне **тільки live-сесії** (автовхід, розкладка для live, заглушки гостьових інструментів). Пам'ятайте: інсталятор, який копіює образ на диск, перенесе і ці файли — їх доведеться прибирати (див. [9.4](#94-копіювання-образу-чи-встановлення-пакетів)).
- Усе, що має бути у встановленій системі, — у пакети.
### 7.3. Основні параметри (на прикладі mklive)
```sh
./mklive.sh \
-a x86_64 \ # архітектура
-r /work/out/hostdir/binpkgs \ # ваш репозиторій (додається перед upstream)
-c /var/cache/xbps \ # кеш пакетів
-p "$(read_list live/packages.x86_64)" \
-S "$(read_list live/services)" \ # служби runit
-I "$include" \ # накладка на корінь
-l uk_UA.UTF-8 -k us \ # локаль і розкладка live
-T "Das OS 0.9.1" \ # заголовок меню завантаження
-C "live.user=live quiet loglevel=3" \ # параметри ядра
-o out/iso/dasos-0.9.1-x86_64.iso
```
### 7.4. Нюанси
- **Меню завантаження** за замовчуванням показує версію ядра; користувачу корисніша версія дистрибутива. Латайте шаблони меню GRUB і isolinux, а не результат.
- **Серверний образ:** параметри `console=tty0 console=ttyS0,115200` дають вивід і на екран, і на послідовну консоль (IPMI, VPS, `qemu -nographic`). Останній `console=` стає основним для `/dev/console`.
- **Часовий пояс і локаль live** задавайте явно, інакше буде UTC і `en_US`.
- **Ventoy:** багато користувачів завантажують ISO через Ventoy. Перевірте, що образ працює і в ньому; Ventoy може показувати власний значок за назвою образу (`live/branding/ventoy/`).
- **Розмір файлу:** образ понад 4 ГБ не скопіюється на флешку з FAT32 (Ventoy за замовчуванням використовує exFAT, це нормально, але «записати файлом» на FAT32 не вийде).
- **Ім'я файлу ISO** — `назва-варіант-версія-архітектура.iso`: користувачі й скрипти покладаються на передбачуване ім'я.
---
## 8. Налаштування за замовчуванням і оформлення
### 8.1. Ідентичність системи
- `/etc/os-release` (`NAME`, `PRETTY_NAME`, `ID`, `ID_LIKE`, `VERSION_ID`, `HOME_URL`, `BUG_REPORT_URL`, `LOGO`, `ANSI_COLOR`). **Обережно з `ID`:** скрипти й програми (інсталятори, `neofetch`, Steam, драйвери, Calamares) перевіряють `ID=void`/`ID=ubuntu`. Якщо змінюєте `ID`, обов'язково вкажіть `ID_LIKE=<основа>`, і перевірте програми, які на це покладаються. Файл зазвичай належить базовому пакету upstream — постачайте свій через механізм, що не конфліктує з ним (альтернативи, `/usr/lib/os-release` vs `/etc/os-release`, drop-in, або власний пакет base-files, якщо ви форк).
- `/etc/issue` (текст перед входом у консоль) — у live він може підказувати логін/пароль, у встановленій системі — нейтральний.
- Ім'я хоста live (`dasos`), а не upstream-овий (`void-live`).
- Банер SSH, MOTD, запрошення shell (у Das OS — `das-shell`).
### 8.2. Візуальне оформлення
| Що | Де | Нюанси |
|---|---|---|
| Заставка меню завантаження | GRUB (UEFI), isolinux (BIOS) | Різні формати й роздільність; isolinux — 640×480, обмежена палітра |
| Тема GRUB у встановленій системі | `/boot/grub/themes/`, `GRUB_THEME` | Без неї — чорний екран зі стандартним текстом |
| Plymouth (графічне завантаження) | Тема Plymouth | Потребує KMS; ховає повідомлення ядра, тож залиште спосіб їх побачити |
| Екран входу | LightDM/SDDM/GDM конфіги | Через drop-in (`lightdm.conf.d`), не правкою основного файлу |
| Тема GTK/Qt, іконки, курсор, шрифти | Пакет теми | Перевіряйте світлий і темний варіанти, GTK3 і GTK4/libadwaita |
| Рамки вікон | Тема менеджера вікон | Das OS генерує рамки xfwm4 програмою (`xfwm4gen`), а не малює вручну |
| Шпалери, логотип | SVG у пакеті теми | Векторні джерела в репозиторії, растр генеруйте під час збирання |
| Слайди інсталятора | Бренд Calamares | Версію підставляйте під час збирання з `VERSION` |
- Зберігайте **джерела** зображень (SVG), а PNG генеруйте (`rsvg-convert`), щоб змінювати колір чи текст в одному місці.
- Перевіряйте ліцензії шрифтів, іконок і шпалер, які берете з інтернету (OFL, CC BY-SA вимагає зазначити автора).
### 8.3. Налаштування робочого середовища
- Готуйте налаштування в живій сесії, потім експортуйте у файли (`xfconf-query`, `dconf dump`, `kwriteconfig`), а не пишіть XML вручну.
- Розкладка клавіатури та її перемикання — і в X11 (`/etc/X11/xorg.conf.d/00-keyboard.conf`), і в консолі (`KEYMAP`), і в екрані входу.
- Мова інтерфейсу за замовчуванням, часовий пояс, формат дати.
- Назви тек користувача (`xdg-user-dirs`): реальна помилка, з якою ми стикнулися, описана в [18](#18-типові-пастки).
- Звук (PipeWire + WirePlumber), мережа (NetworkManager), Bluetooth, автомонтування (udisks2, gvfs), керування живленням.
- Агент polkit і `pkexec` для графічних програм, що потребують прав root.
---
## 9. Інсталятор
### 9.1. Вибір
| Інсталятор | Для чого | Плюси | Мінуси |
|---|---|---|---|
| **Calamares** | Графічний, незалежний від дистрибутива | Модульний, бренд, переклади, розмітка дисків, LUKS | Залежить від Qt/KDE Frameworks; під runit/не-systemd потребує налаштувань |
| Anaconda | Fedora/RHEL | Kickstart для автоматизації | Важко відірвати від Fedora |
| debian-installer, Subiquity | Debian, Ubuntu | Перевірені | Складно брендувати |
| archinstall | Arch | Python, скриптується | Лише Arch |
| **Власний TUI** | Сервери, мінімальні образи | Повний контроль, `dialog`/`whiptail`, режим без запитань | Розмітку, завантажувач і крайові випадки пишете самі |
**Das OS:** Calamares для десктопа, власний `das-server-install` на `dialog` для сервера, спільні кроки в `das-install-common` (`mount-source`, `postinstall`).
### 9.2. Що має зробити будь-який інсталятор
1. Розмітити диск (автоматично і вручну), створити файлові системи (і підтоми Btrfs).
2. Перенести систему на диск.
3. Згенерувати `/etc/fstab` за **UUID**, не за `/dev/sdX` (імена дисків змінюються).
4. Налаштувати локаль (і **зібрати** її: у Void — `/etc/default/libc-locales` + `xbps-reconfigure -f glibc-locales`, у Debian — `locale-gen`), часовий пояс, розкладку (X11 і консоль).
5. Створити користувача, групи (`wheel`, `audio`, `video`, `network`, `docker`…), sudo.
6. Задати ім'я хоста, мережу.
7. **Згенерувати унікальні дані машини** (див. 9.3).
8. Перезібрати initramfs під цю машину.
9. Встановити завантажувач.
10. Прибрати все, що потрібне лише live-сесії й самому інсталятору.
### 9.3. Унікальні дані, яких не повинно бути в образі
Усе, що копіюється з образу, буде однаковим на кожному комп'ютері. Тому в образі не повинно бути:
- `/etc/machine-id`, `/var/lib/dbus/machine-id` — генеруються під час встановлення (модуль `machineid` у Calamares) або першого запуску;
- **ключів хоста SSH** (`/etc/ssh/ssh_host_*`) — інакше всі сервери матимуть однаковий ключ, і MITM стане тривіальним; вони генеруються під час першого запуску sshd;
- зерна генератора випадкових чисел (`/var/lib/random-seed`);
- ключів, токенів, паролів збирача, історії shell, журналів збирання.
### 9.4. Копіювання образу чи встановлення пакетів
| Спосіб | Як | Плюси | Мінуси |
|---|---|---|---|
| Копіювання образу (`unpackfs`, rsync) | Розпакувати squashfs на диск | Швидко, без мережі, встановлюється те, що користувач бачив у live | Треба прибирати live-специфічне |
| Встановлення пакетів (`pacstrap`, `debootstrap`, `xbps-install -r`) | Ставити пакети з репозиторію в цільовий корінь | Чиста система, завжди найсвіжіші пакети | Потребує мережі або повного локального репозиторію |
При копіюванні:
- копіюйте **чистий** корінь (у Void — `/dev/mapper/live-base`, нижній шар без змін live-сесії), а не змонтований overlay з live-користувачем і його налаштуваннями;
- після копіювання видаліть live-користувача, автовхід, службові файли (`mklive-ignore.conf`), сам інсталятор і пакети, потрібні лише йому;
- гостьові інструменти віртуальних машин лишайте лише для того гіпервізора, у якому відбувається встановлення (`/sys/class/dmi/id/sys_vendor`, прапорець `hypervisor` у `/proc/cpuinfo`); на реальному залізі — жодних (у Das OS інструменти VirtualBox показували помилку при кожному вході в KVM);
- перевірте, що копіювання **не робить файли розрідженими** там, де це шкодить (див. [18](#18-типові-пастки) про GRUB і Btrfs).
### 9.5. Calamares під не-systemd систему
- `settings.conf` задає послідовність модулів. Свої кроки — через `shellprocess` з різними `id` (`shellprocess@postinstall`).
- Модулі, що викликають `systemctl` (`services-systemd`), замініть на свої (для runit — посилання в `/etc/runit/runsvdir/default/`).
- Модуль `displaymanager` налаштовує автовхід/екран входу; перевірте, що він знає ваш DM.
- `unpackfs` — джерело й тип файлової системи; `mount` — опції монтування й підтоми Btrfs; `partition` — файлові системи за замовчуванням, розмір EFI-розділу, swap.
- Бренд: `branding.desc`, логотипи, слайди, кольори; версію підставляйте під час збирання.
- Збирайте Calamares тієї версії, яку перевірили: оновлення може змінити формат конфігів.
- Запускайте з `-d` для налагодження; журнал — `~/.cache/calamares/session.log`, і його варто копіювати у встановлену систему для звітів про помилки.
### 9.6. Консольний інсталятор
- Режим без запитань (`--config file`) для автоматизації й тестів у CI.
- Перевіряйте введене (ім'я користувача, ім'я хоста, пароль, SSH-ключ) **до** того, як почати стирати диск.
- Явне підтвердження з назвою диска й розміром перед стиранням.
- Опція «вхід по SSH лише за ключем» і перевірка, що ключ справді додано, інакше сервер стане недоступним.
- Повідомлення наприкінці: як увійти, які є команди, де документація.
---
## 10. Завантажувач, initramfs і розмітка диска
### 10.1. Розмітка
| Режим | Таблиця | Обов'язкові розділи |
|---|---|---|
| UEFI | GPT | EFI System Partition (FAT32, 300–1024 МіБ; Das OS — 512 МіБ), корінь |
| BIOS + MBR | MBR | Корінь (позначений активним для деяких BIOS) |
| BIOS + GPT | GPT | **BIOS boot partition** 1 МіБ (тип `ef02`) для GRUB, корінь |
- Вирівнюйте розділи по 1 МіБ.
- Swap: розділ, файл (на Btrfs — з `chattr +C` і без стиснення) або zram. Для сплячого режиму (hibernate) потрібен swap не менший за обсяг RAM і `resume=` у параметрах ядра.
- `/tmp` на tmpfs.
### 10.2. Btrfs для знімків
Типова схема підтомів (як у Das OS, openSUSE, Ubuntu з zsys):
```
@ → /
@home → /home (особисті файли не відкочуються разом із системою)
@snapshots → /.snapshots
@var_log → /var/log (журнали лишаються після відкату — зручно розбиратися)
@var_cache_xbps → /var/cache/xbps (кеш пакетів не роздуває знімки)
```
Опції монтування: `compress=zstd`, `noatime`. Для баз даних і образів VM — `chattr +C` на каталог.
### 10.3. GRUB
- UEFI: `grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=DasOS`.
- **Запасний шлях `\EFI\BOOT\BOOTX64.EFI`** (`--removable` або копія): деякі прошивки «забувають» записи NVRAM або взагалі їх не підтримують — без запасного файлу система не завантажиться.
- BIOS: `grub-install --target=i386-pc /dev/sdX` (на диск, не на розділ).
- **Подвійне завантаження:** з GRUB 2.06 `os-prober` вимкнено за замовчуванням; щоб бачити Windows, потрібен `GRUB_DISABLE_OS_PROBER=false` у `/etc/default/grub`.
- Тема й назва пунктів меню (`GRUB_DISTRIBUTOR`).
- Годинник: Windows тримає апаратний годинник у місцевому часі, Linux — в UTC; при подвійному завантаженні час «стрибає». Виберіть одне й задокументуйте.
### 10.4. initramfs
- Live-образ має **загальний** initramfs з усіма драйверами; у встановленій системі збирайте **під машину** (host-only), як це робить основа при оновленні ядра (`dracut --force`, `mkinitcpio -P`, `update-initramfs -u`).
- Власні модулі dracut/хуки (Das OS: `90das-snapshot-overlay` для завантаження у знімок лише для читання) постачайте пакетом і перевіряйте, що вони потрапляють у initramfs.
- Шифрування (LUKS): `crypttab`, ключ-файл у initramfs, щоб не вводити пароль двічі (GRUB + initramfs), `GRUB_ENABLE_CRYPTODISK=y` для зашифрованого `/boot`. GRUB підтримує LUKS2 лише з PBKDF2, не з Argon2 — враховуйте при створенні тому.
### 10.5. Secure Boot
- Прошивка з увімкненим Secure Boot завантажує лише підписане ключем Microsoft (або вашим, якщо користувач його додав).
- Реалістичні варіанти для невеликого дистрибутива:
1. Основа вже має підписаний ланцюжок `shim → GRUB → ядро` (Debian, Ubuntu, Fedora, openSUSE) і ви **не змінюєте ядро й GRUB** — використовуйте їхні підписані пакети.
2. Власний ключ (`sbctl`, MOK через `mokutil`): користувач один раз реєструє ключ. Кожен модуль ядра (DKMS, NVIDIA) теж треба підписувати.
3. Документувати, що Secure Boot треба вимкнути (так у Void, Arch за замовчуванням).
- Власний shim, підписаний Microsoft, — тривалий процес перевірки, для малого проєкту зазвичай недосяжний.
---
## 11. Оновлення, знімки й відкат
- **Rolling-основа може зламатися будь-якого дня.** Захист: знімок перед кожним оновленням (Das OS: `das-update` робить пару snapper pre/post), меню GRUB зі знімками (`grub-btrfs`), команда відкату (`snapper-rollback`).
- Знімки — **не резервна копія**: вони на тому самому диску.
- Відкат має не чіпати `/home` (окремий підтом).
- Регулярне очищення старих знімків (snapper timeline/number cleanup), інакше диск заповниться.
- Після відкату лишаються старі корені — плануйте їх прибирання.
- Для дистрибутивів з фіксованими версіями: канали `stable`/`testing`, тестування оновлень перед публікацією, бекпорти безпеки.
- Оновлення ваших пакетів має дійти до встановлених систем — перевірте весь шлях: коміт → збирання → підписаний репозиторій → `xbps-install -Su` на чистій установці.
- Тримайте окремий консольний режим оновлення (`das-update --cli`): на сервері немає графіки, а графічна програма може зламатися саме під час оновлення.
- Розгляньте атомарні/незмінні системи (ostree, NixOS, A/B-розділи), якщо відкат — ключова цінність; це інший рівень складності.
---
## 12. Тестування
### 12.1. Віртуальні машини
```sh
# UEFI (OVMF), диск на 20 ГБ, KVM
qemu-system-x86_64 -enable-kvm -m 4G -smp 2 \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=ovmf_vars.fd \
-cdrom out/iso/dasos-0.9.1-x86_64.iso \
-drive file=disk.qcow2,if=virtio \
-nic user,hostfwd=tcp::2222-:22
# BIOS: те саме без pflash (SeaBIOS за замовчуванням)
# Сервер: -nographic -serial mon:stdio
```
- Тестуйте **обидва** режими: UEFI і BIOS; і live, і встановлену систему.
- Копія `OVMF_VARS` для кожної ВМ, інакше записи завантаження змішуються.
- Перенаправлення порту SSH (`localhost:2222`) спрощує автоматичні перевірки.
- Знімки ВМ (`qemu-img snapshot`) перед встановленням пришвидшують повторні тести.
- Різні відеоадаптери: `virtio-vga`, `qxl`, `std` — і VirtualBox/VMware, бо там свої гостьові інструменти.
**Das OS:** `make qemu`, `make qemu-bios`, `make qemu-disk`, `make qemu-server` (`scripts/run-qemu.sh`).
### 12.2. Реальне залізо
ВМ не замінюють залізо. Обов'язковий мінімум перед стабільним релізом:
- Графіка Intel, AMD, NVIDIA (nouveau і пропрієтарний драйвер), гібридні ноутбуки.
- Wi-Fi: Intel (iwlwifi), Realtek, Broadcom (часто потребує пропрієтарного `broadcom-wl`), Bluetooth.
- NVMe, SATA, режим Intel RST/RAID (Linux не бачить диск, поки в BIOS не перемкнути на AHCI — задокументуйте).
- Старий BIOS без UEFI, UEFI з увімкненим/вимкненим Secure Boot.
- Подвійне завантаження з Windows (і BitLocker).
- Сплячий режим, яскравість, тачпад, звук через HDMI, мікрофон, вебкамера.
- Завантаження з флешки, записаної через `dd`, Ventoy, Rufus (режим DD).
### 12.3. Автоматизація
- Модульні тести ваших утиліт під час збирання пакетів (`make test`).
- `shellcheck` для shell-скриптів.
- Інсталятор без запитань (`--config`) у ВМ у CI, після цього вхід по SSH і перевірки (`openQA` — повноцінний варіант, як у openSUSE і Fedora).
- Чекліст ручних перевірок у TODO, з відмітками, на якій версії перевірено.
---
## 13. CI і релізи
### 13.1. Збирання в CI
- Self-hosted runner: збирання ISO потребує привілейованого контейнера, гігабайтів кешу й десятків хвилин — хмарні безкоштовні runner-и часто не підходять за часом і місцем.
- Кеш (`DASOS_OUT`) між запусками на хості runner-а, інакше кожне збирання з нуля.
- `concurrency` з `cancel-in-progress`, щоб новий push скасовував старе збирання.
- Збирайте **всі варіанти одним запуском**, щоб пакети збиралися один раз.
- Для змін, які не впливають на образ (документація), пропускайте збирання: `[skip ci]` у повідомленні коміту або `paths-ignore` у workflow.
- Runner має підніматися сам після перезавантаження хоста.
### 13.2. Публікація релізу
- Реліз — за тегом (`v0.9.1`), версія тегу має збігатися з `VERSION` (перевіряйте в CI).
- Публікуйте `SHA256SUMS` і **підпис** до нього (`gpg --detach-sign SHA256SUMS`), з публічним ключем на сайті.
- Великі файли: ліміти розміру вкладень (Gitea — `[repository.release] FILE_MAX_SIZE`), таймаути зворотного проксі. **Досвід Das OS:** Traefik обривав завантаження ISO через 60 секунд (502), довелося підняти `readTimeout`.
- Торенти й дзеркала для зменшення навантаження.
- Нотатки до релізу: що нового, відомі проблеми, як оновитися з попередньої версії, мінімальні вимоги.
- Не видаляйте старі релізи одразу: комусь потрібно відкотитися.
---
## 14. Безпека
- Підписані пакети й репозиторій, лише HTTPS.
- Приватні ключі — поза git, поза образом, у CI — як секрети з мінімальним доступом.
- Ніяких паролів за замовчуванням у встановленій системі. Пароль `live/live` допустимий лише в live-сесії.
- SSH: `PermitRootLogin prohibit-password`, вхід за ключем, fail2ban або аналог, файрвол «закрито все, крім потрібного» (Das OS Server: nftables у власній таблиці `inet das`, щоб не ламати правила Docker і fail2ban).
- Оновлення безпеки з upstream мають доходити швидко: rolling-основа дає їх сама; власні пакети — ваша відповідальність.
- Стежте за CVE пакетів, які ви збираєте самі (Calamares, власні версії бібліотек).
- `sudo` без пароля — лише в live.
- Мінімум запущених служб за замовчуванням.
- Телеметрія: краще без неї; якщо є — лише з явної згоди й з описом, що збирається.
- Перевіряйте, що в образ не потрапили секрети збирача: `unsquashfs -l` та пошук по `/root`, `/home`, `/tmp`, історії shell.
---
## 15. Ліцензії й торгові марки
> Це не юридична консультація. Для комерційного проєкту зверніться до юриста.
- **GPL:** розповсюджуючи бінарні файли під GPL (ядро, GRUB, coreutils…), ви зобов'язані надати вихідні коди **точно тих версій**. Найпростіше — публікувати поруч з ISO архів вихідних кодів або дзеркало; посилання на upstream надійне лише доти, доки там лежить саме та версія. Ваші власні латки й шаблони — у публічному репозиторії.
- **Ліцензія вашого коду:** оберіть явно (Das OS — MIT) і покладіть `LICENSE` у кожен пакет.
- **Невільні компоненти:** прошивки, драйвери NVIDIA, кодеки (патентні питання в деяких країнах), шрифти Microsoft. Деякі з них не можна перерозповсюджувати в модифікованому вигляді або зовсім — перевірте ліцензію кожного; у Void вони в репозиторії `nonfree`.
- **Торгові марки основи:**
- Ubuntu (Canonical) вимагає дозволу на використання назви для похідних і модифікованих образів — прибирайте їхні логотипи й назву;
- Fedora дозволяє «Remix», але логотипи Fedora треба замінити (`generic-logos`);
- Debian, Arch і Void значно ліберальніші, але й там не видавайте свій дистрибутив за офіційний.
- **Програми з торговими марками:** Firefox дозволяє розповсюджувати незмінені збірки під своєю назвою; якщо ви змінюєте код чи брендинг, перевірте правила Mozilla (історичний приклад — Iceweasel у Debian).
- **Графіка й шрифти:** ліцензії CC, OFL, вимоги зазначати авторство. Державна символіка (наприклад, тризуб) має свої правила використання — перевірте законодавство своєї країни.
---
## 16. Локалізація й доступність
- Мова за замовчуванням і вибір мови в інсталяторі та вікні привітання; зміна мови має діяти після перезавантаження/повторного входу.
- Зібрані локалі для вибраної мови і `en_US.UTF-8` як запасна.
- Переклади ваших утиліт (gettext або власний модуль `i18n` з тестами, що всі рядки перекладено).
- Переклади Calamares і бренду (слайди, назви).
- Розкладки: основна + англійська, зручне перемикання, однаково в X11, консолі й на екрані входу.
- Вікна, що лишаються англійською (у Das OS — агент polkit), — окремий пункт у TODO.
- Доступність: зчитувач екрана (Orca), висока контрастність, масштабування; хоча б перевірте, що їх можна увімкнути.
---
## 17. Документація та спільнота
- README двома мовами: призначення, можливості, скріншоти, як завантажити й встановити, як зібрати.
- Мінімальні вимоги до заліза.
- Відомі проблеми й обхідні шляхи.
- Як повідомити про помилку: які журнали додати (`~/.cache/calamares/session.log`, `dmesg`, `/var/log/socklog`, `xbps-query -l`).
- Журнал змін (CHANGELOG або нотатки до релізів).
- Канал зв'язку (форум, Telegram, Matrix, issues).
- Вкажіть, на чому базується дистрибутив, і подякуйте upstream — частину проблем користувачі мають повідомляти саме туди.
- Помилки, знайдені в upstream, повідомляйте авторам (як у TODO Das OS — про `xdg-user-dirs`).
- Після стабільного релізу — заявка на DistroWatch.
---
## 18. Типові пастки
Реальні проблеми з історії Das OS і загальновідомі:
| Симптом | Причина | Рішення |
|---|---|---|
| GRUB: «premature end of file» при завантаженні ядра з Btrfs | Інсталятор копіював `rsync --sparse`, хвіст ядра з нулів став «діркою» Btrfs, яку GRUB 2.12 не читає | Переписати ядра без розрідженості (`cp --sparse=never`) після копіювання |
| Теки користувача англійською попри українську локаль | `xdg-user-dirs` 0.20 шукає переклади лише в першій теці `XDG_DATA_DIRS` | Задати правильний порядок/обхід у сесії, перейменувати вже створені теки |
| Після перезапуску файрволу зникли правила Docker і fail2ban | Скрипт `finish` служби nftables у Void робить `nft flush ruleset` | Окрема таблиця й команда `dfw reload`, що перезавантажує лише її |
| snapper не працює у встановленій системі | Не запущено `dbus` | Інсталятор вмикає `dbus` разом зі snapper |
| Podman попереджає про спільне монтування | runit лишає `/` приватним | Скрипт ранньої ініціалізації `mount --make-rshared /` |
| Повідомлення VirtualBox при кожному вході в KVM/на залізі | Гостьові інструменти скопійовані з live | Видаляти інструменти не того гіпервізора під час встановлення |
| Версія в інсталяторі не та | Версія жорстко прописана в пакеті | Підставляти з `VERSION` під час збирання образу |
| Латка до upstream-інструмента «тихо» перестала діяти | Інструмент оновився, рядок змінився | Перевіряти наявність рядка перед `sed` і падати з помилкою |
| Пакет зібрано з чужими файлами | Залишки `destdir` після перерваного збирання | Чистити `destdir` перед кожним збиранням |
| Пакет не встановлюється після оновлення upstream | Upstream змінив soname бібліотеки | Автоматично перезбирати пакети з незадоволеними залежностями |
| 502 під час завантаження ISO в реліз | Таймаут зворотного проксі 60 с | Підняти `readTimeout` (Traefik) / `proxy_read_timeout` (nginx) |
| Live-сесія блокує екран під час довгого встановлення | Заставка/блокування за замовчуванням | Вимкнути блокування в live |
| Чорний екран на деяких відеокартах | Проблеми KMS | Пункт меню з `nomodeset`, тестування на залізі |
| Не видно Windows у меню GRUB | `os-prober` вимкнено з GRUB 2.06 | `GRUB_DISABLE_OS_PROBER=false` |
| Система не завантажується після оновлення прошивки | Прошивка стерла запис NVRAM | Запасний `\EFI\BOOT\BOOTX64.EFI` |
| Усі сервери мають однаковий ключ SSH | Ключі хоста потрапили в образ | Генерувати під час першого запуску |
| Користувацькі налаштування скидаються після оновлення | Пакет перезаписує файли в `/home` або основні конфіги | Значення за замовчуванням у `/etc/xdg/<дистр>` і drop-in, `conf_files` |
| Пакети, свідомо прибрані з образу, повертаються | Ігнор налаштовано лише для збирання образу | Той самий список `ignorepkg` у встановленій системі |
| Встановлена система не оновлює ваші пакети | Репозиторій дистрибутива не підключено після встановлення | Пакет з налаштуванням репозиторію й ключем |
---
## 19. Покроковий план з нуля
Порядок, у якому розвивався Das OS; кожен етап завершується робочим результатом, який можна перевірити.
1. **Репозиторій і контейнер збирання.** `git init`, `.gitignore` (`/out/`, `.idea/`), `Dockerfile` з основою, скрипт запуску команд у контейнері, `Makefile` з цілями `packages`, `iso`, `qemu`, `clean`.
2. **Чистий live-образ основи.** Зберіть ISO інструментом upstream без змін, завантажте в QEMU (UEFI і BIOS). Це база для порівняння: якщо щось зламається пізніше, ви знатимете, що це ваша зміна.
3. **Профіль образу.** Список пакетів, служби, локаль, часовий пояс, розкладка, меню завантаження з вашою назвою й версією, ім'я хоста.
4. **Перший власний пакет.** Шаблон з одним конфігом, збирання у власний репозиторій, підключення репозиторію при збиранні ISO. Переконайтеся, що пакет потрапив в образ.
5. **Налаштування робочого середовища пакетом** (`das-settings`): панель, теми, екран входу — через drop-in і `/etc/xdg/<дистр>`.
6. **Оформлення** (`das-theme`): шпалери, логотип, тема, заставки завантажувача, бренд інсталятора.
7. **Інсталятор.** Спершу автоматична розмітка на чистий диск, UEFI, одна файлова система. Потім BIOS, ручна розмітка, інші файлові системи, прибирання live-специфічного.
8. **Знімки й відкат** (якщо Btrfs): підтоми, snapper, меню GRUB, утиліта оновлення зі знімком.
9. **Власні утиліти** (вікно привітання, оновлення, консольні помічники) з тестами.
10. **Додаткові варіанти образу** (сервер) на тих самих пакетах.
11. **CI**: збирання на кожен push, реліз на тег, контрольні суми.
12. **Реальне залізо.** Виправлення окремими патч-версіями.
13. **Підписаний репозиторій і оновлення встановлених систем.**
14. **Перший стабільний реліз**: злиття в `main`, нотатки, документація, оголошення.
Мінімальна команда, з якої все починається (Void):
```sh
docker run --rm -it --privileged -v "$PWD:/work" ghcr.io/void-linux/void-glibc-full sh -c '
xbps-install -Syu xbps && xbps-install -y git bash &&
git clone https://github.com/void-linux/void-mklive /opt/mklive && cd /opt/mklive &&
./mklive.sh -a x86_64 -p "xfce4 xorg-minimal lightdm dbus" -S "dbus lightdm" -o /work/test.iso'
```
Для Arch аналог — `mkarchiso -v -w /tmp/work -o out /usr/share/archiso/configs/releng`, для Debian — `lb config && sudo lb build`.
---
## 20. Чекліст перед релізом
**Збирання**
- [ ] Версія підвищена в `VERSION` і в змінених пакетах; README оновлено.
- [ ] Збирання з чистого дерева git у CI пройшло, тести зелені.
- [ ] Розмір образу в межах очікуваного (порівняти з попереднім релізом).
- [ ] В образі немає секретів, ключів SSH хоста, `machine-id`.
**Live**
- [ ] Завантаження UEFI і BIOS, з `dd`-флешки і Ventoy.
- [ ] Меню показує правильну назву й версію; пункти `nomodeset` і RAM працюють.
- [ ] Мережа, звук, Bluetooth, розкладки, мова інтерфейсу.
**Встановлення**
- [ ] Автоматична й ручна розмітка; UEFI і BIOS; Btrfs і ext4.
- [ ] Перше завантаження встановленої системи, вхід, sudo.
- [ ] Live-користувач, інсталятор і непотрібні гостьові інструменти прибрані.
- [ ] Унікальні `machine-id` і ключі SSH.
- [ ] Оновлення зі знімками, завантаження у знімок, відкат.
- [ ] Подвійне завантаження з Windows (якщо підтримується).
**Сервер**
- [ ] Вхід по SSH за ключем, заборона паролів, файрвол, fail2ban.
- [ ] Послідовна консоль.
- [ ] Встановлення без запитань (`--config`).
**Публікація**
- [ ] Тег збігається з `VERSION`.
- [ ] ISO, `SHA256SUMS`, підпис опубліковано й перевірено завантаженням.
- [ ] Нотатки до релізу з відомими проблемами.
- [ ] Вихідні коди доступні.
---
## 21. Корисні посилання
- Void: [void-mklive](https://github.com/void-linux/void-mklive), [void-packages / xbps-src](https://github.com/void-linux/void-packages), [Void Handbook](https://docs.voidlinux.org)
- Arch: [archiso](https://wiki.archlinux.org/title/Archiso)
- Debian: [Debian Live Manual](https://live-team.pages.debian.net/live-manual/)
- Fedora: [Kiwi](https://osinside.github.io/kiwi/), [Fedora Remix](https://fedoraproject.org/wiki/Remix)
- openSUSE: [Open Build Service](https://openbuildservice.org)
- Ubuntu: [Cubic](https://github.com/PJ-Singh-001/Cubic), [Trademark Policy](https://ubuntu.com/legal/trademarks)
- [Calamares](https://calamares.io) і його [вікі розробника](https://github.com/calamares/calamares/wiki)
- [Linux From Scratch](https://www.linuxfromscratch.org)
- [os-release(5)](https://www.freedesktop.org/software/systemd/man/latest/os-release.html), [XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/latest/)
- [Arch Wiki: Unified Extensible Firmware Interface/Secure Boot](https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot), [sbctl](https://github.com/Foxboron/sbctl)
- [Reproducible Builds](https://reproducible-builds.org), [SOURCE_DATE_EPOCH](https://reproducible-builds.org/docs/source-date-epoch/)
- [openQA](https://open.qa)
- [DistroWatch](https://distrowatch.com)