[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

automatic installation



Hi,

while people is endlessly discussing about boot floppies and sophisticated
installation tools I have just done my first totally automatic installation
of a debian system using my own install program and my dpkg-getconfig tool.

I have installed only a very minimal system but this is a proof of concept
that a completely automatic installation would be feasible now. I will 
describe how it can be done.


BOOT FLOPPIES

In my opinion putting a kernel and a root image in a single 1.44MB rescue
floppy is an exercise in futility. We should instead use two separate
floppies for kernel and compressed root, which would allow using a 4MB
ramdisk with a lot of goodies inside. The two floppies can be combined in
a single 2.88MB image for booting off a cdrom.

With a larger root filesystem we could build a much better rescue with the
real programs instead of the the poor emulations which are in the current
floppy. My boot floppies contain zsh, emacs, gpm, awk, grep, sed, whiptail
and other useful tools which can make life much easier when one has to work
in an emergency. Shell history and mouse makes the difference!


INSTALL PROGRAM

An install program written entirely in C can maybe save some disk space but
is very rigid and difficult to understand and customize. In my opinion this
kind of things should be implemented as shell script whenever possible.
They are much easier to write, to debug and change if needed.

Another limitation of the current install program is that it has been
designed only for interactive use by dumb users and it can't be used for
any sort of automatic installation. Unfortunately there is no other way to
install debian and therefore automatic installation is not allowed.

So I wrote my own install program with the following goals:

  * Totally automatic installation. It should be possible, in most cases,
    to just type a command with the proper parameters and have the program
    run without requiring any other interaction.

  * Automatic configuration of most common things, like keyboard, mouse,
    cdrom, root passwd, network, hosts, networks, resolver, nis, etc.

  * Use of distributed configuration files to specify installation options.
    For example one could store on a server a site configuration plus
    specific files for every machine and specify only the server ip and
    the hostname in order to install any of these machines.

  * Installation option can by given in different ways: from boot prompt,
    from command line, from configuration files and from user interaction.

  * Predefined program defaults for values not explicitly supplied.

  * Automatic selection of preconfigured installation profiles.

  * Automatic loading of network modules. Selected modules can be stored
    directly in the root image, or they can be loaded from a third floppy.
    Pcmcia is currently not supported because I don't have a pcmcia system
    for testing, but it should be possible to add it.

  * Automatic detection and partitioning of the harddisk, if this can be
    done safely. Other cases may require manual fdisk and formatting.

  * Installation from a variety of sources: currently supported are
    cdrom, local filesystem and nfs. It should be possible to add ftp
    and http.

  * Automatic installation of all selected packages without requiring
    interaction with dselect and package selection. This means that apt
    must be configured automatically during the first installation step.

  * Automatic execution of the second installation step after the base
    system has been unpacked, without needing to reboot the system.

  * Automatic configuration of the installed packages. This is not yet
    fully implemented because it requires changes to many packages,
    however it has been succesfully tested with a few packages.

My install program is written as zsh script. It makes use of external tools,
like grep, awk, sed, and of whiptail to present nicely formatted messages
and user interaction dialogs. I choose zsh instead of ash because it is 99%
compatible with sh and bash, it has history and completion and it is much
smaller than bash. I didn't ever consider using C or any other compiled
language. Debugging a C program in a 4MB ramdisk is only for masochists.

This are the synopsis of the install script and the corresponding file
configuration options:

Usage: install [-?|-h|--help] [options...]

options:

    -b|--broadcast <broadcast>                  BROADCAST
    -c|--config <config_name>                   CONFIG_NAME
    -C|--cdrom <cdrom_device>                   CDROM
    -d|--domain <domain>                        DOMAINNAME
    -E|--encrypted-passwd <epasswd>             ROOT_EPASSWD
    -f|--interface|--if <interface>             INTERFACE
    -g|--gateway|--gw <gateway>                 GATEWAY
    -h|--hostname|--host <host[.domain]>        HOSTNAME, DOMAINNAME
    -i|--ipaddr|--ip <ipaddr>                   IPADDR
    -I|--install-ip|--iip <ipaddr>              INSTALL_IP
    -k|--keyboard|--kbd <lang>          	KEYBOARD
    -l|--logfile|--log <filename>               LOGFILE
    -L|--lilo mbr|root|none                     LILO
    -m|--netmask|--mask <netmask>               NETMASK
    -M|--mouse <mouse>                          MOUSE
    -n|--network|--net <network>                NETWORK
    -N|--nameserver|--ns|--dns <nameserver>     NAMESERVER
    -O|--boot-other-os|--other-os <boot...>     BOOT_OTHER_OS
    -p|--profile <profile>                      PROFILE
    -P|--root-passwd|--passwd <passwd>  	ROOT_PASSWD
    -r|--root-partition|--root <device[:size]>  ROOT_PARTITION
    -s|--source <source>                        INSTALL_SOURCE
    -t|--target <target_device>                 TARGET_DEVICE
    -u|--utc|--gmt                              HWCLOCK_UTC
    -v|--verbose <level>                        VERBOSE
    -w|--swap-partition|--swap <device[:size]>  SWAP_PARTITION
    -x|--xserver <xserver>                      XSERVER
    -y|--ypserver <ypserv[:nisdomain]>  	YPSERVER
    -Y|--no-confirm|--yes                       NO_CONFIRM
    -z|--timezone <timezone>                    TIMEZONE
    --install-mode <mode>                       INSTALL_MODE
    --install-program <program>                 INSTALL_PROG
    --modules <module>... .                     MODULES
    --mount <mount>... .                        MOUNTS
    --nisdomain|--nis <nisdomain>               NISDOMAIN
    --packages|--pkg <pkgdef...>                PACKAGES
    --root-size|--rs <size>                     ROOT_PART_SIZE
    --shadowpass|--shadow                       SHADOWPASS
    --swap-size|--ss <size>                     SWAP_PART_SIZE

    source := cdrom | /pathname | /device:/pathname | host:/pathname
    mouse  := device:type[:gpmargs[:speed]]
    module := modname [args...]
    mount  := device mountpoint [type options dump pass]
    boot   := label=device
    pkgdef := @@profile | @task | [+|-]package


The script collects the install options from various sources, boot prompt,
command-line, config files stored in various places, and asks important
missing parameters to the user. If all the required information has been 
supplied it starts the installations and does the following tasks:

    load the specified modules
    find the cdrom
    choose the installation source
    start the network if needed
    update local time from server if possible (not yet working)
    mount the source
    read more configuration defaults from the source location
    choose the target root and swap partitions
    ask user to confirm the configuration, unless install_mode=auto
    create the swap partition if needed
    format and mount the swap
    create and format the target partition if needed
    mount the target partition
    create the new fstab
    mount extra partitions if needed
    find the base files
    install the rescue, drivers and base files
    install optionals extra and config files
    install the kernel image
    configure the keyboard
    configure the mouse
    configure the cdrom
    configure the timezone
    configure the network
    configure the nis if needed
    configure lilo and run it if required
    configure modules
    set the root passwd
    configure the X server
    configure apt and dpkg
    configure the second step of the installation
    save the configuration values and the logfile
    restart the system and execute the second step of the installation

Some of the above actions are executed directly in the target system with a
chroot using the installed programs and libraries, for example encrypting
the root passwd with perl or setting dpkg selections.

It is also interesting to note that the second part of the installation
doesn't require a system reboot but only a chroot in the target and a restart
of the new init with the new inittab and installed programs. This is done by
a modified version of the busybox (the rescue init) which in response to a
certain signal unmounts all filesystem, including /proc, and does a chroot
in the target root and the exec of the new init. Then things go on as usual
with daemons and logins started by init.

Also the second phase of the installation has been implemented in a much
cleaner way. The original debian installation installs a bunch of files in
the root directory, modifies the root shell initialization scripts and 
finally changes the inittab so that a root login is started automatically
by init and the install script is run from root's .bash_profile.
The install script, after making a lot of annoying questions, deletes all the
installation programs and restore the original inittab, so that if you abort
the process in the middle you have lost the install program without having
completed the installation.

In my opinion this is done in the wrong way. Self-deleting programs and
self-modifying code are the hacker's way of doing things. A much better and
cleaner solution is to put the install programs and files in a separate
directory and use the /etc/initscript method to start automatically the
install program on the first console. After the system is installed, and
only then, the /etc/initscript is removed and a normal login is started.
This the /etc/initscript I used to start automatically the installer on tty1:

#
# initscript   initscript used by the DZ Debian installer to run
#              automatically the install.sh script on tty1 if the
#              system is not completely installed. This script is
#              removed by install.sh when the installation is done.
#
#              /etc/initscript is executed by init(8) for every
#              program it wants to spawn like this:
#
#              /bin/sh /etc/initscript <id> <level> <action> <program>
#
# Written by Massimo Dal Zotto <dz@cs.unitn.it>.

# If spawned with id '1' and /etc/install/install.sh exists run it
if [ "$1" = 1 -a -x /etc/install/install.sh ]; then
    exec /etc/install/install.sh < /dev/tty1 > /dev/tty1 2>&1
fi

# Normal action, execute the original program
eval exec "$4"


The install.sh script starts apt or deselect and executes the optional
system.preinst and system.postinst scripts installed in the first step.


PACKAGE CONFIGURATION

This is the most difficult part to handle, because many packages and many
debian tools insist in asking questions on stdout and this makes impossible
any sort of automatic installation. At the moment I have modified the
initscripts of a few packages to make use of my dpkg-getconfig interface
which I proposed some weeks ago but nobody has approved.

It works fine, I define CONFIG_INSTALL_MODE=auto and all the configuration
questions are answered using only the values stored in the config db.
I had also to made a small pacth to dpkg to force it to keep existing
configuration files without questions if this is wanted by the user in
case of automatic installation. The config files are normally installed
from the config.tgz file in step 1, while the extra.tgz could contain non
packaged programs or a full dump of a complete installation. Of course
this is contrary to the dpkg philosophy, but given the way packages are
configured this is currently the only way to do automatic installations.

After the installation finished I logged in as root and found all important
installation messages nicely ordered in my mailbox. None had been lost.
And I never had to touch the keyboard after typing the initial 'install'
command.

My solution is not intended for the general or dumb user, though it could
be used to provide an automatic default installation for non expert people.
My idea is to supply most options from config files or command-line and ask
as few questions as possible to the user.
This is a completely different approach to the problem of debian installation
and could be provided as an alternative to the current install program for
system andministrator who need to install many similar systems.

The ideal solution would be to integrate the two approaches and have a
unique flexible installer which could be used in both ways. Many ideas
could however be applied to the standard installer, for exmple the chroot
init, /etc/initscript and the automatic configuration of many files during
the first step.


-- 
Massimo Dal Zotto

+----------------------------------------------------------------------+
|  Massimo Dal Zotto               email: dz@cs.unitn.it               |
|  Via Marconi, 141                phone: ++39-0461534251              |
|  38057 Pergine Valsugana (TN)      www: http://www.cs.unitn.it/~dz/  |
|  Italy                             pgp: finger dz@tango.cs.unitn.it  |
+----------------------------------------------------------------------+


Reply to: