VMware Cloud Community
SuperSpike
Contributor
Contributor

ESXi 4.1 Scripted Install

Hopefully this is the right forum for this post.

I am having problems porting my ESX 4 "classic" kickstart config and shell scripts to ESXi 4.1. Obviously ESXi does not have a traditional bash environment that ESX classic had. This is presenting problems for me in how I pass variables such as hostname, IP address and default gateway.

Here is a snippet of the %pre section of my master kickstart file that works in a traditional ESX service console environment. All credit goes to Gabe at .

-


%pre

#this %pre bit comes from

#this sets $* to the boot line text

set -- `cat /proc/cmdline`

  1. now we simply loop through the elements of the string and if it starts with "ESX"

  2. we eval it to set a variable so when we echo the network line below it will have

  3. these vars in the statement. It gets fed back into the kickstart with the %include statement

for x in $*; do

case $x in ESX*)

eval $x

  1. put it into a file for use in the %post section

echo $x >> /tmp/networksetup.sh

;;

esac;

done

  1. and now we record our network line for use in the kickstart section...

  2. This gets written to a file in the /tmp RAM drive. It is read into the

  3. kickstart by the %include /tmp/ks_network.sh statment above

cat << EOL >> /tmp/ks_network.sh

network --hostname=$ --ip=$ --bootproto=static --netmask=255.255.255.128 --gateway=$ --nameserver=192.168.1.50 --addvmportgroup=0

EOL

-


Then in my PXE file, all I have to do is pass the variables...

label ESX1

kernel images/esx/4.0/vmlinuz

append ESXIP=192.168.80.12 ESXHOSTNAME=esx1.mydomain.local ESXDGW=192.168.80.1 ksdevice=vmnic0 initrd=/images/esx/initrd.img mem=1024M ks=http://buildbox.mydomain.local/pxe-install/kickstart/esx4u1-master.cfg

The nice thing about this is that I don't have to maintain a unique kickstart.cfg file for every host that I want to build. I just add a line to my PXE file and pass unique variables.

Enter ESXi. Now I have a problem. For starters, there is no such thing as /proc/cmdline in ESXi. The "for" statement is definitely not working as /tmp/networksetup.sh never gets created. Also (and more importantly), my variables are not getting properly passed from weasel to the interpreter (busybox or python). Weasel sees them (verified in /var/log/weasel.log), but when the /tmp/ks_network.sh gets built, there is nothig next to --hostname=, --ip= or --gateway=.

The examples given in the ESXi scripted install PDF are limited. I could go back to square one and start making a kickstart file for each host, but that sort of defeats the purpose and brings version control and kickstart config file consistency issues into the mix.

Anyone have any ideas on how to accomplish this? Anyone having any luck porting their old automation scripts over to ESXi?

Thanks in advance.

@Virtual_EZ
0 Kudos
13 Replies
Gilly
Contributor
Contributor

Were you ever able to figure this out? I am now in the same situation with the same question...

Any ideas?

Thanks,

Joe

0 Kudos
SuperSpike
Contributor
Contributor

Hi Joe,

Sorry, I haven't gotten anywhere with this yet. The short answer is that if I want to create a unique ks.cfg file for every single host I have, things will work fine. But if I want to maintain a single master ks.cfg file and pass the host-specific parameters as boot options, it doesn't work.

I'm hoping to find someone out at VMworld who can help me with this. I haven't had the time to dedicate to troubleshooting. What I do know is that when I look at weasel.log, it says that it skips all of the boot parameters that I pass. However, I saw this in the weasel.log file in ESX 4.0 Update 1 as well, so I'm not sure if that's relevant. I think the issue is that I cannot read from /proc/cmdline because it doesn't exist in the busybox ash shell of ESXi.

I'll update this thread if I eventually figure it out.

@Virtual_EZ
0 Kudos
sumavisor
Contributor
Contributor

Use this command in your %post to get the command line ( what used to be /proc/cmdline)

vsish -e get /system/bootCmdLine | grep 'command line'

Make sure that for your pxe file that you put the arguments first. Here's what mine looks like:

#install esxi4.1-x86_64-base

DEFAULT xCAT

LABEL xCAT

KERNEL xcat/esxi4.1/x86_64/mboot.c32

APPEND xcat/esxi4.1/x86_64/vmkboot.gz nofb utf8 ks=http://rock/install/autoinst/premio ksdevice=vmnic0 console=tty0 console=ttyS0,115200n8r noipv6 IPADDR=asdfasdfasdf NETMASK=asdfasdf BLAH=blah --- xcat/esxi4.1/x86_64/vmkernel.gz --- xcat/esxi4.1/x86_64/sys.vgz --- xcat/esxi4.1/x86_64/cim.vgz --- xcat/esxi4.1/x86_64/ienviron.vgz --- xcat/esxi4.1/x86_64/install.vgz

Then using the vsish command above you can see those arguments and grep for them.

0 Kudos
SuperSpike
Contributor
Contributor

Thanks a lot for this feedback. It's getting me pointed in the right direction. I can now read from the boot command line using vsish. However...

How can I set the vsish commands to a variable so that I can call them in the %post section?

If I try something like...

$IPADDR = vsish -e get /system/bootCmdLine | awk '{print $10}' | sed 's/IPADDR=//'

$NETMASK = vsish -e get /system/bootCmdLine | awk '{print $11}' | sed 's/NETMASK=//'

$HOSTNAME = vsish -e get /system/bootCmdLine | awk '{print $12}' | sed 's/HOSTNAME=//'

network --hostname=$HOSTNAME --device=vmnic0 --ip=$IPADDR --bootproto=static --netmask=$NETMASK --gateway=192.168.15.1 --nameserver="192.168.15.100" --addvmportgroup=0

the -ash shell responds with:

-ash: =: not found

It doesn't seem to like the "=" operator.

Would you mind posting your ks.cfg file?

@Virtual_EZ
0 Kudos
Gilly
Contributor
Contributor

I am out of the office until Monday, August 23. If you need immediate assistance, please contact Rick Counts.

Thanks,

Joe

This e-mail contains information which (a) may be PROPRIETARY IN NATURE OR

OTHERWISE PROTECTED BY LAW FROM DISCLOSURE, and (b) is intended only for the

use of the addressee(s) named above. If you are not the addressee, or the

person responsible for delivering this to the addressee(s), you are notified

that reading, copying or distributing this e-mail is prohibited. If you have

received this e-mail in error, please contact the sender immediately.

0 Kudos
sumavisor
Contributor
Contributor

How can I set the vsish commands to a variable so that I can call them in the %post section?

If I try something like...

$IPADDR = vsish -e get /system/bootCmdLine | awk '{print $10}' | sed 's/IPADDR=//'

$NETMASK = vsish -e get /system/bootCmdLine | awk '{print $11}' | sed 's/NETMASK=//'

$HOSTNAME = vsish -e get /system/bootCmdLine | awk '{print $12}' | sed 's/HOSTNAME=//'

network --hostname=$HOSTNAME --device=vmnic0 --ip=$IPADDR --bootproto=static --netmask=$NETMASK --gateway=192.168.15.1 --nameserver="192.168.15.100" --addvmportgroup=0

the -ash shell responds with:

-ash: =: not found

It doesn't seem to like the "=" operator.

I notice you have the $ before the variable. When assigning, I would do something like:

IPADDR=`vsish -e get /system/bootCmdLine | awk '{print $10}' | sed 's/IPADDR=//'` (notice not $IPADDR, just IPADDR)

I also would just use DHCP in the initial kickstart variable stuff and then use this in the %post section to statically set the network. (since you'll probably need to set up the vswitch and all that jazz too). So something like:

%post --unsupported --interpreter=busybox

IPADDR=`vsish -e get /system/bootCmdLine | awk '{print $10}' | sed 's/IPADDR=//'` # notice not $IPADDR, just IPADDR, also notice back ticks

NETMASK=`vsish -e get /system/bootCmdLine | awk '{print $11}' | sed 's/NETMASK=//'`

esxcfg-vmknic -i $IPADDR -n $NETMASK "Management Network"

...

Would you mind posting your ks.cfg file?

I haven't had need of this yet so I don't have a kickstart file that does it all the way.

In xCAT (which is what I use, shameless plug) there is a script that sets up the file as part of the stateless install that uses this information.

The file is here

Hope that helps!

0 Kudos
cnienhaus
Contributor
Contributor

Did you ever get this worked out?  I'm having the same issue trying to get input during pre to pass to ipaddress.  My small test script using python just freezes the the install.  Here is my simple test code to see if I can get input using python.

vmaccepteula
rootpw letmein
autopart --firstdisk --overwritevmfs
install cdrom
network --bootproto=dhcp --device=vmnic0


#%include /tmp/partconfig

%pre --unsupported --interpreter=python
import commands
import os
import sys
import re
import time

ip_addr = raw_input('IP address: ')

0 Kudos
lamw
Community Manager
Community Manager

Is there any particular reason you're using kickstart which is generally meant for automated and unattended installation and injecting a manual process such as requiring user input? You can easily solve this by either relying on DHCP to provide the correct IP Address and using that information to then static the ESXi host, generally what I would recommend and have used in the past. The other alternative is completely DHCP just for the initial boot and then performing a "wget" which is what the original OP posted to then statically assign the ESX(i) host based on a configuration file.

0 Kudos
cnienhaus
Contributor
Contributor

For the most part I want the installation to be automated, but would like to do a little customization for each install before starting.  The reasons for this are:

We want one image for multiple global sites.  All sites have different subnets.  Our corporate policy is to assign all servers with static IP’s and not to have dhcp servers accessible to the server network.  We were offering the option to customize partition also, but I think with esxi we will drop that.  My example script was just a test to see if I could pass value to variable in python like we were doing in the original bash script.  See below.  I snipped out parts not pertaining to my question.  If there is a better way of doing this, please advise.  Thanks.

< start ks snip>

accepteula

# keyboard us

# Read network information from a file we are going to populate in the %pre section

# of this kixstart script.

%include /tmp/networkconfig

%include /tmp/partconfig

auth  --enablemd5 --enableshadow

install cdrom

rootpw --iscrypted <encryptpass>

timezone --utc 'GMT'

# Read partition information from a file we are going to populate in the %pre section

# This allows me to create local vmfs with "hostname:storage1" and I've adjusted the sizes

# on my service console partitions.

%pre --interpreter=bash

#################################

###  Get network information  ###

#################################

# Clear screen prior to prompting for input and change to virtual terminal 1

# vSphere will only work on tty1 to read input

exec </dev/tty1 >/dev/tty1

chvt 1

header ()

{

clear

echo

echo "################################################################"

echo "###            companyname VMWare ESX 4.0 Scripted Install            ###"

echo "###                                                          ###"

echo -e "### \033[31m \033[5m** WARNING ALL VISIBLE SAN LUNS WILL BE EREASED ** \033[0m     ###"

echo "###                                                          ###"

echo "###       ** BE SURE ETH0 NETWORK INTERFACE IS CONNECTED **  ###"

echo "###             company Engineering Script Version 1.5           ###"

echo "###                                                          ###"

echo -e "### \033[31m \033[5m   ** BE SURE TO DISCONNECT ALL SAN FIBER CABLES ** \033[0m    ###"

echo "################################################################"

echo

}

# Get user input

while [ "$fqdn" == "" ] ;do

header

echo "Please Enter FQDN for ESX Host below:"

echo -n "Ex: hostname.companynamex.com : "

read fqdn

done

while [ "$ipnew" == "" ] ;do

header

echo "*** Important *** note: This scripted install assumes  "

echo "eth0 network adapter is connected and linked."

echo ""

echo -n "Please Enter Service Console IP Address: "

read ipnew

done

while [ "$companynamemask" == "" ] ;do

header

echo ""

echo -n "Please Enter Service Console IP Subnet Mask: "

read companynamemask

done

while [ "$companynamegatew" == "" ] ;do

header

echo ""

echo -n "Please Enter Service Console Default gateway: "

read companynamegatew

done

while [ "$companynamepdns" == "" ] ;do

header

echo ""

echo -n "Please Enter Primary DNS Server: "

read companynamepdns

done

while [ "$companynamesdns" == "" ] ;do

header

echo ""

echo -n "Please Enter Secondary DNS Server: "

read companynamesdns

done

echo ""

echo -n "Please Confirm the Service Console IP Settings:"

echo ""

echo ""

echo -n "ESX Host name: $fqdn"

echo ""

echo -n "IP:           $ipnew"

echo ""

echo -n "Subnet Mask:   $companynamemask"

echo ""

echo -n "Gateway:       $companynamegatew"

echo ""

echo -n "Pri DNS:       $companynamepdns"

echo ""

echo -n "Sec DNS:       $companynamesdns"

echo ""

echo ""

echo -e " \033[31m \033[5m *** WARNING ALL VISIBLE/SAN LUNS WILL BE EREASED *** \033[0m"

echo -e " \033[31m \033[5m *** DISCONNECT ALL FIBER SAN CABLES NOW!! *** \033[0m"

while [ "$check1" != "true" ]

do

      echo ""

      echo -n "Is the above information correct (type y or n) ? "

      read opt

      case $opt in

            "yes"|"y"|"no"|"n") check1="true"

            ;;        

          

            *)    check=1"false"

            ;;

      esac

done

    if [ "$opt" != "yes" ] && [ "$opt" != "y" ] ; then

       echo ""

       echo "##############################################"

       echo "company ESX 4.0 Installation FAILED !!!!! "

       echo ""

       echo "Please reboot the ESX Host to Restart Installation."

       echo "##############################################"

       read instfail

       exit 1

    fi

< mid snip>

EOF

# Write the networkconfig file to be used by the Weasel install

# Using the "--addvmportgroup=0" option because another script will define my specific port groups

cat <<EOF> /tmp/networkconfig

network --device=vmnic0 --bootproto=static --ip=$ipnew --netmask=$companynamemask --gateway=$companynamegatew --nameserver="$companynamepdns,$companynamesdns" --hostname=$fqdn --vlanid=0 --addvmportgroup=0

EOF

<end snip>

0 Kudos
lamw
Community Manager
Community Manager

Take a look at this post - http://www.virtuallyghetto.com/2011/05/semi-interactive-automated-esxi.html It should give you a good starting point and hopefully what you're trying to accomplish.

0 Kudos
cnienhaus
Contributor
Contributor

Very nice!!! thanks for your help. I saw some chatter above this post about using this method, but you have laid this out so quite clear I can cut and paste it.  I appreciate your time, and knowledge.  Your method for formatting the input is exactly what I needed.  Thanks again!

0 Kudos
lamw
Community Manager
Community Manager

Cool. You're always welcome to donate - http://www.virtuallyghetto.com/p/how-you-can-help.html Smiley Happy

0 Kudos
Buck1967
Contributor
Contributor

I must have used a similar example for my host builds for 4.0.

Is there a way to prompt for the entries within the KS script file rather than having to specify them on the on the loader?

I have a menu entry for each of our data centers and have all the other properties hardcoded.

# Get user input
while [ "$fqdn" == "" ] ;do
header
echo "Please Enter FQDN for ESX Host "
echo -n "Enter Host name: "
read fqdn
done

while [ "$ipnew" == "" ] ;do
header
echo "Important note: This scripted install assumes vmnic0 is a VLAN trunk "
echo " The VLan that the service console will be DEFAULTED TO VLAN 10"
echo ""
echo "Please Enter Main Service Console "
echo -n "IP Address (ie. 10.10.10.XXX): "
read ipnew
done

I than read the 2 values and set the hostname and IP. Everything else is than always consistent in the build process and is very dummy proof.

Buck

0 Kudos