[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/agent/Makefile.in b/agent/Makefile.in
index 0b864ae..ad4c641 100644
--- a/agent/Makefile.in
+++ b/agent/Makefile.in
@@ -239,7 +239,9 @@
 ##        openolt
 ##
 ##
+OLT_SW_UPGRADE_DIR = ../olt-sw-upgrade
 SRCS = $(wildcard src/*.cc) $(wildcard common/*.cc) $(wildcard device/$(OPENOLTDEVICE)/*.cc)
+ANSIBLE_DIR = /etc/ansible
 OBJS = $(SRCS:.cc=.o)
 DEPS = $(SRCS:.cc=.d)
 .DEFAULT_GOAL := all
@@ -302,11 +304,21 @@
 	cp $(TOP_DIR)/inband/scripts/* $(ONL_DIR)/OpenNetworkLinux/bal_packages
 	cp $(TOP_DIR)/inband/config/inband.config $(ONL_DIR)/OpenNetworkLinux/bal_packages
 	cp $(BUILD_DIR)/openolt_$(OPENOLTDEVICE)-$(VERSION)-$(LABEL_VCS_REF).deb $(ONL_DIR)/OpenNetworkLinux/bal_packages/openolt_$(OPENOLTDEVICE).deb
+	cp $(OLT_SW_UPGRADE_DIR)/change_labels.sh $(ONL_DIR)/OpenNetworkLinux/bal_packages
 
 	# Rebuild ONL packed with already built BAL+Openolt debian package
 	make -C $(ONL_DIR) onl-$(ONL_KERN_VER_MAJOR) INBAND=y
 	echo "inband=y" > $(ONL_DIR)/onl_build.mode
 	make inband-onl-cleanup
+# requires 'sudo' privileges
+
+ansible:
+	(ONL_INSTALLED_INSTALLER="$(shell find "$$(cd ./build/onl/OpenNetworkLinux/RELEASE/jessie/amd64; pwd)" -name "ONL-onl-*_AMD64_INSTALLED_INSTALLER")"; \
+	rm -rf $(ANSIBLE_DIR)/roles/upgrade/files; \
+	mkdir -p $(ANSIBLE_DIR)/roles/upgrade/files; \
+	cp ../olt-sw-upgrade/install_onl.sh $(ANSIBLE_DIR)/roles/upgrade/files; \
+	chmod +x $(ANSIBLE_DIR)/roles/upgrade/files/*.sh; \
+	ln -s $$ONL_INSTALLED_INSTALLER $(ANSIBLE_DIR)/roles/upgrade/files/ONL_INSTALLED_INSTALLER)
 
 src/%.o: %.cpp
 	$(CXX) -MMD -c $< -o $@
@@ -347,4 +359,4 @@
 distclean: clean-src clean
 	@rm -rf $(BUILD_DIR)
 
-.PHONY: onl sdk bal protos inband-onl .FORCE
+.PHONY: onl sdk bal protos inband-onl ansible .FORCE
diff --git a/agent/inband/config/inband.config b/agent/inband/config/inband.config
index 6dddb0b..7e24691 100644
--- a/agent/inband/config/inband.config
+++ b/agent/inband/config/inband.config
@@ -18,4 +18,4 @@
 enable_out_of_band_connection=no
 
 # wait time before configuring in-band on BAL
-wait_time_bal_ready=45
+wait_time_bal_ready=120
diff --git a/agent/inband/patch/inband-72b95a7.patch b/agent/inband/patch/inband-72b95a7.patch
index 341ab48..1d69e28 100644
--- a/agent/inband/patch/inband-72b95a7.patch
+++ b/agent/inband/patch/inband-72b95a7.patch
@@ -10,11 +10,114 @@
 +- python3-yaml
 +- cron
 +- logrotate
+diff --git a/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml b/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml
+index e04f366..81ef69a 100644
+--- a/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml
++++ b/builds/any/rootfs/jessie/common/overlay/etc/mtab.yml
+@@ -1,21 +1,30 @@
+ mounts:
+   ONL-IMAGES:
+-    mount: ro
++    mount: rw
+     dir: /mnt/onl/images
+     fsck: true
+ 
+-  ONL-DATA:
++  ONL-ACTIVE-DATA:
++    mount: rw
++    dir: /mnt/onl/active_data
++
++  ONL-STANDBY-DATA:
+     mount: rw
+-    dir: /mnt/onl/data
++    dir: /mnt/onl/standby_data
+ 
+   ONL-CONFIG:
+-    mount: ro
++    mount: rw
+     dir: /mnt/onl/config
+     fsck: true
+ 
+-  ONL-BOOT:
+-    mount: ro
+-    dir: /mnt/onl/boot
++  ONL-ACTIVE-BOOT:
++    mount: rw
++    dir: /mnt/onl/active_boot
++    fsck: false
++
++  ONL-STANDBY-BOOT:
++    mount: rw
++    dir: /mnt/onl/standby_boot
+     fsck: false
+ 
+   # ESP (EFI system partition)
+diff --git a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml
+index 598e4c6..744baf3 100644
+--- a/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml
++++ b/builds/any/rootfs/wheezy/common/overlay/etc/mtab.yml
+@@ -1,19 +1,28 @@
+ mounts:
+   ONL-IMAGES:
+-    mount: ro
++    mount: rw
+     dir: /mnt/onl/images
+     fsck: true
+ 
+-  ONL-DATA:
++  ONL-ACTIVE-DATA:
++    mount: rw
++    dir: /mnt/onl/active_data
++
++  ONL-STANDBY-DATA:
+     mount: rw
+-    dir: /mnt/onl/data
++    dir: /mnt/onl/standby_data
+ 
+   ONL-CONFIG:
+-    mount: ro
++    mount: rw
+     dir: /mnt/onl/config
+     fsck: true
+ 
+-  ONL-BOOT:
+-    mount: ro
+-    dir: /mnt/onl/boot
++  ONL-ACTIVE-BOOT:
++    mount: rw
++    dir: /mnt/onl/active_boot
++    fsck: false
++
++  ONL-STANDBY-BOOT:
++    mount: rw
++    dir: /mnt/onl/standby_boot
+     fsck: false
+diff --git a/packages/base/all/boot.d/src/53.install-debs b/packages/base/all/boot.d/src/53.install-debs
+index e31d382..cf72eb3 100755
+--- a/packages/base/all/boot.d/src/53.install-debs
++++ b/packages/base/all/boot.d/src/53.install-debs
+@@ -1,6 +1,15 @@
+ #!/bin/sh
+ ############################################################
+-PACKAGE_DIR=/mnt/onl/data/install-debs
++ROOTFS_PATH=
++CMD_LINE_FILE="/proc/cmdline"
++if [ -f ${CMD_LINE_FILE} ]; then
++   if grep -q "data-active" ${CMD_LINE_FILE}; then
++       ROOTFS_PATH="active_data"
++   else
++       ROOTFS_PATH="standby_data"
++   fi
++fi
++PACKAGE_DIR=/mnt/onl/${ROOTFS_PATH}/install-debs
+ PACKAGE_LIST="$PACKAGE_DIR/list"
+ 
+ if [ -e "$PACKAGE_LIST" ]; then
 diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep
 index d5a72f8e..0b0583e1 100755
 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep
 +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep
-@@ -173,7 +173,46 @@ if test "$mode_install"; then
+@@ -173,7 +173,49 @@ if test "$mode_install"; then
      echo "*** invalid squashfs contents" 1>&2
      exit 1
    fi
@@ -35,6 +138,7 @@
 +  echo "INFO: Copying init scripts to init.d"
 +  cp  "$workdir"/start_inband_oltservices.sh "$destdir"/etc/init.d/
 +  cp "$workdir"/inband.config "$destdir"/
++  cp "$workdir"/change_labels.sh "$destdir"/etc/init.d/
 +  cd -
  fi
 +cat > "$destdir"/etc/rc.local  <<- EOF
@@ -53,7 +157,9 @@
 +
 +chmod 0777 /etc/init.d/start_inband_oltservices.sh
 +chmod 0777 /root/validate_onl_installation.sh
++chmod 0777 /etc/init.d/change_labels.sh
 +nohup sh /etc/init.d/start_inband_oltservices.sh >> /var/log/startup.log &
++sh /etc/init.d/change_labels.sh >> /var/log/olt_upgrage_changelabels.log
 +exit 0
 +
 +EOF
@@ -61,8 +167,650 @@
  if test "$mode_overlay"; then
    # keep the squashfs file around
    mv $workdir/rootfs.sqsh /tmp/.rootfs
+diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit b/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit
+index 6529c75..cc9892d 100755
+--- a/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit
++++ b/packages/base/all/initrds/loader-initrd-files/src/bin/sysinit
+@@ -90,13 +90,14 @@ if [ ! -f /etc/onl/abort ]; then
+         cat /etc/issue
+     fi
+ 
+-    if [ -f /mnt/onl/boot/boot-config ]; then
++    if [ -f /mnt/onl/active_boot/boot-config ]; then
+         # Use local boot-config.
+-        cp /mnt/onl/boot/boot-config /etc/onl/boot-config
++        cp /mnt/onl/active_boot/boot-config /etc/onl/boot-config
+     elif [ -f /etc/onl/boot-config-default ]; then
+         # Use default boot-config.
+         cp /etc/onl/boot-config-default /etc/onl/boot-config
+-        cp /etc/onl/boot-config-default /mnt/onl/boot/boot-config
++        cp /etc/onl/boot-config-default /mnt/onl/active_boot/boot-config
++
+     fi
+ fi
+ 
+diff --git a/packages/base/all/initrds/loader-initrd-files/src/bootmodes/installed b/packages/base/all/initrds/loader-initrd-files/src/bootmodes/installed
+index dc0e887..b068acb 100755
+--- a/packages/base/all/initrds/loader-initrd-files/src/bootmodes/installed
++++ b/packages/base/all/initrds/loader-initrd-files/src/bootmodes/installed
+@@ -8,17 +8,44 @@
+ . /lib/msgs
+ . /etc/onl/BOOTPARAMS
+ 
+-# make sure /mnt/onl/data exists
+-if [ ! -d /mnt/onl/data ]; then
+-    msg_error "Missing /mnt/onl/data, disk boot cannot continue"
++ONL_ROOT="/mnt/onl"
++IMAGES_PATH="${ONL_ROOT}/images"
++ACTIVE_DATA="${ONL_ROOT}/active_data"
++STANDBY_DATA="${ONL_ROOT}/standby_data"
++UPGRADE_IMAGE_PATH="${IMAGES_PATH}/upgrade"
++FILE="${ONL_ROOT}/config/upgrade_config"
++
++# Default root file system path
++ROOTFS_PATH=${ACTIVE_DATA}
++DATA_NAME="active_data"
++# Default switch image file
++SWI_FILE=$(ls ${IMAGES_PATH}/*.swi)
++
++# Get the image based on the boot
++grep -q "data-active" /proc/cmdline
++if [ $? -ne 0 ]; then
++    ROOTFS_PATH=${STANDBY_DATA}
++    DATA_NAME="standby_data"
++    # for temporary reboot on standby mode
++    if [ -d ${UPGRADE_IMAGE_PATH} ]; then
++        SWI_FILE=$(ls ${UPGRADE_IMAGE_PATH}/*.swi)
++    else
++        echo "ERROR: No Swi found for upgrade"
++        exit 1
++    fi
++fi
++
++# make sure /mnt/onl/active_data exists
++if [ ! -d ${ROOTFS_PATH} ]; then
++    msg_error "Missing ${ROOTFS_PATH}, disk boot cannot continue"
+     exit 200
+ fi
+ 
+ # make sure it's mounted as per mtab.yml
+ d1=$(stat -f -c '%b' /mnt/onl)
+-d2=$(stat -f -c '%b' /mnt/onl/data)
++d2=$(stat -f -c '%d' ${ROOTFS_PATH})
+ if [ "$d1" -eq "$d2" ]; then
+-    msg_error "Unmounted /mnt/onl/data, disk boot cannot continue"
++    msg_error "Unmounted ${ROOTFS_PATH}, disk boot cannot continue"
+     exit 200
+ fi
+ 
+@@ -37,8 +64,8 @@ case "$SWI" in
+     ""|dir:*|nfs://*/)
+         msg_info "*** missing SWI file, will attempt to boot existing image"
+ 
+-        if [ ! -s /mnt/onl/data/etc/onl/SWI ]; then
+-            msg_error "Un-populated /mnt/onl/data, cannot continue"
++        if [ ! -s ${ROOTFS_PATH}/etc/onl/SWI ]; then
++            msg_error "Un-populated ${ROOTFS_PATH}, cannot continue"
+             exit 200
+         fi
+ 
+@@ -50,11 +77,11 @@ case "$SWI" in
+         TMPDIR=$swiget_workdir swipath=$(swiget $SWI)
+ 
+         # do some sort of test to see if it's populated
+-        if [ ! -s /mnt/onl/data/etc/onl/SWI ]; then
+-            msg_info "Un-populated /mnt/onl/data, will (re-)image"
++        if [ ! -s ${ROOTFS_PATH}/etc/onl/SWI ]; then
++            msg_info "Un-populated ${ROOTFS_PATH}, will (re-)image"
+             do_unpack=1
+         else
+-            msg_info "Found valid (current) image at /mnt/onl/data"
++            msg_info "Found valid (current) image at ${ROOTFS_PATH}"
+         fi
+         ;;
+ esac
+@@ -69,12 +96,13 @@ case "$SWI" in
+ esac
+ 
+ sed -i -e '/^SWI=/d' /etc/onl/BOOTPARAMS
+-echo "SWI=dir:data:/" >> /etc/onl/BOOTPARAMS
++echo "SWI=dir:$DATA_NAME:/" >> /etc/onl/BOOTPARAMS
+ 
+ if [ "$do_unpack" ]; then
+-    swiprep --install "$swipath" --swiref "$swistamp" /mnt/onl/data
++    swipath=$SWI_FILE
++    swiprep --install "$swipath" --swiref "$swistamp" "$ROOTFS_PATH"
+ fi
+-swiprep --record "$swipath" --swiref "$swistamp" /mnt/onl/data
++swiprep --record "$swipath" --swiref "$swistamp" "$ROOTFS_PATH"
+ 
+ trap - 0 1
+ do_cleanup
+diff --git a/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml b/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml
+index 051105c..c5f4c35 100644
+--- a/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml
++++ b/packages/base/all/initrds/loader-initrd-files/src/etc/mtab.yml
+@@ -4,19 +4,29 @@ mounts:
+     dir: /mnt/onl/images
+     fsck: true
+ 
+-  ONL-DATA:
++  ONL-ACTIVE-DATA:
+     mount: rw
+-    dir: /mnt/onl/data
++    dir: /mnt/onl/active_data
+     fsck: true
+ 
+   ONL-CONFIG:
+-    mount: ro
++    mount: rw
+     dir: /mnt/onl/config
+     fsck: true
+ 
+-  ONL-BOOT:
++  ONL-ACTIVE-BOOT:
++    mount: rw
++    dir: /mnt/onl/active_boot
++    fsck: true
++
++  ONL-STANDBY-BOOT:
++    mount: rw
++    dir: /mnt/onl/standby_boot
++    fsck: true
++
++  ONL-STANDBY-DATA:
+     mount: rw
+-    dir: /mnt/onl/boot
++    dir: /mnt/onl/standby_data
+     fsck: true
+ 
+   # ESP (EFI system partition)
+diff --git a/packages/base/all/vendor-config-onl/src/bin/onlfit b/packages/base/all/vendor-config-onl/src/bin/onlfit
+index 2c4b21e..01de3a0 100755
+--- a/packages/base/all/vendor-config-onl/src/bin/onlfit
++++ b/packages/base/all/vendor-config-onl/src/bin/onlfit
+@@ -21,7 +21,7 @@ dir=`mktemp -d`
+ rc=
+ 
+ if (cd $dir && wget $1); then
+-    onlfs rw boot mv $dir/* /mnt/onl/boot/${PLATFORM}.itb
++    onlfs rw boot mv $dir/* /mnt/onl/active_boot/${PLATFORM}.itb
+     rc=0
+ else
+     echo "Download failed."
+diff --git a/packages/base/all/vendor-config-onl/src/bin/onlkernel b/packages/base/all/vendor-config-onl/src/bin/onlkernel
+index e77a6cc..a61046a 100755
+--- a/packages/base/all/vendor-config-onl/src/bin/onlkernel
++++ b/packages/base/all/vendor-config-onl/src/bin/onlkernel
+@@ -19,7 +19,7 @@ dir=`mktemp -d`
+ rc=
+ 
+ if (cd $dir && wget $1); then
+-    onlfs rw boot mv $dir/* /mnt/onl/boot
++    onlfs rw boot mv $dir/* /mnt/onl/active_boot
+     rc=0
+ else
+     echo "Download failed."
+diff --git a/packages/base/all/vendor-config-onl/src/boot.d/70.dhclient.conf b/packages/base/all/vendor-config-onl/src/boot.d/70.dhclient.conf
+index 052f28f..4af1bf2 100755
+--- a/packages/base/all/vendor-config-onl/src/boot.d/70.dhclient.conf
++++ b/packages/base/all/vendor-config-onl/src/boot.d/70.dhclient.conf
+@@ -7,12 +7,10 @@
+ MA1_MAC=${MA1_MAC:-$(cat /sys/class/net/ma1/address)}
+ DHCLIENT_CONF=${DHCLIENT_CONF:-/etc/dhcp/dhclient.conf}
+ 
+-echo "interface \"ma1\" {" >> $DHCLIENT_CONF
+-echo "    send dhcp-client-identifier 01:$MA1_MAC;" >> $DHCLIENT_CONF
+-echo "}" >> $DHCLIENT_CONF
+-
+-
+-
+-
+-
++grep -q "interface \"ma1\" {" $DHCLIENT_CONF
++if [ $? -ne 0 ];then
++    echo "interface \"ma1\" {" >> $DHCLIENT_CONF
++    echo "    send dhcp-client-identifier 01:$MA1_MAC;" >> $DHCLIENT_CONF
++    echo "}" >> $DHCLIENT_CONF
++fi
+ 
+diff --git a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml
+index 432c6a9..098e014 100644
+--- a/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml
++++ b/packages/base/all/vendor-config-onl/src/etc/onl/sysconfig/00-defaults.yml
+@@ -7,6 +7,9 @@
+ ############################################################
+ installer:
+   menu_name: "\"Open Network Linux\""
++  menu_name_active: "\"ONL Active\""
++  menu_name_standby: "\"ONL Standby\""
++
+   os_name: Open Network Linux
+   grub:
+     - $PLATFORM.cpio.gz
+diff --git a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml
+index 57e61fb..31d3de0 100644
+--- a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml
++++ b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml
+@@ -171,7 +171,7 @@ default:
+   # data --> rest of disk
+   # default format (as shown) is ext4
+   installer:
+-  - ONL-BOOT:
++  - ONL-ACTIVE-BOOT:
+       =: 128MiB
+       # NOTE that u-boot wants the boot partition ext2, not ext4
+       format: ext2
+@@ -181,9 +181,15 @@ default:
+       =: 128MiB
+       format: ext4
+   - ONL-IMAGES:
+-      =: 1GiB
++      =: 3GiB
+       format: ext4
+-  - ONL-DATA:
++  - ONL-ACTIVE-DATA:
++      =: 3GiB
++      format: ext4
++  - ONL-STANDBY-BOOT:
++      =: 128MiB
++      format: ext4
++  - ONL-STANDBY-DATA:
+       =: 100%
+       format: ext4
+ 
+diff --git a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml
+index 544bc2f..900cbef 100644
+--- a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml
++++ b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-x86-64.yml
+@@ -75,6 +75,9 @@ default:
+     device: ONIE-BOOT
+     # install to the device that contains the ONIE-BOOT partition
+     # (query using parted and/or blkid)
++  install_type:
++    type: install
++    device: None
+ 
+   # Default partitioning scheme
+   # boot, config --> 128MiB
+@@ -82,16 +85,22 @@ default:
+   # data --> rest of disk
+   # default format (as shown) is ext4
+   installer:
+-  - ONL-BOOT:
++  - ONL-ACTIVE-BOOT:
+       =: 128MiB
+       format: ext4
+   - ONL-CONFIG:
+       =: 128MiB
+       format: ext4
+   - ONL-IMAGES:
+-      =: 1GiB
++      =: 3GiB
+       format: ext4
+-  - ONL-DATA:
++  - ONL-ACTIVE-DATA:
++      =: 3GiB
++      format: ext4
++  - ONL-STANDBY-BOOT:
++      =: 128MiB
++      format: ext4
++  - ONL-STANDBY-DATA:
+       =: 100%
+       format: ext4
+ 
+diff --git a/packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py
+index e85c9ca..2c047be 100755
+--- a/packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py
++++ b/packages/base/all/vendor-config-onl/src/python/onl/bootconfig/__init__.py
+@@ -5,7 +5,7 @@ import sys
+ import netaddr
+ 
+ class OnlBootConfig(object):
+-    BOOT_CONFIG_DEFAULT='/mnt/onl/boot/boot-config'
++    BOOT_CONFIG_DEFAULT='/mnt/onl/active_boot/boot-config'
+ 
+     def __init__(self):
+         self.keys = {}
+@@ -26,7 +26,7 @@ class OnlBootConfig(object):
+             self._readf(self.BOOT_CONFIG_DEFAULT)
+         else:
+             from onl.mounts import OnlMountContextReadOnly
+-            with OnlMountContextReadOnly("ONL-BOOT", logger=None):
++            with OnlMountContextReadOnly("ONL-ACTIVE-BOOT", logger=None):
+                 self._readf(self.BOOT_CONFIG_DEFAULT)
+ 
+     def set(self, k, v):
+@@ -53,7 +53,8 @@ class OnlBootConfig(object):
+             return True
+         else:
+             from onl.mounts import OnlMountContextReadWrite
+-            with OnlMountContextReadWrite("ONL-BOOT", logger=None):
++            with OnlMountContextReadWrite("ONL-ACTIVE-BOOT", logger=None):
++
+                 if not os.path.exists(self.BOOT_CONFIG_DEFAULT) or force_overwrite:
+                     self._writef(self.BOOT_CONFIG_DEFAULT)
+                     return True
+diff --git a/packages/base/all/vendor-config-onl/src/python/onl/grub/__init__.py b/packages/base/all/vendor-config-onl/src/python/onl/grub/__init__.py
+index b23b948..7bbca82 100644
+--- a/packages/base/all/vendor-config-onl/src/python/onl/grub/__init__.py
++++ b/packages/base/all/vendor-config-onl/src/python/onl/grub/__init__.py
+@@ -34,7 +34,7 @@ def onie_fwpkg(arguments):
+         subprocess.check_call("%s/onie/tools/bin/onie-fwpkg %s" % (ob.directory, arguments), shell=True)
+ 
+ def boot_entry_set(index):
+-    with OnlMountContextReadWrite("ONL-BOOT", logger=None) as ob:
++    with OnlMountContextReadWrite("ONL-ACTIVE-BOOT", logger=None) as ob:
+         subprocess.check_call("/usr/sbin/grub-set-default --boot-directory=%s %d" % (ob.directory, index), shell=True)
+ 
+ def boot_onie():
+diff --git a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py
+index 7416c20..0c72c9d 100755
+--- a/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py
++++ b/packages/base/all/vendor-config-onl/src/python/onl/install/BaseInstall.py
+@@ -364,30 +364,30 @@ class Base:
+         return 0
+ 
+     def installBootConfig(self):
++        devices = ["ONL-ACTIVE-BOOT", "ONL-STANDBY-BOOT"]
+ 
+-        try:
+-            dev = self.blkidParts['ONL-BOOT']
+-        except IndexError as ex:
+-            self.log.warn("cannot find ONL-BOOT partition (maybe raw?) : %s", str(ex))
+-            return 1
+-
+-        self.log.info("Installing boot-config to %s", dev.device)
++        for device in devices:
++            try:
++                dev = self.blkidParts[device]
++            except IndexError as ex:
++                self.log.warn("cannot find ONL-BOOT partition (maybe raw?) : %s", str(ex))
++                return 1
+ 
+-        basename = 'boot-config'
+-        with MountContext(dev.device, log=self.log) as ctx:
+-            dst = os.path.join(ctx.dir, basename)
++            basename = 'boot-config'
++            with MountContext(dev.device, log=self.log) as ctx:
++                dst = os.path.join(ctx.dir, basename)
+ 
+-            if not self.installerCopy(basename, dst, True):
+-                return
++                if not self.installerCopy(basename, dst, True):
++                    return
+ 
+-            with open(dst) as fd:
+-                buf = fd.read()
++                with open(dst) as fd:
++                    buf = fd.read()
+ 
+-        ecf = buf.encode('base64', 'strict').strip()
+-        if self.im.grub and self.im.grubEnv is not None:
+-            setattr(self.im.grubEnv, 'boot_config_default', ecf)
+-        if self.im.uboot and self.im.ubootEnv is not None:
+-            setattr(self.im.ubootEnv, 'boot-config-default', ecf)
++            ecf = buf.encode('base64', 'strict').strip()
++            if self.im.grub and self.im.grubEnv is not None:
++                setattr(self.im.grubEnv, 'boot_config_default', ecf)
++            if self.im.uboot and self.im.ubootEnv is not None:
++                setattr(self.im.ubootEnv, 'boot-config-default', ecf)
+ 
+         return 0
+ 
+@@ -503,14 +503,14 @@ if [ "${saved_entry}" ] ; then
+ fi
+ 
+ menuentry %(boot_menu_entry)s {
+-  search --no-floppy --label --set=root ONL-BOOT
++  search --no-floppy --label --set=root %(boot_partition)s
+   # Always return to this entry by default.
+   set saved_entry="0"
+   save_env saved_entry
+   echo 'Loading %(boot_loading_name)s ...'
+   insmod gzio
+   insmod part_msdos
+-  linux /%(kernel)s %(args)s onl_platform=%(platform)s
++  linux /%(kernel)s %(args)s onl_platform=%(platform)s %(boot_type)s
+   initrd /%(platform)s.cpio.gz
+ }
+ 
+@@ -693,26 +693,26 @@ class GrubInstaller(SubprocessMixin, Base):
+                     initrd = i
+                     break
+ 
+-        dev = self.blkidParts['ONL-BOOT']
++        devices = ["ONL-ACTIVE-BOOT", "ONL-STANDBY-BOOT"]
++        for device in devices:
++            dev = self.blkidParts[device]
+ 
+-        self.log.info("Installing kernel to %s", dev.device)
++            self.log.info("Installing kernel to %s", dev.device)
+ 
+-        with MountContext(dev.device, log=self.log) as ctx:
+-            def _cp(b, dstname=None):
+-                if dstname is None:
+-                    dstname = b
+-                dst = os.path.join(ctx.dir, dstname)
+-                self.installerCopy(b, dst, optional=True)
+-            [_cp(e) for e in kernels]
+-            _cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)
++            with MountContext(dev.device, log=self.log) as ctx:
++                def _cp(b, dstname=None):
++                    if dstname is None:
++                        dstname = b
++                    dst = os.path.join(ctx.dir, dstname)
++                    self.installerCopy(b, dst, optional=True)
++                [_cp(e) for e in kernels]
++                _cp(initrd, "%s.cpio.gz" % self.im.installerConf.installer_platform)
+ 
+         return 0
+ 
+     def installGrubCfg(self):
+-
+-        dev = self.blkidParts['ONL-BOOT']
+-
+-        self.log.info("Installing grub.cfg to %s", dev.device)
++        device = "ONL-ACTIVE-BOOT"
++        dev = self.blkidParts[device]
+ 
+         ctx = {}
+ 
+@@ -723,6 +723,21 @@ class GrubInstaller(SubprocessMixin, Base):
+         ctx['serial'] = self.im.platformConf['grub']['serial']
+ 
+         ctx['boot_menu_entry'] = sysconfig.installer.menu_name
++        cmd = "mkdir /tmp/Test"
++        os.system(cmd)
++        cmd = "mount /dev/sda5 /tmp/Test"
++        os.system(cmd)
++        with open("upgrade_config", "w") as f:
++            f.write("root_path=data-active\n")
++            f.write("boot_path=ONL-ACTIVE-BOOT\n")
++
++        cmd = "mv upgrade_config /tmp/Test/upgrade_config"
++        os.system(cmd)
++        cmd = "umount /tmp/Test"
++        os.system(cmd)
++        ctx['boot_partition'] = "ONL-ACTIVE-BOOT"
++        ctx['boot_type'] = "data-active"
++
+         ctx['boot_loading_name'] = sysconfig.installer.os_name
+ 
+         if self.isUEFI:
+@@ -740,13 +755,12 @@ class GrubInstaller(SubprocessMixin, Base):
+             if not os.path.exists(d):
+                 self.makedirs(d)
+             dst = os.path.join(ctx.dir, 'grub/grub.cfg')
+-            with open(dst, "w") as fd:
++            with open(dst, "a") as fd:
+                 fd.write(cf)
+ 
+         return 0
+ 
+     def installGrub(self):
+-        self.log.info("Installing GRUB to %s", self.partedDevice.path)
+         self.im.grubEnv.install(self.partedDevice.path)
+         return 0
+ 
+@@ -773,11 +787,6 @@ class GrubInstaller(SubprocessMixin, Base):
+         else:
+             self.im.grubEnv.__dict__['espPart'] = None
+ 
+-        self.log.info("Installing to %s starting at partition %d",
+-                      self.device, self.minpart)
+-
+-        self.log.info("disk is %s", self.partedDevice.path)
+-
+         self.log.info("found %s partitions (bsz %s, lbsz %s)",
+                       self.partedDisk.type,
+                       self.partedDevice.sectorSize,
+@@ -803,7 +812,8 @@ class GrubInstaller(SubprocessMixin, Base):
+ 
+         # once we assign the ONL-BOOT partition,
+         # we can re-target the grub environment
+-        dev = self.blkidParts['ONL-BOOT']
++
++        dev = self.blkidParts['ONL-ACTIVE-BOOT']
+         self.im.grubEnv.__dict__['bootPart'] = dev.device
+         self.im.grubEnv.__dict__['bootDir'] = None
+ 
+@@ -1169,7 +1179,7 @@ class UbootInstaller(SubprocessMixin, UBIfsCreater):
+             self.installerDd(loaderBasename, self.rawLoaderDevice)
+             return 0
+ 
+-        dev = self.blkidParts['ONL-BOOT']
++        dev = self.blkidParts['ONL-ACTIVE-BOOT']
+         self.log.info("Installing ONL loader %s --> %s:%s...",
+                       loaderBasename, dev.device, loaderBasename)
+         with MountContext(dev.device, log=self.log) as ctx:
+diff --git a/packages/base/all/vendor-config-onl/src/python/onl/install/ShellApp.py b/packages/base/all/vendor-config-onl/src/python/onl/install/ShellApp.py
+index 4b363e7..fe268fe 100644
+--- a/packages/base/all/vendor-config-onl/src/python/onl/install/ShellApp.py
++++ b/packages/base/all/vendor-config-onl/src/python/onl/install/ShellApp.py
+@@ -331,37 +331,38 @@ class Loader(AppBase):
+     PROG = "loader-shell"
+ 
+     def runGrub(self):
++        devices = ["ONL-ACTIVE-BOOT", "ONL-STANDBY-BOOT"]
++        for boot_device in devices:
++            try:
++                dev = self.blkid[boot_device].device
++            except KeyError:
++                pass
++            if dev is None:
++                self.log.error("cannot find GRUB partition %s", dev)
++                return 1
++            initrd = self.pc['grub']['initrd']
++            if type(initrd) == dict: initrd = initrd['=']
+ 
+-        try:
+-            dev = self.blkid['ONL-BOOT'].device
+-        except KeyError:
+-            pass
+-        if dev is None:
+-            self.log.error("cannot find GRUB partition %s", dev)
+-            return 1
+-
+-        initrd = self.pc['grub']['initrd']
+-        if type(initrd) == dict: initrd = initrd['=']
++            parts = [p for p in self.pm.mounts if p.device == dev]
++            if parts:
++                grubDir = parts[0]
++                self.log.debug("found loader device %s mounted at %s",
++                               dev, grubDir)
++                p = os.path.join(grubDir, initrd)
++                if not os.path.exists(p):
++                    self.log.error("cannot find initrd %s", p)
++                    return 1
++                self.log.debug("found loader initrd at %s", p)
++                return self._runInitrdShell(p)
+ 
+-        parts = [p for p in self.pm.mounts if p.device == dev]
+-        if parts:
+-            grubDir = parts[0]
+-            self.log.debug("found loader device %s mounted at %s",
+-                           dev, grubDir)
+-            p = os.path.join(grubDir, initrd)
+-            if not os.path.exists(p):
+-                self.log.error("cannot find initrd %s", p)
+-                return 1
+-            self.log.debug("found loader initrd at %s", p)
+-            return self._runInitrdShell(p)
++            with MountContext(dev, log=self.log) as ctx:
++                p = os.path.join(ctx.dir, initrd)
++                if not os.path.exists(p):
++                    self.log.error("cannot find initrd %s:%s", dev, p)
++                    return 1
++                self.log.debug("found loader initrd at %s:%s", dev, p)
++                return self._runInitrdShell(p)
+ 
+-        with MountContext(dev, log=self.log) as ctx:
+-            p = os.path.join(ctx.dir, initrd)
+-            if not os.path.exists(p):
+-                self.log.error("cannot find initrd %s:%s", dev, p)
+-                return 1
+-            self.log.debug("found loader initrd at %s:%s", dev, p)
+-            return self._runInitrdShell(p)
+ 
+     def runUboot(self):
+ 
+@@ -373,7 +374,7 @@ class Loader(AppBase):
+         bootPartno = None
+         for idx, part in enumerate(self.pc['installer']):
+             label, pdata = list(part.items())[0]
+-            if label == 'ONL-BOOT':
++            if label == 'ONL-ACTIVE-BOOT':
+                 bootPart = pdata
+                 bootPartno = idx + 1
+                 break
+@@ -385,7 +386,7 @@ class Loader(AppBase):
+         if fmt == 'raw':
+             bootDevice = dev + str(bootPartno)
+         else:
+-            bootDevice = self.blkid['ONL-BOOT'].device
++            bootDevice = self.blkid['ONL-ACTIVE-BOOT'].device
+ 
+         # run from a raw partition
+         if fmt == 'raw':
+diff --git a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py
+index bf3bbe5..d282f3f 100755
+--- a/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py
++++ b/packages/base/all/vendor-config-onl/src/python/onl/upgrade/loader.py
+@@ -77,7 +77,8 @@ class LoaderUpgrade_Fit(LoaderUpgradeBase):
+         if fit_image is None:
+             self.abort("The FIT upgrade image is missing. Upgrade cannot continue.")
+ 
+-        with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d:
++        with OnlMountContextReadWrite("ONL-ACTIVE-BOOT", self.logger) as d:
++
+             self.copyfile(fit_image, os.path.join(d.directory, "%s.itb" % (self.platform.platform())))
+ 
+         onlPlatform = onl.platform.current.OnlPlatform()
+@@ -135,7 +136,7 @@ class LoaderUpgrade_x86_64(LoaderUpgradeBase, InstallUtils.SubprocessMixin):
+         X86_64_UPGRADE_DIR=sysconfig.upgrade.loader.package.dir
+         X86_64_UPGRADE_KERNEL_PATTERNS = [ "kernel-*" ]
+ 
+-        with OnlMountContextReadWrite("ONL-BOOT", self.logger) as d:
++        with OnlMountContextReadWrite("ONL-ACTIVE-BOOT", self.logger) as d:
+             for f in os.listdir(X86_64_UPGRADE_DIR):
+                 for pattern in X86_64_UPGRADE_KERNEL_PATTERNS:
+                     if fnmatch.fnmatch(f, pattern):
+diff --git a/packages/base/all/vendor-config-onl/src/sbin/uninstall b/packages/base/all/vendor-config-onl/src/sbin/uninstall
+index 79d0d77..93c7fd9 100755
+--- a/packages/base/all/vendor-config-onl/src/sbin/uninstall
++++ b/packages/base/all/vendor-config-onl/src/sbin/uninstall
+@@ -12,7 +12,7 @@ uninstall_x86_64()
+ 
+         # Force ONIE boot selection
+         onlfs mount boot --rw
+-        echo "default=1" >> /mnt/onl/boot/grub/grub.cfg
++        echo "default=1" >> /mnt/onl/active_boot/grub/grub.cfg
+ 
+     else
+         if [ "$1" = "factory" ]; then
 diff --git a/tools/switool.py b/tools/switool.py
-index 26eb2fb1..6c783c3d 100755
+index 26eb2fb..6c783c3 100755
 --- a/tools/switool.py
 +++ b/tools/switool.py
 @@ -79,6 +79,26 @@ if ops.create or ops.overwrite:
@@ -91,4 +839,4 @@
 +
      for f in ops.add_files:
          swi.add(f, arcname=f)
- 
+
diff --git a/agent/inband/scripts/start_inband_oltservices.sh b/agent/inband/scripts/start_inband_oltservices.sh
index 02607df..ee18bee 100644
--- a/agent/inband/scripts/start_inband_oltservices.sh
+++ b/agent/inband/scripts/start_inband_oltservices.sh
@@ -78,9 +78,6 @@
 # File used to set/get argument to openolt service
 OPENOLT_ARG_INPUT_FILE=/etc/default/openolt
 
-# Wait time for BAL to get ready
-WAIT_TIME_BAL_READY=$(awk '/wait_time_bal_ready/{print $0}' ${INBAND_CONFIG_FILE} | awk -F "=" '{print $2}')
-
 #------------------------------------------------------------------------------
 # Function Name: does_logger_exist
 # Description:
@@ -193,17 +190,17 @@
         ob_cfg=$(awk '/enable_out_of_band_connection/{print $0}' ${INBAND_CONFIG_FILE} | awk -F "=" '{print $2}')
         if [ -z ${ob_cfg} ]; then
             error_message "ERROR: missing configuration to enable out-of-band connection to OLT. Default to false"
-            return false
-        fi
-    else
-        if [ "${ob_cfg}" = "yes" ]; then
-            return true
+            echo "no"
+        elif [ "${ob_cfg}" = "yes" ]; then
+            echo "yes"
         elif [ "${ob_cfg}" = "no" ]; then
-            return false
+            echo "no"
         else
             error_message "ERROR: Invalid configuration to enable out-of-band connection -> ${ob_cfg}"
-            return false
+            echo "no"
         fi
+    else
+        echo "no"
     fi
 }
 
@@ -224,8 +221,8 @@
 #------------------------------------------------------------------------------
 setup_nw_configuration() {
     # Dynamic vlan entry in /etc/network/interfaces file
-
-    if [ is_out_band_connection_enabled ]; then
+    local is_out_band=$(is_out_band_connection_enabled)
+    if [ "${is_out_band}" = "yes" ]; then
         # This interface is used for out-of-band connection for the OLT
         # This is not a mandatory requirement for in-band management of the OLT
         set_dhcp_ip_configuration ma1
@@ -689,6 +686,9 @@
         fi
     fi
     copy_config_files
+    # Wait time for BAL to get ready
+    WAIT_TIME_BAL_READY=$(awk '/wait_time_bal_ready/{print $0}' ${INBAND_CONFIG_FILE} | awk -F "=" '{print $2}')
+
     start_olt_services
 else
     error_message "logger does not exist"
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
+