| |
@@ -0,0 +1,340 @@
|
| |
+ library identifier: "c3i@master",
|
| |
+ retriever: modernSCM([$class: "GitSCMSource",
|
| |
+ remote: "https://pagure.io/c3i-library.git"])
|
| |
+
|
| |
+ pipeline {
|
| |
+ agent {
|
| |
+ kubernetes {
|
| |
+ cloud params.JENKINS_AGENT_CLOUD_NAME
|
| |
+ label "jenkins-slave-${UUID.randomUUID().toString()}"
|
| |
+ serviceAccount params.JENKINS_AGENT_SERVICE_ACCOUNT
|
| |
+ defaultContainer "jnlp"
|
| |
+ yaml """
|
| |
+ apiVersion: v1
|
| |
+ kind: Pod
|
| |
+ metadata:
|
| |
+ labels:
|
| |
+ app: "jenkins-${env.JOB_BASE_NAME}"
|
| |
+ factory2-pipeline-kind: mbs-koji-int-dev-pipeline
|
| |
+ factory2-pipeline-build-number: "${env.BUILD_NUMBER}"
|
| |
+ spec:
|
| |
+ containers:
|
| |
+ - name: jnlp
|
| |
+ image: "${params.JENKINS_AGENT_IMAGE}"
|
| |
+ imagePullPolicy: Always
|
| |
+ tty: true
|
| |
+ env:
|
| |
+ - name: REGISTRY_CREDENTIALS
|
| |
+ valueFrom:
|
| |
+ secretKeyRef:
|
| |
+ name: "${params.CONTAINER_REGISTRY_CREDENTIALS}"
|
| |
+ key: ".dockerconfigjson"
|
| |
+ resources:
|
| |
+ requests:
|
| |
+ memory: 384Mi
|
| |
+ cpu: 200m
|
| |
+ limits:
|
| |
+ memory: 768Mi
|
| |
+ cpu: 300m
|
| |
+ """
|
| |
+ }
|
| |
+ }
|
| |
+ options {
|
| |
+ timestamps()
|
| |
+ timeout(time: 120, unit: "MINUTES")
|
| |
+ buildDiscarder(logRotator(numToKeepStr: "10"))
|
| |
+ }
|
| |
+ environment {
|
| |
+ // Jenkins BUILD_TAG could be too long (> 63 characters) for OpenShift to consume
|
| |
+ TEST_ID = "${params.TEST_ID ?: 'jenkins-' + currentBuild.id}"
|
| |
+ ENVIRONMENT_LABEL = "test-${env.TEST_ID}"
|
| |
+ PIPELINE_NAMESPACE = readFile("/run/secrets/kubernetes.io/serviceaccount/namespace").trim()
|
| |
+ }
|
| |
+ stages {
|
| |
+ stage("Prepare") {
|
| |
+ steps {
|
| |
+ script {
|
| |
+ def scmVars = checkout([$class: "GitSCM",
|
| |
+ branches: [[name: params.MBS_GIT_REF]],
|
| |
+ userRemoteConfigs: [[url: params.MBS_GIT_REPO, refspec: "+refs/heads/*:refs/remotes/origin/* +refs/pull/*/head:refs/remotes/origin/pull/*/head"]],
|
| |
+ ])
|
| |
+ env.GIT_BRANCH = scmVars.GIT_BRANCH
|
| |
+ env.GIT_COMMIT = scmVars.GIT_COMMIT
|
| |
+ env.GIT_COMMIT_SHORT = env.GIT_COMMIT.substring(0, 7)
|
| |
+ env.MBS_VERSION = sh(script: """grep -m 1 -P -o "(?<=version=')[^']+" setup.py""", returnStdout: true).trim()
|
| |
+ env.BUILD_SUFFIX = ".jenkins${currentBuild.id}.git${env.GIT_COMMIT_SHORT}"
|
| |
+ env.MBS_TEMP_TAG = "${env.MBS_VERSION}${env.BUILD_SUFFIX}"
|
| |
+ echo "Building branch=${env.GIT_BRANCH}, commit=${env.GIT_COMMIT}"
|
| |
+ if (params.BUILD_DISPLAY_RENAME_TO) {
|
| |
+ currentBuild.displayName = params.BUILD_DISPLAY_RENAME_TO
|
| |
+ } else {
|
| |
+ currentBuild.displayName = "Building branch=${env.GIT_BRANCH}, commit=${env.GIT_COMMIT_SHORT}"
|
| |
+ }
|
| |
+ def resp = httpRequest params.MBS_SPEC_FILE
|
| |
+ env.SPEC_FILE_NAME = params.MBS_SPEC_FILE.split("/").last()
|
| |
+ writeFile file: env.SPEC_FILE_NAME, text: resp.content
|
| |
+ sh """
|
| |
+ sed -i \
|
| |
+ -e 's/Version:.*/Version: ${env.MBS_VERSION}/' \
|
| |
+ -e 's/%{?dist}/${env.BUILD_SUFFIX}%{?dist}/' \
|
| |
+ ${env.SPEC_FILE_NAME}
|
| |
+
|
| |
+ """
|
| |
+ sh "mkdir repos"
|
| |
+ for (repo in params.EXTRA_REPOS.split()) {
|
| |
+ resp = httpRequest repo
|
| |
+ writeFile file: "repos/${repo.split("/").last()}", text: resp.content
|
| |
+ }
|
| |
+ }
|
| |
+ sh """
|
| |
+ sed -i \
|
| |
+ -e '/enum34/d' \
|
| |
+ -e '/funcsigs/d' \
|
| |
+ -e '/futures/d' \
|
| |
+ -e '/koji/d' \
|
| |
+ requirements.txt
|
| |
+ sed -i \
|
| |
+ -e 's/py.test/py.test-3/g' \
|
| |
+ -e '/basepython/d' \
|
| |
+ -e '/sitepackages/a setenv = PYTHONPATH={toxinidir}' \
|
| |
+ tox.ini
|
| |
+ """
|
| |
+ }
|
| |
+ }
|
| |
+ stage("Build backend image") {
|
| |
+ environment {
|
| |
+ BACKEND_BUILDCONFIG_ID = "mbs-backend-build-${currentBuild.id}"
|
| |
+ FRONTEND_BUILDCONFIG_ID = "mbs-frontend-build-${currentBuild.id}"
|
| |
+ }
|
| |
+ steps {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ // OpenShift BuildConfig doesn't support specifying a tag name at build time.
|
| |
+ // We have to create a new BuildConfig for each image build.
|
| |
+ echo "Creating a BuildConfig for mbs-backend build..."
|
| |
+ def template = readYaml file: "openshift/integration/koji/containers/backend/mbs-backend-build-template.yaml"
|
| |
+ def processed = openshift.process(template,
|
| |
+ "-p", "NAME=${env.BACKEND_BUILDCONFIG_ID}",
|
| |
+ "-p", "MBS_GIT_REPO=${params.MBS_GIT_REPO}",
|
| |
+ "-p", "MBS_GIT_REF=${params.MBS_GIT_REF}",
|
| |
+ "-p", "MBS_BACKEND_IMAGESTREAM_NAME=${params.MBS_BACKEND_IMAGESTREAM_NAME}",
|
| |
+ "-p", "MBS_BACKEND_IMAGESTREAM_NAMESPACE=${env.PIPELINE_NAMESPACE}",
|
| |
+ "-p", "MBS_IMAGE_TAG=${env.MBS_TEMP_TAG}",
|
| |
+ "-p", "EXTRA_RPMS=${params.EXTRA_RPMS}"
|
| |
+ )
|
| |
+ def buildname = c3i.buildAndWait(processed, "--from-dir=.")
|
| |
+ def build = openshift.selector(buildname)
|
| |
+ def ocpBuild = build.object()
|
| |
+ env.BACKEND_IMAGE_REF = ocpBuild.status.outputDockerImageReference
|
| |
+ env.BACKEND_IMAGE_DIGEST = ocpBuild.status.output.to.imageDigest
|
| |
+ env.BACKEND_IMAGE_TAG = env.MBS_TEMP_TAG
|
| |
+ echo "Built image ${env.BACKEND_IMAGE_REF}, digest: ${env.BACKEND_IMAGE_DIGEST}"
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ post {
|
| |
+ cleanup {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ echo "Tearing down..."
|
| |
+ openshift.selector("bc", [
|
| |
+ "app": env.BACKEND_BUILDCONFIG_ID,
|
| |
+ "template": "mbs-backend-build-template",
|
| |
+ ]).delete()
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stage("Build frontend image") {
|
| |
+ environment {
|
| |
+ FRONTEND_BUILDCONFIG_ID = "mbs-frontend-build-${currentBuild.id}"
|
| |
+ }
|
| |
+ steps {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ // OpenShift BuildConfig doesn't support specifying a tag name at build time.
|
| |
+ // We have to create a new BuildConfig for each container build.
|
| |
+ // Create a BuildConfig from a seperated Template.
|
| |
+ echo "Creating a BuildConfig for mbs-frontend build..."
|
| |
+ def template = readYaml file: "openshift/integration/koji/containers/frontend/mbs-frontend-build-template.yaml"
|
| |
+ def processed = openshift.process(template,
|
| |
+ "-p", "NAME=${env.FRONTEND_BUILDCONFIG_ID}",
|
| |
+ "-p", "MBS_GIT_REPO=${params.MBS_GIT_REPO}",
|
| |
+ "-p", "MBS_GIT_REF=${params.MBS_GIT_REF}",
|
| |
+ "-p", "MBS_FRONTEND_IMAGESTREAM_NAME=${params.MBS_FRONTEND_IMAGESTREAM_NAME}",
|
| |
+ "-p", "MBS_FRONTEND_IMAGESTREAM_NAMESPACE=${env.PIPELINE_NAMESPACE}",
|
| |
+ "-p", "MBS_IMAGE_TAG=${env.MBS_TEMP_TAG}",
|
| |
+ "-p", "MBS_BACKEND_IMAGESTREAM_NAME=${params.MBS_BACKEND_IMAGESTREAM_NAME}",
|
| |
+ "-p", "MBS_BACKEND_IMAGESTREAM_NAMESPACE=${env.PIPELINE_NAMESPACE}"
|
| |
+ )
|
| |
+ def buildname = c3i.buildAndWait(processed)
|
| |
+ def build = openshift.selector(buildname)
|
| |
+ def ocpBuild = build.object()
|
| |
+ env.FRONTEND_IMAGE_REF = ocpBuild.status.outputDockerImageReference
|
| |
+ env.FRONTEND_IMAGE_DIGEST = ocpBuild.status.output.to.imageDigest
|
| |
+ env.FRONTEND_IMAGE_TAG = env.MBS_TEMP_TAG
|
| |
+ echo "Built image ${env.FRONTEND_IMAGE_REF}, digest: ${env.FRONTEND_IMAGE_DIGEST}"
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ post {
|
| |
+ cleanup {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ echo "Tearing down..."
|
| |
+ openshift.selector("bc", [
|
| |
+ "app": env.FRONTEND_BUILDCONFIG_ID,
|
| |
+ "template": "mbs-frontend-build-template",
|
| |
+ ]).delete()
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stage("Run integration tests") {
|
| |
+ steps {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ def testcases
|
| |
+ if (params.TESTCASES) {
|
| |
+ if (params.TESTCASES == "skip") {
|
| |
+ testcases = []
|
| |
+ echo "Skipping integration tests"
|
| |
+ } else {
|
| |
+ testcases = params.TESTCASES.split()
|
| |
+ echo "Using specified list of testcases: ${testcases}"
|
| |
+ }
|
| |
+ } else {
|
| |
+ testcases = findFiles(glob: "openshift/integration/koji/pipelines/tests/*.groovy").collect {
|
| |
+ it.name.minus(".groovy")
|
| |
+ }
|
| |
+ echo "Using all available testcases: ${testcases}"
|
| |
+ }
|
| |
+ def testbc = "bc/${params.MBS_INTEGRATION_TEST_BUILD_CONFIG_NAME}"
|
| |
+ testcases.each { testcase ->
|
| |
+ echo """Starting integration test "${testcase}" for the built images..."""
|
| |
+ def build = c3i.buildAndWait(testbc,
|
| |
+ "-e", "MBS_BACKEND_IMAGE=${env.BACKEND_IMAGE_REF}",
|
| |
+ "-e", "MBS_FRONTEND_IMAGE=${env.FRONTEND_IMAGE_REF}",
|
| |
+ "-e", "MBS_GIT_REPO=${params.MBS_GIT_REPO}",
|
| |
+ "-e", "MBS_GIT_REF=${params.MBS_GIT_REF}",
|
| |
+ "-e", "TESTCASE=${testcase}",
|
| |
+ "-e", "CLEANUP=${params.CLEANUP}",
|
| |
+ "-e", "BUILD_DISPLAY_RENAME_TO='${currentBuild.displayName}'"
|
| |
+ )
|
| |
+ echo """Integration test "${testcase}" PASSED"""
|
| |
+ }
|
| |
+ echo "All integration tests PASSED"
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stage("Tag into ImageStreams") {
|
| |
+ when {
|
| |
+ expression {
|
| |
+ return "${params.MBS_DEV_IMAGE_TAG}" && params.TAG_INTO_IMAGESTREAM == "true" &&
|
| |
+ (params.FORCE_PUBLISH_IMAGE == "true" || params.MBS_GIT_REF == params.MBS_MAIN_BRANCH)
|
| |
+ }
|
| |
+ }
|
| |
+ steps {
|
| |
+ script {
|
| |
+ openshift.withCluster() {
|
| |
+ openshift.withProject(params.MBS_BACKEND_IMAGESTREAM_NAMESPACE) {
|
| |
+ def sourceRef = "${params.MBS_BACKEND_IMAGESTREAM_NAME}:${env.BACKEND_IMAGE_TAG}"
|
| |
+ def destRef = "${params.MBS_BACKEND_IMAGESTREAM_NAME}:${params.MBS_DEV_IMAGE_TAG}"
|
| |
+ echo "Tagging ${sourceRef} as ${destRef}..."
|
| |
+ openshift.tag(sourceRef, destRef)
|
| |
+ }
|
| |
+ openshift.withProject(params.MBS_FRONTEND_IMAGESTREAM_NAMESPACE) {
|
| |
+ def sourceRef = "${params.MBS_FRONTEND_IMAGESTREAM_NAME}:${env.FRONTEND_IMAGE_TAG}"
|
| |
+ def destRef = "${params.MBS_FRONTEND_IMAGESTREAM_NAME}:${params.MBS_DEV_IMAGE_TAG}"
|
| |
+ echo "Tagging ${sourceRef} as ${destRef}..."
|
| |
+ openshift.tag(sourceRef, destRef)
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ stage("Push images") {
|
| |
+ when {
|
| |
+ expression {
|
| |
+ return params.FORCE_PUBLISH_IMAGE == "true" || params.MBS_GIT_REF == params.MBS_MAIN_BRANCH
|
| |
+ }
|
| |
+ }
|
| |
+ steps {
|
| |
+ script {
|
| |
+ if (env.REGISTRY_CREDENTIALS) {
|
| |
+ dir ("${env.HOME}/.docker") {
|
| |
+ writeFile file:"config.json", text: env.REGISTRY_CREDENTIALS
|
| |
+ }
|
| |
+ }
|
| |
+ def registryToken = readFile(file: "/var/run/secrets/kubernetes.io/serviceaccount/token")
|
| |
+ def copyDown = { name, src ->
|
| |
+ src = "docker://${src}"
|
| |
+ echo "Pulling ${name} from ${src}..."
|
| |
+ withEnv(["SOURCE_IMAGE_REF=${src}", "TOKEN=${registryToken}"]) {
|
| |
+ sh """
|
| |
+ set -e +x # hide the token from Jenkins console
|
| |
+ mkdir -p _images
|
| |
+ skopeo copy \
|
| |
+ --src-cert-dir=/var/run/secrets/kubernetes.io/serviceaccount/ \
|
| |
+ --src-creds=serviceaccount:"$TOKEN" \
|
| |
+ "$SOURCE_IMAGE_REF" dir:_images/${name}
|
| |
+ """
|
| |
+ }
|
| |
+ }
|
| |
+ def pullJobs = [
|
| |
+ "Pulling backend" : { copyDown("backend", env.BACKEND_IMAGE_REF) },
|
| |
+ "Pulling frontend" : { copyDown("frontend", env.FRONTEND_IMAGE_REF) }
|
| |
+ ]
|
| |
+ parallel pullJobs
|
| |
+ def copyUp = { name, dest ->
|
| |
+ if (!dest.startsWith("atomic:") && !dest.startsWith("docker://")) {
|
| |
+ dest = "docker://${dest}"
|
| |
+ }
|
| |
+ echo "Pushing ${name} to ${dest}..."
|
| |
+ withEnv(["DEST_IMAGE_REF=${dest}"]) {
|
| |
+ sh """
|
| |
+ skopeo copy dir:_images/${name} "$DEST_IMAGE_REF"
|
| |
+ """
|
| |
+ }
|
| |
+ }
|
| |
+ def backendDests = params.MBS_BACKEND_DEV_IMAGE_DESTINATIONS ?
|
| |
+ params.MBS_BACKEND_DEV_IMAGE_DESTINATIONS.split(",") : []
|
| |
+ def frontendDests = params.MBS_FRONTEND_DEV_IMAGE_DESTINATIONS ?
|
| |
+ params.MBS_FRONTEND_DEV_IMAGE_DESTINATIONS.split(",") : []
|
| |
+ def pushJobs = backendDests.collectEntries {
|
| |
+ [ "Pushing backend to ${it}" : { copyUp("backend", it) } ]
|
| |
+ }
|
| |
+ pushJobs << frontendDests.collectEntries {
|
| |
+ [ "Pushing frontend to ${it}" : { copyUp("frontend", it) } ]
|
| |
+ }
|
| |
+ parallel pushJobs
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ post {
|
| |
+ cleanup {
|
| |
+ script {
|
| |
+ if (params.CLEANUP == "true") {
|
| |
+ openshift.withCluster() {
|
| |
+ if (env.BACKEND_IMAGE_TAG) {
|
| |
+ echo "Removing tag ${env.BACKEND_IMAGE_TAG} from the ${params.MBS_BACKEND_IMAGESTREAM_NAME} ImageStream..."
|
| |
+ openshift.withProject(params.MBS_BACKEND_IMAGESTREAM_NAMESPACE) {
|
| |
+ openshift.tag("${params.MBS_BACKEND_IMAGESTREAM_NAME}:${env.BACKEND_IMAGE_TAG}", "-d")
|
| |
+ }
|
| |
+ }
|
| |
+ if (env.FRONTEND_IMAGE_TAG) {
|
| |
+ echo "Removing tag ${env.FRONTEND_IMAGE_TAG} from the ${params.MBS_FRONTEND_IMAGESTREAM_NAME} ImageStream..."
|
| |
+ openshift.withProject(params.MBS_FRONTEND_IMAGESTREAM_NAMESPACE) {
|
| |
+ openshift.tag("${params.MBS_FRONTEND_IMAGESTREAM_NAME}:${env.FRONTEND_IMAGE_TAG}", "-d")
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
+ }
|
| |
This is another test PR.