Automatically Provisioning Fujitsu Servers using iRMC and the ServerView Scripting Toolkit

Short Guide to Provisioning Fujitsu Primergy Servers

This writeup is about provisioning Fujitsu servers automatically in a Linux environment.

Most Fujitsu servers can be provisioned non-interactively. This is acheived by using two facilites. These are the iRMC RESTful API, and the ServerView Scripting Toolkit for Linux (STK).

Typically a series of configuration changes need to be made to various hardware components. This could be for things like configuring RAID volumes, enabling SR-IOV, enabling the iSCSI personality on the network adapter, and more. Additionally, installation media needs to be made avalable, mounted (typically remotely) and the system configured to boot from it.

There are two primary vectors for provisioning orchestration of bare-metal assets. The Preboot eXecution Environment which uses DHCP, and by generating and mounting custom iso images. In either case, a key element is the isolinux config. This is where variables are passed via kernel arguments into the installation environment. This writeup will focus on later method.

The Given Scenario

In this scenario there are three machines: the local workstation, the serverview workspace, and the CIFS server.

The operating system of choise is Red Hat Enterprise Linux 7.4 (RHEL74).

There are two network planes: the management net and the user net. The Baseboard Management Controllers (BMCs) are connected to the management net, which is physically isolated from the user net. It is not possible to route between them. DHCP PXE orchestration is not available due to networking constraints.

Net Name IPv4 Addr
management 10.1.33.0/16
user 96.112.145.0/24

The domain is west.adri.codes.

A CIFS server is used in this scenario to host the installation media. The CIFS server is located at 10.1.57.100.

A number of variables need to be provided at installation time. These variables are unique for every machine. These parameters need to be injected into the isolinux config, generally installed at isolinux/isolinux.cfg. In this scenario these properties include ip, nameserver, bond and some custom properties that get loaded by kickstart.

RHEL74 installation packages are available over HTTP.

There are three different hardware profiles. One optimized for Hadoop HDFS datanode and Yarn nodemanger. These have high performance SSDs. Another for Virtual Desktop Infrastructure (VDI). The third profile is for diskless, general purpose compute nodes that run virtual machines or containers.

The General Procedure

Generally speaking, there are two major parts to setting up automated provisioning of Fujitsu servers using STK.

  1. Setup STK.
  2. Provision machines.

Setup STK

Setting up the environment requires and NFS server to host the STK repository, which gets mounted by the target server during the installation process. A workspace for generating custom inital RAM disks is also required. Additionally, the RedHat installation media must be unpacked to a separate directory for generating a customized installation image based on the RedHat boot image.

The following items are required to setup STK and prepare the environment for massive automated provisioning.

  1. Setup STK repo on NFS that gets mounted by target servers.
  2. Setup working directory for building initial ramdisks and isolinux configs.

Once the environment is setup correctly servers can be provisioned non-interactively.

  1. Update the BIOS and iRMC firmware.
  2. Build the initial ramdisk.
  3. Generate the installation media.
  4. Copy installation media to CIFS server.
  5. Configure iRMC to boot custom installation media.
  6. Reboot into the installation program.

STK has stkMode which has two settings: SAVE and DEPLOY. Save mode generates a log in the STK NFS repo for the target server and prompts for user input prior to rebooting the machine. Deploy mode executes STK scripts then proceeds with the kickstart installation. Generally it's a good idea to try the save mode once for every new type of hardware profile before starting a mass deploy.

Setup STK Repo on NFS

First unpack the STK tarball to the appropriate directory.

mkdir -p /srv/nfs/Serverview_Scripting_Toolkit
tar xzvf /home/a-a/ServerView_Scripting_Toolkit_v1.9.01.tgz -C /srv/nfs/Serverview_Scripting_Toolkit/

Modify the permissions on the necessary shell scripts that get executed by the installation environment on the target server.

chmod +rx /srv/nfs/Serverview_Scripting_Toolkit/*.sh

Copy kernel module pack from SVIM DVD.

cp /mnt/svim/Unix/Linux/RedHat/EL7.0-X86_64/RemoteInstallation/kmp_3.10.0-693.el7.x86_64.tgz /srv/nfs/Serverview_Scripting_Toolkit/svimDVD/rhel74/

Copy add-on software.

cp -rp /mnt/svim/SVSSoftware/Software/ServerView/Linux/{Agentless_Service,ServerView_RAID,Agents} /srv/nfs/Serverview_Scripting_Toolkit/swAddOn/

Extract the necessary RPM packages and setup the appropriate libraries.

mkdir -p /mnt/rhel/7.4
mount ~/rhel-server-7.4-x86_64-dvd.iso /mnt/rhel/7.4
mkdir ~/svstkTmp && cd ~/svstkTmp
rpm2cpio /mnt/rhel/7.4/Packages/audit-libs-2.7.6-3.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/glibc-2.17-196.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/libgcc-4.8.5-16.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/libstdc++-4.8.5-16.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/ncurses-libs-5.9-13.20130511.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/nss-softokn-freebl-3.28.3-6.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/pam-1.1.8-18.el7.x86_64.rpm | cpio -id
pushd /srv/nfs/svstk/tools64/lib/rhel74/
cp ~/svstkTmp/lib64/libaudit.so.1.0.0 .
cp ~/svstkTmp/lib64/libc-2.17.so .
cp ~/svstkTmp/lib64/libcrypt-2.17.so .
cp ~/svstkTmp/lib64/libdl-2.17.so .
cp ~/svstkTmp/lib64/libgcc_s-4.8.5-20150702.so.1 .
cp ~/svstkTmp/lib64/libm-2.17.so .
cp ~/svstkTmp/lib64/libnss_files-2.17.so .
cp ~/svstkTmp/lib64/libpthread-2.17.so .
cp ~/svstkTmp/lib64/libresolv-2.17.so .
cp ~/svstkTmp/lib64/librt-2.17.so .
cp ~/svstkTmp/usr/lib64/libfreebl3.so .
cp ~/svstkTmp/usr/lib64/libpam.so.0.83.1 .
cp ~/svstkTmp/usr/lib64/libpam_misc.so.0.82.0 .
cp ~/svstkTmp/usr/lib64/libtinfo.so.5.9 .
cp ~/svstkTmp/usr/lib64/libstdc++.so.6.0.19 .
ln -s libaudit.so.1.0.0 libaudit.so.1
ln -s libc-2.17.so libc.so.6
ln -s libcrypt-2.17.so libcrypt.so.1
ln -s libdl-2.17.so libdl.so.2
ln -s libgcc_s-4.8.5-20150702.so.1 libgcc_s.so.1
ln -s libm-2.17.so libm.so.6
ln -s libnss_files-2.17.so libnss_files.so.2
ln -s libpam.so.0.83.1 libpam.so.0
ln -s libpam_misc.so.0.82.0 libpam_misc.so.0
ln -s libpthread-2.17.so libpthread.so
ln -s libresolv-2.17.so libresolv.so.2
ln -s librt-2.17.so librt.so
ln -s libstdc++.so.6.0.19 libstdc++.so.6
ln -s libtinfo.so.5.9 libtinfo.so.5
pushd +1
rpm2cpio /mnt/rhel/7.4/Packages/coreutils-8.22-18.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/which-2.20-7.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/zip-3.0-11.el7.x86_64.rpm | cpio -id
rpm2cpio /mnt/rhel/7.4/Packages/unzip-6.0-16.el7.x86_64.rpm | cpio -id
mkdir /srv/nfs/Serverview_Scripting_Toolkit/tools64/lnxUtils/rhel74
cp usr/bin/{id,which,zip,unzip} /srv/nfs/Serverview_Scripting_Toolkit/tools64/lnxUtils/rhel74/

The above sequence seems to be optional but is mentioned in the STK manual and so it is included here for reference.

Edit newSetEnv.sh and update the file paths for the Agentless and the Agents add-ons.

export stkSvAgentsDir="Agents"
export stkSvAgentlessDir="Agentless_Service"

Open ports in firewall.

firewall-cmd --add-server=nfs --permanent && firewall-cmd --reload

Create the NFS server exports configuration file /etc/exports and with the necessary entries. The option no_root_squash allows the root user in the installation environment to update files in the STK repo.

/srv/nfs/Serverview_Scripting_Toolkit 96.112.145.0/24(rw,no_root_squash)

Start the NFS server.

systemctl start nfs-server

Check the active exports list.

exportsfs -s

Setup STK Working Environment

This is the workspace from which the customized initial ramdisks and iso images will be created.

Create a workspace directory.

mkdir -p ~/svstkWorkspace/{adaptIniRamDir,adaptBootIsoDir,SVIMdir}

Create directory work customizing RHEL74 boot media.

mkdir /tmp/rhel74

Mount RHEL74 boot media iso.

mount ~/rhel-server-7.4-x86_64-boot.iso /mnt/rhel74

Copy RHEL74 installation files.

cp -rp /mnt/rhel74/* /tmp/rhel74

Mount the ServerView Installation Manager (SVIM) DVD.

mount ~/SVIM_12.17.09.04.iso /mnt/svim

Copy the appriate ramdisk from the SVIM DVD. This file is located at Unix/Linux/RedHat/EL7.0-X86_64/RemoteInstallation/initrd.as74.gz

cp /mnt/svim/Unix/Linux/RedHat/EL7.0-X86_64/RemoteInstallation/initrd.as74.gz ~/svstkWorkspace/SVIMdir/

Unpack the initial ramdisk into the working directory.

# extract files from ramdisk provided by SVIM into working directory
pushd ~/svstkWorkspace/adaptIniRamDir/
gunzip -c ~/svstkWorkspace/SVIMdir/initrd.as74.gz | cpio -icvBdum
popd

Copy stkProfile.sh, setEnv.sh and stkKickstart.cfg from STK to ramdisk working directory.

# mount svstk repo and copy necessary file into ramdisk working directory
mkdir /mnt/svstk
mkdir ~/svstkWorkspace/adaptIniRamDir/updates/stk
mount -t nfs4 96.112.145.21:/srv/nfs/Serverview_Scripting_Toolkit /mnt/svstk
cp /mnt/svstk/scripts32/{stkProfile.sh,setEnv.sh,stkKickstart_rhel7.cfg} ~/svstkWorkspace/adaptIniRamDir/updates/stk/

Adapt profile script to enable RHEL74. In file ~/svstkWorkspace/adaptIniRamDir/updates/stk/stkProfile.sh add line 62:

62 "3.10.0-693.el7")      stkLinuxType=rhel74 ;;

Adapt environment script ~/svstkWorkspace/adaptIniRamDir/updates/stk/setEnv.sh to use the NFS server exporting the STK repo.

stkReposLocation=96.112.145.21:/srv/nfs/Serverview_Scripting_Toolkit
stkReposMntDir=/localRepository

Extract kernel rpm package into temporary directory and copy necessary modules.

curl -o 'kernel-3.10.0-693.el7.x86_64.rpm' 'http://10.1.57.100/rhel/7.4/Packages/kernel-3.10.0-693.el7.x86_64.rpm'
mkdir /tmp/stksv
cd /tmp/stksv
rpm2cpio /root/kernel-3.10.0-693.el7.x86_64.rpm | cpio -id
cp -p lib/modules/3.10.0-693.el7.x86_64/kernel/drivers/message/fusion/mptctl.ko.xz /root/svstkWorkspace/adaptIniRamDir/updates/stk/
cp -p lib/modules/3.10.0-693.el7.x86_64/kernel/drivers/char/ipmi/ipmi_{msghandler,devintf,si}.ko.xz /root/svstkWorkspace/adaptIniRamDir/updates/stk/
cd /root/svstkWorkspace/adaptIniRamDir/updates/stk
xz -d *.xz

Update iRMC with REST API

The appropriate firmware can be downloaded from here.

Update the iRMC Firmware:

curl --digest -k -u admin:admin --data-binary @FTS_D3289RX2540M2RX2560M2TX2560M2iRMCKron_D3289B10884Fsdr0313_1183249.BIN https://10.1.33.181/irmcupdate?flashSelect=255

Check the status of the iRMC firmware update:

curl --digest -k -u admin:admin -X GET https://10.1.33.179/irmcprogress

Build the Custom Initial Ramdisk

cd /root/svstkWorkspace/adaptIniRamDir
find . | cpio -H newc -o | gzip > /root/svstkWorkspace/adaptBootIsoDir/isolinux/initrd.img

Generate ISO Containing Installation Media

Generate the iso image.

pushd /tmp/rhel74
genisoimage -U -r -v -T -J -joliet-long -V "RHEL-7.4 Server.x86_64" -volset "RHEL-7.4 Server.x86_64" -A "RHEL-7.4 Server.x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -o ../fujitsu-rhel-7.4.iso .

Implant the md5sum into the iso.

implantisomd5 ../fujitsu-rhel-7.4.iso

Copy Installation Media to CIFS Server

# copy the installation media from the serverview workspace to local workstation
scp 10.1.57.142:/tmp/fujitsu-rhel-7.4.iso .

# copy the installation media from local workstation to CIFS server
scp fujitsu-rhel-7.4.iso 10.1.57.100:.

Configure iRMC

To configure the various aspects of the iRMC, one must create a .pre file containing the desired setting. This file is then posted to the appropriate endpoint in the iRMC webserver.

The correct curl syntax:

# properties in angle brackets (<>) need to be replace with appropriate values
curl -k -u <username>:<password> -X POST -d@<config file>.pre https://<target_server>/config

See Details of ServerView Configuration Space Values for a reference of all the available ConfigSpace properties.

This scenario will cover the following process.

  1. Configure Server Information
  2. Configure and mount remote media.
  3. Power On, power off and reset the server.

Necessary examples are provided below.

Configure Server Information

Configure the basic server information.

ServerInfo.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<!-- "ConfCabinetLocation" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="200" OI="0" Type="SET">
<DATA Type="xsd::string">215</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfSystemName" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="201" OI="0" Type="SET">
<DATA Type="xsd::string">hdfs4</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfSystemDescription" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="203" OI="0" Type="SET">
<DATA Type="xsd::string">Hadoop HDFS datanode and Yarn nodemanager with SSD storage.</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfSystemContact" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="204" OI="0" Type="SET">
<DATA Type="xsd::string">Adrian Arias Adrian_Arias@adri.codes</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfServerOperatingSystem" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="20F" OI="0" Type="SET">
<DATA Type="xsd::string">RHEL74</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBMCAssetTag" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="210" OI="0" Type="SET">
<DATA Type="xsd::string">Unknown</DATA>
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@ServerInfo.pre https://10.1.33.179/config
Connect Installation Media

Configure the remote media details.

ConfigureRemoteMedia.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<!-- "ConfBmcRemoteCdImageServer" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A60" OI="0" Type="SET">
<DATA Type="xsd::string">10.1.57.100</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageUserName" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A61" OI="0" Type="SET">
<DATA Type="xsd::string">anon</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageUserPassword" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A62" OI="0" Type="SET">
<DATA Type="xsd::string" Encrypted="3">UrV7E6RVdtVT89U9qSQ5x1wGOAY=</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageUserDomain" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A63" OI="0" Type="SET">
<DATA Type="xsd::string">SAMBA</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageShareType" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A64" OI="0" Type="SET">
<DATA Type="xsd::integer">1</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageShareName" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A65" OI="0" Type="SET">
<DATA Type="xsd::string">anon</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcRemoteCdImageImageName" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A66" OI="0" Type="SET">
<DATA Type="xsd::string">fujitsu-rhel-7.4.iso</DATA>
<STATUS>0</STATUS>
</CMD>
<!-- "ConfBmcMediaOptionsCdAttachMode" -->
<CMD Context="SCCI" OC="ConfigSpace" OE="1A67" OI="0" Type="SET">
<DATA Type="xsd::integer">1</DATA>
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@ConfigureRemoteMedia.pre https://10.1.33.179/config

Mount the media.

ConnectRemoteMedia.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<CMD Context="SCCI" OC="ConnectRemoteCdImage" OE="0" OI="0" Type="SET">
<DATA Type="xsd::integer">1</DATA>
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@ConnectRemoteMedia.pre https://10.1.33.179/config
Power On, Power Off and Reset

Power off on the target server.

PowerOff.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<CMD Context="SCCI" OC="PowerOffCabinet" OE="0" OI="0" Type="SET">
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@PowerOff.pre https://10.1.33.179/config

Power on the target server.

PowerOn.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<CMD Context="SCCI" OC="PowerOnCabinet" OE="0" OI="0" Type="SET">
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@PowerOn.pre https://10.1.33.179/config

Power cycle the target server.

PowerCycle.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<CMD Context="SCCI" OC="PowerOffOnCabinet" OE="0" OI="0" Type="SET">
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@PowerCycle.pre https://10.1.33.179/config

Reset the target server.

ResetServer.pre

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CMDSEQ>
<CMD Context="SCCI" OC="ResetServer" OE="0" OI="0" Type="SET">
<STATUS>0</STATUS>
</CMD>
</CMDSEQ>
curl -k -u admin:admin -X POST -d@ResetServer.pre https://10.1.33.179/config

Provision Machines

Provisioning machines is accomplished by the following sequence. #. Update BIOS and iRMC firmware. #. Configure iRMC server information. #. Create a new isolinux.cfg file containing the necessary stage 2 boot parameters. #. Create a new kickstart profile for the target server. #. Generate the iso for the target server containing the appropriate isolinux config and initial ramdisk. #. Copy installation image to CIFS server. #. Create a new hardware profile on the STK NFS repo for the target server. #. Configure iRMC on the target server and mount the custom installation media. #. Optionally, perform a test run in SAVE mode to collect the necessary server information. #. Power on or reset the server to boot into the installation program.

In this example we configure the VDI server. This operating system installation has a single logical storage volume presented to it by the RAID controller, on top of which an LVM logical volume is created and formatted with the XFS filesystem. It also has 2 10G-SR NICs for the user net which must be configured as a single LACP port channel.

Update BIOS and iRMC Firmware

The BIOS and iRMC updates should be downloaded in advance.

curl --digest -k -u admin:admin --data-binary @FTS_D3289RX2540M2RX2560M2TX2560M2iRMCKron_D3289B10884Fsdr0313_1183249.BIN https://10.1.33.181/irmcupdate?flashSelect=255

Prepare Isolinux

Create a copy of the default isolinux/isolinux.cfg from the RHEL7 boot image. Modify the entries starting at line 61 accordingly.

~/svstkWorkspace/adaptBootIsoDir/isolinux/vdi0.west.adri.codes.isolinux.cfg

61 label linux
62   menu label ^Install RHEL 7.4 on VDI optimized Fujitsu CX2570M2R2
63   menu default
64   kernel vmlinuz
65   append initrd=initrd.img ks=http://96.112.145.21/kickstart/STK_Fujitsu_CX2570M2R2_RHEL74_VDI.cfg bond=bond0:eno1,eno2,ens11f0,ens11f1:mode=802.3ad ip=96.112.145.50::96.112.145.1:255.255.255.0:vdi0.west.adri.codes:bond0:none nameserver=96.112.145.11 nameserver=96.112.145.12 hostname=vdi0.adri.codes deploynet=bond0:::96.112.145.50/255.255.255.0:::96.112.145.1:::96.112.145.11,96.112.145.12
66 
67 label check
68   menu label Test ^media & install RHEL 7.4 on VDI optimized Fujitsu CX2570M2R2
69   kernel vmlinuz
70   append initrd=initrd.img ks=http://96.112.145.21/kickstart/STK_Fujitsu_CX2570M2R2_RHEL74_VDI.cfg rd.live.check quiet bond=bond0:eno1,eno2,ens11f0,ens11f1:mode=802.3ad ip=96.112.145.50::96.112.145.1:255.255.255.0:vdi0.west.adri.codes:bond0:none nameserver=96.112.145.11 nameserver=96.112.145.12 hostname=vdi0.adri.codes deploynet=bond0:::96.112.145.50/255.255.255.0:::96.112.145.1:::96.112.145.11,96.112.145.12

Generate the initial ramdisk.

cd /root/svstkWorkspace/adaptIniRamDir
find . | cpio -H newc -o | gzip > /root/svstkWorkspace/adaptBootIsoDir/isolinux/initrd.img

Prepare Kickstart File

Create the appropriate kickstart file. Name the file to describe the specific profile. Copy this file to a web server that is accessible from the user net. This could be the same server that is hosting the RHEL74 installation packages.

In the %pre stanza custom parameters, that were provided by the isolinux config in the initial ramdisk, are parsed from /proc/cmdline and used to dynamically configure the network stack and other aspects of the installation. Afterwards, STK is invoked. When STK completes and is configured for DEPLOY mode the kickstart installation begins.

/var/www/html/kickstart/STK_Fujitsu_CX2570M2R2_RHEL74_VDI.cfg

#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use network installation
url --url="http://96.112.145.21/rhel/7.4/"
# Use text install
text
# Don't run the Setup Agent on first boot
firstboot --disable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
%include /tmp/network.ks

# Root password
rootpw --iscrypted $6$/6ob8L5HI.VUrd8w$juiEoby2yf9JJnk2nuSIu7fHIyk9FCCDZbI99S1z9PO/YFP1DcxnXSHhdZgT44yAzZZRc9DfzE1aS1VExU3Zx0
# System timezone
timezone America/Los_Angeles --isUtc
user --groups=wheel --name=a-a --password=$6$6p9cpfKaWNQ71Ei4$5pyuNZJ97wYC3M11F0Rj9awOZKMjcqazavK1I9E8kpsu/OB4IyU19tQlIPZ7ztLiZIfdbryxNf1UZSD5NDu080 --iscrypted --gecos="Adrian Arias"
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
# Partition clearing information
clearpart --none --initlabel
# Disk partitioning information
autopart --type=lvm --fstype=xfs
eula --agreed
reboot

%packages
@^minimal
@core
kexec-tools
curl
vim-enhanced
bash-completion
lsof
%end

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

%end

%pre

for x in `cat /proc/cmdline`; do
        case $x in
                hostname*)
                        hostname=$(echo $x | awk -F'=' '{print $2}')
                        ;;
                deploynet*)
                        device=$(echo $x | awk -F'=' '{print $2}' | awk -F':::' '{print $1}')
                        ipv4addr=$(echo $x | awk -F'=' '{print $2}' | awk -F':::' '{print $2}' | awk -F'/' '{print $1}')
                        ipv4netmask=$(echo $x | awk -F'=' '{print $2}' | awk -F':::' '{print $2}' | awk -F'/' '{print $2}')
                        ipv4gateway=$(echo $x | awk -F'=' '{print $2}' | awk -F':::' '{print $3}')
                        ipv4dns=$(echo $x | awk -F'=' '{print $2}' | awk -F':::' '{print $4}')
                        ;;
        esac;

        echo "network --device ${device} --bootproto static --ipv6=auto --activate --hostname ${hostname} --ip ${ipv4addr} --netmask ${ipv4netmask} --gateway ${ipv4gateway} --nameserver ${ipv4dns}" | tee /tmp/network.ks
done

2>&1 /stk/stkProfile.sh > /stk/stkMessages.log
retval=$?

if [ $retval != 0 ]
then
        echo -e "\x1b[41m"                                              > /dev/tty0
        printf "**************************************************\n\r" > /dev/tty0
        printf "* STK Linux                                      *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "*  An error occured during execution of STK      *\n\r" > /dev/tty0
        printf "*  preinstallation scripts.                      *\n\r" > /dev/tty0
        printf "*  Please switch to a shell with <ctrl><alt><f2> *\n\r" > /dev/tty0
        printf "*  and see  /stk/stkMessages.log  for details.   *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "*  Please check the variables in files           *\n\r" > /dev/tty0
        printf "*    setEnv.sh and/or newSetEnv.sh               *\n\r" > /dev/tty0
        printf "*  before restarting the installation process.   *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "*  Return to this terminal with <ctrl><alt><f1>  *\n\r" > /dev/tty0
        printf "*  Pressing <enter> here will reboot the system. *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "**************************************************\n\r" > /dev/tty0
        echo -e "\x1b[0m"                                               > /dev/tty0
        read -p "__  >>> "
        reboot
fi

%end

%post --nochroot
2>&1 /stk/stkPostInstall.sh > /stk/stkPostInstall.log
retval=$?

if [ $retval != 0 ]
then
        echo -e "\x1b[41m"                                              > /dev/tty0
        printf "**************************************************\n\r" > /dev/tty0
        printf "* STK Linux                                      *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "*  An error occured during execution of STK      *\n\r" > /dev/tty0
        printf "*  post-installation scripts.                    *\n\r" > /dev/tty0
        printf "*  Please switch to a shell with <ctrl><alt><f2> *\n\r" > /dev/tty0
        printf "*  and see  /stk/stkMessages.log  for details.   *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "*  Return to this terminal with <ctrl><alt><f1>  *\n\r" > /dev/tty0
        printf "*  Pressing <enter> here will reboot the system. *\n\r" > /dev/tty0
        printf "*                                                *\n\r" > /dev/tty0
        printf "**************************************************\n\r" > /dev/tty0
        echo -e "\x1b[0m"                                               > /dev/tty0
        read -p "__  >>> "
        reboot
fi
%end

In this scenario the apprioate SELinux file context needs to be configured.

semanage fcontext -a -t httpd_sys_content_t "/var/www/html/kickstart(/.*)?"
restorecon -R -v /var/www/html/kickstart

Generate ISO

Copy the adapted isolinux config and initial ramdisk to the directory containing the custom RHEL74 boot media.

cp ~/svstkWorkspace/adaptBootIsoDir/isolinux/vdi0.west.adri.codes.isolinux.cfg /tmp/rhel74/isolinux/isolinux.cfg
cp ~/svstkWorkspace/adaptBootIsoDir/isolinux/initrd.img /tmp/rhel74/isolinux/

Generate the iso image.

cd ~/svstkWorkspace/adaptIniRamDir
genisoimage -U -r -v -T -J -joliet-long -V "RHEL-7.4 Server.x86_64" -volset "RHEL-7.4 Server.x86_64" -A "RHEL-7.4 Server.x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -o ../fujitsu-cx2570m2-vdi-rhel-7.4.iso .

Copy Installation Media to CIFS Server

From local workstation copy down the newly minted iso image, then upload it to the installation media server.

scp 96.112.145.21:/tmp/fujitsu-cx2570m2-vdi-rhel-7.4.iso .
scp fujitsu-cx2570m2-vdi-rhel-7.4.iso 10.1.57.100:/tmp/.

Then from the media server move the image into place and set the SELinux context properly.

mv /tmp/fujitsu-cx2570m2-vdi-rhel-7.4.iso installation_media/
cp installation_media/fujitsu-cx2570m2-vdi-rhel-7.4.iso /srv/cifs/anon/
semanage fcontext -a -t samba_share_t "/srv/cifs/anon(/.*)?"
restorecon -R -v /srv/cifs/anon

Configure iRMC and Mount Remote Media

From the local workstation containing the iRMC .pre files, configure the remote media details and mount the image.

Remember to update the filename accodingly.

curl -k -u admin:admin -X POST -d@ConfigureRemoteMedia.pre https://10.1.33.179/config
curl -k -u admin:admin -X POST -d@ConnectRemoteMedia.pre https://10.1.33.179/config

Create Hardware Profile Specific Settings

On the STK NFS repo, create a new subdirectory for the target server's newSetEnv file. The path to the filename consists of the following syntax.

hwProf/<chassis type>/<product serial number>.sh
mkdir -p /srv/nfs/Serverview_Scripting_Toolkit/hwProf/CX2570M2

An example filename would be.

hwProf/CX2570M2/YM6J001067.sh

Optionally Execute a Test Run in Save Mode

To execute a test run it is necessary to make a change the value of stkMode in the updates/stk/setEnv.sh script located in the init ramdisk working directory.

stkMode=SAVE

Then rebuild the initial ramdisk.

find . | cpio -H newc -o | gzip > /root/svstkWorkspace/adaptBootIsoDir/isolinux/initrd.img

Reboot into Installation

Finally, issue a reboot to begin the un-attended installation.

curl -k -u admin:admin -X POST -d@ResetServer.pre https://10.1.33.179/config

Scripted Out

Utility function.

ProvisionTarget.funcs.sh:

  1 function update_bios(){
  2         local goNoGo=1
  3         if [ -z "${1}" ]; then
  4                 echo "First argument is target server IP address and is required."
  5                 goNoGo=0
  6         fi
  7         if [ -z "${2}" ]; then
  8                 echo "Second argument is iRMC username and is required."
  9                 goNoGo=0
 10         fi
 11         if [ -z "${3}" ]; then
 12                 echo "Third argument is iRMC password and is required."
 13                 goNoGo=0
 14         fi
 15         if [ -z "${4}" -a ! -e "${4}" ]; then
 16                 echo "Fourth argument is for BIOS update filename, is required and must exist on the filesystem."
 17                 goNoGo=0
 18         fi
 19         if [ $goNoGo -ne 1 ]; then
 20                 echo "example: update_bios <target server> <irmc username> <irmc password> <bios update file>"
 21                 return 1
 22         fi
 23         local targetServerMgmtAddr=${1}
 24         local biosUpdateFile="${2}"
 25         local irmcUsername="${3}"
 26         local irmcPassword="${4}"
 27         local res=''
 28         res=$(curl -k \
 29              --digest \
 30              -u ${irmcUsername}:${irmcPassword} \
 31              --data-binary @${bios_update_file}\
 32              https://${targetServerMgmtAddr}/biosupdate?flashSelect=255)
 33 }
 34 
 35 function update_irmc_firmware(){
 36         local goNoGo=1
 37         if [ -z "${1}" ]; then
 38                 echo "First argument is target server IP address and is required."
 39                 goNoGo=0
 40         fi
 41         if [ -z "${2}" ]; then
 42                 echo "Second argument is iRMC username and is required."
 43                 goNoGo=0
 44         fi
 45         if [ -z "${3}" ]; then
 46                 echo "Third argument is iRMC password and is required."
 47                 goNoGo=0
 48         fi
 49         if [ -z "${4}" -a ! -e "${4}" ]; then
 50                 echo "Fourth argument is for BIOS update filename, is required and must exist on the filesystem."
 51                 goNoGo=0
 52         fi
 53         if [ $goNoGo -ne 1 ]; then
 54                 echo "example: update_bios <target server> <irmc username> <irmc password> <bios update file>"
 55                 return 1
 56         fi
 57         local targetServerMgmtAddr=${1}
 58         local irmcUpdateFile="${2}"
 59         local irmcUsername="${3}"
 60         local irmcPassword="${4}"
 61         local res=''
 62         res=$(curl -k \
 63              --digest \
 64              -u ${irmcUsername}:${irmcPassword} \
 65              --data-binary @${irmcUpdateFile}\
 66              https://${targetServerMgmtAddr}/irmcupdate?flashSelect=255)
 67         # check response
 68         return 0
 69 }
 70 
 71 # example: prepare_isolinux_config vdi0.west.adri.codes ${HOME}/svstkWorkspace '^Install RHEL 7.4 on VDI optimized Fujitsu CX2570M2R2' 'ks=http://96.112.145.21/kickstart/STK_Fujitsu_CX2570M2R2_RHEL74_VDI.cfg bond=bond0:eno1,eno2,ens11f0,ens11f1:mode=802.3ad ip=96.112.145.50::96.112.145.1:255.255.255.0:vdi0.west.adri.codes:bond0:none nameserver=96.112.145.11 nameserver=96.112.145.12 hostname=vdi0.adri.codes deploynet=bond0:::96.112.145.50/255.255.255.0:::96.112.145.1:::96.112.145.11,96.112.145.12'
 72 function prepare_isolinux_config(){
 73         if [ -z "${1}" ]; then
 74                 goNoGoMsg='First argument is for fqdn of target server on user plane.'
 75                 echo "${goNoGoMsg}"
 76                 goNoGo=0
 77         fi
 78         if [ -z "${2}" ]; then
 79                 goNoGoMsg='Second argument is for local STK workspace.'
 80                 echo "${goNoGoMsg}"
 81                 goNoGo=0
 82         fi
 83         if [ -z "${3}" ]; then
 84                 goNoGoMsg='Third argument is for isolinux menu label.'
 85                 echo "${goNoGoMsg}"
 86                 goNoGo=0
 87         fi
 88         if [ -z "${4}" ]; then
 89                 goNoGoMsg='Fourth argument is for extra kernel arguments and is not required.'
 90                 echo "${goNoGoMsg}"
 91         fi
 92         if [ $goNoGo -ne 1 ]; then
 93                 echo 'example: prepare_isolinux_config <fqdn> \'
 94                 echo '                                 <stk workspace directory> \'
 95                 echo '                                 <isolinux menu label> \'
 96                 echo '                                 [<extra kernal arguments>]'
 97                 return 1
 98         fi
 99         local fqdn=${1}
100         local stkWorkspace=${2}
101         local menuLabel="${3}"
102         local extraArgs="${4}"
103         local newIsolinuxCfg=${fqdn}.isolinux.cfg
104 
105         pushd ${stkWorkspace}/adaptBootIsoDir/isolinux
106         cp isolinux.cfg ${newIsolinuxCfg}
107         sed -i '63s/^.*$/  menu label '${menuLabel}'/' ${newIsolinuxCfg}
108         sed -i '64s/^.*$/  append initrd=initrd.img/' ${newIsolinuxCfg}
109         sed -i '64s/$/ '${extraArgs}'/' ${newIsolinuxCfg}
110         popd
111         return 0
112 }
113 
114 function generate_iso_image(){
115         local goNoGo=1
116         if [ -z "${1}" ]; then
117                 goNoGoMsg='First argument is for fqdn of target server on user plane.'
118                 echo "${goNoGoMsg}"
119                 goNoGo=0
120         fi
121         if [ -z "${2}" ]; then
122                 goNoGoMsg='Second argument is for local STK workspace directory.'
123                 echo "${goNoGoMsg}"
124                 goNoGo=0
125         fi
126         if [ -z "${3}" ]; then
127                 goNoGoMsg='Third argument is for directory containing original boot media .'
128                 echo "${goNoGoMsg}"
129                 goNoGo=0
130         fi
131         if [ -z "${4}" ]; then
132                 goNoGoMsg='Fourth argument is for directory containing output iso images.'
133                 echo "${goNoGoMsg}"
134                 goNoGo=0
135         fi
136         if [ -z "${5}" ]; then
137                 goNoGoMsg='Fifth argument is for filename of iso image.'
138                 echo "${goNoGoMsg}"
139                 goNoGo=0
140         fi
141         if [ $goNoGo -ne 1 ]; then
142                 echo 'example: generate_iso_image <fqdn> \'
143                 echo '                            <stk workspace directory> \'
144                 echo '                            <boot media directory> \'
145                 echo '                            <boot media output directory> \'
146                 echo '                            <boot media output filename>'
147                 return 1
148         fi
149         # example: generate_iso_image vdi0.west.adri.codes ${HOME}/svstkWorkspace /tmp/rhel74 fujitsu-cx2570m2-vdi-rhel-7.4.iso
150         local fqdn=${1}
151         local stkWorkspace=${2}
152         local bootMediaDir=${3}
153         local bootMediaOutputDir=${4}
154         local bootMediaOutputFilename=${5}
155 
156         cp ${stkWorkspace}/adaptBootIsoDir/isolinux/${fqdn}.isolinux.cfg ${bootMediaDir}/isolinux/isolinux.cfg
157         cp ${stkWorkspace}/adaptBootIsoDir/isolinux/initrd.img ${bootMediaDir}/isolinux/
158         pushd ${bootMediaDir}
159         genisoimage -U -r -v -T -J -joliet-long -V "RHEL-7.4 Server.x86_64" -volset "RHEL-7.4 Server.x86_64" -A "RHEL-7.4 Server.x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e images/efiboot.img -no-emul-boot -o ${bootMediaOutputDir}/${bootMediaOutputFilename} .
160         popd
161 }
162 
163 # example: copy_image_to_media_server 10.1.57.100 /srv/cifs/anon /tmp fujitsu-cx2570-vdi-rhel-7.4.iso
164 function copy_image_to_media_server(){
165         local goNoGo=1
166         if [ -z "${1}" ]; then
167                 goNoGoMsg='First argument is for media server IP address.'
168                 goNoGo=0
169         fi
170         if [ -z "${2}" ]; then
171                 goNoGoMsg='Second argument is for media server host directory.'
172                 goNoGo=0
173         fi
174         if [ -z "${3}" ]; then
175                 goNoGoMsg='Third argument is for boot media output directory.'
176                 goNoGo=0
177         fi
178         if [ -z "${4}" ]; then
179                 goNoGoMsg='Fourth argument is for boot media filename.'
180                 goNoGo=0
181         fi
182         if [ $goNoGo -ne 1 ]; then
183                 echo 'example: copy_image_to_media_server <media server ip> \'
184                 echo '                                    <media sever host directory> \'
185                 echo '                                    <boot media output directory> \'
186                 echo '                                    <boot media file name> \'
187                 echo '                                    <media config file>'
188                 return 1
189         fi
190         local mediaServerAddr=${1}
191         local mediaServerHostDir=${2}
192         local bootMediaOutputDir=${3}
193         local bootMediaOutputFilename=${4}
194         scp ${bootMediaOutputDir}/${bootMediaOutputFilename} ${mediaServerAddr}:.
195         ssh ${mediaServerAddr} "sudo mv ${bootMediaOutputFilename} ${mediaServerHostDir}/"
196         ssh ${mediaServerAddr} "sudo semanage fcontext -a -t samba_share_t '${mediaServerHostDir}(/.*)?'"
197         ssh ${mediaServerAddr} "sudo restorecon -R -v ${mediaServerHostDir}"
198         # XXX: handle failure scenario
199         return 0
200 }
201 
202 # example: configure_irmc_remote_media 10.1.33.179 admin admin ConfigureRemoteMedia.pre
203 function configure_irmc_remote_media(){
204         local goNoGo=1
205         if [ -z "${1}" ]; then
206                 goNoGoMsg='First argument is for target server managment ip address.'
207                 goNoGo=0
208         fi
209         if [ -z "${2}" ]; then
210                 goNoGoMsg='Second argument is for iRMC username.'
211                 goNoGo=0
212         fi
213         if [ -z "${3}" ]; then
214                 goNoGoMsg='Third argument is for iRMC password.'
215                 goNoGo=0
216         fi
217         if [ -z "${4}" ]; then
218                 goNoGoMsg='Fourth argument is for file containing media configuration.'
219                 goNoGo=0
220         fi
221         if [ $goNoGo -ne 1 ]; then
222                 echo 'example: configure_irmc_remote_media <target server mgmtnet ip> \'
223                 echo '                       <irmc username> \'
224                 echo '                       <irmc password> \'
225                 echo '                       <media config file>'
226                 return 1
227         fi
228         local targetServerMgmtAddr=${1}
229         local irmcUser=${2}
230         local irmcPass=${3}
231         local mediaConfigFile=${4}
232 
233         curl -k -u ${irmcUser}:${irmcPass} -X POST -d@${mediaConfigFile} https://${targetServerMgmtAddr}/config
234         # XXX: handle response
235 }
236 
237 # example: create_target_hwprof /mnt/stk CX2570M2 YM6J001067 SAVE YES 1 1 2 NO
238 function create_target_hwprof(){
239         local goNoGo=1
240         local goNoGoMsg=''
241         if [ -z "${1}" -o ! -d "${1}" ]; then
242                 goNoGoMsg='First argument is for location of STK NFS repo, '
243                 goNoGoMsg+='is required and must exist on the filesystem.'
244                 goNoGo=0
245         fi
246         if [ -z "${2}" -o ! -d "${2}" ]; then
247                 goNoGoMsg='Second argument is for target server chassis '
248                 goNoGoMsg+='type and is required.'
249                 goNoGo=0
250         fi
251         if [ -z "${3}" -o ! -d "${3}" ]; then
252                 goNoGoMsg='Third argument is for target server product '
253                 goNoGoMsg+='id and is required.'
254                 goNoGo=0
255         fi
256         if [ -z "${4}" -o ! -d "${4}" ]; then
257                 goNoGoMsg='Fourth argument is for stk deploy mode and is required.'
258                 goNoGo=0
259         fi
260         if [ -z "${5}" -o ! -d "${5}" ]; then
261                 goNoGoMsg='Fifth argument is for enabling RAID configuration.'
262                 goNoGo=0
263         fi
264         if [ -z "${6}" -o ! -d "${6}" ]; then
265                 goNoGoMsg='Sixth argument is for selecting RAID controller for configuration.'
266                 goNoGo=0
267         fi
268         if [ -z "${7}" -o ! -d "${7}" ]; then
269                 goNoGoMsg='Seventh argument is for type of RAID volume.'
270                 goNoGo=0
271         fi
272         if [ -z "${8}" -o ! -d "${8}" ]; then
273                 goNoGoMsg='Eigth argument is for # of drives for RAID volume.'
274                 goNoGo=0
275         fi
276         if [ -z "${8}" -o ! -d "${8}" ]; then
277                 goNoGoMsg='Nineth argument is for # of fast init of RAID volume.'
278                 goNoGo=0
279         fi
280         if [ $goNoGo -ne 1 ]; then
281                 echo 'example: create_target_hwprof <stk nfs mountpoint> \'
282                 echo '                              <chassis type> \'
283                 echo '                              <product id> \'
284                 echo '                              <stk mode> \'
285                 echo '                              <configure raid> \'
286                 echo '                              <raid controller #> \'
287                 echo '                              <raid type> \'
288                 echo '                              <# of drives> \'
289                 echo '                              <fast init raid>'
290                 return 1
291         fi
292         local stkRepoDir=${1}
293         local chassisType=${2}
294         local productId=${3}
295         local stkMode=${4}
296         local stkCfgRaidDirect=${5}
297         local stkCtrlNo=${6}
298         local stkRaidType=${7}
299         local stkDriveNo=${8}
300         local stkFastInit=${9}
301         local stkChassisDir=${stkRepoDir}/hwProf/${chassisType}
302 
303         [ ! -d ${stkChassisDir} ] && mkdir -p pushd ${stkChassisDir}
304         pushd ${stkRepoDir}/hwProf/${chassisType}
305         cp ${stkRepoDir}/scripts32/newSetEnv.sh ${productId}.sh
306         sed -i '/^stkMode=/s/=.*/='${stkMode}'/' ${productId}.sh
307         sed -i '/^stkCfgRaidDirect=/s/=.*/='${stkCfgRaidDirect}'/' ${productId}.sh
308         sed -i '/^stkCtrlNo=/s/=.*/='${stkCtrlNo}'/' ${productId}.sh
309         sed -i '/^stkRaidType=/s/=.*/='${stkRaidType}'/' ${productId}.sh
310         sed -i '/^stkDriveNo=/s/=.*/='${stkDriveNo}'/' ${productId}.sh
311         sed -i '/^stkFastInit=/s/=.*/='${stkFastInit}'/' ${productId}.sh
312         popd
313 }
314 
315 # example reboot_target 10.1.33.179 admin admin
316 function reboot_target(){
317         local goNoGo=1
318         if [ -z "${1}" ]; then
319                 goNoGoMsg='First argument is for # of target server managment ip address.'
320                 goNoGo=0
321         fi
322         if [ -z "${2}" ]; then
323                 goNoGoMsg='Second argument is for iRMC username.'
324                 goNoGo=0
325         fi
326         if [ -z "${3}" ]; then
327                 goNoGoMsg='Third argument is for iRMC password.'
328                 goNoGo=0
329         fi
330         if [ $goNoGo -ne 1 ]; then
331                 echo 'example: reboot_target <target server mgmtnet ip> \'
332                 echo '                       <irmc username> \'
333                 echo '                       <irmc password> \'
334                 return 1
335         fi
336         local targetServerMgmtAddr=${1}
337         local irmcUser=${2}
338         local irmcPass=${3}
339         curl -k -u ${irmcUser}:${irmcPass} -X POST -d@ResetServer.pre https://${targetServerMgmtAddr}/config
340         # XXX: handle response
341 }

Host specific settings.

10.1.33.179/ProvisionTarget.settings:

MEDIA_SERVER_ADDR=10.1.57.100
TARGET_SERVER_MGMT_ADDR=10.1.33.179
TARGET_SERVER_USER_ADDR=96.112.145.50
TARGET_SERVER_USER_NETMASK=255.255.255.0
TARGET_SERVER_USER_GATEWAY=96.112.145.1
TARGET_SERVER_USER_NS1=96.112.145.11
TARGET_SERVER_USER_NS2=96.112.145.12
TARGET_SERVER_USER_DNS=${TARGET_SERVER_USER_NS1}
if [ -n "${TARGET_SERVER_USER_NS2}" ]; then
        TARGET_SERVER_USER_DNS="${TARGET_SERVER_USER_NS1},${TARGET_SERVER_USER_NS2}"
fi
TARGET_SERVER_DEPLOY_NET=bond0:::${TARGET_SERVER_USER_ADDR}/${TARGET_SERVER_USER_NETMASK}:::${TARGET_SERVER_USER_GATEWAY}:::${TARGET_SERVER_USER_DNS}

Main script.

'ProvisionTarget.sh`:

prepare_isolinux_config &&
generate_iso_image &&
copy_image_to_media_server &&
configure_irmc_remote_media &&
create_target_hwprof &&
reboot_target ${TARGET_SERVER_ADDR}