Merge "Add jobs to build arm functest images"
authorAric Gardner <agardner@linuxfoundation.org>
Fri, 10 Feb 2017 17:30:00 +0000 (17:30 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Fri, 10 Feb 2017 17:30:00 +0000 (17:30 +0000)
69 files changed:
.gitignore
jjb/3rd_party_ci/create-apex-vms.sh
jjb/3rd_party_ci/download-netvirt-artifact.sh
jjb/3rd_party_ci/install-netvirt.sh
jjb/3rd_party_ci/odl-netvirt.yml
jjb/3rd_party_ci/postprocess-netvirt.sh
jjb/apex/apex-deploy.sh
jjb/apex/apex-snapshot-create.sh
jjb/apex/apex-snapshot-deploy.sh
jjb/apex/apex-upload-artifact.sh
jjb/apex/apex.yml
jjb/compass4nfv/compass-ci-jobs.yml
jjb/daisy4nfv/daisy4nfv-merge-jobs.yml
jjb/dovetail/dovetail-ci-jobs.yml
jjb/dovetail/dovetail-weekly-jobs.yml
jjb/fuel/fuel-daily-jobs.yml
jjb/functest/functest-ci-jobs.yml
jjb/functest/functest-cleanup.sh
jjb/functest/set-functest-env.sh
jjb/global/releng-macros.yml
jjb/global/slave-params.yml
jjb/infra/bifrost-verify.sh
jjb/openretriever/openretriever-project.yml [new file with mode: 0644]
jjb/opera/opera-daily-jobs.yml
jjb/opnfvdocs/docs-post-rtd.sh [deleted file]
jjb/opnfvdocs/docs-rtd.yaml [deleted file]
jjb/opnfvdocs/project.cfg
jjb/qtip/qtip-validate-jobs.yml
jjb/vswitchperf/vswitchperf.yml
jjb/yardstick/yardstick-ci-jobs.yml
modules/opnfv/deployment/__init__.py [moved from modules/opnfv/installer_adapters/__init__.py with 100% similarity]
modules/opnfv/deployment/apex/__init__.py [moved from modules/opnfv/installer_adapters/apex/__init__.py with 100% similarity]
modules/opnfv/deployment/apex/adapter.py [new file with mode: 0644]
modules/opnfv/deployment/example.py [new file with mode: 0644]
modules/opnfv/deployment/factory.py [new file with mode: 0644]
modules/opnfv/deployment/fuel/__init__.py [moved from modules/opnfv/installer_adapters/compass/__init__.py with 100% similarity]
modules/opnfv/deployment/fuel/adapter.py [new file with mode: 0644]
modules/opnfv/deployment/manager.py [new file with mode: 0644]
modules/opnfv/installer_adapters/InstallerHandler.py [deleted file]
modules/opnfv/installer_adapters/apex/ApexAdapter.py [deleted file]
modules/opnfv/installer_adapters/apex/example.py [deleted file]
modules/opnfv/installer_adapters/compass/CompassAdapter.py [deleted file]
modules/opnfv/installer_adapters/daisy/DaisyAdapter.py [deleted file]
modules/opnfv/installer_adapters/daisy/__init__.py [deleted file]
modules/opnfv/installer_adapters/fuel/FuelAdapter.py [deleted file]
modules/opnfv/installer_adapters/fuel/__init__.py [deleted file]
modules/opnfv/installer_adapters/fuel/example.py [deleted file]
modules/opnfv/installer_adapters/joid/JoidAdapter.py [deleted file]
modules/opnfv/installer_adapters/joid/__init__.py [deleted file]
modules/opnfv/utils/opnfv_logger.py [moved from modules/opnfv/utils/OPNFVLogger.py with 100% similarity]
modules/opnfv/utils/ssh_utils.py [moved from modules/opnfv/utils/SSHUtils.py with 95% similarity]
utils/fetch_os_creds.sh
utils/push-test-logs.sh
utils/test/vnfcatalogue/VNF_Catalogue/README.md [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/app.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/bin/www [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/package.json [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/images/3rd_party/commits.png [moved from utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/3rd_party/commits.png with 100% similarity]
utils/test/vnfcatalogue/VNF_Catalogue/public/images/logo.png [moved from utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/logo.png with 100% similarity]
utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/3rd_party/bootstrap.css [moved from utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/3rd_party/bootstrap.css with 100% similarity]
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css [moved from utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/style.css with 98% similarity]
utils/test/vnfcatalogue/VNF_Catalogue/routes/index.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/error.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade [new file with mode: 0644]
utils/test/vnfcatalogue/assets/Vnf_landing/index.html [deleted file]

index 024dfac..91ccabc 100644 (file)
@@ -26,3 +26,4 @@ wheels/
 .venv/
 venv/
 ENV/
+node_modules/
index 3f5dbd1..0744ac8 100755 (executable)
@@ -1,12 +1,8 @@
 #!/bin/bash
-set -e
+set -o errexit
+set -o nounset
+set -o pipefail
 
-if [ -z ${WORKSPACE} ]; then
-  echo "WORKSPACE is unset. Please do so."
-  exit 1
-fi
-# wipe the WORKSPACE
-/bin/rm -rf $WORKSPACE/*
 # clone opnfv sdnvpn repo
 git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git $WORKSPACE/sdnvpn
 
index be2d405..fe8066c 100755 (executable)
@@ -1,12 +1,7 @@
 #!/bin/bash
-set -e
-
-if [ -z ${WORKSPACE} ]; then
-  echo "WORKSPACE is unset. Please do so."
-  exit 1
-fi
-# wipe the WORKSPACE
-/bin/rm -rf $WORKSPACE/*
+set -o errexit
+set -o nounset
+set -o pipefail
 
 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"
index c9aa4c5..ce2a50c 100755 (executable)
@@ -1,12 +1,4 @@
 #!/bin/bash
-set -e
-
-if [ -z ${WORKSPACE} ]; then
-  echo "WORKSPACE is unset. Please set."
-  exit 1
-fi
-# wipe the WORKSPACE
-/bin/rm -rf $WORKSPACE/*
 set -o errexit
 set -o nounset
 set -o pipefail
index 6e25425..f3a4c02 100644 (file)
             max-per-node: 1
             option: 'project'
 
+    scm:
+        - git:
+            url: https://gerrit.opnfv.org/gerrit/apex
+            branches:
+                - 'origin/master'
+            timeout: 15
+            wipe-workspace: true
+
     parameters:
         - project-parameter:
             project: '{project}'
             timeout: 360
             fail: true
 
+    scm:
+        - git:
+            url: https://gerrit.opnfv.org/gerrit/apex
+            branches:
+                - 'origin/master'
+            timeout: 15
+            wipe-workspace: true
+
     parameters:
         - project-parameter:
             project: '{project}'
             name: DEPLOY_SCENARIO
             default: 'os-odl_l2-bgpvpn-noha'
             description: 'Scenario to deploy and test'
+        - string:
+            name: GS_URL
+            default: artifacts.opnfv.org/apex
+            description: "URL to Google Storage with snapshot artifacts."
 
     builders:
         - description-setter:
index 5baf378..7965142 100755 (executable)
@@ -1,12 +1,8 @@
 #!/bin/bash
-set -e
+set -o errexit
+set -o nounset
+set -o pipefail
 
-if [ -z ${WORKSPACE} ]; then
-  echo "WORKSPACE is unset. Please do so."
-  exit 1
-fi
-# wipe the WORKSPACE
-/bin/rm -rf $WORKSPACE/*
 # clone opnfv sdnvpn repo
 git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git $WORKSPACE/sdnvpn
 . $WORKSPACE/sdnvpn/odl-pipeline/odl-pipeline-common.sh
index 9535e7f..b68225f 100755 (executable)
@@ -62,6 +62,21 @@ fi
 if [ -z "$DEPLOY_SCENARIO" ]; then
   echo "Deploy scenario not set!"
   exit 1
+elif [[ "$DEPLOY_SCENARIO" == *gate* ]]; then
+  echo "Detecting Gating scenario..."
+  if [ -z "$GERRIT_EVENT_COMMENT_TEXT" ]; then
+    echo "ERROR: Gate job triggered without comment!"
+    exit 1
+  else
+    DEPLOY_SCENARIO=$(echo ${GERRIT_EVENT_COMMENT_TEXT} | grep start-gate-scenario | grep -Eo 'os-.*$')
+    if [ -z "$DEPLOY_SCENARIO" ]; then
+      echo "ERROR: Unable to detect scenario in Gerrit Comment!"
+      echo "Format of comment to trigger gate should be 'start-gate-scenario: <scenario>'"
+      exit 1
+    else
+      echo "Gate scenario detected: ${DEPLOY_SCENARIO}"
+    fi
+  fi
 fi
 
 # use local build for verify and csit promote
@@ -203,6 +218,16 @@ fi
 # start deployment
 sudo ${DEPLOY_CMD} -d ${DEPLOY_FILE} -n ${NETWORK_FILE} --debug
 
+if [[ "$JOB_NAME" == *csit* ]]; then
+  echo "CSIT job: setting host route for floating ip routing"
+  # csit route to allow docker container to reach floating ips
+  UNDERCLOUD=$(sudo virsh domifaddr undercloud | grep -Eo "[0-9\.]+{3}[0-9]+")
+  if sudo route | grep 192.168.37.128 > /dev/null; then
+    sudo route del -net 192.168.37.128 netmask 255.255.255.128
+  fi
+  sudo route add -net 192.168.37.128 netmask 255.255.255.128 gw ${UNDERCLOUD}
+fi
+
 echo
 echo "--------------------------------------------------------"
 echo "Done!"
index 5725ac6..f146dd8 100644 (file)
@@ -35,8 +35,9 @@ popd > /dev/null
 echo "Gathering introspection information"
 git clone https://gerrit.opnfv.org/gerrit/sdnvpn.git
 pushd sdnvpn/odl-pipeline/lib > /dev/null
-./tripleo_introspector.sh --out-file ${tmp_dir}/node.yaml
+sudo ./tripleo_introspector.sh --out-file ${tmp_dir}/node.yaml
 popd > /dev/null
+sudo rm -rf sdnvpn
 
 echo "Shutting down nodes"
 # Shut down nodes
@@ -63,10 +64,11 @@ for node in $nodes; do
   fi
 done
 
+pushd ${tmp_dir} > /dev/null
 echo "Gathering virsh definitions"
 # copy qcow2s, virsh definitions
 for node in $nodes; do
-  cp -f /var/lib/libvirt/images/${node}.qcow2 ./
+  sudo cp -f /var/lib/libvirt/images/${node}.qcow2 ./
   sudo virsh dumpxml ${node} > ${node}.xml
 done
 
@@ -75,11 +77,13 @@ for net in admin api external storage tenant; do
   sudo virsh net-dumpxml ${net} > ${net}.xml
 done
 
+sudo chown jenkins-ci:jenkins-ci *
+
 # tar up artifacts
 DATE=`date +%Y-%m-%d`
 tar czf ../apex-csit-snap-${DATE}.tar.gz .
 popd > /dev/null
-rm -rf ./.tmp
+sudo rm -rf ${tmp_dir}
 echo "Snapshot saved as apex-csit-snap-${DATE}.tar.gz"
 
 # update opnfv properties file
index 3bb65a0..a99955f 100644 (file)
@@ -21,8 +21,7 @@ echo "--------------------------"
 echo
 
 echo "Cleaning server"
-git clone https://gerrit.opnfv.org/gerrit/apex.git
-pushd apex/ci > /dev/null
+pushd ci > /dev/null
 sudo CONFIG=../build/ LIB=../lib ./clean.sh
 popd > /dev/null
 
index 89fd5ed..ef8ad53 100755 (executable)
@@ -81,7 +81,7 @@ uploadsnap () {
   echo "Upload complete for Snapshot"
 }
 
-if grep csit $WORKSPACE; then
+if echo $WORKSPACE | grep csit > /dev/null; then
   uploadsnap
 elif gpg2 --list-keys | grep "opnfv-helpdesk@rt.linuxfoundation.org"; then
   echo "Signing Key avaliable"
index 512112e..e3f0f53 100644 (file)
@@ -2,6 +2,7 @@
     name: apex
     jobs:
         - 'apex-verify-{stream}'
+        - 'apex-verify-gate-{stream}'
         - 'apex-verify-unit-tests-{stream}'
         - 'apex-runner-{platform}-{scenario}-{stream}'
         - 'apex-runner-cperf-{stream}'
@@ -45,6 +46,7 @@
          - 'os-odl_l3-fdio_dvr-ha'
          - 'os-odl_l3-csit-noha'
          - 'os-onos-nofeature-ha'
+         - 'gate'
 
     platform:
          - 'baremetal'
             same-node: true
         - 'apex-workspace-cleanup'
 
+# Verify Scenario Gate
+- job-template:
+    name: 'apex-verify-gate-{stream}'
+
+    node: '{verify-slave}'
+
+    concurrent: true
+
+    parameters:
+        - apex-parameter:
+            gs-pathname: '{gs-pathname}'
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - string:
+            name: GIT_BASE
+            default: https://gerrit.opnfv.org/gerrit/$PROJECT
+            description: "Used for overriding the GIT URL coming from parameters macro."
+
+    scm:
+        - git-scm-gerrit
+
+    triggers:
+        - gerrit:
+            server-name: 'gerrit.opnfv.org'
+            trigger-on:
+                - comment-added-contains-event:
+                    comment-contains-value: '^Patch Set [0-9]+: Code-Review\+2.*start-gate-scenario:.*'
+            projects:
+              - project-compare-type: 'ANT'
+                project-pattern: 'apex'
+                branches:
+                  - branch-compare-type: 'ANT'
+                    branch-pattern: '**/{branch}'
+                file-paths:
+                  - compare-type: ANT
+                    pattern: 'ci/**'
+                  - compare-type: ANT
+                    pattern: 'build/**'
+                  - compare-type: ANT
+                    pattern: 'lib/**'
+                  - compare-type: ANT
+                    pattern: 'config/**'
+
+    properties:
+        - logrotate-default
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-daily.*'
+                - 'apex-deploy.*'
+                - 'apex-build.*'
+                - 'apex-runner.*'
+                - 'apex-verify.*'
+        - throttle:
+            max-per-node: 1
+            max-total: 10
+            option: 'project'
+
+    builders:
+        - 'apex-build'
+        - trigger-builds:
+          - project: 'apex-deploy-virtual-gate-{stream}'
+            predefined-parameters: |
+              BUILD_DIRECTORY=apex-verify-gate-{stream}
+              OPNFV_CLEAN=yes
+            current-parameters: true
+            git-revision: false
+            block: true
+            same-node: true
+        - trigger-builds:
+          - project: 'functest-apex-{verify-slave}-suite-{stream}'
+            predefined-parameters: |
+              DEPLOY_SCENARIO=os-nosdn-nofeature-ha
+              FUNCTEST_SUITE_NAME=healthcheck
+            block: true
+            same-node: true
+        - 'apex-workspace-cleanup'
+
 - job-template:
     name: 'apex-runner-{platform}-{scenario}-{stream}'
 
index b749ea6..7258e89 100644 (file)
@@ -41,8 +41,8 @@
 #--------------------------------
 #        master
 #--------------------------------
-        - huawei-pod5:
-            slave-label: '{pod}'
+        - baremetal-centos:
+            slave-label: 'intel-pod8'
             os-version: 'centos7'
             <<: *master
 
 # trigger macros
 ########################
 - trigger:
-    name: 'compass-os-nosdn-nofeature-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-nosdn-nofeature-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 19 * * *'
 - trigger:
-    name: 'compass-os-odl_l2-nofeature-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-odl_l2-nofeature-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 23 * * *'
 - trigger:
-    name: 'compass-os-odl_l3-nofeature-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-odl_l3-nofeature-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 15 * * *'
 - trigger:
-    name: 'compass-os-onos-nofeature-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-onos-nofeature-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 7 * * *'
 - trigger:
-    name: 'compass-os-ocl-nofeature-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-ocl-nofeature-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 11 * * *'
 - trigger:
-    name: 'compass-os-onos-sfc-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-onos-sfc-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: '0 3 * * *'
 - trigger:
-    name: 'compass-os-odl_l2-moon-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-odl_l2-moon-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: ''
 - trigger:
-    name: 'compass-os-nosdn-kvm-ha-huawei-pod5-master-trigger'
+    name: 'compass-os-nosdn-kvm-ha-baremetal-centos-master-trigger'
     triggers:
         - timed: ''
 
index 11cdc1b..a6659b2 100644 (file)
     name: 'daisy-merge-build-macro'
     builders:
         - shell:
-            !include-raw-escape: ./daisy4nfv-basic.sh
+            !include-raw: ./daisy4nfv-basic.sh
         - shell:
-            !include-raw-escape: ./daisy4nfv-build.sh
+            !include-raw: ./daisy4nfv-build.sh
         - shell:
-            !include-raw-escape: ./daisy4nfv-upload-artifact.sh
+            !include-raw: ./daisy4nfv-upload-artifact.sh
         - shell:
-            !include-raw-escape: ./daisy4nfv-workspace-cleanup.sh
+            !include-raw: ./daisy4nfv-workspace-cleanup.sh
 
 - builder:
     name: 'daisy-merge-deploy-virtual-macro'
     builders:
         - shell:
-            !include-raw-escape: ./daisy4nfv-download-artifact.sh
+            !include-raw: ./daisy4nfv-download-artifact.sh
         - shell:
-            !include-raw-escape: ./daisy4nfv-virtual-deploy.sh
+            !include-raw: ./daisy4nfv-virtual-deploy.sh
         - shell:
-            !include-raw-escape: ./daisy4nfv-workspace-cleanup.sh
+            !include-raw: ./daisy4nfv-workspace-cleanup.sh
 
 #####################################
 # parameter macros
index 4d92980..e2a334d 100644 (file)
 #--------------------------------
 #        None-CI PODs
 #--------------------------------
-        - huawei-pod5:
-            slave-label: '{pod}'
+        - baremetal-centos:
+            slave-label: 'intel-pod8'
             SUT: compass
             auto-trigger-name: 'daily-trigger-disabled'
             <<: *master
     parameters:
         - project-parameter:
             project: '{project}'
-            branch: '{branch}'
+            branch: '{dovetail-branch}'
         - '{SUT}-defaults'
         - '{slave-label}-defaults'
         - string:
index 66c05e2..8edce42 100644 (file)
@@ -82,7 +82,7 @@
     parameters:
         - project-parameter:
             project: '{project}'
-            branch: '{branch}'
+            branch: '{dovetail-branch}'
         - '{sut}-defaults'
         - '{slave-label}-defaults'
         - string:
index 02267bd..f78c4a3 100644 (file)
 - trigger:
     name: 'fuel-os-odl_l2-nofeature-ha-baremetal-daily-master-trigger'
     triggers:
-        - timed: '' # '5 23 * * *'
+        - timed: '5 23 * * *'
 - trigger:
     name: 'fuel-os-odl_l3-nofeature-ha-baremetal-daily-master-trigger'
     triggers:
-        - timed: '' # '5 2 * * *'
+        - timed: '5 2 * * *'
+- trigger:
+    name: 'fuel-os-nosdn-ovs-ha-baremetal-daily-master-trigger'
+    triggers:
+        - timed: '5 5 * * *'
 - trigger:
     name: 'fuel-os-onos-sfc-ha-baremetal-daily-master-trigger'
     triggers:
 - trigger:
     name: 'fuel-os-odl_l2-sfc-ha-baremetal-daily-master-trigger'
     triggers:
-        - timed: '' # '5 11 * * *'
+        - timed: '5 11 * * *'
 - trigger:
     name: 'fuel-os-odl_l2-bgpvpn-ha-baremetal-daily-master-trigger'
     triggers:
 - trigger:
     name: 'fuel-os-nosdn-kvm-ha-baremetal-daily-master-trigger'
     triggers:
-        - timed: '' # '5 17 * * *'
-- trigger:
-    name: 'fuel-os-nosdn-ovs-ha-baremetal-daily-master-trigger'
-    triggers:
-        - timed: '5 20 * * *'
+        - timed: '5 17 * * *'
 - trigger:
     name: 'fuel-os-nosdn-kvm_ovs_dpdk-ha-baremetal-daily-master-trigger'
     triggers:
 - trigger:
     name: 'fuel-os-onos-sfc-noha-virtual-daily-master-trigger'
     triggers:
-        - timed: '35 20 * * *'
+        - timed: '' # '35 20 * * *'
 - trigger:
     name: 'fuel-os-onos-nofeature-noha-virtual-daily-master-trigger'
     triggers:
-        - timed: '5 23 * * *'
+        - timed: '' # '5 23 * * *'
 - trigger:
     name: 'fuel-os-odl_l2-sfc-noha-virtual-daily-master-trigger'
     triggers:
index 7174045..49901be 100644 (file)
             slave-label: '{pod}'
             installer: joid
             <<: *master
-        - huawei-pod5:
-            slave-label: '{pod}'
+        - baremetal-centos:
+            slave-label: 'intel-pod8'
             installer: compass
             <<: *master
         - nokia-pod1:
         - string:
             name: CLEAN_DOCKER_IMAGES
             default: 'false'
-            description: 'Remove downloaded docker images (opnfv/functest:*)'
+            description: 'Remove downloaded docker images (opnfv/functest*:*)'
         - functest-parameter:
             gs-pathname: '{gs-pathname}'
 
index b03d477..3ef9b90 100755 (executable)
@@ -3,8 +3,13 @@
 [[ $CI_DEBUG == true ]] && redirect="/dev/stdout" || redirect="/dev/null"
 
 echo "Cleaning up docker containers/images..."
+HOST_ARCH=$(uname -m)
 FUNCTEST_IMAGE=opnfv/functest
-# Remove containers along with image opnfv/functest:<none>
+if [ "$HOST_ARCH" = "aarch64" ]; then
+    FUNCTEST_IMAGE="${FUNCTEST_IMAGE}_${HOST_ARCH}"
+fi
+
+# Remove containers along with image opnfv/functest*:<none>
 dangling_images=($(docker images -f "dangling=true" | grep $FUNCTEST_IMAGE | awk '{print $3}'))
 if [[ -n ${dangling_images} ]]; then
     echo "  Removing $FUNCTEST_IMAGE:<none> images and their containers..."
index afd656f..5224793 100755 (executable)
@@ -70,17 +70,22 @@ envs="-e INSTALLER_TYPE=${INSTALLER_TYPE} -e INSTALLER_IP=${INSTALLER_IP} \
 
 volumes="${results_vol} ${sshkey_vol} ${stackrc_vol} ${rc_file_vol}"
 
+HOST_ARCH=$(uname -m)
+FUNCTEST_IMAGE="opnfv/functest"
+if [ "$HOST_ARCH" = "aarch64" ]; then
+    FUNCTEST_IMAGE="${FUNCTEST_IMAGE}_${HOST_ARCH}"
+fi
 
-echo "Functest: Pulling image opnfv/functest:${DOCKER_TAG}"
-docker pull opnfv/functest:$DOCKER_TAG >/dev/null
+echo "Functest: Pulling image ${FUNCTEST_IMAGE}:${DOCKER_TAG}"
+docker pull ${FUNCTEST_IMAGE}:$DOCKER_TAG >/dev/null
 
 cmd="sudo docker run --privileged=true -id ${envs} ${volumes} \
      ${custom_params} ${TESTCASE_OPTIONS} \
-     opnfv/functest:${DOCKER_TAG} /bin/bash"
+     ${FUNCTEST_IMAGE}:${DOCKER_TAG} /bin/bash"
 echo "Functest: Running docker run command: ${cmd}"
 ${cmd} >${redirect}
 sleep 5
-container_id=$(docker ps | grep "opnfv/functest:${DOCKER_TAG}" | awk '{print $1}' | head -1)
+container_id=$(docker ps | grep "${FUNCTEST_IMAGE}:${DOCKER_TAG}" | awk '{print $1}' | head -1)
 echo "Container ID=${container_id}"
 if [ -z ${container_id} ]; then
     echo "Cannot find opnfv/functest container ID ${container_id}. Please check if it is existing."
@@ -91,8 +96,8 @@ echo "Starting the container: docker start ${container_id}"
 docker start ${container_id}
 sleep 5
 docker ps >${redirect}
-if [ $(docker ps | grep "opnfv/functest:${DOCKER_TAG}" | wc -l) == 0 ]; then
-    echo "The container opnfv/functest with ID=${container_id} has not been properly started. Exiting..."
+if [ $(docker ps | grep "${FUNCTEST_IMAGE}:${DOCKER_TAG}" | wc -l) == 0 ]; then
+    echo "The container ${FUNCTEST_IMAGE} with ID=${container_id} has not been properly started. Exiting..."
     exit 1
 fi
 if [[ "$BRANCH" =~ 'brahmaputra' ]]; then
index 175d82f..9b09e31 100644 (file)
@@ -72,6 +72,7 @@
     triggers:
         - timed: ''
 
+# NOTE: unused macro, but we may use this for some jobs.
 - trigger:
     name: gerrit-trigger-patchset-created
     triggers:
index 546c75d..429828e 100644 (file)
             default: https://gerrit.opnfv.org/gerrit/$PROJECT
             description: 'Git URL to use on this Jenkins Slave'
 - parameter:
-    name: 'intel-pod3-defaults'
+    name: 'intel-pod12-defaults'
     parameters:
         - node:
             name: SLAVE_NAME
             description: 'Slave name on Jenkins'
             allowed-slaves:
-                - intel-pod3
+                - intel-pod12
             default-slaves:
-                - intel-pod3
+                - intel-pod12
         - string:
             name: GIT_BASE
             default: https://gerrit.opnfv.org/gerrit/$PROJECT
             default: https://gerrit.opnfv.org/gerrit/$PROJECT
             description: 'Git URL to use on this Jenkins Slave'
 - parameter:
-    name: 'huawei-pod5-defaults'
+    name: 'intel-pod8-defaults'
     parameters:
         - node:
             name: SLAVE_NAME
             description: 'Slave name on Jenkins'
             allowed-slaves:
-                - huawei-pod5
+                - intel-pod8
             default-slaves:
-                - huawei-pod5
+                - intel-pod8
         - string:
             name: GIT_BASE
             default: https://gerrit.opnfv.org/gerrit/$PROJECT
index 94c7dac..4115ffc 100755 (executable)
@@ -24,8 +24,9 @@ function upload_logs() {
     # before we upload the new data.
     gsutil -q rm ${BIFROST_GS_URL}/index.html || true
 
+    echo "Uploading collected bifrost build logs to ${BIFROST_LOG_URL}"
+
     if [[ -d ${WORKSPACE}/logs ]]; then
-        echo "Uploading collected bifrost logs to ${BIFROST_LOG_URL}"
         pushd ${WORKSPACE}/logs &> /dev/null
         for x in *.log; do
             echo "Compressing and uploading $x"
@@ -34,7 +35,7 @@ function upload_logs() {
         popd &> /dev/null
     fi
 
-    echo "Generating the landing page"
+    echo "Generating the ${BIFROST_LOG_URL}/index.html landing page"
     cat > ${WORKSPACE}/index.html <<EOF
 <html>
 <h1>Build results for <a href=https://$GERRIT_NAME/#/c/$GERRIT_CHANGE_NUMBER/$GERRIT_PATCHSET_NUMBER>$GERRIT_NAME/$GERRIT_CHANGE_NUMBER/$GERRIT_PATCHSET_NUMBER</a></h1>
@@ -58,7 +59,7 @@ EOF
 
     # Finally, download and upload the entire build log so we can retain
     # as much build information as possible
-    echo "Uploading console output"
+    echo "Uploading the final console output"
     curl -s -L ${BIFROST_CONSOLE_LOG} > ${WORKSPACE}/build_log.txt
     gsutil -q cp -Z ${WORKSPACE}/build_log.txt ${BIFROST_GS_URL}/build_log.txt
     rm ${WORKSPACE}/build_log.txt
diff --git a/jjb/openretriever/openretriever-project.yml b/jjb/openretriever/openretriever-project.yml
new file mode 100644 (file)
index 0000000..3d53f9b
--- /dev/null
@@ -0,0 +1,62 @@
+###################################################
+# All the jobs except verify have been removed!
+# They will only be enabled on request by projects!
+###################################################
+- project:
+    name: openretriever
+
+    project: '{name}'
+
+    jobs:
+        - 'openretriever-verify-{stream}'
+
+    stream:
+        - master:
+            branch: '{stream}'
+            gs-pathname: ''
+            disabled: false
+        - danube:
+            branch: 'stable/{stream}'
+            gs-pathname: '/{stream}'
+            disabled: false
+
+- job-template:
+    name: 'openretriever-verify-{stream}'
+
+    disabled: '{obj:disabled}'
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - 'opnfv-build-ubuntu-defaults'
+
+    scm:
+        - git-scm-gerrit
+
+    triggers:
+        - gerrit:
+            server-name: 'gerrit.opnfv.org'
+            trigger-on:
+                - patchset-created-event:
+                    exclude-drafts: 'false'
+                    exclude-trivial-rebase: 'false'
+                    exclude-no-code-change: 'false'
+                - draft-published-event
+                - comment-added-contains-event:
+                    comment-contains-value: 'recheck'
+                - comment-added-contains-event:
+                    comment-contains-value: 'reverify'
+            projects:
+              - project-compare-type: 'ANT'
+                project-pattern: '{project}'
+                branches:
+                  - branch-compare-type: 'ANT'
+                    branch-pattern: '**/{branch}'
+                forbidden-file-paths:
+                  - compare-type: ANT
+                    pattern: 'docs/**|.gitignore'
+
+    builders:
+        - shell: |
+            echo "Nothing to verify!"
index f1ea1aa..d49caf1 100644 (file)
@@ -52,7 +52,7 @@
         - ssh-agent-wrapper
 
         - timeout:
-            timeout: 120
+            timeout: 240
             fail: true
 
     triggers:
diff --git a/jjb/opnfvdocs/docs-post-rtd.sh b/jjb/opnfvdocs/docs-post-rtd.sh
deleted file mode 100644 (file)
index 7faa26f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-if [ $GERRIT_BRANCH == "master" ]; then
-    RTD_BUILD_VERSION=latest
-else
-    RTD_BUILD_VERSION=${{GERRIT_BRANCH/\//-}}
-fi
-curl -X POST --data "version_slug=$RTD_BUILD_VERSION" https://readthedocs.org/build/{rtdproject}
diff --git a/jjb/opnfvdocs/docs-rtd.yaml b/jjb/opnfvdocs/docs-rtd.yaml
deleted file mode 100644 (file)
index 7ff8cd1..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-- project:
-    name: docs-rtd
-    jobs:
-        - 'docs-merge-rtd-{stream}'
-        - 'docs-verify-rtd-{stream}'
-
-    stream:
-        - danube:
-            branch: 'master'
-        - colorado:
-            branch: 'stable/colorado'
-
-    project: 'opnfvdocs'
-    rtdproject: 'opnfv'
-    # TODO: Archive Artifacts
-
-- job-template:
-    name: 'docs-merge-rtd-{stream}'
-
-    project-type: freestyle
-
-    parameters:
-        - project-parameter:
-            project: '{project}'
-            branch: '{branch}'
-    scm:
-        - git-scm
-
-    triggers:
-        - gerrit-trigger-change-merged
-
-    builders:
-        - shell: !include-raw: docs-post-rtd.sh
-
-- job-template:
-    name: 'docs-verify-rtd-{stream}'
-
-    project-type: freestyle
-
-    parameters:
-        - project-parameter:
-            project: '{project}'
-            branch: '{branch}'
-    scm:
-        - git-scm
-
-    triggers:
-        - gerrit-trigger-patchset-created:
-            server: 'gerrit.opnfv.org'
-            project: '**'
-            branch: '{branch}'
-            files: 'docs/**/*.rst'
-        - timed: 'H H * * *'
-
-    builders:
-        - shell: |
-            if [ "$GERRIT_PROJECT" != "opnfvdocs" ]; then
-                cd opnfvdocs/submodules/$GERRIT_PROJECT
-                git fetch origin $GERRIT_REFSPEC && git checkout FETCH_HEAD
-            else
-                git fetch origin $GERRIT_REFSPEC && git checkout FETCH_HEAD
-            fi
-        - shell: |
-            virtualenv $WORKSPACE/venv
-            source $WORKSPACE/venv/bin/activate
-            pip install --upgrade pip
-            pip freeze
-            pip install tox
-            tox -edocs
\ No newline at end of file
index 186e0ea..1ea05c1 100644 (file)
@@ -24,6 +24,7 @@ movie
 multisite
 octopus
 onosfw
+openretriever
 ovno
 ovsnfv
 parser
index 997fd8a..98f7ab9 100644 (file)
@@ -13,6 +13,7 @@
         branch: '{stream}'
         gs-pathname: ''
         docker-tag: latest
+
 #--------------------------------
 # JOB VARIABLES
 #--------------------------------
         - validate:
             auto-builder-name: qtip-validate-setup
             auto-trigger-name: qtip-validate-trigger
+        - experimental:
+            auto-builder-name: qtip-validate-setup
+            auto-trigger-name: experimental
+
 #--------------------------------
 # JOB LIST
 #--------------------------------
index 9364837..ef0e90a 100644 (file)
@@ -19,7 +19,7 @@
             branch: 'stable/{stream}'
             gs-pathname: '/{stream}'
             disabled: true
-            slave-label: 'intel-pod3'
+            slave-label: 'intel-pod12'
 
 - job-template:
 
@@ -31,7 +31,7 @@
         - project-parameter:
             project: '{project}'
             branch: '{branch}'
-        - 'intel-pod3-defaults'
+        - 'intel-pod12-defaults'
 
     scm:
         - git-scm
index 2c3dda9..604eaed 100644 (file)
             installer: compass
             auto-trigger-name: 'yardstick-daily-huawei-pod4-trigger'
             <<: *master
-        - huawei-pod5:
-            slave-label: '{pod}'
+        - baremetal-centos:
+            slave-label: 'intel-pod8'
             installer: compass
             auto-trigger-name: 'daily-trigger-disabled'
             <<: *master
             name: YARDSTICK_DB_BACKEND
             default: '-i 104.197.68.199:8086'
             description: 'Arguments to use in order to choose the backend DB'
-
-- parameter:
-    name: 'yardstick-params-huawei-pod5'
-    parameters:
-        - string:
-            name: YARDSTICK_DB_BACKEND
-            default: '-i 104.197.68.199:8086'
-            description: 'Arguments to use in order to choose the backend DB'
-
 - parameter:
     name: 'yardstick-params-zte-pod1'
     parameters:
diff --git a/modules/opnfv/deployment/apex/adapter.py b/modules/opnfv/deployment/apex/adapter.py
new file mode 100644 (file)
index 0000000..1b81e78
--- /dev/null
@@ -0,0 +1,93 @@
+##############################################################################
+# Copyright (c) 2017 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.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 re
+
+from opnfv.deployment import manager
+from opnfv.utils import opnfv_logger as logger
+from opnfv.utils import ssh_utils
+
+logger = logger.Logger(__name__).getLogger()
+
+
+class ApexAdapter(manager.DeploymentHandler):
+
+    def __init__(self, installer_ip, installer_user, pkey_file):
+        super(ApexAdapter, self).__init__(installer='apex',
+                                          installer_ip=installer_ip,
+                                          installer_user=installer_user,
+                                          installer_pwd=None,
+                                          pkey_file=pkey_file)
+
+    def nodes(self):
+        nodes = []
+        cmd = "source /home/stack/stackrc;nova list 2>/dev/null"
+        output = self.installer_node.run_cmd(cmd)
+        lines = output.rsplit('\n')
+        if len(lines) < 4:
+            logger.info("No nodes found in the deployment.")
+            return None
+
+        for line in lines:
+            if 'controller' in line:
+                roles = "controller"
+            elif 'compute' in line:
+                roles = "compute"
+            else:
+                continue
+            if 'Daylight' in line:
+                roles += ", OpenDaylight"
+            fields = line.split('|')
+            id = re.sub('[!| ]', '', fields[1])
+            name = re.sub('[!| ]', '', fields[2])
+            status_node = re.sub('[!| ]', '', fields[3])
+            ip = re.sub('[!| ctlplane=]', '', fields[6])
+
+            if status_node == 'ACTIVE':
+                status = manager.Node.STATUS_OK
+                ssh_client = ssh_utils.get_ssh_client(hostname=ip,
+                                                      username='heat-admin',
+                                                      pkey_file=self.pkey_file)
+            else:
+                status = manager.Node.STATUS_INACTIVE
+                ssh_client = None
+
+            node = manager.Node(id, ip, name, status, roles, ssh_client)
+            nodes.append(node)
+
+        return nodes
+
+    def get_openstack_version(self):
+        cmd = 'source overcloudrc;sudo nova-manage version'
+        result = self.installer_node.run_cmd(cmd)
+        return result
+
+    def get_sdn_version(self):
+        cmd_descr = ("sudo yum info opendaylight 2>/dev/null|"
+                     "grep Description|sed 's/^.*\: //'")
+        cmd_ver = ("sudo yum info opendaylight 2>/dev/null|"
+                   "grep Version|sed 's/^.*\: //'")
+        for node in self.nodes:
+            if 'controller' in node.get_attribute('roles'):
+                description = node.run_cmd(cmd_descr)
+                version = node.run_cmd(cmd_ver)
+                break
+
+        if description is None:
+            return None
+        else:
+            return description + ':' + version
+
+    def get_deployment_status(self):
+        cmd = 'source stackrc;openstack stack list|grep CREATE_COMPLETE'
+        result = self.installer_node.run_cmd(cmd)
+        if result is None or len(result) == 0:
+            return 'failed'
+        else:
+            return 'active'
diff --git a/modules/opnfv/deployment/example.py b/modules/opnfv/deployment/example.py
new file mode 100644 (file)
index 0000000..6a76eb9
--- /dev/null
@@ -0,0 +1,21 @@
+# This is an example of usage of this Tool
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+
+from opnfv.deployment import factory
+
+handler = factory.Factory.get_handler('apex',
+                                      '192.168.122.135',
+                                      'stack',
+                                      pkey_file='/root/.ssh/id_rsa')
+
+
+installer_node = handler.get_installer_node()
+print("Hello, I am node '%s'" % installer_node.run_cmd('hostname'))
+installer_node.get_file('/home/stack/overcloudrc', './overcloudrc')
+
+nodes = handler.get_nodes()
+for node in nodes:
+    print("Hello, I am node '%s' and my ip is %s." %
+          (node.run_cmd('hostname'), node.ip))
+
+print handler.get_deployment_info()
diff --git a/modules/opnfv/deployment/factory.py b/modules/opnfv/deployment/factory.py
new file mode 100644 (file)
index 0000000..e48a751
--- /dev/null
@@ -0,0 +1,44 @@
+##############################################################################
+# Copyright (c) 2017 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.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
+##############################################################################
+
+
+from opnfv.deployment.apex import adapter as apex_adapter
+from opnfv.deployment.fuel import adapter as fuel_adapter
+from opnfv.utils import opnfv_logger as logger
+
+logger = logger.Logger(__name__).getLogger()
+
+
+class Factory(object):
+
+    INSTALLERS = ["fuel", "apex", "compass", "joid", "daisy"]
+
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def get_handler(installer,
+                    installer_ip,
+                    installer_user,
+                    installer_pwd=None,
+                    pkey_file=None):
+
+        if installer not in Factory.INSTALLERS:
+            raise Exception("This is not an OPNFV installer.")
+
+        if installer.lower() == "apex":
+            return apex_adapter.ApexAdapter(installer_ip=installer_ip,
+                                            installer_user=installer_user,
+                                            pkey_file=pkey_file)
+        elif installer.lower() == "fuel":
+            return fuel_adapter.FuelAdapter(installer_ip=installer_ip,
+                                            installer_user=installer_user,
+                                            installer_pwd=installer_pwd)
+        else:
+            raise Exception("Installer adapter is not implemented.")
diff --git a/modules/opnfv/deployment/fuel/adapter.py b/modules/opnfv/deployment/fuel/adapter.py
new file mode 100644 (file)
index 0000000..d53966e
--- /dev/null
@@ -0,0 +1,167 @@
+##############################################################################
+# Copyright (c) 2017 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+#         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
+##############################################################################
+
+
+from opnfv.deployment import manager
+from opnfv.utils import opnfv_logger as logger
+from opnfv.utils import ssh_utils
+
+logger = logger.Logger("FuelAdapter").getLogger()
+
+
+class FuelAdapter(manager.DeploymentHandler):
+
+    def __init__(self, installer_ip, installer_user, installer_pwd):
+        super(FuelAdapter, self).__init__(installer='fuel',
+                                          installer_ip=installer_ip,
+                                          installer_user=installer_user,
+                                          installer_pwd=installer_pwd,
+                                          pkey_file=None)
+
+    def _get_clusters(self):
+        environments = []
+        output = self.runcmd_fuel_env()
+        lines = output.rsplit('\n')
+        if len(lines) < 2:
+            logger.info("No environments found in the deployment.")
+            return None
+        else:
+            fields = lines[0].rsplit(' | ')
+
+            index_id = -1
+            index_status = -1
+            index_name = -1
+            index_release_id = -1
+
+            for i in range(len(fields) - 1):
+                if "id" in fields[i]:
+                    index_id = i
+                elif "status" in fields[i]:
+                    index_status = i
+                elif "name" in fields[i]:
+                    index_name = i
+                elif "release_id" in fields[i]:
+                    index_release_id = i
+
+            # order env info
+            for i in range(2, len(lines) - 1):
+                fields = lines[i].rsplit(' | ')
+                dict = {"id": fields[index_id].strip(),
+                        "status": fields[index_status].strip(),
+                        "name": fields[index_name].strip(),
+                        "release_id": fields[index_release_id].strip()}
+                environments.append(dict)
+
+        return environments
+
+    def nodes(self, options=None):
+        nodes = []
+        cmd = 'fuel node'
+        output = self.installer_node.run_cmd(cmd)
+        lines = output.rsplit('\n')
+        if len(lines) < 2:
+            logger.info("No nodes found in the deployment.")
+            return None
+        else:
+            # get fields indexes
+            fields = lines[0].rsplit(' | ')
+
+            index_id = -1
+            index_status = -1
+            index_name = -1
+            index_cluster = -1
+            index_ip = -1
+            index_mac = -1
+            index_roles = -1
+            index_online = -1
+
+            for i in range(0, len(fields) - 1):
+                if "id" in fields[i]:
+                    index_id = i
+                elif "status" in fields[i]:
+                    index_status = i
+                elif "name" in fields[i]:
+                    index_name = i
+                elif "cluster" in fields[i]:
+                    index_cluster = i
+                elif "ip" in fields[i]:
+                    index_ip = i
+                elif "mac" in fields[i]:
+                    index_mac = i
+                elif "roles " in fields[i]:
+                    index_roles = i
+                elif "online" in fields[i]:
+                    index_online = i
+
+            # order nodes info
+            for i in range(2, len(lines) - 1):
+                fields = lines[i].rsplit(' | ')
+
+                id = fields[index_id].strip(),
+                ip = fields[index_ip].strip()
+                status_node = fields[index_status].strip()
+                name = fields[index_name].strip()
+                roles = fields[index_roles].strip()
+
+                dict = {"cluster": fields[index_cluster].strip(),
+                        "mac": fields[index_mac].strip(),
+                        "online": fields[index_online].strip()}
+
+                if status_node == 'ready':
+                    status = manager.Node.STATUS_OK
+                    proxy = {'ip': self.installer_ip,
+                             'username': self.installer_user,
+                             'password': self.installer_pwd}
+                    ssh_client = ssh_utils.get_ssh_client(hostname=ip,
+                                                          username='root',
+                                                          proxy=proxy)
+                else:
+                    status = manager.Node.STATUS_INACTIVE
+                    ssh_client = None
+
+                node = manager.Node(
+                    id, ip, name, status, roles, ssh_client, dict)
+                nodes.append(node)
+
+                # TODO: Add support for Fuel cluster selection
+                '''
+                if options and options['cluster']:
+                    if fields[index_cluster].strip() == options['cluster']:
+                '''
+
+        return nodes
+
+    def get_openstack_version(self):
+        cmd = 'source openrc;nova-manage version 2>/dev/null'
+        version = None
+        for node in self.nodes:
+            if 'controller' in node.get_attribute('roles'):
+                version = node.run_cmd(cmd)
+                break
+        return version
+
+    def get_sdn_version(self):
+        cmd = "apt-cache show opendaylight|grep Version|sed 's/^.*\: //'"
+        version = None
+        for node in self.nodes:
+            if 'controller' in node.get_attribute('roles'):
+                odl_version = node.run_cmd(cmd)
+                if odl_version:
+                    version = 'OpenDaylight ' + odl_version
+                break
+        return version
+
+    def get_deployment_status(self):
+        cmd = 'fuel env|grep operational'
+        result = self.installer_node.run_cmd(cmd)
+        if result is None or len(result) == 0:
+            return 'failed'
+        else:
+            return 'active'
diff --git a/modules/opnfv/deployment/manager.py b/modules/opnfv/deployment/manager.py
new file mode 100644 (file)
index 0000000..f0e4429
--- /dev/null
@@ -0,0 +1,299 @@
+##############################################################################
+# Copyright (c) 2017 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.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
+##############################################################################
+
+from abc import abstractmethod
+import os
+
+
+from opnfv.utils import opnfv_logger as logger
+from opnfv.utils import ssh_utils
+
+logger = logger.Logger(__name__).getLogger()
+
+
+class Deployment(object):
+
+    def __init__(self,
+                 installer,
+                 installer_ip,
+                 scenario,
+                 pod,
+                 status,
+                 openstack_version,
+                 sdn_controller,
+                 nodes=[]):
+
+        self.deployment_info = {
+            'installer': installer,
+            'installer_ip': installer_ip,
+            'scenario': scenario,
+            'pod': pod,
+            'status': status,
+            'openstack_version': openstack_version,
+            'sdn_controller': sdn_controller,
+            'nodes': nodes
+        }
+
+    def _get_openstack_release(self):
+        '''
+        Translates an openstack version into the release name
+        '''
+        os_versions = {
+            '12': 'Liberty',
+            '13': 'Mitaka',
+            '14': 'Newton',
+            '15': 'Ocata',
+            '16': 'Pike',
+            '17': 'Queens'
+        }
+        try:
+            version = self.deployment_info['openstack_version'].split('.')[0]
+            name = os_versions[version]
+            return name
+        except Exception as e:
+            return 'Unknown release'
+
+    def get_dict(self):
+        '''
+        Returns a dictionary will all the attributes
+        '''
+        return self.deployment_info
+
+    def __str__(self):
+        '''
+        Override of the str method
+        '''
+        s = '''
+        INSTALLER:    {installer}
+        SCENARIO:     {scenario}
+        INSTALLER IP: {installer_ip}
+        POD:          {pod}
+        STATUS:       {status}
+        OPENSTACK:    {openstack_version} ({openstack_release})
+        SDN:          {sdn_controller}
+        NODES:
+    '''.format(installer=self.deployment_info['installer'],
+               scenario=self.deployment_info['scenario'],
+               installer_ip=self.deployment_info['installer_ip'],
+               pod=self.deployment_info['pod'],
+               status=self.deployment_info['status'],
+               openstack_version=self.deployment_info[
+            'openstack_version'],
+            openstack_release=self._get_openstack_release(),
+            sdn_controller=self.deployment_info['sdn_controller'])
+
+        for node in self.deployment_info['nodes']:
+            s += '\t\t{node_object}\n'.format(node_object=node)
+
+        return s
+
+
+class Node(object):
+
+    STATUS_OK = 'active'
+    STATUS_INACTIVE = 'inactive'
+    STATUS_OFFLINE = 'offline'
+    STATUS_FAILED = 'failed'
+
+    def __init__(self,
+                 id,
+                 ip,
+                 name,
+                 status,
+                 roles,
+                 ssh_client,
+                 info={}):
+        self.id = id
+        self.ip = ip
+        self.name = name
+        self.status = status
+        self.ssh_client = ssh_client
+        self.roles = roles
+        self.info = info
+
+    def get_file(self, src, dest):
+        '''
+        SCP file from a node
+        '''
+        if self.status is not Node.STATUS_OK:
+            logger.info("The node %s is not active" % self.ip)
+            return 1
+        logger.info("Fetching %s from %s" % (src, self.ip))
+        get_file_result = ssh_utils.get_file(self.ssh_client, src, dest)
+        if get_file_result is None:
+            logger.error("SFTP failed to retrieve the file.")
+        else:
+            logger.info("Successfully copied %s:%s to %s" %
+                        (self.ip, src, dest))
+        return get_file_result
+
+    def put_file(self, src, dest):
+        '''
+        SCP file to a node
+        '''
+        if self.status is not Node.STATUS_OK:
+            logger.info("The node %s is not active" % self.ip)
+            return 1
+        logger.info("Copying %s to %s" % (src, self.ip))
+        put_file_result = ssh_utils.put_file(self.ssh_client, src, dest)
+        if put_file_result is None:
+            logger.error("SFTP failed to retrieve the file.")
+        else:
+            logger.info("Successfully copied %s to %s:%s" %
+                        (src, dest, self.ip))
+        return put_file_result
+
+    def run_cmd(self, cmd):
+        '''
+        Run command remotely on a node
+        '''
+        if self.status is not Node.STATUS_OK:
+            logger.info("The node %s is not active" % self.ip)
+            return 1
+        _, stdout, stderr = (self.ssh_client.exec_command(cmd))
+        error = stderr.readlines()
+        if len(error) > 0:
+            logger.error("error %s" % ''.join(error))
+            return error
+        output = ''.join(stdout.readlines()).rstrip()
+        return output
+
+    def get_dict(self):
+        '''
+        Returns a dictionary with all the attributes
+        '''
+        return {
+            'id': self.id,
+            'ip': self.ip,
+            'name': self.name,
+            'status': self.status,
+            'roles': self.roles,
+            'info': self.info
+        }
+
+    def get_attribute(self, attribute):
+        '''
+        Returns an attribute given the name
+        '''
+        return self.get_dict()[attribute]
+
+    def is_controller(self):
+        '''
+        Returns if the node is a controller
+        '''
+        if 'controller' in self.get_attribute('roles'):
+            return True
+        return False
+
+    def is_compute(self):
+        '''
+        Returns if the node is a compute
+        '''
+        if 'compute' in self.get_attribute('roles'):
+            return True
+        return False
+
+    def __str__(self):
+        return str(self.get_dict())
+
+
+class DeploymentHandler(object):
+
+    EX_OK = os.EX_OK
+    EX_ERROR = os.EX_SOFTWARE
+    FUNCTION_NOT_IMPLEMENTED = "Function not implemented by adapter!"
+
+    def __init__(self,
+                 installer,
+                 installer_ip,
+                 installer_user,
+                 installer_pwd=None,
+                 pkey_file=None):
+
+        self.installer = installer.lower()
+        self.installer_ip = installer_ip
+        self.installer_user = installer_user
+        self.installer_pwd = installer_pwd
+        self.pkey_file = pkey_file
+
+        if pkey_file is not None and not os.path.isfile(pkey_file):
+            raise Exception(
+                'The private key file %s does not exist!' % pkey_file)
+
+        self.installer_connection = ssh_utils.get_ssh_client(
+            hostname=self.installer_ip,
+            username=self.installer_user,
+            password=self.installer_pwd,
+            pkey_file=self.pkey_file)
+
+        if self.installer_connection:
+            self.installer_node = Node(id='',
+                                       ip=installer_ip,
+                                       name=installer,
+                                       status='active',
+                                       ssh_client=self.installer_connection,
+                                       roles='installer node')
+        else:
+            raise Exception(
+                'Cannot establish connection to the installer node!')
+
+        self.nodes = self.nodes()
+
+    @abstractmethod
+    def get_openstack_version(self):
+        '''
+        Returns a string of the openstack version (nova-compute)
+        '''
+        raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
+
+    @abstractmethod
+    def get_sdn_version(self):
+        '''
+        Returns a string of the sdn controller and its version, if exists
+        '''
+        raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
+
+    @abstractmethod
+    def get_deployment_status(self):
+        '''
+        Returns a string of the status of the deployment
+        '''
+        raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
+
+    @abstractmethod
+    def nodes(self, options=None):
+        '''
+            Generates a list of all the nodes in the deployment
+        '''
+        raise Exception(DeploymentHandler.FUNCTION_NOT_IMPLEMENTED)
+
+    def get_nodes(self, options=None):
+        '''
+            Returns the list of Node objects
+        '''
+        return self.nodes
+
+    def get_installer_node(self):
+        '''
+            Returns the installer node object
+        '''
+        return self.installer_node
+
+    def get_deployment_info(self):
+        '''
+            Returns an object of type Deployment
+        '''
+        return Deployment(installer=self.installer,
+                          installer_ip=self.installer_ip,
+                          scenario=os.getenv('DEPLOY_SCENARIO', 'Unknown'),
+                          status=self.get_deployment_status(),
+                          pod=os.getenv('NODE_NAME', 'Unknown'),
+                          openstack_version=self.get_openstack_version(),
+                          sdn_controller=self.get_sdn_version(),
+                          nodes=self.nodes)
diff --git a/modules/opnfv/installer_adapters/InstallerHandler.py b/modules/opnfv/installer_adapters/InstallerHandler.py
deleted file mode 100644 (file)
index 6c43a46..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-##############################################################################
-# Copyright (c) 2017 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.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
-##############################################################################
-
-from opnfv.installer_adapters.fuel.FuelAdapter import FuelAdapter
-from opnfv.installer_adapters.apex.ApexAdapter import ApexAdapter
-from opnfv.installer_adapters.compass.CompassAdapter import CompassAdapter
-from opnfv.installer_adapters.joid.JoidAdapter import JoidAdapter
-from opnfv.installer_adapters.daisy.DaisyAdapter import DaisyAdapter
-
-
-INSTALLERS = ["fuel", "apex", "compass", "joid", "daisy"]
-
-
-class InstallerHandler:
-
-    def __init__(self,
-                 installer,
-                 installer_ip,
-                 installer_user,
-                 installer_pwd=None,
-                 private_key_file=None):
-        self.installer = installer.lower()
-        self.installer_ip = installer_ip
-        self.installer_user = installer_user
-        self.installer_pwd = installer_pwd
-        self.private_key_file = private_key_file
-
-        if self.installer == INSTALLERS[0]:
-            self.InstallerAdapter = FuelAdapter(self.installer_ip,
-                                                self.installer_user,
-                                                self.installer_pwd)
-        elif self.installer == INSTALLERS[1]:
-            self.InstallerAdapter = ApexAdapter(installer_ip=self.installer_ip,
-                                                user=self.installer_user,
-                                                pkey_file=self.private_key_file)
-        elif self.installer == INSTALLERS[2]:
-            self.InstallerAdapter = CompassAdapter(self.installer_ip)
-        elif self.installer == INSTALLERS[3]:
-            self.InstallerAdapter = JoidAdapter(self.installer_ip)
-        elif self.installer == INSTALLERS[4]:
-            self.InstallerAdapter = DaisyAdapter(self.installer_ip)
-        else:
-            print("Installer %s is  not valid. "
-                  "Please use one of the followings: %s"
-                  % (self.installer, INSTALLERS))
-            exit(1)
-
-    def get_deployment_info(self):
-        return self.InstallerAdapter.get_deployment_info()
-
-    def get_nodes(self, options=None):
-        return self.InstallerAdapter.get_nodes(options=options)
-
-    def get_controller_ips(self, options=None):
-        return self.InstallerAdapter.get_controller_ips(options=options)
-
-    def get_compute_ips(self, options=None):
-        return self.InstallerAdapter.get_compute_ips(options=options)
-
-    def get_file_from_installer(self,
-                                remote_path,
-                                local_path,
-                                options=None):
-        return self.InstallerAdapter.get_file_from_installer(remote_path,
-                                                             local_path,
-                                                             options=options)
-
-    def get_file_from_controller(self,
-                                 remote_path,
-                                 local_path,
-                                 ip=None,
-                                 options=None):
-        return self.InstallerAdapter.get_file_from_controller(remote_path,
-                                                              local_path,
-                                                              ip=ip,
-                                                              options=options)
-
-    def get_all(self):
-        pass
diff --git a/modules/opnfv/installer_adapters/apex/ApexAdapter.py b/modules/opnfv/installer_adapters/apex/ApexAdapter.py
deleted file mode 100644 (file)
index 29637d7..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.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 os
-import re
-
-import opnfv.utils.SSHUtils as ssh_utils
-import opnfv.utils.OPNFVLogger as logger
-
-
-class ApexAdapter:
-
-    def __init__(self, installer_ip, pkey_file, user="stack"):
-        self.installer_ip = installer_ip
-        self.installer_user = user
-        self.pkey_file = pkey_file
-        self.installer_connection = ssh_utils.get_ssh_client(
-            self.installer_ip,
-            self.installer_user,
-            pkey_file=self.pkey_file)
-        self.logger = logger.Logger("ApexHandler").getLogger()
-
-    def runcmd_apex_installer(self, cmd):
-        _, stdout, stderr = (self.installer_connection.exec_command(cmd))
-        error = stderr.readlines()
-        if len(error) > 0:
-            self.logger.error("error %s" % ''.join(error))
-            return error
-        output = ''.join(stdout.readlines())
-        return output
-
-    def get_nodes(self):
-        nodes = []
-        output = self.runcmd_apex_installer(
-            "source /home/stack/stackrc;nova list")
-        lines = output.rsplit('\n')
-        if len(lines) < 4:
-            self.logger.info("No nodes found in the deployment.")
-            return None
-
-        for line in lines:
-            if 'controller' in line:
-                roles = "controller"
-            elif 'compute' in line:
-                roles = "compute"
-            else:
-                continue
-            if 'Daylight' in line:
-                roles = + ", OpenDaylight"
-            fields = line.split('|')
-            dict = {"id": re.sub('[!| ]', '', fields[1]),
-                    "roles": roles,
-                    "name": re.sub('[!| ]', '', fields[2]),
-                    "status": re.sub('[!| ]', '', fields[3]),
-                    "ip": re.sub('[!| ctlplane=]', '', fields[6])}
-            nodes.append(dict)
-
-        return nodes
-
-    def get_deployment_info(self):
-        str = "Deployment details:\n"
-        str += "\tINSTALLER:   Apex\n"
-        str += ("\tSCENARIO:    %s\n" %
-                os.getenv('DEPLOY_SCENARIO', 'Unknown'))
-        sdn = "None"
-
-        nodes = self.get_nodes()
-        if nodes is None:
-            self.logger.info("No nodes found in the deployment.")
-            return
-        num_nodes = len(nodes)
-        num_controllers = 0
-        num_computes = 0
-        for node in nodes:
-            if 'controller' in node['roles']:
-                num_controllers += 1
-            if 'compute' in node['roles']:
-                num_computes += 1
-            if 'Daylight' in node['name']:
-                sdn = 'OpenDaylight'
-
-        ha = str(num_controllers >= 3)
-
-        str += "\tHA:          %s\n" % ha
-        str += "\tNUM.NODES:   %s\n" % num_nodes
-        str += "\tCONTROLLERS: %s\n" % num_controllers
-        str += "\tCOMPUTES:    %s\n" % num_computes
-        str += "\tSDN CONTR.:  %s\n\n" % sdn
-
-        str += "\tNODES:\n"
-        for node in nodes:
-            str += ("\t  ID:     %s\n" % node['id'])
-            str += ("\t  Name:   %s\n" % node['name'])
-            str += ("\t  Roles:  %s\n" % node['roles'])
-            str += ("\t  Status: %s\n" % node['status'])
-            str += ("\t  IP:     %s\n\n" % node['ip'])
-
-        return str
-
-    def get_controller_ips(self, options=None):
-        nodes = self.get_nodes()
-        controllers = []
-        for node in nodes:
-            if "controller" in node["roles"]:
-                controllers.append(node['ip'])
-        return controllers
-
-    def get_compute_ips(self, options=None):
-        nodes = self.get_nodes()
-        computes = []
-        for node in nodes:
-            if "compute" in node["roles"]:
-                computes.append(node['ip'])
-        return computes
-
-    def get_file_from_installer(self, remote_path, local_path, options=None):
-        self.logger.debug("Fetching %s from Undercloud %s" %
-                          (remote_path, self.installer_ip))
-        get_file_result = ssh_utils.get_file(self.installer_connection,
-                                             remote_path,
-                                             local_path)
-        if get_file_result is None:
-            self.logger.error("SFTP failed to retrieve the file.")
-            return 1
-        self.logger.info("%s successfully copied from Undercloud to %s" %
-                         (remote_path, local_path))
-
-    def get_file_from_controller(self,
-                                 remote_path,
-                                 local_path,
-                                 ip=None,
-                                 options=None):
-        if ip is None:
-            controllers = self.get_controller_ips()
-            ip = controllers[0]
-
-        connection = ssh_utils.get_ssh_client(ip,
-                                              'heat-admin',
-                                              pkey_file=self.pkey_file)
-
-        get_file_result = ssh_utils.get_file(connection,
-                                             remote_path,
-                                             local_path)
-        if get_file_result is None:
-            self.logger.error("SFTP failed to retrieve the file.")
-            return 1
-        self.logger.info("%s successfully copied from %s to %s" %
-                         (remote_path, ip, local_path))
diff --git a/modules/opnfv/installer_adapters/apex/example.py b/modules/opnfv/installer_adapters/apex/example.py
deleted file mode 100644 (file)
index c8c4737..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# This is an example of usage of this Tool
-# Author: Jose Lausuch (jose.lausuch@ericsson.com)
-
-import opnfv.installer_adapters.InstallerHandler as ins_handler
-
-apex_handler = ins_handler.InstallerHandler(installer='apex',
-                                            installer_ip='192.168.122.135',
-                                            installer_user='stack',
-                                            private_key_file='/root/.ssh/id_rsa')
-apex_handler.get_file_from_installer(
-    '/home/stack/overcloudrc', './overcloudrc')
-
-print("\n%s\n" % apex_handler.get_deployment_info())
-
-apex_handler.get_file_from_controller(
-    '/etc/resolv.conf', './resolv.conf')
diff --git a/modules/opnfv/installer_adapters/compass/CompassAdapter.py b/modules/opnfv/installer_adapters/compass/CompassAdapter.py
deleted file mode 100644 (file)
index 47cbc64..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.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
-##############################################################################
-
-
-class CompassAdapter:
-
-    def __init__(self, installer_ip):
-        self.installer_ip = installer_ip
-
-    def get_deployment_info(self):
-        pass
-
-    def get_nodes(self):
-        pass
-
-    def get_controller_ips(self):
-        pass
-
-    def get_compute_ips(self):
-        pass
-
-    def get_file_from_installer(self, origin, target, options=None):
-        pass
-
-    def get_file_from_controller(self, origin, target, ip=None, options=None):
-        pass
diff --git a/modules/opnfv/installer_adapters/daisy/DaisyAdapter.py b/modules/opnfv/installer_adapters/daisy/DaisyAdapter.py
deleted file mode 100644 (file)
index 9b06f4c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.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
-##############################################################################
-
-
-class DaisyAdapter:
-
-    def __init__(self, installer_ip):
-        self.installer_ip = installer_ip
-
-    def get_deployment_info(self):
-        pass
-
-    def get_nodes(self):
-        pass
-
-    def get_controller_ips(self):
-        pass
-
-    def get_compute_ips(self):
-        pass
-
-    def get_file_from_installer(self, origin, target, options=None):
-        pass
-
-    def get_file_from_controller(self, origin, target, ip=None, options=None):
-        pass
diff --git a/modules/opnfv/installer_adapters/daisy/__init__.py b/modules/opnfv/installer_adapters/daisy/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/modules/opnfv/installer_adapters/fuel/FuelAdapter.py b/modules/opnfv/installer_adapters/fuel/FuelAdapter.py
deleted file mode 100644 (file)
index 8ed8f89..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.com)
-#         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.SSHUtils as ssh_utils
-import opnfv.utils.OPNFVLogger as logger
-
-
-class FuelAdapter:
-
-    def __init__(self, installer_ip, user="root", password="r00tme"):
-        self.installer_ip = installer_ip
-        self.installer_user = user
-        self.installer_password = password
-        self.installer_connection = ssh_utils.get_ssh_client(
-            installer_ip,
-            self.installer_user,
-            password=self.installer_password)
-        self.logger = logger.Logger("FuelHandler").getLogger()
-
-    def runcmd_fuel_installer(self, cmd):
-        _, stdout, stderr = (self
-                             .installer_connection
-                             .exec_command(cmd))
-        error = stderr.readlines()
-        if len(error) > 0:
-            self.logger.error("error %s" % ''.join(error))
-            return error
-        output = ''.join(stdout.readlines())
-        return output
-
-    def runcmd_fuel_nodes(self):
-        return self.runcmd_fuel_installer('fuel nodes')
-
-    def runcmd_fuel_env(self):
-        return self.runcmd_fuel_installer('fuel env')
-
-    def get_clusters(self):
-        environments = []
-        output = self.runcmd_fuel_env()
-        lines = output.rsplit('\n')
-        if len(lines) < 2:
-            self.logger.infp("No environments found in the deployment.")
-            return None
-        else:
-            fields = lines[0].rsplit(' | ')
-
-            index_id = -1
-            index_status = -1
-            index_name = -1
-            index_release_id = -1
-
-            for i in range(0, len(fields) - 1):
-                if "id" in fields[i]:
-                    index_id = i
-                elif "status" in fields[i]:
-                    index_status = i
-                elif "name" in fields[i]:
-                    index_name = i
-                elif "release_id" in fields[i]:
-                    index_release_id = i
-
-            # order env info
-            for i in range(2, len(lines) - 1):
-                fields = lines[i].rsplit(' | ')
-                dict = {"id": fields[index_id].strip(),
-                        "status": fields[index_status].strip(),
-                        "name": fields[index_name].strip(),
-                        "release_id": fields[index_release_id].strip()}
-                environments.append(dict)
-
-        return environments
-
-    def get_nodes(self, options=None):
-        nodes = []
-        output = self.runcmd_fuel_nodes()
-        lines = output.rsplit('\n')
-        if len(lines) < 2:
-            self.logger.info("No nodes found in the deployment.")
-            return None
-        else:
-            # get fields indexes
-            fields = lines[0].rsplit(' | ')
-
-            index_id = -1
-            index_status = -1
-            index_name = -1
-            index_cluster = -1
-            index_ip = -1
-            index_mac = -1
-            index_roles = -1
-            index_online = -1
-
-            for i in range(0, len(fields) - 1):
-                if "id" in fields[i]:
-                    index_id = i
-                elif "status" in fields[i]:
-                    index_status = i
-                elif "name" in fields[i]:
-                    index_name = i
-                elif "cluster" in fields[i]:
-                    index_cluster = i
-                elif "ip" in fields[i]:
-                    index_ip = i
-                elif "mac" in fields[i]:
-                    index_mac = i
-                elif "roles " in fields[i]:
-                    index_roles = i
-                elif "online" in fields[i]:
-                    index_online = i
-
-            # order nodes info
-            for i in range(2, len(lines) - 1):
-                fields = lines[i].rsplit(' | ')
-                dict = {"id": fields[index_id].strip(),
-                        "status": fields[index_status].strip(),
-                        "name": fields[index_name].strip(),
-                        "cluster": fields[index_cluster].strip(),
-                        "ip": fields[index_ip].strip(),
-                        "mac": fields[index_mac].strip(),
-                        "roles": fields[index_roles].strip(),
-                        "online": fields[index_online].strip()}
-                if options and options['cluster']:
-                    if fields[index_cluster].strip() == options['cluster']:
-                        nodes.append(dict)
-                else:
-                    nodes.append(dict)
-
-        return nodes
-
-    def get_controller_ips(self, options):
-        nodes = self.get_nodes(options=options)
-        controllers = []
-        for node in nodes:
-            if "controller" in node["roles"]:
-                controllers.append(node['ip'])
-        return controllers
-
-    def get_compute_ips(self, options=None):
-        nodes = self.get_nodes(options=options)
-        computes = []
-        for node in nodes:
-            if "compute" in node["roles"]:
-                computes.append(node['ip'])
-        return computes
-
-    def get_deployment_info(self):
-        str = "Deployment details:\n"
-        str += "\tInstaller:  Fuel\n"
-        str += "\tScenario:   Unknown\n"
-        sdn = "None"
-        clusters = self.get_clusters()
-        str += "\tN.Clusters: %s\n" % len(clusters)
-        for cluster in clusters:
-            cluster_dic = {'cluster': cluster['id']}
-            str += "\tCluster info:\n"
-            str += "\t   ID:          %s\n" % cluster['id']
-            str += "\t   NAME:        %s\n" % cluster['name']
-            str += "\t   STATUS:      %s\n" % cluster['status']
-            nodes = self.get_nodes(options=cluster_dic)
-            num_nodes = len(nodes)
-            for node in nodes:
-                if "opendaylight" in node['roles']:
-                    sdn = "OpenDaylight"
-                elif "onos" in node['roles']:
-                    sdn = "ONOS"
-            num_controllers = len(
-                self.get_controller_ips(options=cluster_dic))
-            num_computes = len(self.get_compute_ips(options=cluster_dic))
-            ha = False
-            if num_controllers > 1:
-                ha = True
-
-            str += "\t   HA:          %s\n" % ha
-            str += "\t   NUM.NODES:   %s\n" % num_nodes
-            str += "\t   CONTROLLERS: %s\n" % num_controllers
-            str += "\t   COMPUTES:    %s\n" % num_computes
-            str += "\t   SDN CONTR.:  %s\n\n" % sdn
-        str += self.runcmd_fuel_nodes()
-        return str
-
-    def get_file_from_installer(self, remote_path, local_path, options=None):
-        self.logger.debug("Fetching %s from %s" %
-                          (remote_path, self.installer_ip))
-        get_file_result = ssh_utils.get_file(self.installer_connection,
-                                             remote_path,
-                                             local_path)
-        if get_file_result is None:
-            self.logger.error("SFTP failed to retrieve the file.")
-            return 1
-        self.logger.info("%s successfully copied from Fuel to %s" %
-                         (remote_path, local_path))
-
-    def get_file_from_controller(self,
-                                 remote_path,
-                                 local_path,
-                                 ip=None,
-                                 user='root',
-                                 options=None):
-        if ip is None:
-            controllers = self.get_controller_ips(options=options)
-            if len(controllers) == 0:
-                self.logger.info("No controllers found in the deployment.")
-                return 1
-            else:
-                target_ip = controllers[0]
-        else:
-            target_ip = ip
-
-        installer_proxy = {
-            'ip': self.installer_ip,
-            'username': self.installer_user,
-            'password': self.installer_password
-        }
-        controller_conn = ssh_utils.get_ssh_client(
-            target_ip,
-            user,
-            proxy=installer_proxy)
-
-        self.logger.debug("Fetching %s from %s" %
-                          (remote_path, target_ip))
-
-        get_file_result = ssh_utils.get_file(controller_conn,
-                                             remote_path,
-                                             local_path)
-        if get_file_result is None:
-            self.logger.error("SFTP failed to retrieve the file.")
-            return 1
-        self.logger.info("%s successfully copied from %s to %s" %
-                         (remote_path, target_ip, local_path))
diff --git a/modules/opnfv/installer_adapters/fuel/__init__.py b/modules/opnfv/installer_adapters/fuel/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/modules/opnfv/installer_adapters/fuel/example.py b/modules/opnfv/installer_adapters/fuel/example.py
deleted file mode 100644 (file)
index 7fea4df..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# This is an example of usage of this Tool
-# Author: Jose Lausuch (jose.lausuch@ericsson.com)
-
-import opnfv.installer_adapters.InstallerHandler as ins_handler
-
-fuel_handler = ins_handler.InstallerHandler(installer='fuel',
-                                            installer_ip='10.20.0.2',
-                                            installer_user='root',
-                                            installer_pwd='r00tme')
-print("Nodes in cluster 1:\n%s\n" %
-      fuel_handler.get_nodes(options={'cluster': '1'}))
-print("Nodes in cluster 2:\n%s\n" %
-      fuel_handler.get_nodes(options={'cluster': '2'}))
-print("Nodes:\n%s\n" % fuel_handler.get_nodes())
-print("Controller nodes:\n%s\n" % fuel_handler.get_controller_ips())
-print("Compute nodes:\n%s\n" % fuel_handler.get_compute_ips())
-print("\n%s\n" % fuel_handler.get_deployment_info())
-fuel_handler.get_file_from_installer('/root/deploy/dea.yaml', './dea.yaml')
-fuel_handler.get_file_from_controller(
-    '/etc/neutron/neutron.conf', './neutron.conf')
-fuel_handler.get_file_from_controller(
-    '/root/openrc', './openrc')
diff --git a/modules/opnfv/installer_adapters/joid/JoidAdapter.py b/modules/opnfv/installer_adapters/joid/JoidAdapter.py
deleted file mode 100644 (file)
index be8c2eb..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Ericsson AB and others.
-# Author: Jose Lausuch (jose.lausuch@ericsson.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
-##############################################################################
-
-
-class JoidAdapter:
-
-    def __init__(self, installer_ip):
-        self.installer_ip = installer_ip
-
-    def get_deployment_info(self):
-        pass
-
-    def get_nodes(self):
-        pass
-
-    def get_controller_ips(self):
-        pass
-
-    def get_compute_ips(self):
-        pass
-
-    def get_file_from_installer(self, origin, target, options=None):
-        pass
-
-    def get_file_from_controller(self, origin, target, ip=None, options=None):
-        pass
diff --git a/modules/opnfv/installer_adapters/joid/__init__.py b/modules/opnfv/installer_adapters/joid/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
similarity index 95%
rename from modules/opnfv/utils/SSHUtils.py
rename to modules/opnfv/utils/ssh_utils.py
index e0a830c..f900455 100644 (file)
@@ -9,11 +9,12 @@
 ##############################################################################
 
 
-import paramiko
-import opnfv.utils.OPNFVLogger as OPNFVLogger
 import os
+import paramiko
+
+from opnfv.utils import opnfv_logger as logger
 
-logger = OPNFVLogger.Logger('SSHUtils').getLogger()
+logger = logger.Logger("SSH utils").getLogger()
 
 
 def get_ssh_client(hostname,
@@ -79,7 +80,6 @@ class ProxyHopClient(paramiko.SSHClient):
     '''
 
     def __init__(self, *args, **kwargs):
-        self.logger = OPNFVLogger.Logger("ProxyHopClient").getLogger()
         self.proxy_ssh = None
         self.proxy_transport = None
         self.proxy_channel = None
@@ -129,4 +129,4 @@ class ProxyHopClient(paramiko.SSHClient):
                                                 sock=self.proxy_channel)
             os.remove(self.local_ssh_key)
         except Exception, e:
-            self.logger.error(e)
+            logger.error(e)
index c1e21f3..f00e022 100755 (executable)
@@ -144,7 +144,7 @@ elif [ "$installer_type" == "compass" ]; then
     verify_connectivity $installer_ip
     controller_ip=$(sshpass -p'root' ssh 2>/dev/null $ssh_options root@${installer_ip} \
         'mysql -ucompass -pcompass -Dcompass -e"select *  from cluster;"' \
-        | awk -F"," '{for(i=1;i<NF;i++)if($i~/\"host[1-5]\"/) {print $(i+1);break;}}'  \
+        | awk -F"," '{for(i=1;i<NF;i++)if($i~/\"127.0.0.1\"/) {print $(i+2);break;}}'  \
         | grep -oP "\d+.\d+.\d+.\d+")
 
     if [ -z $controller_ip ]; then
index ed6825b..09861c4 100644 (file)
@@ -19,16 +19,16 @@ branch=${BRANCH##*/}
 testbed=$NODE_NAME
 dir_result="${HOME}/opnfv/$project/results/${branch}"
 # src: https://wiki.opnfv.org/display/INF/Hardware+Infrastructure
-# + intel-pod3 (vsperf)
+# + intel-pod12 (vsperf)
 node_list=(\
-'lf-pod1' 'lf-pod2' 'intel-pod2' 'intel-pod3' \
+'lf-pod1' 'lf-pod2' 'intel-pod2' 'intel-pod12' \
 'intel-pod5' 'intel-pod6' 'intel-pod7' 'intel-pod8' \
 'ericsson-pod1' 'ericsson-pod2' \
 'ericsson-virtual1' 'ericsson-virtual2'  'ericsson-virtual3' \
 'ericsson-virtual4' 'ericsson-virtual5' \
 'arm-pod1' 'arm-pod3' \
 'huawei-pod1' 'huawei-pod2' 'huawei-pod3' 'huawei-pod4' 'huawei-pod5' \
-'huawei-pod6' 'huawei-pod7' \
+'huawei-pod6' 'huawei-pod7' 'huawei-pod12'\
 'huawei-virtual1' 'huawei-virtual2' 'huawei-virtual3' 'huawei-virtual4')
 
 
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/README.md b/utils/test/vnfcatalogue/VNF_Catalogue/README.md
new file mode 100644 (file)
index 0000000..32ad654
--- /dev/null
@@ -0,0 +1,12 @@
+#VNF_Catalogue Nodejs + Jade + MySql server
+
+
+## Quickstart
+
+First install the dependencies
+
+       ```npm install```
+
+Then Start the Server
+
+       ```npm start```
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/app.js b/utils/test/vnfcatalogue/VNF_Catalogue/app.js
new file mode 100644 (file)
index 0000000..0f842b6
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * 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
+ *******************************************************************************/
+
+var express = require('express');
+var path = require('path');
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var cookieParser = require('cookie-parser');
+var bodyParser = require('body-parser');
+
+var routes = require('./routes/index');
+var search_projects = require('./routes/search_projects');
+
+var app = express();
+
+// view engine setup
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'jade');
+
+// Database
+var db = require('mysql2');
+
+// uncomment after placing your favicon in /public
+//app.use(favicon(__dirname + '/public/favicon.ico'));
+app.use(logger('dev'));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(cookieParser());
+app.use(express.static(path.join(__dirname, 'public')));
+
+// Make our db accessible to our router
+app.use(function(req,res,next){
+    req.db = db;
+    next();
+});
+
+app.use('/', routes);
+app.use('/search_projects', search_projects);
+
+
+// Some Error handling for now #TODO Remove
+
+/// catch 404 and forwarding to error handler
+app.use(function(req, res, next) {
+    var err = new Error('Not Found');
+    err.status = 404;
+    next(err);
+});
+
+
+// development error handler
+// will print stacktrace
+if (app.get('env') === 'development') {
+    app.use(function(err, req, res, next) {
+        res.status(err.status || 500);
+        res.render('error', {
+            message: err.message,
+            error: err
+        });
+    });
+}
+
+// production error handler
+// no stacktraces leaked to user
+app.use(function(err, req, res, next) {
+    res.status(err.status || 500);
+    res.render('error', {
+        message: err.message,
+        error: {}
+    });
+});
+
+module.exports = app;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/bin/www b/utils/test/vnfcatalogue/VNF_Catalogue/bin/www
new file mode 100644 (file)
index 0000000..3cfbf77
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env node
+var debug = require('debug')('my-application');
+var app = require('../app');
+
+app.set('port', process.env.PORT || 3000);
+
+var server = app.listen(app.get('port'), function() {
+  debug('Express server listening on port ' + server.address().port);
+});
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/package.json b/utils/test/vnfcatalogue/VNF_Catalogue/package.json
new file mode 100644 (file)
index 0000000..7c6a867
--- /dev/null
@@ -0,0 +1,18 @@
+{
+    "name": "VNF_Catalogue",
+    "version": "0.0.1",
+    "private": true,
+    "scripts": {
+        "start": "node ./bin/www"
+    },
+    "dependencies": {
+        "body-parser": "~1.15.1",
+        "cookie-parser": "~1.4.3",
+        "debug": "~2.2.0",
+        "express": "~4.13.4",
+        "jade": "~1.11.0",
+        "morgan": "~1.7.0",
+        "serve-favicon": "~2.3.0",
+        "mysql2": "*"
+    }
+}
\ No newline at end of file
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js
new file mode 100644 (file)
index 0000000..73f16b6
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************\r
+ * Copyright (c) 2017 Kumar Rishabh and others.\r
+ *\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Apache License, Version 2.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *******************************************************************************/\r
+\r
+$(document).ready( function() {\r
+    $('#Search').click(function() {\r
+        var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);\r
+        window.location.href = '/search_projects?tags=' + tags;\r
+        return false;\r
+    });\r
+});\r
@@ -39,7 +39,7 @@ header ul li
 }
 header .logo
 {
-  background: url(../images/logo.png) no-repeat;
+  background: url(../../images/logo.png) no-repeat;
   background-size: cover;
   width: 155px;
   height: 34px;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/index.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/index.js
new file mode 100644 (file)
index 0000000..950fcd5
--- /dev/null
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* GET VNF_Catalogue Home Page. */
+router.get('/', function(req, res) {
+  res.render('index', { title: 'Express' });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js
new file mode 100644 (file)
index 0000000..49fceeb
--- /dev/null
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh and others.
+ *
+ * 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+router.get('/', function(req, res) {
+  var tags = req.param('tags');
+  console.log(tags);
+  res.render('search_projects', { title: 'Express' });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/error.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/error.jade
new file mode 100644 (file)
index 0000000..4f7fbca
--- /dev/null
@@ -0,0 +1,12 @@
+// 
+  Copyright (c) 2017 Kumar Rishabh and others.
+  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
+extends layout
+
+block content
+  h1= message
+  h2= error.status
+  pre #{error.stack}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade
new file mode 100644 (file)
index 0000000..b183f36
--- /dev/null
@@ -0,0 +1,131 @@
+doctype html
+//
+  Copyright (c) 2017 Kumar Rishabh and others.
+  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
+html(lang='en')
+  head
+    meta(charset='UTF-8')
+    title Document
+    link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
+    link(rel='stylesheet', href='/stylesheets/style.css')
+  body
+    script(type='text/javascript' src='http://code.jquery.com/jquery.min.js')
+    script(src='/javascripts/global.js')
+    header
+      ul.navigation
+        li.logo
+        li.links
+          a(href='#') Projects
+        li.links
+          a(href='#') People
+        li.links
+          a(href='#') About
+      ul.navigation-right
+        li.signup
+          a(href='#') Sign up
+        li.option or
+        li.signin
+          a(href='#') Sign in
+    .search-box
+      h1 VNF Catalogue
+      form.search-form
+        input.search-input(type='text', placeholder='Search...', id='Tags')
+        .space-10
+        button.search-button(type='submit', value='Search', id='Search') Search
+    .content
+      ul.most-menu
+        li.items.active
+          a(href='#') Most Popular
+        li.items
+          a(href='#') Most Active
+        li.items
+          a(href='#') Most Active Contributions
+      .container
+        .row
+          .box-container
+            .col-md-3
+              .content-box
+                .content-data
+                  h1.content-title AAA
+                  .box
+                    img.commit-icon(src='/images/3rd_party/commits.png')
+                    h3.commits
+                      | 4,845
+                      br
+                      | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+      footer
+        | © 2017 OPNFV
+script.
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade
new file mode 100644 (file)
index 0000000..7cc7dfc
--- /dev/null
@@ -0,0 +1,15 @@
+doctype html
+//
+  Copyright (c) 2017 Kumar Rishabh and others.
+  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
+html
+    head
+        title= title
+        link(rel='stylesheet', href='/stylesheets/style.css')
+    body
+        block content
+        script(src='http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js')
+        script(src='/javascripts/global.js')
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade
new file mode 100644 (file)
index 0000000..3076543
--- /dev/null
@@ -0,0 +1,128 @@
+doctype html
+//
+  Copyright (c) 2017 Kumar Rishabh and others.
+  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
+html(lang='en')
+  head
+    meta(charset='UTF-8')
+    title Document
+    link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
+    link(rel='stylesheet', href='/stylesheets/style.css')
+  body
+    header
+      ul.navigation
+        li.logo
+        li.links
+          a(href='#') Projects
+        li.links
+          a(href='#') People
+        li.links
+          a(href='#') About
+      ul.navigation-right
+        li.signup
+          a(href='#') Sign up
+        li.option or
+        li.signin
+          a(href='#') Sign in
+    .search-box
+      h1 VNF Catalogue
+      form.search-form
+        input.search-input(type='text', placeholder='Search...')
+        .space-10
+        button.search-button(type='submit', value='Search') Search
+    .content
+      ul.most-menu
+        li.items.active
+          a(href='#') Most Popular
+        li.items
+          a(href='#') Most Active
+        li.items
+          a(href='#') Most Active Contributions
+      .container
+        .row
+          .box-container
+            .col-md-3
+              .content-box
+                .content-data
+                  h1.content-title AAA
+                  .box
+                    img.commit-icon(src='/images/3rd_party/commits.png')
+                    h3.commits
+                      | 4,845
+                      br
+                      | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+          .col-md-3
+            .content-box
+              .content-data
+                h1.content-title AAA
+                .box
+                  img.commit-icon(src='/images/3rd_party/commits.png')
+                  h3.commits
+                    | 4,845
+                    br
+                    | commits
+      footer
+        | © 2017 OPNFV
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/index.html b/utils/test/vnfcatalogue/assets/Vnf_landing/index.html
deleted file mode 100644 (file)
index 5aebd46..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-<!--
- Copyright (c) 2017 Kumar Rishabh and others.
-
-  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
--->
-
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title>Document</title>
-  <link rel="stylesheet" href="assets/css/3rd_party/bootstrap.css">
-  <link rel="stylesheet" href="assets/css/style.css">
-</head>
-<body>
-<header>
-  <ul class="navigation">
-    <li class="logo"></li>
-    <li class="links"><a href="#">Projects</a></li>
-    <li class="links"><a href="#">People</a></li>
-    <li class="links"><a href="#">About</a></li>
-  </ul>
-  <ul class="navigation-right">
-    <li class="signup"><a href="#">Sign up</a></li>
-    <li class="option">or</li>
-    <li class="signin"><a href="#">Sign in</a></li>
-  </ul>
-</header>
-<div class="search-box">
-  <h1>VNF Catalogue</h1>
-  <form class="search-form">
-    <input type="text" placeholder="Search..." class="search-input">
-    <div class="space-10"></div>
-    <button type="submit" value="Search" class="search-button">Search</button>
-  </form>
-</div>
-<div class="content">
-<ul class="most-menu">
-  <li class="items active"><a href="#">Most Popular</a></li>
-  <li class="items"><a href="#">Most Active</a></li>
-  <li class="items"><a href="#">Most Active Contributions</a></li>
-</ul>
-<div class="container">
-  <div class="row">
-    <div class="box-container">
-      <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-          <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-      </div>
-    <div class="col-md-3">
-      <div class="content-box">
-        <div class="content-data">
-          <h1 class="content-title">AAA</h1>
-          <div class="box">
-            <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-            <h3 class="commits">4,845<br>commits</h3>
-          </div>
-        </div>
-      </div>
-    </div>
-          <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-      </div>
-            <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-      </div>
-    <div class="col-md-3">
-      <div class="content-box">
-        <div class="content-data">
-          <h1 class="content-title">AAA</h1>
-          <div class="box">
-            <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-            <h3 class="commits">4,845<br>commits</h3>
-          </div>
-        </div>
-      </div>
-    </div>
-          <div class="col-md-3">
-        <div class="content-box">
-          <div class="content-data">
-            <h1 class="content-title">AAA</h1>
-            <div class="box">
-              <img src="assets/images/3rd_party/commits.png" class="commit-icon">
-              <h3 class="commits">4,845<br>commits</h3>
-            </div>
-          </div>
-        </div>
-    </div>
-  </div>
-</div>
-<footer>
-  &copy; 2017 OPNFV
-</footer>
-</div>
-</body>
-</html>