Merge "Added more JJB docs"
diff --git a/jjb/cord-test/cord-test-pipeline.yaml b/jjb/cord-test/cord-test-pipeline.yaml
index 73e36a6..f0a058a 100644
--- a/jjb/cord-test/cord-test-pipeline.yaml
+++ b/jjb/cord-test/cord-test-pipeline.yaml
@@ -20,26 +20,36 @@
     stream: 'master'
     jenkins-path: 'Jenkinsfile'
 
+- job-pod-plate: &job-pod-plate
+    name: job-pod-plate
+    pod:
+      - 'qct-pod1'
+      - 'qct-pod3'
 
 - job-version-plate: &job-version-plate
     name: job-version-plate
     version:
       - 'master'
+      - 'cord-5.0'
+      - 'cord-4.1'
+      - 'cord-4.0'
 
 - job-template:
-    name: 'automated-nightly-build-qct4-cord-master'
+    name: 'build-{pod}-{version}'
     description: |
                   <!-- Managed by Jenkins Job Builder -->
-                  It builds nighlty a full POD using R-CORD at QCT - POD 4 <br /><br />
+                  It builds nighlty a full POD at {pod} <br /><br />
                   Created by Kailash Khalasi - kailash@opennetworking.org<br />
                   Copyright (c) 2017 Open Networking Foundation (ONF)
 
     <<: *test-pipe-job-boiler-plate
 
+    <<: *job-pod-plate
+
     parameters:
       - string:
          name: devNodeName
-         default: 'qct-cord-pod4'
+         default: '{pod}'
          description: 'Jenkins node name of Dev Node'
 
       - string:
@@ -54,26 +64,20 @@
 
       - string:
          name: configRepoFile
-         default: 'deployment-configs/qct-pod4.yml'
+         default: 'deployment-configs/{pod}.yml'
          description: 'The deployment config file'
 
       - string:
+         name: GERRIT_BRANCH
+         default: '{version}'
+
+      - string:
          name: RECEIPIENT
          default: 'kailash@opennetworking.org, you@opennetworking.org, suchitra@opennetworking.org'
          description: ''
 
-      - lf-infra-parameters:
-         project: 'CordTest'
-         branch: 'master'
-         stream: 'master'
-         lftools-version: '<1.0.0'
-
     concurrent: true
 
-    triggers:
-      - timed: |
-                TZ=America/Los_Angeles
-                H 21 * * *
 
     pipeline-scm:
       script-path: 'Jenkinsfile'
@@ -87,10 +91,12 @@
 - project:
     name: nightly-build-pipeline
 
-    project-name: 'automated-build-pipeline'
+    <<: *job-pod-plate
+    <<: *job-version-plate
+
+    project-name: '{name}'
 
     build-timeout: '300'
-    build-node: 'qct-cord-pod-04'
 
     jobs:
-      - 'automated-nightly-build-qct4-cord-master'
+      - 'build-{pod}-{version}'
diff --git a/jjb/cord/cord-xos-gui-unit.sh b/jjb/cord/cord-xos-gui-unit.sh
deleted file mode 100644
index 034b8da..0000000
--- a/jjb/cord/cord-xos-gui-unit.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash -ex
-
-# Install npm deps
-npm install
-
-# Install typings deps
-# typings install
-
-# Check code style
-npm run lint
-
-# Execute tests
-npm test
\ No newline at end of file
diff --git a/jjb/cord/cord-xos-gui-unit.yaml b/jjb/cord/cord-xos-gui-unit.yaml
deleted file mode 100644
index f51e863..0000000
--- a/jjb/cord/cord-xos-gui-unit.yaml
+++ /dev/null
@@ -1,104 +0,0 @@
----
-
-- job_boiler_plate: &job_boiler_plate
-    name: job-boiler-plate
-
-    project-type: freestyle
-    node: '{build-node}'
-
-    ######################
-    # Default parameters #
-    ######################
-
-    branch: master
-    submodule-recursive: false
-    git-url: '$GIT_URL/$GERRIT_PROJECT'
-
-    #####################
-    # Job Configuration #
-    #####################
-
-    properties:
-      - lf-infra-properties:
-          project: '{project}'
-          build-days-to-keep: '{build-days-to-keep}'
-
-    parameters:
-      - lf-infra-parameters:
-          project: '{project}'
-          branch: '{stream}'
-          stream: '{stream}'
-          lftools-version: '{lftools-version}'
-
-    wrappers:
-      - lf-infra-wrappers:
-          build-timeout: '{build-timeout}'
-          jenkins-ssh-credential: '{jenkins-ssh-credential}'
-
-- verify_boiler_plate: &verify_boiler_plate
-    name: verify_boiler_plate
-
-    concurrent: true
-
-    scm:
-      - lf-infra-gerrit-scm:
-          git-url: '{git-url}'
-          refspec: '$GERRIT_REFSPEC'
-          branch: '$GERRIT_BRANCH'
-          submodule-recursive: '{submodule-recursive}'
-          choosing-strategy: gerrit
-          jenkins-ssh-credential: '{jenkins-ssh-credential}'
-
-    triggers:
-      - gerrit:
-         #server-name: '{gerrit-server-name}'
-         server-name: 'CORD Project Gerrit'
-         #trigger-on: '{obj:gerrit_verify_triggers}'
-         trigger-on:
-           - patchset-created-event:
-               exclude-drafts: true
-               exclude-trivial-rebase: false
-               exclude-no-code-change: true
-           - draft-published-event
-           - comment-added-contains-event:
-               comment-contains-value: '(?i)^.*recheck$'
-         projects:
-           - project-compare-type: PLAIN
-             project-pattern: '{project}'
-             branches:
-               - branch-compare-type: ANT
-                 branch-pattern: '**/{stream}'
-             #file-paths: '{obj:gerrit_trigger_file_paths}'
-
-# workaround for lack of parameter expansion support in shell: (see above)
-- job-template:
-    #default name is global
-    name: 'cord-xos-gui-unit-{stream}'
-
-    <<: *job_boiler_plate
-    # yamllint disable-line rule:key-duplicates
-    <<: *verify_boiler_plate
-
-    builders:
-    #put shell scripts in file then make sure shell check is installed on verify vms
-      - shell: !include-raw-escape: cord-xos-gui-unit.sh
-
-- project:
-    name: cord-xos-gui-unit
-    project-name: cord-xos-gui-unit
-    project: xos-gui
-
-    build-timeout: '10'
-    build-node: '{build-node}'
-
-    # ideally this would be in defaults.yaml, but that doesn't work
-    supported_versions: &supported_versions
-      - 'master'
-      - 'cord-5.0'
-      - 'cord-4.1'
-      - 'cord-4.0'
-
-    stream: *supported_versions
-
-    jobs:
-      - 'cord-xos-gui-unit-{stream}'
diff --git a/jjb/gui-unit.yaml b/jjb/gui-unit.yaml
new file mode 100644
index 0000000..1cfd3c0
--- /dev/null
+++ b/jjb/gui-unit.yaml
@@ -0,0 +1,46 @@
+---
+# xos-gui unit test
+
+- job-template:
+    id: 'gui-unit-test'
+    name: 'verify_{project}_gui-unit-test'
+
+    description: |
+      Created by gui-unit-tests job-template from ci-management/jjb/gui-unit.yaml
+
+    triggers:
+      - cord-infra-gerrit-trigger-patchset:
+          gerrit-server-name: '{gerrit-server-name}'
+          project-regexp: '^{project}$'
+          branch-regexp: '{branch-regexp}'
+          dependency-jobs: '{dependency-jobs}'
+          file-include-regexp: '{all-files-regexp}'
+
+    properties:
+      - cord-infra-properties:
+          build-days-to-keep: '{build-days-to-keep}'
+          artifact-num-to-keep: '{artifact-num-to-keep}'
+
+    wrappers:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    scm:
+      - lf-infra-gerrit-scm:
+          git-url: '$GIT_URL/$GERRIT_PROJECT'
+          refspec: '$GERRIT_REFSPEC'
+          branch: '$GERRIT_BRANCH'
+          submodule-recursive: 'false'
+          choosing-strategy: gerrit
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+    shell: |
+      npm install
+      npm run lint
+      npm test
+
diff --git a/jjb/sonar.yaml b/jjb/sonar.yaml
new file mode 100644
index 0000000..d6adbf2
--- /dev/null
+++ b/jjb/sonar.yaml
@@ -0,0 +1,123 @@
+---
+# Sonarqube coverage tests
+#
+# There are two kinds of tests:
+#
+#  - coverage_{project}_sonarqube - run after merge to give an idea of ongoing code health
+#  - verify_{project}_sonarqube - run on patchsets, invoked in the verify/*.yaml
+#
+# JJB module docs:
+#  https://docs.openstack.org/infra/jenkins-job-builder/builders.html?highlight=sonar#builders.sonar
+#
+# Sonarqube docs:
+#  https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Jenkins
+#  https://docs.sonarqube.org/display/SCAN/Advanced+SonarQube+Scanner+Usages
+
+- project:
+    name: 'sonarqube-ongoing-coverage'
+
+    jobs:
+      - 'sonarqube-coverage':
+          branch-regexp: '{supported-branches-regexp}'
+          project:
+            - 'cord'
+            - 'maas'
+            - 'platform-install'
+            - 'xos'
+
+# run ongoing coverage tests on merged patchsets
+- job-template:
+    id: sonarqube-coverage
+    name: 'coverage_{project}_sonarqube'
+    description: |
+      Created by sonarqube-coverage job-template from ci-management/jjb/sonar.yaml
+
+    triggers:
+      - cord-infra-gerrit-trigger-merge:
+          gerrit-server-name: '{gerrit-server-name}'
+          project-regexp: '^{project}$'
+          branch-regexp: '{branch-regexp}'
+          dependency-jobs: '{dependency-jobs}'
+          file-include-regexp: '{all-files-regexp}'
+
+    properties:
+      - cord-infra-properties:
+          build-days-to-keep: '{build-days-to-keep}'
+          artifact-num-to-keep: '{artifact-num-to-keep}'
+
+    wrappers:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    scm:
+      - lf-infra-gerrit-scm:
+          git-url: '$GIT_URL/$GERRIT_PROJECT'
+          refspec: '$GERRIT_REFSPEC'
+          branch: '$GERRIT_BRANCH'
+          submodule-recursive: 'false'
+          choosing-strategy: gerrit
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+    builders:
+      - sonar:
+          sonar-name: 'sonarqube.opencord.org'
+          properties: |
+            sonar.projectKey={project}_$GERRIT_BRANCH
+            sonar.python.pylint=/usr/local/bin/pylint
+
+
+# run Sonarqube as a verification jobs on individual patchsets
+- job-template:
+    id: verify-sonarqube
+    name: 'verify_{project}_sonarqube'
+    description: |
+      Created by verify-sonarqube job-template from ci-management/jjb/sonar.yaml
+
+    triggers:
+      - cord-infra-gerrit-trigger-patchset:
+          gerrit-server-name: '{gerrit-server-name}'
+          project-regexp: '^{project}$'
+          branch-regexp: '{branch-regexp}'
+          dependency-jobs: '{dependency-jobs}'
+          file-include-regexp: '{all-files-regexp}'
+
+    properties:
+      - cord-infra-properties:
+          build-days-to-keep: '{build-days-to-keep}'
+          artifact-num-to-keep: '{artifact-num-to-keep}'
+
+    wrappers:
+      - lf-infra-wrappers:
+          build-timeout: '{build-timeout}'
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    scm:
+      - lf-infra-gerrit-scm:
+          git-url: '$GIT_URL/$GERRIT_PROJECT'
+          refspec: '$GERRIT_REFSPEC'
+          branch: '$GERRIT_BRANCH'
+          submodule-recursive: 'false'
+          choosing-strategy: gerrit
+          jenkins-ssh-credential: '{jenkins-ssh-credential}'
+
+    node: '{build-node}'
+    project-type: freestyle
+    concurrent: true
+
+# coverage checks with sonarqube
+# module docs: https://docs.openstack.org/infra/jenkins-job-builder/builders.html?highlight=sonar#builders.sonar
+# Sonarqube docs:
+#  https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Jenkins
+#  https://docs.sonarqube.org/display/SCAN/Advanced+SonarQube+Scanner+Usages
+    builders:
+      - sonar:
+          sonar-name: 'sonarqube.opencord.org'
+          properties: |
+            sonar.projectKey=verify_{project}_$GERRIT_BRANCH
+            sonar.python.pylint=/usr/local/bin/pylint
+
diff --git a/jjb/verify/chameleon.yaml b/jjb/verify/chameleon.yaml
new file mode 100644
index 0000000..90262e7
--- /dev/null
+++ b/jjb/verify/chameleon.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'chameleon' repo
+
+- project:
+    name: chameleon
+    project: '{name}'
+
+    jobs:
+      - 'verify-chameleon-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-chameleon-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_chameleon_licensed'
diff --git a/jjb/verify/cord-tester.yaml b/jjb/verify/cord-tester.yaml
new file mode 100644
index 0000000..11e26b2
--- /dev/null
+++ b/jjb/verify/cord-tester.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'cord-tester' repo
+
+- project:
+    name: cord-tester
+    project: '{name}'
+
+    jobs:
+      - 'verify-cord-tester-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-cord-tester-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_cord-tester_licensed'
diff --git a/jjb/verify/cord.yaml b/jjb/verify/cord.yaml
index 601f3b0..7509064 100644
--- a/jjb/verify/cord.yaml
+++ b/jjb/verify/cord.yaml
@@ -15,6 +15,8 @@
       - 'verify-licensed'
       - 'verify-ansible-lint':
           dependency-jobs: 'verify_cord_licensed'
+      - 'verify-sonarqube':
+          dependency-jobs: 'verify_cord_ansible-lint'
       - 'api-test':
-          dependency-jobs: 'verify_cord_licensed, verify_cord_ansible-lint'
+          dependency-jobs: 'verify_cord_sonarqube'
 
diff --git a/jjb/verify/ecord.yaml b/jjb/verify/ecord.yaml
new file mode 100644
index 0000000..38fa940
--- /dev/null
+++ b/jjb/verify/ecord.yaml
@@ -0,0 +1,19 @@
+---
+# verification jobs for 'ecord' repo
+
+- project:
+    name: ecord
+    project: '{name}'
+
+    jobs:
+      - 'verify-ecord-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-ecord-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'verify-ansible-lint':
+          dependency-jobs: 'verify_ecord_licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_ecord_ansible-lint'
diff --git a/jjb/verify/fabric.yaml b/jjb/verify/fabric.yaml
new file mode 100644
index 0000000..185c01c
--- /dev/null
+++ b/jjb/verify/fabric.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'fabric' repo
+
+- project:
+    name: fabric
+    project: '{name}'
+
+    jobs:
+      - 'verify-fabric-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-fabric-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_fabric_licensed'
diff --git a/jjb/verify/maas.yaml b/jjb/verify/maas.yaml
index f9c029c..00127de 100644
--- a/jjb/verify/maas.yaml
+++ b/jjb/verify/maas.yaml
@@ -15,4 +15,6 @@
       - 'verify-licensed'
       - 'verify-ansible-lint':
           dependency-jobs: 'verify_maas_licensed'
+      - 'verify-sonarqube':
+          dependency-jobs: 'verify_maas_ansible-lint'
 
diff --git a/jjb/verify/mcord.yaml b/jjb/verify/mcord.yaml
new file mode 100644
index 0000000..204eba1
--- /dev/null
+++ b/jjb/verify/mcord.yaml
@@ -0,0 +1,19 @@
+---
+# verification jobs for 'mcord' repo
+
+- project:
+    name: mcord
+    project: '{name}'
+
+    jobs:
+      - 'verify-mcord-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-mcord-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'verify-ansible-lint':
+          dependency-jobs: 'verify_mcord_licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_mcord_ansible-lint'
diff --git a/jjb/verify/olt-service.yaml b/jjb/verify/olt-service.yaml
new file mode 100644
index 0000000..3a85e14
--- /dev/null
+++ b/jjb/verify/olt-service.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'olt-service' repo
+
+- project:
+    name: olt-service
+    project: '{name}'
+
+    jobs:
+      - 'verify-olt-service-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-olt-service-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_olt-service_licensed'
diff --git a/jjb/verify/onos-service.yaml b/jjb/verify/onos-service.yaml
new file mode 100644
index 0000000..3e878e6
--- /dev/null
+++ b/jjb/verify/onos-service.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'onos-service' repo
+
+- project:
+    name: onos-service
+    project: '{name}'
+
+    jobs:
+      - 'verify-onos-service-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-onos-service-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_onos-service_licensed'
diff --git a/jjb/verify/openstack.yaml b/jjb/verify/openstack.yaml
new file mode 100644
index 0000000..16d56ad
--- /dev/null
+++ b/jjb/verify/openstack.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'openstack' repo
+
+- project:
+    name: openstack
+    project: '{name}'
+
+    jobs:
+      - 'verify-openstack-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-openstack-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_openstack_licensed'
diff --git a/jjb/verify/platform-install.yaml b/jjb/verify/platform-install.yaml
index c04db63..241c8bf 100644
--- a/jjb/verify/platform-install.yaml
+++ b/jjb/verify/platform-install.yaml
@@ -15,6 +15,8 @@
       - 'verify-licensed'
       - 'verify-ansible-lint':
           dependency-jobs: 'verify_platform-install_licensed'
+      - 'verify-sonarqube':
+          dependency-jobs: 'verify_platform-install_ansible-lint'
       - 'api-test':
-          dependency-jobs: 'verify_platform-install_licensed, verify_platform-install_ansible-lint'
+          dependency-jobs: 'verify_platform-install_sonarqube'
 
diff --git a/jjb/verify/rcord.yaml b/jjb/verify/rcord.yaml
new file mode 100644
index 0000000..a7cbf76
--- /dev/null
+++ b/jjb/verify/rcord.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'rcord' repo
+
+- project:
+    name: rcord
+    project: '{name}'
+
+    jobs:
+      - 'verify-rcord-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-rcord-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_rcord_licensed'
diff --git a/jjb/verify/vEE.yaml b/jjb/verify/vEE.yaml
new file mode 100644
index 0000000..4e24e13
--- /dev/null
+++ b/jjb/verify/vEE.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vEE' repo
+
+- project:
+    name: vEE
+    project: '{name}'
+
+    jobs:
+      - 'verify-vEE-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vEE-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vEE_licensed'
diff --git a/jjb/verify/vEG.yaml b/jjb/verify/vEG.yaml
new file mode 100644
index 0000000..c57b95a
--- /dev/null
+++ b/jjb/verify/vEG.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vEG' repo
+
+- project:
+    name: vEG
+    project: '{name}'
+
+    jobs:
+      - 'verify-vEG-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vEG-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vEG_licensed'
diff --git a/jjb/verify/vEPC.yaml b/jjb/verify/vEPC.yaml
new file mode 100644
index 0000000..5b1451d
--- /dev/null
+++ b/jjb/verify/vEPC.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vEPC' repo
+
+- project:
+    name: vEPC
+    project: '{name}'
+
+    jobs:
+      - 'verify-vEPC-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vEPC-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vEPC_licensed'
diff --git a/jjb/verify/vHSS.yaml b/jjb/verify/vHSS.yaml
new file mode 100644
index 0000000..d41748e
--- /dev/null
+++ b/jjb/verify/vHSS.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vHSS' repo
+
+- project:
+    name: vHSS
+    project: '{name}'
+
+    jobs:
+      - 'verify-vHSS-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vHSS-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vHSS_licensed'
diff --git a/jjb/verify/vMME.yaml b/jjb/verify/vMME.yaml
new file mode 100644
index 0000000..1b87edf
--- /dev/null
+++ b/jjb/verify/vMME.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vMME' repo
+
+- project:
+    name: vMME
+    project: '{name}'
+
+    jobs:
+      - 'verify-vMME-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vMME-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vMME_licensed'
diff --git a/jjb/verify/venb.yaml b/jjb/verify/venb.yaml
new file mode 100644
index 0000000..68f3ced
--- /dev/null
+++ b/jjb/verify/venb.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'venb' repo
+
+- project:
+    name: venb
+    project: '{name}'
+
+    jobs:
+      - 'verify-venb-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-venb-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_venb_licensed'
diff --git a/jjb/verify/vrouter.yaml b/jjb/verify/vrouter.yaml
new file mode 100644
index 0000000..467c5e8
--- /dev/null
+++ b/jjb/verify/vrouter.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vrouter' repo
+
+- project:
+    name: vrouter
+    project: '{name}'
+
+    jobs:
+      - 'verify-vrouter-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vrouter-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vrouter_licensed'
diff --git a/jjb/verify/vsg.yaml b/jjb/verify/vsg.yaml
new file mode 100644
index 0000000..2a70758
--- /dev/null
+++ b/jjb/verify/vsg.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vsg' repo
+
+- project:
+    name: vsg
+    project: '{name}'
+
+    jobs:
+      - 'verify-vsg-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vsg-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vsg_licensed'
diff --git a/jjb/verify/vspgwc.yaml b/jjb/verify/vspgwc.yaml
new file mode 100644
index 0000000..2bef282
--- /dev/null
+++ b/jjb/verify/vspgwc.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vspgwc' repo
+
+- project:
+    name: vspgwc
+    project: '{name}'
+
+    jobs:
+      - 'verify-vspgwc-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vspgwc-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vspgwc_licensed'
diff --git a/jjb/verify/vspgwu.yaml b/jjb/verify/vspgwu.yaml
new file mode 100644
index 0000000..d221209
--- /dev/null
+++ b/jjb/verify/vspgwu.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vspgwu' repo
+
+- project:
+    name: vspgwu
+    project: '{name}'
+
+    jobs:
+      - 'verify-vspgwu-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vspgwu-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vspgwu_licensed'
diff --git a/jjb/verify/vtn.yaml b/jjb/verify/vtn.yaml
new file mode 100644
index 0000000..31350f5
--- /dev/null
+++ b/jjb/verify/vtn.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vtn' repo
+
+- project:
+    name: vtn
+    project: '{name}'
+
+    jobs:
+      - 'verify-vtn-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vtn-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vtn_licensed'
diff --git a/jjb/verify/vtr.yaml b/jjb/verify/vtr.yaml
new file mode 100644
index 0000000..4afca83
--- /dev/null
+++ b/jjb/verify/vtr.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'vtr' repo
+
+- project:
+    name: vtr
+    project: '{name}'
+
+    jobs:
+      - 'verify-vtr-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-vtr-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_vtr_licensed'
diff --git a/jjb/verify/xos-gui.yaml b/jjb/verify/xos-gui.yaml
new file mode 100644
index 0000000..e7cd509
--- /dev/null
+++ b/jjb/verify/xos-gui.yaml
@@ -0,0 +1,17 @@
+---
+# verification jobs for 'xos-gui' repo
+
+- project:
+    name: xos-gui
+    project: '{name}'
+
+    jobs:
+      - 'verify-xos-gui-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-xos-gui-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'gui-unit-test':
+          dependency-jobs: 'verify_xos-gui_licensed'
diff --git a/jjb/verify/xos.yaml b/jjb/verify/xos.yaml
new file mode 100644
index 0000000..5f3e911
--- /dev/null
+++ b/jjb/verify/xos.yaml
@@ -0,0 +1,19 @@
+---
+# verification jobs for 'xos' repo
+
+- project:
+    name: xos
+    project: '{name}'
+
+    jobs:
+      - 'verify-xos-jobs':
+          branch-regexp: '{supported-branches-regexp}'
+
+- job-group:
+    name: 'verify-xos-jobs'
+    jobs:
+      - 'verify-licensed'
+      - 'verify-sonarqube':
+          dependency-jobs: 'verify_xos_licensed'
+      - 'api-test':
+          dependency-jobs: 'verify_xos_sonarqube'
diff --git a/packer/provision/basebuild.sh b/packer/provision/basebuild.sh
index 35f05c4..76a0204 100644
--- a/packer/provision/basebuild.sh
+++ b/packer/provision/basebuild.sh
@@ -77,6 +77,7 @@
         gitpython \
         graphviz \
         isort \
+        linkchecker \
         pexpect \
         pylint \
         pyyaml \
@@ -94,6 +95,10 @@
         typings
         # end of npm install list
 
+    # ubuntu 16.04 installs the node binary as /usr/bin/nodejs, which breaks
+    # tools that expect it to be named just `node`. Symlink it to fix
+    ln -s /usr/bin/nodejs /usr/local/bin/node
+
     # install repo
     REPO_SHA256SUM="394d93ac7261d59db58afa49bb5f88386fea8518792491ee3db8baab49c3ecda"
     curl -o /tmp/repo 'https://gerrit.opencord.org/gitweb?p=repo.git;a=blob_plain;f=repo;hb=refs/heads/stable'