В первом варианте этой статьи на первом шаге использовался единственный скрипт, в котором вся настройка выполнялась его редактированием. После того, как пользователи высказали свои замечания, я решил разделить код и данные на уровне скриптов. Это позволяет создавать разные наборы конфигурационных данных для установки различных систем без внесения изменений в скрипты с кодом.
Скрипт с кодом для первого этапа называется stage_1.sh, и он запускается с единственным аргументом, например
будет считывать свою конфигурацию из файла stage_1.conf.default и записывать протокол в файл stage_1.log.default.
Далее приводится мой файл stage_1.conf.default. Вам необходимо подправить его в различных местах для того, чтобы он соответствовал вашим представлениям об ''идеальной системе''. Я попытался подробно прокомментировать те места, которые вы должны исправлять. Конфигурационный скрипт должен предоставлять четыре функции для оболочки, create_file_systems, create_etc_fstab, copy_files и all_remaining_customization (в случае, если это имеет смысл: именно в такой последовательности они будут вызываться из stage_1.sh).
Следует внимательно отнестись к следующим моментам:
Разбиение разделов.
Я не являюсь сторонником наличия одного большого раздела для всей системы. Мои системы, как правило, имеют по крайней мере по одному разделу для /, /usr и /var с каталогом /tmp, образованным символической ссылкой в /var/tmp. Вдобавок я использую файловые системы в режиме совместного доступа к /home (домашние каталоги пользователей), /home/ncvs (копия CVS-хранилища FreeBSD), /usr/ports (дерево портов), /src (различные выгруженные из хранилища деревья исходных текстов) и /share (остальные совместно используемые данные, резервные копии которых не нужны, например, спул сервера телеконференций).
Новые возможности.
Это то, что вы хотите иметь сразу после загрузки новой системы и даже до запуска второго этапа. Причина отказа от создания и перехода в chroot-окружение новой системы во время первого этапа и простой установки всех моих любимых портов заключается в том, что теоретически и практически существуют проблемы начальной загрузки и целостности: на первом этапе работает ваше старое ядро, однако в chroot-окружении содержатся новые двоичные файлы программ и файлы объявлений. Если новые программы используют новый системный вызов, то они будут завершаться SIGSYS, Плохой системный вызов, так как старое ядро не поддерживает этот новый вызов. Я наблюдал и другие проблемы при попытке построения порта lang/perl5.8.
Перед тем, как запускать stage_1.sh, убедитесь, что вы выполнили обычные действия при подготовке к make installworld installkernel, типа:
отредактировали конфигурационный файл вашего ядра
успешно выполнили make buildworld
успешно выполнили make buildkernel KERNCONF=whatever
Когда вы запускаете stage_1.sh первый раз, и конфигурационный файл, скопированный с работающей системы в новую, является устаревшим по сравнению с тем, что находится в каталоге /usr/src, mergemaster будет запрашивать вас на отработку этой ситуации. Я рекомендую переносить изменения. Если вам надоело отвечать на запросы, вы можете просто единожды обновить файлы в вашей работающей системе (Если только это вам подходит. Скорее всего, вам не нужно это делать, если одна из ваших систем работает под управлением -STABLE, а другая с -CURRENT. Изменения могут оказаться несовместимыми). Последующие вызовы утилиты mergemaster обнаружат, что RCS-идентификаторы версий соответствуют тем, что находятся в /usr/src, и пропустят файл.
Скрипт stage_1.sh остановится на первой команде, которая завершится неудачно (возвратит ненулевой код завершения) из-за set -e, так что вы не пропустите ошибки. Он также остановится, если вы используете неустановленную переменную окружения, как правило, из-за опечатки. Вы должны исправить все ошибки в вашей версии stage_1.conf.default перед тем, как продолжить работу.
В скрипте stage_1.sh мы вызываем mergemaster. Даже если никаким файлам объединение не требуется, он выведет сообщение и в конце сделает запрос
*** Comparison complete *** Saving mtree database for future upgrades Do you wish to delete what is left of /var/tmp/temproot.stage1? [no] no
Пожалуйста, ответьте no или просто нажмите Enter. Причина в том, что mergemaster оставит несколько файлов нулевой длины в каталоге /var/tmp/temproot.stage1, которые позже будут скопированы в новую систему (в случае, если их там еще нет).
После этого mergemaster перечислит установленные им файлы и уточнит, стоит ли генерировать новый login.conf:
*** You chose the automatic install option for files that did not
exist on your system. The following were installed for you:
/newroot/etc/defaults/rc.conf
...
/newroot/COPYRIGHT
*** You installed a new aliases file into /newroot/etc/mail, but
the newaliases command is limited to the directories configured
in sendmail.cf. Make sure to create your aliases database by
hand when your sendmail configuration is done.
*** You installed a login.conf file, so make sure that you run
'/usr/bin/cap_mkdb /newroot/etc/login.conf'
to rebuild your login.conf database
Would you like to run it now? y or n [n]
Ответ не имеет значения, так как stage_1.sh будет запускать cap_mkdb(1) в любом случае.
Вот авторский файл stage_1.conf.default, который вы должны потом существенно модифицировать. В комментариях даётся достаточно информации о том, что необходимо изменить.
# This file: stage_1.conf.default, sourced by stage_1.sh.
#
# $Id: stage_1.conf.default,v 1.5 2011-05-14 20:44:31 hrs Exp $
# $FreeBSD: head/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_1.conf.default 38826 2012-05-17 19:12:14Z hrs $
# Root mount point where you create the new system. Because it is only
# used as a mount point, no space will be used on that file system as all
# files are of course written to the mounted file system(s).
DESTDIR="/newroot"
# Where your src tree is.
SRC="/usr/src"
# Where your obj is.
MAKEOBJDIRPREFIX="/usr/obj"
# Your kernel config name as from make buildkernel KERNCONF=...
KERNCONF="HAL9000"
# Your target architecture as used for make buildworld TARGET=...
# If you did not specify a TARGET when building world, it defaulted
# to the build architecture (run "uname -m" to find out if you are unsure).
TARGET="i386" # amd64 arm i386 ia64 mips pc98 powerpc sparc64
# Available time zones are those under /usr/share/zoneinfo.
TIMEZONE="Europe/Berlin"
#
# The create_file_systems function must create the mountpoints under
# DESTDIR, create the file systems, and then mount them under DESTDIR.
#
create_file_systems () {
# The new root file system. Mandatory.
# Change DEVICE names.
DEVICE=/dev/daXYZs1a
mkdir -m 755 -p ${DESTDIR}
chown root:wheel ${DESTDIR}
newfs -U ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}
# Additional file systems and initial mount points. Optional.
DEVICE=/dev/daXYZs1e
mkdir -m 755 -p ${DESTDIR}/var
chown root:wheel ${DESTDIR}/var
newfs -U ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}/var
DEVICE=/dev/daXYZs1e
mkdir -m 755 -p ${DESTDIR}/usr
chown root:wheel ${DESTDIR}/usr
newfs -U ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}/usr
}
#
# The create_etc_fstab function must create an fstab matching the
# file systems created in create_file_systems.
#
create_etc_fstab () {
cat <<EOF >${DESTDIR}/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/da0s1b none swap sw 0 0
/dev/da1s1b none swap sw 0 0
/dev/da2s2b none swap sw 0 0
/dev/da3s2b none swap sw 0 0
/dev/da0s1a / ufs rw,noatime 1 1
/dev/da0s1e /var ufs rw,noatime 1 1
/dev/da2s1e /usr ufs rw,noatime 1 1
/dev/vinum/Share /share ufs rw,noatime 0 2
/dev/vinum/home /home ufs rw,noatime 0 2
/dev/vinum/ncvs /home/ncvs ufs rw,noatime 0 2
/dev/vinum/ports /usr/ports ufs rw,noatime 0 2
/dev/ad1s1a /flash ufs rw,noatime 0 0
/dev/ad0s1 /2k ntfs ro,noauto 0 0
/dev/ad0s6 /linux ext2fs ro,noauto 0 0
#
/dev/cd0 /cdrom cd9660 ro,noauto 0 0
/dev/cd1 /dvd cd9660 ro,noauto 0 0
proc /proc procfs rw 0 0
linproc /compat/linux/proc linprocfs rw 0 0
EOF
chmod 644 ${DESTDIR}/etc/fstab
chown root:wheel ${DESTDIR}/etc/fstab
}
#
# The copy_files function is used to copy files before mergemaster is run.
#
copy_files () {
# Add or remove from this list at your discretion. Mostly mandatory.
for f in \
/.profile \
/etc/devd.conf \
/etc/devd.rules \
/etc/exports \
/etc/group \
/etc/hosts \
/etc/inetd.conf \
/etc/ipfw.conf \
/etc/make.conf \
/etc/master.passwd \
/etc/nsswitch.conf \
/etc/ntp.conf \
/etc/printcap \
/etc/profile \
/etc/rc.conf \
/etc/resolv.conf \
/etc/src.conf \
/etc/sysctl.conf \
/etc/ttys \
/etc/mail/aliases \
/etc/mail/aliases.db \
/etc/mail/hal9000.mc \
/etc/mail/service.switch \
/etc/ssh/*key* \
/etc/ssh/*_config \
/etc/X11/xorg.conf \
/var/cron/tabs/* \
/root/.profile \
/boot/*.bmp \
/boot/loader.conf \
/boot/device.hints ; do
cp -p ${f} ${DESTDIR}${f}
done
}
#
# Everything else you want to tune in the new system.
# NOTE: Do not install too many binaries here. With the old system running and
# the new binaries and headers installed you are likely to run into bootstrap
# problems. Ports should be compiled after you have booted in the new system.
#
all_remaining_customization () {
# Without the compat symlink the linux_base files end up on the root fs:
cd ${DESTDIR}
mkdir -m 755 usr/compat; chown root:wheel usr/compat; ln -s usr/compat
mkdir -m 755 usr/compat/linux; chown root:wheel usr/compat/linux
mkdir -m 555 usr/compat/linux/proc; chown root:wheel usr/compat/linux/proc
mkdir -m 755 boot/grub; chown root:wheel boot/grub
mkdir -m 755 linux 2k; chown root:wheel linux 2k
mkdir -m 755 src; chown root:wheel src
mkdir -m 755 share; chown root:wheel share
mkdir -m 755 dvd cdrom flash; chown root:wheel dvd cdrom flash
mkdir -m 755 home; chown root:wheel home
mkdir -m 755 usr/ports; chown root:wheel usr/ports
# Create the ntp and slip log files.
touch ${DESTDIR}/var/log/ntp ${DESTDIR}/var/log/slip.log
# Make /usr/src point to the right directory. Optional.
# Note: some ports need part of the src tree, e.g. emulators/kqemu,
# sysutils/lsof, sysutils/fusefs, ...
cd ${DESTDIR}/usr
if test "${SRC}" != /usr/src; then
rmdir src; ln -s ${SRC}
fi
if test "${MAKEOBJDIRPREFIX}" != /usr/obj; then
rmdir obj; ln -s ${MAKEOBJDIRPREFIX}
fi
# My personal preference is to symlink tmp -> var/tmp. Optional.
cd ${DESTDIR}; rmdir tmp; ln -s var/tmp
# Make spooldirs for the printers in my /etc/printcap.
cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
touch ${DESTDIR}/var/log/lpd-errs
# If you do not have /home on a shared partition, you may want to copy it:
# mkdir -p ${DESTDIR}/home
# cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)
}
# vim: tabstop=2:expandtab:shiftwidth=2:syntax=sh:
# EOF $RCSfile: stage_1.conf.default,v $
Скачайте stage_1.conf.default.
При работе этот скрипт устанавливает систему, которая при загрузке предоставит:
Унаследованные списки пользователей и групп.
Подключение к Internet по Ethernet с использованием межсетевого экрана.
Правильный временной пояс и NTP.
Другие более мелкие конфигурационные параметры, например, /etc/ttys и inetd.
Другие функции готовы к настройке, но не будут работать, пока не будет завершён второй этап. Например, мы скопировали файлы для настройки печати и X11. Однако для печати, скорее всего, необходимы приложения, отсутствующие в базовом комплекте системы, например, такие как PostScript®. X11 не будет работать, пока мы не откомпилируем сервер, библиотеки и программы.
Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.