install
text
%include /tmp/source.ks
reboot --eject
lang en_US.UTF-8
keyboard us
rootpw r00tme
timezone --utc Etc/UTC
firewall --disabled
selinux --disabled
# ignore unsupported hardware warning
unsupported_hardware
# SKIP CONFIGURING X
skipx
# NEVER ever place zerombr here, it breaks automated installation
%include /tmp/bootloader.ks
%include /tmp/partition.ks

# PREINSTALL SECTION
# HERE ARE COMMANDS THAT WILL BE LAUNCHED BEFORE
# INSTALLATION PROCESS ITSELF
%pre
#!/bin/sh

# hard drives
drives=""
removable_drives=""
for drv in `ls -1 /sys/block | grep "sd\|hd\|vd\|cciss"`; do
    if !(blkid | grep -q "${drv}.*Fuel"); then
      if (grep -q 0 /sys/block/${drv}/removable); then
          drives="${drives} ${drv}"
      else
          removable_drives="${removable_drives} ${drv}"
      fi
    fi
done
default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'`

installdrive="undefined"
forceformat="no"
for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done

set ${drives} ${removable_drives}
numdrives=`echo $#`

tgtdrive="${installdrive}"

function confirm_format {
  check_drive="$1"
  local confirm_format="no"

  if [[ "$forceformat" == "yes" ]] ; then
    return 0
  fi

  if parted -s /dev/$check_drive print &>/dev/null ; then
    echo
    echo "$check_drive drive contains partition table:"
    parted -s /dev/$check_drive print
    echo
    read -p "Are you sure you want to erase ALL data on disk $check_drive? (y/N)" confirm_format
    if [[ "$confirm_format" == "y" ]] || [[ "$confirm_format" == "Y" ]] || [[ "$forceformat" == "yes" ]]; then
      return 0
    else
      return 1
    fi
  else
    return 0
  fi
}

format_confirmed="no"

if [ $numdrives -lt 1 ]; then
    exec < /dev/tty3 > /dev/tty3 2>&1
    chvt 3
    clear
    echo
    echo '********************************************************************'
    echo '*                            E R R O R                             *'
    echo '*                                                                  *'
    echo '*      There is no suitable media available for installation.      *'
    echo '*                Please attach a drive and try again.              *'
    echo '*                                                                  *'
    echo '********************************************************************'
    echo
    read -p "Press Enter to shut down the system: " _
    poweroff
fi

if [ ${numdrives} -gt 1 ] || [ `echo ${drives} | wc -w` -eq 0 ] ; then
    exec < /dev/tty3 > /dev/tty3 2>&1
    chvt 3
    while [ "${tgtdrive}" = "undefined" ]; do
        clear
        echo
        echo '********************************************************************************'
        echo '*                                 W A R N I N G                                *'
        echo '*                                                                              *'
        echo '*  Which of the detected hard drives do you want to be used as                 *'
        echo '*  the installation target?                                                    *'
        echo '*                                                                              *'
        echo '********************************************************************************'
        echo
        echo "Possible choices"
        echo "Persistent drives: ${drives}"
        echo "Removable drives: ${removable_drives}"
        echo
        if [ `echo ${drives} | wc -w` -eq 1 ] ; then
            read -t 30 -p "Choose hard drive: " tgtdrive || tgtdrive=$default_drive
        else
            read -p "Choose hard drive: " tgtdrive
        fi
        match="no"
        for drive in ${drives[@]} ${removable_drives[@]}; do
          if [[ "$drive" == "$tgtdrive" ]] && match="yes" ; then
            if confirm_format $tgtdrive ; then
              format_confirmed="yes"
              break
            else
              tgtdrive="undefined"
              read -p "You may select another disk. Press Enter to continue." _
            fi
          fi
        done
        if [[ "$match" == "no" ]]; then
          tgtdrive="undefined"
          read -p "Invalid choice. Press Enter to continue." _
        fi
    done
    clear
    chvt 1
else
    tgtdrive=`echo ${drives} | sed -e "s/^\s*//" -e "s/\s*$//"`
fi

if [ "$format_confirmed" != "yes" ] ; then
  exec < /dev/tty3 > /dev/tty3 2>&1
  chvt 3
  if ! confirm_format $tgtdrive ; then
      clear
      echo
      echo '********************************************************************'
      echo '*                            E R R O R                             *'
      echo '*                                                                  *'
      echo '*           Disk $tgtdrive contains active partition(s).           *'
      echo '*        Installation cannot continue without confirmation.        *'
      echo '*                                                                  *'
      echo '********************************************************************'
      echo
      read -p "Press Enter to restart: " _
      reboot
  fi
  chvt 1
fi

# verify tgtdrive is at least 41GB
tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 ))
if [ $tgtdrivesize -lt 41984 ]; then
    exec < /dev/tty3 > /dev/tty3 2>&1
    chvt 3
    clear
    echo
    echo '********************************************************************'
    echo '*                            E R R O R                             *'
    echo '*                                                                  *'
    echo '*  Your disk is under 41GB in size. Installation cannot continue.  *'
    echo '*             Restart installation with a larger disk.             *'
    echo '*                                                                  *'
    echo '********************************************************************'
    echo
    read -p "Press Enter to restart: " _
    reboot
fi

# paths in /dev have "/" instead of "!" for cciss devices
tgtdrive=$(echo $tgtdrive | sed -e 's/!/\//')

# source
if test -e /dev/disk/by-label/"OpenStack_Fuel"; then
    echo "harddrive --partition=LABEL="OpenStack_Fuel" --dir=/" > /tmp/source.ks
elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then
    echo "harddrive --partition=UUID=will_be_substituted_with_actual_uuid --dir=/" > /tmp/source.ks
else
    echo "cdrom" > /tmp/source.ks
fi

vgremove -ff os
dd if=/dev/zero of=/dev/${tgtdrive} bs=10M count=10
sleep 3
hdparm -z /dev/${tgtdrive}
parted -s /dev/${tgtdrive} mklabel gpt
parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 0 24
parted -s /dev/${tgtdrive} set 1 bios_grub on
parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary fat16 24 224
parted -s /dev/${tgtdrive} set 2 boot on
parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 224 424
sleep 3
hdparm -z /dev/${tgtdrive}

# partition

# This adds support for the p seperator required for cciss devices
if echo ${tgtdrive} | grep -q -e cciss ; then
    bootdev=${tgtdrive}p
else
    bootdev=${tgtdrive}
fi
echo > /tmp/partition.ks
echo "partition /boot --onpart=/dev/${bootdev}3" >> /tmp/partition.ks
echo "partition /boot/efi --onpart=/dev/${bootdev}2" >> /tmp/partition.ks
echo "partition pv.001 --ondisk=${tgtdrive} --size=41000 --grow" >> /tmp/partition.ks
echo "volgroup os pv.001" >> /tmp/partition.ks
echo "logvol swap --vgname=os --recommended --name=swap" >> /tmp/partition.ks
echo "logvol / --vgname=os --size=10000 --name=root --fstype=ext4" >> /tmp/partition.ks
echo "logvol /var --vgname=os --size=10000 --percent 30 --grow --name=var --fstype=ext4" >> /tmp/partition.ks
echo "logvol /var/lib/docker --vgname=os --size=17000  --percent 20 --grow --name=varlibdocker --fstype=ext4" >> /tmp/partition.ks
echo "logvol /var/log --vgname=os --size=4096 --percent 50 --grow --name=varlog --fstype=ext4" >> /tmp/partition.ks


# bootloader
echo "bootloader --location=partition --driveorder=${tgtdrive} --append=' biosdevname=0 crashkernel=none'" > /tmp/bootloader.ks

# Anaconda can not install grub 0.97 on disks which are >4T.
# The reason is that grub does not support such large geometries
# and it simply thinks that the cylinder number has negative value.
# Here we just set geometry manually so that grub thinks that disk
# size is equal to 1G.
# 130 cylinders * (16065 * 512 = 8225280 bytes) = 1G
echo "%post --nochroot --log=/mnt/sysimage/root/anaconda-post-partition.log" > /tmp/post_partition.ks
echo "echo \"device (hd0) /dev/${tgtdrive}\" >> /tmp/grub.script" >> /tmp/post_partition.ks
echo "echo \"geometry (hd0) 130 255 63\" >> /tmp/grub.script" >> /tmp/post_partition.ks
echo "echo \"root (hd0,2)\" >> /tmp/grub.script" >> /tmp/post_partition.ks
echo "echo \"install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf\" >> /tmp/grub.script" >> /tmp/post_partition.ks
echo "echo quit >> /tmp/grub.script" >> /tmp/post_partition.ks
echo "cat /tmp/grub.script | chroot /mnt/sysimage /sbin/grub --no-floppy --batch" >> /tmp/post_partition.ks

%end

%packages --nobase --excludedocs
@Core
fuel
fuel-library
fuel-dockerctl
authconfig
bind-utils
cronie
crontabs
curl
daemonize
dhcp
docker-io
fuel-bootstrap-image
fuel-createmirror
fuel-target-centos-images
fuel-package-updates
fuelmenu
fuel-docker-images
gdisk
lrzip
lsof
man
mlocate
nmap-ncat
ntp
ntpdate
openssh-clients
policycoreutils
python-daemon
rsync
ruby21-puppet
ruby21-rubygem-netaddr
ruby21-rubygem-openstack
selinux-policy-targeted
strace
subscription-manager
sysstat
system-config-firewall-base
tcpdump
telnet
vim-enhanced
virt-what
wget
yum
yum-plugin-priorities

%include /tmp/post_partition.ks

# POSTINSTALL SECTION
# HERE ARE COMMANDS THAT WILL BE LAUNCHED JUST AFTER
# INSTALLATION ITSELF COMPLETED
%post
echo -e "modprobe nf_conntrack_ipv4\nmodprobe nf_conntrack_ipv6\nmodprobe nf_conntrack_tftp\nmodprobe nf_nat_tftp" >> /etc/rc.modules
chmod +x /etc/rc.modules
echo -e "net.nf_conntrack_max=1048576" >> /etc/sysctl.conf
mkdir -p /var/log/coredump
echo -e "kernel.core_pattern=/var/log/coredump/core.%e.%p.%h.%t" >> /etc/sysctl.conf
chmod 777 /var/log/coredump
echo -e "* soft core unlimited\n* hard core unlimited" >> /etc/security/limits.conf

# Mount installation media in chroot
%post --nochroot --log=/mnt/sysimage/root/anaconda-post-before-chroot.log
#!/bin/sh

set -x

SOURCE="/mnt/sysimage/tmp/source"

for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done

mkdir -p "${SOURCE}"

case "${repo}" in
  nfs:*)
    nfs_url="${repo#nfs:}"
    mount -t nfs "${nfs_url}" "${SOURCE}"
  ;;
  *)
    if [ -d "/mnt/source" ]; then
      mount -o bind "/mnt/source" "${SOURCE}"
    fi
  ;;
esac

%post --log=/root/anaconda-post-after-chroot.log
#!/bin/bash

set -x

function save_cfg {
    scrFile="/etc/sysconfig/network-scripts/ifcfg-$device"
    search="domain $domain\nsearch $domain"
    sed -i -e 's#^\(HOSTNAME=\).*$#\1'"$hostname"'#' /etc/sysconfig/network
    grep -q "^\s*$ip\s+$hostname" /etc/hosts || echo "$ip $hostname" >> /etc/hosts
    echo "${search}\nnameserver 127.0.0.1" > /etc/resolv.conf
    [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/resolv.conf
    [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/dnsmasq.upstream
    [ $dns2 ] && echo "nameserver $dns2" >> /etc/resolv.conf
    [ $dns2 ] && echo "nameserver $dns2" >> /etc/dnsmasq.upstream

    echo DEVICE=$device > $scrFile
    echo ONBOOT=yes >> $scrFile
    echo NM_CONTROLLED=no >> $scrFile
    echo HWADDR=$hwaddr >> $scrFile
    echo USERCTL=no >> $scrFile
    echo PEERDNS=no >> $scrFile
    if [ $ip ]; then
        echo BOOTPROTO=static >> $scrFile
        echo IPADDR=$ip >> $scrFile
        echo NETMASK=$netmask >> $scrFile
    else
        echo BOOTPROTO=dhcp >> $scrFile
    fi
    scrDHCPFile="/etc/sysconfig/network-scripts/ifcfg-$dhcp_interface"
    #Ignore gateway and set up DHCP if it is used, otherwise apply it
    if [ $dhcp_interface ] && [ "$dhcp_interface" != "$device" ]; then
        echo "DEVICE=$dhcp_interface" > $scrDHCPFile
        echo "BOOTPROTO=dhcp" >> $scrDHCPFile
        echo "ONBOOT=yes" >> $scrDHCPFile
        echo "USERCTL=no" >> $scrDHCPFile
    else
        echo GATEWAY=$gw >> /etc/sysconfig/network
    fi
    [ -n "$build_images" -a "$build_images" != "0" ] && echo -e "$build_images" > /root/.build_images
}

# Default FQDN
hostname="nailgun.mirantis.com"

for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done
hostname=$hostname
domain=${hostname#*.}
ip=$ip
netmask=$netmask
gw=$gw
device="eth0"
hwaddr=`ifconfig $device | grep -i hwaddr | sed -e 's#^.*hwaddr[[:space:]]*##I'`
dhcp_interface=$dhcp_interface
build_images=$build_images
save_cfg

# Mounting installation source
SOURCE=/tmp/source
FS=/tmp/fs

echo
mkdir -p ${SOURCE}
mkdir -p ${FS}

if test -e /dev/disk/by-label/"OpenStack_Fuel"; then
    mount /dev/disk/by-label/"OpenStack_Fuel" ${SOURCE}
elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then
    mount /dev/disk/by-uuid/will_be_substituted_with_actual_uuid ${FS}
    mount -o loop ${FS}/nailgun.iso ${SOURCE}
fi

OPENSTACK_VERSION=`cat ${SOURCE}/openstack_version`

# ----------------------
# UNPACKING REPOSITORIES
# ----------------------

wwwdir="/var/www/nailgun"
repodir="${wwwdir}/${OPENSTACK_VERSION}"

# Copying Centos files
mkdir -p ${repodir}/centos/x86_64
cp -r ${SOURCE}/images ${repodir}/centos/x86_64
cp -r ${SOURCE}/isolinux ${repodir}/centos/x86_64
cp -r ${SOURCE}/repodata ${repodir}/centos/x86_64
cp -r ${SOURCE}/Packages ${repodir}/centos/x86_64
cp ${SOURCE}/.treeinfo ${repodir}/centos/x86_64

# Copying Ubuntu files
mkdir -p ${repodir}/ubuntu/x86_64/images
cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/x86_64
cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/x86_64

# We do not ship debian-installer kernel and initrd on ISO.
# But we still need to be able to create ubuntu cobbler distro
# which requires kernel and initrd to be available. So, we
# just touch these files to work around cobbler's limitation.
touch ${repodir}/ubuntu/x86_64/images/linux
touch ${repodir}/ubuntu/x86_64/images/initrd.gz

# make links for backward compatibility
ln -s ${repodir}/centos ${wwwdir}/centos
ln -s ${repodir}/ubuntu ${wwwdir}/ubuntu

# --------------------------
# UNPACKING PUPPET MANIFESTS
# --------------------------

# create folders
#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/manifests/
#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/modules/
#rm -rf /etc/puppet/modules/

# TODO(ikalnitsky): investigate why we need this
#cp ${SOURCE}/puppet-slave.tgz ${wwwdir}/

# place modules and manifests
#tar zxf ${SOURCE}/puppet-slave.tgz -C /etc/puppet/${OPENSTACK_VERSION}/modules
#cp /etc/puppet/${OPENSTACK_VERSION}/modules/osnailyfacter/examples/site.pp /etc/puppet/${OPENSTACK_VERSION}/manifests/site.pp
cp ${SOURCE}/centos-versions.yaml ${SOURCE}/ubuntu-versions.yaml /etc/puppet/${OPENSTACK_VERSION}/manifests/

# make links for backward compatibility
#pushd /etc/puppet
#ln -s ${OPENSTACK_VERSION}/manifests/ /etc/puppet/manifests
#ln -s ${OPENSTACK_VERSION}/modules/ /etc/puppet/modules
#popd

cp ${SOURCE}/send2syslog.py /bin/send2syslog.py
mkdir -p /var/lib/hiera
touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml

# Prepare local repository specification
rm /etc/yum.repos.d/CentOS*.repo
cat > /etc/yum.repos.d/nailgun.repo << EOF
[nailgun]
name=Nailgun Local Repo
baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/centos/x86_64
gpgcheck=0
EOF

# Disable subscription-manager plugins
sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/product-id.conf || :
sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/subscription-manager.conf || :

# Disable GSSAPI in ssh server config
sed -i -e "/^\s*GSSAPICleanupCredentials yes/d" -e "/^\s*GSSAPIAuthentication yes/d" /etc/ssh/sshd_config

# Enable MOTD banner in sshd
sed -i -e "s/^\s*PrintMotd no/PrintMotd yes/g" /etc/ssh/sshd_config

# Add note regarding local repos creation to MOTD
cat >> /etc/motd << EOF

All environments use online repositories by default.
Use the following commands to create local repositories
on master node and change default repository settings:

* CentOS: fuel-package-updates (see --help for options)
* Ubuntu: fuel-createmirror (see --help for options)

Please refer to the following guide for more information:
https://docs.mirantis.com/openstack/fuel/fuel-6.1/reference-architecture.html#fuel-rep-mirror

EOF

# Copying bootstrap_admin_node.sh, chmod it and
# adding /etc/init/bootstrap_admin_node.conf
cp ${SOURCE}/bootstrap_admin_node.sh /usr/local/sbin/bootstrap_admin_node.sh
chmod 0777 /usr/local/sbin/bootstrap_admin_node.sh
cp ${SOURCE}/bootstrap_admin_node.conf /etc/init/bootstrap_admin_node.conf
echo "ENABLED=1" > /etc/sysconfig/bootstrap_admin_node

# Copying version.yaml file. It contains COMMIT_SHA of last commit.
RELEASE=$(awk '/release/{gsub(/"/, "");print $2}' ${SOURCE}/version.yaml)
mkdir -p /etc/nailgun /etc/fuel/${RELEASE} /etc/fuel/release_versions
cp ${SOURCE}/version.yaml /etc/nailgun/version.yaml
cp ${SOURCE}/version.yaml /etc/fuel/${RELEASE}/version.yaml
ln -s /etc/fuel/${RELEASE}/version.yaml /etc/fuel/version.yaml
cp ${SOURCE}/version.yaml /etc/fuel/release_versions/`cat  ${SOURCE}/openstack_version`.yaml

# Generete Fuel UUID
uuidgen > /etc/fuel/fuel-uuid

###Run fuel menu
[ -z "$showmenu" ] && showmenu="no"
cat > /root/.showfuelmenu << EOF
#Set to yes to run Fuel Setup
#Set to no to accept default settings
showmenu=$showmenu
EOF

# Prepare custom /etc/issue logon banner and script for changing IP in it
cat > /etc/issue << EOF
#########################################
#       Welcome to the Fuel server      #
#########################################
Server is running on \m platform

Fuel UI is available on:
http://:8000

Default administrator login:    root
Default administrator password: r00tme

Default Fuel UI login: admin
Default Fuel UI password: admin

Please change root password on first login.

EOF


cat >> '/etc/rc.local' << EOF
first=yes
for ip in \$(ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1); do
if [ "\$first" = "yes" ]; then
  ipstr="Fuel UI is available on: http://\$ip:8000"
  first=no
else
  ipstr=\$(printf "%s\n%25s%s" "\$ipstr" " " "http://\$ip:8000")
fi
done
tmpissue=\$(mktemp)
while read -r line; do
  if [[ "\$line" =~ "Fuel UI is available on" ]]; then
    echo -e "\$ipstr" >> \$tmpissue
  elif [[ "\$line" =~ :8000$ ]]; then
    :
  else
    echo -e "\$line" >> \$tmpissue
  fi
done < /etc/issue
mv "\$tmpissue" /etc/issue

EOF


# Unmounting source
umount -f ${SOURCE}
rm -rf ${SOURCE}

umount -f ${FS} || true
rm -rf ${FS}

echo "tos orphan 7" >> /etc/ntp.conf

# Do not show error message on ntpdate failure. Customers should not be confused
# if admin node does not have access to the internet time servers.
sed -i /etc/rc.d/init.d/ntpdate -e 's/\([ $RETVAL -eq 0 ] && success || \)failure/\1success/'

# Disabling splash
sed -i --follow-symlinks -e '/^\skernel/ s/rhgb//' /etc/grub.conf
sed -i --follow-symlinks -e '/^\skernel/ s/quiet//' /etc/grub.conf

# Disabling console clearing
sed -i 's/getty/getty --noclear/' /etc/init/tty.conf

# Disabling starting first console from start-ttys service
sed -i --follow-symlinks -e 's/ACTIVE_CONSOLES=.*/ACTIVE_CONSOLES=\/dev\/tty\[2-6\]/' /etc/sysconfig/init

# Copying default bash settings to the root directory
cp -f /etc/skel/.bash* /root/

# Blacklist i2c_piix4 module for VirtualBox so it does not create kernel errors
[[ $(virt-what) = "virtualbox" ]] && echo "blacklist i2c_piix4" > /etc/modprobe.d/blacklist-i2c-piix4.conf

%end