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

71 KiB
Raw Permalink Blame History

Як створити власний дистрибутив Linux

Докладна інструкція: від вибору основи до опублікованого релізу. Загальні поради підкріплено прикладами з Das OS (Void Linux + Xfce): шляхи на кшталт scripts/container/build-iso.sh ведуть до файлів цього репозиторію, а позначка «Досвід Das OS» — до реальних помилок, на які ми натрапили.

Зміст

  1. Що таке «власний дистрибутив»
  2. Планування перед першим рядком коду
  3. Вибір основи
  4. Середовище збирання
  5. Власні пакети й репозиторій
  6. Як влаштований live-образ
  7. Збирання ISO
  8. Налаштування за замовчуванням і оформлення
  9. Інсталятор
  10. Завантажувач, initramfs і розмітка диска
  11. Оновлення, знімки й відкат
  12. Тестування
  13. CI і релізи
  14. Безпека
  15. Ліцензії й торгові марки
  16. Локалізація й доступність
  17. Документація та спільнота
  18. Типові пастки
  19. Покроковий план з нуля
  20. Чекліст перед релізом
  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)

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).
  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).
  • Усе, що має бути у встановленій системі, — у пакети.

7.3. Основні параметри (на прикладі mklive)

./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.
  • Звук (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 про 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. Віртуальні машини

# 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):

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. Корисні посилання