MaaS Part 2 - Centos 7.x and Kickstart

In part 1, I walked through the initial network booting process to be able to start the Centos 7.x installation process. In this part, part 2, I’ll continue on to explain the Centos 7.x specific portions of things as well as break down the kickstart configuration file.

Centos 7 Specifics

In the grub.cfg file, the following kernel line:

  linux (tftp)/vmlinuz noipv6 inst.repo=http://deploy/repos/centos/7/os/x86_64/ inst.ks=http://deploy/ks.cfg inst.ks.sendmac

has three RedHat/Centos specific items under the inst prefix. Full reference

inst.repo

This option tells the installer (anaconda) where it can find its installation repository. In this case, the web root of our centos7mirror container.

inst.ks

This option tells anaconda where it can find the optional kickstart configuration file. Again in this case, the web root of our centos7mirror container.

inst.ks.sendmac

This option tells anaconda to send the NIC name and mac address of the interface used to request the kickstart inside as special HTTP header named X-RHN-Provisioning-MAC-0. e.g.

X-RHN-Provisioning-MAC-0: eth0 01:23:45:67:89:ab

Custom Kickstart Handler

So, in our /var/www/html/ks.php file, we parse the MAC header and serve up our custom kickstart file if it’s valid and exists as a configuration file. Remember, we use mod_rewrite rules to make any requests for ks.cfg be served by /var/www/html/ks.php:

 1 <?php
 2   # kickstart needs text/plain or it fails
 3   header("Content-Type: text/plain");
 4 
 5   # Cfg file path
 6   $cfgpath = "./cfg";
 7 
 8   # Did we get the inst.ks.sendmac header
 9   if (isset($_SERVER['HTTP_X_RHN_PROVISIONING_MAC_0'])) {
10     # Parse the header
11     $macstring = $_SERVER['HTTP_X_RHN_PROVISIONING_MAC_0'];
12     $macarray = explode(" ", $macstring);
13 
14     # Did the header contain a mac address?
15     if (isset($macarray[1])) {
16       $mac = $macarray[1];
17 
18       # Valid mac format?
19       if (preg_match('/([a-fA-F0-9]{2}:?){6}/', $mac) == 0) {
20         echo "Invalid Request\n";
21         exit;
22       }
23 
24       # Send its config if one exists
25       $configfile = "$cfgpath/$mac.cfg";
26       if (file_exists($configfile)) {
27         readfile($configfile);
28       } else {
29         echo "Invalid Request\n";
30       }
31     }
32   } else {
33     echo "Invalid Request\n";
34     exit;
35   }
36 ?>

And here is what’s in /var/www/html/cfg:

[admin@deploy cfg]$ pwd
/var/www/html/cfg
[admin@deploy cfg]$ ls -al
total 40
drwxr-xr-x 2 root root 4096 Jul 25 15:04 .
drwxr-xr-x 4 root root   58 Jul 26 01:00 ..
-rw-r--r-- 1 root root 1814 Jul 25 15:04 00:23:32:2f:40:3c.cfg
-rw-r--r-- 1 root root 1819 Jul 25 15:04 00:25:90:96:c4:9a.cfg
-rw-r--r-- 1 root root 1819 Jul 25 15:04 00:25:90:96:c6:5a.cfg
-rw-r--r-- 1 root root 1808 Jul 25 15:04 00:30:48:fb:e2:44.cfg
-rw-r--r-- 1 root root 1811 Jul 25 15:04 a8:20:66:34:ff:e9.cfg
-rw-r--r-- 1 root root 1811 Jul 25 15:04 a8:20:66:4a:ce:46.cfg
-rw-r--r-- 1 root root 1811 Jul 25 15:04 a8:20:66:4a:d9:da.cfg
-rw-r--r-- 1 root root 1810 Jul 25 15:04 bc:30:5b:e5:73:b7.cfg
-rw-r--r-- 1 root root 1810 Jul 25 15:04 bc:30:5b:e5:75:28.cfg

Custom Kickstart File

 1 #version=DEVEL
 2 # System authorization information
 3 auth --enableshadow --passalgo=sha512
 4 # Use CDROM installation media
 5 url --url http://deploy/repos/centos/7/os/x86_64/
 6 # Use graphical install
 7 #graphical
 8 text
 9 # Run the Setup Agent on first boot
10 firstboot --enable
11 ignoredisk --only-use=sdb
12 # Keyboard layouts
13 keyboard --vckeymap=us --xlayouts='us'
14 # System language
15 lang en_US.UTF-8
16 
17 # Network information
18 network  --bootproto=dhcp --device=enp2s0 --noipv6 --activate
19 network  --hostname=mm1
20 
21 # During Install
22 sshpw --user=root s3cr3t
23 
24 # Root password
25 rootpw --iscrypted $6$SANKK2GLJES9hSp9$PgaXUwpz2S4mRwg6kUQo.E3IyArxeA.MdIc77e1kkPRDD3BI8d3mxrwmoD.8BbZ2613XJoZNgWX0fwCsu1tih.
26 # System timezone
27 timezone America/New_York --isUtc
28 user --groups=wheel --name=admin --password=$6$0YFXS7zQLIQ99FCh$gqxId0ypSP16GCwiOfOcGUZK9AASxatDVF4g8PtTy5HDaZ5jXeIo9NeOU4ttK1KWjsI/6D6TVMfOh37XCMSG2/ --iscrypted --gecos="admin"
29 # System bootloader configuration
30 bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sdb
31 autopart --type=lvm
32 # Partition clearing information
33 clearpart --all --initlabel --drives=sda,sdb
34 # Reboot after install finishes
35 reboot
36 
37 %packages
38 @^minimal
39 @core
40 kexec-tools
41 net-tools
42 tcpdump
43 wget
44 nc
45 %end
46 
47 %addon com_redhat_kdump --enable --reserve-mb='auto'
48 
49 %end
50 
51 %post --log=/root/postinstall.log
52 # SSH UseDNS no
53 sed -ri 's/#UseDNS yes/UseDNS no/'g /etc/ssh/sshd_config
54 # SSH Key
55 mkdir -p /home/admin/.ssh
56 chmod 700 /home/admin/.ssh
57 echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCugz/eu/a6U5ZXtYVp9ufCghVSP0Lux/nP6BgbranKE6r3h3xgqo8yR2LUG9VwH6Vo+BtGgToeww+jbgr3oq9g8/mQmNvQEefvWyzhYxrpv6q36fdYS0KhQxA6vnpOZZ1M9cZ1q6iPaUryxDUFU3HULDKM4g/6XBzqBJZ2illyuw==" > /home/admin/.ssh/authorized_keys
58 chmod 600 /home/admin/.ssh/authorized_keys
59 chown -R admin:admin /home/admin/.ssh
60 
61 yum -y update
62  
63 %end

A couple key notes:

  • The file was created by first performing a manual installation. This ends up as /root/anaconda-ks.cfg after installation completes. I then added a couple packages and then the contents of the post section.
  • All partitions are cleared and the default partitioning scheme is used
  • A default account of admin is made
  • A public SSH key for admin is added to enable access once booted
  • UseDNS no is changed to speed up SSH access by removing reverse DNS lookups on connection.

Back to Index