2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !
FreeBSD in packages
Дистрибьюция FreeBSD в виде монолитной базы является предметом ненависти у одной группы системных инженеров и в то же время предметом гордости у другой. Доводы обоих весьма понятны.
Довольно грустно, когда в процессе работы внезапно и срочно необходимы утилиты вроде ping, finger, ssh, telnet, traceroute и их нет под рукой. И довольно весело, когда одной командой можно поставить все необходимое без лишнего хлама.
Между тем не многие критики "толстой базы" FreeBSD знают, что с крайне бородадых времен разработчиками ОС ведутся KNOBS-ы — определенные переменные, специфичные для того или иного приложения.
С помощью них, например, собирают кастомайженные базы через src.conf. Остается лишь решить вопрос построения репозитория в автоматическом режиме и методов его дистрибьюции, с чем нам может помочь pkgng. Следующими парой строчек sh-сценария ( сырцы тут: base2pkg ) решается один из самых наистрашнейших минусов FreeBSD, которым десятилетиями пугают молодежь камрады с Ubuntu.
Всю работу по автоматическому построению списка файлов, соответствующих тому или иному KNOBs и построению файлов MANIFEST, необходимые для создания pkg, выполняет скрипт makepkg.
Алгоритм работы не идеален (ввиду большого количества циклов installworld), но прост: один раз собирается FreeBSD база с опциями по-умолчанию (или со всеми возможными опциями вообще), после чего в цикле из всех возможных KNOBs выполняется installworld WITHOUT_KNOBS и сравниваются файлы с оригиналом. Список файлов, присутствующие в инсталляции по-умолчанию и отсутствующие в базе с WITHOUT_KNOBS и используются для создания пекеджа с именем knobs. Для того, чтобы операция не изнашивала циклами installworld диск, все операции по-умолчанию выполняются на md(4) диске, что требует ~basesize x 2 (окола 1 Гб).
Список всех возможных KNOBS описан в файле /usr/share/mk/bsd.own.mk в __DEFAULT_YES_OPTIONS и __DEFAULT_NO_OPTIONS переменных, отражающие все опции и с какими именно создается база по-умолчанию. Этот список нам понадобятся, поэтому выпишем их в отдельном файле knobs.inc.
Перед запуском подразумевается, что в /usr/src находятся исходные коды FreeBSD и имеются объектные файлы сборки (стадия buildworld), те, операция
% make -C /usr/src buildworld
прошла успешно.
Запуск скрипта:
% /makepkg.sh * WIP: defaultbase. Knobs 0 from 114 * WIP: acct. Knobs 0 from 114 * WIP: acpi. Knobs 1 from 114 * WIP: amd. Knobs 2 from 114 * WIP: apm. Knobs 3 from 114 * WIP: arm_eabi. Knobs 4 from 114 ...
По окончанию отработки, в текущем каталоге со скриптом, в txz/ каталоге будут сфомированы соотетствующие пакеты:
% ls -1 txz/ freebsd-acct-9.2.258493.txz freebsd-acpi-9.2.258493.txz freebsd-amd-9.2.258493.txz freebsd-apm-9.2.258493.txz freebsd-at-9.2.258493.txz freebsd-atm-9.2.258493.txz freebsd-audit-9.2.258493.txz freebsd-authpf-9.2.258493.txz ..
Примечание: Третья цифра в версии соответствует ревизии SVN дерева исходных кодов. Если утилиты svn нет в системе, будет подставлен результат data %s.
Таким образом, вы можете обеспечить свои сервера, которые находятся на промежуточных версиях ( например STABLE_X или вовсе на HEAD-ветках ) бинарным обновлением.
Примечание2: поскольку пакетов много, имеет смысл сделать кумулятивный Meta-пакет freebsd-base, содержащий в качестве зависимостей все другие пекеджи базы.
Последним шагом создадим pkg-каталог через pkg repo и закинем результат на доступный HTTP WEB сервер для раздачи.
% cd txz/ % pkg repo .
Эпилог
Чисто теоретически, в pkgng таким образом можно обернуть абсолютно всю базу, включая разные ядра ОС и обеспечить альтернативу бинарного обновления через FreeBSD update server, однако привычное поведение pkg при любой ошибке делать deinstall устанавливаемого пакета по манифесту, делает не очень надеждым данный способ: неприятно будет потерять файлы в каталоге /lib/* если что-то пойдет не так. Конечно, через pkg hold package можно заморозить состояние пакета, поставив иммунитет на обновления и тп.
Однако гораздо лучшим решением будет создание микро-базы (например средствами picobsd, которая идет в составе FreeBSD, или mfsBSD. Оба инструмента по-умолчанию создают рабочую базу FreeBSD объемем ~20-30 Мб, не подверженную обновлению в pkg, которая будет проливаться на ваш хостинг/парк серверов, а уже сверху через pkg доставлять все, что заблагорассудится.
Наслаждаемся результатом:
% pkg install freebsd-openssh freebsd-zoneinfo freebsd-examples freebsd-games Updating repository catalogue The following 4 packages will be installed: Installing freebsd-openssh: 9.2.258493 Installing freebsd-zoneinfo: 9.2.258493 Installing freebsd-examples: 9.2.258493 Installing freebsd-games: 9.2.258493 The installation will require 9 MB more space 2 MB to be downloaded Proceed with installing packages [y/N]: y freebsd-openssh-9.2.258493.txz 100% 886KB 886.0KB/s 886.0KB/s 00:00 freebsd-zoneinfo-9.2.258493.txz 100% 108KB 108.3KB/s 108.3KB/s 00:00 freebsd-examples-9.2.258493.txz 100% 378KB 378.5KB/s 378.5KB/s 00:00 freebsd-games-9.2.258493.txz 100% 868KB 867.8KB/s 867.8KB/s 00:00 Checking integrity... done [1/4] Installing freebsd-openssh-9.2.258493... done [2/4] Installing freebsd-zoneinfo-9.2.258493... done [3/4] Installing freebsd-examples-9.2.258493... done [4/4] Installing freebsd-games-9.2.258493... done
% pkg info freebsd-acct-9.2.258493 FreeBSD base freebsd-acpi-9.2.258493 FreeBSD base freebsd-amd-9.2.258493 FreeBSD base freebsd-apm-9.2.258493 FreeBSD base freebsd-at-9.2.258493 FreeBSD base freebsd-atm-9.2.258493 FreeBSD base freebsd-audit-9.2.258493 FreeBSD base freebsd-authpf-9.2.258493 FreeBSD base freebsd-binutils-9.2.258493 FreeBSD base freebsd-bluetooth-9.2.258493 FreeBSD base freebsd-boot-9.2.258493 FreeBSD base freebsd-bsd_cpio-9.2.258493 FreeBSD base freebsd-bsnmp-9.2.258493 FreeBSD base freebsd-calendar-9.2.258493 FreeBSD base freebsd-cddl-9.2.258493 FreeBSD base freebsd-cpp-9.2.258493 FreeBSD base freebsd-crypt-9.2.258493 FreeBSD base freebsd-ctm-9.2.258493 FreeBSD base freebsd-cxx-9.2.258493 FreeBSD base freebsd-dict-9.2.258493 FreeBSD base freebsd-examples-9.2.258493 FreeBSD base freebsd-floppy-9.2.258493 FreeBSD base freebsd-forth-9.2.258493 FreeBSD base freebsd-freebsd_update-9.2.258493 FreeBSD base freebsd-games-9.2.258493 FreeBSD base freebsd-gcov-9.2.258493 FreeBSD base freebsd-gdb-9.2.258493 FreeBSD base freebsd-gpib-9.2.258493 FreeBSD base freebsd-gpio-9.2.258493 FreeBSD base freebsd-groff-9.2.258493 FreeBSD base freebsd-html-9.2.258493 FreeBSD base freebsd-inet6-9.2.258493 FreeBSD base freebsd-info-9.2.258493 FreeBSD base freebsd-installlib-9.2.258493 FreeBSD base freebsd-ipfilter-9.2.258493 FreeBSD base freebsd-ipfw-9.2.258493 FreeBSD base freebsd-ipx-9.2.258493 FreeBSD base freebsd-jail-9.2.258493 FreeBSD base freebsd-kerberos-9.2.258493 FreeBSD base freebsd-legacy_console-9.2.258493 FreeBSD base freebsd-lib32-9.2.258493 FreeBSD base freebsd-locales-9.2.258493 FreeBSD base freebsd-locate-9.2.258493 FreeBSD base freebsd-lpr-9.2.258493 FreeBSD base freebsd-mail-9.2.258493 FreeBSD base freebsd-mailwrapper-9.2.258493 FreeBSD base freebsd-make-9.2.258493 FreeBSD base freebsd-man-9.2.258493 FreeBSD base freebsd-ndis-9.2.258493 FreeBSD base freebsd-netcat-9.2.258493 FreeBSD base freebsd-netgraph-9.2.258493 FreeBSD base freebsd-nis-9.2.258493 FreeBSD base freebsd-nls-9.2.258493 FreeBSD base freebsd-ns_caching-9.2.258493 FreeBSD base freebsd-ntp-9.2.258493 FreeBSD base freebsd-openssh-9.2.258493 FreeBSD base freebsd-openssl-9.2.258493 FreeBSD base freebsd-pc_sysinstall-9.2.258493 FreeBSD base freebsd-pf-9.2.258493 FreeBSD base freebsd-pmc-9.2.258493 FreeBSD base freebsd-portsnap-9.2.258493 FreeBSD base freebsd-ppp-9.2.258493 FreeBSD base freebsd-profile-9.2.258493 FreeBSD base freebsd-quotas-9.2.258493 FreeBSD base freebsd-rcmds-9.2.258493 FreeBSD base freebsd-rcs-9.2.258493 FreeBSD base freebsd-rescue-9.2.258493 FreeBSD base freebsd-routed-9.2.258493 FreeBSD base freebsd-sendmail-9.2.258493 FreeBSD base freebsd-sharedocs-9.2.258493 FreeBSD base freebsd-syscons-9.2.258493 FreeBSD base freebsd-sysinstall-9.2.258493 FreeBSD base freebsd-tcsh-9.2.258493 FreeBSD base freebsd-telnet-9.2.258493 FreeBSD base freebsd-textproc-9.2.258493 FreeBSD base freebsd-usb-9.2.258493 FreeBSD base freebsd-utmpx-9.2.258493 FreeBSD base freebsd-wireless-9.2.258493 FreeBSD base freebsd-zfs-9.2.258493 FreeBSD base freebsd-zoneinfo-9.2.258493 FreeBSD base
% which mail portsnap gdb /usr/bin/mail /usr/sbin/portsnap /usr/bin/gdb % pkg which /usr/bin/mail /usr/bin/mail was installed by package freebsd-mail-9.2.258493 % pkg which /usr/bin/gdb /usr/bin/gdb was installed by package freebsd-gdb-9.2.258493 % pkg remove freebsd-mail freebsd-gdb freebsd-portsnap Deinstallation has been requested for the following 3 packages: freebsd-mail-9.2.258493 freebsd-gdb-9.2.258493 freebsd-portsnap-9.2.258493 The deinstallation will free 11 MB Proceed with deinstalling packages [y/N]: y [1/3] Deleting freebsd-mail-9.2.258493... done [2/3] Deleting freebsd-gdb-9.2.258493... done [3/3] Deleting freebsd-portsnap-9.2.258493... done % which mail portsnap gdb mail: Command not found. portsnap: Command not found. gdb: Command not found.
PS: В данной реализации не учтены возможные конфликты по устанавливаемым файлам ( поскольку сборка сделана из общей базы, то при установке пакета freebsd-examples всегда будет выдаваться руганть о коллизиях некоторых файлов ), а также не учтены зависимости. Например, пакет freebsd-openssh и freebsd-openssl зависят от пакета freebsd-crypto.