Docs: Ukrainian guide to building your own distribution [skip ci]
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||||
Reference in New Issue
Block a user