Kickstart installation problem

Hi everyone,
I am trying to master the kickstart installation. While my ks.cfg file was basic (actually copied from the manually installed system) it worked OK. However, when I added some staff to it, the system stopped booting following the post-install reboot. I am attaching the screenshot of the last part of the screen log that was displayed at the boot time.
Below is the ks.cfg file (I commented out the last part of it, namely related to the VM creation and installing the latest Linux updates just to keep it simple while I am still learning/experimenting.

# Originally Generated by Anaconda 34.25.2.10
# Originally Generated by pykickstart v3.32
#version=RHEL9

# ---------- ---------- ---------- 1. INSTALLATION OPTIONS ---------- ---------- ----------

# Use graphical install
graphical
repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
#network  --bootproto=static --device=ens1f0np0 --gateway=192.168.0.18 --ip=192.168.0.152 --nameserver=8.8.8.8,8.8.4.4,192.168.0.38 --netmask=255.255.255.0 --ipv6=auto --activate
#
#   ATTENTION! The hostname should be checked and adjusted before each and every system installation!
#              The network setup is also a subject for verification. By default the installed system
#              is supposed to use DHCP, thus possessing a dynamic IP address, however it is up to a
#              customer to decide.
#
network  --bootproto=dhcp --device=ens1f0np0 --noipv6 --activate
network  --hostname=DL380

# Use CDROM installation media
cdrom

# ---------- ---------- ---------- 2. PACKAGES ---------- ---------- ----------

%packages
@^graphical-server-environment
@ftp-server
@graphical-admin-tools
@security-tools
@system-tools
@virtualization-client
@virtualization-tools
@virtualization-platform
@virtualization-hypervisor
telnet
telnet-server
mtr
ftp
vsftpd

%end

# Run the Setup Agent on first boot
firstboot --enable

# Generated using Blivet version 3.6.0
ignoredisk --only-use=sda
# Partition clearing information
clearpart --all --drives=sda --initlabel
zerombr
autopart

# System timezone
timezone America/Los_Angeles --utc

# Root password
rootpw --iscrypted $6$kcKcYNBU1v34K2ED$kyJo5qatVwOb197HlsQMv9XNBxjzPhgudK7dBJSOCLtkIHDXsrJcB5tcqsTaiAYrsjvws7jNLsbas3rSVvwGL0
user --groups=wheel --name=hsq --password=$6$0XZv7UczFR.ZkP2/$yYpNj2CNkPcg66k2uKpf8ik0BkXTCHNYRtzZkxtrdDOWNbm0F2AzLMcL3LXTFTCqtbYXs7Zvkg5lW0O68xXK3/ --iscrypted --gecos="hsq"

# ---------- ---------- ---------- 3. PRE-REBOOT POST-INSTALLATION PHASE I ---------- ---------- ----------

# Perform the first step of the two-phase installation (pre-reboot) with logging
%post --nochroot --log=/mnt/sysimage/root/pre-reboot.log

echo "Started pre-reboot installation phase (phase I)..."

DEV=$(blkid -L OEMDRV)
echo "Copying auxiliary files from ${DEV} to the destination"
mkdir -p /mnt/installation_source
mount "$DEV" /mnt/installation_source
mkdir -p /mnt/sysimage/root/Downloads/installation
cp -v /mnt/installation_source/VM.xml /mnt/sysimage/root/Downloads/installation
umount /mnt/installation_source
rmdir /mnt/installation_source

# ----- ----- FOR debugging ONLY: ----- -----                                                                           TEST
echo "List /root/Downloads"
ls -l -a /mnt/sysimage/root/Downloads
echo "List /root/Downloads/installation"
ls -l -a /mnt/sysimage/root/Downloads/installation
# ----- -----  ----- -----  ----- ----- -----

echo "Create phase I completion flag"
touch /mnt/sysimage/root/kickstart_ph_I_complete

echo "Rebooting..."
sleep 5
/sbin/reboot

%end

# ---------- ---------- ---------- 4. POST-REBOOT POST-INSTALLATION PHASE II ---------- ---------- ----------

# Perform the phase II (post-boot) with its own logging
%post --log=/root/post-reboot.log

echo "Started post-reboot installation phase (phase II)..."
#!/bin/bash

# ********** ATTENTION! **********
# System-dependent parameters that have to be changed for each and every system
# The definitions below would be used if the server should use static IP address (no DHCP)
#
USE_DHCP="YES"
#
if [ $USE_DHCP != "YES" ]; then
    NEW_IP="192.168.222.101"
    NEW_GW="192.168.0.38"
    NEW_DNS1="8.8.8.8"
    NEW_DNS2="8.8.4.4"
    NEW_DNS3="192.168.0.38"
fi
# ******************************

# Just in case check if the phase I completed
if [ -f /root/kickstart_ph_I_complete ]; then
    echo "Verified phase I completion. Proceed with phase II"
else
    echo "ERROR: missing phase I completion flag!"
    exit 1
fi

# Create a systemd service that will execute all necessary post-reboot tasks
echo "Create a first boot service: /etc/systemd/system/firstboot.service"
cat <<EOF > /etc/systemd/system/firstboot.service
#------------------------------
[Unit]
Description=Run first-boot tasks
After=network.target

[Service]
Type=oneshot
ExecStart=/root/firstboot.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

EOF
#------------------------------
# Make the service executable
chmod +x /etc/systemd/system/firstboot.service

FIRSTBOOT_SCRIPT="/root/firstboot.sh"

# Enable the service
systemctl enable firstboot.service

# Create the first boot script
echo "Create the first boot script: ${FIRSTBOOT_SCRIPT}"

cat <<EOF > $FIRSTBOOT_SCRIPT
#------------------------------

#!/bin/bash
# Ensure first boot logging
exec > /root/firstboot.log 2>&1

# Start the virtualization management service
echo "Activate libvirtd"
systemctl start libvirtd
systemctl enable libvirtd
newgrp libvrt
usermod -aG libvirt root
usermod -aG libvirt hsq

# Configure FTP server and allow it through firewall
echo "Configure FTP server"
systemctl start vsftpd
systemctl enable vsftpd
cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
sed -i "/croot_local_user/c\chroot_local_user=YES" /etc/vsftpd/vsftpd.conf
sed -i "$ a\allow_writeable_chroot=YES" /etc/vsftpd/vsftpd.conf
systemctl restart vsftpd
firewall-cmd --zone=public --add-service=ftp –permanent
firewall-cmd --reload

# Increase the X session and SSH session timeouts to 1 hour
echo "Increase session timeouts"
sed -i "/ClientAliveInterval/c\ClientAliveInterval 3600" /etc/ssh/sshd_config
sed -i "/ClientAliveCountMax/c\ClientAliveCountMax 3"    /etc/ssh/sshd_config
runuser -l hsq -c 'dconf write /org/gnome/desktop/session/idle-delay "uint32 3600"'

# ********** ATTENTION! **********
# System-dependent parameter that has to be unique for each and every system
# Note that the hostname is supposed to be 6 characters long, the first three
# letters should encode an intended customer's site, the 4th and 5th should be
# "LH", and the sixth should match the last charadtere of the planned OpenVMS
# nodename of the VM guest. If necessary, "LH" letters can be changed but the
# overall structure is better to be preserved.
# ********************************
NEW_HOST="ABCLHB"

echo "Changing the host name to $NEW_HOST"
hostnamectl set-hostname "$NEW_HOST"

# If the IP address has to be restricted and belong to a particular subnet,
# the following command template should be modified accordingly and enabled
# nmcli con mod ens1f0np0 ipv4.routes "192.168.222.0/24"

# Create the network bridge
echo "Create network bridge"

EOF

# Create a variable part of the command file
if [ $USE_DHCP == "YES" ]; then
    # ----- Using DHCP -----
    cat <<EOF >> $FIRSTBOOT_SCRIPT
nmcli connection add type bridge autoconnect yes con-name br0 ifname br0
nmcli connection modify br0 ipv4.method auto
EOF
else
    # ----- Not using DHCP -----
    cat <<EOF >> $FIRSTBOOT_SCRIPT
nmcli connection modify br0 ipv4.addresses $NEW_IP/24
nmcli connection modify br0 ipv4.gateway $NEW_GW
nmcli connection modify br0 ipv4.dns $NEW_DNS1 +ipv4.dns $NEW_DNS2 +ipv4.dns $NEW_DNS3
nmcli connection modify br0 ipv4.method manual
EOF
fi

# Continue command file creation
cat <<EOF >> $FIRSTBOOT_SCRIPT
nmcli connection add type bridge-slave ifname ens1f0np0 master br0
nmcli connection modify br0 ipv6.method disabled
nmcli connection up br0
nmcli connection up bridge-slave-ens1f0np0

# Verify the bridge was created successfully - these commands are to be used for debugging purposes ONLY!               TEST
nmcli connection show
ip address show br0

# Add the Virtial Machine Manager utility (VMM) to the favorites list
echo "Add VMM to the favorites list"
gsettings set org.gnome.shell favorite-apps "$(gsettings get org.gnome.shell favorite-apps | sed "s/]$/, 'virt-manager.desktop']/")"

echo "Remove the phase I completion flag"
rm -f /root/kickstart_ph_I_complete
echo "Disable firstboot service"
systemctl disable firstboot.service

# Our rule for the 6-characters nodenames stays true for the Linux hosts
#echo "Create target VM configuration file"
#NEW_VM_NAME=${hostname:0:3}_${hostname:5:1}
#if [-f /root/Downloads/installation/VM.xml ]; then
#    CONF_FILE="/root/Downloads/installation/${NEW_VM_NAME}.xml"
#    cp /root/Downloads/installation/VM.xml $CONF_FILE
#    NEW_UUID=$(uuidgen)
#    NEW_MAC=$(openssl rand -hex 3 | sed 's/\(..\)/\1:g; s/.$//' | awk '{print "52:54:00:" $0}')
#
#    # Update configuration file
#    sed -i "s|<name>.*</name>|<name>${NEW_VM_NAME}</name>|" $CONF_FILE
#    sed -i "s|<uuid>.*</uuid>|<uuid>${NEW_UUID}</uuid>|" $CONF_FILE
#    sed -i "s|<title>.*</title>|<title>${NEW_VM_NAME}</title>|" $CONF_FILE
#    sed -i "s|<description>.*</description>|<description>${NEW_VM_NAME} system</description>|" $CONF_FILE
#    sed -i "s|<mac address='.*'/>|<mac address='${NEW_MAC}'/>|" $CONF_FILE
#
#    virsh define $CONF_FILE
#else
#    echo "ERROR: missing VM configuration file VM.xml !"
#    exit 1
#fi

#echo "Start the VM to create the storage"
#virsh start $NEW_VM_NAME
#while [[ "$(virsh domstate $NEW_VM_NAME)" != "running" ]]; do
#    sleep 5
#done

#echo "Stop the VM now"
#virsh destroy $NEW_VM_NAME

# Install latest system updates
#echo "Installing latest system updates"

#dnf makecache
#dnf check-update
#dnf -y upgrade

#echo "Remove kickstart boot option"
#sed -i 's/inst.ks=[^]*//g' /etc/default/grub
#grub2-mkconfig -o /boot/grub2/g

#/sbin/reboot
EOF

%end

What could go wrong?

You do explicitly reboot in the post. The system should then load the installed system, rather than reload the installer. (If it would reboot to installer, then the entire installation would restart from scratch rather than continue the post.) I’m quite sure that that is not correct.

Do in post only the things that can/must be done before reboot.
One of those would be to deploy the script that has to run after (first) reboot.
The one that does all the “after reboot” tasks.


You have “system-dependent parameters” in the kickstart, i.e. separate kickstart for each system?
Then you can, for example,
modify the network --bootproto=dhcp --device=ens1f0np0 --noipv6 --activate
if IP config has to be manual.

It seems you are still in the kickstart phase and you do not have the dbus session open to change gsettings.

One solution would be to add a autostart script that runs at the first login to change gnome settings.

I used to have lots of things in %post, but nowadays I tend to keep kickstart to a minumum and run ansible after the first boot - seems more flexible to me.

jlehtone and robbott, thank you for your help! I will definitely look into it. However, I would like to note, that - at least according to what I know - the reboot is allowed during the kickstart process. That is why I hve two %post sections in my ks.cfg: %post --nochroot (for the pre-reboot functionality) and %post (assuming --chroot - for the post-reboot tasks). I agree though that now having two secions does not have much sense, and I can simplify the configuration eliminating the second section… but I cannot see why it can break the functionality.
Best regards,
Mike Faynberg

Could you point to the documentation about that?

jlehtone, thank you - upon more thorough investigation I discovered my understanding was wrong, and kickstart installation cannot continue after reboot. Sorry about my mistake. That means I have to create a first-boot command file and a service, which would run that file after the system starts for thte first time…
Best regards,
Mike Faynberg

1 Like