[VOL-3603][SEBA-1000]: Support OLT image upgrade
- patchset on ONL source code (applied when ONL built in inband mode)
- scripts to support image upgrade procedure
- README to test the procedure.
- increased BAL READY TIME before enabling inband channel on BAL.

Change-Id: I069fc1309dd13d504af03552c1709a6b3ba42232
diff --git a/olt-sw-upgrade/README.md b/olt-sw-upgrade/README.md
new file mode 100644
index 0000000..36a340e
--- /dev/null
+++ b/olt-sw-upgrade/README.md
@@ -0,0 +1,120 @@
+# ONL Image Upgrade Procedure
+# Introduction:
+After the NOS(Network Operating System) is booted into the active partition, the images on the standby partition can be
+updated using the same NOS installer. In this case,
+• The installer searches if ‘active’ and ‘standby’ partitions already exists, and if they exists
+• Upgrades the NOS in the standby partition
+• Copies the selected configuration files from the active NOS file system to the standby file
+system
+• Updates the GRUB to boot one time to the standby partition, through the ‘grub-reboot
+<menu-entry> command’
+
+Once the standby NOS boots, it can change (swap) the partition labels and setup the GRUB again to boot the new active partition by default. Before it does this, it must check if the system has booted correctly by verifying several resources and their states. Few of the checks it can perform are
+• Check if all of the devices ( network, storage, peripherals etc ) are visible in the NOS
+• Check if all of the deamons have started
+• Check that the service ports if any are available for access
+• Check if the forwarding plane is initialized and setup up accordingly
+
+Following are the other modified files in OpenNetworkLinux source code and brief info:
+
+1.  builds/any/rootfs/jessie/common/overlay/etc/mtab.yml and builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml
+
+These configuration files are used to create the partitions, permissions for the partitions(read or write), mount path, directory. In these files we create labels for portioning.
+
+2.  packages/base/all/initrds/loader-initrd-files/src/bin/swiprep
+
+The function of this file is to extract the root file system from the “SWITCH IMAGE(.swi)” file.
+
+Note: The switch image file will be available in ‘/mnt/onl/images’ path if OLT is booted from Active Partition. The image will be available in ‘/mnt/onl/images/upgrade’ path if OLT is booted from Standby Partition.
+
+Changes: Based on current boot partition, the extracted RFS is copied to either ‘ACTIVE DATA/STANDBY DATA’ partition.
+
+3.  packages/base/any/kernels/3.7/configs/x86_64-all/x86_64-all.config: enabled CONFIG_VLAN_8021Q module
+
+4.  ¬packages/base/all/initrds/loader-initrd-files/src/bin/sysinit: copies boot config file.
+
+5.  packages/base/all/initrds/loader-initrd-files/src/bootmodes/installed: this file is used to get the root file system path
+
+    a. /mnt/onl/active_data – if system is booted from active mode
+
+    b. /mnt/onl/standby_data – if system is booted from standby mode
+
+6.  packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml: it is a configuration file
+
+7.  packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml: this is an uboot configuration file and has following list of configurations
+
+    a. size of the partitions in GB or MB
+
+8.  packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml: this is x86 platform configuration file and it has following configurations
+
+    a. size of the partitions in GB or MB
+
+9.  packages/base/all/vendor-config-onl/src/python/onl/bootconfig/**init**.py: this is an ONL boot config file. the modification in this is : The label name ‘ONL-BOOT’ is changed as ‘ONL-ACTIVE-BOOT’.
+
+10.  packages/base/all/vendor-config-onl/src/python/onl/grub/**init**.py: this is ONL grub config file changed from ‘ONL-BOOT’ to ‘ONL-ACTIVE-BOOT’.
+
+11.  packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py: This is the main core file where important modifications are done. The modifications are
+
+    a. partitioning – active and standby
+
+    b. grub configuration changes – ‘ONL-BOOT’ to ‘ONL-ACTIVE-BOOT’
+
+    c. mount paths from ONL-DATA to ‘ONL-ACTIVE-DATA’ and ‘ONL-STANDBY-DATA’
+
+12.  packages/base/all/vendor-config-onl/src/python/onl/install/ShellApp.py: only mount paths got changed from ONL-BOOT to ONL-ACTIVE-BOOT.
+
+13.  packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py: only ONL-BOOT label is changed to ONL-ACTIVE-BOOT
+
+14.  tools/switool.py: This script, iterates through “bal_packages” directory and adds the files to SWITCH image file.
+
+# Upgrade procedure
+Note:
+1. OLT image upgrade patch set on OpenNetworkLinux source code applied when ONL built in inband mode)
+2. To upgrade OLT image, OLT must have ONL installed with active and standby partitions on it.
+
+## Prepare for the upgrade: 
+Files included in image upgrade test are: 
+**install_onl.sh**  - Used as part of upgrade process. ONL  image is passed as an argument to the file.
+
+**change_label.sh** - This file change the block Id label once upgrade is successful and is integrated into ONL swi image.
+
+Pre-requisites:
+ Component |Specification  |
+|----------|---------------|
+|Ansible  |2.7.12 and above|
+
+ 1 . Have a OLT minicom session for the upgrade process since OLT reboots while upgrade.
+
+ Check the OLT IP before upgrade  in below file
+
+      ```shell
+	vi $HOME/openolt/olt-sw-upgrade/test/ansible/inventory/hosts
+	[device-olt]
+	192.168.50.100 ansible_ssh_user=root ansible_ssh_pass=onl ansible_sudo_pass=onl ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
+
+If required change  the OLT IP 192.168.50.100
+
+2 . Upgrade procedure is executed using ansible playbook here.
+a. Execute all commands in sudo mode
+```
+sudo su
+cd $HOME/openolt/agent
+``` 
+b.  Build an ONL image used for upgrade as shown below
+```shell
+make OPENOLTDEVICE=asfvolt16 clean
+make OPENOLTDEVICE=asfvolt16 INBAND=y VLAN_ID=<INBAND_VLAN>
+e.g:
+make OPENOLTDEVICE=asfvolt16 INBAND=y VLAN_ID=5
+```
+If no VLAN_ID is specified in above command it defaults to 4093.
+
+c. The below command prepare the ansible environment to start upgrade process.
+```
+make ansible
+```
+## Start the Upgrade:
+```shell
+$cd $HOME/openolt/olt-sw-upgrade/test/ansible
+$sudo ansible-playbook -i inventory/hosts upgrade_olt.yml
+```
diff --git a/olt-sw-upgrade/change_labels.sh b/olt-sw-upgrade/change_labels.sh
new file mode 100755
index 0000000..65b8d6f
--- /dev/null
+++ b/olt-sw-upgrade/change_labels.sh
@@ -0,0 +1,613 @@
+#!/bin/bash
+
+#Copyright 2020-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.
+#
+
+### BEGIN INIT INFO
+# Description:
+#                   This script swaps the block id labels if expected services 
+#                   like system services onlp, sshd, bal_core_dist, dhclient, physical
+#                   ,vlan interfaces status and olt services dev_mgmt_daemon, openolt services
+#                   are UP and RUNNING. If all services are not UP and RUNNING, then roll back 
+#                   to previous state.
+### END INIT INFO
+
+# Labels names
+ONL_ACTIVE_BOOT="ONL-ACTIVE-BOOT"
+ONL_ACTIVE_DATA="ONL-ACTIVE-DATA"
+ONL_STANDBY_BOOT="ONL-STANDBY-BOOT"
+ONL_STANDBY_DATA="ONL-STANDBY-DATA"
+
+RUNNING_ROOT_DEV=
+RUNNING_ROOT_LABEL=
+RUNNING_BOOT_LABEL=
+RUNNING_BOOT_DEV=
+
+STANDBY_BOOT_DEV=
+STANDBY_BOOT_LABEL=
+STANDBY_ROOT_LABEL=
+STANDBY_ROOT_DEV=
+
+# Configuration file about upgrade
+ONL_ROOT="/mnt/onl"
+IMAGES="${ONL_ROOT}/images"
+UPGRADE_PATH="${IMAGES}/upgrade"
+ACTIVE_GRUB_ENV_FILE="${ONL_ROOT}/active_boot/grub/grubenv"
+STANDBY_GRUB_ENV_FILE="${ONL_ROOT}/standby_boot/grub/grubenv"
+GRUB_STAND_PATH="${ONL_ROOT}/standby_boot/grub"
+GRUB_ACTIVE_PATH="${ONL_ROOT}/active_boot/grub"
+STANDBY_GRUB_ACTIVE_PATH="${ONL_ROOT}/standby_boot/grub"
+GRUB_CFG="grub.cfg"
+GRUB_CFG_BACKUP="grub.cfg.back"
+GRUB_CONFIG_FILE="${ONL_ROOT}/config/grub.cfg"
+# Time interval in seconds
+TIME_INTERVAL=5
+
+#in band interface IP
+ASFVOLT16_ETH2_VLAN_INF_IP=
+
+ASGVOLT64_ETH1_VLAN_INF_IP=
+
+ETH3_VLAN_IP=
+
+BRCM_DIR='/broadcom'
+
+# vlan config file
+VLAN_CONFIG_FILE="${BRCM_DIR}/inband.config"
+
+# vlan id for asfvolt16
+ASFVOLT16_VLAN_ID_ETH2=
+
+#vlan id for asgvolt64
+ASGVOLT64_VLAN_ID_ETH1=
+
+OLT_MODEL=$(cat /sys/devices/virtual/dmi/id/board_name)
+ASXvOLT16="ASXvOLT16"
+ASGvOLT64="ASGvOLT64"
+
+VLAN_ID_1=
+VLAN_ID_2=
+
+# interfaces
+ETH1=eth1
+ETH2=eth2
+
+#------------------------------------------------------------------------------
+# Function Name: does_logger_exist
+# Description:
+#    This function check if logger exist and executable.
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    returns 0 if exist and executable else 1
+#------------------------------------------------------------------------------
+does_logger_exist()
+{
+cmd=/usr/bin/logger
+if [ -x ${cmd} ]; then
+     return 0
+   else
+     return 1
+   fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name: info_message
+# Description:
+#    This function print the info message information to the console
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    string message
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+info_message()
+{
+    echo "INFO: $1"
+    logger -p user.info "$1"
+}
+
+#------------------------------------------------------------------------------
+# Function Name: error_message
+# Description:
+#    This function print the error message information to the console
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    string message
+#
+# Returns:
+#    returns 1
+#------------------------------------------------------------------------------
+error_message()
+{
+    echo "ERROR: $1"
+    logger -p user.err "$1"
+    return 1
+}
+
+
+#------------------------------------------------------------------------------
+# Function Name: error_message
+# Description:
+#    This function print the error message information to the console
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    string message
+#
+# Returns:
+#    returns 1
+#------------------------------------------------------------------------------
+display_services()
+{
+    echo "Sanity result: 
+          Service Name       - Status
+          --------------------------------------
+          1. eth2                     - UP & RUNNING
+          2. eth1                     - UP & RUNNING
+          3. bal_service              - RUNNING
+          4. system services          - RUNNING"
+
+    if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+       echo "
+          5. eth2.${ASFVOLT16_VLAN_ID_ETH2}        - UP & RUNNING
+          6. eth2.${ASFVOLT16_VLAN_ID_ETH2} IP     - ${ASFVOLT16_ETH2_VLAN_INF_IP}"
+    elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+       echo"
+          5. eth1.${ASGVOLT64_VLAN_ID_ETH1}        - UP & RUNNING
+          6. eth1.${ASGVOLT64_VLAN_ID_ETH1} IP     - ${ASGVOLT64_ETH1_VLAN_INF_IP}"
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name: is_interface_up_running
+# Description:
+#    This function validate the interface whether it is UP and RUNNING or DOWN.
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    interface name
+#
+# Returns:
+#    returns 0 if interface is up and running and returns 1 if interface is down
+#------------------------------------------------------------------------------
+is_interface_up_running()
+{
+    info_message "Validating interface - $1"
+    interface_name=$1
+    ifconfig ${interface_name} | grep -q "UP BROADCAST RUNNING MULTICAST"
+    if [ $? -eq 0 ]; then
+        info_message "${interface_name} UP & RUNNING"
+        echo "---------------------------------------------------------------------"
+        return 0
+    else
+        error_message "${interface_name} is DOWN"
+        echo "---------------------------------------------------------------------"
+        return 1
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name: validate_ip
+# Description:
+#    This function get the ip from the interface and validates it.
+#
+# Globals:
+#    OLT_MODEL, ASXvOLT16, ASGvOLT64, ASFVOLT16_VLAN_ID_ETH2,
+#     ASFVOLT16_VLAN_ID_ETH2, ASGVOLT64_VLAN_ID_ETH1
+#
+#
+# Arguments:
+#    interface name
+#
+# Returns:
+#    ip address
+#------------------------------------------------------------------------------
+validate_ip()
+{
+    interface_name=$1
+    ip_address=$(ifconfig $interface_name | grep "inet addr" | awk  'BEGIN {FS =":"} {print $2}' | awk '{print $1}')
+
+    if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+        if [ ! -z $ip_address ] && [ $interface_name = ${ETH2}.${ASFVOLT16_VLAN_ID_ETH2} ]; then
+           ASFVOLT16_ETH2_VLAN_INF_IP=$ip_address
+        fi
+    elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+        if [ ! -z $ip_address ] && [ $interface_name = ${ETH1}.${ASGVOLT64_VLAN_ID_ETH1} ]; then
+           ASGVOLT64_ETH1_VLAN_INF_IP=$ip_address
+        fi
+    fi
+
+    info_message "Validating $1 ip address - $ip_address"
+    if expr "$ip_address" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
+        for i in 1 2 3 4; do
+            if [ $(echo "$ip_address" | cut -d. -f$i) -gt 255 ]; then
+                return 1
+            fi
+        done
+        return 0
+    else
+        return 1
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name : validate_interfaces
+# Description:
+#    This function validate interfaces ${ETH2}.${ASFVOLT16_VLAN_ID_ETH2} and
+#    or ${ETH1}.${ASGVOLT64_VLAN_ID_ETH1} and based on OLT model.
+#    Basically it validates if these interfaces are UP and RUNNING or not
+#
+# Globals:
+#    ASFVOLT16_VLAN_ID_ETH2, ASGVOLT64_VLAN_ID_ETH1,
+#    ETH1, ETH2, ASFVOLT16_BAL_PACKAGE
+#
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    return 1 if interface are down else returns 0
+#------------------------------------------------------------------------------
+validate_interfaces()
+{
+    # Validating interfaces whether they are UP and RUNNING or not
+    if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+        is_interface_up_running ${ETH2}.${ASFVOLT16_VLAN_ID_ETH2}
+        if [ $? -eq 0 ]; then
+            return 0
+        else
+            return 1
+        fi
+    elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+       is_interface_up_running ${ETH1}.${ASGVOLT64_VLAN_ID_ETH1}
+       if [ $? -eq 0 ]; then
+           return 0
+       else
+           return 1
+       fi
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name: validate_vlan_intf_ip
+# Description:
+#    This function validate the inband vlan interfaces ip, checks if DHCP server has
+#    assigned proper IP addresses.
+#
+#
+# Globals:
+#    ASFVOLT16_VLAN_ID_ETH2,  ASGVOLT64_VLAN_ID_ETH1,
+#    ETH1, ETH2, OLT_MODEL, ASXvOLT16 and ASGvOLT64
+#
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    returns 0 if ip adresses are valid else return 1
+#------------------------------------------------------------------------------
+validate_vlan_intf_ip()
+{
+    # Validating vlan interfaces and their IP
+    if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+        validate_ip ${ETH2}.${ASFVOLT16_VLAN_ID_ETH2}
+        if [ $? -eq 0 ]; then
+           return 0
+        else
+           return 1
+        fi
+    elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+        validate_ip ${ETH1}.${ASGVOLT64_VLAN_ID_ETH1}
+        if [ $? -eq 0 ]; then
+           return 0
+        else
+           return 1
+        fi
+
+    fi
+    return 0
+}
+
+#------------------------------------------------------------------------------
+# Function Name: validate_system_services
+# Description:
+#    This function checks if the below services/processes are running or not.
+#    1. dev_mgmt_daemon
+#    2. openolt
+#    3. onlp
+#    4. sshd
+#    5. dhclient
+# Globals:
+#    None
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    returns 0
+#------------------------------------------------------------------------------
+validate_system_services()
+{
+    echo "---------------------------------------------------------------------"
+    echo "Validating Services"
+    echo "---------------------------------------------------------------------"
+
+    dhclient_interface dhclient_val1 dhclient_val2
+    for service_name in dev_mgmt_daemon openolt onlp sshd ${dhclient_val1} ${dhclient_val2}
+    do
+        echo "---------------------------------------------------------------------"
+        ps -ef | grep -v grep | grep ${service_name}
+        if [ $? -eq 0 ]; then
+          info_message "${service_name} service is running"
+        else
+          error_message "${service_name} is not running"
+          return 1
+        fi
+        echo "---------------------------------------------------------------------"
+    done
+    return 0
+}
+
+#------------------------------------------------------------------------------
+# Function Name: dhclient_interface
+# Description:
+#    This function sets values to which tagged interface dhclient service need
+#    to be tested based on the OLT model package.
+#
+# Globals:
+#    OLT_MODEL, ASFVOLT16_VLAN_ID_ETH2,
+#    ASGVOLT64_VLAN_ID_ETH1, ETH1, ETH2,
+#    ASGvOLT64, ASXvOLT16.
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+dhclient_interface()
+{
+    local value1=$1
+    local value2=$2
+    if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+       dhclient1=dhclient.${ETH2}.${ASFVOLT16_VLAN_ID_ETH2}
+       eval $value1="'$dhclient1'"
+    elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+       dhclient3=dhclient.${ETH1}.${ASGVOLT64_VLAN_ID_ETH1}
+       eval $value1="'$dhclient3'"
+    fi
+
+}
+
+#------------------------------------------------------------------------------
+# Function Name: check_services
+# Description:
+#    This function check the expected services, like system services for ex:
+#    onlp, sshd, bal_core_dist, dhclient and physical and vlan interfaces status.
+#
+# Globals:
+#   VLAN_CONFIG_FILE, ASFVOLT16_VLAN_ID_ETH2, ASGVOLT64_VLAN_ID_ETH1
+#   TIME_INTERVAL, OLT_MODEL, ASXvOLT16, ASGvOLT64
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+check_services()
+{
+    # Let bal services are up and running
+    waiting_time=0
+    while true; do
+        sleep ${TIME_INTERVAL}
+        if [ $waiting_time -eq 70 ]; then
+            break
+        fi
+        waiting_time=$((waiting_time+${TIME_INTERVAL}))
+    done
+
+    if [ -f ${VLAN_CONFIG_FILE} ]; then
+        ASFVOLT16_VLAN_ID_ETH2=$(awk '/asfvolt16_vlan_id_eth2/{print $0}' \
+        ${VLAN_CONFIG_FILE} | awk -F "=" '{print $2}')
+        ASGVOLT64_VLAN_ID_ETH1=$(awk '/asgvolt64_vlan_id_eth1/{print $0}' \
+        ${VLAN_CONFIG_FILE} | awk -F "=" '{print $2}')
+        if [ "${OLT_MODEL}" = ${ASXvOLT16} ];then
+            if [ ${ASFVOLT16_VLAN_ID_ETH2} -gt 4094 ] || [ ${ASFVOLT16_VLAN_ID_ETH2} -lt 1 ]; then
+                error_message "vlan ids not in range"
+                exit 1
+            fi
+        elif [ "${OLT_MODEL}" = ${ASGvOLT64} ];then
+            if [ ${ASGVOLT64_VLAN_ID_ETH1} -gt 4094 ] || [ ${ASGVOLT64_VLAN_ID_ETH1} -lt 1 ]; then
+                error_message "vlan ids not in range"
+                exit 1
+           fi
+       fi
+    else
+        error_message "${VLAN_CONFIG_FILE} does not exist"
+        exit 1
+    fi
+
+    info_message "Sanity check"
+    for func_name in validate_interfaces validate_vlan_intf_ip validate_system_services
+    do
+        counter=0
+        while true; do
+            sleep ${TIME_INTERVAL}
+            $func_name
+            if [ $? -eq 0 ]; then
+                break
+            fi
+            if [ $counter -eq 100 ]; then
+                error_message "Time out ,all services are not up"
+                return 1
+            fi
+            counter=$((counter+${TIME_INTERVAL}))
+        done
+    done
+    display_services
+    return 0
+}
+
+#------------------------------------------------------------------------------
+# Function Name: change_labels
+# Description:
+#    This function does the following functions
+#             1) After the upgrade procedure installs the image in stand_by_partition,
+#                This function checks for the system services after upgrade,
+#                if all ther services are up and running then following steps takes place
+#                a) It changes the device labels from Active to Standby and
+#                Standby to Active.
+#                b) It sets the grub menu entry from 1 to 0 which is default
+#                grub entry. After reboot in the grub menu entry will 
+#                have one entry.
+#                c) It will swap the upgrade image to Image directory and vice
+#                versa.
+#             2) If system services fails to start after image upgrade,
+#                roll-back to previous state of OLT i.e
+#                boot the OLT back from the active partition.
+#
+# Globals:
+#    RUNNING_BOOT_DEV, STANDBY_BOOT_LABEL, RUNNING_ROOT_DEV, STANDBY_ROOT_LABEL
+#    STANDBY_BOOT_DEV, RUNNING_BOOT_LABEL, STANDBY_ROOT_DEV, RUNNING_ROOT_LABEL
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+change_labels()
+{
+    grep "data-standby" /proc/cmdline > /dev/null
+    if [ $? -eq 0 ]; then
+        check_services
+        # if the OLT system services fail to start, fall back to previous state
+        if [ $? -eq 1 ]; then
+            reboot -f
+        fi
+        # Change running boot device label to standby boot label
+        e2label $RUNNING_BOOT_DEV $STANDBY_BOOT_LABEL
+        # Change running root device label to standby root label
+        e2label $RUNNING_ROOT_DEV $STANDBY_ROOT_LABEL
+        # Change standby boot device label to active boot label
+        e2label $STANDBY_BOOT_DEV $RUNNING_BOOT_LABEL
+        # Change standby root device label to active root label
+        e2label $STANDBY_ROOT_DEV $RUNNING_ROOT_LABEL
+        partprobe
+
+        if [ -f ${ACTIVE_GRUB_ENV_FILE} ]; then
+            next_entry=$(grub-editenv  ${ACTIVE_GRUB_ENV_FILE} list | sed -n 's/^next_entry=//p')
+            saved_entry=$(grub-editenv  ${ACTIVE_GRUB_ENV_FILE} list | sed -n 's/^saved_entry=//p')
+            if [ ${next_entry} -eq 1 ] || [ ${saved_entry} -eq 1 ]; then
+                grub-editenv ${ACTIVE_GRUB_ENV_FILE} set next_entry=0
+                grub-editenv ${ACTIVE_GRUB_ENV_FILE} set saved_entry=0
+            fi
+        fi
+
+        if [ -f ${STANDBY_GRUB_ENV_FILE} ]; then
+            next_entry=$(grub-editenv  ${STANDBY_GRUB_ENV_FILE} list | sed -n 's/^next_entry=//p')
+            saved_entry=$(grub-editenv  ${STANDBY_GRUB_ENV_FILE} list | sed -n 's/^saved_entry=//p')
+            if [ ${next_entry} -eq 1 ] || [ ${saved_entry} -eq 1 ]; then
+                grub-editenv ${STANDBY_GRUB_ENV_FILE} set next_entry=0
+                grub-editenv ${STANDBY_GRUB_ENV_FILE} set saved_entry=0
+            fi
+        fi
+
+        if [ -f ${GRUB_CONFIG_FILE} ]; then
+            if [ -f "${GRUB_ACTIVE_PATH}/${GRUB_CFG}" ]; then
+                cp ${GRUB_CONFIG_FILE}  ${GRUB_ACTIVE_PATH}/${GRUB_CFG}
+            fi
+            if [ -f "${GRUB_STAND_PATH}/${GRUB_CFG}" ]; then
+                cp ${GRUB_CONFIG_FILE} ${GRUB_STAND_PATH}/${GRUB_CFG}
+            fi
+        fi
+
+        if [ -d ${UPGRADE_PATH} ]; then
+            cd ${UPGRADE_PATH}
+            upgrade_image=$(ls *.swi)
+            mv $upgrade_image "$upgrade_image.bak"
+            cd ${IMAGES}
+            active_image=$(ls *.swi)
+            mv $active_image "$active_image.bak"
+            mv ${UPGRADE_PATH}/"$upgrade_image.bak" ${IMAGES}/$upgrade_image
+            mv ${IMAGES}/"$active_image.bak" ${UPGRADE_PATH}/$active_image
+        fi
+    fi
+
+}
+
+#------------------------------------------------------------------------------
+# Function Name: get_labels
+# Description:
+#    This function get the labels of the devices and also find out the 
+#    Running and Standby devices.
+#
+# Globals:
+#    RUNNING_ROOT_DEV, RUNNING_ROOT_LABEL, RUNNING_BOOT_LABEL, STANDBY_BOOT_LABEL
+#    RUNNING_ROOT_LABEL, STANDBY_ROOT_LABEL
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+get_labels()
+{
+    RUNNING_ROOT_DEV=$(cat /proc/mounts | grep  " \/ ext4" | awk '{print $1}')
+    RUNNING_ROOT_LABEL=$(blkid | grep ${RUNNING_ROOT_DEV} | awk '{print $2}' | cut -c 7- | tr -d \")
+    if [ ${RUNNING_ROOT_LABEL} = "ONL-ACTIVE-DATA" ]; then
+        RUNNING_BOOT_LABEL=${ONL_ACTIVE_BOOT}
+        STANDBY_BOOT_LABEL=${ONL_STANDBY_BOOT}
+        RUNNING_ROOT_LABEL=${ONL_ACTIVE_DATA}
+        STANDBY_ROOT_LABEL=${ONL_STANDBY_DATA}
+    else
+        RUNNING_BOOT_LABEL=${ONL_STANDBY_BOOT}
+        RUNNING_ROOT_LABEL=${ONL_STANDBY_DATA}
+        STANDBY_BOOT_LABEL=${ONL_ACTIVE_BOOT}
+        STANDBY_ROOT_LABEL=${ONL_ACTIVE_DATA}
+    fi
+    STANDBY_ROOT_DEV=$(blkid | grep " LABEL=\"$STANDBY_ROOT_LABEL\"" | awk '{print $1}' | tr -d :)
+    RUNNING_BOOT_DEV=$(blkid | grep " LABEL=\"$RUNNING_BOOT_LABEL\"" | awk '{print $1}' | tr -d :)
+    STANDBY_BOOT_DEV=$(blkid | grep " LABEL=\"$STANDBY_BOOT_LABEL\"" | awk '{print $1}' | tr -d :)
+}
+
+# Starts from here
+does_logger_exist
+if [ $? -eq 0 ]; then
+   get_labels
+   change_labels
+else
+   error_message "logger does not exist"
+   exit 1
+fi
diff --git a/olt-sw-upgrade/install_onl.sh b/olt-sw-upgrade/install_onl.sh
new file mode 100755
index 0000000..69d9863
--- /dev/null
+++ b/olt-sw-upgrade/install_onl.sh
@@ -0,0 +1,554 @@
+#!/bin/bash
+
+#Copyright 2020-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.
+
+### BEGIN INIT INFO
+# Description:
+#             Upgrade the NOS from Active to Standby partition, 
+#             This script checks if installed ONL on OLT has active and standby partions
+#             if yes, it extracts the ONL package and keep the
+#             required files to the Standby partition and start the NOS from Standby partition.
+#
+### END INIT INFO
+
+
+WORKING_DIR=$(pwd)
+# Name of the script
+SCRIPT_NAME="$(basename ${0})"
+UPGRADE=
+ONL_FILE=${1}
+ONL_ROOT="/mnt/onl"
+ACTIVE_BOOTDIR="${ONL_ROOT}/active_boot/"
+STANDBY_BOOTDIR="${ONL_ROOT}/standby_boot/"
+
+# Partition labels
+ONL_ACTIVE_BOOT="ONL-ACTIVE-BOOT"
+ONL_ACTIVE_DATA="ONL-ACTIVE-DATA"
+ONL_STANDBY_BOOT="ONL-STANDBY-BOOT"
+ONL_STANDBY_DATA="ONL-STANDBY-DATA"
+ONL_CONFIG="ONL-CONFIG"
+ONL_IMAGES="ONL-IMAGES"
+
+# Mount paths
+CONFIG="${ONL_ROOT}/config"
+IMAGES="${ONL_ROOT}/images"
+ACTIVE_DATA="${ONL_ROOT}/active_data"
+ACTIVE_BOOT="${ONL_ROOT}/active_boot"
+STANDBY_DATA="${ONL_ROOT}/standby_data"
+STANDBY_BOOT="${ONL_ROOT}/standby_boot"
+GRUB="grub"
+ONL_SOURCE="onl_source"
+
+ACTIVE_DATA_DEV_NAME=
+ACTIVE_DATA_MNT_PATH=
+ACTIVE_BOOT_DEV_NAME=
+ACTIVE_BOOT_MNT_PATH=
+STANDBY_DATA_DEV_NAME=
+STANDBY_DATA_MNT_PATH=
+STANDBY_BOOT_DEV_NAME=
+STANDBY_BOOT_MNT_PATH=
+
+# Configuration file about upgrade
+IMAGES="${ONL_ROOT}/images"
+ACTIVE_GRUB_ENV_FILE="${ONL_ROOT}/active_boot/grub/grubenv"
+STANDBY_GRUB_ENV_FILE="${ONL_ROOT}/active_boot/grub/grubenv"
+GRUB_CONFIG_FILE="${ONL_ROOT}/config/grub.cfg"
+GRUB_CONFIG_FILE_CHANGED="${ONL_ROOT}/config/grub.cfg.changed"
+ASF_VOLT16_VOLTHA_BAL=$(ls /*asfvolt16*.tar.gz 2>/dev/null)
+BROADCOM="/broadcom"
+OPT="/opt/bcm68620"
+DEV_MGMT_DAEMON="dev_mgmt_daemon -d -pcie"
+OPENOLT="openolt"
+#------------------------------------------------------------------------------
+# Function : usage
+#
+# Description: 
+#    This function says how to use the script
+#                                                                               
+# Globals:                                                                 
+#    SCRIPT_NAME
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                 
+#    None        
+#------------------------------------------------------------------------------
+
+usage()
+{
+    echo "${SCRIPT_NAME}:usage:
+        ${SCRIPT_NAME} <ONL_IMAGE_WITH_ABSOLUTE_PATH>
+    "
+    exit 1
+}
+
+#------------------------------------------------------------------------------
+# Function Name: does_logger_exist
+# Description:
+#    This function check if logger exist and executable.
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    None
+#
+# Returns:
+#    returns 0 if exist and executable else 1
+#------------------------------------------------------------------------------
+does_logger_exist()
+{
+cmd=/usr/bin/logger
+if [ -x ${cmd} ]; then
+     return 0
+   else
+     return 1
+   fi
+}
+
+#------------------------------------------------------------------------------
+# Function Name: info_message
+# Description:
+#    This function print the info message information to the console
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    string message
+#
+# Returns:
+#    None
+#------------------------------------------------------------------------------
+info_message()
+{
+    echo "INFO: $1"
+    logger -p user.info "$1"
+}
+
+#------------------------------------------------------------------------------
+# Function Name: error_message
+# Description:
+#    This function print the error message information to the console
+#
+# Globals:
+#    None
+#
+# Arguments:
+#    string message
+#
+# Returns:
+#    returns 1
+#------------------------------------------------------------------------------
+error_message()
+{
+    echo "ERROR: $1"
+    logger -p user.err "$1"
+    return 1
+}
+
+#------------------------------------------------------------------------------
+# Function: clean_up 
+#
+# Description: 
+#    This function delete the existing image in the standby boot partition. 
+#    In order to copy the the new image. also delete the onl source in the 
+#    working directory if it is there.
+#
+# Globals:                                                                 
+#    WORKING_DIR, ONL_SOURCE, STANDBY_BOOT_MNT_PATH, ACTIVE_DATA_MNT_PATh
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                 
+#    None        
+#------------------------------------------------------------------------------
+clean_up()
+{
+     info_message "Deleting onl source"
+     rm -rf ${WORKING_DIR}/${ONL_SOURCE}
+     info_message "Deleting kernel and initrd files"
+     rm -rf ${STANDBY_BOOT_MNT_PATH}/kernel-*
+     rm -rf ${STANDBY_BOOT_MNT_PATH}/x86-64-accton-*
+     echo "INFO: Deleting configuration files"
+     rm -rf /etc/onl/*
+     rm -rf /lib/vendor-config/
+     info_message "Deleting standby rootfs"
+     rm -rf ${STANDBY_DATA_MNT_PATH}/*
+}
+
+#------------------------------------------------------------------------------
+# Function: update_grub_cfg_for_temp_reboot
+#
+# Description: 
+#    This function updates the grub.cfg file in order to achieve the temporary 
+#    reboot. by making standby entry in the temporary reboot. once temporary 
+#    reboot happens successfully grub.cfg file will have only active entry.
+#                                                                               
+# Globals:                                                                 
+#    GRUB_CONFIG_FILE_CHANGED, ACTIVE_KERNEL_NAME, STANDBY_KERNEL_NAME
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                 
+#    None        
+#------------------------------------------------------------------------------
+update_grub_cfg_for_temp_reboot()
+{
+     cat > ${GRUB_CONFIG_FILE_CHANGED} <<- EOF
+serial --port=0x3f8 --speed=115200 --word=8 --parity=no --stop=1
+terminal_input serial
+terminal_output serial
+set timeout=5
+
+# Always boot the saved_entry value
+load_env
+if [ \$saved_entry ] ; then
+   set default=\$saved_entry
+fi
+
+menuentry "Open Network Linux" {
+  search --no-floppy --label --set=root ONL-ACTIVE-BOOT
+  # Always return to this entry by default.
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading Open Network Linux ...'
+  insmod gzio
+  insmod part_msdos
+  linux /${ACTIVE_KERNEL_NAME} nopat console=ttyS0,115200n8 tg3.short_preamble=1 tg3.bcm5718s_reset=1 intel_iommu=off onl_platform=x86-64-accton-asxvolt16-r0 data-active
+  initrd /x86-64-accton-asxvolt16-r0.cpio.gz
+}
+
+menuentry "Open Network Linux Standby" {
+  search --no-floppy --label --set=root ONL-STANDBY-BOOT
+  # Always return to this entry by default.
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading Open Network Linux Standby...'
+  insmod gzio
+  insmod part_msdos
+  linux /${STANDBY_KERNEL_NAME} nopat console=ttyS0,115200n8 tg3.short_preamble=1 tg3.bcm5718s_reset=1 intel_iommu=off onl_platform=x86-64-accton-asxvolt16-r0 data-standby
+  initrd /x86-64-accton-asxvolt16-r0.cpio.gz
+}
+
+# Menu entry to chainload ONIE
+menuentry ONIE {
+  search --no-floppy --label --set=root ONIE-BOOT
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading ONIE ...'
+  chainloader +1
+}
+
+
+EOF
+}
+
+#------------------------------------------------------------------------------
+# Function: revert_grub_cfg 
+#
+# Description: 
+#    This function revert the original grub.cfg file which was affected
+#    by temporary reboot.
+#                                                                               
+# Globals:                                                                 
+#    GRUB_CONFIG_FILE, ACTIVE_KERNEL_NAME
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                 
+#    None        
+#------------------------------------------------------------------------------
+revert_grub_cfg()
+{
+     cat > ${GRUB_CONFIG_FILE}  <<- EOF
+serial --port=0x3f8 --speed=115200 --word=8 --parity=no --stop=1
+terminal_input serial
+terminal_output serial
+set timeout=5
+
+# Always boot the saved_entry value
+load_env
+if [ \$saved_entry ] ; then
+   set default=\$saved_entry
+fi
+
+menuentry "Open Network Linux" {
+  search --no-floppy --label --set=root ONL-ACTIVE-BOOT
+  # Always return to this entry by default.
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading Open Network Linux ...'
+  insmod gzio
+  insmod part_msdos
+  linux /${ACTIVE_KERNEL_NAME} nopat console=ttyS0,115200n8 tg3.short_preamble=1 tg3.bcm5718s_reset=1 intel_iommu=off onl_platform=x86-64-accton-asxvolt16-r0 data-active
+  initrd /x86-64-accton-asxvolt16-r0.cpio.gz
+}
+
+menuentry "Open Network Linux Standby" {
+  search --no-floppy --label --set=root ONL-STANDBY-BOOT
+  # Always return to this entry by default.
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading Open Network Linux Standby...'
+  insmod gzio
+  insmod part_msdos
+  linux /${STANDBY_KERNEL_NAME} nopat console=ttyS0,115200n8 tg3.short_preamble=1 tg3.bcm5718s_reset=1 intel_iommu=off onl_platform=x86-64-accton-asxvolt16-r0 data-standby
+  initrd /x86-64-accton-asxvolt16-r0.cpio.gz
+}
+
+# Menu entry to chainload ONIE
+menuentry ONIE {
+  search --no-floppy --label --set=root ONIE-BOOT
+  set saved_entry="0"
+  save_env saved_entry
+  echo 'Loading ONIE ...'
+  chainloader +1
+}
+
+EOF
+}
+#------------------------------------------------------------------------------
+# Function: grub_reboot 
+#
+# Description: 
+#    This function gives a temporary reboot using grub-reboot command, this will 
+#    set the boot menu entry from active default one to Standby. Now OS will 
+#    boot up in Standby mode.
+#                                                                               
+# Globals:
+#    ACTIVE_BOOTDIR, STANDBY_BOOTDIR, GRUB_CONFIG_FILE_CHANGED, ACTIVE_BOOT
+#    GRUB
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                
+#    None        
+#------------------------------------------------------------------------------
+grub_reboot()
+{
+    if [ -f "${ACTIVE_BOOTDIR}/grub/grubenv" ]; then
+        saved_entry=$(grub-editenv  ${ACTIVE_BOOTDIR}/grub/grubenv list | sed -n 's/^saved_entry=//p')
+        if [ ${saved_entry} -eq 0 ]; then
+            grub-editenv ${ACTIVE_BOOTDIR}/grub/grubenv set saved_entry=1
+            sed  -i '/next_entry=/a\prev_saved_entry=1' ${ACTIVE_BOOTDIR}/grub/grubenv
+        fi
+    fi
+
+    if [ -f "${STANDBY_BOOTDIR}/grub/grubenv" ]; then
+        saved_entry=$(grub-editenv  ${STANDBY_BOOTDIR}/grub/grubenv list | sed -n 's/^saved_entry=//p')
+        if [ ${saved_entry} -eq 0 ]; then
+            grub-editenv ${STANDBY_BOOTDIR}/grub/grubenv set saved_entry=1
+            sed  -i '/next_entry=/a\prev_saved_entry=1' ${STANDBY_BOOTDIR}/grub/grubenv
+        fi
+    fi
+
+    if [ -f ${GRUB_CONFIG_FILE_CHANGED} ]; then
+        if [ -f "${ACTIVE_BOOT}/${GRUB}/grub.cfg" ]; then
+            cp ${GRUB_CONFIG_FILE_CHANGED} ${ACTIVE_BOOT}/${GRUB}/grub.cfg
+        fi
+        if [ -f "${STANDBY_BOOT}/${GRUB}/grub.cfg" ]; then
+            cp ${GRUB_CONFIG_FILE_CHANGED} ${STANDBY_BOOT}/${GRUB}/grub.cfg
+        fi
+    fi
+    grub-reboot --boot-directory=${ACTIVE_BOOTDIR} 1
+    reboot
+}
+
+#------------------------------------------------------------------------------
+# Function: install_onl
+#
+# Description: 
+#    This function copy the upgrade image.
+#
+# Globals:
+#    WORKING_DIR, ONL_SOURCE, STANDBY_BOOT_MNT_PATH, IMAGES, ACTIVE_BOOT_MNT_PATH 
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                
+#    None        
+#------------------------------------------------------------------------------
+install_onl()
+{
+    if [ -f ${ONL_FILE} ]; then
+        clean_up
+        mkdir ${WORKING_DIR}/${ONL_SOURCE}
+        cd ${WORKING_DIR}/${ONL_SOURCE}
+        chmod 777 ${ONL_FILE}
+        # Extract onl package
+        unzip ${ONL_FILE}
+        # Copy kernel files to standby boot partition
+        cp kernel-* ${STANDBY_BOOT_MNT_PATH}/
+        # Copy initrd file to standby boot partition
+        cp onl-loader-initrd-amd64.cpio.gz ${STANDBY_BOOT_MNT_PATH}/x86-64-accton-asxvolt16-r0.cpio.gz
+        # Create upgrade directory in the images partition to copy upgrade image
+        if [ -d ${IMAGES}/upgrade ]; then
+            rm -rf ${IMAGES}/upgrade
+        fi
+        info_message "Creating Upgrade Directory"
+        mkdir ${IMAGES}/upgrade
+        info_message "Copying SWI file to Upgrade Directory"
+        cp *.swi ${IMAGES}/upgrade
+
+        # Update the kernel version
+        STANDBY_KERNEL_NAME=$(ls ${STANDBY_BOOT_MNT_PATH} | grep kernel-4.14)
+        ACTIVE_KERNEL_NAME=$(ls ${ACTIVE_BOOT_MNT_PATH} | grep kernel-4.14 )
+        update_grub_cfg_for_temp_reboot
+        revert_grub_cfg
+    else
+        error_message "ONL file not found"
+        exit 1
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function: upgrade_onl 
+#
+# Description: 
+#    This function get the labels, and install the upgrade NOS.
+#
+# Globals       :
+#    ACTIVE_DATA_DEV_NAME, ACTIVE_BOOT_DEV_NAME, ACTIVE_BOOT_MNT_PATH, 
+#    STANDBY_DATA_DEV_NAME, STANDBY_BOOT_MNT_PATH 
+#                                                                               
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                
+#    None        
+#------------------------------------------------------------------------------
+upgrade_onl()
+{
+
+    ACTIVE_DATA_DEV_NAME=$(blkid | grep " LABEL=\"ONL-ACTIVE-DATA\"" | awk '{print $1}' | sed 's/://')
+    echo "active data dev - $ACTIVE_DATA_DEV_NAME"
+    ACTIVE_DATA_MNT_PATH=$(mount | grep $ACTIVE_DATA_DEV_NAME | awk '{print $3}')
+    echo $"active data mnt - $ACTIVE_DATA_MNT_PATH"
+    ACTIVE_BOOT_DEV_NAME=$(blkid | grep " LABEL=\"ONL-ACTIVE-BOOT\"" | awk '{print $1}' | sed 's/://')
+    echo "active boot dev $ACTIVE_BOOT_DEV_NAME"
+    ACTIVE_BOOT_MNT_PATH=$(mount | grep $ACTIVE_BOOT_DEV_NAME | awk '{print $3}')
+    echo "active boot mnt - $ACTIVE_BOOT_MNT_PATH"
+    STANDBY_DATA_DEV_NAME=$(blkid | grep " LABEL=\"ONL-STANDBY-DATA\"" | awk '{print $1}' | sed 's/://')
+    echo "standby data dev - $STANDBY_DATA_DEV_NAME"
+    STANDBY_DATA_MNT_PATH=$(mount | grep $STANDBY_DATA_DEV_NAME | awk '{print $3}')
+    echo "standby data mnt - $STANDBY_DATA_MNT_PATH"
+    STANDBY_BOOT_DEV_NAME=$(blkid | grep " LABEL=\"ONL-STANDBY-BOOT\"" | awk '{print $1}' | sed 's/://')
+    echo "standby boot dev - $STANDBY_BOOT_DEV_NAME"
+    STANDBY_BOOT_MNT_PATH=$(mount | grep $STANDBY_BOOT_DEV_NAME | awk '{print $3}')
+    echo "standby boot mnt -$STANDBY_BOOT_MNT_PATH"
+
+    install_onl
+    grub_reboot
+}
+
+#------------------------------------------------------------------------------
+# Function: command_result 
+#
+# Description: 
+#    This function executes the blkid command.
+#
+# Globals:
+#    None
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                
+#    None        
+#------------------------------------------------------------------------------
+command_result(){
+    blkid | grep $1 > /dev/null
+    if [ $? -eq 0 ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function: is_onl_running 
+#
+# Description: 
+#    This function check the running NOS and  also check the Upgrade is required 
+#    or not.
+#
+# Globals:
+#    ONL_ACTIVE_BOOT, ONL_ACTIVE_DATA, ONL_STANDBY_BOOT, ONL_STANDBY_DATA
+#    ONL_CONFIG, ONL_IMAGES, IMAGES, ACTIVE_DATA, ACTIVE_BOOT, STANDBY_DATA
+#    STANDBY_BOOT
+#
+# Arguments:                                                                 
+#    None                                                                       
+#                                                                               
+# Returns:                                                                
+#    None        
+#------------------------------------------------------------------------------
+is_onl_running()
+{
+    info_message "Check all directories exist or not"
+    if command_result "$ONL_ACTIVE_BOOT" && command_result "$ONL_ACTIVE_DATA" && command_result "$ONL_STANDBY_BOOT" && command_result "$ONL_STANDBY_DATA" && command_result "$ONL_CONFIG" && command_result "$ONL_IMAGES" ; then
+        if [ \( -d "$CONFIG" -a -d "$IMAGES" \) -a \( -d "$ACTIVE_DATA" -a -d "$ACTIVE_BOOT" \) -a \( -d "$STANDBY_DATA" -a -d "$STANDBY_BOOT" \) ]; then 
+            info_message "All directories exist. Need Upgrade"
+            UPGRADE=1
+        fi
+    else
+        info_message "It is new installation"
+        UPGRADE=0
+    fi
+}
+
+#------------------------------------------------------------------------------
+# Function: main 
+#
+# Description: 
+#    This is the main function. which decides fresh installation is required or 
+#    upgrade is required.
+#
+# Globals       :
+#    UPGRADE, ONL_FILE
+# Arguments     :                                                                 
+#    None                                                                       
+#                                                                               
+# Returns       :                                                                
+#    None        
+#------------------------------------------------------------------------------
+main()
+{
+    echo "INFO: Check if image upgrade or new installation"
+    is_onl_running
+    if [ $UPGRADE -eq 0 ]; then
+        error_message "ONL does not have active and stand by partitions \
+        install ONL image with active and standby partitions"
+        exit 1    
+    else
+        info_message "Upgrade started"
+        upgrade_onl
+    fi
+}
+
+# main function call
+does_logger_exist
+if [ $? -eq 0 ]; then
+    main
+else
+   error_message "logger does not exist"
+   exit 1
+fi
diff --git a/olt-sw-upgrade/test/ansible/inventory/hosts b/olt-sw-upgrade/test/ansible/inventory/hosts
new file mode 100644
index 0000000..ffe62eb
--- /dev/null
+++ b/olt-sw-upgrade/test/ansible/inventory/hosts
@@ -0,0 +1,2 @@
+[device-olt]
+192.168.50.150 ansible_ssh_user=root ansible_ssh_pass=onl ansible_sudo_pass=onl ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
diff --git a/olt-sw-upgrade/test/ansible/roles/upgrade/tasks/main.yml b/olt-sw-upgrade/test/ansible/roles/upgrade/tasks/main.yml
new file mode 100644
index 0000000..42bb2ae
--- /dev/null
+++ b/olt-sw-upgrade/test/ansible/roles/upgrade/tasks/main.yml
@@ -0,0 +1,38 @@
+# Copyright (c) 2020 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.
+
+### BEGIN INIT INFO
+# Description:
+#                    This script executes the main list of tasks,
+#                    1. Copies install_onl.sh, an utility file for upgrade procedure to /tmp directory.
+#                    2. Copied ONL image to /tmp directory.
+#                    3. Upgrade OLT tasks is executed which executes install_onl.sh file on OLT by taking ONL
+#                       image as an argument.
+### END INIT INFO
+
+
+---
+# Copy install_onl.sh script amd ONL image files to /root  and provide executable permission
+  - name: copying install_onl.sh file to /tmp
+    copy: src='/etc/ansible/roles/upgrade/files/install_onl.sh' dest='/tmp' mode=0777
+
+  - name: copying ONL image  to /tmp
+    copy: src='/etc/ansible/roles/upgrade/files/ONL_INSTALLED_INSTALLER' dest='/tmp' mode=0777
+ 
+# Updgrade OLT
+  - name: Upgrade OLT ...
+    command: sh /tmp/install_onl.sh  /tmp/ONL_INSTALLED_INSTALLER
+    register: verify_upgrade
+    failed_when: verify_upgrade.rc != 0
+
diff --git a/olt-sw-upgrade/test/ansible/upgrade_olt.yml b/olt-sw-upgrade/test/ansible/upgrade_olt.yml
new file mode 100644
index 0000000..80f5dca
--- /dev/null
+++ b/olt-sw-upgrade/test/ansible/upgrade_olt.yml
@@ -0,0 +1,23 @@
+# Copyright (c) 2020 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.
+
+### BEGIN INIT INFO
+# Description:
+#            This is a ansible-playbook defines the role for a given hosts.
+### END INIT INFO
+---
+   - hosts: device-olt
+     roles:
+       - upgrade
+