The mysteries of anaconda and kickstart

Problem

At work, I was trying to get a node installed remotely through kickstart such that I can create the partition table in a specific order. Unfortunately anaconda does not allow us to do that, and you could get disks partitioned not necessarily in the same order. i.e. I wanted the below

  • partition 1 == 10M
  • partition 2 ~ 50M with raid 2 across all 8 disks, with 6 Hot Spares
  • Partition 3 ~ 50G with raid 5 across all 8 disks, with 1 Hot Spare
  • Partition 4 everything else

But when I did this in the conventional method of adding as `part` commands in the kickstart file, using the following excerpt

part /boot/efi  --size 102 --fstype=vfat --ondisk=sda
part /boot/efi1 --size 102 --fstype=vfat --ondisk=sdb
part /boot/efi2 --size 102 --fstype=vfat --ondisk=sdc
part /boot/efi3 --size 102 --fstype=vfat --ondisk=sdd
part /boot/efi4 --size 102 --fstype=vfat --ondisk=sde
part /boot/efi5 --size 102 --fstype=vfat --ondisk=sdf
part /boot/efi6 --size 102 --fstype=vfat --ondisk=sdg
part /boot/efi7 --size 102 --fstype=vfat --ondisk=sdh

part raid.01    --size 512 --ondisk=sda
part raid.02    --size 512 --ondisk=sdb
part raid.03    --size 512 --ondisk=sdc
part raid.04    --size 512 --ondisk=sdd
part raid.05    --size 512 --ondisk=sde
part raid.06    --size 512 --ondisk=sdf
part raid.07    --size 512 --ondisk=sdg
part raid.08    --size 512 --ondisk=sdh

part raid.11    --size 51200 --ondisk=sda
part raid.12    --size 51200 --ondisk=sdb
part raid.13    --size 51200 --ondisk=sdc
part raid.14    --size 51200 --ondisk=sdd
part raid.15    --size 51200 --ondisk=sde
part raid.16    --size 51200 --ondisk=sdf
part raid.17    --size 51200 --ondisk=sdg
part raid.18    --size 51200 --ondisk=sdh

part /bddata    --size 1 --grow --ondisk=sda
part /bddata1   --size 1 --grow --ondisk=sdb
part /bddata2   --size 1 --grow --ondisk=sdc
part /bddata3   --size 1 --grow --ondisk=sdd
part /bddata4   --size 1 --grow --ondisk=sde
part /bddata5   --size 1 --grow --ondisk=sdf
part /bddata6   --size 1 --grow --ondisk=sdg
part /bddata7   --size 1 --grow --ondisk=sdh

raid /boot      --fstype=ext4 --device=md0 --level=1 --spares=6 raid.01 raid.02 raid.03 raid.04 raid.05 raid.06 raid.07 raid.08
raid pv.1       --fstype=ext4 --device=md1 --level=5 --spares=1 raid.11 raid.12 raid.13 raid.14 raid.15 raid.16 raid.17 raid.18

volgroup system --pesize=4096 pv.1

logvol /    --name=root --vgname=system --size=20480 --fstype=ext4
logvol swap --name=swap --vgname=system --size=8192
logvol /var --name=var  --vgname=system --size=40960 --fstype=ext4

I got the disks in not the order I wanted, i.e,.

# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [raid1]
md0 : active raid1 sdd2[3](S) sdh2[7](S) sdb2[1] sdg2[6](S) sde2[4](S) sdf2[5](S) sda3[0] sdc2[2](S)
      524224 blocks super 1.0 [2/2] [UU]

md1 : active raid5 sda2[0] sdd1[3] sdb1[1] sde1[4] sdg1[8] sdc1[2] sdf1[5] sdh1[7](S)
      314373120 blocks super 1.1 level 5, 512k chunk, algorithm 2 [7/6] [UUUUUU_]
      [=======>.............]  recovery = 38.7% (20320760/52395520) finish=11.0min speed=48478K/sec
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

here I have sda3 in md0, and the rest of the devices in the array are sdX2. The second array md1 I have sdb1, whereas the rest of the devices are sdX2. In both cases the last digit in at least one of the devices was different. As I have mentioned earlier, I wanted these to be identical

My Solution

The solution involves editing the kickstart file, and then generating the partition through a script through the %pre flag in kickstart

Kickstart File

Change the clearpart in the kickstart file such that it’s changed to clearpart –none, otherwise anaconda will not detect the disks. The way anaconda works is that it runs the %pre script first, and then goes through the kickstart configuration. So you don’t want it to clear the partition through clearpart. Below is an excerpt of the kickstart I used. Note, I also have %include /tmp/partitionfile, which will include the relevant partitions that will be created by a script.

#
# Clear the MBR
#
zerombr

#
# Wipe out the disk
#
#clearpart --all --initlabel
#clearpart --linux
clearpart --none
key --skip

#
# Customize to fit your needs
#

%include /tmp/partitionfile

Partition table generator script

Once the main part of the kickstart file is created, at the bottom you can start a new line with `%pre`, and add the contents of a script that I have listed below. This will go through the disks `sda` to `sdh` and create the required partitions using parted and write out the relevant partition layout to `/tmp/partitionfile`, which kickstart will use to provision the node.

#!/bin/bash

partfile=/tmp/partitionfile
disks="sda sdb sdc sdd sde sdf sdg sdh"
i=0
rm -rf ${partfile}
touch ${partfile}

for disk in `echo ${disks}`
do
  efipart=${i}
  [[ ${i} -eq 0 ]] && efipart=""

  dd if=/dev/zero of=/dev/${disk} bs=512 count=1

  parted -s /dev/${disk} mklabel gpt

  parted -s /dev/${disk} mkpart primary 1MiB 100MiB
  parted -s /dev/${disk} set 1 boot on
  parted -s /dev/${disk} mkpart primary 100MiB 600MiB
  parted -s /dev/${disk} set 2 raid on
  parted -s /dev/${disk} mkpart primary 600MiB 51800MiB
  parted -s /dev/${disk} set 3 raid on
  parted -s /dev/${disk} mkpart primary 51800MiB 100%

cat >> ${partfile} << EOF

part /boot/efi${efipart} --fstype=vfat --onpart=/dev/${disk}1
part raid.0${i} --onpart=/dev/${disk}2
part raid.1${i} --onpart=/dev/${disk}3
EOF

  (( i++ ))
done

cat >> ${partfile} << EOF
raid /boot      --fstype=ext4 --device=md0 --level=1 --spares=6 raid.00 raid.01 raid.02 raid.03 raid.04 raid.05 raid.06 raid.07
raid pv.1       --fstype=ext4 --device=md1 --level=5 --spares=1 raid.10 raid.11 raid.12 raid.13 raid.14 raid.15 raid.16 raid.17

volgroup system --pesize=4096 pv.1

logvol /    --name=root --vgname=system --size=20480 --fstype=ext4
logvol swap --name=swap --vgname=system --size=8192
logvol /var --name=var  --vgname=system --size=40960 --fstype=ext4
EOF

Notes

kpartx

A lot of the websites and recommendations suggest that you can update the device list by using kpartx, but this creates /dev/md-X devices, and then you get symbolic links in /dev/mapper/sdXX. This is not the desired effect, and the nodes will not install.

clearpart is required

If you don’t have clearpart in the kickstart file, then you will get the following error if you have specified cmdline in your anaconda boot line

In interactive step cleardiskssel, can't continue

order of execution

The %pre will always run before the kickatart attributes are run, so make sure that anything you do in the %pre section doesn’t get overridden in the main file and cause problems

Thanks

I’d like to thank the RedHat users on the #anaconda IRC channel, who helped me to resolve the problems, and made me understand on how it works

Leave a Reply

Your email address will not be published.