[ONOS-7054] Implement prototype of ISSU protocol

Change-Id: Id543c0de9c97b68f977c824cbc987b35d81beb2d
diff --git a/tools/dev/bash_profile b/tools/dev/bash_profile
index 3a3c3c6..991cfaf 100644
--- a/tools/dev/bash_profile
+++ b/tools/dev/bash_profile
@@ -174,6 +174,25 @@
     echo $OCI
 }
 
+# Sets minority (OCMI) and majority (OCMA) variables
+function setMinorityMajority {
+    nodes=($(env | grep 'OC[0-9]*=' | sort | cut -d= -f2))
+    middle=$(expr "${#nodes[@]}" / "2")
+    index=0
+    min=1
+    maj=1
+    for node in "${nodes[@]}"; do
+        if [ "$index" -gt "$middle" ]; then
+            export OCMI${min}=${node}
+            min=$(expr $min + 1)
+        else
+            export OCMA${maj}=${node}
+            maj=$(expr $maj + 1)
+        fi
+        index=$(expr $index + 1)
+    done
+}
+
 # ON.Lab shared test cell warden address
 export CELL_WARDEN="10.254.1.19"
 export CELL_SLAVES="$CELL_WARDEN 10.254.1.18 10.254.1.17"
@@ -184,6 +203,8 @@
     unset OCI OCN OCT ONOS_INSTANCES ONOS_FEATURES
     unset ONOS_USER ONOS_GROUP ONOS_WEB_USER ONOS_WEB_PASS
     unset $(env | sed -n 's:\(^OC[0-9]\{1,\}\)=.*:\1 :g p')
+    unset $(env | sed -n 's:\(^OCMI[0-9]\{1,\}\)=.*:\1 :g p')
+    unset $(env | sed -n 's:\(^OCMA[0-9]\{1,\}\)=.*:\1 :g p')
 }
 
 # Applies the settings in the specified cell file or lists current cell definition
@@ -204,6 +225,7 @@
         . $aux
         rm -f $aux
         setPrimaryInstance 1 >/dev/null
+        setMinorityMajority >/dev/null
         onos-verify-cell
         topo default >/dev/null
         ;;
diff --git a/tools/test/bin/onos-install b/tools/test/bin/onos-install
index cc00da0..65b7a42 100755
--- a/tools/test/bin/onos-install
+++ b/tools/test/bin/onos-install
@@ -36,7 +36,7 @@
 
 onos-check-bits
 
-while getopts fnm: o; do
+while getopts fnvm: o; do
     case "$o" in
         f) uninstall=true;;
         u) noupstart=true; noinitd=true; nosysd=true;;
@@ -44,6 +44,7 @@
         s) nosysd=true;;
         n) nostart=true;;
         m) mvn_settings=$OPTARG;;
+        v) upgrade=true;;
     esac
 done
 let OPC=$OPTIND-1
@@ -60,7 +61,7 @@
 [ ! -z "$mvn_settings" ] && scp -q $mvn_settings $remote:/tmp/settings.xml
 
 ssh -tt $remote "
-    [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1
+    [ -z "$upgrade" ] && [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1
 
     # Prepare a landing zone and unroll the bits
     sudo mkdir -p $ONOS_INSTALL_DIR && sudo chown ${ONOS_USER}:${ONOS_GROUP} $ONOS_INSTALL_DIR
@@ -81,6 +82,12 @@
     # Set up correct user to run onos-service
     echo 'export ONOS_USER=$ONOS_USER' >> $ONOS_INSTALL_DIR/options
 
+    # If the upgrade flag is set, append ".upgrade" to the version string.
+    if [ ! -z "$upgrade" ]
+    then
+        echo '.upgrade' >> $ONOS_INSTALL_DIR/VERSION
+    fi
+
     # Remove any previous ON.Lab bits from ~/.m2 repo.
     rm -fr ~/.m2/repository/org/onosproject
 
diff --git a/tools/test/scenarios/upgrade-rollback.xml b/tools/test/scenarios/upgrade-rollback.xml
new file mode 100644
index 0000000..4e58829
--- /dev/null
+++ b/tools/test/scenarios/upgrade-rollback.xml
@@ -0,0 +1,125 @@
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<scenario name="upgrade-rollback" description="ONOS cluster upgrade and rollback">
+    <group name="Upgrade-Rollback">
+        <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/>
+
+        <step name="Initialize-Upgrade"
+              exec="onos ${OC1} issu init"/>
+
+        <group name="Phase-1">
+            <sequential var="${OCMI#}"
+                        starts="Phase-One-Stop-Service-${#}"
+                        ends="Phase-One-Wait-for-Start-${#-1}">
+                <step name="Phase-One-Stop-Service-${#}"
+                      exec="onos-service ${OCMI#} stop"
+                      requires="Initialize-Upgrade"/>
+
+                <step name="Phase-One-Wait-for-Stop-${#}"
+                      exec="onos-wait-for-stop ${OCMI#}"
+                      requires="~Phase-One-Stop-Service-${#}"/>
+
+                <step name="Phase-One-Uninstall-${#}"
+                      exec="onos-uninstall ${OCMI#}"
+                      requires="~Phase-One-Wait-for-Stop-${#}"/>
+
+                <step name="Phase-One-Push-Bits-${#}"
+                      exec="onos-push-bits ${OCMI#}"
+                      unless="${OCT}"
+                      requires="~Phase-One-Stop-Service-${#}"/>
+
+                <step name="Phase-One-Install-Upgrade-${#}"
+                      exec="onos-install -v ${OCMI#}"
+                      requires="Phase-One-Push-Bits-${#},Push-Bits,Phase-One-Uninstall-${#}"/>
+
+                <step name="Phase-One-Secure-SSH-${#}"
+                      exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} ${OCMI#}"
+                      requires="~Phase-One-Install-Upgrade-${#}"/>
+
+                <step name="Phase-One-Wait-for-Start-${#}"
+                      exec="onos-wait-for-start ${OCMI#}"
+                      requires="Phase-One-Secure-SSH-${#}"/>
+            </sequential>
+        </group>
+
+        <step name="Run-Upgrade"
+              exec="onos ${OC1} issu upgrade"
+              requires="Phase-1"/>
+
+        <step name="Run-Rollback"
+              exec="onos ${OC1} issu rollback"
+              requires="Run-Upgrade"/>
+
+        <group name="Phase-2" requires="Run-Rollback">
+            <sequential var="${OCMI#}"
+                        starts="Phase-Two-Stop-Service-${#}"
+                        ends="Phase-Two-Wait-for-Start-${#-1}">
+                <step name="Phase-Two-Stop-Service-${#}"
+                      exec="onos-service ${OCMI#} stop"
+                      requires="Run-Rollback"/>
+
+                <step name="Phase-Two-Wait-for-Stop-${#}"
+                      exec="onos-wait-for-stop ${OCMI#}"
+                      requires="~Phase-Two-Stop-Service-${#}"/>
+
+                <step name="Phase-Two-Uninstall-${#}"
+                      exec="onos-uninstall ${OCMI#}"
+                      requires="~Phase-Two-Wait-for-Stop-${#}"/>
+
+                <step name="Phase-Two-Push-Bits-${#}"
+                      exec="onos-push-bits ${OCMI#}"
+                      unless="${OCT}"
+                      requires="~Phase-Two-Stop-Service-${#}"/>
+
+                <step name="Phase-Two-Install-Upgrade-${#}"
+                      exec="onos-install ${OCMI#}"
+                      requires="Phase-Two-Push-Bits-${#},Push-Bits,Phase-Two-Uninstall-${#}"/>
+
+                <step name="Phase-Two-Secure-SSH-${#}"
+                      exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} ${OCMI#}"
+                      requires="~Phase-Two-Install-Upgrade-${#}"/>
+
+                <step name="Phase-Two-Wait-for-Start-${#}"
+                      exec="onos-wait-for-start ${OCMI#}"
+                      requires="Phase-Two-Secure-SSH-${#}"/>
+            </sequential>
+        </group>
+
+        <step name="Reset-Upgrade"
+              exec="onos ${OC1} issu reset"
+              requires="Phase-2"/>
+
+        <group name="Verify-Rollback" requires="Reset-Upgrade">
+            <parallel var="${OC#}">
+                <step name="Check-Nodes-${#}"
+                      exec="onos-check-nodes ${OC#}"
+                      delay="3"
+                      requires="Reset-Upgrade"/>
+                <step name="Check-Components-${#}"
+                      exec="onos-check-components ${OC#}"
+                      delay="5"
+                      requires="~Check-Nodes-${#}"/>
+
+                <step name="Check-Logs-${#}"
+                      exec="onos-check-logs ${OC#}"
+                      requires="~Check-Components-${#}"/>
+                <step name="Check-Apps-${#}"
+                      exec="onos-check-apps ${OC#} ${ONOS_APPS} includes"
+                      requires="~Check-Components-${#}"/>
+            </parallel>
+        </group>
+    </group>
+</scenario>
\ No newline at end of file
diff --git a/tools/test/scenarios/upgrade.xml b/tools/test/scenarios/upgrade.xml
new file mode 100644
index 0000000..e675632
--- /dev/null
+++ b/tools/test/scenarios/upgrade.xml
@@ -0,0 +1,121 @@
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<scenario name="upgrade" description="ONOS cluster upgrade">
+    <group name="Upgrade">
+        <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/>
+
+        <step name="Initialize-Upgrade"
+              exec="onos ${OC1} issu init"/>
+
+        <group name="Phase-1">
+            <sequential var="${OCMI#}"
+                        starts="Phase-One-Stop-Service-${#}"
+                        ends="Phase-One-Wait-for-Start-${#-1}">
+                <step name="Phase-One-Stop-Service-${#}"
+                      exec="onos-service ${OCMI#} stop"
+                      requires="Initialize-Upgrade"/>
+
+                <step name="Phase-One-Wait-for-Stop-${#}"
+                      exec="onos-wait-for-stop ${OCMI#}"
+                      requires="~Phase-One-Stop-Service-${#}"/>
+
+                <step name="Phase-One-Uninstall-${#}"
+                      exec="onos-uninstall ${OCMI#}"
+                      requires="~Phase-One-Wait-for-Stop-${#}"/>
+
+                <step name="Phase-One-Push-Bits-${#}"
+                      exec="onos-push-bits ${OCMI#}"
+                      unless="${OCT}"
+                      requires="~Phase-One-Stop-Service-${#}"/>
+
+                <step name="Phase-One-Install-Upgrade-${#}"
+                      exec="onos-install -v ${OCMI#}"
+                      requires="Phase-One-Push-Bits-${#},Push-Bits,Phase-One-Uninstall-${#}"/>
+
+                <step name="Phase-One-Secure-SSH-${#}"
+                      exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} ${OCMI#}"
+                      requires="~Phase-One-Install-Upgrade-${#}"/>
+
+                <step name="Phase-One-Wait-for-Start-${#}"
+                      exec="onos-wait-for-start ${OCMI#}"
+                      requires="Phase-One-Secure-SSH-${#}"/>
+            </sequential>
+        </group>
+
+        <step name="Run-Upgrade"
+              exec="onos ${OC1} issu upgrade"
+              requires="Phase-1"/>
+
+        <group name="Phase-2" requires="Run-Upgrade">
+            <sequential var="${OCMA#}"
+                        starts="Phase-Two-Stop-Service-${#}"
+                        ends="Phase-Two-Wait-for-Start-${#-1}">
+                <step name="Phase-Two-Stop-Service-${#}"
+                      exec="onos-service ${OCMA#} stop"
+                      requires="Run-Upgrade"/>
+
+                <step name="Phase-Two-Wait-for-Stop-${#}"
+                      exec="onos-wait-for-stop ${OCMA#}"
+                      requires="~Phase-Two-Stop-Service-${#}"/>
+
+                <step name="Phase-Two-Uninstall-${#}"
+                      exec="onos-uninstall ${OCMA#}"
+                      requires="~Phase-Two-Wait-for-Stop-${#}"/>
+
+                <step name="Phase-Two-Push-Bits-${#}"
+                      exec="onos-push-bits ${OCMA#}"
+                      unless="${OCT}"
+                      requires="~Phase-Two-Stop-Service-${#}"/>
+
+                <step name="Phase-Two-Install-Upgrade-${#}"
+                      exec="onos-install -v ${OCMA#}"
+                      requires="Phase-Two-Push-Bits-${#},Push-Bits,Phase-Two-Uninstall-${#}"/>
+
+                <step name="Phase-Two-Secure-SSH-${#}"
+                      exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} ${OCMA#}"
+                      requires="~Phase-Two-Install-Upgrade-${#}"/>
+
+                <step name="Phase-Two-Wait-for-Start-${#}"
+                      exec="onos-wait-for-start ${OCMA#}"
+                      requires="Phase-Two-Secure-SSH-${#}"/>
+            </sequential>
+        </group>
+
+        <step name="Commit-Upgrade"
+              exec="onos ${OC1} issu commit"
+              requires="Phase-2"/>
+
+        <group name="Verify-Upgrade" requires="Commit-Upgrade">
+            <parallel var="${OC#}">
+                <step name="Check-Nodes-${#}"
+                      exec="onos-check-nodes ${OC#}"
+                      delay="3"
+                      requires="Commit-Upgrade"/>
+                <step name="Check-Components-${#}"
+                      exec="onos-check-components ${OC#}"
+                      delay="5"
+                      requires="~Check-Nodes-${#}"/>
+
+                <step name="Check-Logs-${#}"
+                      exec="onos-check-logs ${OC#}"
+                      requires="~Check-Components-${#}"/>
+                <step name="Check-Apps-${#}"
+                      exec="onos-check-apps ${OC#} ${ONOS_APPS} includes"
+                      requires="~Check-Components-${#}"/>
+            </parallel>
+        </group>
+    </group>
+</scenario>
\ No newline at end of file