diff --git a/Jenkinsfile.MCORDBuildSystem b/Jenkinsfile.MCORDBuildSystem
new file mode 100644
index 0000000..26b5712
--- /dev/null
+++ b/Jenkinsfile.MCORDBuildSystem
@@ -0,0 +1,485 @@
+// Copyright 2017-present Open Networking Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import groovy.json.JsonSlurperClassic
+
+def filename = 'manifest-${branch}.xml'
+def manifestUrl = 'https://gerrit.opencord.org/manifest'
+deployment_config = null;
+pod_config = null;
+
+node ('master') {
+    checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: "${manifestUrl}", quiet: true]
+
+    stage ("Generate and Copy Manifest file") {
+        sh returnStdout: true, script: 'repo manifest -r -o ' + filename
+        sh returnStdout: true, script: 'cp ' + filename + ' ' + env.JENKINS_HOME + '/tmp'
+    }
+
+    stage ("Parse deployment configuration file") {
+        sh returnStdout: true, script: 'rm -rf ${configRepoBaseDir}'
+        sh returnStdout: true, script: 'git clone -b ${branch} ${configRepoUrl}'
+        deployment_config = readYaml file: "${configRepoBaseDir}${configRepoFile}"
+        pod_config = readYaml file: "${configRepoBaseDir}${deployment_config.pod_config.file_name}"
+    }
+}
+
+node ("${deployment_config.dev_node.name}") {
+    timeout (time: 360) {
+        stage ('Remove old head node from known hosts') {
+            sh "ssh-keygen -R ${deployment_config.head.ip}"
+        }
+
+        stage ('Checkout cord repo') {
+            checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: "${manifestUrl}", quiet: true]
+        }
+
+        stage ('Copy NG40 license file') {
+            sh "cp ../ng40-license orchestration/xos_services/venb/xos/synchronizer/files/ng40-license"   
+        }
+
+        try {
+            dir('build') {
+                stage ("Re-deploy head node") {
+                    maasOps: {
+                        sh "maas login maas http://${deployment_config.maas.ip}/MAAS/api/2.0 ${deployment_config.maas.api_key}"
+                        sh "maas maas machine release ${deployment_config.maas.head_system_id}"
+
+                        timeout(time: 15) {
+                            waitUntil {
+                               try {
+                                    sh "maas maas machine read ${deployment_config.maas.head_system_id} | grep Ready"
+                                    return true
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+
+                        sh 'maas maas machines allocate'
+                        sh "maas maas machine deploy ${deployment_config.maas.head_system_id}"
+
+                        timeout(time: 30) {
+                            waitUntil {
+                               try {
+                                    sh "maas maas machine read ${deployment_config.maas.head_system_id} | grep Deployed"
+                                    return true
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+                }
+
+                stage ("Download CORD POD configuration") {
+                    sh "cd ../orchestration/profiles; git clone -b ${branch} ${deployment_config.pod_config.repo_url} automation"
+                }
+
+                stage ("Generate CORD configuration") {
+                    sh "make PODCONFIG_PATH=../orchestration/profiles/automation/${deployment_config.pod_config.file_name} config"
+                }
+
+                if (deployment_config.fabric_switches != null) {
+                    stage("Reserve IPs for fabric switches") {
+                        for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+                            def str = createMACIPbindingStr("fabric", i+1,
+                                                           "${deployment_config.fabric_switches[i].mac}",
+                                                           "${deployment_config.fabric_switches[i].ip}")
+                            sh "echo $str >> maas/roles/maas/files/dhcpd.reservations"
+                        }
+                    }
+                }
+
+                stage ("Deploy") {
+                    sh 'sed -i "s/^\\(dev_vm_cpu: \\).*/\\120/" genconfig/config.yml'
+                    sh 'sed -i "s/^\\(dev_vm_mem: \\).*/\\140960/" genconfig/config.yml'
+                    sh "make build"
+                }
+
+                if (deployment_config.compute_nodes != null) {
+                    stage ("Power cycle compute nodes") {
+                        for(int i=0; i < deployment_config.compute_nodes.size(); i++) {
+                            sh "ipmitool -U ${deployment_config.compute_nodes[i].ipmi.user} -P ${deployment_config.compute_nodes[i].ipmi.pass} -H ${deployment_config.compute_nodes[i].ipmi.ip} power cycle"
+                        }
+                    }
+
+                    stage ("Wait for compute nodes to get deployed") {
+                        sh "ssh-keygen -f /home/${deployment_config.dev_node.user}/.ssh/known_hosts -R ${deployment_config.head.ip}"
+                        def cordApiKey = runHeadNodeCmd("sudo maas-region-admin apikey --username ${deployment_config.head.user}")
+                        runHeadNodeCmd("maas login pod-maas http://${deployment_config.head.ip}/MAAS/api/1.0 ${cordApiKey}")
+                        timeout(time: 90) {
+                            waitUntil {
+                                try {
+                                    num = runHeadNodeCmd("maas pod-maas nodes list | grep substatus_name | grep -i deployed | wc -l").trim()
+                                    return num.toInteger() == deployment_config.compute_nodes.size()
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+
+                    stage ("Wait for compute nodes to be provisioned") {
+                        timeout(time:90) {
+                            waitUntil {
+                                try {
+                                    num = runHeadNodeCmd("cord prov list | grep -i node | grep -i complete | wc -l").trim()
+                                    return num.toInteger() == deployment_config.compute_nodes.size()
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (deployment_config.fabric_switches != null) {
+                    stage ("Wait for fabric switches to get deployed") {
+                        runFabricSwitchCmdAll("sudo onl-onie-boot-mode install")
+                        runFabricSwitchCmdAll("sudo reboot")
+                            // Ensure that switches get provisioned after ONIE reinstall.
+                            // Delete them if they were provisioned earlier.  If the switches are not
+                            // present in 'cord prov list', this command has no effect.
+                        for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+                            runHeadNodeCmd("cord prov delete ${deployment_config.fabric_switches[i].mac}")
+                        }
+                        timeout(time: 45) {
+                            waitUntil {
+                                try {
+                                    def harvestCompleted = runHeadNodeCmd("cord harvest list | grep -i fabric | wc -l").trim()
+                                    return harvestCompleted.toInteger() == deployment_config.fabric_switches.size()
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+
+                    stage ("Wait for fabric switches to be provisioned") {
+                        timeout(time:45) {
+                            waitUntil {
+                                try {
+                                    def provCompleted = 0
+                                    for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+                                        def count = runHeadNodeCmd("cord prov list | grep -i ${deployment_config.fabric_switches[i].ip} | grep -i complete | wc -l").trim()
+                                        provCompleted = provCompleted + count.toInteger()
+                                    }
+                                    return provCompleted == deployment_config.fabric_switches.size()
+                                } catch (exception) {
+                                    return false
+                                }
+                            }
+                        }
+                    }
+
+                    // Post installation configuration starts here
+                    fabricIpPrefix = pod_config.fabric_ip.split(/\.\d+\.\d+\/24/)[0]
+                    xosUser = "xosadmin@opencord.org"
+                    xosPass = runHeadNodeCmd("cat /opt/credentials/xosadmin@opencord.org").trim()
+                    stage ("Connect fabric switches and compute nodes to ONOS") {
+                        // Configure breakout ports
+                        for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+                            if (deployment_config.fabric_switches[i].breakout_ports != null) {
+                                for(int j=0; j < deployment_config.fabric_switches[i].breakout_ports.size(); j++) {
+                                    runFabricSwitchCmd("${deployment_config.fabric_switches[i].ip}",
+                                                       "${deployment_config.fabric_switches[i].user}",
+                                                       "${deployment_config.fabric_switches[i].pass}",
+                                                       "sed -i -e 's/#port_mode_${deployment_config.fabric_switches[i].breakout_ports[j]}=/port_mode_${deployment_config.fabric_switches[i].breakout_ports[j]}=/g' /etc/accton/ofdpa.conf")
+                                }
+                            }
+                        }
+                        connectFabricAndComputeToOnos()
+                    }
+                    stage ("Configure the compute nodes") {
+                        leafSwitchNum = 0
+                        for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+                            if(deployment_config.fabric_switches[i].containsKey("role")) {
+                                if(deployment_config.fabric_switches[i].role.toLowerCase().contains("leaf")) {
+                                    leafSwitchNum += 1
+                                }
+                            }
+                        }
+                        for(int i=1; i<=leafSwitchNum; i++) {
+                            // Figure out which compute node connects to which switch
+                            leafName = "leaf-" + i.toString()
+                            computeNames = getComputeNames(leafName)
+                            echo "Compute nodes connnected to " + leafName + " switch:"
+                            for(name in computeNames) { echo "${name}" }
+                            index = 1
+                            for(name in computeNames) {
+                                if(i>1) {
+                                    //Update fabric IP of compute nodes
+                                    index += 1
+                                    fabricIp = runComputeNodeCmd("${name}", "ip a | grep -o '${fabricIpPrefix}.[1-9][0-9]*.[0-9]*/24'").trim()
+                                    if (fabricIp != "") {
+                                        nodeId = sh(returnStdout: true, script: "curl -u ${xosUser}:${xosPass} -X GET http://${deployment_config.head.ip}/xosapi/v1/core/nodes | jq '.[\"items\"][] | select(.dataPlaneIp==\"${fabricIp}\") | .id'").trim()
+                                        newFabricIp = "${fabricIpPrefix}." + i.toString() + "." + index.toString() + "/24"
+                                        out = sh(returnStdout: true, script: "curl -u ${xosUser}:${xosPass} -X PUT -d '{\"dataPlaneIp\":\"${newFabricIp}\"}' http://${deployment_config.head.ip}/xosapi/v1/core/nodes/${nodeId}").trim()
+                                        // Wait until the new fabric IP gets configured
+                                        timeout(time: 5) {
+                                            waitUntil {
+                                                try {
+                                                    num = runComputeNodeCmd("${name}", "ip a | grep " + newFabricIp + " | wc -l").trim()
+                                                    return num.toInteger() == 1
+                                                } catch (exception) {
+                                                    return false
+                                                }
+                                            }
+                                        }
+                                    }
+                                    else echo "Cannot find fabric IP matching pattern ${fabricIpPrefix}.[1-9][0-9]*.[0-9]*"
+                                }
+                                //Add routes to fabric subnets
+                                for(int j=1; j<=leafSwitchNum; j++) {
+                                    if(j!=i) {
+                                        runComputeNodeCmd("${name}", "sudo ip route add ${fabricIpPrefix}." + j.toString() + ".0/24 via ${fabricIpPrefix}." + i.toString() + ".254 || echo route already exists")
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    stage ("Generate and load network configuration") {
+                        // Reconnect compute nodes to update the fabric IP in ONOS
+                        connectFabricAndComputeToOnos()
+                        // Generate network configuration
+                        runHeadNodeCmd("""
+                                       cd /opt/cord_profile/
+                                       cp fabric-network-cfg.json fabric-network-cfg.json.\$(date +%Y%m%d-%H%M%S)
+                                       cord generate > fabric-network-cfg.json
+                                       """)
+                        // Install httpie on the head-node
+                        runHeadNodeCmd("sudo pip install httpie")
+                        // Delete old ONOS netcfg
+                        runHeadNodeCmd("http -a onos:rocks DELETE http://onos-fabric:8181/onos/v1/network/configuration/")
+                        // Load new configuration
+                        runHeadNodeCmd("http -a onos:rocks POST http://onos-fabric:8181/onos/v1/network/configuration/ < /opt/cord_profile/fabric-network-cfg.json")
+                        // Restart ONOS apps
+                        runHeadNodeCmd("""
+                                       http -a onos:rocks DELETE http://onos-fabric:8181/onos/v1/applications/org.onosproject.segmentrouting/active; sleep 5
+                                       http -a onos:rocks POST http://onos-fabric:8181/onos/v1/applications/org.onosproject.segmentrouting/active; sleep 5
+                                       """)
+                    }
+                }
+            }
+
+            if (deployment_config.make_release == true) {
+                stage ("Trigger Build") {
+                    url = 'https://jenkins.opencord.org/job/release-build/job/' + params.branch + '/build'
+                    httpRequest authentication: 'auto-release', httpMode: 'POST', url: url, validResponseCodes: '201'
+                }
+            }
+
+            currentBuild.result = 'SUCCESS'
+        } catch (err) {
+            currentBuild.result = 'FAILURE'
+            step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${notificationEmail}", sendToIndividuals: false])
+        } finally {
+            //sh "make -C build clean-all || true"
+            //sh "rm -rf *"
+        }
+        echo "RESULT: ${currentBuild.result}"
+    }
+}
+
+/**
+ * Returns a string used to bind IPs and MAC addresses, substituting the values
+ * given.
+ *
+ * @param word    the word used to generate the host name
+ * @param counter the counter used to generate the host name
+ * @param mac     the MAC address to substitute
+ * @param ip      the IP address to substitute
+ */
+def createMACIPbindingStr(word, counter, mac, ip) {
+    return """host ${word}-${counter} {'\n'hardware ethernet ${mac}';''\n'fixed-address ${ip}';''\n'}"""
+}
+
+/**
+ * Runs a command on a remote host using sshpass.
+ *
+ * @param ip      the node IP address
+ * @param user    the node user name
+ * @param pass    the node password
+ * @param command the command to run
+ * @param sshArgs arguments for the ssh command
+ * @return the output of the command
+ */
+def runCmd(ip, user, pass, command, sshArgs="") {
+    return sh(returnStdout: true, script: "sshpass -p ${pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${user} ${ip} \"${command}\"")
+}
+
+/**
+ * Runs a command on the head node.
+ *
+ * @param command the command to run
+ * @param sshArgs arguments for the ssh command
+ * @return the output of the command
+ */
+def runHeadNodeCmd(command, sshArgs="") {
+    return sh(returnStdout: true, script: "sshpass -p ${deployment_config.head.pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${deployment_config.head.user} ${deployment_config.head.ip} \"${command}\"")
+}
+
+/**
+ * Runs a command on a fabric switch.
+ *
+ * @param ip      the mgmt IP of the fabric switch, reachable from the head node
+ * @param user    the mgmt user name of the fabric switch
+ * @param pass    the mgmt password of the fabric switch
+ * @param command the command to run on the fabric switch
+ * @param ssgArgs arguments for the ssh command
+ * @return the output of the command
+ */
+def runFabricSwitchCmd(ip, user, pass, command, sshArgs="") {
+    return sh(returnStdout: true, script: "sshpass -p ${deployment_config.head.pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${deployment_config.head.user} ${deployment_config.head.ip} \"sshpass -p ${pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${user} ${ip} ${command}\"")
+}
+
+/**
+ * Runs a command on all fabric switches
+ *
+ * @param command the command to run on the fabric switches
+ * @param ssgArgs arguments for the ssh command
+ */
+def runFabricSwitchCmdAll(command, sshArgs="") {
+    for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+        runFabricSwitchCmd("${deployment_config.fabric_switches[i].ip}",
+                           "${deployment_config.fabric_switches[i].user}",
+                           "${deployment_config.fabric_switches[i].pass}",
+                           "${command}",
+                           "${sshArgs}")
+    }
+}
+
+/**
+ * Runs a command on a compute node.
+ *
+ * @param name    the name of the compute node
+ * @param command the command to run on the compute node
+ * @param ssgArgs arguments for the ssh command
+ * @return the output of the command
+ */
+def runComputeNodeCmd(name, command, sshArgs="") {
+    return sh(returnStdout: true, script: "sshpass -p ${deployment_config.head.pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${deployment_config.head.user} ${deployment_config.head.ip} \"ssh ${sshArgs} ubuntu@${name} ${command}\"")
+}
+
+/**
+ * Runs a command on all compute nodes
+ *
+ * @param command the command to run on the compute nodes
+ * @param ssgArgs arguments for the ssh command
+ */
+def runComputeNodeCmdAll(command, sshArgs="") {
+    computeNamesAll = getComputeNames()
+    for (name in computeNamesAll) {
+        runComputeNodeCmd("${name}", "${command}", "${sshArgs}")
+    }
+}
+
+/**
+ * Runs an ONOS CLI command
+ *
+ * @param name    the onos node name, reachable from the head node
+ * @param port    the port used to login to ONOS CLI
+ * @param user    the user name to login to ONOS CLI
+ * @param pass    the password to login to ONOS CLI
+ * @param command the command to run in ONOS CLI
+ * @return the output of the command
+ */
+def runOnosCliCmd(name, port, user, pass, command) {
+    return sh(returnStdout: true, script: "sshpass -p ${deployment_config.head.pass} ssh -oStrictHostKeyChecking=no -l ${deployment_config.head.user} ${deployment_config.head.ip} \"sshpass -p ${pass} ssh -oStrictHostKeyChecking=no -l ${user} -p ${port} ${name} ${command}\"")
+}
+
+/**
+ * Returns a list of compute node names. When "role" is specified, returns only
+ * names of compute nodes connected to the switch
+ *
+ * @param role    the switch role, i.e. "leaf-1"
+ */
+def getComputeNames(role="") {
+    computeNamesAll = runHeadNodeCmd("cord prov list | grep node | awk '{print \\\$2}' | sed -e \\\"s/.*/'&'/\\\"").trim()
+    computeNamesAll = "${computeNamesAll}".split()
+    computeNamesAll = "${computeNamesAll}".replaceAll("'", "\"")
+    computeNamesAll = new JsonSlurperClassic().parseText("${computeNamesAll}")
+    if ("${role}" == "") return computeNamesAll
+    computeNames = []
+    switchMac = ""
+    for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+        if(deployment_config.fabric_switches[i].containsKey("role")) {
+            if ("${deployment_config.fabric_switches[i].role}" == "${role}")
+                switchMac = "${deployment_config.fabric_switches[i].mac}"
+        }
+    }
+    if ("${switchMac}" != "") {
+        switchMac = switchMac.toLowerCase().replaceAll(':','')
+        // Get fabric IPs of compute nodes connected to the switch
+        try {
+            computeFabricIps = runHeadNodeCmd("sshpass -p rocks ssh -q -oStrictHostKeyChecking=no -l onos -p 8101 onos-fabric hosts -j | jq '.[] | select(.location.elementId | contains(\\\"${switchMac}\\\")) | .ipAddresses' | grep -o '\\\"${fabricIpPrefix}.[1-9][0-9]*.[0-9]*\\\"'",
+                                              "-q").trim()
+        }catch (exception) {
+            return computeNames
+        }
+        computeFabricIps = "${computeFabricIps}".split()
+        computeFabricIps = new JsonSlurperClassic().parseText("${computeFabricIps}")
+        // Figure out which compute node connects to the switch
+        for (name in computeNamesAll) {
+            fabricIp = runComputeNodeCmd("${name}", "ip a | grep -o '${fabricIpPrefix}.[1-9][0-9]*.[0-9]*'").trim()
+            if (fabricIp in computeFabricIps) {
+                computeNames.add("${name}")
+            }
+        }
+    }
+    return computeNames
+}
+
+/**
+ * Connects all fabric switches and compute nodes to ONOS
+ */
+def connectFabricAndComputeToOnos() {
+    // Kill existing switch connections
+    runFabricSwitchCmdAll("./killit || echo no ofagentapp running")
+    // Clean stale ONOS data
+    runOnosCliCmd("onos-fabric", "8101", "onos", "rocks", "wipe-out -r -j please")
+    // Connect switches to ONOS
+    for(int i=0; i < deployment_config.fabric_switches.size(); i++) {
+        runFabricSwitchCmd("${deployment_config.fabric_switches[i].ip}",
+                           "${deployment_config.fabric_switches[i].user}",
+                           "${deployment_config.fabric_switches[i].pass}",
+                           "./connect -bg 2>&1 > ${deployment_config.fabric_switches[i].ip}.log",
+                           "-qftn")
+    }
+    // Verify ONOS has recognized the switches
+    timeout(time: 5) {
+        waitUntil {
+            try {
+                num = runHeadNodeCmd("\"sshpass -p rocks ssh -q -oStrictHostKeyChecking=no -l onos -p 8101 onos-fabric devices | grep available=true | wc -l\"").trim()
+                return num.toInteger() == deployment_config.fabric_switches.size()
+            } catch (exception) {
+                return false
+            }
+        }
+    }
+    // Connect compute nodes to ONOS
+    runComputeNodeCmdAll("ping -c 1 ${fabricIpPrefix}.1.254", "-qftn")
+    // Verify ONOS has recognized the hosts
+    timeout(time: 5) {
+        waitUntil {
+            try {
+                num = runHeadNodeCmd("\"sshpass -p rocks ssh -q -oStrictHostKeyChecking=no -l onos -p 8101 onos-fabric hosts | grep id= | wc -l\"").trim()
+                return num.toInteger() >= deployment_config.compute_nodes.size()
+            } catch (exception) {
+                return false
+            }
+        }
+    }
+}
