Installing yunohost automatically using Debian, PXE and preseed


Installing yunohost automatically using Debian, PXE and preseed

In this article i will cover the process used to install debian and yunohost using network boot and PXE on debian, this article can be used to automate the Debian install process with our without yunohost.

Lets start by installing the correct packages:

apt-get update
apt-get install isc-dhcp-server
apt-get install tftp-hpa 
apt-get install tftp
apt-get install apache2

Setup the DHCP server

Now we need to first configure the DHCP server by editing "/etc/dhcp/dhcpd.conf":

#
# Sample configuration file for ISC dhcpd for Debian
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
option domain-name "weho.st";
option domain-name-servers 8.8.8.8, 8.8.4.4;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
#authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.

#subnet 10.152.187.0 netmask 255.255.255.0 {
#}

# This is a very basic subnet declaration.

#subnet 10.254.239.0 netmask 255.255.255.224 {
#  range 10.254.239.10 10.254.239.20;
#  option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}

# This declaration allows BOOTP clients to get dynamic addresses,
# which we don't really recommend.

#subnet 10.254.239.32 netmask 255.255.255.224 {
#  range dynamic-bootp 10.254.239.40 10.254.239.60;
#  option broadcast-address 10.254.239.31;
#  option routers rtr-239-32-1.example.org;
#}

# A slightly different configuration for an internal subnet.
#subnet 10.5.5.0 netmask 255.255.255.224 {
#  range 10.5.5.26 10.5.5.30;
#  option domain-name-servers ns1.internal.example.org;
#  option domain-name "internal.example.org";
#  option routers 10.5.5.1;
#  option broadcast-address 10.5.5.31;
#  default-lease-time 600;
#  max-lease-time 7200;
#}

# Hosts which require special configuration options can be listed in
# host statements.   If no address is specified, the address will be
# allocated dynamically (if possible), but the host-specific information
# will still come from the host declaration.

#host passacaglia {
#  hardware ethernet 0:0:c0:5d:bd:95;
#  filename "vmunix.passacaglia";
#  server-name "toccata.fugue.com";
#}

# Fixed IP addresses can also be specified for hosts.   These addresses
# should not also be listed as being available for dynamic assignment.
# Hosts for which fixed IP addresses have been specified can boot using
# BOOTP or DHCP.   Hosts for which no fixed address is specified can only
# be booted with DHCP, unless there is an address range on the subnet
# to which a BOOTP client is connected which has the dynamic-bootp flag
# set.
#host fantasia {
#  hardware ethernet 08:00:07:26:c0:a5;
#  fixed-address fantasia.fugue.com;
#}

# You can declare a class of clients and then do address allocation
# based on that.   The example below shows a case where all clients
# in a certain class get addresses on the 10.17.224/24 subnet, and all
# other clients get addresses on the 10.0.29/24 subnet.

#class "foo" {
#  match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
#}

#shared-network 224-29 {
#  subnet 10.17.224.0 netmask 255.255.255.0 {
#    option routers rtr-224.example.org;
#  }
#  subnet 10.0.29.0 netmask 255.255.255.0 {
#    option routers rtr-29.example.org;
#  }
#  pool {
#    allow members of "foo";
#    range 10.17.224.10 10.17.224.250;
#  }
#  pool {
#    deny members of "foo";
#    range 10.0.29.10 10.0.29.230;
#  }
#}

#allow PXE 
allow booting;

# in this example, we serve DHCP requests from 10.0.1.(20 to 30)
# and we have a router at 192.168.0.1
subnet 10.0.1.0 netmask 255.255.255.0 {
  range 10.0.1.20 10.0.1.30;
  option broadcast-address 10.0.1.255;
  option routers 10.0.1.1;             # our router
# Optional Domain name
  option domain-name "network.local";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
# the TFTP server
  next-server 10.0.1.254;  
# file to download from the tftp serveer              
  filename "pxelinux.0"; 
}

After this you need to restart the service:

/etc/init.d/isc-dhcp-server restart

Then we should check DHCP is running:

  # pgrep -lf dhcpd
  32277 /usr/sbin/dhcpd -q

Setting up the TFTP server

Now we configure the TFTP server by checking if the interface binding is correct and which directory it is using in "/etc/default/tftpd-hpa" (default directory is "/srv/tftp" for the files it serves):

  TFTP_USERNAME="tftp"
  TFTP_DIRECTORY="/srv/tftp"
  TFTP_ADDRESS="0.0.0.0:69"
  TFTP_OPTIONS="--secure"

Ignore older Web sites that instruct you to insert something like 'RUN_DAEMON="yes"'.

After each modification of the above configuration file, restart the TFTP server with

/etc/init.d/tftpd-hpa restart

On jessie the directory /srv/tftp will be automatically created. This means the next two steps are not necessary if you use jessie.

Initially, on pre-jessie versions, this might fail with a message like

  Restarting HPA's tftpd: in.tftpd/srv/tftp missing, aborting.

Therefore, as root, create the directory /srv/tftp. Restart the TFTP daemon. Check that it is actually running:

  # pgrep -lf tftpd
  12555 /usr/sbin/in.tftpd

It is useful to test your TFTP server with a TFTP client, you may simply use the tftp-hpa package for this purpose:

  # cd /tmp
  # uname -a >/srv/tftp/test
  # tftp 127.0.0.1
  tftp> get test
  tftp> quit
  # diff test /srv/tftp/test
  (nothing, they are identical)

Reboot the Client. You should see error messages starting with

  PXE-T01: File not found

which is quite correct since we did not yet provide any files.

Get the boot image

Download netboot/netboot.tar.gz from a Debian mirror (see http://www.debian.org/distrib/netinst#netboot).

Unpack netboot.tar.gz to /srv/tftp, which should now contain

  debian-installer/
  pxelinux.0@
  pxelinux.cfg@
  version.info

It may be necessary to chmod -R a+r * to make all files in this directory readable for the TFTP daemon.

Restart the TFTP daemon, then reboot the Client. You should get to a Debian install screen.

If you lookup into /var/log/daemon.log, you will see what has been downloaded from the TFTP server by the PXE bootloader, and then by SYSLINUX:

Jun  3 09:53:51 server tftpd.in[32698]: Serving pxelinux.0 to 192.168.0.3:2070
Jun  3 09:53:51 server tftpd.in[32698]: Serving pxelinux.0 to 192.168.0.3:2071
Jun  3 09:53:51 server tftpd.in[32698]: Serving pxelinux.cfg/44454c4c-5600-1048-8051-c7c04f575831 to 192.168.0.3:57089
Jun  3 09:53:51 server tftpd.in[32698]: Serving pxelinux.cfg/40-01-b1-1c-47-44-1e to 192.168.0.3:57090
Jun  3 09:53:51 server tftpd.in[32698]: Serving pxelinux.cfg/default to 192.168.0.3:57090
Jun  3 09:53:51 server tftpd.in[32698]: Serving bootmenu.txt to 192.168.0.3:57095

The PXE loader (the firmware in the BIOS or the network controller) try to load into that order:

  • pxelinux.0 (or more exactly, what you told it to download in the 'filename' field of the DHCP response)

Then SYSLINUX/PXELINUX will try to search its configuration at different paths, from the most specific to the least:

  • pxelinux.cfg/GUID
  • pxelinux.cfg/MAC
  • pxelinux.cfg/default

And if the configuration menu depends on other configuration items, they are also downloaded. Debian will at least need the 'bootmenu.txt' file which is the main menu.

By default you arrive at the graphical Debian install start menu screen. Press 'enter' to start intallation. Be patient: it may last over a minute before the next screen ('Select a language') appears.

Debian boot process configuration

Now we have a bootable generic Debian installer lets add the preseed and discuss the editing the boot menu:

First we need to have a preseed file that the machine can download so we need to create a file in the apache root directory ("/var/www/preseed.cfg" and add the following to it"

d-i debian-installer/language string en
d-i debian-installer/country string US
d-i debian-installer/locale string en_US
# Keyboard selection.
d-i console-keymaps-at/keymap select us
d-i keyboard-configuration/xkb-keymap select us
d-i netcfg/choose_interface select auto
d-i netcfg/dhcp_failed note
d-i netcfg/dhcp_options select Configure network manually
d-i netcfg/disable_dhcp boolean false
d-i netcfg/get_hostname string yunohost
d-i netcfg/get_domain string yunohost.org
d-i netcfg/get_domain seen true
d-i mirror/country string manual
d-i mirror/http/hostname string ftp.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Paris
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string 0.fr.pool.ntp.org
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select multi
#d-i partman-auto/expert_recipe string                           \
#        condpart ::                                             \
#        300 4000 7000 ext3                                      \
#                $primary{ } $bootable{ }                        \
#                method{ format } format{ }                      \
#                use_filesystem{ } filesystem{ ext3 }            \
#                mountpoint{ / }                                 \
#        .                                                       \
#        64 512 300% linux-swap                                  \
#                method{ swap } format{ }                        \
#        .                                                       \
#        100 10000 1000000000 ext3                               \
#                method{ keep } format{ }                \
#                use_filesystem{ } filesystem{ ext3 }            \
#                mountpoint{ /var }                            \
#        .
d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean false
d-i partman/confirm_nooverwrite boolean true
d-i passwd/root-password-crypted password $1$6xBdkGvE$8nLCNRxwABespdFJniEiX0
d-i passwd/make-user boolean fasle
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Amsterdam
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string 0.debian.pool.ntp.org
d-i apt-setup/non-free boolean true
d-i apt-setup/contrib boolean true
d-i apt-setup/local0/repository string \
    http://repo.yunohost.org/ megusta main
d-i apt-setup/local0/key string http://repo.yunohost.org/yunohost.asc
d-i debian-installer/allow_unauthenticated string true
tasksel tasksel/first multiselect standard, web-server, ssh-server
d-i pkgsel/include postfix yunohost
popularity-contest popularity-contest/participate boolean false
debconf debconf/frontend select Noninteractive
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i finish-install/reboot_in_progress note
d-i cdrom-detect/eject boolean true
d-i debian-installer/exit/reboot boolean true
slapd slapd/domain string yunohost.org
slapd shared/organization string yunohost
slapd slapd/password1 password yunohost
slapd slapd/password2 password yunohost
postfix    postfix/main_mailer_type    select Internet Site
postfix postfix/mailname string /etc/mailname
mysql-server-5.5 mysql-server/root_password password yunohost
mysql-server-5.5 mysql-server/root_password_again password yunohost
samba-common samba-common/workgroup string WORKGROUP
samba-common samba-common/workgroup boolean true
nslcd    nslcd/ldap-bindpw    password    
nslcd    nslcd/ldap-starttls    boolean    false
nslcd    nslcd/ldap-reqcert    select    
nslcd    nslcd/ldap-uris    string    ldap://localhost/
nslcd    nslcd/ldap-binddn    string
nslcd   nslcd/ldap-base      string dc=yunohost,dc=org
proftpd-basic    shared/proftpd/inetd_or_standalone    select standalone
iptables-persistent     iptables-persistent/autosave_v6 boolean false
iptables-persistent     iptables-persistent/autosave_v4 boolean false
libnss-ldapd    libnss-ldapd/nsswitch multiselect group, passwd, shadow

Now we want to make it bootable so lets create a new menu item for the grub menu and make it the default option:

Create the file "/srv/tftp/debian-installer/amd64/boot-screens/yunohost.cfg" and add the following to it:

default yunohost
label yunohost
        menu label ^Install yunohost
        menu default
        kernel debian-installer/amd64/linux
        append vga=788 initrd=debian-installer/amd64/initrd.gz  preseed/url=http://10.0.1.254/preseed.cfg --- quiet

Notice the preseed/url line ,make sure you change that is set to the webserver where your preseed file is in the case above we are using the dhcp servers apache instance for that.

If you want the install to go unatended you can use the following configuration in the "/srv/tftp/debian-installer/amd64/boot-screens/yunohost.cfg" instead of the one above:

default yunohost
label yunohost
        menu label ^Install yunohost Debien Jessie
        menu default
        kernel debian-installer/amd64/linux
        append vga=788 initrd=debian-installer/amd64/initrd.gz preseed/url=http://10.0.1.254/wehost.preseed locale=en_US console-setup/ask_detect=false console-setup/layoutcode=us keyboard-configuration/xkb-keymap=us interface=eth0 hostname=hostname domain=example.com --- quiet

Note that the hostname should be set via DHCP as it will replace the hostname above (the hostname above does not need to change from hostname.example.com but you can change it to your own domain if you would like.

now we need to remove the default line from the original default item which is install debian by editing "/srv/tftp/debian-installer/amd64/boot-screens/txt.cfg" and removeing or commenting out the line:

menu default

Last but not least in the file "/srv/tftp/debian-installer/amd64/boot-screens/menu.cfg" add an include statement for yunohost.cfg at the top of the file like below:

menu hshift 7
menu width 61

menu title Debian GNU/Linux installer boot menu
include debian-installer/amd64/boot-screens/stdmenu.cfg
include debian-installer/amd64/boot-screens/yunohost.cfg
include debian-installer/amd64/boot-screens/txt.cfg
include debian-installer/amd64/boot-screens/amdtxt.cfg
include debian-installer/amd64/boot-screens/gtk.cfg
include debian-installer/amd64/boot-screens/amdgtk.cfg
 menu begin advanced
    menu label ^Advanced options
       menu title Advanced options
       include debian-installer/amd64/boot-screens/stdmenu.cfg
       label mainmenu
               menu label ^Back..
               menu exit
       include debian-installer/amd64/boot-screens/adtxt.cfg
       include debian-installer/amd64/boot-screens/amdadtxt.cfg
       include debian-installer/amd64/boot-screens/adgtk.cfg
       include debian-installer/amd64/boot-screens/amdadgtk.cfg
menu end
label help
       menu label ^Help
       text help
   Display help screens; type 'menu' at boot prompt to return to this menu
       endtext
       config debian-installer/amd64/boot-screens/prompt.cfg
include debian-installer/amd64/boot-screens/spk.cfg
include debian-installer/amd64/boot-screens/amdspk.cfg
include debian-installer/amd64/boot-screens/spkgtk.cfg
include debian-installer/amd64/boot-screens/amdspgtk.cfg

Now we are finished and should boot, ask a few questions about the country settings and start automaticlly installing the operating system and packages.

Added customization removing useless items

i edited the file "/srv/tftp/debian-installer/amd64/boot-screens/menu.cfg" as seen below to get rid of the help and advanced options menu:

menu hshift 7
menu width 61

menu title Debian GNU/Linux installer boot menu
include debian-installer/amd64/boot-screens/stdmenu.cfg
include debian-installer/amd64/boot-screens/yunohost.cfg
include debian-installer/amd64/boot-screens/txt.cfg
include debian-installer/amd64/boot-screens/amdtxt.cfg
include debian-installer/amd64/boot-screens/gtk.cfg
include debian-installer/amd64/boot-screens/amdgtk.cfg
# menu begin advanced
#    menu label ^Advanced options
#       menu title Advanced options
#       include debian-installer/amd64/boot-screens/stdmenu.cfg
#       label mainmenu
#               menu label ^Back..
#               menu exit
#       include debian-installer/amd64/boot-screens/adtxt.cfg
#       include debian-installer/amd64/boot-screens/amdadtxt.cfg
#       include debian-installer/amd64/boot-screens/adgtk.cfg
#       include debian-installer/amd64/boot-screens/amdadgtk.cfg
#menu end
#label help
#       menu label ^Help
#       text help
#   Display help screens; type 'menu' at boot prompt to return to this menu
#       endtext
#       config debian-installer/amd64/boot-screens/prompt.cfg
include debian-installer/amd64/boot-screens/spk.cfg
include debian-installer/amd64/boot-screens/amdspk.cfg
include debian-installer/amd64/boot-screens/spkgtk.cfg
include debian-installer/amd64/boot-screens/amdspgtk.cfg

Adding a static host entry, setting hostname and ip address from the DHCP server:

in "/etc/dhcp/dhcpd.conf" add the following at the end of the file to set a static lease for a machine and its future hostname:


# STATIC LEASES testsrv001

host testsrv001{
hardware ethernet 36:34:32:33:61:63; # MAC is needed to map the address to the right host. 
fixed-address 10.0.1.100;
option host-name "testsrv001";
}

changing the boot menu theme

Editing the file "/srv/tftp/debian-installer/amd64/boot-screens/stdmenu.cfg" will allow you to change the looks of the text boot menu such as I did:

See our test customization below:

Before (with customized menu): After (with customized menu):

Sources:

https://wiki.debian.org/PXEBootInstall

https://www.debian.org/releases/stable/i386/apbs02.html.en


Written by Matthew Frost on Tuesday December 1, 2015
Tags: