aboutsummaryrefslogtreecommitdiffstats
path: root/build/f_isoroot/f_bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'build/f_isoroot/f_bootstrap')
-rw-r--r--build/f_isoroot/f_bootstrap/Makefile48
-rw-r--r--build/f_isoroot/f_bootstrap/README24
-rwxr-xr-xbuild/f_isoroot/f_bootstrap/bootstrap_admin_node.sh266
-rwxr-xr-xbuild/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig246
-rwxr-xr-xbuild/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh4
-rwxr-xr-xbuild/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh19
-rwxr-xr-xbuild/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh4
7 files changed, 611 insertions, 0 deletions
diff --git a/build/f_isoroot/f_bootstrap/Makefile b/build/f_isoroot/f_bootstrap/Makefile
new file mode 100644
index 000000000..a958aa2d6
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/Makefile
@@ -0,0 +1,48 @@
+##############################################################################
+# Copyright (c) 2015 Ericsson AB and others.
+# stefan.k.berg@ericsson.com
+# jonas.bjurel@ericsson.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+TOP := $(shell pwd)
+
+.PHONY: all
+all:
+ @mkdir -p release/opnfv/bootstrap/pre.d
+ @mkdir -p release/opnfv/bootstrap/post.d
+ @mkdir -p release/usr/local/sbin
+ @cp pre-scripts/* release/opnfv/bootstrap/pre.d
+ @cp post-scripts/* release/opnfv/bootstrap/post.d
+ @cp bootstrap_admin_node.sh release
+ @cp bootstrap_admin_node.sh.orig release
+
+.PHONY: clean
+clean:
+ @rm -rf release
+
+.PHONY: release
+release:all
+ @cp -Rvp release/* ../release
+
+#############################################################################
+# Cache operations - only used when building through ci/build.sh
+#############################################################################
+
+# Clean local data related to caching - called prior to ordinary build
+.PHONY: clean-cache
+clean-cache: clean
+ @echo "clean-cache not implemented"
+
+# Try to download cache - called prior to ordinary build
+.PHONY: get-cache
+get-cache:
+ @echo "get-cache not implemented"
+
+# Store cache if not already stored - called after ordinary build
+.PHONY: put-cache
+put-cache:
+ @echo "put-cache not implemented"
diff --git a/build/f_isoroot/f_bootstrap/README b/build/f_isoroot/f_bootstrap/README
new file mode 100644
index 000000000..5da954ca4
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/README
@@ -0,0 +1,24 @@
+##############################################################################
+# Copyright (c) 2015 Ericsson AB and others.
+# stefan.k.berg@ericsson.com
+# jonas.bjurel@ericsson.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+This function modifies the adds hooks to the beginning and end of
+/usr/local/sbin/bootstrap_admin_nodes.sh, which is run as the
+last post step from ks.cfg
+
+This enables other functions to place scripts into two directories
+run either at the beginning or the end of the bootstrap procedure:
+
+ /opt/opnfv/bootstrap/pre.d
+ /opt/opnfv/bootstrap/post.d
+
+These will be run in lexical order at pre or post.
+
+CI note: Using pre.d, it would be possible to "inject" a pre-defined
+astute.yaml for Fuel.
diff --git a/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh
new file mode 100755
index 000000000..065d0cb7d
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh
@@ -0,0 +1,266 @@
+#!/bin/bash
+FUEL_RELEASE=$(grep release: /etc/fuel/version.yaml | cut -d: -f2 | tr -d '" ')
+
+function countdown() {
+ local i
+ sleep 1
+ for ((i=$1-1; i>=1; i--)); do
+ printf '\b\b\b\b%04d' "$i"
+ sleep 1
+ done
+}
+
+function fail() {
+ echo "ERROR: Fuel node deployment FAILED! Check /var/log/puppet/bootstrap_admin_node.log for details" 1>&2
+ exit 1
+}
+# LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details
+export LANG=en_US.UTF8
+export ADMIN_INTERFACE=eth0
+
+showmenu="no"
+if [ -f /etc/fuel/bootstrap_admin_node.conf ]; then
+ . /etc/fuel/bootstrap_admin_node.conf
+ echo "Applying admin interface '$ADMIN_INTERFACE'"
+fi
+
+echo "Applying default Fuel settings..."
+set -x
+fuelmenu --save-only --iface=$ADMIN_INTERFACE
+set +x
+echo "Done!"
+
+### OPNFV addition BEGIN
+shopt -s nullglob
+for script in /opt/opnfv/bootstrap/pre.d/*.sh
+do
+ echo "Pre script: $script" >> /root/pre.log 2>&1
+ $script >> /root/pre.log 2>&1
+done
+shopt -u nullglob
+### OPNFV addition END
+
+if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then
+ fuelmenu
+ else
+ #Give user 15 seconds to enter fuelmenu or else continue
+ echo
+ echo -n "Press a key to enter Fuel Setup (or press ESC to skip)... 15"
+ countdown 15 & pid=$!
+ if ! read -s -n 1 -t 15 key; then
+ echo -e "\nSkipping Fuel Setup..."
+ else
+ { kill "$pid"; wait $!; } 2>/dev/null
+ case "$key" in
+ $'\e') echo "Skipping Fuel Setup.."
+ ;;
+ *) echo -e "\nEntering Fuel Setup..."
+ fuelmenu
+ ;;
+ esac
+ fi
+fi
+
+if [ "$wait_for_external_config" == "yes" ]; then
+ wait_timeout=3000
+ pidfile=/var/lock/wait_for_external_config
+ echo -n "Waiting for external configuration (or press ESC to skip)...
+$wait_timeout"
+ countdown $wait_timeout & countdown_pid=$!
+ exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$!
+ echo $wait_pid > $pidfile
+ while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do
+ read -s -n 1 -t 2 key
+ case "$key" in
+ $'\e') echo -e "\b\b\b\b abort on user input"
+ break
+ ;;
+ *) ;;
+ esac
+ done
+ { kill $countdown_pid $wait_pid & wait $!; }
+ rm -f $pidfile
+fi
+
+
+#Reread /etc/sysconfig/network to inform puppet of changes
+. /etc/sysconfig/network
+hostname "$HOSTNAME"
+
+# XXX: ssh keys which should be included into the bootstrap image are
+# generated during containers deployment. However cobbler checkfs for
+# a kernel and initramfs when creating a profile, which poses chicken
+# and egg problem. Fortunately cobbler is pretty happy with empty files
+# so it's easy to break the loop.
+make_ubuntu_bootstrap_stub () {
+ local bootstrap_dir='/var/www/nailgun/bootstrap/ubuntu'
+ mkdir -p $bootstrap_dir
+ for item in linux initramfs.img; do
+ touch "$bootstrap_dir/$item"
+ done
+}
+
+get_bootstrap_flavor () {
+ local ASTUTE_YAML='/etc/fuel/astute.yaml'
+ python <<-EOF
+ from fuelmenu.fuelmenu import Settings
+ conf = Settings().read("$ASTUTE_YAML").get('BOOTSTRAP', {})
+ print(conf.get('flavor', 'centos'))
+ EOF
+}
+
+# Actually build the bootstrap image
+build_ubuntu_bootstrap () {
+ local ret=1
+ local max_attempts=3
+ local config='/etc/fuel-bootstrap-image.conf'
+ local log='/var/log/fuel-bootstrap-image-build.log'
+ if ! grep -qE '^BOOTSTRAP_SSH_KEYS' "$config"; then
+ # FIXME: config file generated by fuelmenu has no trailing newline
+ echo >> "$config"
+ cat >> "$config" <<-EOF
+ BOOTSTRAP_SSH_KEYS=/root/.ssh/id_rsa.pub
+ EOF
+ fi
+ for n in `seq 1 $max_attempts`; do
+ echo "Bulding bootstrap image, attempt $n" >&2
+ if fuel-bootstrap-image >>"$log" 2>&1; then
+ ret=0
+ fuel-bootstrap-image-set "ubuntu"
+ break
+ fi
+ done
+ if [ $ret -ne 0 ]; then
+ warning="WARNING: failed to build the bootstrap image, see $log for details.
+Perhaps your Internet connection is broken. Please fix the problem and run
+\`fuel-bootstrap-image-set ubuntu\`"
+ fuel notify --topic warning --send "$warning"
+ fi
+ return $ret
+}
+
+
+# Create empty files to make cobbler happy
+# (even if we don't use Ubuntu based bootstrap)
+make_ubuntu_bootstrap_stub
+
+service docker start
+
+if [ -f /root/.build_images ]; then
+ #Fail on all errors
+ set -e
+ trap fail EXIT
+
+ echo "Loading Fuel base image for Docker..."
+ docker load -i /var/www/nailgun/docker/images/fuel-images.tar
+
+ echo "Building Fuel Docker images..."
+ WORKDIR=$(mktemp -d /tmp/docker-buildXXX)
+ SOURCE=/var/www/nailgun/docker
+ REPO_CONT_ID=$(docker -D run -d -p 80 -v /var/www/nailgun:/var/www/nailgun fuel/centos sh -c 'mkdir /var/www/html/os;ln -sf /var/www/nailgun/centos/x86_64 /var/www/html/os/x86_64;/usr/sbin/apachectl -DFOREGROUND')
+ RANDOM_PORT=$(docker port $REPO_CONT_ID 80 | cut -d':' -f2)
+
+ for imagesource in /var/www/nailgun/docker/sources/*; do
+ if ! [ -f "$imagesource/Dockerfile" ]; then
+ echo "Skipping ${imagesource}..."
+ continue
+ fi
+ image=$(basename "$imagesource")
+ cp -R "$imagesource" $WORKDIR/$image
+ mkdir -p $WORKDIR/$image/etc
+ cp -R /etc/puppet /etc/fuel $WORKDIR/$image/etc
+ sed -e "s/_PORT_/${RANDOM_PORT}/" -i $WORKDIR/$image/Dockerfile
+ sed -e 's/production:.*/production: "docker-build"/' -i $WORKDIR/$image/etc/fuel/version.yaml
+ docker build -t fuel/${image}_${FUEL_RELEASE} $WORKDIR/$image
+ done
+ docker rm -f $REPO_CONT_ID
+ rm -rf "$WORKDIR"
+
+ #Remove trap for normal deployment
+ trap - EXIT
+ set +e
+else
+ echo "Loading docker images. (This may take a while)"
+ docker load -i /var/www/nailgun/docker/images/fuel-images.tar
+fi
+
+# apply puppet
+puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/host-only.pp
+if [ $? -ge 4 ];then
+ fail
+fi
+
+rmdir /var/log/remote && ln -s /var/log/docker-logs/remote /var/log/remote
+
+dockerctl check || fail
+bash /etc/rc.local
+
+if [ "`get_bootstrap_flavor`" = "ubuntu" ]; then
+ build_ubuntu_bootstrap || true
+fi
+
+### OPNFV addition BEGIN
+shopt -s nullglob
+for script in /opt/opnfv/bootstrap/post.d/*.sh
+do
+ echo "Post script: $script" >> /root/post.log 2>&1
+ $script >> /root/post.log 2>&1
+done
+shopt -u nullglob
+### OPNFV addition END
+
+# Enable updates repository
+cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-updates.repo << EOF
+[mos${FUEL_RELEASE}-updates]
+name=mos${FUEL_RELEASE}-updates
+baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/updates/x86_64/
+gpgcheck=0
+skip_if_unavailable=1
+EOF
+
+# Enable security repository
+cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-security.repo << EOF
+[mos${FUEL_RELEASE}-security]
+name=mos${FUEL_RELEASE}-security
+baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/security/x86_64/
+gpgcheck=0
+skip_if_unavailable=1
+EOF
+
+#Check if repo is accessible
+echo "Checking for access to updates repository..."
+repourl=$(grep baseurl /etc/yum.repos.d/*updates* 2>/dev/null | cut -d'=' -f2- | head -1)
+if urlaccesscheck check "$repourl" ; then
+ UPDATE_ISSUES=0
+else
+ UPDATE_ISSUES=1
+fi
+
+if [ $UPDATE_ISSUES -eq 1 ]; then
+ message="There is an issue connecting to the Fuel update repository. \
+Please fix your connection prior to applying any updates. \
+Once the connection is fixed, we recommend reviewing and applying \
+Maintenance Updates for this release of Mirantis OpenStack: \
+https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
+release-notes.html#maintenance-updates"
+ level="warning"
+else
+ message="We recommend reviewing and applying Maintenance Updates \
+for this release of Mirantis OpenStack: \
+https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
+release-notes.html#maintenance-updates"
+ level="done"
+fi
+echo
+echo "*************************************************"
+echo -e "${message}"
+echo "*************************************************"
+echo "Sending notification to Fuel UI..."
+fuel notify --topic "${level}" --send "${message}"
+
+# TODO(kozhukalov) If building of bootstrap image fails
+# and if this image was supposed to be a default bootstrap image
+# we need to warn a user about this and give her
+# advice how to treat this.
+
+echo "Fuel node deployment complete!"
diff --git a/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig
new file mode 100755
index 000000000..1bc349314
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig
@@ -0,0 +1,246 @@
+#!/bin/bash
+FUEL_RELEASE=$(grep release: /etc/fuel/version.yaml | cut -d: -f2 | tr -d '" ')
+
+function countdown() {
+ local i
+ sleep 1
+ for ((i=$1-1; i>=1; i--)); do
+ printf '\b\b\b\b%04d' "$i"
+ sleep 1
+ done
+}
+
+function fail() {
+ echo "ERROR: Fuel node deployment FAILED! Check /var/log/puppet/bootstrap_admin_node.log for details" 1>&2
+ exit 1
+}
+# LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details
+export LANG=en_US.UTF8
+export ADMIN_INTERFACE=eth0
+
+showmenu="no"
+if [ -f /etc/fuel/bootstrap_admin_node.conf ]; then
+ . /etc/fuel/bootstrap_admin_node.conf
+ echo "Applying admin interface '$ADMIN_INTERFACE'"
+fi
+
+echo "Applying default Fuel settings..."
+set -x
+fuelmenu --save-only --iface=$ADMIN_INTERFACE
+set +x
+echo "Done!"
+
+if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then
+ fuelmenu
+ else
+ #Give user 15 seconds to enter fuelmenu or else continue
+ echo
+ echo -n "Press a key to enter Fuel Setup (or press ESC to skip)... 15"
+ countdown 15 & pid=$!
+ if ! read -s -n 1 -t 15 key; then
+ echo -e "\nSkipping Fuel Setup..."
+ else
+ { kill "$pid"; wait $!; } 2>/dev/null
+ case "$key" in
+ $'\e') echo "Skipping Fuel Setup.."
+ ;;
+ *) echo -e "\nEntering Fuel Setup..."
+ fuelmenu
+ ;;
+ esac
+ fi
+fi
+
+if [ "$wait_for_external_config" == "yes" ]; then
+ wait_timeout=3000
+ pidfile=/var/lock/wait_for_external_config
+ echo -n "Waiting for external configuration (or press ESC to skip)...
+$wait_timeout"
+ countdown $wait_timeout & countdown_pid=$!
+ exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$!
+ echo $wait_pid > $pidfile
+ while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do
+ read -s -n 1 -t 2 key
+ case "$key" in
+ $'\e') echo -e "\b\b\b\b abort on user input"
+ break
+ ;;
+ *) ;;
+ esac
+ done
+ { kill $countdown_pid $wait_pid & wait $!; }
+ rm -f $pidfile
+fi
+
+
+#Reread /etc/sysconfig/network to inform puppet of changes
+. /etc/sysconfig/network
+hostname "$HOSTNAME"
+
+# XXX: ssh keys which should be included into the bootstrap image are
+# generated during containers deployment. However cobbler checkfs for
+# a kernel and initramfs when creating a profile, which poses chicken
+# and egg problem. Fortunately cobbler is pretty happy with empty files
+# so it's easy to break the loop.
+make_ubuntu_bootstrap_stub () {
+ local bootstrap_dir='/var/www/nailgun/bootstrap/ubuntu'
+ mkdir -p $bootstrap_dir
+ for item in linux initramfs.img; do
+ touch "$bootstrap_dir/$item"
+ done
+}
+
+get_bootstrap_flavor () {
+ local ASTUTE_YAML='/etc/fuel/astute.yaml'
+ python <<-EOF
+ from fuelmenu.fuelmenu import Settings
+ conf = Settings().read("$ASTUTE_YAML").get('BOOTSTRAP', {})
+ print(conf.get('flavor', 'centos'))
+ EOF
+}
+
+# Actually build the bootstrap image
+build_ubuntu_bootstrap () {
+ local ret=1
+ local max_attempts=3
+ local config='/etc/fuel-bootstrap-image.conf'
+ local log='/var/log/fuel-bootstrap-image-build.log'
+ if ! grep -qE '^BOOTSTRAP_SSH_KEYS' "$config"; then
+ # FIXME: config file generated by fuelmenu has no trailing newline
+ echo >> "$config"
+ cat >> "$config" <<-EOF
+ BOOTSTRAP_SSH_KEYS=/root/.ssh/id_rsa.pub
+ EOF
+ fi
+ for n in `seq 1 $max_attempts`; do
+ echo "Bulding bootstrap image, attempt $n" >&2
+ if fuel-bootstrap-image >>"$log" 2>&1; then
+ ret=0
+ fuel-bootstrap-image-set "ubuntu"
+ break
+ fi
+ done
+ if [ $ret -ne 0 ]; then
+ warning="WARNING: failed to build the bootstrap image, see $log for details.
+Perhaps your Internet connection is broken. Please fix the problem and run
+\`fuel-bootstrap-image-set ubuntu\`"
+ fuel notify --topic warning --send "$warning"
+ fi
+ return $ret
+}
+
+
+# Create empty files to make cobbler happy
+# (even if we don't use Ubuntu based bootstrap)
+make_ubuntu_bootstrap_stub
+
+service docker start
+
+if [ -f /root/.build_images ]; then
+ #Fail on all errors
+ set -e
+ trap fail EXIT
+
+ echo "Loading Fuel base image for Docker..."
+ docker load -i /var/www/nailgun/docker/images/fuel-images.tar
+
+ echo "Building Fuel Docker images..."
+ WORKDIR=$(mktemp -d /tmp/docker-buildXXX)
+ SOURCE=/var/www/nailgun/docker
+ REPO_CONT_ID=$(docker -D run -d -p 80 -v /var/www/nailgun:/var/www/nailgun fuel/centos sh -c 'mkdir /var/www/html/os;ln -sf /var/www/nailgun/centos/x86_64 /var/www/html/os/x86_64;/usr/sbin/apachectl -DFOREGROUND')
+ RANDOM_PORT=$(docker port $REPO_CONT_ID 80 | cut -d':' -f2)
+
+ for imagesource in /var/www/nailgun/docker/sources/*; do
+ if ! [ -f "$imagesource/Dockerfile" ]; then
+ echo "Skipping ${imagesource}..."
+ continue
+ fi
+ image=$(basename "$imagesource")
+ cp -R "$imagesource" $WORKDIR/$image
+ mkdir -p $WORKDIR/$image/etc
+ cp -R /etc/puppet /etc/fuel $WORKDIR/$image/etc
+ sed -e "s/_PORT_/${RANDOM_PORT}/" -i $WORKDIR/$image/Dockerfile
+ sed -e 's/production:.*/production: "docker-build"/' -i $WORKDIR/$image/etc/fuel/version.yaml
+ docker build -t fuel/${image}_${FUEL_RELEASE} $WORKDIR/$image
+ done
+ docker rm -f $REPO_CONT_ID
+ rm -rf "$WORKDIR"
+
+ #Remove trap for normal deployment
+ trap - EXIT
+ set +e
+else
+ echo "Loading docker images. (This may take a while)"
+ docker load -i /var/www/nailgun/docker/images/fuel-images.tar
+fi
+
+# apply puppet
+puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/host-only.pp
+if [ $? -ge 4 ];then
+ fail
+fi
+
+rmdir /var/log/remote && ln -s /var/log/docker-logs/remote /var/log/remote
+
+dockerctl check || fail
+bash /etc/rc.local
+
+if [ "`get_bootstrap_flavor`" = "ubuntu" ]; then
+ build_ubuntu_bootstrap || true
+fi
+
+# Enable updates repository
+cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-updates.repo << EOF
+[mos${FUEL_RELEASE}-updates]
+name=mos${FUEL_RELEASE}-updates
+baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/updates/x86_64/
+gpgcheck=0
+skip_if_unavailable=1
+EOF
+
+# Enable security repository
+cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-security.repo << EOF
+[mos${FUEL_RELEASE}-security]
+name=mos${FUEL_RELEASE}-security
+baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/security/x86_64/
+gpgcheck=0
+skip_if_unavailable=1
+EOF
+
+#Check if repo is accessible
+echo "Checking for access to updates repository..."
+repourl=$(grep baseurl /etc/yum.repos.d/*updates* 2>/dev/null | cut -d'=' -f2- | head -1)
+if urlaccesscheck check "$repourl" ; then
+ UPDATE_ISSUES=0
+else
+ UPDATE_ISSUES=1
+fi
+
+if [ $UPDATE_ISSUES -eq 1 ]; then
+ message="There is an issue connecting to the Fuel update repository. \
+Please fix your connection prior to applying any updates. \
+Once the connection is fixed, we recommend reviewing and applying \
+Maintenance Updates for this release of Mirantis OpenStack: \
+https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
+release-notes.html#maintenance-updates"
+ level="warning"
+else
+ message="We recommend reviewing and applying Maintenance Updates \
+for this release of Mirantis OpenStack: \
+https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\
+release-notes.html#maintenance-updates"
+ level="done"
+fi
+echo
+echo "*************************************************"
+echo -e "${message}"
+echo "*************************************************"
+echo "Sending notification to Fuel UI..."
+fuel notify --topic "${level}" --send "${message}"
+
+# TODO(kozhukalov) If building of bootstrap image fails
+# and if this image was supposed to be a default bootstrap image
+# we need to warn a user about this and give her
+# advice how to treat this.
+
+echo "Fuel node deployment complete!"
diff --git a/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh b/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh
new file mode 100755
index 000000000..7ac896589
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh
@@ -0,0 +1,4 @@
+#/bin/sh
+date
+echo "This is an example file run at post-bootstrap."
+exit 0
diff --git a/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh b/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh
new file mode 100755
index 000000000..427a55add
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh
@@ -0,0 +1,19 @@
+#/bin/sh
+echo "Installing pre-build repo"
+if [ ! -d /opt/opnfv/nailgun ]; then
+ echo "Error - found no repo!"
+ exit 1
+fi
+
+mkdir -p /var/www/nailgun
+mv /opt/opnfv/nailgun/* /var/www/nailgun
+if [ $? -ne 0 ]; then
+ echo "Error moving repos to their correct location!"
+ exit 1
+fi
+rmdir /opt/opnfv/nailgun
+if [ $? -ne 0 ]; then
+ echo "Error removing /opt/opnfv/nailgun directory!"
+ exit 1
+fi
+echo "Done installing pre-build repo"
diff --git a/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh b/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh
new file mode 100755
index 000000000..ac427bf87
--- /dev/null
+++ b/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh
@@ -0,0 +1,4 @@
+#/bin/sh
+date
+echo "This is an example file run at pre-bootstrap."
+exit 0