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 (grep -q 0 /sys/block/${drv}/removable); then drives="${drives} ${drv}" else removable_drives="${removable_drives} ${drv}" 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" ]] || [[ "$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 30GB tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 )) if [ $tgtdrivesize -lt 30720 ]; 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 30GB 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-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 pv.001 --ondisk=${tgtdrive} --size=30000 --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=1 --grow --name=var --fstype=xfs" >> /tmp/partition.ks # bootloader echo "bootloader --location=mbr --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 authconfig bind-utils cronie crontabs curl daemonize dhcp docker-io fuelmenu gdisk lrzip lsof man mlocate nmap-ncat ntp openssh-clients policycoreutils 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 %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 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 } # 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 save_cfg # Mounting installation source SOURCE=/tmp/source FS=/tmp/fs echo mkdir -p ${SOURCE} mkdir -p ${FS} if 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 # Copying Repo to the nailgun /var/www directory repodir="/var/www/nailgun" mkdir -p ${repodir}/centos/fuelweb/x86_64 cp -r ${SOURCE}/images ${repodir}/centos/fuelweb/x86_64 cp -r ${SOURCE}/isolinux ${repodir}/centos/fuelweb/x86_64 cp -r ${SOURCE}/repodata ${repodir}/centos/fuelweb/x86_64 cp -r ${SOURCE}/Packages ${repodir}/centos/fuelweb/x86_64 cp ${SOURCE}/.treeinfo ${repodir}/centos/fuelweb/x86_64 # Copying Ubuntu files mkdir -p ${repodir}/ubuntu/fuelweb/x86_64/images cp -r ${SOURCE}/ubuntu/conf ${repodir}/ubuntu/fuelweb/x86_64 cp -r ${SOURCE}/ubuntu/db ${repodir}/ubuntu/fuelweb/x86_64 cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/fuelweb/x86_64 cp -r ${SOURCE}/ubuntu/indices ${repodir}/ubuntu/fuelweb/x86_64 cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/fuelweb/x86_64 cp -r ${SOURCE}/ubuntu/installer-amd64/current/images/netboot/ubuntu-installer/amd64/linux ${repodir}/ubuntu/fuelweb/x86_64/images cp -r ${SOURCE}/ubuntu/installer-amd64/current/images/netboot/ubuntu-installer/amd64/initrd.gz ${repodir}/ubuntu/fuelweb/x86_64/images # Copying bootstrap image mkdir -p ${repodir}/bootstrap cp -r ${SOURCE}/bootstrap/initramfs.img ${repodir}/bootstrap cp -r ${SOURCE}/bootstrap/linux ${repodir}/bootstrap mkdir -p /root/.ssh chmod 700 /root/.ssh cp ${SOURCE}/bootstrap/bootstrap.rsa /root/.ssh chmod 600 /root/.ssh/bootstrap.rsa # Unpacking puppet manifests for master and slave cp ${SOURCE}/puppet-slave.tgz ${repodir}/ tar zxf ${SOURCE}/puppet-slave.tgz -C /etc/puppet/modules mkdir -p /etc/puppet/manifests/ cp /etc/puppet/modules/osnailyfacter/examples/site.pp /etc/puppet/manifests/site.pp cp ${SOURCE}/centos-versions.yaml ${SOURCE}/ubuntu-versions.yaml /etc/puppet/manifests/ cp ${SOURCE}/send2syslog.py /bin/send2syslog.py mkdir -p /var/lib/hiera touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml # Deploy docker images and ctl tools if we built ISO with docker containers support [ -d "${SOURCE}/docker" ] && cp -r ${SOURCE}/docker ${repodir}/docker # 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/centos/fuelweb/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 # 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%51s" "\$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} # Enabling/configuring NTPD and ntpdate services echo "server 127.127.1.0" >> /etc/ntp.conf echo "fudge 127.127.1.0 stratum 10" >> /etc/ntp.conf 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