FreeBSD virtual environment management and repository

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.