What commands are available in the %pre section of a Kickstart file on CentOS?
The %pre
section(s) of your kickstart run inside the installer environment.
Here's a list of helpful commands that are available in the installer environment in RHEL6.5:
- Shell utils:
arch awk basename bash cat chattr chgrp chmod chown chroot clear clock consoletype cp cut date df dmesg du echo egrep env expr false fgrep find getopt grep head hwclock id kill killall killall5 less ln ls lsattr mkdir mknod mktemp mv pidof ps pwd readlink rm rmdir sed sh shred sleep sort split sync tac tail tee top touch true tty uname uniq wc which xargs
- Editors and pagers:
less more vi
- Hash utilities:
md5sum sha1sum sha256sum
- Compression and archives:
gzip bzip2 cpio dd tar rpm
fsck
/mkfs
/etc. forext2 ext3 ext4 xfs btrfs msdos vfat
- Other filesystem stuff:
mkswap swapon swapoff dmraid dmsetup mdadm mdmon dump restore mt lvm lvs vgs pvs ...
- Networking utilities:
arp arping curl dhclient dhclient-script ftp ifconfig hostname ip ipcalc mtr nc ping rcp rdate rlogin telnet nslookup ntpdate route rsh rsync ssh ssh-keygen sshd scp sftp wget
- Hardware info:
biosdevname blkdeactivate blkid blockdev dmidecode lshal lspci lsscsi sginfo smartctl
- Disk utilities:
eject dump restore hdparm smartctl losetup kpartx parted fdisk sfdisk
- Console handling / dialogs:
chvt consolehelper openvt whiptail zenity
- Logging:
logger rsyslogd syslogd
python
- And lots more!
If you run a manual install, you can switch to the terminal on VT2 (CtrlAltF2) and poke around to find out everything that's available inside the installer environment. compgen -c | sort -u
is an easy way to list every command available, and there's lots of system information to be found in /sys
and /proc
.
(And yes, the kickstart is re-parsed after the %pre
scripts run, so your %pre
can edit the kickstart and/or generate new kickstart snippets to use with %include
.)
Commands such as these are typically not available in the %pre
section of kickstart.
excerpt - http://narrabilis.com/book/export/s5/6
%pre
The %pre section is where you can specify commands to run before the system is installed. Commands placed here are not run in the chrooted install environment.
%pre
must come at the end of the kickstart file. You may append --interpreter to the%pre
line to have the pre script run a different interpreter than/bin/sh
The Fedora documentation also discusses what's available in %pre
, in section Chapter 4. Pre-installation Script of the Anaconda/Kickstart docs.
excerpt
You can add commands to run on the system immediately after the ks.cfg has been parsed and the lang, keyboard, and url options have been processed. This section must be at the end of the kickstart file (after the commands) and must start with the %pre command. You can access the network in the %pre section; however, name service has not been configured at this point, so only IP addresses will work.
Finally the Red Hat official docs have this to say, titled: 32.6. Pre-installation Script:
The pre-installation script section of kickstart cannot manage multiple install trees or source media. This information must be included for each created ks.cfg file, as the pre-installation script occurs during the second stage of the installation process.
So you'll have access to commands that are included in your interpreter (Bash, Python, etc) but little else.
After digging a bit more, I found a ton of system info in /proc
that is available for
viewing when the %pre
section in ks.cfg
executes. Checkout dmidecode and files in /proc to get all the information you need. Here is what worked for me:
%pre --log=/tmp/ks_pre.log
#!/bin/sh
#----------------------------------------------
# echos message to console screen and a log file
#----------------------------------------------
echo_screen_n_log() {
msg=$1
# Send to console screen
(echo "$msg") >/dev/tty1
# Send to log
echo "$msg"
}
echo_screen_n_log ""
echo_screen_n_log "Analyzing Hardware..."
echo_screen_n_log ""
#----------------------------------------------
# System Memory
#----------------------------------------------
IFS=$'\n'
mem_info=(`dmidecode --type memory`)
unset IFS
sys_mem_sizes=""
sys_mem_banks=""
sys_tot_mem=0
cntr=0
bank_cntr=0
for i in "${mem_info[@]}"
do
# echo_screen_n_log "i: $i"
# Maximum system memory that can be placed on the motherboard
REG_EX="Maximum Capacity: (.*)$"
if [[ $i =~ $REG_EX ]]
then
sys_mem_max=${BASH_REMATCH[1]}
fi
# How many memory slots are on the motherboard
REG_EX="Number Of Devices: (.*)$"
if [[ $i =~ $REG_EX ]]
then
sys_mem_slots=${BASH_REMATCH[1]}
fi
REG_EX="^[[:space:]]+Size: (.*)$"
if [[ $i =~ $REG_EX ]]
then
sys_mem_sizes[cntr]=${BASH_REMATCH[1]}
cntr=$(( $cntr + 1 ))
fi
REG_EX="^[[:space:]]+Bank Locator: (.*)$"
if [[ $i =~ $REG_EX ]]
then
sys_mem_banks[bank_cntr]=${BASH_REMATCH[1]}
bank_cntr=$(( $bank_cntr + 1 ))
fi
done
cntr=$(( $cntr - 1 ))
echo_screen_n_log "Max system memory: $sys_mem_max"
echo_screen_n_log "Total system slots: $sys_mem_slots"
i=0
while [ $i -le $cntr ]
do
echo_screen_n_log "Memory Bank Location ${sys_mem_banks[$i]} : ${sys_mem_sizes[$i]}"
REG_EX="No Module Installed$"
if [[ ! ${sys_mem_sizes[$i]} =~ $REG_EX ]]
then
REG_EX="^([0-9]+) [A-Z][A-Z]$"
if [[ ${sys_mem_sizes[$i]} =~ $REG_EX ]]
then
sys_tot_mem=$(( $sys_tot_mem + ${BASH_REMATCH[1]} ))
fi
fi
i=$(( $i + 1 ))
done
echo_screen_n_log "System Total Memory: $sys_tot_mem MB"
#--------------------------------------------
# Get Disk size information
#--------------------------------------------
IFS=$'\n'
disk_info=(`cat /proc/partitions`)
unset IFS
total_disk_space=0
type=""
# Grab from minor column starting with 0 ending in 3 letters (drive node)
REG_EX="0\s+([0-9]+) [a-z][a-z][a-z]$"
for i in "${disk_info[@]}"
do
# echo_screen_n_log "i: $i"
if [[ $i =~ $REG_EX ]]
then
total_disk_space=${BASH_REMATCH[1]}
total_disk_space=$(( $total_disk_space * 1024 ))
type="GB"
div_num=1000000000
if [ "$total_disk_space" -lt $div_num ]
then
type="MB"
div_num=1000000
fi
total_disk_space=$(( $total_disk_space / $div_num ))
fi
done
echo_screen_n_log "Disk Space: $total_disk_space $type"
#-----------------------------------------------------
# Get CPU model name
#-----------------------------------------------------
cpu_grep=`grep 'model name' /proc/cpuinfo`
cpu_model_nm="Not Found!"
REG_EX="^.*: (.*)$"
if [[ $cpu_grep =~ $REG_EX ]]
then
cpu_model_nm=${BASH_REMATCH[1]}
fi
echo_screen_n_log "CPU Model: $cpu_model_nm"
#-------------------------------------------------------
# Get number of physical CPUs
#-------------------------------------------------------
IFS=$'\n'
cpu_count=(`grep "physical id" /proc/cpuinfo`)
unset IFS
last_cpu_id=""
total_cpu_cnt=0
# Add up all cores of the CPU to get total MIPS
total_cpus=0
REG_EX="^physical id\s+: ([0-9]+)$"
for i in "${cpu_count[@]}"
do
# echo_screen_n_log "i: $i"
if [[ $i =~ $REG_EX ]]
then
cpu_id=${BASH_REMATCH[1]}
if [ ! "$last_cpu_id" = "$cpu_id" ]
then
total_cpu_cnt=$(( $total_cpu_cnt + 1 ))
last_cpu_id=$cpu_id
fi
fi
done
echo_screen_n_log "System physical CPUs: $total_cpu_cnt"
#-------------------------------------------------------
# Get number of CPU cores
#-------------------------------------------------------
IFS=$'\n'
cpu_cores=(`grep -m 1 "cpu cores" /proc/cpuinfo`)
unset IFS
total_cpu_cores=0
REG_EX="^cpu cores\s+: ([0-9]+)$"
for i in "${cpu_cores[@]}"
do
# echo_screen_n_log "i: $i"
if [[ $i =~ $REG_EX ]]
then
total_cpu_cores=${BASH_REMATCH[1]}
fi
done
echo_screen_n_log "CPU cores: $total_cpu_cores"
#-------------------------------------------------------
# CPU MHz
#-------------------------------------------------------
IFS=$'\n'
dmi_cpu_MHz=(`dmidecode --string processor-frequency`)
unset IFS
cpu_MHz=0
REG_EX="^[0-9]+ "
for i in "${dmi_cpu_MHz[@]}"
do
# echo_screen_n_log "i: $i"
if [[ $i =~ $REG_EX ]]
then
cpu_MHz=${BASH_REMATCH[1]}
fi
done
echo_screen_n_log "CPU MHz: ${dmi_cpu_MHz:0:1}.${dmi_cpu_MHz:1:$(( ${#dmi_cpu_MHz} - 1 ))}"
#-------------------------------------------------------
# Get CPU bogomips (Millions of instructions per second)
#-------------------------------------------------------
IFS=$'\n'
cpu_mips=(`grep "bogomips" /proc/cpuinfo`)
unset IFS
# Add up all cores of the CPU to get total MIPS
total_mips=0
REG_EX="\s([0-9]+)\..*$"
for i in "${cpu_mips[@]}"
do
# echo_screen_n_log "i: $i"
if [[ $i =~ $REG_EX ]]
then
cpu_bogomips=${BASH_REMATCH[1]}
total_mips=$(( $total_mips + $cpu_bogomips ))
fi
done
echo_screen_n_log "Total CPU MIPS (Millions of instructions per second) : $total_mips"
echo_screen_n_log ""
(echo -n "Press <enter> to continue..") >/dev/tty1
read text
%end
I just need to add the criteria for determining what a base system for our installations should look like and I'm done.....
Updated this with more information... You can also do the following for disk info in the %pre section:
IFS=$'\n'
parted_txt=(`parted -l`)
unset IFS
for i in "${parted_txt[@]}"
do
# (echo "i: \"$i\"") >/dev/tty1
REG_EX="^Model: (.*)$"
if [[ $i =~ $REG_EX ]]
then
disk_model=${BASH_REMATCH[1]}
# (echo "Disk Model: \"$disk_model\"") >/dev/tty1
fi
REG_EX="^Disk (.*): ([0-9]+).[0-9]([A-Z][A-Z])$"
if [[ $i =~ $REG_EX ]]
then
disk_device=${BASH_REMATCH[1]}
disk_capacity=${BASH_REMATCH[2]}
disk_capacity_type=${BASH_REMATCH[3]}
(echo "Device: \"$disk_device\" \"$disk_capacity\" $disk_capacity_type") >/dev/tty1
IFS=$'\n'
disk_txt=(`udevadm info --query=all --name=$disk_device`)
unset IFS
is_USB_drive=0
for j in "${disk_txt[@]}"
do
#(echo "j: \"$j\"") >/dev/tty1
REG_EX="^ID_BUS=usb$"
if [[ $j =~ $REG_EX ]]
then
# USB keys are not to be included in total disk space
# (echo "$disk_device is a USB drive!") >/dev/tty1
is_USB_drive=1
fi
done
if [ "$is_USB_drive" = "0" ]
then
total_capacity=$(( $total_capacity + $disk_capacity ))
fi
fi
done
(echo "Disk Model: $disk_model") >/dev/tty1
(echo "Disk $disk_device Capacity: $total_capacity $disk_capacity_type") >/dev/tty1