Проект GNU Guix (произносится geeks) — это не производная другого дистрибутива, а независимый дистрибутив со своим менеджером пакетов и Scheme — языком семейства лисп — в качестве системного скриптового языка.
В качестве системы управления сервисами Guix использует не SysV init и не systemd, а GNU sheperd, который произошел из GNU/Hurd и также поддерживает Scheme в качестве языка описания сервисов.
РЕКОМЕНДУЕМ:
Лучшие дистрибутивы для программистов
В этой статье я покажу, как установить GuixSD на виртуальную машину, настроить, обновить систему и создать пакеты.
Установка и базовая настройка GuixSD
Установка в VirtualBox не представляет никакой сложности. При загрузке с ISO нас встречает вполне типичный псевдографический установщик — на этом этапе заметить отличия от других дистрибутивов сложно.
Если ты решишься попробовать на физическом железе, нужно учитывать, что разработчики Guix — члены FSF, а значит, в поставке по умолчанию отсутствуют все несвободные драйверы и прошивки.
Под конец установки пользователь начинает понимать, куда попал, — нам советуют искать базовые настройки в /etc/config.scm и показывают файл с выбранными при установке настройками.
Этот файл — скрипт на языке Scheme и хранит указанные при установке настройки в виде S-выражений.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
;; This is an operating system configuration generated ;; by the graphical installer. (use-modules (gnu)) (use-service-modules desktop networking ssh xorg) (operating-system (locale "en_US.utf8") (timezone "America/Anchorage") (keyboard-layout (keyboard-layout "us")) (host-name "guix") (users (cons* (user-account (name "xakep") (comment "Xakep") (group "users") (home-directory "/home/xakep") (supplementary-groups '("wheel" "netdev" "audio" "video"))) %base-user-accounts)) (packages (append (list (specification->package "nss-certs")) %base-packages)) (services (append (list (service xfce-desktop-service-type) (service openssh-service-type) (set-xorg-configuration (xorg-configuration (keyboard-layout keyboard-layout)))) %desktop-services)) (bootloader (bootloader-configuration (bootloader grub-bootloader) (target "/dev/sda") (keyboard-layout keyboard-layout))) (swap-devices (list "/dev/sda2")) (file-systems (cons* (file-system (mount-point "/") (device (uuid "8f368be5-0dee-4bcc-b9d2-54c8f36a77ab" 'ext4)) (type "ext4")) %base-file-systems))) |
Главное преимущество языков семейства лисп — расширяемый синтаксис. В этом файле
operating-system и прочее — не ключевые слова языка или формата файла, а всего лишь макросы Scheme.
Но пока мы оставим его в стороне и посмотрим на установку пакетов из репозиториев.
Установка и обновление пакетов
Менеджер пакетов, как и сам дистрибутив, называется guix. Иногда, чтобы отличать их, дистрибутив называют GuixSD (Guix System Distribution). В отличие от dpkg или rpm, guix отвечает и за установку пакетов, и за создание системных конфигов из абстрактных высокоуровневых описаний. Также там нет разделения на менеджер пакетов и инструмент работы с репозиториями, как dpkg/APT или rpm/yum.
Для начала мы посмотрим, как использовать его в качестве менеджера пакетов. Перед тем как что-то обновлять или устанавливать, нужно обновить метаданные репозиториев, подобно apt-get update в Debian.
Делается это командой guix pull. Описания пакетов хранятся в Git, и вместо традиционных подписей файлов с метаданными разработчики используют подписанные коммиты. Командой guix pull --news можно посмотреть сводку изменений со времени последнего обновления. Обновляет все пакеты команда guix package --upgrade.
Нужно сразу отметить, что в Guix возможна установка пакетов от имени обычных пользователей — в их личный профиль. Более того, метаданные репозиториев у каждого пользователя тоже свои.
Для примера поставим очень полезную программу — GNU hello.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
xakep@guix ~$ guix pull xakep@guix ~$ guix install hello guix install: warning: Consider running 'guix pull' followed by 'guix package -u' to get up-to-date packages and security updates. The following package will be installed: hello 2.10 substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0% The following derivation will be built: /gnu/store/8x0ck5izca92m13fslj7zrqdip87zvxc-profile.drv 0.1 MB will be downloaded: /gnu/store/a462kby1q51ndvxdv3b6p0rsixxrgx1h-hello-2.10 The following profile hooks will be built: /gnu/store/0m4z25sqnaln6k7wmf59cd4a7ic58da6-ca-certificate-bundle.drv /gnu/store/9hn49fix4wr27djhcmq3d01ihgfc7aij-fonts-dir.drv /gnu/store/9k1xsdbk7nmh7iv2dj3dv0a3zmx0bf70-manual-database.drv /gnu/store/z5i1s0k76zgk9wkqazw1rnz6yirzpylz-info-dir.drv downloading from https://ci.guix.gnu.org/nar/lzip/a462kby1q51ndvxdv3b6p0rsixxrgx1h-hello-2.10 ... hello-2.10 51KiB ... building profile with 1 package... |
Что значит updating substitutes? В терминологии Guix так называются собранные двоичные пакеты. «Основным» способом установки считается сборка пакетов из исходников, но для удобства и экономии ресурсов поддерживается и установка двоичных пакетов как «суррогат» локальной сборки. Несмотря на такое уничижительное название, никаких особых недостатков у двоичных пакетов нет, и оба метода установки равноправны. Guix фокусируется на воспроизводимости окружений сборки и исполняемых файлов, поэтому причин бояться локальной сборки тоже нет. С опцией --no-substitutes Guix игнорирует двоичные пакеты, даже если они доступны, и собирает пакет из исходников.
Исполняемый файл окажется в /home/xakep/.guix-profile/bin/hello. Эта установка пакета будет доступна только нашему пользователю xakep. Другие пользователи вполне могут держать другую версию в своем профиле, и обновление другим пользователем своего пакета никак не затронет наш. Даже у root’а есть свой профиль — установка от его имени еще не значит глобальную установку для всех.
Поиск пакетов организован непривычно и на первый взгляд крайне неудобно. Команда guix search ищет совпадения во всех полях описания пакетов и не предоставляет никаких фильтров. Поиск по guix search hello выдает изрядное количество совершенно не относящихся к делу результатов из-за совпадений в описаниях. На самом деле это не баг, просто следование философии UNIX иногда принимает причудливые формы. В качестве фильтра для результатов поиска авторы рекомендуют GNU recutils. Формат recfile — это текстовый формат для простых баз данных (его можно описать как YAML с однозначной грамматикой), а утилита recsel — инструмент для работы с ним. К примеру, командой guix search hello | recsel -p name,synopsis можно ограничить вывод полями с именем и коротким описанием, как это делают большинство других менеджеров пакетов. С опцией -e можно использовать для поиска регулярные выражения POSIX.
Подход, безусловно, гибкий, но крайне необычный. Мне хочется верить, что другие менеджеры пакетов добавят машиночитаемый вывод — и что Guix сделает свой поиск проще.
Просмотреть информацию об установленном пакете можно командой guix package -I.
1 2 |
$ guix package -I hello hello 2.10 out /gnu/store/a462kby1q51ndvxdv3b6p0rsixxrgx1h-hello-2.10 |
Удалить пакет — командой guix package -r ( --remove).
Обновление системы и конфигурации
В Guix управление пакетами тесно связано с управлением конфигурацией. Каждое обновление системы с помощью guix package --upgrade создает новое «поколение» (generation) состояния системы.
1 2 3 4 5 6 7 8 9 |
xakep@guix ~$ sudo guix system list-generations Generation 1 Jun 22 2020 07:45:03 file name: /var/guix/profiles/system-1-link canonical file name: /gnu/store/xqy25i9sfmznd5b1sw5n4155i8v0l2xc-system label: GNU with Linux-Libre 5.4.31 bootloader: grub root device: UUID: 8f368be5-0dee-4bcc-b9d2-54c8f36a77ab kernel: /gnu/store/g56i8savnfr7981fil03idkjl0syj29d-linux-libre-5.4.31/bzImage configuration file: /gnu/store/cbn7d14kpv7a6agab3x1fm4mxrm4yzl5-configuration.scm |
Командой sudo guix system roll-back можно откатить систему к предыдущему состоянию, если с обновлением что-то пошло не так. Но и это еще не все: команда guix system switch-generation $number позволяет откатить ее к любому предыдущему состоянию, не только последнему.
Очевидно, держать большое количество снимков системы на диске накладно. Командой
sudo guix delete-generations $num можно удалить состояние с указанным номером, а этой же командой без аргумента — все состояния, кроме текущего.
Полезно также помнить про команду
sudo guix gc. Ей можно принудительно удалить все неиспользуемые данные, оставшиеся от прошлых поколений.
Теперь вернемся к файлу настроек /etc/config.scm. В нем хранятся все настройки системы, которыми управляет сам Guix, от имени хоста до списка включенных сервисов. В чем-то это похоже на rc.conf из систем BSD, но с куда более структурированным синтаксисом. Доступные опции описаны в руководстве.
Применить настройки после редактирования файла можно командой sudo guix system reconfigure /etc/config.scm. Эта команда создаст новое «поколение» состояния системы. Как и обновление пакетов, эти изменения можно откатить. Это существенно уменьшает потребность в инструментах вроде Ansible.
В то же время и возможностей управлять настройками вручную в Guix куда меньше. Традиционные команды вроде useradd оказываются бесполезными: guix system reconfigure приведет состояние системы в полное соответствие с файлом /etc/config.scm и удалит все, что ты создал руками.
Создание пакетов
Описания пакетов в Guix тоже пишутся с использованием макросов Scheme. Хорошее введение можно найти в посте A packaging tutorial for Guix. Мы не будем рассматривать создание дополнительных репозитариев и вместо этого воспользуемся возможностью установить пакет из локального файла с описанием.
Для примера возьмем генератор статических блогов blogc. Он не требует никаких зависимостей и использует стандартную процедуру ./configure && make && make install, что сильно упрощает дело.
Сначала нам нужно получить хеш пакета. Стандартная sha256sum выводит хеш в Base64, а Guix по каким-то причинам предпочитает Base32. К счастью, вычисление хешей в нужном формате — встроенная функция.
1 2 3 |
xakep@guix ~$ wget https://github.com/blogc/blogc/releases/download/v0.19.0/blogc-0.19.0.tar.xz xakep@guix ~$ guix hash --hash=sha256 ./blogc-0.19.0.tar.xz 1vr4772ivckaisplwcngfilkq2cnzbdjf326mj7l84r5x3nxw2dl |
Теперь напишем файл описания пакета по аналогии с постом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
(define-module (gnu packages hope) #:use-module (guix packages) #:use-module (gnu packages) #:use-module (guix download) #:use-module (guix build-system gnu) #:use-module (guix licenses)) (package (name "blogc") (version "0.19.0") (source (origin (method url-fetch) (uri (string-append "https://github.com/blogc/blogc/releases/download/v0.19.0/blogc-" version ".tar.xz")) (sha256 (base32 "1vr4772ivckaisplwcngfilkq2cnzbdjf326mj7l84r5x3nxw2dl")))) (build-system gnu-build-system) (synopsis "blogc: a static blog generator") (description "blogc is a blog compiler. It compiles source files and templates into blog/website resources. ") (home-page "https://blogc.rgm.io/") (license bsd-3)) |
Осталось сохранить его в файл. Имя файла не имеет значения, вся информация хранится внутри. Назовем его blogc.scm и выполним guix package --install-from-file=blogc.scm. Теперь команда blogc доступна текущему пользователю.
Просмотреть и даже поправить описание любого установленного пакета можно командой guix edit $packageName. Очень помогает в написании файлов по аналогии.
Заключение
Рекомендовать столь необычный и во многом экспериментальный дистрибутив для широкого применения явно рано, но и обойти стороной тоже невозможно.
Самый заметный недостаток — требования к месту на диске. Классические менеджеры пакетов создавались с целью сделать как можно больше библиотек и данных общими для всех пакетов и таким образом сэкономить место. Подход Nix и Guix уничтожает это преимущество. С другой стороны, он заметно уменьшает потребность в резервных копиях системы и отдельных решениях для установки программ от имени пользователя, так что это скорее компромисс, чем недостаток.
Более заметный минус — склонность Guix принудительно синхронизировать состояние системы с последними репозиториями, когда его об этом не просят. Во многих случаях редактирование настроек в /etc/config.scm и выполнение guix system reconfigure /etc/config.scm «заодно» производит обновление системы, если оно не совпадает с данными из последнего guix pull. Хочется верить, что авторы это исправят.
В официальных репозиториях почти 14 тысяч пакетов. Для независимого дистрибутива довольно внушительно, и все основное там есть, но с более популярными дистрибутивами не сравнить, особенно когда дело касается несвободного ПО — увы, порой без него сложно обойтись.
РЕКОМЕНДУЕМ:
Обзор дистрибутива Feren OS
Сложность ручного управления настройками для одних людей и сценариев применения — явный недостаток, а для других — огромное преимущество. Ну и Scheme как системный язык — это весьма смелое решение, хотя у пользователей куда более популярного Clojure с его изучением не будет никаких проблем.
В целом каждый в итоге решает сам, но посмотреть на новые идеи всегда интересно.