<!DOCTYPE debiandoc PUBLIC "-//DebianDoc//DTD DebianDoc//EN" [
  <!-- include version information so we don't have to hard code it
       within the document -->
  <!-- common, language independant entities -->
  <!entity % commondata SYSTEM "common.ent" > %commondata;
  <!-- CVS revision of this document -->
  <!entity cvs-rev "$Id$">

<!entity version "1.2">
<!entity date    "XXX september 2001">

]>

<debiandoc>
<book>
      <title>FAI Guide (Fully Automatic Installation)

      <author>Thomas Lange <email>lange@informatik.uni-koeln.de</email>
      <version>Version &version for FAI version 2.2, &date

<abstract>
This manual describes the fully automatic installation package for
&dgl;. This includes the installation of the package, the planing and
creating of the configuration and how to deal with errors.
 
<copyright>
<copyrightsummary>
Copyright &copy; 2000-2001 Thomas Lange
</copyrightsummary>
	<p>
This manual is free software; you may redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
	<p>
This is distributed in the hope that it will be useful, but
<em>without any warranty</em>; without even the implied warranty of
merchantability or fitness for a particular purpose.  See the GNU
General Public License for more details.
	<p>
A copy of the GNU General Public License is available as &file-GPL; in
the &dgl distribution or on the World Wide Web at <url id="&url-gpl;"
	name="the GNU website">.  You can also obtain it by 
writing to the &fsf-addr;.

<toc detail="sect2">

<chapt id="intro">Introduction<p>
The homepage of FAI is
<httpsite>http://www.informatik.uni-koeln.de</httpsite><httppath>/fai</httppath>.

There you will find any information about FAI, for e.g. the mailing
list archive. The FAI package is available as a Debian package from
&faidownload;. It's an official Debian package and is available from
all Debian mirrors. Send any bug or comment to
<email>fai@informatik.uni-koeln.de</email>. You can also use the
Debian bug tracking system (BTS)
<httpsite>http://www.debian.org</httpsite><httppath>/Bugs</httppath>
for reporting errors.
<p>
You can access the CVS repository from a bourne shell using the
following commands. The login password is empty, so only press return. 
<example>
> CVSROOT=:pserver:anonymous@cvs.debian.org:/cvs/debian-boot
> cvs login
> cvs co -P fai-kernels
> cvs co -P fai
</example>

You can also use the web interface for the CVS repository at:
<httpsite>http://cvs.debian.org/</httpsite><httppath>fai/</httppath>
(and <package>fai-kernels</package>).
<p>
Now read this manual, then enjoy the fully automatic installation and
your saved time.


<sect id="motivation">Motivation<p> Have you ever performed identical
installations of an operating system several times?  Would you like to
be able to install a Linux cluster with dozens of nodes single
handedly?

<p>
Repeating the same task time and again is boring -- and will surely
lead to mistakes. Also a whole lot of time could be saved, if the
installation were done automatically.  An installation process with
manual interaction does not scale.  But clusters have the habit of
growing over the years.  Think long-term rather than plan only just a
few months into the future.  

<p>
In 1999, I had to organize an installation of a Linux cluster with one
server and 16 clients.  Since I had much experience doing automatic
installation of Solaris operating system on SUN SPARC hardware, the
idea to build an automatic installation for Debian was born. Solaris
has an automatic installation feature called JumpStart<footnote> <p>
Solaris 8 Advanced Installation Guide at
<httpsite>docs.sun.com</httpsite></p> </footnote>. In conjunction
with the auto-install scripts from Casper Dik<footnote><p><url
id="ftp://ftp.wins.uva.nl:/pub/solaris/auto-install/"></p> </footnote>,
I could save a lot of time not only for every new SUN computer, but
also for reinstallation of existing workstations.  For example, I had
to build a temporary LAN with four SUN workstations for a conference,
lasting only a few days. I took these workstations out of our normal
research network and set up a new installation for the conference.
When it was over, I simply integrated the workstation back into the
research network, rebooted just once, and after half an hour,
everything was up and running as before. The configuration of all
workstations was exactly the same as before the conference, because
everything was performed by the same installation process. I also use
the automatic installation for reinstalling a workstation after a
damaged hard disk had been replaced. It took two weeks until I
received the new hard disk but only a few minutes after the new disk
was installed, the workstation was running as before. And this is why
I chose to adapt this technique to a PC cluster running Linux.



<sect id="overview">Overview and concepts<p>
<p>
FAI is a non interactive system to install a &dgl operating system on
a single computer or a whole cluster. You can take one or more virgin
PC's, turn on the power and after a few minutes Linux is installed,
configured and running on the whole cluster, without any interaction
necessary. Thus, it's a scalable method for installing and updating a
cluster unattended with little effort involved. FAI uses the &dgl;
distribution and a collection of shell and perl scripts for the
installation process. Changes to the configuration files of the
operating system can be made by cfengine, shell, perl and expect scripts.

<p>
FAI's target group are system administrators how have to install
Debian onto one or even hundreds of computers. Because it's a general
purpose installation tool, it can be used for installing a beowulf
cluster, a rendering farm or a linux laboratory or a classroom. Also
large-scale linux networks with different hardware or different installation
requirements are easy to establish using FAI. But don't forget to plan
your installation. <ref id="plan"> has some useful hints for this topic.
<p>
First, some terms used in this manual are described.

<taglist>
	  <tag> install server : <item> <p>The host, where the package FAI
	  is installed. It provides several services for all install
	  clients. In the examples of this manual this host is called
	  <tt>kueppers</tt>.

	  <tag>install client : <item> A host, which will be installed using
	  FAI and a configuration from the install server. Also called
	  client for short. In this manual the example hosts are
	  called <tt>bigfoot, ant01, ant02,...</tt></p> </item>
	  <tag> configuration : <item> The details, how the installation
	  of the clients should be performed. This includes information about:
<list>
		<item> <p>Hard disk layout</p> </item>
		<item> <p>Local filesystems</p> </item>
		<item> <p>Software packages</p>	</item>
		<item> <p>Keyboard layout, time zone, NIS,
		X11 configuration, remote filesystems, user accounts,
		printers ...</p>	</item>
</list>
	  <tag> nfsroot : <item> A filesystem located on the install
	  server. It's the complete filesystem for the install
	  clients during the installation process. All clients share the
	  same nfsroot, which they mount read only.</item>
</taglist>

<sect id="work">How does FAI work ?<p> 

The install client which will be installed using FAI, is
booted from floppy disk or via network card. It gets an IP address and
boots a linux kernel which mounts its root filesystem via NFS from the install
server. After the operating system is running, the FAI startup script
performs the automatic installation which doesn't need any
interaction. First, the hard disks will be partitioned, filesystems are
created and then software packages are installed. After that, the new
installed operating system is configured to your local needs using
some scripts. Finally the new operating system will be booted from the local
disk.
<p>
The details, of how to install the computer (the configuration), are
stored in the configuration space on the install server. Configuration
files are shared among groups of computers if they are similar using the
class concept. So you need not to create a configuration for every new
host. Hence, FAI is a scalable method to install a big cluster with a
great number of nodes.

<p>
FAI can also be used as an network rescue system. You can boot your
computer, but it will not perform an installation. Instead it will run a
fully functional &dgl without using the local hard disks. Then you can
do a remote login and backup or restore a disk partition, check a filesystem,
inspect the hardware or do any other task.

<sect id="features">Features<p> 
<list>
	    <item> <p> </p> </item>

	    <item> <p>A fully automated installation can be perfomed</p> </item>
	    <item> <p>Very quick unattended installation</p> </item>
	    <item> <p>Hosts can boot from floppy or from network card </p> </item>
	    <item> <p>BOOTP and DHCP protocol are supported</p> </item>
	    <item> <p>No initial ramdisk is needed, 8MB RAM suffice</p> </item>
	    <item> <p>Runs even on a 386 CPU </p> </item>
	    <item> <p>The installation kernel can use modules</p> </item>
	    <item> <p>Remote login via ssh during installation process
	    possible</p> </item>
	    <item> <p>Two additional virtual terminals available
	    during installation</p> </item>
	    <item> <p>All similar configuration are shared among
	    all install clients</p> </item>
	    <item> <p>Log files are saved on to the installation server</p> </item>
	    <item> <p>Shell, perl, expect and cfengine scripts are
	    supported for the configuration setup</p> </item>
	    <item> <p>Access to a Debian mirror via NFS, FTP or HTTP</p> </item>
	    <item> <p>Easy creation of the common boot floppy</p> </item>
	    <item> <p>Keyboard layout selectable</p> </item>
	    <item> <p>Can be used as a rescue system</p> </item>
	    <item> <p>Tested on SUN SPARC hardware</p> </item>
	    <item> <p>Diskless client support</p> </item>
	    <item> <p>Easily add your own functions via hooks</p> </item>
	    <item> <p>Lilo and grub support</p> </item>
</list>

<chapt id="inst">Installing FAI
<sect id="requirements">Requirements<p> 

Following items are required for an installation via FAI.

<taglist>
	  <tag>A computer: </tag><item> The computer must have a
	  network interface card and a local harddisk. No floppy disk,
	  CD-ROM, keyboard or graphic card is needed.</item>
	  <tag>BOOTP or DHCP server: </tag><item> <p> 
The clients need one of these daemons to obtain boot information.<footnote>
		  <p>It's also possible without a server, if all
information is put on the boot disk.</p>
		</footnote>
 </p> </item>

	  <tag>TFTP server:<item> The TFTP daemon is used for
	  transfering the kernel to the clients. Only needed when
	  booting from network card with a boot PROM.</item>
	  <tag>Client root:<item> A mountable directory which contains the whole
	  filesystem for the install clients during installation. It will
	  be created during setup of the FAI package and is also
	  called <strong>nfsroot</strong>.</item>
	  <tag>Debian mirror:<item> Access to a Debian
	  mirror is needed. A local mirror of all Debian
	  packages is recommended if you install several computers.</item>
	  <tag>Install kernel: <item> A kernel image that supports the
	  network card and mounts its root filesystem via NFS. </item>
	  <tag>Configuration space:<item> A mountable directory which contains the configuration data. </item>
	</taglist>
<p>

The TFTP daemon and a NFS server will be enabled automatically when
installing the FAI package. Different install kernel images for BOOTP
and DHCP are available within the package
<package>fai-kernels</package>. All clients must have a network card,
which is recognized by the install kernel.
<p>


<sect id="debian-mirror">How to create a local Debian mirror<p> 

The script <prgn>mkdebmirror</prgn> <footnote> Available in
 <p><file>/usr/share/doc/fai/utils/</file>.</p> </footnote> can be
 used for creating your own local Debian mirror. This script uses the
 script <prgn>debmirror</prgn><footnote> Available at
 <httpsite>http://cvs.kitenet.net/</httpsite><httppath>joey-cvs/bin/debmirror</httppath>
 or at the FAI homepage.</footnote> and <manref name="rsync"
 section="1">.

A partitial Debian mirror only for i386 architecture for Debian 2.2r3
(aka potato) without the source packages needs about 2.4 GB of disk
space.


<sect id=faisetup> Setting up FAI
<p>

Before installing FAI, you have to install the package <package>fai-kernels</package>,
which contains the install kernels for FAI. <footnote> <p><tt># apt-get
install fai</tt> should also work.</p></footnote>

<example>
kueppers[~]# dpkg -i fai-kernels_&faikernelver;_i386.deb 
Selecting previously deselected package fai-kernels.
(Reading database ... 40562 files and directories currently installed.)
Unpacking fai-kernels (from .../lange/fai-kernels_&faikernelver;_i386.deb) ...
Setting up fai-kernels (&faikernelver;) ...
</example>

Get the newest version of FAI and install it using the
<prgn>dpkg</prgn> command:

<example>
kueppers[~]# dpkg -i fai_&faiver;_all.deb
Selecting previously deselected package fai.
(Reading database ... 39564 files and directories currently installed.)
Unpacking fai (from fai_&faiver;_all.deb) ...
Setting up fai (&faiver;) ...
To set up FAI edit /etc/fai.conf and call fai-setup
</example>
<p>

All definitions for the FAI package (not the configuration data) are defined in
&fc;. Since FAI doesn't use <prgn>debconf</prgn>
yet, edit this file before calling <prgn>fai-setup</prgn>.
These are important variables in &fc;:

<taglist>
	    <tag><var>FAI_DEBOOTSTRAP</var></tag>
	    <item>
	  <p>For building the nfsroot there's a new command called
	  <manref name="debootstrap" section="8">, which replaces the
	  use of the <var>FAI_BASETGZ</var> variable. It needs
	  the location of a Debian mirror and the distribution
	  (potato,woody,stable,unstable) for which the basic Debian
	  system should be build.
	    </p> </item>

	    <tag><var>FAI_BASETGZ</var></tag>
	    <item>
	      <p>The location, where the the base file is fetched
	      from. For building the nfsroot, the Debian base system
	      is needed. It's a big tar file (&basetgzsize for
	      &basetgz), which is a minimal collection of all required
	      packages for Debian. If a file &basetgz is already
	      available in <file>/tmp</file> this file will be used
	      instead and no file will be fetched from the defined
	      location. Fetching via ftp or http could take much time,
	      if you do not have a fast connection to your Debian
	      mirror. You can find the current version of this archive
	      in the directory
	      <tt>debian/dists/stable/main/disks-i386/current/</tt> of
	      a Debian mirror.</p>
	    </item>

	    <tag><var>FAI_SOURCES_LIST</var></tag> <item> <p>This
	    multi line string is the definition for
	    <file>sources.list</file> (used by <manref name="apt-get"
	    section="8">), which defines the location and access
	    method of the Debian mirror. If this variable is undefined,
	    the definitions of <file>/etc/apt/sources.list</file> will
	    be used. For more information on the
	    file format see <manref name="sources.list" section="5">.
	    </p> </item>

	    <tag><var>FAI_DEBMIRROR</var></tag>
	    <item>
	      <p> If you have NFS access to your local Debian mirror,
	      specify the remote filesystem. It will be mounted to
	      <var>$MNTPOINT</var> (defined in
	      &fc;). It's not needed if you use acces via FTP
	      or HTTP.</p> </item>

	    <tag><var>KERNELPACKAGE</var></tag>
	    <item>
	  <p> You must specify the software package - build with <manref
	      name="make-kpkg" section="8"> - which includes
	      the default kernel for booting the install clients. The
	      Debian package <package>fai-kernels</package> contains the
	      default install kernels with BOOTP and DHCP support. Do
	      not use the kernel with BOOTP support when you have a
	      DHCP server running in your network and vice versa. This
	      could lead to missing information.</p></item>
	<tag> <var>NFSROOT_PACKAGES</var></tag>
	    <item>
	  <p> Contains a list of additional software package, that
	  will be added to nfsroot.</p></item>
	  </taglist>
<p>

The variables <var>FAI_SOURCES_LIST</var> and <var>FAI_DEBMIRROR</var>
are used by the install server and also by the clients. If your
install server has multiple network card and different host names for
each card (as for a beowulf server), use the install
server name which is known by the install clients.<p>

FAI uses <manref name="apt-get" section="8"> to create the nfsroot
filesystem in <file>/usr/lib/fai/nfsroot</file>, which needs about
&nfsrootsize of free disk space. Before setting up FAI, you should get
the program <prgn>imggen</prgn>,<footnote>Available at the download
page <httpsite>http://www.ltsp.org</httpsite> or from the FAI download
page &faidownload;.</footnote> if you like to boot from a 3Com network
card. This executable converts netboot images created by <manref
name="mknbi-linux" section="8">, so they can be booted by network
cards from 3Com. Put that executable in your path
(e.g. <file>/usr/local/bin</file>). After editing &fc; call
<prgn>fai-setup</prgn>.

<example>
kueppers[~]# fai-setup 
Adding system user fai...
Stopping Name Service Cache Daemon: nscd.
Adding new user fai (100) with group nogroup.
Starting Name Service Cache Daemon: nscd.
Creating home directory /home/fai.
/home/fai/.rhosts created.
User account fai created.
Creating FAI nfsroot can take a long time and will
need more than 100MB disk space in /usr/lib/fai/nfsroot.
Unpacking /tmp/base2_2.tgz
Upgrading /usr/lib/fai/nfsroot
Adding additional packages to /usr/lib/fai/nfsroot:
perl-5.005 dhcp-client file rdate cfengine bootpc wget rsh-client less dump ext2resize raidtools2 strace expect5.31 hdparm parted dnsutils grub ssh
grep: /etc/ssh/sshd_config: No such file or directory
grep: /etc/ssh/sshd_config: No such file or directory
Not starting OpenBSD Secure Shell server (/etc/ssh/NOSERVER)
make-fai-nfsroot finished.
Stopping NFS kernel daemon: mountd nfsd.
Unexporting directories for NFS kernel daemon...done.
Starting NFS kernel daemon: nfsd mountd.
Exporting directories for NFS kernel daemon...done.
Kernel image file name  = /usr/lib/fai/nfsroot/boot/vmlinuz-&kver;
Output file name        = /boot/fai/installimage
Kernel command line     = "auto rw root=/dev/nfs nfsroot=kernel nfsaddrs=kernel"

Image Creator for MBA ROMs v1.00
Usage: imggen [OPTION] inputfile outputfile
  -a,   Add 3Com MBA/BootWare support
  -r,   Remove 3Com MBA/BootWare support from image file
  -i,   Show information on an image
  -h,   Help screen

In filename: /boot/fai/installimage
Out filename: /boot/fai/installimage_3com
Adding MBA support...
MBA support has been succesfully added 
You have no FAI configuration. Copy FAI template files with:
cp -a /usr/share/fai/templates/* /usr/local/share/fai
Then change the configuration files to meet your local needs.
FAI setup finished.
</example>

<p>
The setup routine adds lines to <file>/etc/exports</file> to export
some directories to all hosts that belong to the netgroup
<em>faiclients</em>. All install clients must belog to this netgroup,
in order to mount these directories succesfully. Netgroups are
defined in <file>/etc/netgroup</file> or in the corresponding NIS
map. An example for the netgroup file can be found in
<file>/usr/share/doc/fai/examples/etc/netgroup</file>. For more
information, read the manual pages <manref name="netgroup"
section="5"> and the NIS HOWTO. After changing the netgroups , the NFS
server has to reload its configuration.  Use one of the following
commands, depending on which NFS server you are using:

<example>
kueppers[~]# /etc/init.d/nfs-kernel-server reload
kueppers[~]# /etc/init.d/nfs-server reload
</example>

<p>
The setup also creates the account <tt>fai</tt> ($LOGUSER). The log
files of all install clients are saved to the home directory of this
account. If you boot from network card, you should change the primary
group of this account, so this account has write permissions to
<file>/boot/fai</file> in order to change symbolic links to the kernel
image, that is booted by a client. See also variable
<var>TFTPLINK</var> in <file>class/DEFAULT.var</file>.


<p>
After that, FAI is installed successfully on your server, but has no
configuration for the install clients. Start with the templates from
<tt> /usr/share/fai/templates</tt> using the copy command above
and read <ref id="config">. Before you can set up a DHCP or BOOTP
daemon, you should collect some network information of all your
install clients. This is described in section <ref id="bootfloppy">.
<p>
When you make changes to &fc; or want to install a new kernel to
nfsroot, the nfsroot has to be rebuild by calling <prgn>make-fai-nfsroot</prgn>.

<chapt id="booting">Preparing booting <p> 

Before booting for the first time, you have to choose which medium you
use for booting. You can use the boot floppy or configure the computer
to boot via network card using a boot PROM, which is much smarter. 

<sect id="nicboot">Booting from 3Com network card with boot PROM
<p>
If you have a 3Com network card that is equipped with a boot ROM by
Lanworks Technologie or already includes the DynamicAccess Managed PC
Boot Agent (MBA) software<footnote> <p><httpsite>http://support.3com.com/</httpsite>
<httppath>infodeli/tools/nic/mba.htm</httppath></p></footnote>, you
can enter the MBA setup by typing <tt>Ctrl+Alt+B</tt> during boot. The
setup will look like this:

<example>
Managed PC Boot Agent (MBA) v4.00
(C) Copyright 1999 Lanworks Technologies Co. a subsidiary of 3Com Corporation
All rights reserved.
===============================================================================
                            Configuration

Boot Method:                TCP/IP
Protocol:                   BOOTP
Default Boot:               Network
Local Boot:                 Enabled
Config Message:             Enabled
Message Timeout:            3 Seconds
Boot Failure Prompt:        Wait for key
===============================================================================
  Use cursor keys to edit: Up/Down change field, Left/Right change value
  ESC to quit, F9 restore previous settings, F10 to save
</example>

Set the boot method to <tt>TCP/IP</tt> and the protocol to either
<tt>BOOTP</tt> or <tt>DHCP</tt>. I prefer BOOTP because the daemon
automaticly reloads its configuration when it's changed.
Make a symbolic link from the hostname of your client to the
appropriate kernel image in <file>/boot/fai</file>. In the following
example the host is called <tt>bigfoot</tt>. The file
<file>installimage_3com</file> is created by <prgn>imggen</prgn> and
suitable for booting 3Com network cards.

<example> 
kueppers[~]# cd /boot/fai
kueppers[~]# ln -s installimage_3com bigfoot
</example>


<sect id="pxeboot">Booting from network card with a PXE conforming boot ROM
<p>
Some network cards (e.g. Intel EtherExpress PRO 100) have a fixed
configuration for booting using the PXE protocol. This requires a PXE
Linux boot loader an a special version of the <tt>TFTP</tt> daemon. See
<file>/usr/share/doc/syslinux/pxelinux.doc.gz</file> for more
information, how to boot such an environment. There are also some
mails in the FAI mailing list archive concerning this topic.

<sect id="bootfloppy">Creating a boot floppy
<p>
If your network card can't boot itself, you have to boot via
floppy. Use the command <prgn>make-fai-bootfloppy</prgn> to create the
boot floppy. Since there's no client specific information on this
floppy, it's suitable for all your install clients.
You can also specify additional kernel parameters for this boot
floppy, if desired. There's more help available.
 <example># make-fai-bootfloppy -h</example>
If you have no BOOTP or DHCP server, supply the network
 configuration as kernel parameters.
<footnote> 
The format is: <example>ip=&lt;client-ip&gt;:&lt;server-ip&gt;:&lt;gw-ip&gt;:&lt;netmask&gt;:&lt;hostname&gt;:&lt;device&gt;:&lt;autoconf&gt;
</example>For additional information see <file>/usr/src/linux/Documentation/nfsroot.txt</file> in the kernel
sources.
 </footnote>

<sect id="mac">Collecting Ethernet addresses<p>

Now it's time to boot your install clients for the first time. They
will fail to boot completely, because no BOOTP or DHCP daemon is running yet or
recognizes the hosts. But you can use this first boot attempt to
easily collect all Ethernet addresses of the network cards.
<p>

You have to collect all Ethernet (MAC) addresses of the install clients
and assign a hostname and IP address to each client. To collect 
 all MAC addresses, now boot all your install clients. While the
install clients are booting, they send broadcast packets to the LAN. You
can log the MAC addresses of these hosts, if following
command is running simultaneously on the server:

<example># tcpdump -qte broadcast and port bootpc >/tmp/mac.lis</example>

<p>
After the hosts has been sent some broadcast packets (they will fail
to boot because <prgn>bootpd</prgn> isn't running or does not recognize the MAC
address yet) abort <prgn>tcpdump</prgn> by typing <tt>ctrl-c</tt>. You get a list
of all unique MAC addresses with these commands:

<example># perl -ane 'print "\U$F[0]\n"' /tmp/mac.lis|sort|uniq</example>

After that, you only have to assign these MAC addresses to hostnames
and IP addresses (<file>/etc/ethers</file> and <file>/etc/hosts</file>
or corresponding NIS maps). With these information you can configure
your <prgn>BOOTP</prgn> or <prgn>DHCP</prgn> daemon (see the section
<ref id="bootptab">).  I recommend to write the MAC addresses (last
three bytes will suffice if you have network cards from the same
vendor) and the hostname in the front of each chassis.

<sect id=bootptab>Configuration of the BOOTP daemon<p>

An example configuration for the BOOTP daemon is included in FAI. If
you have no <file>/etc/bootptab</file> file you can use
<file>/usr/share/doc/fai/examples/etc/bootptab</file> as template.

<example>
# /etc/bootptab example for FAI
# replace FAISERVER with the name of your install server

.faiglobal:\
 :ms=1024:\
 :hd=/boot/fai:\
 :hn:bs=auto:\
 :rp=/usr/lib/fai/nfsroot:
# rp: $NFSROOT

# your local values
#
# sa: your tftp server (install server)
# ts: your timeserver (time enabled in inetd.conf)

# these are optional
# ys: NIS server
# yd: NIS domainname
# nt: list of NTP servers

.failocal:\
 :tc=.faiglobal:\
 :sa=FAISERVER:\
 :ts=FAISERVER:\
 :T170="FAISERVER:/usr/local/share/fai":\
 :T171="sysinfo":\
 :sm=255.255.255.0:\
 :gw=134.95.9.254:\
 :dn=informatik.uni-koeln.de:\
 :ds=134.95.9.136,134.95.100.209,134.95.100.208,134.95.140.208:\
 :ys=rubens:yd=informatik4711.YP:\
 :nt=time.rrz.uni-koeln.de,time2.rrz.uni-koeln.de:

# now one entry for each install client
bigfoot:ha=0x00105A240012:bf=bigfoot:tc=.failocal:T171="sysinfo":T172="verbose sshd createvt debug ":
ant01:ha=0x00105A000000:bf=ant01:tc=.failocal:T172="sshd":
</example>

Insert one line for each install client at the end of this file as
done for <em>bigfoot</em> and <em>ant01</em>. Replace the string
<tt>FAISERVER</tt> with the name of your install server. If the
install server has multiple network cards and host names, use the host
name of the network card to which the install clients are
connected. Then adjust the other network tags (<tt>sm, gw, dn,
ds</tt>) to your local needs.

<taglist>
 <tag>sm</tag> <item>  <p>: Subnet mask</p> </item>
 <tag>gw</tag> <item>  <p>: Default gateway / router</p> </item>
 <tag>dn</tag> <item>  <p>: Domain name</p> </item>
 <tag>ds</tag> <item>  <p>: List of DNS server </p> </item>
 <tag>T170</tag> <item>  <p>Location of the FAI configuration directory
</p> </item>
 <tag>T171</tag> <item>  <p>FAI_ACTION</p> </item>
 <tag>T172</tag> <item>  <p>List of FAI_FLAGS; e.g. verbose, debug, reboot, createvt, sshd</p> </item>
 <tag>T173</tag> <item>  <p>Reserved for future use</p> </item>
 <tag>T174</tag> <item>  <p>Reserved for backup devices and backup options; NOT YET USED
</p> </item>
 </taglist>

The tags for NIS and time servers (<tt>yp, yd, nt</tt>) are
optional. Tags with prefix <tt>T</tt> (starting from T170) are generic
tags which are used to transfer some FAI specific data to the
clients. <strong> It is important, that T171 (equivalent to variable
<var>FAI_ACTION</var><footnote> <p>Theses names are used in the main
installation script <file>rcS_fai</file>. The configuration files for
DHCP and BOOTP daemons use other names. Example: <var>FAI_ACTION</var>
is equal to <tt>T171</tt> in bootptab or <tt>option-171</tt> in
dhcp.conf. </p> </footnote>. is set to <tt>sysinfo</tt> !</strong>
Later you can set it to <tt>install</tt>, in order to start the
automatic installation. For more information on all tags see <manref
name="bootptab" section="5">.
<p>

When you have created your <file>bootptab</file> file, you have to
enable the BOOTP daemon once. It's installed but Debian does not enable it
by default. Edit <file>/etc/inetd.conf</file> and remove the comment
(the hash) in the line containing <tt>#bootps</tt>. Then tell
<prgn>inetd</prgn> to reload its configuration.

<example># /etc/init.d/inetd reload</example>

I recommend to use the BOOTP daemon and protocol for booting because
it automatically reloads the configuration file if any changes are
made to it. The daemon for DHCP must always be manually restarted
after changes to the configuration file are made <footnote> <p>If you
can't use one of these, there's also the possibility to supply all
information via a file or compile them into the kernel, but it's
easier to use a daemon.
</p>
</footnote>. Now it's time to boot all install clients again!








FAI can perform several actions when the client is booting. This action
is defined in the variable <var>FAI_ACTION</var>

Be very carefully if you set <var>FAI_ACTION </var> to
<em>install</em>. This can destroy all your data on the install
client, indeed most time it should do this ;-). It's recommended to change this only
on a per client base in the BOOTP configuration. Do not change it in
the section <tt>.failocal</tt> in <file>/etc/bootptab</file>, which
is a definition for all clients.

<sect id="bootdhcp">Configuration of the DHCP daemon <p>
An example for <manref name="dhcp.conf" section="5"> is available in
<file>/usr/share/doc/fai/examples/etc</file>. Start using this example
and look at all options used therein. If you make any changes
to this configuration, you must restart the daemon.


<sect id="bootmesg">Boot messages <p>

These are the messages, when booting from floppy.
<example>
LILO Loading FAI-BOOTP.
Uncompressing Linux... OK, booting the Kernel.
Linux version &kver; (root@kueppers) (gcc version 2.95.2 20000220
.
.
.
</example>
The rest of the boot message will be equal to those when booting from
network card. When booting from network card you will see:
<example>
BOOTP.
TFTP....
Linux Net Boot Image Loader Version 0.8.1 (netboot)
.
Uncompressing Linux... OK, booting the Kernel.
Linux version &kver; (root@kueppers) (gcc version 2.95.2 20000220
.
.
.
Sending BOOTP requests ..... OK
IP-Config: Got BOOTP answer from 134.95.9.149
IP-Config: Complete:
 device=eth0, addr=134.95.9.200, mask=255.255.255.0, gw=134.95.9.254,
 host=ant01, domain=informatik.uni-koeln.de, nis-domain=informatik4711.YP,
 bootserver=134.95.9.149, rootserver=134.95.9.149, rootpath=/usr/lib/fai/nfsroot
.
.
   ------------------------------------------------------
     FAI &faiver;, &faiverdate;
     Fully Automatic Installation for Debian GNU/Linux

     Copyright (c) 1999-2001, Thomas Lange
             lange@informatik.uni-koeln.de
   ------------------------------------------------------
.
.
/fai mounted from kueppers:/usr/local/share/fai
FAI_ACTION: sysinfo
.
.
Press &lt;RETURN&gt; to reboot or ctrl-c to execute a shell
</example>

When the copyright message is shown, the install client has mounted
the nfsroot<footnote> <p><file>/usr/lib/fai/nfsroot</file> from the
install server</p> </footnote> to the clients root directory <file>/</file>. This
is the whole filesystem for the client at this moment. When
<file>/fai</file> is mounted, the configuration data from the install
server is available on the client.
<p>

Following error message indicates, that your install client doesn't
get an answer from a BOOTP server. Check your cables or start the
<manref name="bootpd" section="8"> daemon with the debug flag enabled.
<example>
Sending BOOTP requests ........ timed out!
IP-Config: Retrying forever (NFS root)...
</example>

If you get the following error message, the install kernel has
no driver compiled in for your network card. 
<example>
IP-Config: No network devices available
Partition check:
 hda: hda1 hda2 < hda5 hda6 hda7 hda8 >
Root-NFS: No NFS server available, giving up.
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Insert root floppy and press ENTER
</example>
Then you have to compile a new kernel has a driver compiled in, which
supports your network card. This driver must no be a kernel module. To
compile the new kernel, start using the default kernel configuration
of FAI.
<example>
kueppers# cd /usr/src/kernel-source-&kver;
kueppers# cp /usr/lib/fai/nfsroot/boot/config-&kver; .config
kueppers# make menuconfig
</example>
Call <prgn>make menuconfig</prgn> and add the driver in menu <tt>Network
device support/Ethernet</tt> which supports your network card. Then
create a Debian package using <manref name="make-kpkg" section="8">:
<example>
kueppers# make-kpkg clean
kueppers# make-kpkg --revision BOOTP2 kernel-image
</example>

This command creates the file 
<file>/usr/src/kernel-image-&kver;_BOOTP2_i386.deb</file>. Adjust 
the variable <var>KERNELPACKAGE</var> in  &fc; and rebuild the nfsroot.
<example>
kueppers# make-fai-nfsroot
</example> 
After that, you have to create a new boot floppy. Now your network
card should be recognized and the install kernel should mount
the nfsroot successfully. More information how to compile an
install kernel can be found in the <file>README</file> of the package <tt>fai-kernels</tt>.

<sect id="sysinfo">Collecting other system information 
<p>

Now the clients have booted with <var>FAI_ACTION</var> set to <em>sysinfo</em>. Type
<tt>ctrl-c</tt> to get a shell or use <tt>Alt-F2</tt> or
<tt>Alt-F3</tt> and you will get another console terminal, if you have added <tt>createvt</tt>
to <var>FAI_FLAGS</var>.

Remote login is available via the secure shell, if <tt>sshd</tt> if
added to <var>FAI_FLAGS</var>. The encrypted password is set with
variable <var>FAI_ROOTPW</var> in &fc; and is default to "fai". You
can also log in without a password when using <var>
SSH_IDENTITY</var>. To log in from your server to the install client
(for eg. named ant01) use:

<example>> ssh -l root ant01
Warning: Permanently added 'ant01,134.95.9.200' to the list of known hosts.
root@ant01's password: 
</example>


You have now a running Linux system on the install client
without using the local hard disk. Use this as a rescue system, if
your local disk is damaged or the computer can't boot properly from
hard disk. You will get a shell and can execute various commands
(dmesg, lsmod, df, lspci, ...). Look at the log file in
<file>/tmp</file>. There you can find much information about the boot
process.

All log files from <file>/tmp </file> are also written to the install server
into the directory <tt>~fai/ant01/sysinfo/</tt><footnote>More
general: <tt>~$LOGUSER/$HOSTNAME/$FAI_ACTION/</tt>. Examples of log
files can be found on the FAI homepage.
</footnote>

<p>
A very nice feature is, that FAI mounts all filesystems it finds on
the local disks read only. It also tells you on which partition a file
<file>/etc/fstab</file> exists. When only one file is found, the
partitions are mounted according to this information. Here's an
example:
<example>
ant01:~# df
Filesystem   1k-blocks    Used Available Use% Mounted on
/dev/root      1249132  855648    330032  72% /
/dev/ram0         3963      36      3927   1% /tmp
kueppers:/usr/local/share/fai
               1249132  855648    330032  72% /fai
/dev/hda1        54447    9859     41777  19% /tmp/target
/dev/hda10     1153576      20   1141992   0% /tmp/target/files/install
/dev/hda9       711540      20    711520   0% /tmp/target/home
/dev/hda8       303336      13    300191   0% /tmp/target/tmp
/dev/hda7      1517948   98252   1342588   7% /tmp/target/usr
/dev/hda6       202225    8834    182949   5% /tmp/target/var
</example>

<strong>This method can be used as an rescue environment !</strong> In
future it will be possible to make backups or restore data to existing
filesystems. If you need a filesystem with read-write access use the
<prgn>rwmount</prgn> command:

<example>ant01:~# rwmount /tmp/target/home</example> 

<sect id=checkbootp>Checking parameters from BOOTP and DHCP servers<p>

If the install client boots with action <em>sysinfo</em>, you can also
check if all information from the BOOTP or DHCP daemons are received
correctly. If the kernel uses BOOTP requests to receive data, these
information will be written to <file>/tmp/bootp.log</file>. If the
kernel support the DHCP protocol all is written to
<file>/tmp/dhcp.log</file>. And example for the result of a BOOTP
requests can be found in <ref id="s1">.


<sect id=reboot>Rebooting the computer<p>
At any time you can reboot the computer using the command
<prgn>faireboot</prgn>, also if logged in from remote. If the
installation hasn't finished, use <tt>faireboot -s</tt>, so the log
files are also copied to the install server.

<chapt id=instprocess>Overview of the installation sequence<p>

Following steps are performed during an installation after the linux kernel
has booted on the install clients.

<enumlist>
	    <item> <p>Set up FAI </p> </item>
	    <item> <p>Load kernel modules</p> </item>
	    <item> <p>Define classes</p> </item>
	    <item> <p>Define variables</p> </item>
	    <item> <p>Partition local disks</p> </item>
	    <item> <p>Create and mount local filesystems</p> </item>
	    <item> <p>Install software packages</p> </item>
	    <item> <p>Call site specific configuration scripts</p> </item>
	    <item> <p>Save log files</p> </item>
	    <item> <p>Reboot the new installed system</p> </item>
	  </enumlist>

You can also define additional programs or scripts, that will be run on particular
occasions. They are called <tt>hooks</tt>. Hooks can add aditional
functions to the installation process or replace the default subtasks
of FAI. So it's very easy to
customize the whole installation process. Hooks are explained in
detail in <ref id="hooks">.

<p>
The installation time is mainly determined by the amount of software
that will be installed. A dual Pentium II, 400 MHZ with 128 MB RAM and
a 10 Mbit network card needs about 11 min when installing 520 MB of
software to local disk. An installation with 90 MB software (a
dataless client) only needs two minutes. The checking for bad blocks
on a 4 GB partition needs additional 6 minutes. Using a 100 Mbit LAN does
not decrease the installation time considerable, so the network will
not be the bottleneck when installing multiple clients simultaneously.

<sect id=isetup>Set up FAI<p>

After the install client has booted, only the program
<file>/sbin/rcS_fai</file><footnote><p>Since the root filesystem on
the clients is mounted via NFS, <prgn>rcS_fai</prgn> is located in
<file>/usr/lib/fai/nfsroot/sbin</file> on the install server.</p>
</footnote> is executed. This is the main script, that controls the
sequence of tasks for FAI. No other scripts in
<file>/etc/init.d/</file> are executed.
<p>
A ramdisk is created and mounted to <file>/tmp</file>, which is the
only writable directory, until local filesystems are
mounted. Additional parameters are received from the BOOTP or DHCP
daemon and the configuration space if
mounted via NFS from the install server to <file>/fai</file>.  The
setup is finished after additional virtual terminals are created and
the secure shell daemon for remote access is started on demand.

<sect id=iclass>Defining classes, variables and loading kernel modules<p>

Now scripts in <file>/fai/class/</file> are executed to define classes
and variables that are later used in the site specific configuration
scripts.  All scripts matching <tt>S[0-9]*.{sh,pl}</tt> are executed
in alphabetical order. Every word that these scripts print to the
standard output are interpreted as class names. These classes are
defined for this install client. You can also say this client belongs
to these classes. A class is defined or undefined and has no
value. Only defined classes are of interest for an install client.  A
description of all classes can be found in
<file>/usr/share/doc/fai/classes_description.txt</file>. It is
advisable to document the task a new class performs. Then, this
documentation is the base for composing a configuration from classes.

<p>
The scripts <prgn>S05modules.sh</prgn> loads kernel modules
on demand. So you can use classes when loading modules and also define
more classes after the kernel has loaded modules and recognized new hardware.
A complete description of all these scripts can be found in <ref id="cscripts">.
<p>

After defining the classes, every file
matching <tt>*.var</tt>, which prefix is a defined class, is executed
to define variables.

<sect id=ipartition>Partitioning local disks, creating filesystems<p>

Then one (only one) disk configuration file from
<file>/fai/disk_config</file> is selected using classes. It's the
description how all the local disks will be partitioned, which
filesystems should be created and how they are mounted. It's also
possible to preserve the disk layout or to preserve the data on a
partition. It's done by the command <prgn>setup_harddisks</prgn>
<footnote> <p>If <prgn>/usr/local/bin/my-fdisk</prgn> exists, this
command is used instead. In future, this script will be completely
rewritten. Plans are to use <prgn>parted</prgn> or <prgn>fdisk</prgn>
and the device filesystems <tt>devfs</tt>. </footnote>, which uses
<prgn>sfdisk</prgn> for obtaining disk information and for
partitioning. The format of the configuration file is described in
<file>/usr/share/doc/fai/README.disk_config</file>.
<p>
During the installation process all local filesystems are mounted
relative to <file>/tmp/target</file> . So, for
e.g. <file>/tmp/target/home</file> will become  <file>/home</file>
in the new installed system.  

<sect id=ipackages>Installing software packages<p>

When local filesystems are created, they are all empty (except for
preserved partitions). Now the Debian base system and all requested
software packages are installed on the new filesystems. First the
base archive is unpacked, then the command
<prgn>install_packages</prgn> installs all packages using <manref
name="apt-get" section="8"> without any manually interaction needed. If
a packages requires an other packages it resolves
this dependency by installing the required package.
<p>

Classes are also used when selecting the configuration files in
<file>/fai/package_config/</file> for software installation. The
format of the configuration files is described in <ref
id="packageconfig">.

<sect id=icscripts>Site specific configuration<p>

After all requested software packages are installed, the system is
nearly ready to go. But not all default configurations of the software
packages will meet your site specific needs. So you can call arbitrary
scripts, which adjust the system configuration. Therefore scripts, that match
a class name in <file>/fai/scripts</file><footnote>
<p><file>/usr/local/share/fai/scripts</file> on the install
server.</p> </footnote> will be executed. FAI comes with some
templates for these scripts, but you can write your own bourne, bash,
perl, cfengine or expect scripts.
<p>
These important scripts are described in detail in <ref
id="cscripts">.

<sect id=isavelog>Save log files<p> When all installation tasks are
finished, the log files are written to
<tt>/var/log/fai/$HOSTNAME/install/</tt> <footnote>
<p><file>/var/log/fai/localhost/install/</file> is a link to this
directory.</p> </footnote> on the new system and to
the a account on the install
server, if <var>$LOGUSER</var> is defined in &fc;.

<sect id=ireboot>Reboot the new installed system<p>

At least the system is automatically rebooted if the flag
<var>reboot</var> is set <footnote><p>Add "reboot" to
<var>FAI_FLAGS</var> (= T172).</p> </footnote>.  This is only useful
if booting from network card or if you can change the boot device
using the command <prgn>bootsector</prgn>. Otherwise, you have to
remove the floppy disk and type return or call <prgn>faireboot</prgn>
from a remote login. You must change the boot device, to boot the new
installed system otherwise the installation would be performed
again. Read <ref id="changeboot"> how to change the boot device.

<chapt id=plan>How to plan your installation<p>
<em>Plan your installation, and FAI installs your plans.</em>
<p>
Before starting your installation, you should spend much time in
planing your installation. When you're happy with your installation
concept, FAI can do all the boring, repeating tasks to put your plans
into practice. FAI can't do good installations, if your concept is
imperfect or lacks some important details. Start planing the
installations by answering yourself following
questions:

<taglist>
  <tag></tag> <item> <p>Will I create a Beowulf cluster, or do I
  have multiple workstations, each only used by a single user ?</p> </item>
  <tag></tag> <item> <p>How does my LAN topology looks like ?</p> </item>
  <tag></tag> <item> <p>Do I have uniform hardware ?</p> </item>
  <tag></tag> <item> <p>Will the hardware stay uniform in the future ?</p> </item>
  <tag></tag> <item> <p>How should the hosts be named ?</p> </item>
  <tag></tag> <item> <p>How should the local harddisks be partitioned ?</p> </item>
  <tag></tag> <item> <p>Which software should be installed ?</p> </item>
  <tag></tag> <item> <p>Which daemons should be started, and how
  should the configuration for these looks like ?</p> </item>
  <tag></tag> <item> <p>Which remote filesystems should be mounted ?</p> </item>
  <tag></tag> <item> <p>Does the hardware needs a special kernel ?</p> </item>
  <tag></tag> <item> <p></p> </item>
</taglist>

You have also to think about user accounts, printing, mail, cron jobs,
graphic cards, dual boot, NIS, NTP, timezone, keyboard layout,
exporting and mounting directories via NFS and many other things. So,
there's a lot to do before starting an installation. And remember
that knowledge is power, and it's up to you to use it. Installation
and administration is a process, not a product. FAI can't do things
you don't tell it to do.
<p>
But you need not to start from scratch. Look at all files and scripts
in the configuration space. There are a lot of things you can use for
your own installation.

A good paper with more aspects of building an infrastructure is
<url id="http://www.infrastructures.org/papers/bootstrap/">
"Bootstrapping an Infrastructure".

<chapt id=config>Installation details<p>

<sect id=c3>The configuration space<p>

The configuration is the collection of information how exactly to
install a computer. The central configuration space for all install
clients is located on the server in <file>/usr/local/share/fai</file>
and its subdirectories. This will be mounted by the install clients to
<file>/fai</file>. Following subdirectories are available:

<taglist>
	  <tag><tt>class/</tt></tag> <item> <p>Scripts and files to
	  load kernel modules and define classes and variables.</p> </item>
	  <tag><tt>disk_config/</tt></tag> <item> <p>Configuration
	  files for disk partitioning and file system creation.</p> </item>
	  <tag><tt>package_config/</tt></tag> <item> <p>Software
	  packages to be installed or removed.</p> </item>
	  <tag><tt>scripts/</tt></tag> <item> <p>Script for customization.</p> </item>
	  <tag><tt>files/</tt></tag> <item> <p>Files used by
	  customization scripts.</p> </item>
	  <tag><tt>hooks/</tt></tag> <item> <p>Hooks are user defined
	  programs, which are called during the installation process.
</taglist>

The main installation script <prgn>rcS_fai</prgn> uses these
subdirectories in the order listed. Copy the configuration templates
to the configuration space and start an installation.

<example>
> cp -a /usr/share/fai/templates/* /usr/local/share/fai
</example>

These files contain configuration for some example hosts.

<taglist>  
   <tag>bigfoot</tag>  <item> <p>This is a server with much software. It
   provides the home directory and all programs for its NFS clients. Also some
   daemons are installed and activated by default.</p> </item>
   <tag>ant01,...</tag>  <item> <p>These dataless clients mount
   <file>/usr</file> and <file>/home</file> from bigfoot. Most of
   the disk space is spend for a scratch partition, which is exported
   to a netgroup of hosts.</p> </item>
</taglist>
Start looking at these examples and study them. Then change or add
things to these examples. But don't forget to plan your own
installation !

<sect id=s1> Set up FAI<p>

This jobs is done by the tasks: <em>confdir</em> and <em>setup</em>.<p>


Since only the ramdisk is writable in the beginning, all log
files are written to <file>/tmp</file>. The main script
<prgn>rcS_fai</prgn> logs its messages to
<file>/tmp/rcS.log</file>. If you have any problems during
installation, look for errors there. You can find examples of the log files for
some hosts in the download directory of the FAI homepage.<p>

When the kernel has booted and the network interface is set up, the
BOOTP (or DHCP) server is inquired a second time to get the additional
information for FAI. The command <manref name="bootpc" section="8"> is
called and its output is used to define the corresponding global
variables which are save in <file>/tmp/bootp.log</file>.

<example>
/tmp/bootp.log:

SERVER='134.95.9.149'
IPADDR='134.95.9.200'
BOOTFILE='/boot/fai/bigfoot'
NETMASK='255.255.255.0'
NETWORK='134.95.9.0'
BROADCAST='134.95.9.255'
GATEWAYS_1='134.95.9.254'
GATEWAYS='134.95.9.254'
ROOT_PATH='/usr/lib/fai/nfsroot'
DNSSRVS_1='134.95.9.136'
DNSSRVS_2='134.95.100.209'
DNSSRVS_3='134.95.100.208'
DNSSRVS_4='134.95.140.208'
DNSSRVS='134.95.9.136 134.95.100.209 134.95.100.208 134.95.140.208'
DOMAIN='informatik.uni-koeln.de'
SEARCH='informatik.uni-koeln.de uni-koeln.de'
YPSRVR_1='134.95.9.10'
YPSRVR='134.95.9.10'
YPDOMAIN='informatik4711.YP'
TIMESRVS_1='134.95.9.10'
TIMESRVS='134.95.9.10'
NTPSRVS_1='134.95.81.172'
NTPSRVS_2='134.95.140.172'
NTPSRVS='134.95.81.172 134.95.140.172'
HOSTNAME='bigfoot'
T170='kueppers:/usr/local/share/fai'
T171='sysinfo'
T171='install'
T172='createvt sshd'
</example>

It's not a bug, if a variable (T171 in the example above) is defined
twice. The second definition supersedes the first.

<p>
<var>FAI_FLAGS</var> (T172) contains a space separated list of
flags. Following flags are known:
<taglist>
 <tag>verbose</tag> <item> <p>Create verbose output during
 installation. This should be alsway the first flag, so consecutive
 definitions of flags will be verbosely displayed.</p> </item>

 <tag>debug</tag> <item> <p>Create debug output. No interactive
 installation is performed. During package installation you have to
 answer all questions of the postinstall scripts from the
 console. </p> </item>

 <tag>sshd</tag> <item> <p>Start ssh daemon to enable remote logins.</p> </item>

	    <tag>createvt</tag> <item> <p>Create two virtual terminals and execute a bash if <tt>ctrl-c</tt> it typed. The terminals can be accessed by typing <tt>Alt-F2</tt> or <tt>Alt-F3</tt>. Otherwiese no terminals are available and typing <tt>ctrl-c</tt> will reboot the install client. Useful for installation which should not be interruptible.</p> </item>

 <tag>reboot</tag> <item> <p>Reboot after installation is finished
 without typing RETURN on the console. Only useful if you can change
 the boot image or boot device automatically (Can your assembly robot remove the
 boot floppy via remote control ?). Currently useful if you boot from network card and use
 <var>$TFTPLINK</var>. or change the boot device with the command
 <prgn>bootsector</prgn>.</p> </item> 
</taglist>


<sect id=classc> The class concept<p>

The idea of using classes in general and using certain files matching
a class name for a configuration is adopted from the installation
scripts by Casper Dik for Solaris. This technique proved to be very
useful for the SUN workstations, so I also use it for the fully
automatic installation of Linux. One simple and very efficient feature
of Casper's scripts is to call a command with all files, whose file
names are also a class. The following loop may implement this function
in a shell script:

<example>
   for class in $all_classes
   do
   if [ -r $config_dir/$class ]; then
      command $config_dir/$class
      # exit, if only the first matching file is needed
   fi
   done
</example>
A variation would be to call the command only for the first file that
matches a class name. Therefore it is possible to add a new file to
the configuration without changing the script. This is because the
loop automaticly detects new configurations files that should be
used. Unfortunately cfengine does not support this nice feature, so
all classes being used in cfengine need also to be specified inside
the cfengine scripts. Classes are very important for the fully
automatic installation. If a client belongs to class <tt>A</tt>, we
say the class <tt>A</tt> is defined. A class has no value, it is just
defined or undefined. Within scripts, the variable <var>$classes</var>
holds a space separated list with the names of all defined classes.
Classes determine how the installation is performed. For example, an
install client is configured to become a FTP server by default.

Mostly a configuration is created by only changing or appending the
classes to which a client belongs, making the installation of a new
client very easy.  Thus no additional information needs to be added to
the configuration files if the existing classes suffice your needs.
There are different possibilities to define classes:
<enumlist>
     <item><p>Some default classes are defined for every host:
     DEFAULT, LAST and its hostname.</p> </item>
     <item><p>Classes may listed within a file.</p> </item>
     <item><p>Classes may be defined by scripts.</p> </item>
 </enumlist>

The last option is a very nice feature, since these scripts will
define classes automatically.  For example, several classes are
defined only if certain hardware is identified.  We use Perl and shell
scripts to define classes.  All names of classes, except the hostname,
are written in uppercase. They must not contain a hyphen, a hash or a
dot, but may contain underscores. A description of all classes can be
found in <file>/usr/share/doc/fai/classes_description.txt</file>.
<p>

Hostnames should rarely be used for the configuration files in the
configuration space. Instead, a class should defined and this class is
then added to the host.

<sect id=s2> Defining classes<p>

This part is done by the task <em>defclass</em><p>

The main FAI script <file>rcS_fai</file> defines the classes
<tt>DEFAULT, LAST, $HOSTNAME</tt> and all classes in the file
<file>/fai/class/</file><tt>$HOSTNAME</tt> for every hosts.
Additionally, all files that are executable and match the shell
regular expression <tt>S[0-9]*.{sh,pl}</tt> are called in alphabetical
order. Every output from these scripts is used to define
classes. Multiple classes in one line must be space separated. The
list of all defined classes is stored in the variable
<var>$classes</var> and in <file>/tmp/FAI_CLASSES</file>. The list of
all classes is transfered to <prgn>cfengine</prgn>, so it can use them
too. Script <file>S01alias.sh</file> (see below) is used to define
classes for groups of hosts. All hosts with prefix <var>ant</var> use
all classes in the file <file>anthill</file>. Hosts, which have an IP
address in subnet <var>134.95.9.0</var> also belongs to class
<tt>NET_9</tt>. Finally this scripts defines the class with the name
of the hardware architecture in uppercase letters.

<example>
S01alias.sh:

# all hosts named ant?? are using the classes in file anthill
case $HOSTNAME in
    ant??)
        cat anthill ;;
esac

# if host belongs to class C subnet 134.95.9.0 use class NET_9
case $IPADDR in
    134.95.9.*)
        echo NET_9 ;;
esac


# echo architecture
dpkg --print-installation-architecture | tr /a-z/ /A-Z/
</example>

Script <file>S07disk.pl</file> can be used to define classes depending
on the number of local disks or the size of these scripts<footnote>
<p>It uses the library <file>Fai.pm</file>, which includes some useful
subroutines, e.g. <tt>class</tt>, <tt>classes</tt>,
<tt>read_memory_info</tt>, <tt>read_ethernet_info</tt>.</p>
</footnote>. But you can also use a range of partition size in the
disk configuration file (in <file>disk_config</file>), so you may not
need a class for every different disk size. The script
<file>S24nis.sh</file> automatically defines classes corresponding to
NIS. The name of the NIS domain (defined via BOOTP or DHCP) will also
become a class (only uppercase letters and minus is replaced by
underscore). Depending on several partition names,
<file>S90partitions.pl</file> defines classes. For eg., if a partition
<file>/files/scratch</file> exists, the install client will export
this directory via NFS therefore installs a NFS server packages.

<p>
The script <prgn>S05modules.sh</prgn> does not define any class, but
is responsible for loading kernel modules. Kernel modules are
important for detecting hardware. The script calls the script
<tt>$HOSTNAME.mod</tt> and all scripts that have the format
<tt>&lt;classname&gt;.mod</tt> and those class names are already
defined. Classes, that are used for loading modules must be defined
before this script is called. For e.g., if class <tt>DEFAULT</tt> is
defined (this class is always defined) and a file
<file>DEFAULT.mod</file> exists, this script is executed. These
scripts should contain all command for loading kernel modules:

<example>
DEFAULT.mod:

modprobe parport_probe
modprobe serial
</example>

You can find messages from modprobe in <file>/tmp/dmesg.log</file> and
the on the fourth console terminal (pressing <tt>Alt-F4</tt>).<p>

<sect id=classvariables> Variables in <tt>class/*.var</tt><p>

This part is done by the task <em>defvar</em><p>

All variables can be set global in <file>DEFAULT.var</file>. For
certain groups of hosts use a class file or for a single host use
the file <tt>$</tt><file>HOSTNAME.var</file>.

<taglist>
   <tag>hdparm</tag> <item> <p>Multi line commands to tune the
   harddisks. They are executed during installation and also creates the
   script <file>/etc/init.d/S61hdparm</file>.</p> </item>

   <tag>UTC</tag> <item> <p>Set hardware clock to UTC if
   <tt>$UTC=yes</tt>. Otherwise set clock to locatime. See <manref
   name="clock" section="8"> for more information.</p> </item>

   <tag>time_zone</tag> <item> <p>File relative to
   <file>/usr/share/zoneinfo/</file> which indicates your time
   zone.</p> </item>

   <tag>FAI_CONSOLEFONT</tag> <item> <p>Font, that is loaded during
   installation by <manref name="consolechars" section="8">.</p> </item>

   <tag>FAI_KEYMAP</tag> <item> <p>Keyboard map file in
   <file>/usr/share/keymaps</file>. You need not specify the complete
   path, since this file will be located automatically.</p> </item>

   <tag>kernelimage</tag> <item> <p>The kernel that is installed to
   the new system. If a Debian package
   <file>/fai/files/packages/</file><tt>$kernelimage</tt> exists,
   isntall this kernel package. Otherwise install the package
   <tt>$kernelimage</tt> from the Debian mirror. For eg., if
   <tt>kernelimage=kernel-image-&kver;-idepci</tt> this kernel will be
   installed. To install the a special kernel for host bigfoot, set
   <tt>kernelimage=kernel-image-&kver;_bigfoot1_i386.deb</tt> and this
   kernel will be installed from
   <file>/fai/files/packages/</file>.</p></item>

   <tag>liloappend</tag> <item> <p>Append parameters for the kernel of
   the new system (written to <file>/etc/lilo.conf</file>).</p> </item>

   <tag>moduleslist</tag> <item> <p>Multi line definition. List of modules (including kernel
   parameters), that are loaded during boot of the new system (written to /etc/modules).</p> </item>

   <tag>rootpw</tag> <item> <p>The root password for the new
   system. Additionally, FAI creates an root account with the same
   password called <tt>roott</tt>, which uses the <manref name="tcsh"
   section="1">.</p> </item>

   <tag>TFTPLINK</tag> <item> <p>Link to the TFTP kernel image, that boots
   using the root file system from the local disk. </p> </item>

   <tag>hserver, bserver</tag> <item> <p>Name of NFS servers for
   <file>/home</file> and <file>/usr</file>.</p> </item> 

   <tag>printers</tag> <item> <p>List of printer, for which a spool
   directory is created. Does not set up <file>/etc/printcap</file>.</p> </item>
   <tag></tag> <item> <p></p> </item>
</taglist>


<sect id=diskconfig>Hard disk configuration<p> 

The format of the hard disk configuration files is described in
<file>/usr/share/doc/fai/README.disk_config.gz</file>. The config file
<file>/fai/disk_config/CS_KOELN</file> is a generic description for
one IDE hard disk, which should fit for most installations. If you
can't partition your harddisk using this script <footnote><p>Currently
this script uses the command <tt>sfdisk(8)</tt>, which isn't available
on SUN SPARC.</p> </footnote>, use a hook instead. The hook should
write the new partition table, create the file systems and create the
file <file>/tmp/fstab</file> and <file>/tmp/disk_var.sh</file>, which
contains definitions of boot and root partitions.

<sect id=packageconfig>Software package configuration<p>
The script <prgn>install_packages</prgn> installs the selected software
packages. It uses all configuration files in <file>/fai/package_config/</file>,
which file name is also defined as a class. The syntax is very
simple.

<example>
# an example package class

PRELOADRM http://www.location.org/rp8_linux20_libc6_i386_cs1_rpm /root

PACKAGES taskinst
german science german

PACKAGES install
adduser netstd ae
less passwd
realplayer

PACKAGES remove
gpm xdm

PACKAGES dselect-upgrade
ddd                     install
a2ps                    install
</example>

Comments are starting with a hash (#) and are ending at the end of
the line. Every command begins with the word <tt>PACKAGES</tt>
followed by a command name. The command name is similar to those of
<prgn>apt-get</prgn>. Here's the list of supported command names:


<taglist>
<tag>install:</tag> <item> <p>Install all packages that are specified
in the following lines. If a hyphen is appended to the package name
   (with no intervening space), the package will be removed, not
   installed.</p> </item>

<tag>remove:</tag> <item> <p>Remove all packages that are specified in
the following lines. Append a + to the package name, if the package
should be installed.</p> </item>

<tag>taskinst:</tag> <item> <p>Install all packages belonging to the
task that are specified in the following lines. This works only for
Debian 3.0 and later.</p> </item>

<tag>dselect-upgrade</tag> <item> <p> Set package selections using the
following lines. The following lines must be the output of the commands
<prgn>dpkg --get-selections</prgn>.
</taglist>


Multiple lines with lists of space separated names of packages follows
the commands install and remove. All dependencies are resolved and <prgn>apt-get</prgn>
is used to perform the installation or removal of packages. The order of the
packages is of no matter. 
<p>
A line, that contains the <tt>PRELOADRM</tt> commands, loads a file
into a directory before installing the packages. For examples the
package <prgn>realplayer</prgn> needs an archive to install the
software, so this archive is downloaded to the directory
<file>/root</file>.  After installing the packages this file will be
removed. If the file shouldn't be removed, use the the command
<tt>PRELOAD</tt> instead.

<p>
If you specify a package that does not exists (e.g. you made a typo),
the the whole installation of software package will not be started.
This could happen when the command <manref name="xviddetect"
 section="1"> does not recognize the video card, because the
configuration file <file>SERVER</file> contains following line:

<example>
 xserver-`xviddetect -q`
</example>

If the video card isn't detected, the software installation tries to
install the package <tt>xserver-unknown</tt>. It will not start
because this package doesn't exist. You can test all software package
configuration files with the utility <prgn>chkdebnames</prgn>, which
is available in <file>/usr/share/doc/fai/utils/</file>.
<example>
> chkdebnames stable /usr/local/share/fai/package_config/*
</example>

<sect id=cscripts>Scripts in <tt>/fai/scripts</tt><p>

The default set of scripts in this directory is only an example. But
they should do a reasonable jobs for your installation. You can edit them
or add new scripts to match your local needs.



<sect1 id=shell>Shell scripts<p>

Most script are Bourne shell script. Shell scripts are good, if the
configuration task only needs to call some shell commands or create a
file from scratch. In order not to write much short script, it's
possible to distinguish classes within a script using the command
<tt>ifclass</tt>. For copying files with classes, use the command
<manref name="fcopy" section="8">. If you like to extract an archive
using classes, use <manref name="ftar" section="8">.
But now have a look at the scripts and see what they are doing.

<sect1 id=perl>Perl scripts<p>
Currently no Perl scripts are used for modifying the system
configuration.

<sect1 id=expect>Expect scripts<p>
Currently no expect scripts are used for modifying the system
configuration.

<sect1 id=cfengine>Cfengine scripts<p>

Cfengine has a rich set of functions to edit existing configuration
files, e.g <tt>LocateLineMatching, ReplaceAll, InsertLine,
AppendIfNoSuchLine, HashCommentLinesContaining</tt>. But it can't
handle variables, that are undefined. If a variables is undefined,
the whole cfengine script will abort. 

More information can be found at in the manual page <manref
name="cfengine" section="8"> or at the homepage for cfengine
<httpsite>http://www.iu.hioslo.no</httpsite><httppath>/cfengine</httppath>.


<sect id=changeboot>Changing the boot device<p>

Changing the boot sequence is normally done in your BIOS setup. But
you can't change the BIOS from a running Linux system (If you know how
to perform this, send me an email). But there's another way of swapping
the boot device of a running Linux system.

<p>
Change the boot sequence in your BIOS, so the first boot device is the
local disk, where the master boot record is located.  The second boot
device should be set to LAN or floppy disk, depending from which media
you boot when the installation process is performed.
<p>
After the installation is performed, <manref name="lilo" section="8">
will write a valid boot sector to the local disk. Since it's the first
boot device, the computer will boot the new installed system. If you
like to perform an installation again, you have to disable this boot
sector using the command <prgn>bootsector</prgn><footnote><p>The
command <tt>bootsector</tt> is part of the package
<package>fai</package> and will be installed to
<file>/usr/local/sbin</file> on the install clients.</p></footnote>
. For more information use: <example># bootsector -h
</example>


This is how to set up the a 3Com network card as second boot device,
even if the BIOS doesn't support this. Enable LAN as first boot device
in the BIOS.

<example>
Boot From LAN First: Enabled
Boot Sequence      : C only
</example>

Then enter the MBA setup of the 3Com network card and change it as follows:
<example>
Default Boot           Local
Local Boot             Enabled
Message Timeout        3 Seconds
Boot Failure Prompt    Wait for timeout
Boot Failure           Next boot device
</example>

This will enable the first IDE hard disk as first boot device. If the
boot sector of the hard disk is disabled, the computer will use the
network interface as second boot device and boots from it. Maybe the
disk p[artitioning tool can't work on such a disk. So you have to
enable the boot sector before you want to partition the disk.

<sect id=hooks>Hooks<p>

Hooks let you specify functions or programs, that are run at certain
steps of the installation process. FAI provides many locations where
hooks can be called. As you might expect, classes are also used when
calling hooks. Hooks are executed for every defined class. You only
have to create the hook with the name for the desired class and it
will be used. If <tt>debug</tt> is included in <var>$FAI_FLAG</var>
the option <tt>-d</tt> is passed to all hooks, so you can debug your
own hooks.
<p>
The directory <file>/fai/hooks/</file> contains all hooks. The file
name of a hook consists of a hook name as a prefix and a class name,
chained by a dot. The prefix describes the time when the hook is
called, if the class if defined for the install client. For example,
the hook <file>partition.DISKLESS</file> is called for every client
belonging to the class <tt>DISKLESS</tt> before the local disks would
be partitioned. If it should become a diskless client, this hook
can mount remote filesystems via NFS and create a <tt>/tmp/fstab</tt>.
After that, the installation process would not try to partition and
format a local hard disk, because a file <file>/tmp/fstab</file>
already exists.
<p>
A hook of the form <tt>hookprefix.classname</tt>  can't define
variables for the installation script, because it's a subprocess. But
you can use any binary executable or any script you wrote. Hooks that
has the suffix <tt>.sh</tt> (eg. <file>partition.DEFAULT.sh</file>) must
be bourne shell scripts and are sourced. So it's possible to
redefine variables for the installation scripts.
<p>
This is the complete list of hooks and when they will be called.

<taglist>
      <tag>confdir</tag> <item><p>After some basic initialization,
      all hooks with prefix <tt>confdir</tt> are called. Since the
      configuration directory <file>/fai</file> is not yet mount on
      the install client, these are the only hooks located in
      <tt>$</tt><file>nfsroot/fai/hooks</file> on the install server.
      All other hooks are found in
      <file>/usr/local/share/fai/hooks</file>. The last step is to
      mount the configuration directory to <file>/fai</file> and to
      source the file <file>/fai/hooks/subroutines</file> if it
      exists. Using this file, you can define your own subroutines or
      override the definition of FAI's subroutines.</p>
      </item>

      <tag>setup</tag> <item><p>These hooks are immediately called
      after the configuration directory is mounted to
      <file>/fai</file>. </p> </item>

      <tag>action</tag> <item><p>Hooks called before the variable
      <var>FAI_ACTION</var> is evaluated and it's decided which action
      to perform.</p> </item>

      <tag>sysinfo</tag> <item><p>Called when no installation is
      performed but the action is <tt>sysinfo</tt>.</p>
      </item>

     <tag>backup</tag> <item><p>Called when action is
     <tt>backup</tt>. Here you can define your own backup taks.</p>
     </item>

     <tag>install</tag> <item><p>These hooks are called when the
      <var>FAI_ACTION</var> is <em>install</em> and a automatic
      installation should be performed.</p> </item>

      <tag>defclass</tag> <item><p>Called before defining classes.</p>
      </item>

      <tag>defvar</tag> <item><p>Called before defining variables.</p>
      </item> <tag>partition</tag> <item><p>Called before partitioning
      the local hard disks.</p> </item>

      <tag>mountdisks</tag> <item><p>Called before the local disks are
      mounted to <var>$FAI_ROOT</var>.</p> </item>

    <tag>extrbase</tag> <item><p>Called before the base archive
    <file>base.tgz</file> in unpacked.</p> </item>

      <tag>mirror</tag> <item><p>Called before the Debian mirror would
      be mounted when accessing he Debian mirror via NFS.</p> </item>

      <tag>updatebase</tag> <item><p>Called before the base system is
      upgraded.</p> </item>

      <tag>instsoft</tag> <item><p>Called before the software packages
      are installed.</p> </item>

	<tag>configure</tag> <item><p>Called before the scripts in
      <file>/fai/scripts/</file> are called.</p> </item>

      <tag>chboot</tag> <item><p>Called before the boot device should
      be changed.</p> </item>

      <tag>savelog</tag> <item><p>Called before are log files are save
      to local disk and to the install server.</p> </item>

      <tag>faiend</tag> <item><p>Called when the installation is
      finished, but before the automatic reboot is performed.</p> </item>

 </taglist>

FAI has default jobs for following values of <var>FAI_ACTION</var>.

<list>
	    <item>	      <p>sysinfo</p>	    </item>
	    <item>	      <p>install</p>	    </item>
	    <item>	      <p>backup</p>	    </item>
</list>

If another value is defined, FAI will look for a hook
<file>/fai/hooks/$FAI_ACTION</file> and executes this hook. So you can
easily define your own actions.<p>


All hooks that are called before classes are defined can only use the
following classes: <tt>DEFAULT $HOSTNAME LAST</tt>. If a hook for
class <tt>DEFAULT</tt> should only be called if no hook for class
<tt>$HOSTNAME</tt> is available, insert these lines to the default
hook:

<example>
hookexample.DEFAULT:

#! /bin/sh

# skip DEFAULT hook, if a hook for $HOSTNAME exists
scriptname=$(basename $0 .DEFAULT)
[-f /fai/hooks/$scriptname.$HOSTNAME ] && exit
# here follows the actions for class DEFAULT
.
.
</example>


<p> Some examples what hooks could be used for:

<list>
<item> <p>Use <prgn>ssh</prgn> in the very beginning to verify that
you mounted the configuration from the correct server and not a
possible spoofing host.</p></item>

<item> <p>Pop up a little menu and ask the user, which kind of installation should be performed (eg. CAD
workstation, scientific workstation, workgroup server, Gnome desktop...). Keep in
mind that this won't lead to a fully automatic installation ;-)
</p></item>

<item> <p>Do not mount the configuration directory, instead get a
compressed archive via HTTP or from floppy disk and extract it into a
new ram disk, then redefine <var>$FAI_LOCATION</var>.</p></item>

<item> <p>Load kernel modules before classes are defined
in <file>/fai/class</file>. </p></item>

<item> <p>Send an email to the administrator, if the installation is finished.</p></item>

<item> <p></p></item>
</list>

<sect id=errors>Looking for errors<p>
If the client can't succsessfully boot from the network card, use
<manref name="tcpdump" section="8"> to look for ethernet packets
between the install server and the client. Search also for entries in
several log files made by <manref name="in.tftpd" section="8"> and
<manref name="bootpd" section="8">:

<example>egrep "tftpd|bootpd" /var/log/*</example>

The BOOTP daemon can also be started in debug modus:
<example># bootpd -d7</example>


If the installation process stops or even it finishes, parse all log files for errors using:
<example>
# egrep "no such variable|bad variable|E:|ERROR" *.log
</example>

Sometimes the installation seems to stop, but there's only a
postinstall script of a software package that requires manual input
from the console. Change to another virtual terminal and look which
process is running (<manref name="top" section="1">, <manref
name="pstree" section="1">). You can add <tt>debug</tt> to <tt>FAI_FLAGS</tt>,
so the installation process will show all output from the postinst
scripts on the console. Don't hesitate to send an email to the
mailing list or to <email>fai@informatik.uni-koeln.de</email> if you
have any questions. Sample log files from successful
installed computers are available on the FAI homepage.

<chapt id=sparc>FAI on SUN SPARC<p>
Even FAI is architecture independent, there are some packages, that
are only available for certain architectures (eg. silo, sparc-utils).

SUN can boot from their boot prompt and don't need a boot floppy. To boot a SUN you must use:
<example>boot net</example>

Read the FAQ at <httpsite>http://www.ultralinux.org</httpsite> for
more information. You have to convert the kernel image from ELF format
to a.out format. Therefore use the program <prgn>elftoaout</prgn>
(mentioned in the FAQ). The symlink to the kernel image to be booted
is not the host name. Look at the FAQ for more information.


<!--
<chapt id=hints>Various Hints<p>

check for bad blocks:

$ROOTCMD dpkg -l

One of the most important feature of FAI are the classes. Using
classes you can share configuration data among multiple
clients. Details are described in <ref id="classes">.
All defined classes are listed in <file>/tmp/FAI_CLASSES</file>.

The only task, which has to be done manually for new hardware, is to
assign the MAC address to a hostname and to an IP address and to
define classes for this host, or all host which match a certain name
(look at <file>class/S01alias.sh</file>).


Using cfengine, you can easily edit any existing text file or remove
files, create links or directories.  It has a rich set of editing
commands (AppendIfNoSuchLine, ReplaceAll, LocateLineMatching,
InsertLine, HashCommentLinesContaining,...) and support the use of
classes.
 
<p>If you have to create a new file or append many line to an exiting
one, it's better to use perl or a shell script. Cfengine is also
sensitive to undefined variables. A cfengine script does not get
executed, if any of the used variables is undefinded. Hence, it's not
useful if you have a variable number of parameters in your
configuration (a famous example are the DNS server for
<file>/etc/resolv.conf</file>).


There's a tradeoff between writing a few large script, which
use definitions by cases or to write a single script for each
class. It may also be useful to write two scripts, that together
perform one task. Try to find the right way, and let us participate in
your scripts.

general hints:

all in one config file, or multiple small config files. Ypou can
choose !

FAI-BOOTPART 
-->
</book>
</debiandoc>


<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:nil
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-declaration:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
