Set exit on error by default. Make script idempotent.

Change-Id: I0d1e24f3f892afe045f324efcd8f0476908e87ec
diff --git a/de/heat-templates/scripts/instance_boot.sh b/de/heat-templates/scripts/instance_boot.sh
index dfeafab..b8689db 100644
--- a/de/heat-templates/scripts/instance_boot.sh
+++ b/de/heat-templates/scripts/instance_boot.sh
@@ -1,5 +1,6 @@
 #!/bin/bash
 set -x
+set -e
 # allow access to the local variables from prepare-metadata.py
 set -a
 
@@ -220,11 +221,13 @@
         local device_num=$1
         local device_size=$2
         local vg_name=$3
-
-        #configure lvm only on compute nodes
-        if [[ ${NODE_METADATA} == *"openstack-compute-node"* ]]; then
-            truncate --size ${device_size}G /srv/disk${device_num}
-            cat <<EOF > /etc/systemd/system/setup-loopback-loop${device_num}.service
+        if losetup -l | grep /dev/loop${device_num}; then
+        echo "Volume /dev/loop${device_num} is already initialize"
+        else
+            #configure lvm only on compute nodes
+            if [[ ${NODE_METADATA} == *"openstack-compute-node"* ]]; then
+                truncate --size ${device_size}G /srv/disk${device_num}
+                cat <<EOF > /etc/systemd/system/setup-loopback-loop${device_num}.service
 [Unit]
 Description=Setup loop${device_num} device
 DefaultDependencies=no
@@ -240,12 +243,13 @@
 [Install]
 WantedBy=local-fs.target
 EOF
-            systemctl enable setup-loopback-loop${device_num}
-            systemctl start setup-loopback-loop${device_num}
-            #adding short sleep to give time for service to start
-            sleep 3
-            pvcreate /dev/loop${device_num}
-            vgcreate ${vg_name} /dev/loop${device_num}
+                systemctl enable setup-loopback-loop${device_num}
+                systemctl start setup-loopback-loop${device_num}
+                #adding short sleep to give time for service to start
+                sleep 3
+                pvcreate /dev/loop${device_num}
+                vgcreate ${vg_name} /dev/loop${device_num}
+            fi
         fi
     }
 
@@ -309,19 +313,22 @@
 }
 
 function install_ucp {
-    local tmpd
-    tmpd=$(mktemp -d)
-    function docker_run_retry {
-        docker container run --rm --name ucp \
-        -v /var/run/docker.sock:/var/run/docker.sock \
-        ${DOCKER_UCP_IMAGE} install \
-        --host-address $UCP_IP_ADDRESS \
-        --admin-username $UCP_USERNAME \
-        --admin-password $UCP_PASSWORD \
-        --existing-config
-    }
-
-    retry 10 "Can't bring up docker UCP container" docker_run_retry
+    if docker ps --all | grep ucp-controller; then
+        echo "Docker UCP container is running"
+    else
+        local tmpd
+        tmpd=$(mktemp -d)
+        function docker_run_retry {
+            docker container run --rm --name ucp \
+            -v /var/run/docker.sock:/var/run/docker.sock \
+            ${DOCKER_UCP_IMAGE} install \
+            --host-address $UCP_IP_ADDRESS \
+            --admin-username $UCP_USERNAME \
+            --admin-password $UCP_PASSWORD \
+            --existing-config
+        }
+        retry 10 "Can't bring up docker UCP container" docker_run_retry
+    fi
 }
 
 function get_authtoken_retry {
@@ -365,18 +372,25 @@
 }
 
 function join_node {
-    local type=${1}
-    function retry_join_node {
-        env -i $(docker swarm join-token $type |grep 'docker swarm join' | xargs)
-    }
-    retry 10 "Failed to join node to swarm" retry_join_node
+    if kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes |grep -w Ready |awk '{print $1}' |grep -q $(hostname); then
+        echo "This node is already join"
+    else
+        local type=${1}
+        function retry_join_node {
+            env -i $(docker swarm join-token $type |grep 'docker swarm join' | xargs)
+        }
+        retry 10 "Failed to join node to swarm" retry_join_node
+    fi
 }
 
 function create_ucp_config {
     if [[ "${SINGLE_NODE}" == true ]]; then
         max_pods="kubelet_max_pods = 220"
     fi
-    echo "
+    if docker config ls | grep com.docker.ucp.config ; then
+        echo "Config com.docker.ucp.config already exists"
+    else
+        echo "
 [scheduling_configuration]
     enable_admin_ucp_scheduling = true
     default_node_orchestrator = \"kubernetes\"
@@ -384,10 +398,15 @@
     dns = [\"172.18.208.44\"]
     ${max_pods}
 " | docker config create com.docker.ucp.config -
+    fi
 }
 
 function swarm_init {
-    docker swarm init --advertise-addr ${UCP_IP_ADDRESS} --data-path-addr ${UCP_IP_ADDRESS} --listen-addr ${UCP_IP_ADDRESS} --data-path-port ${UCP_DOCKER_SWARM_DATA_PORT}
+    if docker node ls | grep $HOSTNAME; then
+        echo "This node is already part of a swarm"
+    else
+        docker swarm init --advertise-addr ${UCP_IP_ADDRESS} --data-path-addr ${UCP_IP_ADDRESS} --listen-addr ${UCP_IP_ADDRESS} --data-path-port ${UCP_DOCKER_SWARM_DATA_PORT}
+    fi
 }
 
 function rm_ucp_config {
@@ -454,16 +473,19 @@
 }
 
 function workaround_default_forward_policy {
-    cat << EOF > /etc/iptables/rules.v4
+    if grep "DOCKER-USER" /etc/iptables/rules.v4; then
+        echo "Iptables is already configurations"
+    else
+        cat << EOF > /etc/iptables/rules.v4
 *filter
 :DOCKER-USER - [0:0]
 EOF
-    for net in $FLOATING_NETWORK_PREFIXES; do
+        for net in $FLOATING_NETWORK_PREFIXES; do
 cat << EOF >> /etc/iptables/rules.v4
 -A DOCKER-USER -d ${net} -j ACCEPT
 -A DOCKER-USER -s ${net} -j ACCEPT
 EOF
-    done
+        done
 
 cat << EOF >> /etc/iptables/rules.v4
 -A DOCKER-USER -j RETURN
@@ -475,16 +497,17 @@
 *nat
 :POSTROUTING ACCEPT - [0:0]
 EOF
-    for net in $FLOATING_NETWORK_PREFIXES; do
+        for net in $FLOATING_NETWORK_PREFIXES; do
 cat << EOF >> /etc/iptables/rules.v4
 -A POSTROUTING -s ${net} -o ${DEFAULT_INTERFACE} -j MASQUERADE
 EOF
-    done
+        done
 
 cat << EOF >> /etc/iptables/rules.v4
 COMMIT
 EOF
-    sudo netfilter-persistent reload
+        sudo netfilter-persistent reload
+    fi
 }
 
 function disable_rp_filter {