Merge "prototypes: bifrost: Cleanup old VM console logs"
authorMarkos Chandras <mchandras@suse.de>
Fri, 3 Feb 2017 13:17:22 +0000 (13:17 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Fri, 3 Feb 2017 13:17:22 +0000 (13:17 +0000)
15 files changed:
jjb/3rd_party_ci/install-netvirt.sh
jjb/3rd_party_ci/odl-netvirt.yml
jjb/apex/apex-build.sh
jjb/apex/apex-deploy.sh
jjb/apex/apex-snapshot-create.sh [new file with mode: 0644]
jjb/apex/apex-snapshot-deploy.sh [new file with mode: 0644]
jjb/apex/apex-upload-artifact.sh
jjb/apex/apex.yml
jjb/compass4nfv/compass-dovetail-jobs.yml [new file with mode: 0644]
jjb/opera/opera-daily-jobs.yml
utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/3rd_party/bootstrap.css [new file with mode: 0755]
utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/style.css [new file with mode: 0644]
utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/3rd_party/commits.png [new file with mode: 0644]
utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/logo.png [new file with mode: 0644]
utils/test/vnfcatalogue/assets/Vnf_landing/index.html [new file with mode: 0644]

index f111d48..c9aa4c5 100755 (executable)
@@ -2,14 +2,28 @@
 set -e
 
 if [ -z ${WORKSPACE} ]; then
-  echo "WORKSPACE is unset. Please do so."
+  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
+
+SNAP_CACHE=$HOME/snap_cache
 # clone opnfv sdnvpn repo
 git clone https://gerrit.opnfv.org/gerrit/p/sdnvpn.git $WORKSPACE/sdnvpn
-. $WORKSPACE/sdnvpn/odl-pipeline/odl-pipeline-common.sh
-pushd $LIB
-./odl_reinstaller.sh --cloner-info $CLONER_INFO --odl-artifact $NETVIRT_ARTIFACT
-popd
\ No newline at end of file
+
+if [ ! -f "$NETVIRT_ARTIFACT" ]; then
+  echo "ERROR: ${NETVIRT_ARTIFACT} specified as NetVirt Artifact, but file does not exist"
+  exit 1
+fi
+
+# TODO (trozet) snapshot should have already been unpacked into cache folder
+# but we really should check the cache here, and not use a single cache folder
+# for when we support multiple jobs on a single slave
+pushd sdnvpn/odl-pipeline/lib > /dev/null
+./odl_reinstaller.sh --pod-config ${SNAP_CACHE}/node.yaml \
+  --odl-artifact ${NETVIRT_ARTIFACT} --ssh-key-file ${SNAP_CACHE}/id_rsa
+popd > /dev/null
index f07c372..6e25425 100644 (file)
 #####################################
     phase:
         - 'create-apex-vms':
-            slave-label: 'ericsson-virtual5'
+            slave-label: 'odl-netvirt-virtual-intel'
         - 'install-netvirt':
-            slave-label: 'odl-netvirt-virtual'
+            slave-label: 'odl-netvirt-virtual-intel'
         - 'postprocess':
-            slave-label: 'odl-netvirt-virtual'
+            slave-label: 'odl-netvirt-virtual-intel'
 #####################################
 # jobs
 #####################################
         - gerrit:
             server-name: 'git.opendaylight.org'
             trigger-on:
-                - comment-added-contains-event:
-                    comment-contains-value: 'https://jenkins.opendaylight.org/releng/job/netvirt-patch-test-current-carbon/.*?/ : SUCCESS'
-                - comment-added-contains-event:
-                    comment-contains-value: 'https://jenkins.opendaylight.org/releng/job/netvirt-patch-test-current-carbon/.*?/ : UNSTABLE'
#               - comment-added-contains-event:
#                   comment-contains-value: 'https://jenkins.opendaylight.org/releng/job/netvirt-patch-test-current-carbon/.*?/ : SUCCESS'
#               - comment-added-contains-event:
#                   comment-contains-value: 'https://jenkins.opendaylight.org/releng/job/netvirt-patch-test-current-carbon/.*?/ : UNSTABLE'
                 - comment-added-contains-event:
                     comment-contains-value: 'opnfv-test'
             projects:
             name: functest
             condition: SUCCESSFUL
             projects:
-                - name: 'functest-netvirt-virtual-daily-{stream}'
+                - name: 'functest-netvirt-virtual-suite-{stream}'
                   predefined-parameters: |
-                    RC_FILE_PATH=/home/jenkins/cloner-info/overcloudrc
-                    DEPLOY_SCENARIO=os-odl_l2-bgpvpn-noha
+                    DEPLOY_SCENARIO=os-odl_l3-nofeature-ha
+                    FUNCTEST_SUITE_NAME=healthcheck
                   node-parameters: true
                   kill-phase-on: FAILURE
                   abort-all-job: false
                     NETVIRT_ARTIFACT=$NETVIRT_ARTIFACT
                   node-parameters: true
                   kill-phase-on: FAILURE
-                  abort-all-job: true
+                  abort-all-job: false
 
 - job-template:
     name: 'odl-netvirt-verify-virtual-{phase}-{stream}'
         - build-blocker:
             use-build-blocker: true
             blocking-jobs:
-                - 'odl-netvirt-verify-virtual-install-.*'
-                - 'functest-netvirt-virtual-daily-.*'
+                - 'odl-netvirt-verify-virtual-create-apex-vms-.*'
+                - 'odl-netvirt-verify-virtual-install-netvirt-.*'
+                - 'functest-netvirt-virtual-suite-.*'
                 - 'odl-netvirt-verify-virtual-postprocess-.*'
             block-level: 'NODE'
 
     name: 'netvirt-verify-create-apex-vms-builder'
     builders:
         - shell:
-            !include-raw: ./create-apex-vms.sh
+            !include-raw: ../apex/apex-snapshot-deploy.sh
 - builder:
     name: 'netvirt-verify-install-netvirt-builder'
     builders:
index ee1dfb5..220d024 100755 (executable)
@@ -12,6 +12,9 @@ echo
 if echo $BUILD_TAG | grep "apex-verify" 1> /dev/null; then
   export OPNFV_ARTIFACT_VERSION=dev${BUILD_NUMBER}
   export BUILD_ARGS="-r $OPNFV_ARTIFACT_VERSION -c $CACHE_DIRECTORY"
+elif echo $BUILD_TAG | grep "csit" 1> /dev/null; then
+  export OPNFV_ARTIFACT_VERSION=csit${BUILD_NUMBER}
+  export BUILD_ARGS="-r $OPNFV_ARTIFACT_VERSION -c $CACHE_DIRECTORY"
 elif [ "$ARTIFACT_VERSION" == "daily" ]; then
   export OPNFV_ARTIFACT_VERSION=$(date -u +"%Y-%m-%d")
   export BUILD_ARGS="-r $OPNFV_ARTIFACT_VERSION -c $CACHE_DIRECTORY --iso"
index 8d5c4cb..9535e7f 100755 (executable)
@@ -15,7 +15,7 @@ if ! rpm -q wget > /dev/null; then
   sudo yum -y install wget
 fi
 
-if [[ $BUILD_DIRECTORY == *verify* ]]; then
+if [[ "$BUILD_DIRECTORY" == *verify* || "$BUILD_DIRECTORY" == *csit* ]]; then
     # Build is from a verify, use local build artifacts (not RPMs)
     cd $WORKSPACE/../${BUILD_DIRECTORY}
     WORKSPACE=$(pwd)
@@ -64,8 +64,8 @@ if [ -z "$DEPLOY_SCENARIO" ]; then
   exit 1
 fi
 
-# use local build for verify
-if [[ "$BUILD_DIRECTORY" == *verify* ]]; then
+# use local build for verify and csit promote
+if [[ "$BUILD_DIRECTORY" == *verify* || "$BUILD_DIRECTORY" == *csit* ]]; then
     if [ ! -e "${WORKSPACE}/build/lib" ]; then
       ln -s ${WORKSPACE}/lib ${WORKSPACE}/build/lib
     fi
@@ -144,7 +144,7 @@ if [ "$OPNFV_CLEAN" == 'yes' ]; then
   else
     clean_opts=''
   fi
-  if [[ "$BUILD_DIRECTORY" == *verify* ]]; then
+  if [[ "$BUILD_DIRECTORY" == *verify* || "$BUILD_DIRECTORY" == *csit* ]]; then
     sudo CONFIG=${CONFIG} LIB=${LIB} ./clean.sh ${clean_opts}
   else
     sudo CONFIG=${CONFIG} LIB=${LIB} opnfv-clean ${clean_opts}
@@ -172,6 +172,9 @@ if [[ "$JOB_NAME" == *virtual* ]]; then
     NETWORK_FILE="${NETWORK_SETTINGS_DIR}/network_settings.yaml"
   fi
   DEPLOY_CMD="${DEPLOY_CMD} -v"
+  if [[ "$JOB_NAME" == *csit* ]]; then
+    DEPLOY_CMD="${DEPLOY_CMD} -e csit-environment.yaml --virtual-computes 2"
+  fi
 else
   # settings for bare metal deployment
   if [ "$IPV6_FLAG" == "True" ]; then
diff --git a/jjb/apex/apex-snapshot-create.sh b/jjb/apex/apex-snapshot-create.sh
new file mode 100644 (file)
index 0000000..09c6a11
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+##############################################################################
+# Copyright (c) 2016 Tim Rozet (Red Hat) 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
+##############################################################################
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
+
+echo "Creating Apex snapshot..."
+echo "-------------------------"
+echo
+
+# create tmp directory
+tmp_dir=$(pwd)/.tmp
+mkdir -p ${tmp_dir}
+
+# TODO(trozet) remove this after fix goes in for tripleo_inspector to copy these
+pushd ${tmp_dir} > /dev/null
+echo "Copying overcloudrc and ssh key from Undercloud..."
+# Store overcloudrc
+UNDERCLOUD=$(sudo virsh domifaddr undercloud | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]')
+scp ${SSH_OPTIONS[@]} stack@${UNDERCLOUD}:overcloudrc ./
+# Copy out ssh key of stack from undercloud
+scp ${SSH_OPTIONS[@]} stack@${UNDERCLOUD}:.ssh/id_rsa ./
+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
+popd > /dev/null
+
+echo "Shutting down nodes"
+# Shut down nodes
+nodes=$(sudo virsh list | grep -Eo "baremetal[0-9]")
+for node in $nodes; do
+  sudo virsh shutdown ${node} --mode acpi
+done
+
+for node in $nodes; do
+  count=0
+  while [ "$count" -lt 10 ]; do
+    sleep 10
+    if sudo virsh list | grep ${node}; then
+       echo "Waiting for $node to shutdown, try $count"
+    else
+       break
+    fi
+    count=$((count+1))
+  done
+
+  if [ "$count" -ge 10 ]; then
+    echo "Node $node failed to shutdown"
+    exit 1
+  fi
+done
+
+echo "Gathering virsh definitions"
+# copy qcow2s, virsh definitions
+for node in $nodes; do
+  cp -f /var/lib/libvirt/images/${node}.qcow2 ./
+  sudo virsh dumpxml ${node} > ${node}.xml
+done
+
+# copy virsh net definitions
+for net in admin api external storage tenant; do
+  sudo virsh net-dumpxml ${net} > ${net}.xml
+done
+
+# tar up artifacts
+DATE=`date +%Y-%m-%d`
+tar czf ../apex-csit-snap-${DATE}.tar.gz .
+popd > /dev/null
+rm -rf ./.tmp
+echo "Snapshot saved as apex-csit-snap-${DATE}.tar.gz"
+
+# update opnfv properties file
+curl -O -L http://$GS_URL/snapshot.properties
+sed -i '/^OPNFV_SNAP_URL=/{h;s#=.*#='${GS_URL}'/apex-csit-snap-'${DATE}'.tar.gz#};${x;/^$/{s##OPNFV_SNAP_URL='${GS_URL}'/apex-csit-snap-'${DATE}'.tar.gz#;H};x}' snapshot.properties
+snap_sha=$(sha512sum apex-csit-snap-${DATE}.tar.gz | cut -d' ' -f1)
+sed -i '/^OPNFV_SNAP_SHA512SUM=/{h;s/=.*/='${snap_sha}'/};${x;/^$/{s//OPNFV_SNAP_SHA512SUM='${snap_sha}'/;H};x}' snapshot.properties
+echo "OPNFV_SNAP_URL=$GS_URL/apex-csit-snap-${DATE}.tar.gz"
+echo "OPNFV_SNAP_SHA512SUM=$(sha512sum apex-csit-snap-${DATE}.tar.gz | cut -d' ' -f1)"
+echo "Updated properties file: "
+cat snapshot.properties
diff --git a/jjb/apex/apex-snapshot-deploy.sh b/jjb/apex/apex-snapshot-deploy.sh
new file mode 100644 (file)
index 0000000..3bb65a0
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/env bash
+##############################################################################
+# Copyright (c) 2016 Tim Rozet (Red Hat) 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
+##############################################################################
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
+SNAP_CACHE=$HOME/snap_cache
+
+
+echo "Deploying Apex snapshot..."
+echo "--------------------------"
+echo
+
+echo "Cleaning server"
+git clone https://gerrit.opnfv.org/gerrit/apex.git
+pushd apex/ci > /dev/null
+sudo CONFIG=../build/ LIB=../lib ./clean.sh
+popd > /dev/null
+
+echo "Downloading latest snapshot properties file"
+if ! wget -O $WORKSPACE/opnfv.properties http://$GS_URL/snapshot.properties; then
+  echo "ERROR: Unable to find snapshot.properties at ${GS_URL}...exiting"
+  exit 1
+fi
+
+# find latest check sum
+latest_snap_checksum=$(cat opnfv.properties | grep OPNFV_SNAP_SHA512SUM | awk -F "=" '{print $2}')
+if [ -z "$latest_snap_checksum" ]; then
+  echo "ERROR: checksum of latest snapshot from snapshot.properties is null!"
+  exit 1
+fi
+
+local_snap_checksum=""
+
+# check snap cache directory exists
+if [ -d "$SNAP_CACHE" ]; then
+  latest_snap=$(ls -Art | grep tar.gz | tail -n 1)
+  if [ -n "$latest_snap" ]; then
+    local_snap_checksum=$(sha512sum ${latest_snap} | cut -d' ' -f1)
+  fi
+else
+  mkdir -p ${SNAP_CACHE}
+fi
+
+# compare check sum and download latest snap if not up to date
+if [ "$local_snap_checksum" -ne "$latest_snap_checksum" ]; then
+  snap_url=$(cat opnfv.properties | grep OPNFV_SNAP_URL | awk -F "=" '{print $2}')
+  if [ -z "$snap_url" ]; then
+    echo "ERROR: Snap URL from snapshot.properties is null!"
+    exit 1
+  fi
+  echo "INFO: SHA mismatch, will download latest snapshot"
+  wget --directory-prefix=${SNAP_CACHE}/ ${snap_url}
+  snap_tar=$(basename ${snap_url})
+else
+  snap_tar=${latest_snap}
+fi
+
+echo "INFO: Snapshot to be used is ${snap_tar}"
+
+# create tmp directory and unpack snap
+mkdir -p ./tmp
+pushd ./tmp > /dev/null
+tar xvf ${snap_tar}
+
+# create each network
+virsh_networks=$(ls *.xml | grep -v baremetal)
+
+if [ -z "$virsh_networks" ]; then
+  echo "ERROR: no virsh networks found in snapshot unpack"
+  exit 1
+fi
+
+for network_def in ${virsh_networks}; do
+  sudo virsh net-create ${network_def}
+  network=$(echo ${network_def} | awk -F '.' '{print $1}')
+  if ! sudo virsh net-list | grep ${network}; then
+    sudo virsh net-start ${network}
+  fi
+  echo "Checking if OVS bridge is missing for network: ${network}"
+  if ! ovs-vsctl show | grep "br-${network}"; then
+    ovs-vsctl add-br br-${network}
+    echo "OVS Bridge created: br-${network}"
+    if [ "br-${network}" == 'br-admin' ]; then
+      echo "Configuring IP 192.0.2.99 on br-admin"
+      sudo ip addr add  192.0.2.99/24 dev br-admin
+      sudo ip link set up dev br-admin
+    elif [ "br-${network}" == 'br-external' ]; then
+      echo "Configuring IP 192.168.37.99 on br-external"
+      sudo ip addr add  192.168.37.99/24 dev br-external
+      sudo ip link set up dev br-external
+    fi
+  fi
+done
+
+echo "Virsh networks up: $(virsh net-list)"
+echo "Bringing up Overcloud VMs..."
+virsh_vm_defs=$(ls baremetal*.xml)
+
+if [ -z "$virsh_vm_defs" ]; then
+  echo "ERROR: no virsh VMs found in snapshot unpack"
+  exit 1
+fi
+
+for node_def in ${virsh_vm_defs}; do
+  sudo virsh define ${node_def}
+  node=$(echo ${node_def} | awk -F '.' '{print $1}')
+  sudo cp -f ${node}.qcow2 /var/lib/libvirt/images/
+  sudo virsh start ${node}
+  echo "Node: ${node} started"
+done
+
+echo "Checking overcloudrc"
+if ! stat overcloudrc; then
+  echo "ERROR: overcloudrc does not exist in snap unpack"
+  exit 1
+fi
+
+# copy overcloudrc for functest
+mkdir -p $HOME/cloner-info
+cp -f overcloudrc $HOME/cloner-info/
+
+admin_controller_ip=$(cat overcloudrc | grep -Eo "192.0.2.[0-9]+")
+netvirt_url="http://${admin_controller_ip}:8081/restconf/operational/network-topology:network-topology/topology/netvirt:1"
+
+source overcloudrc
+counter=1
+while [ "$counter" -le 10 ]; do
+  if curl --fail ${admin_controller_ip}:80; then
+    echo "Overcloud Horizon is up...Checking if OpenDaylight NetVirt is up..."
+    if curl --fail ${netvirt_url} > /dev/null; then
+      echo "OpenDaylight is up.  Overcloud deployment complete"
+      exit 0
+    else
+      echo "OpenDaylight not yet up, try ${counter}"
+    fi
+  else
+    echo "Horizon/Apache not yet up, try ${counter}"
+  fi
+  counter=$((counter+1))
+  sleep 60
+done
+
+echo "ERROR: Deployment not up after 10 minutes...exiting."
+exit 1
index 64f13f4..89fd5ed 100755 (executable)
@@ -73,7 +73,17 @@ gsutil cp $WORKSPACE/opnfv.properties gs://$GS_URL/opnfv-$OPNFV_ARTIFACT_VERSION
 gsutil cp $WORKSPACE/opnfv.properties gs://$GS_URL/latest.properties > gsutil.latest.log
 }
 
-if gpg2 --list-keys | grep "opnfv-helpdesk@rt.linuxfoundation.org"; then
+uploadsnap () {
+  # Uploads snapshot artifact and updated properties file
+  echo "Uploading snapshot artifacts"
+  gsutil cp $WORKSPACE/apex-csit-snap-`date +%Y-%m-%d`.tar.gz gs://$GS_URL/ > gsutil.iso.log
+  gsutil cp $WORKSPACE/snapshot.properties gs://$GS_URL/snapshot.properties > gsutil.latest.log
+  echo "Upload complete for Snapshot"
+}
+
+if grep csit $WORKSPACE; then
+  uploadsnap
+elif gpg2 --list-keys | grep "opnfv-helpdesk@rt.linuxfoundation.org"; then
   echo "Signing Key avaliable"
   signiso
   uploadiso
index 9f9fffb..fcf08ed 100644 (file)
@@ -12,6 +12,7 @@
         - 'apex-daily-colorado'
         - 'apex-build-colorado'
         - 'apex-deploy-baremetal-os-odl_l2-fdio-ha-colorado'
+        - 'apex-csit-promote-daily-{stream}'
 
     # stream:    branch with - in place of / (eg. stable-arno)
     # branch:    branch (eg. stable/arno)
          - 'os-odl_l2-sfc-noha'
          - 'os-odl_l3-nofeature-ha'
          - 'os-odl-bgpvpn-ha'
-         - 'os-odl-gluon-ha'
+         - 'os-odl-gluon-noha'
          - 'os-odl_l3-fdio-noha'
          - 'os-odl_l3-fdio-ha'
          - 'os-odl_l3-fdio_dvr-noha'
          - 'os-odl_l3-fdio_dvr-ha'
+         - 'os-odl_l3-csit-noha'
          - 'os-onos-nofeature-ha'
 
     platform:
             blocking-jobs:
                 - 'apex-daily.*'
                 - 'apex-verify.*'
+                - 'apex-csit.*'
 
     builders:
         - trigger-builds:
                 - 'apex-deploy.*'
                 - 'apex-build.*'
                 - 'apex-runner.*'
+                - 'apex-csit.*'
 
     triggers:
         - 'apex-{stream}'
                 failure-threshold: 'never'
                 unstable-threshold: 'FAILURE'
 
+# CSIT promote
+- job-template:
+    name: 'apex-csit-promote-daily-{stream}'
+
+    # Job template for promoting CSIT Snapshots
+    #
+    # Required Variables:
+    #     stream:    branch with - in place of / (eg. stable)
+    #     branch:    branch (eg. stable)
+    node: '{daily-slave}'
+
+    disabled: false
+
+    scm:
+        - git-scm
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - apex-parameter:
+            gs-pathname: '{gs-pathname}'
+
+    properties:
+        - build-blocker:
+            use-build-blocker: true
+            block-level: 'NODE'
+            blocking-jobs:
+                - 'apex-verify.*'
+                - 'apex-deploy.*'
+                - 'apex-build.*'
+                - 'apex-runner.*'
+                - 'apex-daily.*'
+
+    triggers:
+        - timed: '0 12 * * 0'
+
+    builders:
+        - 'apex-build'
+        - trigger-builds:
+          - project: 'apex-deploy-virtual-os-odl_l3-csit-noha-{stream}'
+            predefined-parameters: |
+              BUILD_DIRECTORY=apex-csit-promote-daily-{stream}
+              OPNFV_CLEAN=yes
+            git-revision: false
+            block: true
+            same-node: true
+        - trigger-builds:
+          - project: 'functest-apex-{daily-slave}-suite-{stream}'
+            predefined-parameters: |
+              DEPLOY_SCENARIO=os-odl_l3-nofeature-noha
+              FUNCTEST_SUITE_NAME=tempest_smoke_serial
+            block: true
+            same-node: true
+        - shell:
+            !include-raw-escape: ./apex-snapshot-create.sh
+        - shell:
+            !include-raw-escape: ./apex-upload-artifact.sh
+
 - job-template:
     name: 'apex-gs-clean-{stream}'
 
diff --git a/jjb/compass4nfv/compass-dovetail-jobs.yml b/jjb/compass4nfv/compass-dovetail-jobs.yml
new file mode 100644 (file)
index 0000000..3337cd0
--- /dev/null
@@ -0,0 +1,209 @@
+- project:
+
+    name: 'compass-dovetail-jobs'
+    installer: 'compass'
+    project: 'compass4nfv'
+#----------------------------------
+# BRANCH ANCHORS
+#----------------------------------
+    colorado: &colorado
+        stream: colorado
+        branch: 'stable/{stream}'
+        gs-pathname: '/{stream}'
+        disabled: false
+        dovetail-branch: master
+#------------------------------------
+# POD, INSTALLER, AND BRANCH MAPPING
+#------------------------------------
+#        CI PODs
+#------------------------------------
+    pod:
+        - baremetal:
+            slave-label: compass-baremetal
+            os-version: 'trusty'
+            <<: *colorado
+#-----------------------------------
+# scenarios
+#-----------------------------------
+    scenario:
+        - 'os-nosdn-nofeature-ha':
+            disabled: false
+            auto-trigger-name: 'weekly-trigger-disabled'
+
+    jobs:
+        - 'compass-{scenario}-{pod}-weekly-{stream}'
+        - 'compass-deploy-{pod}-weekly-{stream}'
+
+########################
+# job templates
+########################
+- job-template:
+    name: 'compass-{scenario}-{pod}-weekly-{stream}'
+
+    disabled: '{obj:disabled}'
+
+    concurrent: false
+
+    properties:
+        - build-blocker:
+            use-build-blocker: true
+            blocking-jobs:
+                - 'compass-os-.*?-{pod}-daily-.*?'
+                - 'compass-os-.*?-{pod}-weekly-.*?'
+            block-level: 'NODE'
+
+    wrappers:
+        - build-name:
+            name: '$BUILD_NUMBER - Scenario: $DEPLOY_SCENARIO'
+
+    triggers:
+        - '{auto-trigger-name}'
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - compass-ci-parameter:
+            installer: '{installer}'
+            gs-pathname: '{gs-pathname}'
+        - string:
+            name: DEPLOY_SCENARIO
+            default: '{scenario}'
+        - '{slave-label}-defaults'
+        - '{installer}-defaults'
+
+    triggers:
+        - '{auto-trigger-name}'
+
+    builders:
+        - description-setter:
+            description: "POD: $NODE_NAME"
+        - trigger-builds:
+            - project: 'compass-deploy-{pod}-weekly-{stream}'
+              current-parameters: false
+              predefined-parameters: |
+                DEPLOY_SCENARIO={scenario}
+                COMPASS_OS_VERSION={os-version}
+              same-node: true
+              block: true
+        - trigger-builds:
+            - project: 'dovetail-compass-{pod}-compliance_set-weekly-{stream}'
+              current-parameters: false
+              predefined-parameters:
+                DEPLOY_SCENARIO={scenario}
+              block: true
+              same-node: true
+              block-thresholds:
+                build-step-failure-threshold: 'never'
+                failure-threshold: 'never'
+                unstable-threshold: 'FAILURE'
+        - trigger-builds:
+            - project: 'dovetail-compass-{pod}-debug-weekly-{stream}'
+              current-parameters: false
+              predefined-parameters:
+                DEPLOY_SCENARIO={scenario}
+              block: true
+              same-node: true
+              block-thresholds:
+                build-step-failure-threshold: 'never'
+                failure-threshold: 'never'
+                unstable-threshold: 'FAILURE'
+        - trigger-builds:
+            - project: 'dovetail-compass-{pod}-proposed_tests-weekly-{stream}'
+              current-parameters: false
+              predefined-parameters:
+                DEPLOY_SCENARIO={scenario}
+              block: true
+              same-node: true
+              block-thresholds:
+                build-step-failure-threshold: 'never'
+                failure-threshold: 'never'
+                unstable-threshold: 'FAILURE'
+
+- job-template:
+    name: 'compass-deploy-{pod}-weekly-{stream}'
+
+    disabled: false
+
+    concurrent: true
+
+    properties:
+        - logrotate-default
+        - throttle:
+            enabled: true
+            max-total: 4
+            max-per-node: 1
+            option: 'project'
+        - build-blocker:
+            use-build-blocker: true
+            blocking-jobs:
+                - 'compass-deploy-{pod}-daily-.*?'
+                - 'compass-deploy-{pod}-weekly-.*'
+                - 'compass-verify-deploy-.*?'
+            block-level: 'NODE'
+
+    wrappers:
+        - build-name:
+            name: '$BUILD_NUMBER - Scenario: $DEPLOY_SCENARIO'
+        - timeout:
+            timeout: 120
+            abort: true
+
+    parameters:
+        - project-parameter:
+            project: '{project}'
+            branch: '{branch}'
+        - compass-ci-parameter:
+            installer: '{installer}'
+            gs-pathname: '{gs-pathname}'
+        - '{slave-label}-defaults'
+        - '{installer}-defaults'
+
+    scm:
+        - git-scm
+
+    wrappers:
+        - build-name:
+            name: '$BUILD_NUMBER - Scenario: $DEPLOY_SCENARIO'
+
+
+    builders:
+        - description-setter:
+            description: "POD: $NODE_NAME"
+        - shell:
+            !include-raw-escape: ./compass-download-artifact.sh
+        - shell:
+            !include-raw-escape: ./compass-deploy.sh
+
+    publishers:
+        - archive:
+            artifacts: 'ansible.log'
+            allow-empty: 'true'
+            fingerprint: true
+
+########################
+# parameter macros
+########################
+- parameter:
+    name: compass-dovetail-parameter
+    parameters:
+        - string:
+            name: BUILD_DIRECTORY
+            default: $WORKSPACE/build_output
+            description: "Directory where the build artifact will be located upon the completion of the build."
+        - string:
+            name: GS_URL
+            default: '$GS_BASE{gs-pathname}'
+            description: "URL to Google Storage."
+        - choice:
+            name: COMPASS_OPENSTACK_VERSION
+            choices:
+                - 'mitaka'
+
+########################
+# trigger macros
+########################
+- trigger:
+    name: 'compass-os-nosdn-nofeature-ha-baremetal-weekly-colorado-trigger'
+    triggers:
+        - timed: ''
index a990072..47aa2a4 100644 (file)
@@ -64,7 +64,8 @@
             branch: '{branch}'
         - 'huawei-virtual7-defaults'
         - 'compass-defaults'
-        - 'opera-compass-parameter'
+        - 'opera-compass-parameter':
+            gs-pathname: '{gs-pathname}'
 
     builders:
         - description-setter:
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/3rd_party/bootstrap.css b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/3rd_party/bootstrap.css
new file mode 100755 (executable)
index 0000000..b9c2396
--- /dev/null
@@ -0,0 +1,1299 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*!
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=73eb1273dd80c57866adeff88f30374f)
+ * Config saved to config.json and https://gist.github.com/73eb1273dd80c57866adeff88f30374f
+ */
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+  font-family: sans-serif;
+  -ms-text-size-adjust: 100%;
+  -webkit-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block;
+}
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  vertical-align: baseline;
+}
+audio:not([controls]) {
+  display: none;
+  height: 0;
+}
+[hidden],
+template {
+  display: none;
+}
+a {
+  background-color: transparent;
+}
+a:active,
+a:hover {
+  outline: 0;
+}
+abbr[title] {
+  border-bottom: 1px dotted;
+}
+b,
+strong {
+  font-weight: bold;
+}
+dfn {
+  font-style: italic;
+}
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+mark {
+  background: #ff0;
+  color: #000;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup {
+  top: -0.5em;
+}
+sub {
+  bottom: -0.25em;
+}
+img {
+  border: 0;
+}
+svg:not(:root) {
+  overflow: hidden;
+}
+figure {
+  margin: 1em 40px;
+}
+hr {
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+  height: 0;
+}
+pre {
+  overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  color: inherit;
+  font: inherit;
+  margin: 0;
+}
+button {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+  cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  border: 0;
+  padding: 0;
+}
+input {
+  line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+input[type="search"] {
+  -webkit-appearance: textfield;
+  -webkit-box-sizing: content-box;
+     -moz-box-sizing: content-box;
+          box-sizing: content-box;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em;
+}
+legend {
+  border: 0;
+  padding: 0;
+}
+textarea {
+  overflow: auto;
+}
+optgroup {
+  font-weight: bold;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+td,
+th {
+  padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+  *,
+  *:before,
+  *:after {
+    background: transparent !important;
+    color: #000 !important;
+    -webkit-box-shadow: none !important;
+            box-shadow: none !important;
+    text-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  a[href]:after {
+    content: " (" attr(href) ")";
+  }
+  abbr[title]:after {
+    content: " (" attr(title) ")";
+  }
+  a[href^="#"]:after,
+  a[href^="javascript:"]:after {
+    content: "";
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  img {
+    max-width: 100% !important;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  .navbar {
+    display: none;
+  }
+  .btn > .caret,
+  .dropup > .btn > .caret {
+    border-top-color: #000 !important;
+  }
+  .label {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #ddd !important;
+  }
+}
+* {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+*:before,
+*:after {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+html {
+  font-size: 10px;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 14px;
+  line-height: 1.42857143;
+  color: #333333;
+  background-color: #ffffff;
+}
+input,
+button,
+select,
+textarea {
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+a {
+  color: #337ab7;
+  text-decoration: none;
+}
+a:hover,
+a:focus {
+  color: #23527c;
+  text-decoration: underline;
+}
+a:focus {
+  outline: 5px auto -webkit-focus-ring-color;
+  outline-offset: -2px;
+}
+figure {
+  margin: 0;
+}
+img {
+  vertical-align: middle;
+}
+.img-responsive {
+  display: block;
+  max-width: 100%;
+  height: auto;
+}
+.img-rounded {
+  border-radius: 6px;
+}
+.img-thumbnail {
+  padding: 4px;
+  line-height: 1.42857143;
+  background-color: #ffffff;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+  -webkit-transition: all 0.2s ease-in-out;
+  -o-transition: all 0.2s ease-in-out;
+  transition: all 0.2s ease-in-out;
+  display: inline-block;
+  max-width: 100%;
+  height: auto;
+}
+.img-circle {
+  border-radius: 50%;
+}
+hr {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  border: 0;
+  border-top: 1px solid #eeeeee;
+}
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  margin: -1px;
+  padding: 0;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+  position: static;
+  width: auto;
+  height: auto;
+  margin: 0;
+  overflow: visible;
+  clip: auto;
+}
+[role="button"] {
+  cursor: pointer;
+}
+.container {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+@media (min-width: 768px) {
+  .container {
+    width: 750px;
+  }
+}
+@media (min-width: 992px) {
+  .container {
+    width: 970px;
+  }
+}
+@media (min-width: 1200px) {
+  .container {
+    width: 1170px;
+  }
+}
+.container-fluid {
+  margin-right: auto;
+  margin-left: auto;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.row {
+  margin-left: -15px;
+  margin-right: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+  position: relative;
+  min-height: 1px;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+  float: left;
+}
+.col-xs-12 {
+  width: 100%;
+}
+.col-xs-11 {
+  width: 91.66666667%;
+}
+.col-xs-10 {
+  width: 83.33333333%;
+}
+.col-xs-9 {
+  width: 75%;
+}
+.col-xs-8 {
+  width: 66.66666667%;
+}
+.col-xs-7 {
+  width: 58.33333333%;
+}
+.col-xs-6 {
+  width: 50%;
+}
+.col-xs-5 {
+  width: 41.66666667%;
+}
+.col-xs-4 {
+  width: 33.33333333%;
+}
+.col-xs-3 {
+  width: 25%;
+}
+.col-xs-2 {
+  width: 16.66666667%;
+}
+.col-xs-1 {
+  width: 8.33333333%;
+}
+.col-xs-pull-12 {
+  right: 100%;
+}
+.col-xs-pull-11 {
+  right: 91.66666667%;
+}
+.col-xs-pull-10 {
+  right: 83.33333333%;
+}
+.col-xs-pull-9 {
+  right: 75%;
+}
+.col-xs-pull-8 {
+  right: 66.66666667%;
+}
+.col-xs-pull-7 {
+  right: 58.33333333%;
+}
+.col-xs-pull-6 {
+  right: 50%;
+}
+.col-xs-pull-5 {
+  right: 41.66666667%;
+}
+.col-xs-pull-4 {
+  right: 33.33333333%;
+}
+.col-xs-pull-3 {
+  right: 25%;
+}
+.col-xs-pull-2 {
+  right: 16.66666667%;
+}
+.col-xs-pull-1 {
+  right: 8.33333333%;
+}
+.col-xs-pull-0 {
+  right: auto;
+}
+.col-xs-push-12 {
+  left: 100%;
+}
+.col-xs-push-11 {
+  left: 91.66666667%;
+}
+.col-xs-push-10 {
+  left: 83.33333333%;
+}
+.col-xs-push-9 {
+  left: 75%;
+}
+.col-xs-push-8 {
+  left: 66.66666667%;
+}
+.col-xs-push-7 {
+  left: 58.33333333%;
+}
+.col-xs-push-6 {
+  left: 50%;
+}
+.col-xs-push-5 {
+  left: 41.66666667%;
+}
+.col-xs-push-4 {
+  left: 33.33333333%;
+}
+.col-xs-push-3 {
+  left: 25%;
+}
+.col-xs-push-2 {
+  left: 16.66666667%;
+}
+.col-xs-push-1 {
+  left: 8.33333333%;
+}
+.col-xs-push-0 {
+  left: auto;
+}
+.col-xs-offset-12 {
+  margin-left: 100%;
+}
+.col-xs-offset-11 {
+  margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+  margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+  margin-left: 75%;
+}
+.col-xs-offset-8 {
+  margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+  margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+  margin-left: 50%;
+}
+.col-xs-offset-5 {
+  margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+  margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+  margin-left: 25%;
+}
+.col-xs-offset-2 {
+  margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+  margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+  margin-left: 0%;
+}
+@media (min-width: 768px) {
+  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+    float: left;
+  }
+  .col-sm-12 {
+    width: 100%;
+  }
+  .col-sm-11 {
+    width: 91.66666667%;
+  }
+  .col-sm-10 {
+    width: 83.33333333%;
+  }
+  .col-sm-9 {
+    width: 75%;
+  }
+  .col-sm-8 {
+    width: 66.66666667%;
+  }
+  .col-sm-7 {
+    width: 58.33333333%;
+  }
+  .col-sm-6 {
+    width: 50%;
+  }
+  .col-sm-5 {
+    width: 41.66666667%;
+  }
+  .col-sm-4 {
+    width: 33.33333333%;
+  }
+  .col-sm-3 {
+    width: 25%;
+  }
+  .col-sm-2 {
+    width: 16.66666667%;
+  }
+  .col-sm-1 {
+    width: 8.33333333%;
+  }
+  .col-sm-pull-12 {
+    right: 100%;
+  }
+  .col-sm-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-sm-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-sm-pull-9 {
+    right: 75%;
+  }
+  .col-sm-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-sm-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-sm-pull-6 {
+    right: 50%;
+  }
+  .col-sm-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-sm-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-sm-pull-3 {
+    right: 25%;
+  }
+  .col-sm-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-sm-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-sm-pull-0 {
+    right: auto;
+  }
+  .col-sm-push-12 {
+    left: 100%;
+  }
+  .col-sm-push-11 {
+    left: 91.66666667%;
+  }
+  .col-sm-push-10 {
+    left: 83.33333333%;
+  }
+  .col-sm-push-9 {
+    left: 75%;
+  }
+  .col-sm-push-8 {
+    left: 66.66666667%;
+  }
+  .col-sm-push-7 {
+    left: 58.33333333%;
+  }
+  .col-sm-push-6 {
+    left: 50%;
+  }
+  .col-sm-push-5 {
+    left: 41.66666667%;
+  }
+  .col-sm-push-4 {
+    left: 33.33333333%;
+  }
+  .col-sm-push-3 {
+    left: 25%;
+  }
+  .col-sm-push-2 {
+    left: 16.66666667%;
+  }
+  .col-sm-push-1 {
+    left: 8.33333333%;
+  }
+  .col-sm-push-0 {
+    left: auto;
+  }
+  .col-sm-offset-12 {
+    margin-left: 100%;
+  }
+  .col-sm-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-sm-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-sm-offset-9 {
+    margin-left: 75%;
+  }
+  .col-sm-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-sm-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-sm-offset-6 {
+    margin-left: 50%;
+  }
+  .col-sm-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-sm-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-sm-offset-3 {
+    margin-left: 25%;
+  }
+  .col-sm-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-sm-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-sm-offset-0 {
+    margin-left: 0%;
+  }
+}
+@media (min-width: 992px) {
+  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+    float: left;
+  }
+  .col-md-12 {
+    width: 100%;
+  }
+  .col-md-11 {
+    width: 91.66666667%;
+  }
+  .col-md-10 {
+    width: 83.33333333%;
+  }
+  .col-md-9 {
+    width: 75%;
+  }
+  .col-md-8 {
+    width: 66.66666667%;
+  }
+  .col-md-7 {
+    width: 58.33333333%;
+  }
+  .col-md-6 {
+    width: 50%;
+  }
+  .col-md-5 {
+    width: 41.66666667%;
+  }
+  .col-md-4 {
+    width: 33.33333333%;
+  }
+  .col-md-3 {
+    width: 25%;
+  }
+  .col-md-2 {
+    width: 16.66666667%;
+  }
+  .col-md-1 {
+    width: 8.33333333%;
+  }
+  .col-md-pull-12 {
+    right: 100%;
+  }
+  .col-md-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-md-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-md-pull-9 {
+    right: 75%;
+  }
+  .col-md-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-md-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-md-pull-6 {
+    right: 50%;
+  }
+  .col-md-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-md-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-md-pull-3 {
+    right: 25%;
+  }
+  .col-md-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-md-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-md-pull-0 {
+    right: auto;
+  }
+  .col-md-push-12 {
+    left: 100%;
+  }
+  .col-md-push-11 {
+    left: 91.66666667%;
+  }
+  .col-md-push-10 {
+    left: 83.33333333%;
+  }
+  .col-md-push-9 {
+    left: 75%;
+  }
+  .col-md-push-8 {
+    left: 66.66666667%;
+  }
+  .col-md-push-7 {
+    left: 58.33333333%;
+  }
+  .col-md-push-6 {
+    left: 50%;
+  }
+  .col-md-push-5 {
+    left: 41.66666667%;
+  }
+  .col-md-push-4 {
+    left: 33.33333333%;
+  }
+  .col-md-push-3 {
+    left: 25%;
+  }
+  .col-md-push-2 {
+    left: 16.66666667%;
+  }
+  .col-md-push-1 {
+    left: 8.33333333%;
+  }
+  .col-md-push-0 {
+    left: auto;
+  }
+  .col-md-offset-12 {
+    margin-left: 100%;
+  }
+  .col-md-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-md-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-md-offset-9 {
+    margin-left: 75%;
+  }
+  .col-md-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-md-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-md-offset-6 {
+    margin-left: 50%;
+  }
+  .col-md-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-md-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-md-offset-3 {
+    margin-left: 25%;
+  }
+  .col-md-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-md-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-md-offset-0 {
+    margin-left: 0%;
+  }
+}
+@media (min-width: 1200px) {
+  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+    float: left;
+  }
+  .col-lg-12 {
+    width: 100%;
+  }
+  .col-lg-11 {
+    width: 91.66666667%;
+  }
+  .col-lg-10 {
+    width: 83.33333333%;
+  }
+  .col-lg-9 {
+    width: 75%;
+  }
+  .col-lg-8 {
+    width: 66.66666667%;
+  }
+  .col-lg-7 {
+    width: 58.33333333%;
+  }
+  .col-lg-6 {
+    width: 50%;
+  }
+  .col-lg-5 {
+    width: 41.66666667%;
+  }
+  .col-lg-4 {
+    width: 33.33333333%;
+  }
+  .col-lg-3 {
+    width: 25%;
+  }
+  .col-lg-2 {
+    width: 16.66666667%;
+  }
+  .col-lg-1 {
+    width: 8.33333333%;
+  }
+  .col-lg-pull-12 {
+    right: 100%;
+  }
+  .col-lg-pull-11 {
+    right: 91.66666667%;
+  }
+  .col-lg-pull-10 {
+    right: 83.33333333%;
+  }
+  .col-lg-pull-9 {
+    right: 75%;
+  }
+  .col-lg-pull-8 {
+    right: 66.66666667%;
+  }
+  .col-lg-pull-7 {
+    right: 58.33333333%;
+  }
+  .col-lg-pull-6 {
+    right: 50%;
+  }
+  .col-lg-pull-5 {
+    right: 41.66666667%;
+  }
+  .col-lg-pull-4 {
+    right: 33.33333333%;
+  }
+  .col-lg-pull-3 {
+    right: 25%;
+  }
+  .col-lg-pull-2 {
+    right: 16.66666667%;
+  }
+  .col-lg-pull-1 {
+    right: 8.33333333%;
+  }
+  .col-lg-pull-0 {
+    right: auto;
+  }
+  .col-lg-push-12 {
+    left: 100%;
+  }
+  .col-lg-push-11 {
+    left: 91.66666667%;
+  }
+  .col-lg-push-10 {
+    left: 83.33333333%;
+  }
+  .col-lg-push-9 {
+    left: 75%;
+  }
+  .col-lg-push-8 {
+    left: 66.66666667%;
+  }
+  .col-lg-push-7 {
+    left: 58.33333333%;
+  }
+  .col-lg-push-6 {
+    left: 50%;
+  }
+  .col-lg-push-5 {
+    left: 41.66666667%;
+  }
+  .col-lg-push-4 {
+    left: 33.33333333%;
+  }
+  .col-lg-push-3 {
+    left: 25%;
+  }
+  .col-lg-push-2 {
+    left: 16.66666667%;
+  }
+  .col-lg-push-1 {
+    left: 8.33333333%;
+  }
+  .col-lg-push-0 {
+    left: auto;
+  }
+  .col-lg-offset-12 {
+    margin-left: 100%;
+  }
+  .col-lg-offset-11 {
+    margin-left: 91.66666667%;
+  }
+  .col-lg-offset-10 {
+    margin-left: 83.33333333%;
+  }
+  .col-lg-offset-9 {
+    margin-left: 75%;
+  }
+  .col-lg-offset-8 {
+    margin-left: 66.66666667%;
+  }
+  .col-lg-offset-7 {
+    margin-left: 58.33333333%;
+  }
+  .col-lg-offset-6 {
+    margin-left: 50%;
+  }
+  .col-lg-offset-5 {
+    margin-left: 41.66666667%;
+  }
+  .col-lg-offset-4 {
+    margin-left: 33.33333333%;
+  }
+  .col-lg-offset-3 {
+    margin-left: 25%;
+  }
+  .col-lg-offset-2 {
+    margin-left: 16.66666667%;
+  }
+  .col-lg-offset-1 {
+    margin-left: 8.33333333%;
+  }
+  .col-lg-offset-0 {
+    margin-left: 0%;
+  }
+}
+.clearfix:before,
+.clearfix:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after {
+  content: " ";
+  display: table;
+}
+.clearfix:after,
+.container:after,
+.container-fluid:after,
+.row:after {
+  clear: both;
+}
+.center-block {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+.pull-right {
+  float: right !important;
+}
+.pull-left {
+  float: left !important;
+}
+.hide {
+  display: none !important;
+}
+.show {
+  display: block !important;
+}
+.invisible {
+  visibility: hidden;
+}
+.text-hide {
+  font: 0/0 a;
+  color: transparent;
+  text-shadow: none;
+  background-color: transparent;
+  border: 0;
+}
+.hidden {
+  display: none !important;
+}
+.affix {
+  position: fixed;
+}
+@-ms-viewport {
+  width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+  display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+  display: none !important;
+}
+@media (max-width: 767px) {
+  .visible-xs {
+    display: block !important;
+  }
+  table.visible-xs {
+    display: table !important;
+  }
+  tr.visible-xs {
+    display: table-row !important;
+  }
+  th.visible-xs,
+  td.visible-xs {
+    display: table-cell !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-block {
+    display: block !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-inline {
+    display: inline !important;
+  }
+}
+@media (max-width: 767px) {
+  .visible-xs-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm {
+    display: block !important;
+  }
+  table.visible-sm {
+    display: table !important;
+  }
+  tr.visible-sm {
+    display: table-row !important;
+  }
+  th.visible-sm,
+  td.visible-sm {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-block {
+    display: block !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .visible-sm-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md {
+    display: block !important;
+  }
+  table.visible-md {
+    display: table !important;
+  }
+  tr.visible-md {
+    display: table-row !important;
+  }
+  th.visible-md,
+  td.visible-md {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-block {
+    display: block !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .visible-md-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg {
+    display: block !important;
+  }
+  table.visible-lg {
+    display: table !important;
+  }
+  tr.visible-lg {
+    display: table-row !important;
+  }
+  th.visible-lg,
+  td.visible-lg {
+    display: table-cell !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-block {
+    display: block !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-inline {
+    display: inline !important;
+  }
+}
+@media (min-width: 1200px) {
+  .visible-lg-inline-block {
+    display: inline-block !important;
+  }
+}
+@media (max-width: 767px) {
+  .hidden-xs {
+    display: none !important;
+  }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+  .hidden-sm {
+    display: none !important;
+  }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+  .hidden-md {
+    display: none !important;
+  }
+}
+@media (min-width: 1200px) {
+  .hidden-lg {
+    display: none !important;
+  }
+}
+.visible-print {
+  display: none !important;
+}
+@media print {
+  .visible-print {
+    display: block !important;
+  }
+  table.visible-print {
+    display: table !important;
+  }
+  tr.visible-print {
+    display: table-row !important;
+  }
+  th.visible-print,
+  td.visible-print {
+    display: table-cell !important;
+  }
+}
+.visible-print-block {
+  display: none !important;
+}
+@media print {
+  .visible-print-block {
+    display: block !important;
+  }
+}
+.visible-print-inline {
+  display: none !important;
+}
+@media print {
+  .visible-print-inline {
+    display: inline !important;
+  }
+}
+.visible-print-inline-block {
+  display: none !important;
+}
+@media print {
+  .visible-print-inline-block {
+    display: inline-block !important;
+  }
+}
+@media print {
+  .hidden-print {
+    display: none !important;
+  }
+}
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/style.css b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/css/style.css
new file mode 100644 (file)
index 0000000..a37340c
--- /dev/null
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+@import url('https://fonts.googleapis.com/css?family=Muli:300,400,600,700,800');
+*
+{
+  color: #333333;
+  font-family: 'Muli', sans-serif;
+}
+*:focus
+{
+    outline: none;
+}
+html,
+body
+{
+  margin: 0;
+  padding: 0;
+  background: #ffffff;
+  font-family: 'Muli', sans-serif;
+}
+header
+{
+  padding: 10px 35px 0 0px;
+}
+header ul
+{
+  list-style: none;
+  display: inline-block;
+}
+header ul li
+{
+  display: inline-block;
+}
+header .logo
+{
+  background: url(../images/logo.png) no-repeat;
+  background-size: cover;
+  width: 155px;
+  height: 34px;
+  display: inline-block;
+  margin-right: 20px;
+  margin-left: 0;
+  float: left;
+}
+header ul li.links
+{
+  margin: 7px 10px 0 0;
+}
+header ul li > a,
+.content ul.most-menu li.items a
+{
+  color: #333333;
+  font-weight: 800;
+  font-size: 14px;
+  letter-spacing: 0.6px;
+  font-family: 'Muli', sans-serif;
+}
+header ul.navigation-right
+{
+  float: right;
+  padding-top: 8px;
+}
+header ul.navigation-right li.signup > a
+{
+  border: 2px solid #333333;
+  border-radius: 4px;
+  font-size: 13px;
+  font-weigt: 700;
+  padding: 9px 15px;
+}
+header ul.navigation-right li.signin > a
+{
+  border-bottom: 2px solid #333333;
+  font-size: 13px;
+  font-weight: 700;
+  padding: 9px 2px;
+}
+header ul.navigation-right li.option
+{
+  font-weight: 800;
+  padding: 0 10px;
+}
+header ul li > a:hover,
+header ul.navigation-right li.signin > a:hover,
+header ul.navigation-right li.signup > a:hover,
+header ul li > a:focus,
+header ul.navigation-right li.signin > a:focus,
+header ul.navigation-right li.signup > a:focus,
+.content ul.most-menu li a:hover,
+.content ul.most-menu li a:focus
+{
+  text-decoration: none;
+  cursor: pointer;
+  color: #333333;
+}
+header ul.navigation-right li.signup > a:hover
+{
+  background: #333333;
+  color: #ffffff;
+}
+.search-box
+{
+  text-align: center;
+  padding: 100px 0;
+}
+.search-box h1
+{
+  font-size: 30px;
+  letter-spacing: 2px;
+  color: #333333;
+  font-weight: 600;
+}
+form.search-form
+{
+  padding: 10px 20px;
+}
+form.search-form input.search-input
+{
+  font-weight: 400;
+  margin: 30px 0;
+  height: 80px;
+  padding: 10px 30px;
+  max-width: 800px;
+  width: 70%;
+  border-radius: 5px;
+  border: 2px solid #333333;
+  box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
+  color: #333333;
+  font-size: 22px;
+}
+form.search-form button.search-button
+{
+  padding: 18px 35px;
+  background: #FFF572;
+  border: 0;
+  box-shadow: 0 0 15px 1px #958F40;
+  border-radius: 1px;
+  font-size: 20px;
+  color: #393E41;
+  letter-spacing: 1px;
+  border-radius: 5px;
+  font-weight: 600;
+}
+form.search-form input:focus
+{
+  outline: none;
+}
+form.search-form input::-webkit-input-placeholder
+{
+  font-weight: 400;
+  letter-spacing: 1px;
+    color: #333333;
+}
+form.search-form input::-moz-placeholder
+{
+  font-weight: 400;
+  letter-spacing: 1px;
+    color: #333333;
+}
+form.search-form input:-moz-placeholder
+{
+  font-weight: 400;
+  letter-spacing: 5px;
+  color: #333333;
+}
+form.search-form input:-ms-input-placeholder
+{
+  font-weight: 400;
+  letter-spacing: 1px;
+  color: #333333;
+}
+.content
+{
+  height: 500px;
+  background: #f9f9f9;
+  padding: 10px 0;
+}
+.content ul.most-menu
+{
+  list-style: none;
+  text-align: center;
+  padding-bottom: 10px;
+}
+.content ul.most-menu li.items
+{
+  display: inline-block;
+  margin-right: 5px;
+  padding: 15px 25px;
+}
+.content ul.most-menu li.active
+{
+  background: #FFF572;
+}
+.content-box
+{
+  overflow: hidden;
+  padding: 20px 0 50px 0;
+  display: flex;
+  justify-content: center;
+  background: #FFFFFF;
+  box-shadow: 0 2px 3px 0 rgba(0,0,0,0.50);
+  border-bottom: 2px solid #8B19A2;
+  margin-bottom: 30px;
+}
+.content-data
+{
+  align-self: center;
+}
+.content-data h1.content-title
+{
+  font-size: 25px;
+  color: #000000;
+  letter-spacing: 1.2px;
+}
+.content-data .box
+{
+  padding: 10px 0;
+  height: 90px;
+  text-align: center;
+  border: 2px solid #4D4D4D;
+  border-radius: 2px;
+}
+.content-data .commit-icon
+{
+  width: 23px;
+  height: 16px;
+}
+.content-data .box h3.commits
+{
+  text-align: center;
+  font-size: 12px;
+  color: #333333;
+  letter-spacing: 0.03px;
+}
+footer
+{
+  font-size: 12px;
+  font-weight: 800;
+  color: #333333;
+  text-align: center;
+  padding: 20px;
+}
+.space-10
+{
+  height: 10px;
+}
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/3rd_party/commits.png b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/3rd_party/commits.png
new file mode 100644 (file)
index 0000000..1247621
Binary files /dev/null and b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/3rd_party/commits.png differ
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/logo.png b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/logo.png
new file mode 100644 (file)
index 0000000..fe18194
Binary files /dev/null and b/utils/test/vnfcatalogue/assets/Vnf_landing/assets/images/logo.png differ
diff --git a/utils/test/vnfcatalogue/assets/Vnf_landing/index.html b/utils/test/vnfcatalogue/assets/Vnf_landing/index.html
new file mode 100644 (file)
index 0000000..5aebd46
--- /dev/null
@@ -0,0 +1,145 @@
+<!--
+ 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>