Back to basics – Kickstart your anaconda file (your systems blueprint)

The final piece in this jigsaw puzzle of network installation madness is the kickstart file.  It is the blueprint from which your RHEL/CentOS/Fedora/[enter distribution name here] is built from.

My preferred way of creating the initial template is to perform a manual installation and then to tweak the resultant /root/anaconda-ks.cfg file to my needs.  This is also the recommended method in the Red Hat documentation.  By doing it this way you can avoid some of the pitfalls of parameter changes within the kickstart script which may alter between releases of RHEL/CentOS.

So, here is what mine currently looks like;

[root@rhc-server ~]# cat anaconda-ks.cfg 
#version=RHEL7
# System authorization information
auth --enableshadow --passalgo=sha512

# Use CDROM installation media
cdrom
# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=uk --xlayouts='gb'
# System language
lang en_GB.UTF-8

# Network information
network  --bootproto=dhcp --device=ens3 --ipv6=auto --activate
network  --hostname=rhc-server
# Root password
rootpw --iscrypted $6$1RcgxNlQgKVJAEHj$dcQtZ3Jhe8vw1Aj3rB8zyLl2tTumL88czrcJo4nyUeashp7/rJvE3lFOmWsu9Ml.AZw7PSx5u1M0IGeTLa5ds.
# System timezone
timezone Europe/London --isUtc
user --groups=wheel --name=toby --password=$6$wRgpQD/lrXaqF8cW$PdCIE3CdBq5PxWYejCSpWFVuiMGUIs.eKQXPR5pDeHTmKp3/10qazLDVaCJcpp7zenDKWNqWPXrYjEGRJsAK41 --iscrypted --gecos="toby"
# System bootloader configuration
bootloader --location=mbr --boot-drive=sda
autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel 

%packages
@core

%end

Over time, the kickstart file will evolve, and it is a wise man or woman who validates the configuration before actually trying to use the file.  But, having said that, the ksvalidator utility (as the documentation states), can only validate things so far and it will not look at the %pre, %post or %packages sections.  It also doesn’t guarantee a successful install, it just provides a sanity check before you really test it.

So anyway, here is my slightly modified version of the kickstart file, which I have saved in a directory which is accessible via the web server.

[root@rhc-server ks]# cat /var/www/html/ks/basic.ks 
# System authorization information
auth --enableshadow --passalgo=sha512

# Use installation files via http
install
url --url=http://rhc-server.lab.tobyheywood.com/centos7/

# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=vda

# Keyboard layouts
keyboard --vckeymap=uk --xlayouts='gb'

# System language
lang en_GB.UTF-8

# Network information
network  --bootproto=dhcp --device=ens3 --ipv6=auto --activate

# Root password
rootpw --iscrypted $6$1RcgxNlQgKVJAEHj$dcQtZ3Jhe8vw1Aj3rB8zyLl2tTumL88czrcJo4nyUeashp7/rJvE3lFOmWsu9Ml.AZw7PSx5u1M0IGeTLa5ds.

# System timezone
timezone Europe/London --isUtc
user --groups=wheel --name=toby --password=$6$wRgpQD/lrXaqF8cW$PdCIE3CdBq5PxWYejCSpWFVuiMGUIs.eKQXPR5pDeHTmKp3/10qazLDVaCJcpp7zenDKWNqWPXrYjEGRJsAK41 --iscrypted --gecos="toby"

# System bootloader configuration
bootloader --location=mbr --boot-drive=vda  --iscrypted --password=grub.pbkdf2.sha512.10000.AD234D09B3DDE933C60C46AAA52B95DBB2D48D766E8DDD1852FBF373C8D0474401E4FD6D1D997B1D169B35C69D7776B3FCAC6A3BB6338B0910EB0899B0452BFE.531AE5C20F8CA36DB321770537C0C872B4670EB60F9461A85D2D429C36BAC80F12EBDCC85A6514889332B70BBA780285F84DFDCA57A3B92C3F9FA7387F9F59A0

autopart --type=lvm
# Partition clearing information
clearpart --none --initlabel 

# Firewall & SELinux settings
firewall --enabled --ssh
selinux --enforcing

# Create yum .repo file
repo --name=TheLab --baseurl=http://rhc-server.lab.tobyheywood.com/centos7/ --install

%packages
@core

%end

reboot

I have highlighted all lines that I have modified and will explain any I have added along the way.

So what did I change?

  • Line 6 & 7 – These two lines are required to specify where the install files are actually located.  Note this does have to be the same structure as the ISO (just in case you were wondering).
  • Line 11 – Just in case we have any other disks available to us, we focus the installation to use only the first virtIO disk it sees.  Another point to make here is that device naming is not guaranteed and the documentation dues make some alternative suggestions here.
  • Line 30 – I updated the boot-drive parameter so that it correctly reflected the hard drive device naming and also followed a best practice of implementing a password for the grub2 bootloader.
  • Line 37 & 38 – I explicitly enable selinux in enforcing mode and also set a very basic firewall rule
  • Line 41 – Rather than having to go in and modify my own yum .repo file you can use this option with the install flag to set this up for you

Not many changes but hopefully it provides a good idea of what is needed to get a working install fully operational.

Validating your kickstart script

As mentioned earlier, it is worth validating you kickstart script simply as a sanity check, this can be done as follows;

Installing the ksvalidtor app

[root@rhc-server ks]# yum install pykickstart
Loaded plugins: fastestmirror
baselocal                                                                                                            | 3.6 kB  00:00:00     
(1/2): baselocal/group_gz                                                                                            | 155 kB  00:00:00     
(2/2): baselocal/primary_db                                                                                          | 2.8 MB  00:00:00     
Determining fastest mirrors
Resolving Dependencies
--> Running transaction check
---> Package pykickstart.noarch 0:1.99.66.6-1.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================
 Package                           Arch                         Version                               Repository                       Size
============================================================================================================================================
Installing:
 pykickstart                       noarch                       1.99.66.6-1.el7                       baselocal                       328 k

Transaction Summary
============================================================================================================================================
Install  1 Package

Total download size: 328 k
Installed size: 1.5 M
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : pykickstart-1.99.66.6-1.el7.noarch                                                                                       1/1 
  Verifying  : pykickstart-1.99.66.6-1.el7.noarch                                                                                       1/1 

Installed:
  pykickstart.noarch 0:1.99.66.6-1.el7                                                                                                      

Complete!

Running ksvalidator

Note.  If there is no output after running the command it is a good sign!  Just for good measure I also like to echo out the return code following the command just to give me that extra warm feeling :).

[root@rhc-server ks]# ksvalidator /var/www/html/ks/basic.ks 
[root@rhc-server ks]# echo $?
0

The last thing we need to do is make sure this will be used, or as a bare minimum, that it can be used.  So lets edit the pxelinux.cfg/default file;

[root@rhc-server ks]# cat /tftpboot/pxelinux.cfg/default 
DEFAULT menu.c32
PROMPT 0
TIMEOUT 300
ONTIMEOUT localdisk
MENU TITLE PXE Network Boot

LABEL localdisk
    MENU LABEL ^Local Hard Drive
    MENU DEFAULT
    LOCALBOOT 0

LABEL Install_CentOS_7_2
    MENU LABEL CentOS 7.2
    KERNEL centos7/vmlinuz
    APPEND initrd=http://rhc-server.lab.tobyheywood.com/centos7/images/pxeboot/initrd.img inst.repo=http://rhc-server.lab.tobyheywood.com/centos7 inst.geoloc=0

LABEL Install_CentOS_7_2_KS
    MENU LABEL CentOS 7.2 (KS)
    KERNEL centos7/vmlinuz
    APPEND initrd=http://rhc-server.lab.tobyheywood.com/centos7/images/pxeboot/initrd.img inst.ks=http://rhc-server.lab.tobyheywood.com/ks/basic.ks inst.geoloc=0

The key thing here is that I have done away with the “repo.inst” parameter and it’s associated value and replaced it with the  “inst.ks” parameter, which points to the kickstart file I created earlier.

And that is it, we have a very basic automated installation of CentOS/RHEL 7 over the network without having to pick up a single ISO image and burn it to disk, or USB stick, or manually mount it to a VM.

Reference Material

Credit to Will Scullin, who made his Blueprint image available on Flickr.com.

Back to basics – Setting up a TFTP server & PXE (PreBoot Environment)

Right then.  So far (if you have been following along) we have done the following;

  • Created a local yum repository based on the installation media on the initial server in our sand boxed lab
  • Installed and setup DNS with Forward and Reverse zones
  • Installed and configured dhcpd for the lab network
  • Tested the DNS and dhcp services using a client machine
  • And network enabled our yum repository by exposing the directory using Apache

The final steps to enable an ISO free installation of CentOS 7 into a KVM virtual machine are;

  • Installing, configuring and testing Trivial FTP, adding additional configuration to DHCPd to enable PXE booting and testing that setup (this post)
  • The final piece will be to create our kickstart file from which will define the standard installation on CentOS 7 (maybe splitting out into server and client)

So, lets not waste any time and get our hands dirty and flex our fingers with a bit of typing…

Trivial FTP (tftp)

First things first, lets log on to the server and get the packages installed.  Thankfully they are part of the installation media and therefore part of the yum repository that was set up in the last post.

[toby@rhc-server ~]$ sudo yum install tftp*
Loaded plugins: fastestmirror
baselocal                                                                                                            | 3.6 kB  00:00:00     
Loading mirror speeds from cached hostfile
Resolving Dependencies
-- Running transaction check
--- Package tftp.x86_64 0:5.2-11.el7 will be installed
--- Package tftp-server.x86_64 0:5.2-11.el7 will be installed
-- Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================
 Package                            Arch                          Version                            Repository                        Size
============================================================================================================================================
Installing:
 tftp                               x86_64                        5.2-11.el7                         baselocal                         35 k
 tftp-server                        x86_64                        5.2-11.el7                         baselocal                         44 k

Transaction Summary
============================================================================================================================================
Install  2 Packages

Total download size: 79 k
Installed size: 112 k
Is this ok [y/d/N]: y
Downloading packages:
--------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                       654 kB/s |  79 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : tftp-server-5.2-11.el7.x86_64                                                                                            1/2 
  Installing : tftp-5.2-11.el7.x86_64                                                                                                   2/2 
  Verifying  : tftp-5.2-11.el7.x86_64                                                                                                   1/2 
  Verifying  : tftp-server-5.2-11.el7.x86_64                                                                                            2/2 

Installed:
  tftp.x86_64 0:5.2-11.el7                                          tftp-server.x86_64 0:5.2-11.el7                                         

Complete!

Note, I’ve installed both client and server RPMs on the server. For my tests from a client I will only install the client tftp package.

Next step is to prepare the folder structure where the files will be served from.  Don’t forget to make sure SELinux contexts, etc. are defined correctly otherwise things will not work as expected.

[root@rhc-server lib]# ll -aZ /var/lib/tftpboot
drwxr-xr-x. root root system_u:object_r:tftpdir_rw_t:s0 .
drwxr-xr-x. root root system_u:object_r:var_lib_t:s0    ..

Note that the SELinux type is “tftpdir_rw_t”, we will need to apply this same type to the folder created next.

[root@rhc-server ~]# mkdir /tftpboot
[root@rhc-server ~]# chcon --reference=/var/lib/tftpboot/ /tftpboot
[root@rhc-server ~]# ll -Z /
[.. snip ..]
drwxr-xr-x. root root system_u:object_r:tftpdir_rw_t:s0 tftpboot

I am slightly cheating with the above command as I am using the standard tftp directory SELinux security types and contexts as a reference. Why make things more difficult than they need to be.

And now lets configure the tftp daemon to use this new location by default.

So lets just check where we are;

  • tftp server and client installed? – check!
  • folder structure created, permissions set and SELinux attributes defined correctly – check!
  • tftp server configured? – Nope

Best fix the TFTP configuration side of things before going further;

[toby@rhc-server lib]$ cat /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
#    protocol.  The tftp protocol is often used to boot diskless \
#    workstations, download configuration files to network-aware printers, \
#    and to start the installation process for some operating systems.
service tftp
{
socket_type        = dgram
protocol        = udp
wait            = yes
user            = root
server            = /usr/sbin/in.tftpd
server_args        = -s /tftpboot
disable            = no
per_source        = 11
cps            = 100 2
flags            = IPv4
}

OK, so the remaining task at this point before we start the service is to make sure the firewall is configured to allow connectivity to the tftp service via its LAN interface and also to make sure the hosts.allow file has an entry for the tftp service.  hosts.allow is used by the xinetd processes, and is required in addition to the firewall changes.

Lets get the hosts.allow file out of the way first;

[root@rhc-server ~]# cat /etc/hosts.allow 
#
# hosts.allow	This file contains access rules which are used to
#		allow or deny connections to network services that
#		either use the tcp_wrappers library or that have been
#		started through a tcp_wrappers-enabled xinetd.
#
#		See 'man 5 hosts_options' and 'man 5 hosts_access'
#		for information on rule syntax.
#		See 'man tcpd' for information on tcp_wrappers
#
in.tftp:	ALL

And now for the firewall;

[root@rhc-server ~]# firewall-cmd --zone public --add-service tftp
[root@rhc-server ~]# firewall-cmd --permanent --zone public --add-service tftp
success

It is worth mentioning that if you use the “–permanent” parameter on the command line, it will not be applied immediately.  Now we should be good to start the service and do some tests. We will create a test file to try and copy via tftp before performing the tests.

[root@rhc-server ~]# systemctl enable tftp.socket
ln -s '/usr/lib/systemd/system/tftp.socket' '/etc/systemd/system/sockets.target.wants/tftp.socket'
[root@rhc-server ~]# systemctl reload xinetd

Based on the above the service has started successfully and nothing appears to be out of the ordinary in the journal, so lets proceed with the testing, and here is my test file;

[root@rhc-server ~]# echo "Hello?  Is it me you're looking for?" > /tftpboot/this_is_a_test

[root@rhc-server ~]# ll -Z /tftpboot/
-rw-r--r--. root root unconfined_u:object_r:tftpdir_rw_t:s0 this_is_a_test

Call me paranoid, but I wanted to make sure the file had inherited the SELinux type of “tftpdir_rw_t”.  Which it did 🙂

Testing locally on server

[toby@rhc-server ~]$ tftp -4 localhost
tftp> get this_is_a_test
tftp> quit
[toby@rhc-server ~]$ ls
this_is_a_test
[toby@rhc-server ~]$ cat this_is_a_test 
Hello?  Is it me you're looking for?

Looking good so far! 🙂

Testing remotely from client

Before we can test lets determine if the tftp package is installed, in my case it wasn’t, so I installed it;

[toby@rhc-client ~]$ yum search tftp
Loaded plugins: fastestmirror, langpacks
Determining fastest mirrors
============================================================ N/S matched: tftp =============================================================
syslinux-tftpboot.x86_64 : SYSLINUX modules in /tftpboot, available for network booting
tftp.x86_64 : The client for the Trivial File Transfer Protocol (TFTP)
tftp-server.x86_64 : The server for the Trivial File Transfer Protocol (TFTP)

  Name and summary matches only, use "search all" for everything.
[toby@rhc-client ~]$ yum list tftp
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Available Packages
tftp.x86_64                                                     5.2-11.el7                                                     th_lab_server
[toby@rhc-client ~]$ sudo yum install tftp
[sudo] password for toby: 
Loaded plugins: fastestmirror, langpacks
th_lab_server                                                                                                        | 3.6 kB  00:00:00     
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package tftp.x86_64 0:5.2-11.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================
 Package                      Arch                           Version                            Repository                             Size
============================================================================================================================================
Installing:
 tftp                         x86_64                         5.2-11.el7                         th_lab_server                          35 k

Transaction Summary
============================================================================================================================================
Install  1 Package

Total download size: 35 k
Installed size: 48 k
Is this ok [y/d/N]: y
Downloading packages:
warning: /var/cache/yum/x86_64/7/th_lab_server/packages/tftp-5.2-11.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for tftp-5.2-11.el7.x86_64.rpm is not installed
tftp-5.2-11.el7.x86_64.rpm                                                                                           |  35 kB  00:00:00     
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
 Userid     : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
 Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
 Package    : centos-release-7-0.1406.el7.centos.2.3.x86_64 (@anaconda)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Is this ok [y/N]: y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : tftp-5.2-11.el7.x86_64                                                                                                   1/1 
  Verifying  : tftp-5.2-11.el7.x86_64                                                                                                   1/1 

Installed:
  tftp.x86_64 0:5.2-11.el7                                                                                                                  

Complete!

And now the test from the client.

[toby@rhc-client ~]$ sudo firewall-cmd --zone public --add-service tftp
[sudo] password for toby: 
success
[toby@rhc-client ~]$ tftp rhc-server
tftp> get this_is_a_test
tftp> quit
[toby@rhc-client ~]$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  test  this_is_a_test  Videos
[toby@rhc-client ~]$ cat this_is_a_test 
Hello?  Is it me you're looking for?
[toby@rhc-client ~]$ sudo firewall-cmd --zone public --remove-service tftp
success

Note. If you don’t temporarily enable the tftp port on the client, the test will fail. I got the follow error via tcpdump which highlighted that the firewall was blocking the request;

23:25:40.388650 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 54)
    192.168.20.50.36588 > 192.168.20.1.69: [udp sum ok]  26 RRQ "this_is_a_test" netascii
23:25:40.390312 IP (tos 0x0, ttl 64, id 31747, offset 0, flags [none], proto UDP (17), length 70)
    192.168.20.1.43788 > 192.168.20.50.36588: [bad udp cksum 0xa9c7 -> 0xddd1!] UDP, length 42
23:25:40.390721 IP (tos 0xc0, ttl 64, id 3881, offset 0, flags [none], proto ICMP (1), length 98)
    192.168.20.50 > 192.168.20.1: ICMP host 192.168.20.50 unreachable - admin prohibited, length 78
	IP (tos 0x0, ttl 64, id 31747, offset 0, flags [none], proto UDP (17), length 70)
    192.168.20.1.43788 > 192.168.20.50.36588: [udp sum ok] UDP, length 42

At this point we have now completed the necessary steps to ensure we have a working tftp service.

Setting up PXE

The second part of today’s post covers the steps needed to enable booting from the network to facilitate building machines without the hassle of creating USB bootable images or burning ISO images to CD or DVD.

Out task list for this section is;

  • Add the additional config to the DHCP scope
  • Ensure we have the pxelinux/syslinux installed and copied to the required location
  • Create a basic menu to provide end users with a installation options
  • Test

Configuring DHCP

So, lets start by reminding ourselves what the current dhcpd.conf file looks like;

[toby@rhc-server ~]$ sudo cat /etc/dhcp/dhcpd.conf
[sudo] password for toby: 
#
#  lab.tobyheywood.com dhcp daemon configuration file
#
#  2016-02-22 - Initial creation
#

# Define which IP to listen on.  NOTE. daemon can only listen to one
# IP at a time if defined.
local-address 192.168.20.1;

# option definitions common to all supported networks...
option domain-name "lab.tobyheywood.com";
option domain-name-servers ns.lab.tobyheywood.com;

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

# Use this to enble / disable dynamic dns updates globally.
#ddns-update-style interim;

# This is the authoritative DHCP server.
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;

# Interface which can be accessed from outside the sandbox
# **** NOT IN USE ****
subnet 192.168.122.0 netmask 255.255.255.0 {
}

# The lab network
subnet 192.168.20.0 netmask 255.255.255.128 {
  range 192.168.20.50 192.168.20.99;
  option routers rtr.lab.tobyheywood.com;
}

So in order to get PXE (Preboot eXecution Environment) to function we will need to add a few more lines to the configuration, as highlighted below.

[toby@rhc-server ~]$ sudo cat /etc/dhcp/dhcpd.conf
[sudo] password for toby: 
#
#  lab.tobyheywood.com dhcp daemon configuration file
#
#  2016-02-22 - Initial creation
#

# Define which IP to listen on.  NOTE. daemon can only listen to one
# IP at a time if defined.
local-address 192.168.20.1;

# option definitions common to all supported networks...
option domain-name "lab.tobyheywood.com";
option domain-name-servers ns.lab.tobyheywood.com;

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

# Use this to enble / disable dynamic dns updates globally.
#ddns-update-style interim;

# This is the authoritative DHCP server.
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;

# Interface which can be accessed from outside the sandbox
# **** NOT IN USE ****
subnet 192.168.122.0 netmask 255.255.255.0 {
}

# The lab network
subnet 192.168.20.0 netmask 255.255.255.128 {
  range 192.168.20.50 192.168.20.99;
  option routers rtr.lab.tobyheywood.com;
}

# Additional configuration for PXE booting
allow booting;
allow bootp;
option option-128 code 128 = string;
option option-129 code 129 = text;
next-server 192.168.20.1;
filename "/pxelinux.0";

Setting up the required syslinux files in /tftpboot

During the section above when testing the tftp service on the client, I saw that there may be a shortcut to getting things up and running.  Everything I have read says you need to manually copy the syslinux files into the /tftpboot directory, however, if you search the rpm database with yum for anything tftp related, I see that there is potentially an easier way.

[toby@rhc-server ~]$ yum list tftp
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Installed Packages
tftp.x86_64                                     5.2-11.el7                                     @baselocal
[toby@rhc-server ~]$ yum search tftp
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
=========================================== N/S matched: tftp ===========================================
syslinux-tftpboot.x86_64 : SYSLINUX modules in /tftpboot, available for network booting
tftp.x86_64 : The client for the Trivial File Transfer Protocol (TFTP)
tftp-server.x86_64 : The server for the Trivial File Transfer Protocol (TFTP)

As you can see there appears to be a syslinux-tftpboot rpm.  So lets see what it gives us;

[toby@rhc-server ~]$ sudo yum install syslinux-tftpboot
[sudo] password for toby: 
Loaded plugins: fastestmirror
baselocal                                                                         | 3.6 kB  00:00:00     
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package syslinux-tftpboot.x86_64 0:4.05-8.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=========================================================================================================
 Package                        Arch                Version                 Repository              Size
=========================================================================================================
Installing:
 syslinux-tftpboot              x86_64              4.05-8.el7              baselocal              425 k

Transaction Summary
=========================================================================================================
Install  1 Package

Total download size: 425 k
Installed size: 1.3 M
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : syslinux-tftpboot-4.05-8.el7.x86_64                                                   1/1 
  Verifying  : syslinux-tftpboot-4.05-8.el7.x86_64                                                   1/1 

Installed:
  syslinux-tftpboot.x86_64 0:4.05-8.el7                                                                  

Complete!
[toby@rhc-server ~]$ ls /tftpboot/
cat.c32        dmitest.c32   host.c32     ls.c32       pcitest.c32   rosh.c32        vesamenu.c32
chain.c32      elf.c32       ifcpu64.c32  lua.c32      pmload.c32    sanboot.c32     vpdtest.c32
cmd.c32        ethersel.c32  ifcpu.c32    mboot.c32    poweroff.com  sdi.c32         whichsys.c32
config.c32     gfxboot.c32   ifplop.c32   memdisk      pwd.c32       sysdump.c32     zzjson.c32
cpuid.c32      gpxecmd.c32   int18.com    memdump.com  pxechain.com  this_is_a_test
cpuidtest.c32  gpxelinux.0   kbdmap.c32   meminfo.c32  pxelinux.0    ver.com
disk.c32       hdt.c32       linux.c32    menu.c32     reboot.c32    vesainfo.c32

It looks like we have a winner!  Now we just need to make sure that the Preboot environment has a kernel or two to play with;

[root@rhc-server ~]# cp /software/centos7/images/pxeboot/* /tftpboot/centos7/
[root@rhc-server ~]# ls -Z /tftpboot/centos7/
-rw-r--r--. root root unconfined_u:object_r:tftpdir_t:s0 initrd.img
-r--r--r--. root root unconfined_u:object_r:tftpdir_t:s0 TRANS.TBL
-rw-r--r--. root root unconfined_u:object_r:tftpdir_t:s0 upgrade.img
-rwxr-xr-x. root root unconfined_u:object_r:tftpdir_t:s0 vmlinuz

OK, so lets now create the directory which will hold the PXE menus;

[toby@rhc-server ~]$ sudo mkdir /tftpboot/pxelinux.cfg
[sudo] password for toby: 
[toby@rhc-server ~]$ ls -Zd /tftpboot/pxelinux.cfg
drwxr-xr-x. root root unconfined_u:object_r:tftpdir_t:s0 /tftpboot/pxelinux.cfg

And now lets look at what is required to create the menus from which we will be able to select installation options.

[root@rhc-server centos7]# cat /tftpboot/pxelinux.cfg/default 
DEFAULT menu.c32
PROMPT 0
TIMEOUT 300
ONTIMEOUT localdisk
MENU TITLE PXE Network Boot

LABEL localdisk
    MENU LABEL ^Local Hard Drive
    MENU DEFAULT
    LOCALBOOT 0

LABEL Install_CentOS_7_2
    MENU LABEL CentOS 7.2
    KERNEL centos7/vmlinuz
    APPEND initrd=http://rhc-server.lab.tobyheywood.com/centos7/isolinux/initrd.img  inst.repo=http://rhc-server.lab.tobyheywood.com/centos7

At this point, all I wanted to do was prove that the pxe settings in dhcp were correct and that maybe, just maybe, I could build a vm across the network, first time.  No such luck! 🙁  Well, I guess 50% of the way there.

You can skip the next and jump to here if you don’t want to understand the pain I went through to get this operational.

I thought things were going well.  I created a blank VM, made sure to select that I was going to boot from the network to install the OS in Virtual Manager and turned the VM on.

pxeboot_initial_screen

So far so good!

pxeboot_menu

I’m now feel pretty happy with myself.  I select CentOS 7.0 and hit the enter key… and then am presented with the expected Welcome to CentOS 7 screen, from where I can kick off a manual installation.

pxeboot_centos7_initial_install_screen

So all, in all, things look good.  However there is more work to be done, as the next step is to create a kickstart file to define how the base install should look.

Reference Material

Trivial FTP (tftp)

PXE

Featured image taken by Ed Robinson who kindly uploaded it to Flickr.com.  I have made no changes to this image and left it in its original form for your viewing pleasure.  And to give the page a bit of colour 😉