Merge "automatic deploy a wholeset of TestAPI ecosystem"
authorMorgan Richomme <morgan.richomme@orange.com>
Wed, 14 Dec 2016 13:07:14 +0000 (13:07 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Wed, 14 Dec 2016 13:07:14 +0000 (13:07 +0000)
13 files changed:
.gitignore
jjb/3rd_party_ci/create-apex-vms.sh
jjb/3rd_party_ci/download-netvirt-artifact.sh
jjb/3rd_party_ci/functest-netvirt.sh
jjb/3rd_party_ci/install-netvirt.sh
jjb/3rd_party_ci/odl-netvirt.yml
jjb/3rd_party_ci/postprocess-netvirt.sh
jjb/dovetail/dovetail-run.sh
jjb/functest/functest-suite.sh
jjb/global/slave-params.yml
modules/opnfv/installer_adapters/fuel/FuelAdapter.py
modules/opnfv/utils/SSHUtils.py
modules/opnfv/utils/ovs_logger.py [new file with mode: 0644]

index 96a76e3..024dfac 100644 (file)
@@ -5,3 +5,24 @@
 /releng/
 .idea
 *.py[cod]
+
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+.venv/
+venv/
+ENV/
index cb74271..a076dd0 100755 (executable)
@@ -1,8 +1,12 @@
 #!/bin/bash
+set -e
 
-# clone opnfv sdnvpn repo
-git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git
-cd sdnvpn
-ls -al
+# wipe the WORKSPACE
+/bin/rm -rf $WORKSPACE/*
 
-# here is where the script(s) to bring up apex vms should be executed
+# clone opnfv sdnvpn repo
+git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git $WORKSPACE/sdnvpn
+. $WORKSPACE/sdnvpn/odl-pipeline/odl-pipeline-common.sh
+pushd $LIB
+./test_environment.sh --env-number $APEX_ENV_NUMBER --cloner-info $CLONER_INFO --snapshot-disks $SNAPSHOT_DISKS --vjump-hosts $VIRTUAL_JUMPHOSTS
+popd
index d0b9a05..0a48e3a 100755 (executable)
@@ -1,4 +1,8 @@
 #!/bin/bash
+set -e
+
+# wipe the WORKSPACE
+/bin/rm -rf $WORKSPACE/*
 
 echo "Attempting to fetch the artifact location from ODL Jenkins"
 CHANGE_DETAILS_URL="https://git.opendaylight.org/gerrit/changes/netvirt~master~$GERRIT_CHANGE_ID/detail"
@@ -7,7 +11,13 @@ ODL_JOB_URL=$(curl -s $CHANGE_DETAILS_URL | grep netvirt-patch-test-current-carb
     sed 's/\\n//g' | awk '{print $6}')
 NETVIRT_ARTIFACT_URL="${ODL_JOB_URL}org.opendaylight.integration\$distribution-karaf/artifact/org.opendaylight.integration/distribution-karaf/0.6.0-SNAPSHOT/distribution-karaf-0.6.0-SNAPSHOT.tar.gz"
 echo -e "URL to artifact is\n\t$NETVIRT_ARTIFACT_URL"
+
 echo "Downloading the artifact. This could take time..."
-curl -s -o $NETVIRT_ARTIFACT $NETVIRT_ARTIFACT_URL
+wget -q -O $NETVIRT_ARTIFACT $NETVIRT_ARTIFACT_URL
+if [[ $? -ne 0 ]]; then
+    echo "The artifact does not exist! Probably removed due to ODL Jenkins artifact retention policy."
+    echo "Rerun netvirt-patch-test-current-carbon to get artifact rebuilt."
+    exit 1
+fi
 echo "Download complete"
 ls -al $NETVIRT_ARTIFACT
index abc7975..adffaf4 100755 (executable)
@@ -1,4 +1,7 @@
 #!/bin/bash
+set -e
+
+# wipe the WORKSPACE
+/bin/rm -rf $WORKSPACE/*
 
 echo "Hello World"
-ls -al $WORKSPACE
index 041d851..96c4b96 100755 (executable)
@@ -1,8 +1,8 @@
 #!/bin/bash
-
+set -e
 # clone opnfv sdnvpn repo
-git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git
-cd sdnvpn
-ls -al
-
-# here is where the script(s) to install netvirt should be executed
+git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git $WORKSPACE/sdnvpn
+. $WORKSPACE/sdnvpn/odl-pipeline/odl-pipeline-common.sh
+pushd $LIB
+./odl_reinstaller.sh --cloner-info $CLONER_INFO --odl-artifact $NETVIRT_ARTIFACT
+popd
\ No newline at end of file
index 54d1e43..3dd4c0b 100644 (file)
         - 'create-apex-vms':
             slave-label: 'ericsson-virtual5'
         - 'install-netvirt':
-            slave-label: 'ericsson-virtual6'
+            slave-label: 'odl-netvirt-virtual'
         - 'functest':
-            slave-label: 'ericsson-virtual6'
+            slave-label: 'odl-netvirt-virtual'
         - 'postprocess':
-            slave-label: 'ericsson-virtual6'
+            slave-label: 'odl-netvirt-virtual'
 #####################################
 # jobs
 #####################################
             branch: '{branch}'
         - string:
             name: NETVIRT_ARTIFACT
-            default: $WORKSPACE/distribution-karaf.tar.gz"
-        - 'ericsson-virtual6-defaults'
-
-    scm:
-        - gerrit-trigger-scm:
-            credentials-id: '{ssh-credentials}'
-            refspec: '$GERRIT_REFSPEC'
-            choosing-strategy: 'gerrit'
+            default: $WORKSPACE/distribution-karaf.tar.gz
+        - 'odl-netvirt-virtual-defaults'
 
     triggers:
         - gerrit:
                     GERRIT_PATCHSET_NUMBER=$GERRIT_PATCHSET_NUMBER
                     GERRIT_PATCHSET_REVISION=$GERRIT_PATCHSET_REVISION
                     NETVIRT_ARTIFACT=$NETVIRT_ARTIFACT
+                    APEX_ENV_NUMBER=$APEX_ENV_NUMBER
                   node-parameters: false
                   kill-phase-on: FAILURE
                   abort-all-job: true
             name: functest
             condition: SUCCESSFUL
             projects:
-                - name: 'odl-netvirt-verify-virtual-functest-{stream}'
-                  current-parameters: false
+                - name: 'functest-netvirt-virtual-suite-{stream}'
                   predefined-parameters: |
-                    GERRIT_BRANCH=$GERRIT_BRANCH
-                    GERRIT_REFSPEC=$GERRIT_REFSPEC
-                    GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
-                    GERRIT_CHANGE_ID=$GERRIT_CHANGE_ID
-                    GERRIT_PATCHSET_NUMBER=$GERRIT_PATCHSET_NUMBER
-                    GERRIT_PATCHSET_REVISION=$GERRIT_PATCHSET_REVISION
-                    NETVIRT_ARTIFACT=$NETVIRT_ARTIFACT
+                    FUNCTEST_SUITE_NAME=vping_userdata,bgpvpn
+                    RC_FILE_PATH=/home/jenkins/cloner-info/overcloudrc
                   node-parameters: true
                   kill-phase-on: FAILURE
-                  abort-all-job: true
+                  abort-all-job: false
         - multijob:
             name: postprocess
-            condition: SUCCESSFUL
+            condition: ALWAYS
             projects:
                 - name: 'odl-netvirt-verify-virtual-postprocess-{stream}'
                   current-parameters: false
                 - 'odl-netvirt-verify-virtual-postprocess-.*'
             block-level: 'NODE'
 
-    scm:
-        - gerrit-trigger-scm:
-            credentials-id: '{ssh-credentials}'
-            refspec: '$GERRIT_REFSPEC'
-            choosing-strategy: 'gerrit'
-
     wrappers:
         - ssh-agent-credentials:
             users:
index abc7975..adffaf4 100755 (executable)
@@ -1,4 +1,7 @@
 #!/bin/bash
+set -e
+
+# wipe the WORKSPACE
+/bin/rm -rf $WORKSPACE/*
 
 echo "Hello World"
-ls -al $WORKSPACE
index a41a989..4082c34 100755 (executable)
@@ -66,7 +66,7 @@ if [ $(docker ps | grep "opnfv/dovetail:${DOCKER_TAG}" | wc -l) == 0 ]; then
     exit 1
 fi
 
-exec_cmd="python ${DOVETAIL_REPO_DIR}/dovetail/run.py --testsuite ${TESTSUITE}"
+exec_cmd="python ${DOVETAIL_REPO_DIR}/dovetail/run.py --testsuite ${TESTSUITE} -d true"
 echo "Container exec command: ${exec_cmd}"
 docker exec ${container_id} ${exec_cmd}
 
index df28656..a30fb59 100755 (executable)
@@ -8,7 +8,7 @@ if [[ ${branch} == *"brahmaputra"* ]]; then
 elif [[ ${branch} == *"colorado"* ]]; then
     cmd="python ${FUNCTEST_REPO_DIR}/ci/run_tests.py -t $FUNCTEST_SUITE_NAME"
 else
-    cmd="python ${FUNCTEST_REPO_DIR}/functest/ci/run_tests.py -t $FUNCTEST_SUITE_NAME"
+    cmd="functest testcase run $FUNCTEST_SUITE_NAME"
 fi
 container_id=$(docker ps -a | grep opnfv/functest | awk '{print $1}' | head -1)
 docker exec $container_id $cmd
index 96ad75c..2526111 100644 (file)
             default: https://git.opendaylight.org/gerrit/p/$PROJECT.git
             description: 'Git URL to use on this Jenkins Slave'
 - parameter:
-    name: 'ericsson-virtual6-defaults'
+    name: 'odl-netvirt-virtual-defaults'
     parameters:
         - label:
             name: SLAVE_LABEL
-            default: 'ericsson-virtual6'
+            default: 'odl-netvirt-virtual'
         - string:
             name: GIT_BASE
             default: https://git.opendaylight.org/gerrit/p/$PROJECT.git
             description: 'Git URL to use on this Jenkins Slave'
-        - string:
-            name: APEX_ENV_NUMBER
-            default: 0
-            description: 'The number of the Apex environment on the machine'
 #####################################################
 # These slaves are just dummy slaves for sandbox jobs
 #####################################################
index 6f07940..8ed8f89 100644 (file)
@@ -213,7 +213,7 @@ class FuelAdapter:
         else:
             target_ip = ip
 
-        installer_jumphost = {
+        installer_proxy = {
             'ip': self.installer_ip,
             'username': self.installer_user,
             'password': self.installer_password
@@ -221,7 +221,7 @@ class FuelAdapter:
         controller_conn = ssh_utils.get_ssh_client(
             target_ip,
             user,
-            jumphost=installer_jumphost)
+            proxy=installer_proxy)
 
         self.logger.debug("Fetching %s from %s" %
                           (remote_path, target_ip))
index 6c794c2..16e34c3 100644 (file)
@@ -16,16 +16,16 @@ import os
 logger = OPNFVLogger.Logger('SSHUtils').getLogger()
 
 
-def get_ssh_client(hostname, username, password=None, jumphost=None):
+def get_ssh_client(hostname, username, password=None, proxy=None):
     client = None
     try:
-        if jumphost is None:
+        if proxy is None:
             client = paramiko.SSHClient()
         else:
-            client = JumpHostHopClient()
-            client.configure_jump_host(jumphost['ip'],
-                                       jumphost['username'],
-                                       jumphost['password'])
+            client = ProxyHopClient()
+            client.configure_jump_host(proxy['ip'],
+                                       proxy['username'],
+                                       proxy['password'])
 
         if client is None:
             raise Exception('Could not connect to client')
@@ -62,31 +62,30 @@ def put_file(ssh_conn, src, dest):
         return None
 
 
-class JumpHostHopClient(paramiko.SSHClient):
+class ProxyHopClient(paramiko.SSHClient):
     '''
-    Connect to a remote server using a jumphost hop
+    Connect to a remote server using a proxy hop
     '''
-
     def __init__(self, *args, **kwargs):
-        self.logger = OPNFVLogger.Logger("JumpHostHopClient").getLogger()
-        self.jumphost_ssh = None
-        self.jumphost_transport = None
-        self.jumphost_channel = None
-        self.jumphost_ip = None
-        self.jumphost_ssh_key = None
+        self.logger = OPNFVLogger.Logger("ProxyHopClient").getLogger()
+        self.proxy_ssh = None
+        self.proxy_transport = None
+        self.proxy_channel = None
+        self.proxy_ip = None
+        self.proxy_ssh_key = None
         self.local_ssh_key = os.path.join(os.getcwd(), 'id_rsa')
-        super(JumpHostHopClient, self).__init__(*args, **kwargs)
+        super(ProxyHopClient, self).__init__(*args, **kwargs)
 
     def configure_jump_host(self, jh_ip, jh_user, jh_pass,
                             jh_ssh_key='/root/.ssh/id_rsa'):
-        self.jumphost_ip = jh_ip
-        self.jumphost_ssh_key = jh_ssh_key
-        self.jumphost_ssh = paramiko.SSHClient()
-        self.jumphost_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-        self.jumphost_ssh.connect(jh_ip,
-                                  username=jh_user,
-                                  password=jh_pass)
-        self.jumphost_transport = self.jumphost_ssh.get_transport()
+        self.proxy_ip = jh_ip
+        self.proxy_ssh_key = jh_ssh_key
+        self.proxy_ssh = paramiko.SSHClient()
+        self.proxy_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        self.proxy_ssh.connect(jh_ip,
+                               username=jh_user,
+                               password=jh_pass)
+        self.proxy_transport = self.proxy_ssh.get_transport()
 
     def connect(self, hostname, port=22, username='root', password=None,
                 pkey=None, key_filename=None, timeout=None, allow_agent=True,
@@ -94,28 +93,28 @@ class JumpHostHopClient(paramiko.SSHClient):
                 gss_kex=False, gss_deleg_creds=True, gss_host=None,
                 banner_timeout=None):
         try:
-            if self.jumphost_ssh is None:
+            if self.proxy_ssh is None:
                 raise Exception('You must configure the jump '
                                 'host before calling connect')
 
-            get_file_res = get_file(self.jumphost_ssh,
-                                    self.jumphost_ssh_key,
+            get_file_res = get_file(self.proxy_ssh,
+                                    self.proxy_ssh_key,
                                     self.local_ssh_key)
             if get_file_res is None:
                 raise Exception('Could\'t fetch SSH key from jump host')
-            jumphost_key = (paramiko.RSAKey
-                            .from_private_key_file(self.local_ssh_key))
+            proxy_key = (paramiko.RSAKey
+                         .from_private_key_file(self.local_ssh_key))
 
-            self.jumphost_channel = self.jumphost_transport.open_channel(
+            self.proxy_channel = self.proxy_transport.open_channel(
                 "direct-tcpip",
                 (hostname, 22),
-                (self.jumphost_ip, 22))
+                (self.proxy_ip, 22))
 
             self.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-            super(JumpHostHopClient, self).connect(hostname,
-                                                   username=username,
-                                                   pkey=jumphost_key,
-                                                   sock=self.jumphost_channel)
+            super(ProxyHopClient, self).connect(hostname,
+                                                username=username,
+                                                pkey=proxy_key,
+                                                sock=self.proxy_channel)
             os.remove(self.local_ssh_key)
         except Exception, e:
             self.logger.error(e)
diff --git a/modules/opnfv/utils/ovs_logger.py b/modules/opnfv/utils/ovs_logger.py
new file mode 100644 (file)
index 0000000..3159609
--- /dev/null
@@ -0,0 +1,118 @@
+##############################################################################
+# Copyright (c) 2015 Ericsson AB and others.
+# Author: George Paraskevopoulos (geopar@intracom-telecom.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import opnfv.utils.OPNFVLogger as OPNFVLogger
+import os
+import time
+import shutil
+
+logger = OPNFVLogger.Logger('ovs_logger').getLogger()
+
+
+class OVSLogger(object):
+    def __init__(self, basedir, ft_resdir):
+        self.ovs_dir = basedir
+        self.ft_resdir = ft_resdir
+        self.__mkdir_p(self.ovs_dir)
+        self.__mkdir_p(self.ft_resdir)
+
+    def __mkdir_p(self, dirpath):
+        if not os.path.exists(dirpath):
+            os.makedirs(dirpath)
+
+    def __ssh_host(self, ssh_conn, host_prefix='10.20.0'):
+        try:
+            _, stdout, _ = ssh_conn.exec_command('hostname -I')
+            hosts = stdout.readline().strip().split(' ')
+            found_host = [h for h in hosts if h.startswith(host_prefix)][0]
+            return found_host
+        except Exception, e:
+            logger.error(e)
+
+    def __dump_to_file(self, operation, host, text, timestamp=None):
+        ts = (timestamp if timestamp is not None
+              else time.strftime("%Y%m%d-%H%M%S"))
+        dumpdir = os.path.join(self.ovs_dir, ts)
+        self.__mkdir_p(dumpdir)
+        fname = '{0}_{1}'.format(operation, host)
+        with open(os.path.join(dumpdir, fname), 'w') as f:
+            f.write(text)
+
+    def __remote_cmd(self, ssh_conn, cmd):
+        try:
+            _, stdout, stderr = ssh_conn.exec_command(cmd)
+            errors = stderr.readlines()
+            if len(errors) > 0:
+                host = self.__ssh_host(ssh_conn)
+                logger.error(''.join(errors))
+                raise Exception('Could not execute {0} in {1}'
+                                .format(cmd, host))
+            output = ''.join(stdout.readlines())
+            return output
+        except Exception, e:
+            logger.error('[__remote_command(ssh_client, {0})]: {1}'
+                         .format(cmd, e))
+            return None
+
+    def create_artifact_archive(self):
+        shutil.make_archive(self.ovs_dir,
+                            'zip',
+                            root_dir=os.path.dirname(self.ovs_dir),
+                            base_dir=self.ovs_dir)
+        shutil.copy2('{0}.zip'.format(self.ovs_dir), self.ft_resdir)
+
+    def ofctl_dump_flows(self, ssh_conn, br='br-int',
+                         choose_table=None, timestamp=None):
+        try:
+            cmd = 'ovs-ofctl -OOpenFlow13 dump-flows {0}'.format(br)
+            if choose_table is not None:
+                cmd = '{0} table={1}'.format(cmd, choose_table)
+            output = self.__remote_cmd(ssh_conn, cmd)
+            operation = 'ofctl_dump_flows'
+            host = self.__ssh_host(ssh_conn)
+            self.__dump_to_file(operation, host, output, timestamp=timestamp)
+            return output
+        except Exception, e:
+            logger.error('[ofctl_dump_flows(ssh_client, {0}, {1})]: {2}'
+                         .format(br, choose_table, e))
+            return None
+
+    def vsctl_show(self, ssh_conn, timestamp=None):
+        try:
+            cmd = 'ovs-vsctl show'
+            output = self.__remote_cmd(ssh_conn, cmd)
+            operation = 'vsctl_show'
+            host = self.__ssh_host(ssh_conn)
+            self.__dump_to_file(operation, host, output, timestamp=timestamp)
+            return output
+        except Exception, e:
+            logger.error('[vsctl_show(ssh_client)]: {0}'.format(e))
+            return None
+
+    def dump_ovs_logs(self, controller_clients, compute_clients,
+                      related_error=None, timestamp=None):
+        if timestamp is None:
+            timestamp = time.strftime("%Y%m%d-%H%M%S")
+
+        for controller_client in controller_clients:
+            self.ofctl_dump_flows(controller_client,
+                                  timestamp=timestamp)
+            self.vsctl_show(controller_client,
+                            timestamp=timestamp)
+
+        for compute_client in compute_clients:
+            self.ofctl_dump_flows(compute_client,
+                                  timestamp=timestamp)
+            self.vsctl_show(compute_client,
+                            timestamp=timestamp)
+
+        if related_error is not None:
+            dumpdir = os.path.join(self.ovs_dir, timestamp)
+            with open(os.path.join(dumpdir, 'error'), 'w') as f:
+                f.write(related_error)