8. The Files
Prev |  |

## 8. The Files

Here are the three files you need beside the config files already shown above.

This is the `stage_1.sh` script, which you should not need to modify.

#!/bin/sh # # stage_1.sh - FreeBSD From Scratch, Stage 1: System Installation. # Usage: ./stage_1.sh profile # will read profile # and write ./stage_1.log.profile # # Author: Jens Schweikhardt # $Id: stage_1.sh,v 1.7 2008-12-11 19:48:21 schweikh Exp $ # $FreeBSD: head/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_1.sh 38826 2012-05-17 19:12:14Z hrs $ PATH=/bin:/usr/bin:/sbin:/usr/sbin # Prerequisites: # # a) Successfully completed "make buildworld" and "make buildkernel" # b) Unused partitions (at least one for the root fs, probably more for # the new /usr and /var, to your liking.) # c) A customized profile file. if test $# -ne 1; then echo "usage: stage_1.sh profile" 1>&2 exit 1 fi # ---------------------------------------------------------------------------- # # Step 1: Create an empty directory tree below $DESTDIR. # ---------------------------------------------------------------------------- # step_one () { create_file_systems # Now create all the other directories. Mandatory. cd ${SRC}/etc; make distrib-dirs DESTDIR=${DESTDIR} TARGET=${TARGET} } # ---------------------------------------------------------------------------- # # Step 2: Fill the empty /etc directory tree and put a few files in /. # ---------------------------------------------------------------------------- # step_two () { copy_files # Delete mergemaster's temproot, if any. TEMPROOT=/var/tmp/temproot.stage1 if test -d ${TEMPROOT}; then chflags -R 0 ${TEMPROOT} rm -rf ${TEMPROOT} fi export MAKEDEVPATH="/bin:/sbin:/usr/bin" mergemaster -i -m ${SRC}/etc -t ${TEMPROOT} -D ${DESTDIR} cap_mkdb ${DESTDIR}/etc/login.conf pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd # Mergemaster does not create empty files, e.g. in /var/log. Do so now, # but do not clobber files that may have been copied with copy_files. cd ${TEMPROOT} find . -type f | sed 's,^\./,,' | while read f; do if test -r ${DESTDIR}/${f}; then echo "${DESTDIR}/${f} already exists; not copied" else echo "Creating empty ${DESTDIR}/${f}" cp -p ${f} ${DESTDIR}/${f} fi done chflags -R 0 ${TEMPROOT} rm -rf ${TEMPROOT} } # ---------------------------------------------------------------------------- # # Step 3: Install world. # ---------------------------------------------------------------------------- # step_three () { cd ${SRC} make installworld DESTDIR=${DESTDIR} TARGET=${TARGET} } # ---------------------------------------------------------------------------- # # Step 4: Install kernel and modules. # ---------------------------------------------------------------------------- # step_four () { cd ${SRC} # The loader.conf and device.hints are required by the installkernel target. # If you have not copied them in Step 2, cp them as shown in the next 2 lines. # cp sys/boot/forth/loader.conf ${DESTDIR}/boot/defaults # cp sys/${TARGET}/conf/GENERIC.hints ${DESTDIR}/boot/device.hints make installkernel DESTDIR=${DESTDIR} KERNCONF=${KERNCONF} TARGET=${TARGET} } # ---------------------------------------------------------------------------- # # Step 5: Install /etc/fstab and time zone info. # ---------------------------------------------------------------------------- # step_five () { create_etc_fstab # Setup time zone info; pretty much mandatory. cp ${DESTDIR}/usr/share/zoneinfo/${TIMEZONE} ${DESTDIR}/etc/localtime if test -r /etc/wall_cmos_clock; then cp -p /etc/wall_cmos_clock ${DESTDIR}/etc/wall_cmos_clock fi } # ---------------------------------------------------------------------------- # # Step 6: All remaining customization. # ---------------------------------------------------------------------------- # step_six () { all_remaining_customization } do_steps () { echo "PROFILE=${PROFILE}" echo "TARGET=${TARGET}" echo "DESTDIR=${DESTDIR}" echo "SRC=${SRC}" echo "KERNCONF=${KERNCONF}" echo "TIMEZONE=${TIMEZONE}" echo "TYPE=${TYPE}" echo "REVISION=${REVISION}" echo "BRANCH=${BRANCH}" echo "RELDATE=${RELDATE}" step_one step_two step_three step_four step_five step_six } # ---------------------------------------------------------------------------- # # The ball starts rolling here. # ---------------------------------------------------------------------------- # PROFILE="$1" set -x -e -u # Stop for any error or use of an undefined variable. . ${PROFILE} # Determine a few variables from the sources that were used to make the # world. The variables can be used to modify actions, e.g. depending on # the system's version. The __FreeBSD_version numbers # for RELDATE are documented in the Porter's Handbook, # doc/en_US.ISO8859-1/books/porters-handbook/freebsd-versions.html. # Scheme is: <major><two digit minor><0 if release branch, otherwise 1>xx # The result will be something like # # TYPE="FreeBSD" # REVISION="8.0" # BRANCH="RC" { "CURRENT", "STABLE", "RELEASE" } # RELDATE="800028" # eval $(awk '/^(TYPE|REVISION|BRANCH)=/' ${SRC}/sys/conf/newvers.sh) RELDATE=$(awk '/^[ \t]*#[ \t]*define[ \t][ \t]*__FreeBSD_version[ \t]/ { print $3 }' ${SRC}/sys/sys/param.h) echo "=> Logging to stage_1.${PROFILE}.log" do_steps 2>&1 | tee "stage_1.${PROFILE}.log" # vim: tabstop=2:expandtab:shiftwidth=2: # EOF $RCSfile: stage_1.sh,v $

Download `stage_1.sh`.

This is the `stage_2.sh` script. You may want to modify the variables at the beginning.

#!/bin/sh # # stage_2.sh - FreeBSD From Scratch, Stage 2: Ports Installation. # Usage: ./stage_2.sh [-hnp] configname # # Author: Jens Schweikhardt # $Id: stage_2.sh,v 1.5 2004-07-19 21:02:26 schweikh Exp $ # $FreeBSD: head/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_2.sh 38826 2012-05-17 19:12:14Z hrs $ DBDIR="/var/db/pkg" PORTS="/usr/ports" : ${PACKAGES:=${PORTS}/packages} LOGDIR="/home/root/setup/ports.log"; mkdir -p ${LOGDIR} PKG_PATH="/cdrom/packages/All:/dvd/packages/All" PKG= MYNAME="$(basename $0)" usage () { exec >&2 echo "usage: ${MYNAME} [-hnp] configname" echo "" echo " Options:" echo " -h Print this help text." echo " -n Dryrun: just show what would be done." echo " -p Install a precompiled package if one can be found." echo "" echo " The config file (stage_2.conf.configname) is a list of" echo " ports to install with one entry per line. Each line" echo " consists of two or three space separated fields:" echo " category, port, and optionally a build command." echo "" exit 1 } # Look for a package in these locations in sequence. # Returns as soon as the first is found. Result on stdout. # # ${PORTS}/${CATEGORY}/${NAME} # ${PACKAGES}/All # ${PACKAGES}/${CATEGORY} # ${PKG_PATH} # find_package () { echo "${PORTS}/${CATEGORY}/${NAME}:${PACKAGES}/All:${PACKAGES}/${CATEGORY}:${PKG_PATH}" | tr : '\n' | while read d; do test -d "${d}" || continue PKG=$(ls ${d}/${PKGNAME}.* 2>/dev/null) test $? -eq 0 && echo "${PKG}" && return done } # # Parse command line arguments. # args=`getopt hnp $*` if test $? != 0; then usage fi set -- $args DRYRUN= CHKPKG= for i; do case "$i" in -n) DRYRUN="yes"; shift;; -p) CHKPKG="yes"; shift;; --) shift; break;; *) usage;; esac done if test $# -eq 1; then DATAFILE="$1" else usage fi # # Loop over the ports list. # while read CATEGORY NAME CMD; do case "${CATEGORY}" in \#*) continue;; '') continue;; esac DIR="${PORTS}/${CATEGORY}/${NAME}" if ! test -d "${DIR}"; then echo "$DIR does not exist -- ignored" continue fi cd ${DIR} PKGNAME=`make -V PKGNAME` if test -n "${CHKPKG}"; then PKG=$(find_package) else PKG="" fi if test -d "${DBDIR}/${PKGNAME}"; then echo "${CATEGORY}/${NAME} already installed as ${PKGNAME}" continue fi LOG="${LOGDIR}/${CATEGORY}+${NAME}" echo "===> Installing ${CATEGORY}/${NAME}; logging to ${LOG}" test -n "${CMD}" || CMD="make install BATCH=yes < /dev/null" if test -n "${DRYRUN}"; then if test -n "${PKG}"; then echo pkg_add -v ${PKG} else echo "${CMD}" fi continue fi date "++++ Started %v %T +++" > ${LOG} STARTED=$(date +%s) ( if test -n "${PKG}"; then echo "Found package ${PKG}" pkg_add -v ${PKG} else echo "CMD: ${CMD}" make clean eval "${CMD}" make clean # Uncomment if diskspace is tight under ${PORTS}. fi ) 2>&1 | tee -a ${LOG} FINISHED=$(date +%s) DURATION=$(dc -e "${FINISHED} ${STARTED} - p") date "++++ Finished %v %T after ${DURATION} secs +++" >> ${LOG} done < stage_2.conf.${DATAFILE} # vim: tabstop=4: # EOF $RCSfile: stage_2.sh,v $

Download `stage_2.sh`.

This is my `stage_3.mk` to give you an idea how to automate all reconfiguration.

# stage_3.mk - FreeBSD From Scratch, Stage 3: Ports Post-Configuration. # Usage: make -f stage_3.mk all (configure everything) # or make -f stage_3.mk target (just configure target) # # Author: Jens Schweikhardt # # It is a good idea to make sure any target can be made more than # once without ill effect. # # $Id: stage_3.mk,v 1.5 2008-12-03 21:59:51 schweikh Exp $ # $FreeBSD: head/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_3.mk 38826 2012-05-17 19:12:14Z hrs $ .POSIX: message: @echo "Please use one of the following targets:" @echo "config_apache" @echo "config_cups" @echo "config_firefox" @echo "config_inn" @echo "config_javaplugin" @echo "config_openoffice" @echo "config_sudo" @echo "config_TeX" @echo "config_tin" @echo "config_wdm" @echo "config_uucp" @echo "all -- all of the above" all: \ config_apache \ config_cups \ config_firefox \ config_inn \ config_javaplugin \ config_openoffice \ config_sudo \ config_TeX \ config_tin \ config_wdm \ config_uucp APACHE = apache22 config_apache: # 1. Modify httpd.conf. perl -pi \ -e 's/^\s*ServerAdmin.*/ServerAdmin schweikh\@schweikhardt.net/;' \ -e 's/^#?ServerName .*/ServerName hal9000.schweikhardt.net:80/;' \ -e 's/^\s*Listen.*/Listen 127.0.0.1:80/;' \ -e 's/^\s*Deny from all/ Allow from 127.0.0.1/i;' \ -e 's,/usr/local/www/$(APACHE)/cgi-bin/,/home/opt/www/cgi-bin/,;' \ /usr/local/etc/$(APACHE)/httpd.conf cp w3c-validator.conf /usr/local/etc/$(APACHE)/Includes # 2. Restore symlinks to web pages. cd /usr/local/www/$(APACHE)/data && \ ln -fs /home/schweikh/prj/homepage schweikhardt.net && \ ln -fs /home/opt/www/test . # 3. Restore W3C Validator config. mkdir -p /etc/w3c cp /usr/local/www/validator/htdocs/config/validator.conf.sample \ /etc/w3c/validator.conf perl -pi \ -e 's/^Allow Private IPs.*/Allow Private IPs = yes/;' \ /etc/w3c/validator.conf # Test if the httpd.conf has changed. @if ! cmp -s /usr/local/etc/$(APACHE)/httpd.conf httpd.conf; then \ echo "ATTENTION: the httpd.conf has changed. Please examine if"; \ echo "the modifications are still correct. If so you can simply"; \ echo "cp /usr/local/etc/$(APACHE)/httpd.conf httpd.conf"; \ echo "to make this message go away. Here is the diff:"; \ diff -u /usr/local/etc/$(APACHE)/httpd.conf httpd.conf; \ fi if test -f /var/run/httpd.pid; then \ /usr/local/etc/rc.d/$(APACHE) stop; \ /usr/local/etc/rc.d/$(APACHE) start; \ else \ /usr/local/etc/rc.d/$(APACHE) start; \ fi # The original ppd file is from http://www.cups.org/ppd.php?L63+I0+T+Q2300 # = http://www.cups.org/ppd/hp/de/hpc2325s.ppd.gz config_cups: chmod 644 /usr/local/etc/cups/cupsd.conf cp printers.conf /usr/local/etc/cups/printers.conf cp LaserJet_2300d.ppd /usr/local/etc/cups/ppd/LaserJet_2300d.ppd config_firefox: # Make this group wheel writable to allow extensions being installed. chmod -R g+w /usr/local/lib/firefox3/chrome config_inn: pw usermod -n news -d /usr/local/news -s /bin/sh mkdir -p /share/news/spool/outgoing \ /share/news/spool/incoming \ /share/news/spool/articles \ /share/news/spool/overview \ /share/news/spool/tmp \ /share/news/db chown -R news:news /share/news # Give the news system its initial configuration. cd /home/root/setup && \ if test ! -f /share/news/db/active; then \ echo "installing /share/news/db/active"; \ install -C -o news -g news -m 664 active /share/news/db; \ fi; \ if test ! -f /share/news/db/newsgroups; then \ echo "installing /share/news/db/newsgroups"; \ install -C -o news -g news -m 664 newsgroups /share/news/db; \ fi # Configure storage method. cd /home/root/setup && \ printf "%s\n%s\n%s\n%s\n" \ "method tradspool {" \ " newsgroups: *" \ " class: 0" \ "}" \ >storage.conf && \ install -C -o news -g news -m 664 storage.conf /usr/local/news/etc # Configure newsfeeds. printf "%s\n%s\n" \ "ME:*::" \ "shuttle/news2.shuttle.de:!junk,!control:B32768/512,Tf,Wfb:" \ >/usr/local/news/etc/newsfeeds # Configure inn.conf. perl -pi \ -e 's/^#*\s*(organization:\s*).*/$$1"An Open Pod Bay Door"/;' \ -e 's/^#*\s*(pathhost:\s*).*/$$1hal9000.schweikhardt.net/;' \ -e 's/^#*\s*(server:).*/$$1 localhost/;' \ -e 's/^#*\s*(domain:).*/$$1 schweikhardt.net/;' \ -e 's/^#*\s*(fromhost:).*/$$1 schweikhardt.net/;' \ -e 's,^#*\s*(moderatormailer:).*,$$1 \%s\@moderators.isc.org,;' \ -e 's,^#*\s*(pathdb:\s*).*,$$1/share/news/db,;' \ -e 's,/usr/local/news/spool,/share/news/spool,;' \ /usr/local/news/etc/inn.conf # Create empty history, if none there. # See post-install in /usr/ports/news/inn-stable/Makefile. set -e; cd /share/news/db; \ if test ! -f history; then \ touch history; \ chmod 644 history; \ chown news:news history; \ su -fm news -c "/usr/local/news/bin/makedbz -i"; \ for s in dir hash index; do \ mv history.n.$${s} history.$${s}; \ done; \ fi # Configure send-uucp. echo shuttle:shuttle >/usr/local/news/etc/send-uucp.cf # Satisfy inncheck: set -e; cd /usr/local/news/etc; \ chown news:news *; \ chmod 640 control.ctl expire.ctl nntpsend.ctl readers.conf /usr/local/news/bin/inncheck # Test if the inn.conf has changed. @if ! cmp -s /usr/local/news/etc/inn.conf inn.conf; then \ echo "ATTENTION: the inn.conf has changed. Please examine if"; \ echo "the modifications are still correct. If so you can simply"; \ echo "cp /usr/local/news/etc/inn.conf inn.conf"; \ echo "to make this message go away. Here is the diff:"; \ diff -u /usr/local/news/etc/inn.conf inn.conf; \ fi if ! test -f /usr/local/news/run/innd.pid; then \ /usr/local/etc/rc.d/innd start; \ fi config_javaplugin: cd /usr/local/lib/firefox3/plugins && \ ln -fs /usr/local/jdk1.6.0/jre/plugin/$$(uname -m)/ns7/libjavaplugin_oji.so config_openoffice: # Copy some truetype files so ooo can use them. find /usr/local/openoffice.org* -type d -name truetype \ -exec echo cp *.ttf {} \; -exec cp *.ttf {} \; config_sudo: if ! grep -q schweikh /usr/local/etc/sudoers; then \ echo 'schweikh ALL = (ALL) NOPASSWD: ALL' >> /usr/local/etc/sudoers; \ fi chmod 440 /usr/local/etc/sudoers config_TeX: # textproc/docproj advises: to typeset the FreeBSD Handbook with JadeTeX, # change the following settings to the listed values: perl -pi \ -e 's/^% original texmf.cnf/% texmf.cnf/;' \ -e 's/^(hash_extra\s*=\s*).*/$${1}60000/;' \ -e 's/^(pool_size\s*=\s*).*/$${1}1000000/;' \ -e 's/^(max_strings\s*=\s*).*/$${1}70000/;' \ -e 's/^(save_size\s*=\s*).*/$${1}10000/;' \ /usr/local/share/texmf/web2c/texmf.cnf # Test if the texmf.cnf has changed. @if ! cmp -s /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf; then \ echo "ATTENTION: the texmf.cnf has changed. Please examine if"; \ echo "the modifications are still correct. If so you can simply"; \ echo "cp /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf"; \ echo "to make this message go away. Here is the diff:"; \ diff -u /usr/local/share/texmf/web2c/texmf.cnf texmf.cnf; \ fi config_tin: # Point tin to our files. printf "%s\n%s\n%s\n" \ "activefile=/share/news/db/active" \ "newsgroupsfile=/share/news/db/newsgroups" \ "spooldir=/share/news/spool/articles" \ >/usr/local/etc/tin.defaults config_wdm: cp daemon1-JS-1600x1200.jpg FreeBSD_small.png \ /usr/local/lib/X11/wdm/pixmaps perl -pi \ -e 's,^(DisplayManager\*wdmBg:).*,\1 pixmap:/usr/local/lib/X11/wdm/pixmaps/daemon1-JS-1600x1200.jpg,;' \ -e 's,^(DisplayManager\*wdmLogo:).*,\1 /usr/local/lib/X11/wdm/pixmaps/FreeBSD_small.png,;' \ -e 's,^(DisplayManager\*wdmWm:).*,\1 ctwm:icewm:xfce4:tvtwm,;' \ /usr/local/lib/X11/wdm/wdm-config @if ! cmp -s /usr/local/lib/X11/wdm/wdm-config wdm-config; then \ echo "ATTENTION: the wdm-config has changed. Please examine if"; \ echo "the modifications are still correct. If so you can simply"; \ echo "cp /usr/local/lib/X11/wdm/wdm-config wdm-config"; \ echo "to make this message go away. Here is the diff:"; \ diff -u /usr/local/lib/X11/wdm/wdm-config wdm-config; \ fi config_uucp: cd /etc/mail && make install SENDMAIL_MC=/etc/mail/hal9000.mc # Make the uucp user's shell the correct uucico, so su(1) works. chpass -s /usr/local/libexec/uucp/uucico uucp # UUCP expects to find /usr/bin/rnews. cd /usr/bin && ln -fs ../local/news/bin/rnews . # Actual UUCP configuration. echo nodename js2015 > /usr/local/etc/uucp/config echo shuttle js2015 `cat uucp` > /usr/local/etc/uucp/call printf 'port tcp\ntype tcp\n' > /usr/local/etc/uucp/port printf "%s\n" \ "call-login *" \ "call-password *" \ "time any" \ "system shuttle" \ "address mail.s.shuttle.de" \ "commands rmail rnews" \ "port tcp" \ >/usr/local/etc/uucp/sys cd /usr/local/etc/uucp && chown uucp:uucp * && chmod o-rwx * # Trigger uucico after booting. mkdir -p /usr/local/etc/rc.d cp uucp.sh /usr/local/etc/rc.d # Rebuild the aliases.db. cp aliases /etc/mail/aliases newaliases # vim: tabstop=4: # EOF $RCSfile: stage_3.mk,v $

Download `stage_3.mk`.

Prev |  |
7. Limitations | Home |

This, and other documents, can be downloaded from http://ftp.FreeBSD.org/pub/FreeBSD/doc/

For questions about FreeBSD, read the documentation before contacting <questions@FreeBSD.org>.
For questions about this documentation, e-mail <doc@FreeBSD.org>.