3 %include /tmp/source.ks
11 # ignore unsupported hardware warning
15 # NEVER ever place zerombr here, it breaks automated installation
16 %include /tmp/bootloader.ks
17 %include /tmp/partition.ks
20 # HERE ARE COMMANDS THAT WILL BE LAUNCHED BEFORE
21 # INSTALLATION PROCESS ITSELF
28 for drv in `ls -1 /sys/block | grep "sd\|hd\|vd\|cciss"`; do
29 if (grep -q 0 /sys/block/${drv}/removable); then
30 drives="${drives} ${drv}"
32 removable_drives="${removable_drives} ${drv}"
35 default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'`
37 installdrive="undefined"
39 for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done
41 set ${drives} ${removable_drives}
44 tgtdrive="${installdrive}"
46 function confirm_format {
48 local confirm_format="no"
50 if [[ "$forceformat" == "yes" ]] ; then
54 if parted -s /dev/$check_drive print &>/dev/null ; then
56 echo "$check_drive drive contains partition table:"
57 parted -s /dev/$check_drive print
59 read -p "Are you sure you want to erase ALL data on disk $check_drive? (y/N)" confirm_format
60 if [[ "$confirm_format" == "y" ]] || [[ "$confirm_format" == "Y" ]] || [[ "$forceformat" == "yes" ]]; then
72 if [ $numdrives -lt 1 ]; then
73 exec < /dev/tty3 > /dev/tty3 2>&1
77 echo '********************************************************************'
80 echo '* There is no suitable media available for installation. *'
81 echo '* Please attach a drive and try again. *'
83 echo '********************************************************************'
85 read -p "Press Enter to shut down the system: " _
89 if [ ${numdrives} -gt 1 ] || [ `echo ${drives} | wc -w` -eq 0 ] ; then
90 exec < /dev/tty3 > /dev/tty3 2>&1
92 while [ "${tgtdrive}" = "undefined" ]; do
95 echo '********************************************************************************'
96 echo '* W A R N I N G *'
98 echo '* Which of the detected hard drives do you want to be used as *'
99 echo '* the installation target? *'
101 echo '********************************************************************************'
103 echo "Possible choices"
104 echo "Persistent drives: ${drives}"
105 echo "Removable drives: ${removable_drives}"
107 if [ `echo ${drives} | wc -w` -eq 1 ] ; then
108 read -t 30 -p "Choose hard drive: " tgtdrive || tgtdrive=$default_drive
110 read -p "Choose hard drive: " tgtdrive
113 for drive in ${drives[@]} ${removable_drives[@]}; do
114 if [[ "$drive" == "$tgtdrive" ]] && match="yes" ; then
115 if confirm_format $tgtdrive ; then
116 format_confirmed="yes"
120 read -p "You may select another disk. Press Enter to continue." _
124 if [[ "$match" == "no" ]]; then
126 read -p "Invalid choice. Press Enter to continue." _
132 tgtdrive=`echo ${drives} | sed -e "s/^\s*//" -e "s/\s*$//"`
135 if [ "$format_confirmed" != "yes" ] ; then
136 exec < /dev/tty3 > /dev/tty3 2>&1
138 if ! confirm_format $tgtdrive ; then
141 echo '********************************************************************'
144 echo '* Disk $tgtdrive contains active partition(s). *'
145 echo '* Installation cannot continue without confirmation. *'
147 echo '********************************************************************'
149 read -p "Press Enter to restart: " _
155 # verify tgtdrive is at least 30GB
156 tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 ))
157 if [ $tgtdrivesize -lt 30720 ]; then
158 exec < /dev/tty3 > /dev/tty3 2>&1
162 echo '********************************************************************'
165 echo '* Your disk is under 30GB in size. Installation cannot continue. *'
166 echo '* Restart installation with a larger disk. *'
168 echo '********************************************************************'
170 read -p "Press Enter to restart: " _
174 # paths in /dev have "/" instead of "!" for cciss devices
175 tgtdrive=$(echo $tgtdrive | sed -e 's/!/\//')
178 if test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then
179 echo "harddrive --partition=UUID=will_be_substituted_with_actual_uuid --dir=/" > /tmp/source.ks
181 echo "cdrom" > /tmp/source.ks
185 dd if=/dev/zero of=/dev/${tgtdrive} bs=10M count=10
187 hdparm -z /dev/${tgtdrive}
188 parted -s /dev/${tgtdrive} mklabel gpt
189 parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 0 24
190 parted -s /dev/${tgtdrive} set 1 bios_grub on
191 parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary fat16 24 224
192 parted -s /dev/${tgtdrive} set 2 boot on
193 parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 224 424
195 hdparm -z /dev/${tgtdrive}
199 # This adds support for the p seperator required for cciss devices
200 if echo ${tgtdrive} | grep -q -e cciss ; then
205 echo > /tmp/partition.ks
206 echo "partition /boot --onpart=/dev/${bootdev}3" >> /tmp/partition.ks
207 echo "partition pv.001 --ondisk=${tgtdrive} --size=30000 --grow" >> /tmp/partition.ks
208 echo "volgroup os pv.001" >> /tmp/partition.ks
209 echo "logvol swap --vgname=os --recommended --name=swap" >> /tmp/partition.ks
210 echo "logvol / --vgname=os --size=10000 --name=root --fstype=ext4" >> /tmp/partition.ks
211 echo "logvol /var --vgname=os --size=10000 --percent 60 --grow --name=var --fstype=ext4" >> /tmp/partition.ks
212 echo "logvol /var/log --vgname=os --size=4096 --percent 40 --grow --name=varlog --fstype=ext4" >> /tmp/partition.ks
216 echo "bootloader --location=mbr --driveorder=${tgtdrive} --append=' biosdevname=0 crashkernel=none'" > /tmp/bootloader.ks
218 # Anaconda can not install grub 0.97 on disks which are >4T.
219 # The reason is that grub does not support such large geometries
220 # and it simply thinks that the cylinder number has negative value.
221 # Here we just set geometry manually so that grub thinks that disk
222 # size is equal to 1G.
223 # 130 cylinders * (16065 * 512 = 8225280 bytes) = 1G
224 echo "%post --nochroot --log=/mnt/sysimage/root/anaconda-post-partition.log" > /tmp/post_partition.ks
225 echo "echo \"device (hd0) /dev/${tgtdrive}\" >> /tmp/grub.script" >> /tmp/post_partition.ks
226 echo "echo \"geometry (hd0) 130 255 63\" >> /tmp/grub.script" >> /tmp/post_partition.ks
227 echo "echo \"root (hd0,2)\" >> /tmp/grub.script" >> /tmp/post_partition.ks
228 echo "echo \"install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf\" >> /tmp/grub.script" >> /tmp/post_partition.ks
229 echo "echo quit >> /tmp/grub.script" >> /tmp/post_partition.ks
230 echo "cat /tmp/grub.script | chroot /mnt/sysimage /sbin/grub --no-floppy --batch" >> /tmp/post_partition.ks
234 %packages --nobase --excludedocs
256 ruby21-rubygem-netaddr
257 ruby21-rubygem-openstack
258 selinux-policy-targeted
262 system-config-firewall-base
270 %include /tmp/post_partition.ks
272 # POSTINSTALL SECTION
273 # HERE ARE COMMANDS THAT WILL BE LAUNCHED JUST AFTER
274 # INSTALLATION ITSELF COMPLETED
276 echo -e "modprobe nf_conntrack_ipv4\nmodprobe nf_conntrack_ipv6\nmodprobe nf_conntrack_tftp\nmodprobe nf_nat_tftp" >> /etc/rc.modules
277 chmod +x /etc/rc.modules
278 echo -e "net.nf_conntrack_max=1048576" >> /etc/sysctl.conf
279 mkdir -p /var/log/coredump
280 echo -e "kernel.core_pattern=/var/log/coredump/core.%e.%p.%h.%t" >> /etc/sysctl.conf
281 chmod 777 /var/log/coredump
282 echo -e "* soft core unlimited\n* hard core unlimited" >> /etc/security/limits.conf
284 # Mount installation media in chroot
285 %post --nochroot --log=/mnt/sysimage/root/anaconda-post-before-chroot.log
288 SOURCE="/mnt/sysimage/tmp/source"
290 for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done
296 nfs_url="${repo#nfs:}"
297 mount -t nfs "${nfs_url}" "${SOURCE}"
300 if [ -d "/mnt/source" ]; then
301 mount -o bind "/mnt/source" "${SOURCE}"
306 %post --log=/root/anaconda-post-after-chroot.log
312 scrFile="/etc/sysconfig/network-scripts/ifcfg-$device"
313 search="domain $domain\nsearch $domain"
314 sed -i -e 's#^\(HOSTNAME=\).*$#\1'"$hostname"'#' /etc/sysconfig/network
315 grep -q "^\s*$ip\s+$hostname" /etc/hosts || echo "$ip $hostname" >> /etc/hosts
316 echo "${search}\nnameserver 127.0.0.1" > /etc/resolv.conf
317 [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/resolv.conf
318 [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/dnsmasq.upstream
319 [ $dns2 ] && echo "nameserver $dns2" >> /etc/resolv.conf
320 [ $dns2 ] && echo "nameserver $dns2" >> /etc/dnsmasq.upstream
322 echo DEVICE=$device > $scrFile
323 echo ONBOOT=yes >> $scrFile
324 echo NM_CONTROLLED=no >> $scrFile
325 echo HWADDR=$hwaddr >> $scrFile
326 echo USERCTL=no >> $scrFile
327 echo PEERDNS=no >> $scrFile
329 echo BOOTPROTO=static >> $scrFile
330 echo IPADDR=$ip >> $scrFile
331 echo NETMASK=$netmask >> $scrFile
333 echo BOOTPROTO=dhcp >> $scrFile
335 scrDHCPFile="/etc/sysconfig/network-scripts/ifcfg-$dhcp_interface"
336 #Ignore gateway and set up DHCP if it is used, otherwise apply it
337 if [ $dhcp_interface ] && [ "$dhcp_interface" != "$device" ]; then
338 echo "DEVICE=$dhcp_interface" > $scrDHCPFile
339 echo "BOOTPROTO=dhcp" >> $scrDHCPFile
340 echo "ONBOOT=yes" >> $scrDHCPFile
341 echo "USERCTL=no" >> $scrDHCPFile
343 echo GATEWAY=$gw >> /etc/sysconfig/network
348 hostname="nailgun.mirantis.com"
350 for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done
352 domain=${hostname#*.}
357 hwaddr=`ifconfig $device | grep -i hwaddr | sed -e 's#^.*hwaddr[[:space:]]*##I'`
358 dhcp_interface=$dhcp_interface
361 # Mounting installation source
369 if test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then
370 mount /dev/disk/by-uuid/will_be_substituted_with_actual_uuid ${FS}
371 mount -o loop ${FS}/nailgun.iso ${SOURCE}
374 OPENSTACK_VERSION=`cat ${SOURCE}/openstack_version`
376 # ----------------------
377 # UNPACKING REPOSITORIES
378 # ----------------------
380 wwwdir="/var/www/nailgun"
381 repodir="${wwwdir}/${OPENSTACK_VERSION}"
383 # Copying Centos files
384 mkdir -p ${repodir}/centos/x86_64
385 cp -r ${SOURCE}/images ${repodir}/centos/x86_64
386 cp -r ${SOURCE}/isolinux ${repodir}/centos/x86_64
387 cp -r ${SOURCE}/repodata ${repodir}/centos/x86_64
388 cp -r ${SOURCE}/Packages ${repodir}/centos/x86_64
389 cp ${SOURCE}/.treeinfo ${repodir}/centos/x86_64
391 # Copying Ubuntu files
392 mkdir -p ${repodir}/ubuntu/x86_64/images
393 cp -r ${SOURCE}/ubuntu/conf ${repodir}/ubuntu/x86_64
394 cp -r ${SOURCE}/ubuntu/db ${repodir}/ubuntu/x86_64
395 cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/x86_64
396 cp -r ${SOURCE}/ubuntu/indices ${repodir}/ubuntu/x86_64
397 cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/x86_64
398 cp -r ${SOURCE}/ubuntu/installer-amd64/current/images/netboot/ubuntu-installer/amd64/linux ${repodir}/ubuntu/x86_64/images
399 cp -r ${SOURCE}/ubuntu/installer-amd64/current/images/netboot/ubuntu-installer/amd64/initrd.gz ${repodir}/ubuntu/x86_64/images
401 # make links for backward compatibility
402 ln -s ${repodir}/centos ${wwwdir}/centos
403 ln -s ${repodir}/ubuntu ${wwwdir}/ubuntu
405 # Copying bootstrap image
406 mkdir -p ${wwwdir}/bootstrap
407 cp -r ${SOURCE}/bootstrap/initramfs.img ${wwwdir}/bootstrap
408 cp -r ${SOURCE}/bootstrap/linux ${wwwdir}/bootstrap
410 # Copying target images
411 cp -r ${SOURCE}/targetimages ${wwwdir}
415 cp ${SOURCE}/bootstrap/bootstrap.rsa /root/.ssh
416 chmod 600 /root/.ssh/bootstrap.rsa
418 # --------------------------
419 # UNPACKING PUPPET MANIFESTS
420 # --------------------------
423 mkdir -p /etc/puppet/${OPENSTACK_VERSION}/manifests/
424 mkdir -p /etc/puppet/${OPENSTACK_VERSION}/modules/
425 rm -rf /etc/puppet/modules/
427 # TODO(ikalnitsky): investigate why we need this
428 cp ${SOURCE}/puppet-slave.tgz ${wwwdir}/
430 # place modules and manifests
431 tar zxf ${SOURCE}/puppet-slave.tgz -C /etc/puppet/${OPENSTACK_VERSION}/modules
432 cp /etc/puppet/${OPENSTACK_VERSION}/modules/osnailyfacter/examples/site.pp /etc/puppet/${OPENSTACK_VERSION}/manifests/site.pp
433 cp ${SOURCE}/centos-versions.yaml ${SOURCE}/ubuntu-versions.yaml /etc/puppet/${OPENSTACK_VERSION}/manifests/
435 # make links for backward compatibility
437 ln -s ${OPENSTACK_VERSION}/manifests/ /etc/puppet/manifests
438 ln -s ${OPENSTACK_VERSION}/modules/ /etc/puppet/modules
441 cp ${SOURCE}/send2syslog.py /bin/send2syslog.py
442 mkdir -p /var/lib/hiera
443 touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml
445 # Deploy docker images and ctl tools if we built ISO with docker containers support
446 [ -d "${SOURCE}/docker" ] && cp -r ${SOURCE}/docker ${wwwdir}/docker
448 # Prepare local repository specification
449 rm /etc/yum.repos.d/CentOS*.repo
450 cat > /etc/yum.repos.d/nailgun.repo << EOF
452 name=Nailgun Local Repo
453 baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/centos/x86_64
457 # Disable subscription-manager plugins
458 sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/product-id.conf || :
459 sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/subscription-manager.conf || :
461 # Disable GSSAPI in ssh server config
462 sed -i -e "/^\s*GSSAPICleanupCredentials yes/d" -e "/^\s*GSSAPIAuthentication yes/d" /etc/ssh/sshd_config
464 # Copying bootstrap_admin_node.sh, chmod it and
465 # adding /etc/init/bootstrap_admin_node.conf
466 cp ${SOURCE}/bootstrap_admin_node.sh /usr/local/sbin/bootstrap_admin_node.sh
467 chmod 0777 /usr/local/sbin/bootstrap_admin_node.sh
468 cp ${SOURCE}/bootstrap_admin_node.conf /etc/init/bootstrap_admin_node.conf
469 echo "ENABLED=1" > /etc/sysconfig/bootstrap_admin_node
471 # Copying version.yaml file. It contains COMMIT_SHA of last commit.
472 RELEASE=$(awk '/release/{gsub(/"/, "");print $2}' ${SOURCE}/version.yaml)
473 mkdir -p /etc/nailgun /etc/fuel/${RELEASE} /etc/fuel/release_versions
474 cp ${SOURCE}/version.yaml /etc/nailgun/version.yaml
475 cp ${SOURCE}/version.yaml /etc/fuel/${RELEASE}/version.yaml
476 ln -s /etc/fuel/${RELEASE}/version.yaml /etc/fuel/version.yaml
477 cp ${SOURCE}/version.yaml /etc/fuel/release_versions/`cat ${SOURCE}/openstack_version`.yaml
480 uuidgen > /etc/fuel/fuel-uuid
483 [ -z "$showmenu" ] && showmenu="no"
484 cat > /root/.showfuelmenu << EOF
485 #Set to yes to run Fuel Setup
486 #Set to no to accept default settings
490 # Prepare custom /etc/issue logon banner and script for changing IP in it
491 cat > /etc/issue << EOF
492 #########################################
493 # Welcome to the Fuel server #
494 #########################################
495 Server is running on \m platform
497 Fuel UI is available on:
500 Default administrator login: root
501 Default administrator password: r00tme
503 Default Fuel UI login: admin
504 Default Fuel UI password: admin
506 Please change root password on first login.
511 cat >> '/etc/rc.local' << EOF
513 for ip in \$(ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1); do
514 if [ "\$first" = "yes" ]; then
515 ipstr="Fuel UI is available on: http://\$ip:8000"
518 ipstr=\$(printf "%s\n%25s%s" "\$ipstr" " " "http://\$ip:8000")
522 while read -r line; do
523 if [[ "\$line" =~ "Fuel UI is available on" ]]; then
524 echo -e "\$ipstr" >> \$tmpissue
525 elif [[ "\$line" =~ :8000$ ]]; then
528 echo -e "\$line" >> \$tmpissue
531 mv "\$tmpissue" /etc/issue
535 ######### OPNFV addition BEGIN ############
536 # Copy data into /opt/opnfv
537 # TODO: This ought to be a package instead!
539 cp -r ${SOURCE}/opnfv /opt
540 ######### OPNFV addition END ############
546 umount -f ${FS} || true
549 # Enabling/configuring NTPD and ntpdate services
550 echo "server 127.127.1.0" >> /etc/ntp.conf
551 echo "fudge 127.127.1.0 stratum 10" >> /etc/ntp.conf
552 echo "tos orphan 7" >> /etc/ntp.conf
554 # Do not show error message on ntpdate failure. Customers should not be confused
555 # if admin node does not have access to the internet time servers.
556 sed -i /etc/rc.d/init.d/ntpdate -e 's/\([ $RETVAL -eq 0 ] && success || \)failure/\1success/'
559 sed -i --follow-symlinks -e '/^\skernel/ s/rhgb//' /etc/grub.conf
560 sed -i --follow-symlinks -e '/^\skernel/ s/quiet//' /etc/grub.conf
562 # Disabling console clearing
563 sed -i 's/getty/getty --noclear/' /etc/init/tty.conf
565 # Disabling starting first console from start-ttys service
566 sed -i --follow-symlinks -e 's/ACTIVE_CONSOLES=.*/ACTIVE_CONSOLES=\/dev\/tty\[2-6\]/' /etc/sysconfig/init
568 # Copying default bash settings to the root directory
569 cp -f /etc/skel/.bash* /root/
571 # Blacklist i2c_piix4 module for VirtualBox so it does not create kernel errors
572 [[ $(virt-what) = "virtualbox" ]] && echo "blacklist i2c_piix4" > /etc/modprobe.d/blacklist-i2c-piix4.conf