Dynamic disk partitioning

Overview

When configuring a host for an unattended kickstart build. It is possible to specify the host's disk layout as an explicit sequence of partions or use a pre-exec dynamic disk layout script. In either case enter the explict partition list or the pre-exec script into the host's disk layout text area, (or choose a predefined configuration.)

If the text is to be interpreted as a dynamic disk layout then please ensure that the pre-exec shell script contains a comment line starting with "#Dynamic" and that your script writes a static partition table into /tmp/diskpart.cfg.

If a disk partition table contains /^#Dynamic/ then the kickstart process will execute the text as a bourne shell script as its very first step and will then include the file /tmp/diskpart.cfg into the downloaded kickstart file.

Examples

#Dynamic - this line tells Foreman this is a script rather then a static layout
#This snippets define the swap partition size, it would generate a partition twice the size of the memory if your physical memory is up to 2GB
#or will create a swap partition with your memory size + 2GB.

#get the actual memory installed on the system and divide by 1024 to get it in MB
act_mem=$((`grep MemTotal: /proc/meminfo | sed 's/^MemTotal: *//'|sed 's/ .*//'` / 1024))

#check if the memory is less than 2GB then swap is double the memory else it is memory plus 2 GB
if [ "$act_mem" -gt 2048 ]; then
    vir_mem=$(($act_mem + 2048))
else
    vir_mem=$(($act_mem * 2))
fi

#copy all the HDD partitions to the temp file for execution
cat <<EOF > /tmp/diskpart.cfg
zerombr yes
clearpart --all --initlabel
part swap --size "$vir_mem" 
part /boot --fstype ext3 --size 100 --asprimary
part / --fstype ext3 --size 1024 --grow
EOF

This next example uses LVM and 4GB swap for real hardware and direct disk and no swap for virtual machines. Virtual machines should use thin-provisioning leaving LVM unnecessary.

#Dynamic - this line tells Foreman this is a script rather then a static layout
#This snippets define the swap partition size and if a /boot should be used.
#4GB for real hardware or nothing for VM's
virtual=0

#test if it's KVM or QEMU
dmidecode | egrep -i 'vendor' |grep QEMU && virtual=1
cat /proc/cpuinfo |grep QEMU && virtual=1
dmesg |grep "Booting paravirtualized kernel on KVM" && virtual=1
#test if it's vmware
dmidecode | grep -i 'manufacturer' |grep VMware && virtual=1

if [ "$virtual" -eq 1 ]; then
    cat <<EOF > /tmp/diskpart.cfg
zerombr yes
clearpart --all --initlabel
part / --fstype ext4 --size 2048 --grow
EOF
else
    cat <<EOF > /tmp/diskpart.cfg
zerombr yes
clearpart --all --initlabel
part /boot --fstype ext4 --size 200 --asprimary
part pv.01 --ondisk sda --grow --size=40000
volgroup os pv.01
logvol / --fstype=ext4 --name=root --vgname=os --size=40000
logvol swap --name=swap --vgname=os --size=4096
EOF
fi

For Suse Linux this ran into some problems for which are described in this pull request: https://github.com/theforeman/community-templates/pull/321

Here is an example which implements this solution:

#Dynamic - this line tells Foreman this is a script rather then a static layout
<%#
kind: ptable
name: AutoYaST LVM modified
oses:
- SLES
- OpenSUSE
%>

# All sizes are in Megabytes
# Set the static size for /boot
BOOT=256

# Calculate the swap size depending on the memory and the recommendations from redhat.
MEM=$(($(sed -n 's/^MemTotal: \+\([0-9]*\) kB/\1/p' /proc/meminfo) / 1024))
if [ "$MEM" -lt "2048" ]; then
    SWAP=$((MEM * 2))
elif [ "$MEM" -gt "2048" ] || [ "$MEM" -le "8192" ]; then
    SWAP=$MEM
elif [ "$MEM" -ge "8192" ]; then
    SWAP=4096
fi

# Get the whole disksize
DSK=$(($(blockdev --getsize64 /dev/sda)/1048576))
# Remove the size reserved for SWAP and /boot from that.
DSK=$((DSK - (SWAP + BOOT)))

cat << EOF > /tmp/diskpart.cfg
  <partitioning config:type="list">
    <drive>
      <device>/dev/sda</device>
      <initialize config:type="boolean">true</initialize>
      <partitions config:type="list">
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">ext4</filesystem>
          <format config:type="boolean">true</format>
          <mount>/boot</mount>
          <partition_id config:type="integer">131</partition_id>
          <partition_nr config:type="integer">1</partition_nr>
          <size>${BOOT}M</size>
          <stripes config:type="integer">1</stripes>
          <stripesize config:type="integer">4</stripesize>
          <subvolumes config:type="list"/>
        </partition>
        <partition>
          <create config:type="boolean">true</create>
          <format config:type="boolean">false</format>
          <lvm_group>vg00</lvm_group>
          <partition_id config:type="integer">142</partition_id>
          <partition_nr config:type="integer">2</partition_nr>
          <size>max</size>
        </partition>
      </partitions>
      <pesize></pesize>
      <type config:type="symbol">CT_DISK</type>
      <use>all</use>
    </drive>
    <drive>
      <device>/dev/vg00</device>
      <initialize config:type="boolean">true</initialize>
      <partitions config:type="list">
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">ext4</filesystem>
          <format config:type="boolean">true</format>
          <lv_name>root</lv_name>
          <mount>/</mount>
          <size>$((DSK/4))M</size>
        </partition>
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">swap</filesystem>
          <format config:type="boolean">true</format>
          <lv_name>swap</lv_name>
          <mount>swap</mount>
          <size>${SWAP}M</size>
        </partition>
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">ext4</filesystem>
          <format config:type="boolean">true</format>
          <lv_name>usr</lv_name>
          <mount>/usr</mount>
          <size>$((DSK/4))M</size>
        </partition>
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">ext4</filesystem>
          <format config:type="boolean">true</format>
          <lv_name>tmp</lv_name>
          <mount>/tmp</mount>
          <size>$((DSK/16))M</size>
        </partition>
        <partition>
          <create config:type="boolean">true</create>
          <filesystem config:type="symbol">ext4</filesystem>
          <format config:type="boolean">true</format>
          <lv_name>var</lv_name>
          <mount>/var</mount>
          <size>$((DSK/4))M</size>
        </partition>
      </partitions>
      <type config:type="symbol">CT_LVM</type>
      <use>all</use>
    </drive>
  </partitioning>
EOF

# See https://github.com/theforeman/foreman/pull/4076 for this little piece of magic.
sed '/<\/ntp-client>/ r /tmp/diskpart.cfg' /tmp/profile/autoinst.xml > /tmp/profile/modified.xml