-
Raphael Defosseux authored
Signed-off-by:
Raphael Defosseux <raphael.defosseux@openairinterface.org>
Raphael Defosseux authoredSigned-off-by:
Raphael Defosseux <raphael.defosseux@openairinterface.org>
Jenkinsfile 14.91 KiB
#!/bin/groovy
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698
*
* 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.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
//-------------------------------------------------------------------------------
// Location of the CN executor node
// Its main purpose is the Ubuntu Build
ubuntuNode = params.UbuntuBuildNode
ubuntuBuildResource = params.UbuntuBuildResource
// Location of the RHEL CN executor
rhelNode = params.RhelBuildNode
rhelResource = params.RhelBuildResource
rhelOcCredentials = params.RhelOcCredentials
// Tags/Branches to use
def flexric_tag = "develop"
def flexric_branch = "dev"
// Merge Request Link
gitlabMergeRequestLink = ''
// Docker Hub account to push to
DH_Account = "oaisoftwarealliance"
// Private Local Registry URL
PrivateRegistryURL = 'selfix.sboai.cs.eurecom.fr'
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
agent {
label ubuntuNode
}
options {
disableConcurrentBuilds()
timestamps()
ansiColor('xterm')
gitLabConnection('OAI GitLab')
// Minimal checks
gitlabBuilds(builds: [
"Build Ubuntu FLEXRIC Image",
"Build RHEL FLEXRIC Image"
])
}
stages {
stage ('Verify Parameters') {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
if (params.DockerHubCredentials == null) {
echo '\u26D4 \u001B[31mNo Credentials to push to DockerHub!\u001B[0m'
error "Stopping pipeline!"
}
if (params.RhelOcCredentials == null) {
echo '\u26D4 \u001B[31mNo Credentials to connect to Openshift!\u001B[0m'
error "Stopping pipeline!"
}
}
}
}
stage ('Prepare Source Code') {
steps {
script {
if ("MERGE".equals(env.gitlabActionType)) {
gitlabMergeRequestLink = sh returnStdout: true, script: "curl --silent 'https://gitlab.eurecom.fr/api/v4/projects/mosaic5g%2Fflexric/merge_requests/${env.gitlabMergeRequestIid}' | jq .web_url | sed 's#\"##g'"
gitlabMergeRequestLink = gitlabMergeRequestLink.trim()
shortenShaOne = sh returnStdout: true, script: 'git log -1 --pretty=format:"%h" --abbrev=8 ' + env.gitlabMergeRequestLastCommit
shortenShaOne = shortenShaOne.trim()
flexric_tag = 'ci-tmp-pr-' + env.gitlabMergeRequestIid + '-' + shortenShaOne
flexric_branch = env.gitlabSourceBranch
echo "========= THIS IS A MERGE REQUEST =========="
echo "MR ID is ${env.gitlabMergeRequestIid}"
echo "MR LINK is ${gitlabMergeRequestLink}"
echo "MR TITLE is ${env.gitlabMergeRequestTitle}"
echo "MR TAG is ${flexric_tag}"
} else {
shortenShaOne = sh returnStdout: true, script: 'git log -1 --pretty=format:"%h" --abbrev=8 ' + env.GIT_COMMIT
shortenShaOne = shortenShaOne.trim()
flexric_tag = 'develop-' + shortenShaOne
flexric_branch = env.GIT_COMMIT
echo "======== THIS IS A PUSH REQUEST ========"
echo "Git Branch is ${GIT_BRANCH}"
echo "Git Commit is ${GIT_COMMIT}"
echo "CI develop TAG is ${flexric_tag}"
}
prepareWorkspaceMergeCase()
}
}
post {
failure {
script {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI"
addGitLabMRComment comment: message
currentBuild.result = 'FAILURE'
}
}
}
}
stage('Build Core Network Function') {
parallel {
stage ('Build Ubuntu FLEXRIC Image') {
steps {
// Now it is only locked during this build stage and not for the whole pipeline
lock(ubuntuBuildResource) {
script {
gitlabCommitStatus(name: "Build Ubuntu FLEXRIC Image") {
sh "docker image rm oai-flexric:${flexric_tag} || true"
sh "docker image prune --force"
if ("PUSH".equals(env.gitlabActionType)) {
dockerBuildOptions = '--no-cache '
}
if ("MERGE".equals(env.gitlabActionType)) {
dockerBuildOptions = ''
}
sh "docker buildx build ${dockerBuildOptions} --target oai-flexric --tag oai-flexric:${flexric_tag} --file docker/Dockerfile.flexric.ubuntu . > archives/flexric_ubuntu_image_build.log 2>&1"
sh "docker image ls | egrep --color=never 'flexric|REPOSITORY' >> archives/flexric_ubuntu_image_build.log"
// Pushing to local private registry for testing purpose
sh "docker login -u oaicicd -p oaicicd ${PrivateRegistryURL}"
sh "docker image tag oai-flexric:${flexric_tag} ${PrivateRegistryURL}/oai-flexric:${flexric_tag}"
sh "docker push ${PrivateRegistryURL}/oai-flexric:${flexric_tag}"
// Remove all images locally
sh "docker rmi oai-flexric:${flexric_tag} ${PrivateRegistryURL}/oai-flexric:${flexric_tag}"
sh "docker logout ${PrivateRegistryURL}"
}
}
}
}
post {
success {
sh "echo 'OAI-FLEXRIC UBUNTU IMAGE BUILD: OK' >> archives/flexric_ubuntu_image_build.log"
}
unsuccessful {
sh "echo 'OAI-FLEXRIC UBUNTU IMAGE BUILD: KO' >> archives/flexric_ubuntu_image_build.log"
}
}
}
stage ('Build RHEL FLEXRIC Image') {
agent { label rhelNode }
steps {
lock (rhelResource) {
script {
gitlabCommitStatus(name: "Build RHEL FLEXRIC Image") {
// It's a different agent from main one.
prepareWorkspaceMergeCase()
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${rhelOcCredentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "oc login -u ${OC_Username} -p ${OC_Password}"
}
sh "oc delete istag oai-flexric:${flexric_tag} || true"
// Copy the RHEL Host certificates for building
sh "./ci-scripts/common/python/recreate_entitlement.py"
// Building
sh "oc delete -f openshift/build-config.yaml || true"
sh "sed -i -e 's@oai-flexric:latest@oai-flexric:${flexric_tag}@g' openshift/build-config.yaml"
sh "oc create -f openshift/build-config.yaml"
sh 'oc start-build flexric-build-cfg --from-dir=./ --exclude=""'
// need python to wait for pod flexric-build-cfg-1-build to be Completed or Error
// it fails if it detects error or timeout at 20 minutes
sh "./ci-scripts/common/python/check_build_pod_status.py --pod-name flexric-build-cfg-1-build --log-file archives/flexric_rhel_image_build.log"
sh "oc describe istag oai-flexric:${flexric_tag} | grep 'Image Size:' >> archives/flexric_rhel_image_build.log"
}
}
}
}
post {
success {
sh "echo 'OAI-FLEXRIC RHEL IMAGE BUILD: OK' >> archives/flexric_rhel_image_build.log"
}
unsuccessful {
sh "echo 'OAI-FLEXRIC RHEL IMAGE BUILD: KO' >> archives/flexric_rhel_image_build.log"
}
cleanup {
script {
sh "oc delete build flexric-build-cfg-1 || true"
sh "oc logout || true"
stash allowEmpty: true, includes: 'archives/flexric_rhel_image_build.log', name: 'rhelBuildLog'
}
}
}
}
}
post {
always {
script {
unstash 'rhelBuildLog'
}
}
}
}
stage ('Running CTests') {
steps {
lock(ubuntuBuildResource) {
script {
gitlabCommitStatus(name: "Running CTests") {
sh "docker image rm oai-flexric-ctest:${flexric_tag} || true"
sh "docker buildx build --target oai-flexric-builder --tag oai-flexric-ctest:${flexric_tag} --file ci-scripts/Dockerfile.ctest . > archives/flexric_ctests.log 2>&1"
}
}
}
}
post {
cleanup {
script {
sh "docker image rm oai-flexric-ctest:${flexric_tag} || true"
}
}
}
}
stage ('Full Stack Testing') {
parallel {
stage ('Flexric-OAI-RAN-5G') {
steps {
script {
gitlabCommitStatus(name: "Flexric-OAI-RAN-5G-Integration") {
if ("MERGE".equals(env.gitlabActionType)) {
MR_NUMBER = 'flexric-' + env.gitlabMergeRequestIid
} else {
MR_NUMBER = 'flexric-dev'
}
localStatus = build job: 'OAI-FLEXRIC-RAN-Integration-Test',
parameters: [
string(name: 'Flexric_Tag', value: String.valueOf(flexric_tag)),
string(name: 'eNB_MR', value: String.valueOf(MR_NUMBER))
], propagate: false
localResult = localStatus.getResult()
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "OAI-FLEXRIC-RAN-Integration-Test is OK"
} else {
error "OAI-FLEXRIC-RAN-Integration-Test is KO"
}
}
}
}
post {
always {
script {
copyArtifacts(projectName: 'OAI-FLEXRIC-RAN-Integration-Test',
filter: 'test_results-OAI-FLEXRIC-RAN-Integration-Test.html',
selector: lastCompleted())
}
}
}
}
}
}
// We are only publishing the Ubuntu image to Docker-Hub
// For Post-Merge events.
// Temporary Images from Merge-Request Runs are kept in local private registry
stage ('Pushing Image to Official Registry') {
steps {
lock(ubuntuBuildResource) {
script {
// Only in case of push to target branch!
if ("PUSH".equals(env.gitlabActionType)) {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DockerHubCredentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
sh "echo ${DH_Password} | docker login --username ${DH_Username} --password-stdin"
}
sh "docker login -u oaicicd -p oaicicd ${PrivateRegistryURL}"
sh "docker pull ${PrivateRegistryURL}/oai-flexric:${flexric_tag}"
sh "docker image tag ${PrivateRegistryURL}/oai-flexric:${flexric_tag} ${DH_Account}/oai-flexric:develop"
sh "docker push ${DH_Account}/oai-flexric:develop"
sh "docker rmi ${DH_Account}/oai-flexric:develop ${PrivateRegistryURL}/oai-flexric:${flexric_tag}"
sh "docker logout ${PrivateRegistryURL}"
sh "docker logout"
}
}
}
}
}
}
post {
success {
script {
if ("MERGE".equals(env.gitlabActionType)) {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
echo "This is a MERGE event"
addGitLabMRComment comment: message
}
}
}
unsuccessful {
script {
if ("MERGE".equals(env.gitlabActionType)) {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
echo "This is a MERGE event"
addGitLabMRComment comment: message
}
}
}
cleanup {
script {
// Zipping all archived log files
sh "zip -r -qq docker_logs.zip archives"
if (fileExists('docker_logs.zip')) {
archiveArtifacts artifacts: 'docker_logs.zip'
}
// Generating the HTML report(s)
if ("MERGE".equals(env.gitlabActionType)) {
sh "./ci-scripts/generateHtmlReport.py --job-name ${JOB_NAME} --build-id ${BUILD_ID} --build-url ${BUILD_URL} --git-url ${GIT_URL} --git-src-branch ${env.gitlabSourceBranch} --git-src-commit ${env.gitlabMergeRequestLastCommit} --git-merge-request --git-dst-branch ${env.gitlabTargetBranch} --git-dst-commit ${GIT_COMMIT}"
} else {
sh "./ci-scripts/generateHtmlReport.py --job-name ${JOB_NAME} --build-id ${BUILD_ID} --build-url ${BUILD_URL} --git-url ${GIT_URL} --git-src-branch ${GIT_BRANCH} --git-src-commit ${GIT_COMMIT}"
}
listOfFiles = sh returnStdout: true, script: 'ls test_results*.html'
String[] htmlFiles = listOfFiles.split("\\n")
for (htmlFile in htmlFiles) {
if ("MERGE".equals(env.gitlabActionType)) {
sh "sed -i -e 's#TEMPLATE_MERGE_REQUEST_LINK#${gitlabMergeRequestLink}#g' ${htmlFile}"
sh "sed -i -e 's#TEMPLATE_MERGE_REQUEST_TEMPLATE#${env.gitlabMergeRequestTitle}#' ${htmlFile}"
}
sh "sed -i -e 's#TEMPLATE_TIME#${JOB_TIMESTAMP}#' ${htmlFile}"
archiveArtifacts artifacts: htmlFile
}
}
}
}
}
def prepareWorkspaceMergeCase () {
sh "git clean -x -d -f > /dev/null 2>&1"
sh "git submodule foreach --recursive 'git clean -x -d -ff' > /dev/null 2>&1"
sh "git submodule deinit --force --all > /dev/null 2>&1"
if ("MERGE".equals(env.gitlabActionType)) {
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
}
sh "git submodule update --init --recursive"
sh "mkdir -p archives"
}