Установка и обновление софта во FreeBSD

В сети есть много информации про использование портов и пакеджей FreeBSD. К сожалению, часто эта информация оказывается устаревшей. Иногда бывает, что одна статья противоречит другой. Что касается хэндбука, то, на момент написания этих строк, в нем не было ни слова про утилиту pkg_upgrade, а информация об установке приложений из портов и их обновлении находилась на расстоянии двадцати глав. В общем, мне такая ситуация не нравится, так что я решил осветить вопрос в своем блоге.


1. Из чего выбираем?

Первое, что нужно сделать относительно установки софта во FreeBSD – это забыть про «традиционный unix-метод», заключающийся в скачивании архива с исходниками, его распаковке и выполнении команд ./configure, make и make install. Может, пару лет назад в каком-нибудь Slackware еще и было принято так делать, но даже в этом дистрибутиве уже появилась система портов.

Как я уже отмечал ранее, FreeBSD предоставляет два способа установки и обновления программ – из бинарных пакетов (packages) и исходных кодов (портов, ports). У каждого подхода есть свои преимущества. С некоторой осторожностью можно использовать их совместно. Для начала рассмотрим два крайних случая – использование только пакеджей или только портов.


2. Использование пакеджей

Бинарные пакеты представляют собой файлы определенного формата и дерево каталогов определенной структуры, упакованных в один архив. Все пакеты, за исключением нескольких особых случаев, можно скачать с ftp.freebsd.org. Поскольку внутри пакеджей хранятся бинарные исполняемые файлы, то для каждой архитектуры процессора и версии операционной системы нужны свои пакеджи. Какие пакеты мы хотим использовать, определяется переменной окружения $PACKAGESITE. Вот пример для FreeBSD 8 и архитектуры процессора i386:
# это нужно прописать в /root/.cshrc
setenv PACKAGESITE http://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-8-stable/Latest/

Как и в случае с версиями операционной системы, пакеджи бывают версий Release, Stable и Current. Stable – оптимальный вариант в плане частоты обновления и стабильности, так что с Release и Current советую вообще не связываться.

Если вы читали мою заметку про быструю установку FreeBSD, то можете помнить, как для установки пакеджей использовалась утилита pkg_add. По умолчанию она ищет пакеджи в каталоге, указанном в переменной окружения $PKG_PATH. Изменить это поведение можно с помощью ключа -r:
pkg_add -r xorg

Программа скачает и установит Xorg, а также все программы и библиотеки, от которых он зависит. Собственно, главная фишка системы пакеджей и портов заключается в автоматическом контроле зависимостей. Не нужно искать по всей сети исходники программ/библиотек, собирать их, а затем выяснить, что тебе нужно было собрать другие версии. Одна команда – и система сделает все за тебя. Современные дистрибутивы Linux и *BSD используют только такой подход. Вот почему нужно забыть «./configure; make; make install», как страшный сон.

Посмотреть список всех установленных программ можно командой pkg_info. Как правило, список получается довольно объемный, так что используйте grep и less.

Для удаления пакеджей предназначена команда pkg_delete. Использовать ее без ключей неудобно, потому что в этом случае нужно указать полное название пакета. Например, «pkg_delete xorg-fonts-7.5» будет работать, а «pkg_delete xorg-fonts» выведет ошибку, дескать пакет не установлен. Чтобы изменить такое поведение, используйте ключи -ix:
pkg_delete -ix xorg

Эта команда будет пытаться удалить все пакеты, в названии которых содержится «xorg» и перед каждым удалением потребует нашего подтверждения. Не правда ли, это удобнее, чем вручную вводить название десяти пакетов, предварительно выясняя их версии с помощью pkg_info? Также pkg_delete следит, чтобы удаление пакета не привело к нарушению зависимостей.

Теперь допустим, что нам хочется почистить систему от ненужных пакетов. Ненужный пакет – это тот, который мы не используем и от которого не зависят другие пакеты. Последнее можно проверить следующим образом:
pkg_info -Ra | less

Проблема в том, что вывод у команды довольно объёмный и искать в нем пакеты, которые можно безопасно удалить, довольно неприятно. Упростить себе работу можно, используя Perl и регулярные выражения:
pkg_info -Ra
| perl -e 'while(<>){$t.=$_};@t=$t=~/Information for ([^:]+):(?:s{3}|s{2}Required by:s{4})/sig;print join(" ",@t)." ";'

Чтобы постоянно не вводить весь этот ужас, советую прописать алиас («pkg_leafs» ?) в /root/.cshrc сохранить команду в .sh-скрипт (почему не csh?) и затем использовать этот скрипт вместе с grep.

Наконец, самое интересное – обновление пакетов. Лучше всего для этой цели подходит pkg_upgrade, входящий в пакет bsdadminscripts. Не удивляйтесь, что система не имеет средств для обновления программ «из коробки». Какой-нибудь веб-сервер обычно настраивается один раз, после чего работает 5-10 лет, пока железо не развалится. Если за это время в Apache не найдут критическую уязвимость (а шансы этого события не так уж велики), то никому в голову не придет обновляться.

Перед обновлением нелишним будет узнать, что собственно мы собираемся обновлять:
pkg_upgrade -an

Того же эффекта можно добиться командой:
pkg_version -v /var/db/uma/FTPINDEX | grep needs

По умолчанию pkg_version использует индекс, расположенный в дереве портов, а совсем не факт, что это дерево у нас имеется. Поэтому путь к файлу указывается явно. Сам файл FTPINDEX обновляется либо pkg_upgrade’ом, как это показано выше, либо утилитой uma.

Обновление бинарных пакетов обычно происходит быстро, так что можно сразу обновить весь устаревший софт:
pkg_upgrade -a

Если же вам нужно обновить только одну или несколько программ, не забывайте, что вы можете нарушить зависимости. Избежать такой неприятности можно с помощью ключей -R (обновить то, что зависит от пакета) и -r (обновить то, от чего зависит пакет):
pkg_upgrade -rR xorg

И последнее – это поиск пакетов. Допустим, вам нужен какой-то пакет, но вы не знаете, как он называется. Есть два пути. Во-первых, можно воспользоваться файлом FTPINDEX:
cat /var/db/uma/FTPINDEX | cut -d '|' -f 1 | grep -i CodeBlocks

Во-вторых, можно воспользоваться веб-поиском на freebsd.org.


3. Использование портов

Система портов позволяет устанавливать программы, компилируя их из исходных кодов. Порты обновляются намного чаще пакетов, так что с их помощью вы получите более свежий софт. Поскольку в нашем распоряжении имеются исходники, мы можем настроить приложение, включив нужные нам опции и отключив ненужные. Также можно произвести оптимизацию программы под используемый нами процессор и передать дополнительные ключи компилятору.

Платить за все это приходится в первую очередь временем установки программ. Например, даже на очень мощных компьютерах компиляция OpenOffice занимает около суток и требует сколько-то там гигабайт оперативной памяти и места на диске. Сколько точно – не помню. Для сравнения, установка OpenOffice с помощью пакетов занимает несколько минут. Однако это – крайний случай. Мелкие утилиты обычно компилируются за минуты, на софт покрупнее может уходить час или два.

Указать аргументы компилятора и тип процессора можно в файле /etc/make.conf:
CPUTYPE=core2 # тип процессора
CFLAGS?=-O3 -pipe # аргументы компилятора, см 'man gcc'

В принципе, можно этот файл и не трогать. Но раз мы решили заюзать порты, почему бы не воспользоваться всеми их плюсами? Если вы не уверены на счет того, какой типа процессора указать, загляните в /usr/share/examples/etc/make.conf. Там перечислены все поддерживаемые типы процессоров. У меня содержимое оказалось следующим:
# Currently the following CPU types are recognized:
# Intel x86 architecture:
# (AMD CPUs) opteron athlon64 athlon-mp athlon-xp athlon-4
# athlon-tbird athlon k8 k6-3 k6-2 k6 k5
# (Intel CPUs) core2 core nocona pentium4m pentium4 prescott
# pentium3m pentium3 pentium-m pentium2
# pentiumpro pentium-mmx pentium i486 i386
# (Via CPUs) c3 c3-2
# Alpha/AXP architecture: ev67 ev6 pca56 ev56 ev5 ev45 ev4
# AMD64 architecture: opteron, athlon64, nocona, prescott, core2
# Intel ia64 architecture: itanium2, itanium

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

Теперь – об аргументах компилятора (CFLAGS). Чем выше уровень оптимизации, тем медленнее собираются программы, но и тем быстрее они будут работать. Например, флаг -O0 вообще отключает оптимизацию (используется gcc по умолчанию), а -O3 включает все доступные способы оптимизации. Еще есть флаг -Os, предназначенный для оптимизации размера программы. Используйте его, если у вас на диске ну очень мало места. Вообще, не стоит слишком беспокоиться на счет того, что программа будет тормозить, если скомпилировать ее с ключом -O2 вместо -O3. К тому же, есть шанс (небольшой, правда) что какие-то программы не соберутся с ключом -O3.

Еще хочу отметить, что ключи, которые вы зададите в CFLAGS, влияют только на порты. Это, в частности, означает, что не нужно беспокоиться, что эксперименты с make.conf приведут к тому, что вы не сможете обновить ядро системы из исходных кодов. Так, информация к сведению.

Дерево портов хранится в каталоге /usr/ports/. Если у вас этот каталог пустой, порты можно скачать с помощью программы portsnap:
portsnap fetch extract

Примечание: В старых мануалах рекомендуется использовать утилиту cvsup, но это устаревший метод. Забудьте про cvsup так же, как и про «./configure; make; make install»!

Если дерево портов уже есть, не забывайте время от времени его обновлять:
portsnap fetch update

Чтобы установить программу из портов, сначала нужно найти соответствующей ей каталог. Имена каталогов образуются следующим образом: /usr/ports/группа/программа/. Например, в каталоге /usr/ports/ftp/ можно найти все программы, имеющие отношение к протоколу FTP, а упомянутый ранее bsdadminscripts находятся в /usr/ports/sysutils/bsdadminscripts/.

Есть несколько способов найти нужную программу, кроме упомянутого поиска на freebsd.org. Например:
# сначала переходим в каталог с портами
cd /usr/ports
# ищем порт по названию
make search name=firefox
# ищем по ключевому слову
make search key=browser
# быстрый поиск
echo /usr/ports/*/*firefox*

Перейдя в нужный каталог, достаточно сказать
make install clean

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

Некоторые порты имеют дополнительные настройки, которые вас попросят уточнить в процессе установки. Если вы не понимаете, что от вас хотят, соглашайтесь на настройки по умолчанию. Часто во время установки нужного вам порта также устанавливаются его зависимости. Некоторые зависимости интересуются, с какими настройками вы хотели бы их собрать. В результате приходится следить за всем процессом и время от времени отвечать на вопросы. Это не совсем удобно.

Большинство портов понимают команду:
make config-recursive

Выполнив ее, вы настроите порт и его зависимости, после чего можно будет все это дело собрать, не отвечая ни на какие вопросы. Также есть команда, позволяющая вам принять все настройки по умолчанию:
make -DBATCH install clean

Самое интересное в портах то, что после компиляции все приложения собираются в пакеты, после чего происходит установка этих самых пакетов. Другими словами, всем хозяйством, установленным из портов, можно управлять теми же средствами, что мы использовались при работы с пакетами – pkg_info, pkg_delete и так далее!

Примечание: Собрать бинарный пакет из портов можно командой «make package». Для создания пакетов из уже установленных приложений используйте команду pkg_create. Например, команда «pkg_create -R -b xorg-fonts-7.5» создаст бинарные пакеты xorg-fonts и всех его зависимостей, а командной «pkg_create -vb ‘*’» можно сделать резервную копию всех установленных приложений. Подробности – в man-pages.

Следующим по интересности, как и следовало ожидать, идет обновление. Есть две утилиты, предназначенные для обновления программ из портов – portupgrade и portmaster. Мне portmaster кажется во всех отношениях лучше. Во-первых, для работы ему не нужно ничего, кроме самого дерева портов. В отличии от него, portupgrade работает с собственной базой, которая частенько портится, в связи с чем ее приходится перестраивать. Во-вторых, portmaster, в отличии от portupgrade, не тянет за собой Ruby. Поскольку программ, использующих Ruby, довольно мало, не хочется тратить время на его сборку ради одного только portupgrade. Мы ведь помним, что каждый лишний порт – это лишнее время на его компиляцию при установке и обновлении?

В общем, я буду считать, что вы используете portmaster (/usr/ports/ports-mgmt/portmaster/). Однако если это не так, не переживайте – portupgrade имеет точно такой же интерфейс, что и portmaster. То есть, при одинаковых аргументах эти программы (как правило) делают одно и то же.

Итак, мы обновили порты с помощью portsnap и узнали, какие программы состарились, с помощью уже знакомого нам pkg_version. Кстати, эта утилита не является частью bsdadminscripts, а идет вместе с системой. Можно запускать portmaster? Нет, не можно!

Первое, что нужно сделать перед обновлением приложений из портов – это внимательно прочитать файл /usr/ports/UPDATING и выполнить все касающиеся нас инструкции. Не сомневайтесь, вы обязательно забудете это сделать, так что лучше сразу подпишитесь на ленту со всеми изменениями в этом файле. Если вы редко заглядываете в свою RSS-читалку, воспользуйтесь сервисом rss2email.ru.

Обновить программу портмастером очень просто (кстати, с его же помощью можно производить установку):
# ключ -d означает "удалять старые архивы с исходниками"
# если не указать, портмастер будет доставать вас
# множеством вопросов по этому поводу
portmaster -d vim

Сложности начинаются, когда вспоминаешь про зависимости. Самое правильное решение заключается в обновлении всех портов, зависящих от данного (приложения, от которых зависит порт, обновляются всегда):
portmaster -rd vim

Еще можно обновить сразу весть устаревший софт:
portmaster -da

Проблема в том, что компиляция исходников обычно занимает много времени. Есть два способа ускорить обновление. Первый – не удалять старые версии библиотек, тогда можно не обновлять зависимые приложения:
portmaster -wd vim

Второй способ заключается в совместном использовании портов и пакеджей, но об этом чуть ниже. Прежде, чем перейти к этой теме, хочу обратить ваше внимание на ключ -L, поддерживаемый portmaster’ом. Он позволяет получить список приложений, которые можно безопасно удалить, не нарушив зависимости. Лучше использовать его, чем связку из алиасов и регулярных выражений, упомянутую выше.


4. Совместное использование портов и пакетов

Пакеджи и порты можно использовать совместно. Если большую часть времени вы используете пакеджи, то можете время от времени устанавливать что-то из портов, потому что в портах софт всегда свежее, чем в бинарных пакетах. Главное – обновить дерево портов перед установкой. Впрочем, в этом случае с большой вероятностью могут произойти Bad Things™, в связи с чем новичкам лучше его избегать.

Если большую часть времени вы пользуетесь портами, то можете сэкономить на времени установки и обновлении приложений. Для этого нужно использовать portmaster с ключом -P:
# обновить vim, по возможности используя пакеты
portmaster -rdP vim

Если portmaster сможет найти на $PACKAGESITE пакет той же версии, что и версия порта, приложение будет установлено из пакета, а не из портов. Еще portmaster имеет ключ -PP, означающий «устанавливать приложения только из пакетов, а если достаточно свежего пакета нет, прервать работу». Правда, пользы от этого ключа мало.

Еще один вариант – создать собственный веб- или ftp-сервер с пакетами, где они будут обновляться чаще, чем на официальном сервере. То есть на сервере пакеты будут собираться из портов, после чего раздаваться клиентам. Правда, это имеет смысл только в том случае, если у вас большой компьютерный парк, на котором нужно поддерживать свежие версии ПО.

Возможно, это будет не сервер, а домашний компьютер, на котором вы будите компилировать пакеты для дальнейшей установки на свой ноутбук и рабочий компьютер. Но это при условии, что на всех трех машинах используется FreeBSD одной ветки и используются процессоры одной архитектуры (i386 или amd64).

Пожалуй, это все, что касается совместного использования портов и пакетов. Основная идея – не устанавливать более старые версии библиотек и приложений, чем есть на данный момент.


5. И снова эта проблема выбора…

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

Преимущества пакетов – простота использования и быстрая установка. За это приходится платить малой гибкостью и редкими обновлениями. Порты позволяют установить самый свежий софт, настроенный для конкретной ситуации и оптимизированный под конкретную машину. Увы, установка из исходников занимает время, а также требует дополнительного места на диске и средств разработки, необходимых для компиляции приложений.

Используя связку порты+пакеты, можно немного компенсировать недостатки каждого из методов. Но комбинированный подход обладает как преимуществами двух методов, так и суммарными недостатками. Оптимальным вариантом было бы завести сервер, предназначенный для сборки пакетов под наши нужды. Но в этом случае придется выделить лишний сервер или раскошелиться на VDS. Впрочем, если у вас есть машина с десятком виртуалок, считайте, что никаких проблем у вас нет.

Совет стандартный. Используйте то, что больше подходит для вашей задачи. Для себя я решил, что на ноутбуке лучше использовать пакеджи, а на сервере – порты. Вообще-то, учитывая мощность современных компьютеров, можно смело обходиться и одними пакетами.

Дополнение: Тут товарищ visokos посоветовал утилиту pkg_cleanup. Как несложно догадаться по названию, предназначена она для удаления ненужных пакетов:

Самое приятное в ней, что после удаления пакетов предлагается сделать повторный поиск. После него будет выведен список только тех пакетов, которые стали ненужными в результате предыдущей итерации. Очень удобно!

http://eax.me/freebsd-soft/

Обновлено: 12.03.2015