Automatically set the hostname during Kickstart Installation

When you want to install linux on a large number of servers kickstart approach is a very good one. But what about hostname?! You have many choices:

  • A kickstart file for each server, but come on... what kind the choice is this?!
  • A kickstart file for all servers and set hostname after installation (manually on every single server, or using a script)

Fortunately for you there is a third option: Automatically set the hostname during Kickstart Installation. I wish to take credit for this, but this will be so unfair for the guy which wrote an article about this.

I won't get to long with the story so... let's get started.

The trick is to pass the kernel a parameter and use it in our kickstart file. What if you were to pass a parameter that it doesn't recognize? In most cases, it will probably ignore it, but it will still in the kernel list. We can check kernel parameters by issuing the following command:

[codesyntax lang="bash"]

cat /proc/cmdline

[/codesyntax]

So what if we can pass a parameter with desired hostname to the kernel? With a very simple script we can parse the output of the above command and look for our parameter.

[codesyntax lang="bash"]

#!/bin/sh

echo "network --device eth0 --bootproto dhcp --hostname localhost.localdomain" > /tmp/network.ks

for x in `cat /proc/cmdline`; do
        case $x in SERVERNAME*)
            eval $x
        echo "network --device eth0 --bootproto dhcp --hostname ${SERVERNAME}" > /tmp/network.ks
                ;;
            esac;
done

[/codesyntax]

Here we are looking for SERVERNAME end evaluates that value into a variable. We will then echo the network setup with the variable (which we will use as part of the hostname setup) and redirect into the file under /tmp. Then we will include that file in our installation section.

You may ask yourself what is all about this line:

[codesyntax lang="bash"]

echo "network --device eth0 --bootproto dhcp --hostname localhost.localdomain" > /tmp/network.ks

[/codesyntax]

in the script above?! Well, if you don't pass the SERVERNAME to the kernel, then /tmp/network.ks will not be created and your installation will fail.

So this is my kickstart file for a minimal CentOS 6.3 installation:

install
firewall --disabled
url --url="ftp://ftp.ines.lug.ro/centos/6.3/os/i386"
network --bootproto=dhcp --device=eth0
rootpw --iscrypted YOUR_ENCRYPTED_PASSWORD
text

%include /tmp/network.ks

keyboard us
lang en_US
selinux --disabled
skipx
logging --level=info
reboot
timezone --utc Europe/Bucharest
bootloader --location=mbr --driveorder=sda,sdb --append="console=tty0 console=ttyS0,115200N1"
zerombr
clearpart --all --initlabel
part / --fstype="ext4" --size=10000
part swap --fstype="swap" --size=8000
part pv.01 --fstype="ext4" --grow --size=1
volgroup vg0 pv.01
logvol /data --vgname=vg0 --percent=90 --name=lv0 --fsoptions=noatime --fstype=ext4 --size=1 --grow

%packages
@core
sed
perl
less
dmidecode
bzip2
iproute
iputils
sysfsutils
rsync
nano
mdadm
setserial
man-pages.noarch
findutils
tar
net-tools
tmpwatch
lsof
python
screen
lvm2
curl
ypbind
yp-tools
smartmontools
openssh-clients
acpid
irqbalance
which
bind-utils
ntsysv
ntp
man
mysql
postfix
chkconfig
gzip
%end

%pre
#!/bin/sh

echo "network --device eth0 --bootproto dhcp --hostname localhost.localdomain" > /tmp/network.ks

for x in `cat /proc/cmdline`; do
        case $x in SERVERNAME*)
               eval $x
        echo "network --device eth0 --bootproto dhcp --hostname ${SERVERNAME}" > /tmp/network.ks
                ;;
            esac;
    done
%end

%post

cat > /etc/cron.d/ntpdate < /dev/null 2>&1
EOF

chkconfig ntpd on
chkconfig sshd on
chkconfig ypbind on
chkconfig iptables off
chkconfig ip6tables off
chkconfig yum-updatesd off
chkconfig haldaemon off
chkconfig mcstrans off
chkconfig sysstat off

cat > /etc/motd <> /etc/motd

echo >> /etc/motd
%end

  1. Hi - I stumbled on this page while searching on Google. Please help me a bit more. Where does the SERVERNAME value come from?

  2. Hello Kevin - The value of SERVERNAME is the hostname of the machine you want to install. You have to add SERVERNAME=hostname as kernel parameter before booting from network (in the PXE boot menu).

  3. Hey, thanks for the tips. Unfortunately, I couldn't get your approach to work, but did realise that you can set a hostname attribute in your boot command.

    So, instead of "SERVERNAME=host", I just added hostname=host as a kernel parameter and skipped everything else. It's worked a charm!

  4. You can also add a command to your (non-chrooted) pre-script: dhclient.
    That command WILL set the hostname, where the other DHCP requests done by the kickstart won't.

    Of course your DHCP server will have to send the hostname ('option host-name ""' per client or just 'use-host-decl-names on;').

    • Thank you Elmar for your comment. One of my teachers had a saying: "If there are more than one solutions, the student will choose the most complicated one". He was right. My approach is different and more complicated than yours. I will test it with the first opportunity.

    • Thanks, that's a really simple fix to the problem.

  5. Douglas Sterner

    how easy would it to be to modify the case $x to also grab ip, netmask, gateway? Thanks,

  6. Using RHEL6.5 I am unable to see the kernel parameter when I press TAB key on an item. All I see is vmlinuz and it dosn't seem to accept the servername flag. Is there a workaround?

  7. I just tested this on RHEL 7.2 and it still works!

  8. if i want to parse in static ip instead of dhcp will it be possible to be to modify the case $x to also grab ip, netmask, gateway? meaning in the pxe boot when i press tab i add in these additional fields

    • the following should work for fedora, centos and rhel

      # Mainsection

      # Keyboard layouts
      keyboard 'de'

      # Desktop Environment
      xconfig --defaultdesktop=GNOME --startxonboot

      # Other stuff ...

      # Network information (see the pre% section below for generating /tmp/network.ks)
      %include /tmp/network.ks

      # Other stuff ...

      # pre% section
      %pre

      # Define clients ("mac-address" "ipv4-address" "hostname")
      clients=("00:00:00:00:A0:01" "10.0.0.201" "client-01")
      clients+=("00:00:00:00:B0:02" "10.0.0.202" "client-02")
      clients+=("00:00:00:00:C0:03" "10.0.0.203" "client-03")
      clients+=("00:00:00:00:D0:04" "10.0.0.204" "client-04")
      clients+=("00:00:00:00:E0:05" "10.0.0.205" "client-05") # etc. ...

      # Grep the ethernet adapter name usually the first in /sys/class/net
      ethernet="$(ls /sys/class/net | head -n1 | cut -d " " -f1)"

      # Grep ethernet adapters mac address TO UPPERCASE
      mac="$(cat /sys/class/net/"$ethernet"/address | tr a-z A-Z)"

      # Define domainname (if needed)
      domain="your.domain.com"

      # Define default gateway
      gateway="10.0.0.1"

      # Define subnetmask
      netmask="255.255.255.0"

      # Define dns servers
      dns1="10.0.0.2"
      dns2="10.0.0.3"

      # Define search domains (if needed)
      search="your.domain.com other.domain.com another.domain.com"

      # iterate trough the clients
      for (( i=0; i /tmp/network.ks

      # setup static ipv4 configuration
      nmcli con mod "$ethernet" connection.autoconnect yes
      nmcli con mod "$ethernet" ipv4.addresses "${clients[i+1]}/24"
      nmcli con mod "$ethernet" ipv4.gateway "$gateway"
      nmcli con mod "$ethernet" ipv4.dns "$dns1,$dns2"
      nmcli con mod "$ethernet" ipv4.dns-search "$search"
      nmcli con mod "$ethernet" ipv4.method manual
      nmcli con down "$ethernet"; nmcli con up "$ethernet"
      fi
      done

      %end

  9. Inject hostname into kickstart | Knowledge Base - pingback on 22 June 2017 at 16:10
  10. Ok, I'll try the for loop at the end again.

    # iterate trough the clients
    for (( i=0; i /tmp/network.ks

    # setup static ipv4 configuration
    nmcli con mod "$ethernet" connection.autoconnect yes
    nmcli con mod "$ethernet" ipv4.addresses "${clients[i+1]}/24"
    nmcli con mod "$ethernet" ipv4.gateway "$gateway"
    nmcli con mod "$ethernet" ipv4.dns "$dns1,$dns2"
    nmcli con mod "$ethernet" ipv4.dns-search "$search"
    nmcli con mod "$ethernet" ipv4.method manual
    nmcli con down "$ethernet"; nmcli con up "$ethernet"
    fi
    done

  11. Nope, this website does not accept this code, sorry . . .

Reply to Torsten ¬
Cancel reply


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.