Synchronize ONOS cord/fabric containers based on the new changes to CiaB that breaks the service-profile makefile approach.

Change-Id: I68414230ac1fab6b069a915baab578c5a766598f
diff --git a/src/test/cli/onosclidriver.py b/src/test/cli/onosclidriver.py
index 4ea1fb6..adb6131 100644
--- a/src/test/cli/onosclidriver.py
+++ b/src/test/cli/onosclidriver.py
@@ -4672,6 +4672,73 @@
 	    main.cleanup()
 	    main.exit()
 
+    def cordVtnSyncNeutronStates( self, endpoint, password, tenant = 'admin', user = 'admin'):
+        """
+        Syncs VTN network with neutron
+        Required:
+            * openstack endpoint
+            * openstack password
+        """
+        try:
+            cmdStr = 'cordvtn-sync-neutron-states {} {} {} {}'.format(endpoint, tenant, user, password)
+            handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
+            if re.search( "Error", handle ):
+                main.log.error( "Error in syncing vtn information" )
+                main.log.error( handle )
+                return main.FALSE
+            else:
+                main.log.info("CordVTN state synced")
+                return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def cordVtnNodeInit( self, host):
+        """
+        Syncs VTN nodes with neutron
+        Required:
+            * openstack node host
+        """
+        try:
+            cmdStr = 'cordvtn-node-init {}'.format(host)
+            handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
+            if re.search( "Error", handle ):
+                main.log.error( "Error in syncing vtn node information" )
+                main.log.error( handle )
+                return main.FALSE
+            else:
+                main.log.info("CordVTN node state synced")
+                return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
 if __name__ == '__main__':
   onos_cli = OnosCliDriver(connect = False)
   name = 'onos_cli'
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index b3dc28d..ab74ab2 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -18,7 +18,9 @@
 import os,sys,time,socket,errno
 import shutil, platform, re
 utils_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), '../utils')
+cli_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), '../cli')
 sys.path.append(utils_dir)
+sys.path.append(cli_dir)
 sys.path.insert(1, '/usr/local/lib/python2.7/dist-packages')
 from OnosCtrl import OnosCtrl, get_mac
 from OltConfig import OltConfig
@@ -512,14 +514,11 @@
             print('Specify ONOS ip using \"-e\" option when running the cord-tester on cord node')
             sys.exit(1)
         if not service_profile:
-            print('Specify service profile location for the ONOS cord instance. Eg: $HOME/service-profile/cord-pod')
+            print('Specify service profile for the ONOS cord instance. Eg: rcord')
             sys.exit(1)
         if not synchronizer:
             print('Specify synchronizer to use for the ONOS cord instance. Eg: vtn, fabric, cord')
             sys.exit(1)
-        if not os.access(service_profile, os.F_OK):
-            print('Service profile location for ONOS cord instance does not exist')
-            sys.exit(1)
         onos_cord = OnosCord(onos_ip, onos_cord_loc, service_profile, synchronizer)
 
     try:
@@ -779,14 +778,11 @@
             print('Specify ONOS ip using \"-e\" option when running the cord-tester on cord node')
             sys.exit(1)
         if not service_profile:
-            print('Specify service profile location for the ONOS cord instance. Eg: $HOME/service-profile/cord-pod')
+            print('Specify service profile for the ONOS cord instance. Eg: rcord')
             sys.exit(1)
         if not synchronizer:
             print('Specify synchronizer to use for the ONOS cord instance. Eg: vtn, fabric, cord')
             sys.exit(1)
-        if not os.access(service_profile, os.F_OK):
-            print('Service profile location for ONOS cord instance does not exist')
-            sys.exit(1)
         onos_cord = OnosCord(onos_ip, onos_cord_loc, service_profile, synchronizer)
 
     Container.IMAGE_PREFIX = test_manifest.image_prefix
diff --git a/src/test/setup/manifest-cord.json b/src/test/setup/manifest-cord.json
index 5fddc11..28ec418 100644
--- a/src/test/setup/manifest-cord.json
+++ b/src/test/setup/manifest-cord.json
@@ -5,7 +5,7 @@
     "onos_image": "onosproject/onos:latest",
     "onos" : "172.19.0.2",
     "onos_cord" : "/home/vagrant/onos-cord",
-    "service_profile" : "/opt/cord/orchestration/service-profile/cord-pod",
+    "service_profile" : "rcord",
     "synchronizer" : "vtn",
     "docker_network" : "onoscord_default",
     "log_level" : "INFO",
diff --git a/src/test/setup/manifest-fabric.json b/src/test/setup/manifest-fabric.json
index b09dd91..56c2559 100644
--- a/src/test/setup/manifest-fabric.json
+++ b/src/test/setup/manifest-fabric.json
@@ -5,7 +5,7 @@
     "onos_image": "onosproject/onos:latest",
     "onos" : "172.20.0.2",
     "onos_cord" : "/home/vagrant/onos-fabric",
-    "service_profile" : "/opt/cord/orchestration/service-profile/cord-pod",
+    "service_profile" : "rcord",
     "synchronizer" : "fabric",
     "docker_network" : "onosfabric_default",
     "log_level" : "INFO",
diff --git a/src/test/utils/CordContainer.py b/src/test/utils/CordContainer.py
index a3afab4..0834302 100644
--- a/src/test/utils/CordContainer.py
+++ b/src/test/utils/CordContainer.py
@@ -28,6 +28,7 @@
 import shutil
 from OnosCtrl import OnosCtrl
 from OnosLog import OnosLog
+from onosclidriver import OnosCliDriver
 from threadPool import ThreadPool
 from threading import Lock
 
@@ -300,13 +301,28 @@
 class OnosCord(Container):
     """Use this when running the cord tester agent on the onos compute node"""
     onos_config_dir_guest = '/root/onos/config'
-    tester_apps = ( 'org.onosproject.proxyarp', 'org.onosproject.hostprovider' )
+    synchronizer_map = { 'vtn' : { 'install':
+                      ('http://mavenrepo:8080/repository/org/opencord/cord-config/1.2-SNAPSHOT/cord-config-1.2-SNAPSHOT.oar',
+                       'http://mavenrepo:8080/repository/org/opencord/vtn/1.2-SNAPSHOT/vtn-1.2-SNAPSHOT.oar',),
+                                   'activate':
+                                   ('org.onosproject.ovsdb-base', 'org.onosproject.drivers.ovsdb',
+                                    'org.onosproject.dhcp', 'org.onosproject.optical-model',
+                                    'org.onosproject.openflow-base', 'org.onosproject.proxyarp',
+                                    'org.onosproject.hostprovider'),
+                                   },
+                         'fabric' : { 'activate':
+                                      ('org.onosproject.hostprovider', 'org.onosproject.optical-model',
+                                       'org.onosproject.openflow-base', 'org.onosproject.vrouter',
+                                       'org.onosproject.netcfghostprovider', 'org.onosproject.netcfglinksprovider',
+                                       'org.onosproject.segmentrouting', 'org.onosproject.proxyarp'),
+                                      }
+                         }
+    tester_apps = ('http://mavenrepo:8080/repository/org/opencord/aaa/1.2-SNAPSHOT/aaa-1.2-SNAPSHOT.oar',
+                   'http://mavenrepo:8080/repository/org/opencord/igmp/1.2-SNAPSHOT/igmp-1.2-SNAPSHOT.oar',)
 
-    def __init__(self, onos_ip, conf, service_profile, synchronizer, start = True, boot_delay = 25):
+    def __init__(self, onos_ip, conf, service_profile, synchronizer, start = True, boot_delay = 5):
         if not os.access(conf, os.F_OK):
             raise Exception('ONOS cord configuration location %s is invalid' %conf)
-        if not os.access(service_profile, os.F_OK):
-            raise Exception('ONOS cord service profile location is not accessible' %service_profile)
         self.onos_ip = onos_ip
         self.onos_cord_dir = conf
         self.boot_delay = boot_delay
@@ -361,6 +377,91 @@
             #start the container back with the shared onos config volume
             self.start()
 
+    def cliEnter(self):
+        retries = 0
+        while retries < 30:
+            cli = OnosCliDriver(controller = self.onos_ip, connect = True)
+            if cli.handle:
+                return cli
+            else:
+                retries += 1
+                time.sleep(2)
+
+        return None
+
+    def cliExit(self, cli):
+        if cli:
+            cli.disconnect()
+
+    def synchronize_vtn(self, cfg = None):
+        if cfg is None:
+            return
+        if not cfg.has_key('apps'):
+            return
+        if not cfg['apps'].has_key('org.opencord.vtn'):
+            return
+        vtn_neutron_cfg = cfg['apps']['org.opencord.vtn']['cordvtn']['openstack']
+        password = vtn_neutron_cfg['password']
+        endpoint = vtn_neutron_cfg['endpoint']
+        user = vtn_neutron_cfg['user']
+        tenant = vtn_neutron_cfg['tenant']
+        vtn_host = cfg['apps']['org.opencord.vtn']['cordvtn']['nodes'][0]['hostname']
+        cli = self.cliEnter()
+        if cli is None:
+            return
+        cli.cordVtnSyncNeutronStates(endpoint, password, tenant = tenant, user = user)
+        time.sleep(2)
+        cli.cordVtnNodeInit(vtn_host)
+        self.cliExit(cli)
+
+    def synchronize(self, cfg_unlink = False):
+        cfg = None
+        #restore the saved config after restart
+        if os.access(self.onos_cfg_save_loc, os.F_OK):
+            with open(self.onos_cfg_save_loc, 'r') as f:
+                cfg = json.load(f)
+                try:
+                    OnosCtrl.config(cfg, controller = self.onos_ip)
+                    if cfg_unlink is True:
+                        os.unlink(self.onos_cfg_save_loc)
+                except:
+                    pass
+
+        if not self.synchronizer_map.has_key(self.synchronizer):
+            return
+
+        install_list = ()
+        if self.synchronizer_map[self.synchronizer].has_key('install'):
+            install_list = self.synchronizer_map[self.synchronizer]['install']
+
+        activate_list = ()
+        if self.synchronizer_map[self.synchronizer].has_key('activate'):
+            activate_list = self.synchronizer_map[self.synchronizer]['activate']
+
+        for app_url in install_list:
+            print('Installing app from url: %s' %app_url)
+            OnosCtrl.install_app_from_url(None, None, app_url = app_url, onos_ip = self.onos_ip)
+
+        for app in activate_list:
+            print('Activating app %s' %app)
+            OnosCtrl(app, controller = self.onos_ip).activate()
+            time.sleep(2)
+
+        for app_url in self.tester_apps:
+            print('Installing tester app from url: %s' %app_url)
+            OnosCtrl.install_app_from_url(None, None, app_url = app_url, onos_ip = self.onos_ip)
+
+        #restart the xos synchronizer container
+        cmd = 'cd /opt/cord_profile/onboarding-docker-compose && \
+        docker-compose -p {} restart xos_synchronizer_{}'.format(self.service_profile, self.synchronizer)
+        try:
+            print(cmd)
+            os.system(cmd)
+        except: pass
+
+        if hasattr(self, 'synchronize_{}'.format(self.synchronizer)):
+            getattr(self, 'synchronize_{}'.format(self.synchronizer))(cfg = cfg)
+
     def start(self, restart = False, network_cfg = None):
         if network_cfg is not None:
             json_data = json.dumps(network_cfg, indent=4)
@@ -369,40 +470,25 @@
 
         #we avoid using docker-compose restart for now.
         #since we don't want to retain the metadata across restarts
-        if True:
-            #stop and start and synchronize the services before installing tester cord apps
-            cmds = [ 'cd {} && docker-compose down'.format(self.onos_cord_dir),
-                     'cd {} && docker-compose up -d'.format(self.onos_cord_dir),
-                     'sleep 45',
-                     'cd {} && make {}'.format(self.service_profile, self.synchronizer)
-            ]
-            for cmd in cmds:
-                try:
-                    print(cmd)
-                    os.system(cmd)
-                except:pass
-            Onos.install_cord_apps(onos_ip = self.onos_ip)
-            self.activate_apps()
-        else:
-            cmd = 'cd {} && docker-compose restart'.format(self.onos_cord_dir)
+        #stop and start and synchronize the services before installing tester cord apps
+        cmds = [ 'cd {} && docker-compose down'.format(self.onos_cord_dir),
+                 'cd {} && docker-compose up -d'.format(self.onos_cord_dir),
+                 'sleep 45',
+        ]
+        for cmd in cmds:
             try:
+                print(cmd)
                 os.system(cmd)
-            except: pass
+            except:pass
 
+        self.synchronize()
         ##we could also connect container to default docker network but disabled for now
         #Container.connect_to_network(self.name, 'bridge')
-
         #connect container to the quagga bridge
         self.connect_to_br(index = 0)
         print('Waiting %d seconds for ONOS instance to start' %self.boot_delay)
         time.sleep(self.boot_delay)
 
-    def activate_apps(self):
-        for app in self.tester_apps:
-            print('Activating ONOS app %s' %(app))
-            OnosCtrl(app, controller = self.onos_ip).activate()
-            time.sleep(2)
-
     def build_image(self):
         build_cmd = 'cd {} && docker-compose build'.format(self.onos_cord_dir)
         os.system(build_cmd)
@@ -414,13 +500,13 @@
         #nothing to restore
         if not os.access(self.docker_yaml_saved, os.F_OK):
             return
+
         #restore the config files back. The synchronizer restore should bring the last config back
         cmds = ['cd {} && docker-compose down'.format(self.onos_cord_dir),
                 'rm -rf {}'.format(self.onos_config_dir),
                 'mv {} {}'.format(self.docker_yaml_saved, self.docker_yaml),
                 'cd {} && docker-compose up -d'.format(self.onos_cord_dir),
                 'sleep 45',
-                'cd {} && make {}'.format(self.service_profile, self.synchronizer)
         ]
         for cmd in cmds:
             try:
@@ -428,15 +514,7 @@
                 os.system(cmd)
             except: pass
 
-        #We may not have to restore the config but still it should match synchronizer last config
-        if os.access(self.onos_cfg_save_loc, os.F_OK):
-            with open(self.onos_cfg_save_loc, 'r') as f:
-                cfg = json.load(f)
-                try:
-                    OnosCtrl.config(cfg, controller = self.onos_ip)
-                    os.unlink(self.onos_cfg_save_loc)
-                except:
-                    pass
+        self.synchronize(cfg_unlink = True)
 
 class OnosCordStopWrapper(Container):
     onos_cord_dir = os.path.join(os.getenv('HOME'), 'cord-tester-cord')