aboutsummaryrefslogtreecommitdiff
path: root/ru_RU.KOI8-R/articles/portbuild/article.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'ru_RU.KOI8-R/articles/portbuild/article.sgml')
-rw-r--r--ru_RU.KOI8-R/articles/portbuild/article.sgml756
1 files changed, 756 insertions, 0 deletions
diff --git a/ru_RU.KOI8-R/articles/portbuild/article.sgml b/ru_RU.KOI8-R/articles/portbuild/article.sgml
new file mode 100644
index 0000000000..c234651672
--- /dev/null
+++ b/ru_RU.KOI8-R/articles/portbuild/article.sgml
@@ -0,0 +1,756 @@
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
+<!--
+ The FreeBSD Russian Documentation Project
+
+ $FreeBSDru: frdp/doc/ru_RU.KOI8-R/articles/portbuild/article.sgml,v 1.11 2007/05/15 19:23:49 gad Exp $
+
+ Original revision: 1.13
+-->
+
+<!ENTITY % articles.ent PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Articles Entity Set//EN">
+%articles.ent;
+]>
+
+<article lang="ru">
+ <articleinfo>
+ <title>Процесс построения пакетов</title>
+
+ <authorgroup>
+ <corpauthor>Группа поддержки портов &os;</corpauthor>
+ </authorgroup>
+
+ <pubdate>$FreeBSD$</pubdate>
+
+ <copyright>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <holder role="mailto:portmgr@FreeBSD.org">Группа поддержки портов
+ &os;</holder>
+ </copyright>
+
+ <legalnotice id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.intel;
+ &tm-attrib.sparc;
+ &tm-attrib.general;
+ </legalnotice>
+ </articleinfo>
+
+ <sect1 id="intro">
+ <title>Введение</title>
+
+ <para>Для того, чтобы подготовить предкомпилированные версии
+ поддерживаемых приложений для &os;, на одном из <quote>Кластеров сборки
+ пакетов</quote> регулярно производится сборка полного дерева портов.
+ В настоящее время существует два таких кластера:
+ <hostid role="fqdn">pointyhat.FreeBSD.org</hostid> и
+ <hostid role="fqdn">dosirak.kr.FreeBSD.org</hostid>.</para>
+
+ <para>Большая часть <quote>магии</quote> процесса сборки
+ сосредоточена в дереве каталогов <filename>/var/portbuild</filename>.
+ Если не оговаривается иное, все пути указаны относительно этого
+ каталога. <replaceable>${arch}</replaceable> используется для указания
+ на архитектуру платформы сборки (&i386;, alpha, &sparc64;, ia64 или
+ amd64); <replaceable>${branch}</replaceable> описывает ветвь построения
+ (4, 5, 5-exp, 6, 6-exp и 7).
+ </para>
+ </sect1>
+
+ <sect1 id="management">
+ <title>Конфигурация машин-клиентов</title>
+
+ <para>Клиенты архитектур &i386;, alpha, amd64 и два из &sparc64; клиентов
+ загружаются по сети с <hostid>pointyhat</hostid>; прочие sparc64 клиенты
+ и машины для сборки ia64 загружаются самостоятельно. Так или иначе, все
+ они в процессе загрузки подготавливаются к сборке пакетов.
+ </para>
+
+ <para>В серии последних обновлений была добавлена поддержка
+ <replaceable>несвязанных (disconnected)</replaceable> узлов кластера.
+ Несвязанный узел не монтирует мастер-машину кластера по NFS, и может,
+ таким образом, быть достаточно удален от центра. Мастер-машина копирует
+ нужные данные (иерархии портов, исходных текстов системы,
+ архивы системы, скрипты и т.п.) при помощи rsync на этапе начальной
+ конфигурации узлов. Затем, каталог portbuild монтируется как nullfs
+ для сборок пакетов.
+ </para>
+
+ <para>Псевдо-пользователь
+ <username>ports-<replaceable>${arch}</replaceable></username>
+ может выполнить команду &man.ssh.1; от имени <username>root</username>
+ на любую клиентскую машину архитектуры
+ <replaceable>${arch}</replaceable>.
+ </para>
+
+ <para>Скрипт <command>scripts/allgohans</command> используется для
+ выполнения команд на всех клиентах архитектуры
+ <replaceable>${arch}</replaceable>.
+ </para>
+
+ <para>Скрипт <command>scripts/checkmachines</command> отслеживает уровень
+ загрузки узлов кластера и распределяет, какой из узлов будет строить
+ очередной порт. Этот скрипт не слишком умен и время от времени умирает.
+ Лучше всего запускать его при загрузке основной машины кластера
+ (<hostid>pointyhat</hostid> или <hostid>dosirak</hostid>) в цикле
+ &man.while.1;.
+ </para>
+ </sect1>
+
+ <sect1 id="setup">
+ <title>Подготовка ограниченной среды сборки</title>
+
+ <para>Пакеты собираются в ограниченной (<literal>chroot</literal>) среде,
+ которая разворачивается скриптом <filename>portbuild</filename> из архива
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/tarballs/bindist.tar</filename>.
+ Этот архив создается при помощи скрипта <command>mkbindist</command>,
+ конфигурация которого описывается файлом
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/mkbindist.conf</filename>.
+ </para>
+
+ <para>Скрипт должен запускаться с правами пользователя
+ <username>root</username> и следующими параметрами:
+ </para>
+
+ <screen>/var/portbuild&prompt.root; <userinput>scripts/mkbindist <replaceable>${arch}</replaceable> <replaceable>${branch}</replaceable></userinput></screen>
+
+ <para>При указании в файле <filename>mkbindist.conf</filename> параметра
+ <literal>ftp=1</literal> с адреса
+ ftp://<replaceable>${ftpserver}</replaceable>/<replaceable>${ftpurl}</replaceable>/<replaceable>${rel}</replaceable>
+ будет загружен предварительно собранный релиз.
+ Если указано <literal>ftp=0</literal> и <literal>buildworld=1</literal>,
+ скрипт <command>mkbindist</command> выполнит
+ <command>makeworld</command> для того, чтобы собрать релиз на месте
+ [<literal>XXX</literal> Эта часть в настоящее время не работает].
+ </para>
+
+ <para>Если оба параметра равны нулю (<literal>ftp=0</literal> и
+ <literal>buildworld=0</literal>), то <command>mkbindist</command>
+ будет использовать существующее на момент запуска состояние дерева
+ <replaceable>${worlddir}</replaceable> для создания
+ <filename>bindist.tar</filename>. На практике это означает, что вы
+ должны предварительно установить систему в ${worlddir}, что обычно
+ делается при помощи скрипта <command>makeworld</command>:
+ </para>
+
+ <screen>/var/portbuild&prompt.root; <userinput>scripts/makeworld <replaceable>${arch}</replaceable> <replaceable>${branch}</replaceable> [-nocvs]</userinput></screen>
+
+ <para>Эта команда соберет систему на базе исходных текстов в дереве
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/src</filename>
+ и установит ее в <replaceable>${worlddir}</replaceable>.
+ Исходные тексты будут обновлены, если не указан параметр
+ <literal>-nocvs</literal>.
+ </para>
+
+ <para>Содержимое архива <filename>bindist.tar</filename> будет распаковано
+ на каждом клиенте в период загрузки, а также на старте каждого прохода
+ скрипта <command>dopackages</command>.
+ </para>
+ </sect1>
+
+ <sect1 id="starting">
+ <title>Запуск сборки</title>
+
+ <para>Для сборки пакетов используются скрипты
+ <filename>scripts/dopackages*</filename>. Наиболее полезными являются:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para><command>dopackages.4</command> - собирает пакеты для версии 4.X
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><command>dopackages.5</command> - собирает пакеты для версии 5.X
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><command>dopackages.5-exp</command> - производит сборку ветви
+ для версии 5.X с экспериментальными изменениями (ветвь 5-exp)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><command>dopackages.6</command> - собирает пакеты для версии 6.X
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><command>dopackages.6-exp</command> - производит сборку ветви
+ для версии 6.X с экспериментальными изменениями (ветвь 6-exp)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><command>dopackages.7</command> - собирает пакеты для версии 7.X
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>Все они вызывают универсальный скрипт <command>dopackages</command>,
+ и являются символьными ссылками на <command>dopackages.wrapper</command>.
+ Для создания скрипта для сборки пакетов новой ветви достаточно создать
+ символическую ссылку <command>dopackages.${branch}</command>, указывающую
+ на <command>dopackages.wrapper</command>. Могут быть указаны
+ многочисленные параметры, например:
+
+ <screen><command>dopackages.6 <replaceable>${arch}</replaceable> <literal>[-options]</literal></command></screen>
+
+ <para><literal>[-options]</literal> может быть произвольным набором из
+ следующих опций:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>-nofinish</literal> - Не производить пост-обработку
+ по завершении сборки. Полезно, если процесс сборки потребуется
+ рестартовать. В обычных ситуациях эту опцию следует использовать
+ всегда.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-finish</literal> - Произвести пост-обработку
+ (и только: собственно сборку не производить).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-restart</literal> - Рестартовать прерванный
+ (или незавершенный, т.е. запущенный без флага
+ <literal>-finish</literal>) процесс сборки с самого начала.
+ При этом порты, попытка сборки которых на предыдущем проходе
+ завершилась неудачно, будут пересобраны.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-continue</literal> - Продолжить прерванный
+ (или незавершенный) процесс сборки. Порты, не прошедшие
+ сборку, не пересобираются.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-incremental</literal> - Сравнить необходимые поля
+ в текущем файле <literal>INDEX</literal> с его предыдущим состоянием,
+ удалить пакеты и журналы их сборки для обновившихся портов и
+ пересобрать их. Этот ключ позволяет существенно сократить время
+ сборки, поскольку нет необходимости пересобирать каждый раз не изменившиеся
+ порты.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-cdrom</literal> - Текущая сборка предназначена для
+ помещения на CD-ROM, поэтому исходные архивы и пакеты портов,
+ помеченных <literal>NO_CDROM</literal> должны быть удалены при
+ пост-обработке.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-nobuild</literal> - Произвести первоначальную
+ подготовку, не запуская собственно процесс сборки пакетов.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-noindex</literal> - Не перестраивать файл
+ <filename>INDEX</filename> в ходе препроцессинга.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-noduds</literal> - Не перестраивать файл
+ <filename>duds</filename> (список портов, которые не будут строиться,
+ например, помеченные признаками <literal>IGNORE</literal>,
+ <literal>NO_PACKAGE</literal> и т.п.) перед процессом сборки.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-trybroken</literal> - Пытаться собрать порты,
+ помеченные как <literal>BROKEN</literal> (по умолчанию выключено,
+ поскольку кластер архитектуры &i386; довольно быстр, и при
+ инкрементной сборке больше времени тратится на пересборку
+ того, что все равно не сможет собраться.
+ С другой стороны, кластеры других архитектур достаточно медленны,
+ так что пытаться собирать на них порты с флагом
+ <literal>BROKEN</literal> было бы напрасной тратой времени.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-nocvs</literal> - Не выполнять обновление
+ (<command>cvs update</command>) дерева исходных текстов
+ (<literal>src</literal>) на этапе препроцессинга.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-noportscvs</literal> - Не обновлять
+ (<command>cvs update</command>) дерево портов
+ (<literal>ports</literal>) на этапе препроцессинга.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-nodoccvs</literal> - Не обновлять
+ (<command>cvs update</command>) дерево документации
+ (<literal>doc</literal>) в ходе препроцессинга. (устаревшая опция)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-norestr</literal> - Не пытаться компилировать порты,
+ помеченные как <literal>RESTRICTED</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-plistcheck</literal> - Считать ошибкой оставление
+ лишних файлов после деинсталляции порта.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-distfiles</literal> - Собрать архивы исходных файлов
+ (<literal>distfiles</literal>) для дальнейшего их переноса на
+ <hostid>ftp-master</hostid>. Эту опцию следует использовать изредка,
+ поскольку она требует очень много места. Исходные архивы следует
+ удалить после загрузки их на <hostid>ftp-master</hostid>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-fetch-original</literal> - Загружать исходные архивы
+ с оригинальных сайтов, определенных переменными
+ <literal>MASTER_SITES</literal>, а не с <hostid>ftp-master</hostid>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Убедитесь, что процесс сборки пакетов для архитектуры
+ <replaceable>${arch}</replaceable> запускается от имени пользователя
+ ports-<replaceable>${arch}</replaceable>; в противном случае ошибки
+ неизбежны.
+ </para>
+
+ <note><para>Сборка пакетов производится в два идентичных прохода. Иногда
+ временные проблемы, такие как ошибки NFS или недоступность FTP-сайтов,
+ могут прервать сборку. Дублирование попыток позволяет обойти подобные
+ проблемы.
+ </para></note>
+
+ <para>Проверьте, чтобы <filename>ports/Makefile</filename>
+ не ссылался на пустые подкаталоги. В особенности это важно для сборки
+ ветви -exp. Если процесс сборки обнаруживает пустой каталог, обе
+ фазы сборки вскоре остановятся. При этом в файлы
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/make.[0|1]</filename>
+ будет записано сообщение об ошибке примерно такого вида:
+ </para>
+
+ <screen><literal>don't know how to make dns-all(continuing)</literal></screen>
+
+ <para>Для исправления ситуации просто закомментируйте или удалите строчки
+ <literal>SUBDIR</literal>, указывающие на пустые подкаталоги.
+ После этого вы можете перезапустить сборку командой
+ <command>dopackages</command>, добавив ей параметр
+ <literal>-restart</literal>.
+ </para>
+
+ <note>
+ <para>Та же проблема возникает при создании файла
+ <filename>Makefile</filename> для новой категории, не содержащего
+ ни одной ссылки на подкаталоги (<makevar>SUBDIR</makevar>).
+ Это, скорее всего, ошибка, подлежащая исправлению.</para>
+ </note>
+ </sect1>
+
+ <sect1 id="anatomy">
+ <title>Процесс сборки</title>
+
+ <para>Полный процесс сборки без каких-либо ключей, начинающихся с
+ <literal>-no</literal>, выполняет следующую последовательность
+ операций:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Обновление из CVS-репозитория текущего дерева
+ <literal>ports</literal> [*]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Обновление из CVS-репозитория дерева
+ <literal>src</literal> необходимой ветви [*]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Проверка файлов <filename>Makefile</filename> на отсутствие
+ строк <literal>SUBDIR</literal> [*]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Создание файла <filename>duds</filename>, содержащего список
+ портов, которые не надо пытаться собирать [*] [+]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Генерация нового файла <filename>INDEX</filename> [*] [+]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Начальная подготовка узлов, которые будут участвовать в сборке
+ [*] [+]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Построение списка портов ограниченного распространения
+ (restricted) [*] [+]</para>
+ </listitem>
+
+ <listitem>
+ <para>Сборка пакетов (фаза 1) [++]</para>
+ </listitem>
+
+ <listitem>
+ <para>Повторная установка узлов сборки [+]</para>
+ </listitem>
+
+ <listitem>
+ <para>Сборка пакетов (фаза 2) [++]</para>
+ </listitem>
+ </orderedlist>
+
+ <para>[*] Результаты выполнения этих шагов записываются в файл
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/build.log</filename>,
+ а также в стандартный вывод для ошибок консоли, с которой запускался скрипт
+ <command>dopackages</command>.</para>
+
+ <para>[+] При неудачном завершении любого из этих шагов процесс
+ прекращается.</para>
+
+ <para>[++] Результаты выполнения пишутся в файл
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/make.[0|1]</filename>,
+ где <filename>make.0</filename> соответствует первой, а
+ <filename>make.1</filename> второй фазе сборки. Журналы сборки отдельных
+ портов записываются в файлы
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/logs</filename>,
+ а журналы портов, собравшихся неудачно, в
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/errors</filename>.
+ </para>
+
+ <para>Ранее из репозитория извлекалось также дерево документации;
+ в настоящий момент это считается ненужным.
+ </para>
+ </sect1>
+
+ <sect1 id="interrupting">
+ <title>Прерывание процесса сборки</title>
+
+ <para>Для прерывания процесса сборки обычно достаточно послать сигнал
+ <literal>HUP</literal> процессам <command>dopackages*</command>
+ или вызванным ими процессам <command>make</command>. Процессы,
+ запущенные на узлах сборки, завершатся самостоятельно в течение
+ нескольких минут (их наличие следует проверять командой
+ <command>ps x</command>). Обычно достаточно следующей команды:</para>
+
+ <screen>&prompt.user; <userinput>killall -HUP sh ssh make</userinput></screen>
+
+ <para>Удалите файл
+ <filename><replaceable>${arch}</replaceable>/lock</filename>
+ перед тем, как перезапустите сборку.
+ </para>
+ </sect1>
+
+ <sect1 id="monitoring">
+ <title>Слежение за процессом</title>
+
+ <para>Команда
+ <command>scripts/stats <replaceable>${branch}</replaceable></command>
+ показывает количество собранных на настоящий момент пакетов.</para>
+
+ <para>Команда <command>cat /var/portbuild/*/loads/*</command>
+ покажет текущую загрузку клиентских машин и количество процессов сборки,
+ запущенных на них.</para>
+
+ <para>Выполнение
+ <command>tail -f <replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/build.log</command>
+ продемонстрирует общее состояние процесса сборки.</para>
+
+ <para>В случае, если порт не собирается, и из логов не понятны причины
+ этого, вы можете сохранить рабочий каталог сборки
+ (<literal>WRKDIR</literal>) для последующего анализа.
+ Для этого создайте файл <filename>.keep</filename> в каталоге порта.
+ При следующей сборке порта кластером архив <literal>WRKDIR</literal>
+ будет помещен в файл
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/wrkdirs</filename>.
+ </para>
+
+ <para>Следите за выводом команды &man.df.1;. Если файловая система,
+ содержащая <filename>/var/portbuild</filename>, переполнится, будет
+ <trademark>Очень Плохо</trademark>.
+ </para>
+ </sect1>
+
+ <sect1 id="release">
+ <title>Сборка пакетов для релизов</title>
+
+ <para>При сборке пакетов для включения в релиз может потребоваться ручное
+ обновление иерархий <literal>ports</literal> и <literal>src</literal>
+ до нужного тэга, а также использование опций <literal>-nocvs</literal>
+ и <literal>-noportscvs</literal>.</para>
+
+ <para>Для подготовки комплекта пакетов для помещения на CD-ROM используйте
+ параметр <literal>-cdrom</literal> при запуске
+ <command>dopackages</command>.</para>
+
+ <para>Если на кластере достаточно дискового пространства, можно применить
+ ключ <literal>-distfiles</literal> для выкачивания дистрибутивных
+ архивов.</para>
+
+ <note><para>Первая сборка должна быть произведена с параметром
+ <literal>-distfiles</literal>.</para></note>
+
+ <para>По завершении первого процесса сборки перезапустите его с параметрами
+ <literal>-restart -distfiles -fetch-original</literal>,
+ для того чтобы выкачать обновленные дистрибутивы.
+ Затем, на этапе финальной обработки, соберите список файлов при помощи
+ команды</para>
+
+ <screen>&prompt.user; <userinput>cd <replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable></userinput>
+&prompt.user; <userinput>find distfiles > distfiles-<replaceable>${release}</replaceable></userinput></screen>
+
+ <para>Этот файл обычно копируют в каталог
+ <filename>i386/<replaceable>${branch}</replaceable></filename>
+ главной машины кластера.</para>
+
+ <para>Данная процедура помогает чистить комплект дистрибутивных архивов,
+ располагающийся на <hostid>ftp-master</hostid>. Если дисковое
+ пространство заканчивается, можно сохранить архивы для свежих релизов,
+ а прочие&nbsp;&mdash; удалить.</para>
+
+ <para>После копирования дистрибутивов (см. ниже) надо создать окончательный
+ комплект пакетов для релиза. Для полного спокойствия, запустите скрипт
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/cdrom.sh</filename>
+ вручную, чтобы быть уверенным, что все пакеты ограниченного
+ распространения и их исходные архивы удалены. Затем скопируйте каталог
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/packages</filename>
+ в
+ <filename><replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/packages-<replaceable>${release}</replaceable></filename>.
+ После того, как пакеты переложены в надежное место, свяжитесь с группой
+ &a.re; и сообщите им расположение финального комплекта пакетов.</para>
+
+ <para>Помните о необходимости координации с группой &a.re; по поводу
+ времени и статуса сборки пакетов для релизов.
+ </para>
+ </sect1>
+
+ <sect1 id="uploading">
+ <title>Загрузка пакетов для раздачи</title>
+
+ <para>После завершения сборки пакеты и/или их исходные архивы
+ могут быть загружены на <hostid>ftp-master</hostid> для
+ раздачи по сети зеркал FTP. Если сборка велась с ключом
+ <literal>-nofinish</literal>, не забудьте произвести пост-обработку
+ при помощи команды <command>dopackages -finish</command> (будут удалены
+ пакеты, помеченные как <literal>RESTRICTED</literal> и
+ <literal>NO_CDROM</literal>, а также пакеты, отсутствующие в файле
+ <filename>INDEX</filename>, из файла <filename>INDEX</filename> будут
+ удалены ссылки на не собравшиеся пакеты, и, наконец, будет создан файл
+ <filename>CHECKSUM.MD5</filename> с контрольными суммами собранных
+ пакетов; кроме того, эта фаза переместит исходные архивы из каталога
+ <filename>distfiles/.pbtmp</filename> в <filename>distfiles/</filename>,
+ а также удалит исходные архивы для портов, помеченных как
+ <literal>RESTRICTED</literal> и <literal>NO_CDROM</literal>).</para>
+
+ <para>Хорошей идеей является запустить вручную скрипты
+ <command>restricted.sh</command> и/или
+ <command>cdrom.sh</command> после завершения работы
+ <command>dopackages</command> просто для собственного спокойствия.
+ Скрипт <command>restricted.sh</command> запускается перед копированием
+ на <hostid>ftp-master</hostid>; затем, перед подготовкой финального
+ набора пакетов для релиза выполните <command>cdrom.sh</command>.
+ </para>
+
+ <para>Пакеты можно копировать во временную область на
+ <hostid>ftp-master</hostid> примерно такой командой:</para>
+
+ <screen>&prompt.root; <userinput>cd /var/portbuild/<replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable></userinput>
+&prompt.root; <userinput>tar cfv - packages/ | ssh portmgr@ftp-master tar xfC - w/ports/<replaceable>${arch}</replaceable>/tmp/<replaceable>${branch}</replaceable></userinput></screen>
+
+ <para>Затем, на машине <hostid>ftp-master</hostid>, убедитесь, что набор
+ пакетов скопирован корректно, удалите старый набор (из каталога
+ <filename>~/w/ports/<replaceable>${arch}</replaceable></filename>),
+ и переместите новый на его место.</para>
+
+ <note><para>Некоторые каталоги на <hostid>ftp-master</hostid> на самом деле
+ являются символьными ссылками. Убедитесь, что вы перемещаете новый набор
+ пакетов в <emphasis>реальный</emphasis> каталог, а не на место
+ расположения одной из ссылок.</para></note>
+
+ <para>Для инкрементных сборок пакеты должны загружаться посредством
+ <command>rsync</command>. Так мы не создаём сильной загрузки на
+ зеркалах:</para>
+
+ <screen>&prompt.root; <userinput>rsync -n -r -v -l -t -p --delete packages/ portmgr@ftp-master:w/ports/<replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable>/ | tee log</userinput></screen>
+
+ <para>Дистрибутивные архивы копируются при помощи команды
+ <command>rsync</command>:</para>
+
+ <screen>&prompt.root; <userinput>cd /var/portbuild/<replaceable>${arch}</replaceable>/<replaceable>${branch}</replaceable></userinput>
+&prompt.root; <userinput>rsync -r -v -l -p -c -n distfiles/ portmgr@ftp-master:w/ports/distfiles/ | tee log</userinput></screen>
+
+ <para><emphasis>ВСЕГДА</emphasis> для начала используйте ключ
+ <literal>-n</literal> команды <command>rsync</command> и проверяйте
+ ее вывод. Если все выглядит нормально, перезапустите
+ <command>rsync</command> без опции <literal>-n</literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="expbuilds">
+ <title>Экспериментальная сборка</title>
+
+ <para>Время от времени для тестирования новых возможностей или
+ исправлений общей инфраструктуры портов (<literal>bsd.port.mk</literal>),
+ а также для тестирования крупных обновлений, затрагивающих существенную
+ часть пакетов, проводится сборка с экспериментальными патчами. Текущей
+ экспериментальной веткой является <literal>6-exp</literal> в архитектуре
+ &i386;.</para>
+
+ <para>В целом, экспериментальная сборка производится так же, как и обычная.
+ Основное отличие: перед запуском скрипта <literal>dopackages</literal>
+ нужно применить к дереву портов необходимые изменения.
+ Хорошей идеей будет сохранить копии всех изменяемых файлов, а также их
+ список. К списку вы сможете вернуться перед произведением окончательного
+ коммита.</para>
+
+ <para>Для создания <quote>контрольного экземпляра</quote> для сравнения
+ следует сначала произвести сборку той ветви архитектуры &i386;, на которой
+ основана экспериментальная ветвь (в настоящее время это ветвь
+ <literal>6</literal>). Перед экспериментальной сборкой выгрузите
+ деревья src и ports на момент произведения контрольной сборки.
+ В этом случае вы можете быть уверены, что сравниваете яблоки с яблоками.
+ </para>
+
+ <note><para>Два кластера сборки могут производить контрольную и
+ экспериментальную сборку одновременно. Это может ощутимо сэкономить
+ общее время сборки.</para></note>
+
+ <para>По завершении сборки сравните результаты контрольной и
+ экспериментальной сборок примерно такой командой (предполагается, что
+ контрольной является ветка <literal>6</literal>, а
+ экспериментальной&nbsp;&mdash; <literal>6-exp</literal>):</para>
+
+ <screen>&prompt.user; <userinput>cd /var/portbuild/i386/6-exp/errors</userinput>
+&prompt.user; <userinput>find . -name \*.log\* | sort > /tmp/6-exp-errs</userinput>
+&prompt.user; <userinput>cd /var/portbuild/i386/6/errors</userinput>
+&prompt.user; <userinput>find . -name \*.log\* | sort > /tmp/6-errs</userinput></screen>
+
+ <note><para>Если с момента завершения одной из сборок прошло достаточно
+ много времени, журналы сборки могут быть автоматически архивированы
+ bzip2. В этом случае используйте
+ <literal>sort | sed 's,\.bz2,,g'</literal>.</para></note>
+
+ <screen>&prompt.user; <userinput>comm -3 /tmp/6-errs /tmp/6-exp-errs | less</userinput></screen>
+
+ <para>Результатом работы последней команды будет отчет, состоящий из двух
+ столбцов. В первой колонке будут перечислены порты, сборка которых не
+ удалась в контрольном, но не в экспериментальном случае; второй столбец
+ описывает противоположную ситуацию. Причины, по которым порт может
+ оказаться в первом списке, включают:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Порт был исправлен с момента последнего контрольного запуска,
+ или обновлен до более свежей версии, которая также не собирается
+ (порт с новой версией появится во втором столбце)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Сборка порта исправлена патчами экспериментальной версии</para>
+ </listitem>
+
+ <listitem>
+ <para>Порт не собирается экспериментальной сборкой из-за ошибок в
+ зависимых портах
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Во втором столбце порт может оказаться по следующим причинам:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Порт не собирается с экспериментальными изменениями [1]</para>
+ </listitem>
+
+ <listitem>
+ <para>Порт был обновлен с момента контрольной сборки и стал
+ несобираемым [2]
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Порт не собрался по причине временных ошибок (недоступный FTP
+ сайт, ошибка ввода-вывода на клиенте и т.п.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Перед коммитом экспериментальных обновлений необходимо изучить
+ содержимое обоих столбцов. Чтобы отличить ситуации [1] и [2], можно
+ пересобрать соответствующие пакеты в контрольной ветке:</para>
+
+ <screen>&prompt.user; <userinput>cd /var/portbuild/i386/6/ports</userinput></screen>
+
+ <note><para>Не забудьте обновить дерево портов до той же даты, что и дерево
+ экспериментальной сборки.</para></note>
+
+ <para>Для подготовки контрольной ветви используйте команду:</para>
+
+ <screen>&prompt.user; <userinput>/var/portbuild/scripts/dopackages.6 -noportscvs -nobuild -nocvs -nofinish</userinput></screen>
+
+ <para>Сборка должна производиться из каталога
+ <literal>packages/All</literal>. Изначально этот каталог должен быть
+ пуст, за исключением символьной ссылки Makefile. Если этой ссылки нет,
+ создайте ее:</para>
+
+ <screen>&prompt.user; <userinput>cd /var/portbuild/i386/6/packages/All</userinput>
+&prompt.user; <userinput>ln -sf ../../Makefile .</userinput>
+&prompt.user; <userinput>make -k -j&lt;#&gt; &lt;список пакетов для сборки&gt;</userinput></screen>
+
+ <note><para>&lt;#&gt; описывает уровень параллелизма сборки.
+ Обычно, это сумма весов клиентских машин, указанных в
+ <filename>/var/portbuild/i386/mlist</filename>, если у вас нет причин
+ проводить более тяжелую или, наоборот, облегченную сборку.</para></note>
+
+ <para>&lt;список пакетов для сборки&gt; представляет собой список имен
+ пакетов (включая их версии) в том виде, как они представлены в файле
+ <filename>INDEX</filename>. Суффикс <literal>PKGSUFFIX</literal>
+ (.tgz или .tbz) является необязательным.</para>
+
+ <para>Будут собраны только указанные пакеты, а также их зависимые порты.</para>
+
+ <para>Процесс сборки можно контролировать так же, как и стандартную сборку.
+ После того, как все ошибки исправлены, вы можете произвести коммит
+ комплекта исправлений. Является хорошим тоном отправить письмо
+ с темой <literal>HEADS UP</literal> в списки рассылки <ulink
+ url="mailto:ports@FreeBSD.org">ports@FreeBSD.org</ulink> и <ulink
+ url="mailto:ports-developers@FreeBSD.org">ports-developers@FreeBSD.org</ulink>
+ с информацией о внесенных изменениях. Краткая аннотация изменений также
+ должна быть добавлена в файл <filename>/usr/ports/CHANGES</filename>.
+ </para>
+ </sect1>
+</article>