From 94b1bf5f8b09bd1e6329aa7ce6e37672442c95b7 Mon Sep 17 00:00:00 2001 From: Anry Das Date: Wed, 21 Oct 2026 14:21:51 +0300 Subject: [PATCH] Docs: Ukrainian guide to building your own distribution [skip ci] Co-Authored-By: Claude Opus 5.5 --- docs/how-to-build-a-distro_ua.md | 652 +++++++++++++++++++++++++++++++ 1 file changed, 652 insertions(+) create mode 100644 docs/how-to-build-a-distro_ua.md diff --git a/docs/how-to-build-a-distro_ua.md b/docs/how-to-build-a-distro_ua.md new file mode 100644 index 0000000..88c0c4b --- /dev/null +++ b/docs/how-to-build-a-distro_ua.md @@ -0,0 +1,652 @@ +# Як створити власний дистрибутив 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)