тут подробно, абстрактненько; на гите коротенько, конкретно: github/scclie/sccl_nix/README.md

? на*&я зачем

вот мне раньше, после 6 лет юза онли арча - тоже не было понятно…

на долгое время в меня всядилось старопердунское мнение о подобных вещах: мол наплодили ещё какой-то попсовый дистр, аля федоры, манжары и прочих качи.

а потом мне захотелось его установить… в процессе и после мир перевернулся:

куча проблем, что возникали на обычных дистрах - моменатами решились. мне даже ранее не казалось что это проблемы - за годы использования стандартных дистров ловишь консенсус, просто привыкаешь к тому как над в них работать, чтоб всё было заебись, но то заебись и это заебись - это совершенно два разных заебись.

в обычных линукс дистрах ты не можешь повторить какое-то состояние системы, т.к. все спагетти связи и т.п. просто невозможно повторно воспроизвести через годы юза одной системы. можно лишь полагаться на бекапы и снапшоты типа от zfs и т.п., но это не хранение стейта системы, а просто костыль для возможности откатиться, а не возможность повторно воспроизвести тот же стейт, условно, на другой машине.

в nix-е тупа описываются все пакеты, конфиги, юзеры, сервисы и т.д. - получается полная опись состояния среды, с которой уже нахрен ненужeн бекап системы, для сейва её стейта - нужно бекпить только данные (пользователькие файлы и т.д.).

позже можно и реплиецировать и на вторую машину тем же конфигом.

никс хранит генерацию в формате симлинков - так по сути всё лежит в единственном /nix/store, в одной огромной куче говна - потому нет конфликта зависимостей, можн откатыватья на любой стейт (генерацию) и клонировать её куда угодно.

из кайфовых фич - nix shell - можно накидать прог, поюзать, забить/забыть - а само удалится при следующем garbage collector (чистка бесполезного хлама из /nix/store).

# откуда nix

в 2006 году крутой мужик по имени Eelco Dolstra защитил PhD “The Purely Functional Software Deployment Model” в Utrecht University.

а что если пакет - это чистая функция?

вход: исходники + зависимости + флаги компиляции.

выход: бинарник.

oдинаковый вход = одинаковый выход (на любой машине)

: эт основная идея, не дающая безусловной гарантии, на деле не всякий софт собирается побитово одинаково: где-то может влиять рандом, гдет timeshatmp и т.д.

в никсе тип каждый пакет лежит в своей директории, и путь включает хеш всех входных данных:

/nix/store/5mq2jcn36ldd97xrcnf3jg8irnfp5xqr-fish-4.0.1/

хеш зависит от исходников, зависимостей, флагов компиляции, версии компилятора - ВСЕГО.

любое изменение - другой хеш - другой путь: потому нет конфликтов зависимостей.

эт совершенно другая парадигма, по сравнению с другими пакетниками.

экосистема nixpkgs сейчас - крупнейший в мире репозиторий пакетов. и всё это собирается одной фермой hydra и кешируется в бинарный кеш.

на самом деле немного обман цифр (ну вернее этим прям буквально наёбывают (пытаются продать)) - очень много пакетов разбиты на куча маленьких. если смотреть по реальному софту - nixpkgs меньше чем тот же aur.

# императивное vs декларативное

как вываливали в какой-то очень старой мысли ещё на заре придумывания nix - пакетники можно сравнить с языками программирования.

есть статья “Functional Package Management with Guix” где эта мысль хорошо раскрыта, но идея звучала и раньше.

мне лень искать, где ещё, но было!

процедурные пакетники - стандартные apt, yum,pacman и т.д. (т.е. типа все императивные пакетники, де ты ручками всё ставишь, иль пишешь под ето последовательные скрипты)

декларативные пакетники - как раз nix и есть ещё guix (это уже типа как функциональный подход, де ты больше описываешь результат)

а дальше чо? какой-то более высокоуровневый подход, более абстрактный? (иль мега абстрактный llm-based chat interface??????? - ai problem resolver :D )

погодите… omarchy linux.

# экосистема

сам по себе nixos решает только проблемы пакетника, а есть ещё куча всего, что хочется в декларативщину.

## flakes

экспериментал features с 2021 года… на самом деле юзают почти все, её уже давно можно назвать стабильной.

он даёт два удобства:

  • версионирование зависимостей через flake.lock
  • общий формат input output

до флейков тоже можно было пинить версии nixpkgs и жить. прст флейки складывают это в более стандартизированную конструкцию.

в моём конфиге флейк авто-дискаверит хосты из папок - кидаешь hosts/<hostname>/, он сам подхватывает в nixosConfigurations.<hostname>.

## home-manager

github.com/nix-community/home-manager - позволяет декларативно управлять пользовательским окружением.

раньше дотфайлы делали через gnu stow или bare git repo, a home-manager позволяет всё то же самое, но nix-way: с опциями, зависимостями и иммутабельностью.

интегрируется с nixos модулем. Один nixos-rebuild switch пересобирает и систему и пользовательское окружение.

## disko

github.com/nix-community/disko - в никсе описывается как код, кроме разметки дисков - при установке делается ручками. disko исправляет это печальное упущение.

достаточно один раз прописать конфиг разметки дисков, а не дрочить каждый раз gparted если хосты с одинаковыми дисками - можно спокойно реплиецировать и его, может с какими-то малыми правками.

## sops-nix

github.com/mic92/sops-nix - позволяет хранить секреты (ssh-ключи, пароли, gpg) прямо в репе, хоть у всех на виду. при билде расшифровываются и монтируются в нужные места.

есть статейка по умному менежменту секретов - я стараюсь следовать ей.

# проблема масштабирования

никс - крутой инструмент, но при выстраивании архитектуры с ним всё можно так же как и везде превратить в свалку с кучей исключений и т.п.

есть подходы, чтоб этого избежать:

  • flake-parts - модульная система для флейков, позволяет разбивать конфиг на переиспользуемые модули. хорош для больших проектов, но добавляет свой слой абстракции.
  • snowfall-lib - библиотека для организации nix-конфигов с авто-дискавери. похожа на то что делаю я, но со своей философией.
  • можно жить как палка ляжет - в рамках одной-двух систем не вызывает особой боли.

# архитектура sccl_nix

(ну чо я делаю, хз насколько это правильно)

у мя дотфайлы разделены на три сущности.

  • hosts - железо и системщина: disko, дрова gpu, сеть, системные пакеты - всё что нельзя синкать между разными машинами. авто-дискаверятся флейком из hosts/.
  • profiles - пользователь со своим зоопарком прог, шеллом и user-level хламом. на одном хосте может быть сколько угодно профилей. импортятся в конфиг хоста.
  • shared - база для всех. всякие основные проги и севрисы, которые импортятся всем.

сейчас два три хоста: sacculos(десктоп, AMD) и aero15laptop(ноут, NVIDIA), laerandr(сервер)

два профиля: paper (основной, со всем зоопарком) и bootstrap (минимальный, только vim, nmtui и ssh для установки с флешки).

## sccl.*

Главная фича, которая не даёт конфигу скатиться в свалку условностей.

В core.nix определены ВСЕ опции, и все они по дефолту false. Каждый модуль гейтит сам себя через lib.mkIf config.sccl.<feature>.enable.

{ config, lib, ... }:
{
  config = lib.mkIf config.sccl.zapret.enable {
    services.zapret = { ... };
  };
}

полный список опций (на момент написания статьи, хз буду ли обновлять (нет не буду, нахуя? их там много.)):

sccl.ui.enable           # Nord-тема + greetd
sccl.audio.enable        # pipewire
sccl.bluetooth.enable    # bluetooth + blueman
sccl.net.enable          # networkmanager + прокси + firewall
sccl.automount.enable    # udisks2 автоподключение флешек
sccl.secrets.enable      # sops-nix шифрованные секреты
sccl.zapret.enable       # обход DPI
sccl.flclashx.enable     # FlClashX GUI для прокси
sccl.playground.enable   # Docker + dev tools
sccl.chaotic.enable      # chaotic-nyx репо
sccl.nix-ld.enable       # nix-ld для бинарников не из nixpkgs
sccl.bootstrap           # bool: минимальный режим установки

Конфиг хоста выглядит буквально так:

sccl = {
  ui.enable = true;
  audio.enable = true;
  net.enable = true;
  automount.enable = true;    # только на десктопе
  zapret.enable = true;       # только на десктопе
  playground.enable = true;   # только на десктопе
  nix-ld.enable = true;
};

так же есть опции для сервера, врубаются так же, их ещё больше, перечислять не буду

для добавление нового хоста тупа копируется вся папка, правится configuration.nix, генерится hardware-configuration.nix, и правится disko.nix- а флейк сам его подхватит.

bootstrap-профиль решает проблему установки на слабом железе (это костыль, но мне так удобна)

в основоном юзаю nixos-anywhere

## Раскладка

Раскладка параметризована через аргументы флейка (specialArgs).

У sacculos эрго-сплит на vial прошивке - us,rulemak_vial. У aero15laptop - colemak_dh,rulemak. один mkHost в flake.nix, и все слои (системная клава, xkb, wm) получают правильную раскладку.

на уровне wm (niri) раскладка тоже передаётся параметром: на десктопе colemak-caws, на ноуте colemak-dh-wide. это удобно для разных клав с разной прошивкой и разными раскладками на разных машинах.

# подвох?

  • буквально над учить новый язык - nix
  • доки есть, доки крутые, многое узнаёшь методом тыка и чтения чужих конфигов. литерально How to Learn Nix - это капеп настрочили букф :skull:
  • дрочь с nix-ld/patchelf при подтягивании своего софта, если он пытается искать зависимости по нужным путям.
  • время билда: билдится всё оч долго, не так долго как женту, что-то тянется с кеша, флейки так же могут сильно тормозить билд. незначительные изменения достаточно быстро проходят.
  • никс не решает проблему версионирования данных.
  • оверкилл для простых вещей
  • при большом скилле и тут можно насрать.

я не знаю зачем я его юзаю, мне по кайфу.