RHEL 6 Kickstart with interactive part does not work

Simon Reber S.Reber at lcsys.ch
Thu Dec 16 18:14:43 UTC 2010


Hi all,

I'm currently trying to make my RHEL 5 kickstart environment working for
RHEL 6.
So far everything looks OK - but when I use the special kickstart file,
that takes some arguments from the user it fails.

The problem is that I have to change the tty (chvt) to get the
interactive stuff working - but for some reason doesn't it have the same
behavior as we had in RHEL 5.
It still changes the tty but after that, the script doesn't process
further. I personally think that it has something to-do with the tty
change (but I also can be wrong).

So if somebody has a working example, I would be really grateful as I've
tried almost everything without luck.

My kickstart file is build as follow:
# Test Kickstart

# Installation specification
install
# url --url http://url_to_repo
cdrom
text
key --skip
lang en_US.UTF-8
keyboard sg-latin1
%include /tmp/network-include
rootpw --iscrypted xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
firewall --disabled
authconfig --enableshadow --enablemd5
selinux --disabled
timezone --utc Europe/Zurich
firstboot --disabled
logging --level=debug

# Partition specification
%include /tmp/part-include

reboot

%packages --excludedocs --nobase
kernel
yum
openssh-server
openssh-clients
audit
man
logrotate
tmpwatch
vixie-cron
crontabs
ksh
ntp
perl
bind-utils
sudo
bc
-sysstat
which
sendmail
wget
xinetd
redhat-lsb
dhclient
-kexec-tools
-firstboot
-rhnsd
-tftp-server
-system-config-soundcard
-squashfs-tools
-device-mapper-multipath
-aspell-en
-aspell
-rdate
-dhcpv6-client
-NetworkManager
-rsh
-sysreport
-irda-utils
-rdist
-anacron
-bluez-utils
-talk
-system-config-lvm
-wireless-tools
-setroubleshoot-server
-setroubleshoot-plugins
-setroubleshoot
-ppp
-GConf2
-dhcpv6-client
-iptables-ipv6
-libselinux-python
-setools
-selinux-policy
-libselinux-utils
-chkfontpath
-urw-fonts
-xorg-x11-xfs
-policycoreutils
-selinux-policy-targeted
-ypbind
-yp-tools
-smartmontools
-pcsc-lite
-trousers
-oddjob
-yum-updatesd
-rhnsd
-readahead
-pcsc-lite
-gpm
-at
-cpuspeed
-conman
-system-config-securitylevel-tui
-tcsh
-firstboot-tui
-ppp
-rp-pppoe
-system-config-network-tui
-syslinux
-pcsc-lite-libs
-pcmciautils
-pam_smb
-mkbootdisk
-jwhois
-ipsec-tools
-ed
-authconfig
-crash
-Deployment_Guide-en-US
-hal
-pm-utils
-dbus
-dbus-glib


%pre --interpreter python
import os
import sys
import re
import os.path
import time
os.system('chvt 3')
os.system('exec < /dev/tty3 > /dev/tty3')
os.system('clear')

# Defining file name and location
file_network = '/tmp/network-include'
file_part = '/tmp/part-include'
file_lcsetup = '/tmp/LCSetup'

# Default Host and DNS domain
hostname = 'localhost'
dns = 'localdomain'

# Get current date/time
localtime = time.asctime( time.localtime(time.time()) )

# Function definition

def ipFormatChk(ip_addr):
        pattern =
r"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0
-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]
|[01]?[0-9][0-9]?)\b"
        if re.match(pattern, ip_addr):
                return True
        else:
                return False

def ProtoChk(proto):
        if proto == 'dhcp' or proto == 'static':
                return True
        else:
                return False

def GetSerial(dmi):
        if re.search('Serial Number', dmi):
                return True
        else:
                return False

def CheckLayout(val):
        if val == 'cmp' or val == 'db' or val == 'opt':
                return True
        else:
                return False

def GetPartition(val1,val2):
        # split disk information toto device and
        # size
        part_size_mb = 0
        dev, size_mb = val2.split(";")
        dev = re.sub('\/dev\/','',dev)

        array = list()
        array.append('bootloader --location=mbr --driveorder=%s
--append=\"audit=1 crashkernel=auto\"' % dev)
        array.append('clearpart --linux --drives=%s' % dev)
        array.append('part /boot --fstype ext4 --size=150 --ondisk=%s' %
dev)

        # Enter swap size
        swap = raw_input('Swap size in MB: ')
        while not re.match("^[0-9]+$", swap):
                swap = raw_input('Invalide argument, please try again in
MB [numeric]: ')

        # Write swap into integer for calcultion
        swap_int = int(swap)
        array.append('part swap --size=%s --ondisk=%s' % (swap, dev))
        array.append('part pv.01 --grow --size=1 --ondisk=%s' % dev)
        array.append('volgroup vgroot pv.01')
        if val1 == 'cmp':
                array.append('logvol  /  --vgname=vgroot  --size=3072
--name=lvroot --fstype=ext4')
                array.append('logvol  /var  --vgname=vgroot  --size=2096
--name=lvvar --fstype=ext4')
                array.append('logvol  /tmp  --vgname=vgroot  --size=1024
--name=lvtmp --fstype=ext4')
                array.append('logvol  /home  --vgname=vgroot
--size=1024  --name=lvhome --fstype=ext4')
                array.append('logvol  /opt/spare  --vgname=vgroot
--size=1  --grow  --name=lvspare --fstype=ext4')
                part_size_mb = swap_int + 7264
        elif val1 == 'db':
                array.append('logvol  /  --vgname=vgroot  --size=3072
--name=lvroot --fstype=ext4')
                array.append('logvol  /var  --vgname=vgroot  --size=2096
--name=lvvar --fstype=ext4')
                array.append('logvol  /tmp  --vgname=vgroot  --size=1024
--name=lvtmp --fstype=ext4')
                array.append('logvol  /home  --vgname=vgroot
--size=1024  --name=lvhome --fstype=ext4')
                array.append('logvol  /opt/oracle  --vgname=vgroot
--size=1  --grow  --name=lvoracle --fstype=ext4')
                part_size_mb = swap_int + 7264
        elif val1 == 'opt':
                array.append('logvol  /  --vgname=vgroot  --size=3072
--name=lvroot --fstype=ext4')
                array.append('logvol  /var  --vgname=vgroot  --size=2096
--name=lvvar --fstype=ext4')
                array.append('logvol  /opt  --vgname=vgroot  --size=3072
--name=lvopt --fstype=ext4')
                array.append('logvol  /tmp  --vgname=vgroot  --size=1024
--name=lvtmp --fstype=ext4')
                array.append('logvol  /home  --vgname=vgroot
--size=1024  --name=lvhome --fstype=ext4')
                array.append('logvol  /opt/spare  --vgname=vgroot
--size=1  --grow  --name=lvspare --fstype=ext4')
                part_size_mb = swap_int + 10336

        part_size_mb = int(part_size_mb)
        size_mb = int(size_mb)
        if part_size_mb > size_mb:
                return (array,False)
        else:
                return (array,True)


# Main Part

print ('Welcome to LCSetup\n')

# Trying to get serial number using
# dmidecode
demidecode = os.popen("/usr/sbin/dmidecode")
sysinfo = demidecode.readlines()
err = demidecode.close()

# Get first Serial Number information
# since this usually is the serial number of
# the computer
c = 1
b = ''
for line in sysinfo:
        i = GetSerial(line)
        if i == True and c == 1:
                a, b = line.split(":")
                b = b.strip()
                c+=1

if b:
        serial = raw_input('Serial number [%s]: ' % b)
else:
        serial = raw_input('Serial number: ')

if not serial and b:
        serial = b
else:
        while not serial:
                serial = raw_input('Invalide serial number, try again:
')

# Ask for the hostname
hostname = raw_input('Hostname of Machine [%s]: ' % hostname)
if hostname == '':
        hostname = 'localhost'

# Write information into LCSetup file
lcs = open(file_lcsetup, 'w')
lcs.write('### LCSetup kickstart installation (%s)\n' % localtime)
lcs.write('###\n')
lcs.write('SERIAL: %s\n' % serial)
lcs.write('HOSTNAME: %s\n' % hostname)
lcs.close

# Network configuration
ifconfig = os.popen("/usr/sbin/ifconfig")
nic = ifconfig.readlines()
err = ifconfig.close()

eth = ''
for n in nic:
        n = n.strip()
        if re.search('^eth', n):
                devif, t = n.split("Link")
                devif = devif.strip()
                net_if = raw_input('Configure interface %s [- to skip]:
' % devif)
                if net_if != '-':
                        eth = devif
                        break
                else:
                        continue

if net_if == '-' or net_if == '':
        net_if = 'localhost'

if eth != '':
        proto = raw_input('DHCP or Static [dhcp|static]: ')
        while not ProtoChk(proto):
                proto = raw_input('Please enter [dhcp] or [static]: ')

        if proto == 'dhcp':
                dns =  raw_input('DNS domain [%s]: ' % dns)
                if dns == '':
                        dns = 'localdomain'

        elif proto == 'static':
                ip_addr = raw_input('IP address: ')
                while not ipFormatChk(ip_addr):
                        ip_addr = raw_input('Invalide IP address, try
again: ')

                subnet_addr = raw_input('Subnet address: ')
                while not ipFormatChk(subnet_addr):
                        subnet_addr = raw_input('Invalide subnet
address, try again: ')

                default_gw = raw_input('Default gateway: ')
                while not ipFormatChk(default_gw):
                        default_gw = raw_input('Invalide default
gateway, try again: ')

                dns =  raw_input('DNS domain [%s]: ' % dns)
                if dns == '':
                        dns = 'localdomain'

        else:
                print "Unknown error...\n"
                sys.exit(1)

        # Write information to file
        if proto == 'dhcp':
                file = open(file_network, 'w')
                file.write('network --device %s --bootproto %s\n' %
(eth, proto))
                file.close
        elif proto == 'static':
                file = open(file_network, 'w')
                file.write('network --device=%s --bootproto=%s --ip=%s
--netmask=%s --gateway=%s --nameserver=xxxxxxxxx --hostname=%s' % (eth,
proto, ip_addr, subnet_addr, default_gw, hostname))
                file.close
        else:
                print "Unknown error..."
                sys.exit(1)

        # Write information into LCSetup file
        lcs = open(file_lcsetup, 'a')
        lcs.write('DNS_DOMAIN: %s\n' % dns)
        lcs.write('NETWORKING=yes\n')
        lcs.write('NET_DEVICE_%s: %s\n' % (eth, eth))
        lcs.write('NET_PROTOCOL_%s: %s\n' % (eth, proto))
        if proto == 'static':
                lcs.write('NET_IP_ADDR_%s: %s\n' % (eth, ip_addr))
                lcs.write('NET_SUB_ADDR_%s: %s\n' % (eth, subnet_addr))
                lcs.write('NET_DEFAULT_GW: %s\n' % default_gw)

        lcs.close
else:
        lcs = open(file_lcsetup, 'a')
        lcs.write('NETWORKING=no')
        lcs.close
        file = open(file_network, 'w')
        file.close

# Get boot parameter and select the apropriate
# partition layout
disk_size = 0
sfdisk = os.popen("/usr/sbin/sfdisk -s")
disk = sfdisk.readlines()
err = sfdisk.close()

c = 0
counter = 1
for count in disk:
        if re.search('\/dev\/',count):
                c += 1

disk_array = list()
for line in disk:
        if re.search('\/dev\/',line):
                if c <= 1:
                        dev, size = line.split(':')
                        dev = dev.strip()
                        size = size.strip()
                        size = int(size)
                        size_mb = size / 1024
                        size_mb = str(size_mb)
                        tmp = dev + ";" + size_mb
                        # print ("%s and %s MB" % (dev, size_mb))
                        disk_size = tmp
                else:
                        dev, size = line.split(':')
                        dev = dev.strip()
                        size = size.strip()
                        size = int(size)
                        size_mb = size / 1024
                        if counter == 1:
                                print "The following disks are available
for usage:\n"

                        print "\t[%s] %s with size %s MB" % (counter,
dev, size_mb)
                        size_mb = str(size_mb)
                        tmp = dev + ";" + size_mb
                        disk_array.append(tmp)
                        counter += 1

if c >= 2:
        disk_selection = raw_input('\nEnter ID of disk to take: ')
        disk_selection = int(disk_selection)
        disk_selection -= 1
        disk_size = disk_array[disk_selection]

# Special workaround is required to refuse
# not size-able partition layout
hd_size = False
part_layout =  raw_input('\nEnter partition layout [cmp|db|opt]: ')
while not CheckLayout(part_layout):
        part_layout =  raw_input('Invalide partition layout, try again
[cmp|db|opt]: ')

part, hd_size = GetPartition(part_layout, disk_size)
while not hd_size:
        part_layout =  raw_input('Size of partition layout does not fit,
choose an other [cmp|db|opt]: ')
        while not CheckLayout(part_layout):
                part_layout =  raw_input('Invalide partition layout, try
again [cmp|db|opt]: ')

        part, hd_size = GetPartition(part_layout, disk_size)

# Write partition table to file
file = open(file_part, 'w')
for l in part:
        l = l.strip()
        file.write("%s\n" % l)

file.close

# Write partition information to LCSetup
# information
disk_dev, disk_dev_sz = disk_size.split(";")
lcs = open(file_lcsetup, 'a')
lcs.write('PART_LAYOUT: %s\n' %  part_layout)
lcs.write('ROOT_DISK: %s\n' % disk_dev)
lcs.close

os.system('chvt 1')
os.system('exec < /dev/tty1 > /dev/tty1')


%post --nochroot
chvt 2
exec < /dev/tty2 > /dev/tty2
mkdir -p /mnt/sysimage/usr/local/host/etc
chmod -R 750 /mnt/sysimage/usr/local/host
cp /tmp/LCSetup /mnt/sysimage/usr/local/host/etc
# chroot /mnt/sysimage /usr/local/host/bin/LCSetup
# rm -rf /mnt/sysimage/usr/local/host/tools/*
chvt 1
exec < /dev/tty1 > /dev/tty1

%end


Thanks and all the best,
Simon Reber




More information about the Kickstart-list mailing list