#369 C3I: use of pipeline-as-a-service, reduce number of jobs
Merged 10 months ago by lholecek. Opened 11 months ago by mkovarik.
mkovarik/waiverdb templating-final  into  master

file modified
+1 -1
@@ -22,7 +22,7 @@ 

  	@for job in $(JOBS); do \

  		echo "[PIPELINE] Updating pipeline job \"$${job}\"..." ; \

  	  template_file=$$(cat ./$(JOBS_DIR)/$${job}.tmpl); \

- 		$(OC_CMD) process --local -f ./$(TEMPLATES_DIR)/$${template_file} \

+ 		jinja2 ./$(TEMPLATES_DIR)/$${template_file} | $(OC_CMD) process --local -f - \

  			--param-file ./$(JOBS_DIR)/$${job}.env | $(OC_CMD) apply -f -; \

  		echo "[PIPELINE] Pipeline job \"$${job}\" updated" ; \

  	done

@@ -1,2 +0,0 @@ 

- NAME=waiverdb-dev-integration-test

- IMAGE=quay.io/factory2/waiverdb:latest

@@ -1,1 +0,0 @@ 

- waiverdb-integration-test-template.yaml

@@ -1,3 +0,0 @@ 

- # This job is deprecated. New jobs are waiverdb-premerge and waiverdb-postmerge

- NAME=waiverdb-dev

- PAGURE_DOC_REPO_NAME= # Temporarily disable doc push to workaround https://pagure.io/pagure/issue/3919. Remove this line when it is fixed.

@@ -1,1 +0,0 @@ 

- waiverdb-build-template.yaml

@@ -3,4 +3,4 @@ 

  TARGET_TAG=prod

  DECISION_CONTEXT_REGEX=c3i_promote_stage_to_prod

  MESSAGING_TOPIC=Consumer.rh-jenkins-ci-plugin.c3i-waiverdb-promote-to-prod.VirtualTopic.eng.greenwave.decision.update

- IMAGE_PROMOTION_JOB=waiverdb-promoting-to-prod

+ PROMOTING_DESTINATIONS=quay.io/factory2/waiverdb

@@ -3,4 +3,4 @@ 

  TARGET_TAG=stage

  DECISION_CONTEXT_REGEX=c3i_promote_dev_to_stage

  MESSAGING_TOPIC=Consumer.rh-jenkins-ci-plugin.c3i-waiverdb-promote-to-stage.VirtualTopic.eng.greenwave.decision.update

- IMAGE_PROMOTION_JOB=waiverdb-promoting-to-stage

+ PROMOTING_DESTINATIONS=quay.io/factory2/waiverdb

@@ -1,2 +0,0 @@ 

- NAME=waiverdb-integration-test

- IMAGE=quay.io/factory2/waiverdb:latest

@@ -1,1 +0,0 @@ 

- waiverdb-integration-test-template.yaml

@@ -1,5 +0,0 @@ 

- NAME=waiverdb-prod-integration-test

- IMAGE=quay.io/factory2/waiverdb:prod

- ENVIRONMENT=prod

- BACKEND_INTEGRATION_TEST_JOB=factory2-prod-integration-test

- BACKEND_INTEGRATION_TEST_JOB_NAMESPACE=c3i

@@ -1,1 +0,0 @@ 

- waiverdb-full-integration-test-template.yaml

@@ -1,3 +0,0 @@ 

- NAME=waiverdb-promoting-to-prod

- IMAGE=quay.io/factory2/waiverdb:stage

- DEST_TAG=prod

@@ -1,1 +0,0 @@ 

- waiverdb-image-promotion-template.yaml

@@ -1,3 +0,0 @@ 

- NAME=waiverdb-promoting-to-stage

- IMAGE=quay.io/factory2/waiverdb:latest

- DEST_TAG=stage

@@ -1,1 +0,0 @@ 

- waiverdb-image-promotion-template.yaml

@@ -1,5 +0,0 @@ 

- NAME=waiverdb-stage-integration-test

- IMAGE=quay.io/factory2/waiverdb:stage

- ENVIRONMENT=stage

- BACKEND_INTEGRATION_TEST_JOB=factory2-stage-integration-test

- BACKEND_INTEGRATION_TEST_JOB_NAMESPACE=c3i

@@ -1,1 +0,0 @@ 

- waiverdb-full-integration-test-template.yaml

@@ -1,4 +1,4 @@ 

  NAME=waiverdb-trigger-on-latest-tag

  MESSAGING_TOPIC=Consumer.rh-jenkins-ci-plugin.c3i-waiverdb-trigger-on-latest-tag.VirtualTopic.eng.repotracker.container.tag.>

- TEST_JOB_NAME=waiverdb-stage-integration-test

+ ENVIRONMENT=stage

  TRACKED_TAG=latest

@@ -1,4 +1,4 @@ 

  NAME=waiverdb-trigger-on-stage-tag

  MESSAGING_TOPIC=Consumer.rh-jenkins-ci-plugin.c3i-waiverdb-trigger-on-stage-tag.VirtualTopic.eng.repotracker.container.tag.>

- TEST_JOB_NAME=waiverdb-prod-integration-test

  TRACKED_TAG=stage

+ ENVIRONMENT=prod

@@ -0,0 +1,8 @@ 

+ - name: C3I_LIB_URL

+   displayName: C3I library git url

+   required: true

+   value: "https://pagure.io/c3i-library.git"

+ - name: C3I_LIB_BRANCH

+   displayName: C3I library branch

+   required: true

+   value: "master"

@@ -0,0 +1,2 @@ 

+ library identifier: "c3i@${C3I_LIB_BRANCH}", changelog: false,

+   retriever: modernSCM([$class: 'GitSCMSource', remote: "${C3I_LIB_URL}"])

@@ -0,0 +1,29 @@ 

+ agent {

+   kubernetes {

+     cloud "${params.OPENSHIFT_CLOUD_NAME}"

+     label "jenkins-slave-${UUID.randomUUID().toString()}"

+     serviceAccount "${params.JENKINS_AGENT_SERVICE_ACCOUNT}"

+     defaultContainer 'jnlp'

+     yaml """

+     apiVersion: v1

+     kind: Pod

+     metadata:

+       labels:

+         app: "${env.JOB_BASE_NAME}"

+         factory2-pipeline-build-number: "${env.BUILD_NUMBER}"

+     spec:

+       containers:

+       - name: jnlp

+         image: "${params.JENKINS_AGENT_IMAGE}"

+         imagePullPolicy: Always

+         tty: true

+         resources:

+           requests:

+             memory: 512Mi

+             cpu: 200m

+           limits:

+             memory: 768Mi

+             cpu: 300m

+     """

+   }

+ }

@@ -0,0 +1,94 @@ 

+ stage('Run integration tests') {

+   stages {

+     stage('Request Pipeline') {

+       steps {

+         script {

+           if (!env.TRIGGER_NAMESPACE) {

+             env.TRIGGER_NAMESPACE = readFile("/run/secrets/kubernetes.io/serviceaccount/namespace").trim()

+           }

+           if (!env.PAAS_DOMAIN) {

+             openshift.withCluster() {

+               openshift.withProject(env.TRIGGER_NAMESPACE) {

+                 def testroute = openshift.create('route', 'edge', "test-${env.BUILD_NUMBER}",  '--service=test', '--port=8080')

+                 def testhost = testroute.object().spec.host

+                 env.PAAS_DOMAIN = testhost.minus("test-${env.BUILD_NUMBER}-${env.TRIGGER_NAMESPACE}.")

+                 testroute.delete()

+               }

+             }

+             echo "Routes end with ${env.PAAS_DOMAIN}"

+           }

+           env.PIPELINE_ID = 'c3i-pipeline-' + UUID.randomUUID().toString().substring(0,4)

+           openshift.withCluster() {

+             openshift.withProject(params.PIPELINE_AS_A_SERVICE_BUILD_NAMESPACE) {

+               c3i.buildAndWait(script: this, objs: "bc/pipeline-as-a-service",

+                 '-e', "DEFAULT_IMAGE_TAG=${env.ENVIRONMENT}",

+                 '-e', "WAIVERDB_IMAGE=${env.IMAGE}",

+                 '-e', "PIPELINE_ID=${env.PIPELINE_ID}",

+                 '-e', "PAAS_DOMAIN=${env.PAAS_DOMAIN}",

+                 '-e', "SERVICES_TO_DEPLOY='resultsdb-updater datanommer greenwave resultsdb umb waiverdb datagrepper'",

+                 '-e', "TRIGGERED_BY=${env.BUILD_URL}"

+               )

+             }

+           }

+         }

+       }

+     }

+     stage('Run integration test') {

+       steps {

+         script {

+           c3i.clone(repo: params.BACKEND_INTEGRATION_TEST_REPO,

+             branch: params.BACKEND_INTEGRATION_TEST_REPO_BRANCH)

+           sh "${env.WORKSPACE}/${BACKEND_INTEGRATION_TEST_FILE} https://${env.PIPELINE_ID}.${env.PAAS_DOMAIN}"

+         }

+       }

+     }

+   }

+   post {

+     changed {

+       script {

+         if (params.MAIL_ADDRESS) {

+           emailext to: "${env.MAIL_ADDRESS}",

+           subject: "${env.JOB_NAME} ${env.BUILD_NUMBER} changed: ${currentBuild.result}",

+           body: "${env.JOB_NAME} ${env.BUILD_NUMBER} changed. Current status: ${currentBuild.result}. You can check it out: ${env.BUILD_URL}"

+         }

+       }

+     }

+     always {

+       script {

+         if (!env.MESSAGING_PROVIDER) {

+           // Don't send a message if messaging provider is not configured

+           return

+         }

+         pipeline_data = controller.getVars()

+         c3i.sendResultToMessageBus(

+           pipeline_data.WAIVERDB_IMAGE,

+           pipeline_data.WAIVERDB_IMAGE_DIGEST,

+           env.BUILD_TAG,

+           env.TARGET_IMAGE_IS_SCRATCH == "true",

+           env.MESSAGING_PROVIDER

+         )

+       }

+     }

+     failure {

+       script {

+         env.TESTCASE_CATEGORY = env.ENVIRONMENT

+         c3i.archiveContainersLogs(env.PIPELINE_ID)

+       }

+     }

+     cleanup {

+       script {

+         if (env.NO_CLEANUP_AFTER_TEST == 'true') {

+           return

+         }

+         openshift.withCluster() {

+           openshift.withProject(env.PIPELINE_ID) {

+             /* Tear down everything we just created */

+             echo 'Tearing down test resources...'

+             openshift.selector('all,pvc,configmap,secret',

+                                ['c3i.redhat.com/pipeline': env.PIPELINE_ID]).delete('--ignore-not-found=true')

+           }

+         }

+       }

+     }

+   }

+ }

openshift/pipelines/templates/snippets/waiverdb-integration-test.groovy openshift/pipelines/templates/waiverdb-integration-test.Jenkinsfile
file renamed
+14 -76
@@ -1,55 +1,10 @@ 

- import java.text.*

- 

- library identifier: 'c3i@master', changelog: false,

-   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: "${env.JOB_BASE_NAME}"

-           factory2-pipeline-kind: "waiverdb-integration-test-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: 512Mi

-               cpu: 200m

-             limits:

-               memory: 768Mi

-               cpu: 300m

-       """

-     }

-   }

-   options {

-     timestamps()

-     timeout(time: 30, unit: 'MINUTES')

-   }

+ stage("Functional tests phase") {

    stages {

      stage('Prepare') {

        steps {

-         checkout([$class: 'GitSCM',

-           branches: [[name: params.WAIVERDB_GIT_REF]],

-           userRemoteConfigs: [[url: params.WAIVERDB_GIT_REPO, refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull/*/head:refs/remotes/origin/pull/*/head']],

-         ])

+         script {

+           env.IMAGE = "${env.RESULTING_IMAGE_REPO}:${env.RESULTING_TAG}"

+         }

        }

      }

      stage('Cleanup') {
@@ -57,29 +12,8 @@ 

        steps {

          script {

            openshift.withCluster() {

-             def df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

-             df.setTimeZone(TimeZone.getTimeZone('UTC'))

-             // Get all OpenShift objects of previous test environments

-             def oldObjs = openshift.selector('dc,deploy,configmap,secret,svc,route',

-               ['template': 'waiverdb-test', 'app':'waiverdb'])

-             def now = new Date()

-             // Delete all objects that are older than 1 hour

-             for (objName in oldObjs.names()) {

-               def obj = openshift.selector(objName)

-               def objData = obj.object()

-               if (!objData.metadata.creationTimestamp)

-                 continue

-               def creationTime = df.parse(objData.metadata.creationTimestamp)

-               // 1 hour = 1000 * 60 * 60 ms

-               if (now.getTime() - creationTime.getTime() < 1000 * 60 * 60)

-                 continue

-               echo "Deleting ${objName}..."

-               try {

-                 obj.delete()

-                 echo "Deleted ${objName}"

-               } catch (e) {

-                 echo "Error deleting ${objName}: ${e.message}"

-               }

+             openshift.withProject(env.PIPELINE_ID) {

+               c3i.cleanup(script: this, age: 60, 'waiverdb')

              }

            }

          }
@@ -91,7 +25,7 @@ 

          TEST_ID = "${params.TEST_ID ?: 'jenkins-' + currentBuild.id + '-' + UUID.randomUUID().toString().substring(0,7)}"

        }

        steps {

-         echo "Container image ${params.IMAGE} will be tested."

+         echo "Container image ${env.IMAGE} will be tested."

          script {

            openshift.withCluster() {

              // Don't set ENVIRONMENT_LABEL in the environment block! Otherwise you will get 2 different UUIDs.
@@ -101,7 +35,7 @@ 

              echo "Creating testing environment with TEST_ID=${env.TEST_ID}..."

              def models = openshift.process(template,

                '-p', "TEST_ID=${env.TEST_ID}",

-               '-p', "WAIVERDB_APP_IMAGE=${params.IMAGE}",

+               '-p', "WAIVERDB_APP_IMAGE=${env.IMAGE}",

                '-p', "WAIVERDB_REPLICAS=${webPodReplicas}",

              )

              c3i.deployAndWait(script: this, objs: models, timeout: 15)
@@ -151,6 +85,10 @@ 

            // Don't send a message if the job fails before getting the image digest.

            return;

          }

+         if (!env.MESSAGING_PROVIDER) {

+           // Don't send a message if messaging provider is not configured

+           return

+         }

          // currentBuild.result == null || currentBuild.result == 'SUCCESS' indicates a successful build,

          // because it's possible that the pipeline engine hasn't set the value nor seen an error when reaching to this line.

          // See example code in https://jenkins.io/doc/book/pipeline/jenkinsfile/#deploy
@@ -180,9 +118,9 @@ 

                "type": "container-image",

                "repository": "factory2/waiverdb",

                "digest": "${env.IMAGE_DIGEST}",

-               "nvr": "${params.IMAGE}",

+               "nvr": "${env.IMAGE}",

                "issuer": "c3i-jenkins",

-               "scratch": ${params.IMAGE_IS_SCRATCH},

+               "scratch": ${params.WAIVERDB_GIT_REF != params.WAIVERDB_MAIN_BRANCH},

                "id": "waiverdb@${env.IMAGE_DIGEST}"

              },

              "system":

@@ -46,7 +46,7 @@ 

    description: If WAIVERDB_MAIN_BRANCH equals WAIVERDB_GIT_REF, this is a post-merge build, otherwise it's a pre-merge build.

    value: master

    required: true

- - name: JENKINS_AGENT_CLOUD_NAME

+ - name: OPENSHIFT_CLOUD_NAME

    displayName: Name of OpenShift cloud in Jenkins master configuration

    required: true

    value: openshift
@@ -102,6 +102,9 @@ 

    displayName: Whether to tag the pushed image as dev

    value: "true"

    required: true

+ - name: MESSAGING_PROVIDER

+   displayName: Name of the JMS messaging provider

+   value: Red Hat UMB

  - name: PAGURE_URL

    displayName: Pagure URL

    value: https://pagure.io
@@ -114,6 +117,7 @@ 

    value: 'pagure-api-key'

  - name: MAIL_ADDRESS

    displayName: If set, build failure messages to this mail address.

+ {% include "snippets/c3i-library-parameters.yaml" %}

  labels:

    template: waiverdb-build

  objects:
@@ -179,10 +183,6 @@ 

    spec:

      runPolicy: "Serial"

      completionDeadlineSeconds: 1800

-     source:

-       git:

-         uri: "${WAIVERDB_GIT_REPO}"

-         ref: "${WAIVERDB_MAIN_BRANCH}"

      strategy:

        type: JenkinsPipeline

        jenkinsPipelineStrategy:
@@ -191,8 +191,8 @@ 

            value: "${WAIVERDB_GIT_REPO}"

          - name: "WAIVERDB_GIT_REF"

            value: "${WAIVERDB_GIT_REF}"

-         - name: "JENKINS_AGENT_CLOUD_NAME"

-           value: "${JENKINS_AGENT_CLOUD_NAME}"

+         - name: "OPENSHIFT_CLOUD_NAME"

+           value: "${OPENSHIFT_CLOUD_NAME}"

          - name: "JENKINS_AGENT_IMAGE"

            value:  "${JENKINS_AGENT_IMAGE}"

          - name: "JENKINS_AGENT_SERVICE_ACCOUNT"
@@ -223,6 +223,8 @@ 

            value: "${WAIVERDB_INTEGRATION_TEST_BUILD_CONFIG_NAME}"

          - name: "WAIVERDB_INTEGRATION_TEST_BUILD_CONFIG_NAMESPACE"

            value: "${WAIVERDB_INTEGRATION_TEST_BUILD_CONFIG_NAMESPACE}"

+         - name: "MESSAGING_PROVIDER"

+           value: "${MESSAGING_PROVIDER}"

          - name: PAGURE_REPO_NAME

            value: "${PAGURE_REPO_NAME}"

          - name: PAGURE_REPO_IS_FORK
@@ -233,4 +235,5 @@ 

            value: "${PAGURE_API_KEY_SECRET_NAME}"

          - name: MAIL_ADDRESS

            value: "${MAIL_ADDRESS}"

-         jenkinsfilePath: openshift/pipelines/templates/waiverdb-build.Jenkinsfile

+         jenkinsfile: |

+           {% filter indent(width=10) %}{% include "waiverdb-build.Jenkinsfile" %}{% endfilter %}

@@ -1,10 +1,9 @@ 

- library identifier: 'c3i@master', changelog: false,

-   retriever: modernSCM([$class: 'GitSCMSource', remote: 'https://pagure.io/c3i-library.git'])

+ {% include "snippets/c3i-library.groovy" %}

  import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;

  pipeline {

    agent {

      kubernetes {

-       cloud params.JENKINS_AGENT_CLOUD_NAME

+       cloud params.OPENSHIFT_CLOUD_NAME

        label "jenkins-slave-${UUID.randomUUID().toString()}"

        serviceAccount params.JENKINS_AGENT_SERVICE_ACCOUNT

        defaultContainer 'jnlp'
@@ -23,11 +22,6 @@ 

            imagePullPolicy: Always

            tty: true

            env:

-           - name: REGISTRY_CREDENTIALS

-             valueFrom:

-               secretKeyRef:

-                 name: "${params.CONTAINER_REGISTRY_CREDENTIALS}"

-                 key: '.dockerconfigjson'

            # Required by unit tests: Set up NSS Wrapper to generate a fake user name for the random UID assigned by OpenShift

            - name: LD_PRELOAD

              value: '/usr/lib64/libnss_wrapper.so'
@@ -76,7 +70,7 @@ 

      timeout(time: 30, unit: 'MINUTES')

    }

    environment {

-     PIPELINE_NAMESPACE = readFile('/run/secrets/kubernetes.io/serviceaccount/namespace').trim()

+     TRIGGER_NAMESPACE = readFile('/run/secrets/kubernetes.io/serviceaccount/namespace').trim()

      PIPELINE_USERNAME = sh(returnStdout: true, script: 'id -un').trim()

      PAGURE_API = "${params.PAGURE_URL}/api/0"

      PAGURE_REPO_IS_FORK = "${params.PAGURE_REPO_IS_FORK}"
@@ -99,6 +93,9 @@ 

            env.WAIVERDB_GIT_COMMIT = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()

            echo "Build ${params.WAIVERDB_GIT_REF}, commit=${env.WAIVERDB_GIT_COMMIT}"

  

+           // Set GIT_COMMIT for pagure in c3i lib

+           env.GIT_COMMIT = env.WAIVERDB_GIT_COMMIT

+ 

            // Is the current branch a pull-request? If no, env.PR_NO will be empty.

            env.PR_NO = getPrNo(params.WAIVERDB_GIT_REF)

  
@@ -133,13 +130,11 @@ 

              // To enable HTML syntax in build description, go to `Jenkins/Global Security/Markup Formatter` and select 'Safe HTML'.

              def pagureLink = """<a href="${env.PR_URL}">${currentBuild.displayName}</a>"""

              try {

-               def prInfo = withPagure {

-                 it.getPR(env.PR_NO)

-               }

+               def prInfo = pagure.getPR(env.PR_NO)

                pagureLink = """<a href="${env.PR_URL}">PR#${env.PR_NO}: ${escapeHtml(prInfo.title)}</a>"""

                // set PR status to Pending

                if (params.PAGURE_API_KEY_SECRET_NAME)

-                 setBuildStatusOnPagurePR(null, 'Building...')

+                 pagure.setBuildStatusOnPR(null, 'Building...')

              } catch (Exception e) {

                echo "Error using pagure API: ${e}"

              }
@@ -149,7 +144,7 @@ 

              currentBuild.description = """<a href="${env.PAGURE_REPO_HOME}/c/${env.WAIVERDB_GIT_COMMIT}">${currentBuild.displayName}</a>"""

              if (params.PAGURE_API_KEY_SECRET_NAME) {

                try {

-                 flagCommit('pending', null, 'Building...')

+                 pagure.flagCommit('pending', null, 'Building...')

                  echo "Updated commit ${env.WAIVERDB_GIT_COMMIT} status to PENDING."

                } catch (e) {

                  echo "Error updating commit ${env.WAIVERDB_GIT_COMMIT} status to PENDING: ${e}"
@@ -212,7 +207,7 @@ 

                  }

                }

                steps {

-                 sshagent (credentials: ["${env.PIPELINE_NAMESPACE}-${params.PAGURE_DOC_SECRET}"]) {

+                 sshagent (credentials: ["${env.TRIGGER_NAMESPACE}-${params.PAGURE_DOC_SECRET}"]) {

                    sh '''

                    mkdir -p ~/.ssh/

                    touch ~/.ssh/known_hosts
@@ -319,29 +314,7 @@ 

          }

        }

      }

-     stage('Run functional tests') {

-       steps {

-         script {

-           openshift.withCluster() {

-             openshift.withProject(params.WAIVERDB_INTEGRATION_TEST_BUILD_CONFIG_NAMESPACE) {

-               echo 'Starting a functional test for the built container image...'

-               c3i.buildAndWait(script: this, objs: "bc/${params.WAIVERDB_INTEGRATION_TEST_BUILD_CONFIG_NAME}",

-                 '-e', "WAIVERDB_GIT_REPO=${params.WAIVERDB_GIT_REPO}",

-                 '-e', "IMAGE=${env.RESULTING_IMAGE_REPO}:${env.RESULTING_TAG}",

-                 '-e', "WAIVERDB_GIT_REF=${env.PR_NO ? env.WAIVERDB_GIT_REF : env.WAIVERDB_GIT_COMMIT}",

-                 '-e', "IMAGE_IS_SCRATCH=${params.WAIVERDB_GIT_REF != params.WAIVERDB_MAIN_BRANCH}"

-               )

-               echo "Functional test passed."

-             }

-           }

-         }

-       }

-       post {

-         failure {

-           echo "Functional test failed."

-         }

-       }

-     }

+     {% include "snippets/waiverdb-integration-test.groovy" %}

      stage('Push container') {

        when {

          expression {
@@ -355,10 +328,11 @@ 

              env.WAIVERDB_DEV_IMAGE_DESTINATIONS.split(',') : []

            openshift.withCluster() {

              def sourceImage = env.RESULTING_IMAGE_REPO + ":" + env.RESULTING_TAG

-             if (env.REGISTRY_CREDENTIALS) {

-                dir ("${env.HOME}/.docker") {

-                     writeFile file:'config.json', text: env.REGISTRY_CREDENTIALS

-                }

+             if (params.CONTAINER_REGISTRY_CREDENTIALS) {

+               dir ("${env.HOME}/.docker") {

+                 def dockerconf = openshift.selector('secret', params.CONTAINER_REGISTRY_CREDENTIALS).object().data['.dockerconfigjson']

+                 writeFile file: 'config.json', text: dockerconf, encoding: "Base64"

+               }

              }

              // pull the built image from imagestream

              echo "Pulling container from ${sourceImage}..."
@@ -436,7 +410,7 @@ 

          // on pre-merge workflow success

          if (params.PAGURE_API_KEY_SECRET_NAME && env.PR_NO) {

            try {

-             setBuildStatusOnPagurePR(100, 'Build passed.')

+             pagure.setBuildStatusOnPR(100, 'Build passed.')

              echo "Updated PR #${env.PR_NO} status to PASS."

            } catch (e) {

              echo "Error updating PR #${env.PR_NO} status to PASS: ${e}"
@@ -445,7 +419,7 @@ 

          // on post-merge workflow success

          if (params.PAGURE_API_KEY_SECRET_NAME && !env.PR_NO) {

            try {

-             flagCommit('success', 100, 'Build passed.')

+             pagure.flagCommit('success', 100, 'Build passed.')

              echo "Updated commit ${env.WAIVERDB_GIT_COMMIT} status to PASS."

            } catch (e) {

              echo "Error updating commit ${env.WAIVERDB_GIT_COMMIT} status to PASS: ${e}"
@@ -459,17 +433,17 @@ 

          if (params.PAGURE_API_KEY_SECRET_NAME && env.PR_NO) {

            // updating Pagure PR flag

            try {

-             setBuildStatusOnPagurePR(0, 'Build failed.')

+             pagure.setBuildStatusOnPR(0, 'Build failed.')

              echo "Updated PR #${env.PR_NO} status to FAILURE."

            } catch (e) {

              echo "Error updating PR #${env.PR_NO} status to FAILURE: ${e}"

            }

            // making a comment

            try {

-             commentOnPR("""

+             pagure.commentOnPR("""

              Build ${env.WAIVERDB_GIT_COMMIT} [FAILED](${env.BUILD_URL})!

              Rebase or make new commits to rebuild.

-             """.stripIndent())

+             """.stripIndent(), env.PR_NO)

              echo "Comment made."

            } catch (e) {

              echo "Error making a comment on PR #${env.PR_NO}: ${e}"
@@ -480,7 +454,7 @@ 

            // updating Pagure commit flag

            if (params.PAGURE_API_KEY_SECRET_NAME) {

              try {

-               flagCommit('failure', 0, 'Build failed.')

+               pagure.flagCommit('failure', 0, 'Build failed.')

                echo "Updated commit ${env.WAIVERDB_GIT_COMMIT} status to FAILURE."

              } catch (e) {

                echo "Error updating commit ${env.WAIVERDB_GIT_COMMIT} status to FAILURE: ${e}"
@@ -504,38 +478,7 @@ 

    def prMatch = branch =~ /^(?:.+\/)?pull\/(\d+)\/head$/

    return prMatch ? prMatch[0][1] : ''

  }

- def withPagure(args=[:], cl) {

-   args.apiUrl = env.PAGURE_API

-   args.repo = env.PAGURE_REPO_NAME

-   args.isFork = env.PAGURE_REPO_IS_FORK == 'true'

-   def pagureClient = pagure.client(args)

-   return cl(pagureClient)

- }

- def withPagureCreds(args=[:], cl) {

-   def pagureClient = null

-   withCredentials([string(credentialsId: "${env.PIPELINE_NAMESPACE}-${env.PAGURE_API_KEY_SECRET_NAME}", variable: 'TOKEN')]) {

-     args.token = env.TOKEN

-     pagureClient = withPagure(args, cl)

-   }

-   return pagureClient

- }

- def setBuildStatusOnPagurePR(percent, String comment) {

-   withPagureCreds {

-     it.updatePRStatus(username: 'c3i-jenkins', uid: 'ci-pre-merge',

-       url: env.BUILD_URL, percent: percent, comment: comment, pr: env.PR_NO)

-   }

- }

- def flagCommit(status, percent, comment) {

-   withPagureCreds {

-     it.flagCommit(username: 'c3i-jenkins', uid: "ci-post-merge-${env.WAIVERDB_GIT_COMMIT.substring(0, 7)}", status: status,

-       url: env.BUILD_URL, percent: percent, comment: comment, commit: env.WAIVERDB_GIT_COMMIT)

-   }

- }

- def commentOnPR(String comment) {

-   withPagureCreds {

-     it.commentOnPR(comment: comment, pr: env.PR_NO)

-   }

- }

+ 

  def sendBuildStatusEmail(String status) {

    def recipient = params.MAIL_ADDRESS

    def subject = "Jenkins job ${env.JOB_NAME} #${env.BUILD_NUMBER} ${status}."

@@ -1,117 +0,0 @@ 

- # Template to produce a new OpenShift pipeline for running integration tests

- #

- ---

- apiVersion: v1

- kind: Template

- metadata:

-   name: waiverdb-full-integration-test

- labels:

-   template: waiverdb-full-integration-test

- parameters:

- - name: NAME

-   displayName: Short unique identifier for the templated instances

-   description: This field is used to deploy multiple pipelines to one OpenShift project from this template.

-   required: true

-   value: waiverdb-full-integration-test

- - name: IMAGE

-   displayName: The container image to be tested

-   description: This field must be in repo:tag or repo@sha256 format

-   value: quay.io/factory2/waiverdb:latest

- - name: WAIVERDB_GIT_REPO

-   displayName: WaiverDB Git repo URL

-   description: Default WaiverDB Git repo URL in which to run functional tests against

-   required: true

-   value: "https://pagure.io/waiverdb.git"

- - name: WAIVERDB_GIT_REF

-   displayName: WaiverDB Git repo ref

-   description: Default WaiverDB Git repo ref in which to run functional tests against

-   required: true

-   value: master

- - name: JENKINS_AGENT_IMAGE

-   displayName: Container image for Jenkins slave pods

-   required: true

-   value: docker-registry.upshift.redhat.com/factory2/waiverdb-jenkins-slave:latest

- - name: CONTAINER_REGISTRY_CREDENTIALS

-   displayName: Secret name of container registries used for pulling and pushing images

-   value: factory2-pipeline-registry-credentials

-   required: false

- - name: JENKINS_AGENT_CLOUD_NAME

-   displayName: Name of OpenShift cloud in Jenkins master configuration

-   required: true

-   value: openshift

- - name: ENVIRONMENT

-   displayName: environment name (dev/stage/prod)

-   required: true

-   value: stage

- - name: MESSAGING_PROVIDER

-   displayName: Name of the JMS messaging provider

-   value: Red Hat UMB

- - name: BACKEND_INTEGRATION_TEST_JOB

-   displayName: backend integration test job to trigger

-   required: true

- - name: BACKEND_INTEGRATION_TEST_JOB_NAMESPACE

-   displayName: backend integration test job to trigger

-   required: false

-   value: c3i

- objects:

- - kind: ServiceAccount

-   apiVersion: v1

-   metadata:

-     name: "${NAME}-jenkins-slave"

-     labels:

-       app: "${NAME}"

- - kind: RoleBinding

-   apiVersion: v1

-   metadata:

-     name: "${NAME}-jenkins-slave_edit"

-     labels:

-       app: "${NAME}"

-   subjects:

-   - kind: ServiceAccount

-     name: "${NAME}-jenkins-slave"

-   roleRef:

-     name: edit

- - kind: "BuildConfig"

-   apiVersion: "v1"

-   metadata:

-     name: "${NAME}"

-     labels:

-       app: "${NAME}"

-   spec:

-     runPolicy: "Serial" # FIXME: Parallel is supported, but we have limited quota in UpShift.

-     completionDeadlineSeconds: 1800

-     source:

-       git:

-         uri: "${WAIVERDB_GIT_REPO}"

-         ref: "${WAIVERDB_GIT_REF}"

-     strategy:

-       type: JenkinsPipeline

-       jenkinsPipelineStrategy:

-         env:

-         - name: "WAIVERDB_GIT_REPO"

-           value: "${WAIVERDB_GIT_REPO}"

-         - name: "WAIVERDB_GIT_REF"

-           value: "${WAIVERDB_GIT_REF}"

-         - name: "IMAGE"

-           value: "${IMAGE}"

-         - name: IMAGE_IS_SCRATCH

-           value: "true"

-         - name: "CONTAINER_REGISTRY_CREDENTIALS"

-           value: "${CONTAINER_REGISTRY_CREDENTIALS}"

-         - name: "TEST_ID"

-           value: ""

-         - name: JENKINS_AGENT_IMAGE

-           value: "${JENKINS_AGENT_IMAGE}"

-         - name: JENKINS_AGENT_CLOUD_NAME

-           value: "${JENKINS_AGENT_CLOUD_NAME}"

-         - name: JENKINS_AGENT_SERVICE_ACCOUNT

-           value: "${NAME}-jenkins-slave"

-         - name: ENVIRONMENT

-           value: "${ENVIRONMENT}"

-         - name: MESSAGING_PROVIDER

-           value: "${MESSAGING_PROVIDER}"

-         - name: BACKEND_INTEGRATION_TEST_JOB

-           value: "${BACKEND_INTEGRATION_TEST_JOB}"

-         - name: BACKEND_INTEGRATION_TEST_JOB_NAMESPACE

-           value: "${BACKEND_INTEGRATION_TEST_JOB_NAMESPACE}"

-         jenkinsfilePath: openshift/pipelines/templates/waiverdb-full-integration-test.Jenkinsfile

@@ -1,85 +0,0 @@ 

- library identifier: 'c3i@master', changelog: false,

-   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: "${env.JOB_BASE_NAME}"

-           factory2-pipeline-kind: "waiverdb-integration-test-pipeline"

-           factory2-pipeline-build-number: "${env.BUILD_NUMBER}"

-       spec:

-         containers:

-         - name: jnlp

-           image: "${params.JENKINS_AGENT_IMAGE}"

-           imagePullPolicy: Always

-           resources:

-             requests:

-               memory: 512Mi

-               cpu: 200m

-             limits:

-               memory: 768Mi

-               cpu: 300m

-       """

-     }

-   }

-   options {

-     timestamps()

-     timeout(time: 30, unit: 'MINUTES')

-   }

-   stages {

-     stage('Run integration test') {

-       steps {

-         script {

-           env.IMAGE_DIGEST = getImageDigest(env.IMAGE)

-           if (!env.IMAGE_DIGEST) {

-             env.IMAGE_URI = env.IMAGE

-              if (!env.IMAGE_URI.startsWith('atomic:') && !env.IMAGE_URI.startsWith('docker://')) {

-                   env.IMAGE_URI = 'docker://' + env.IMAGE_URI

-               }

-             echo "Image URI ${env.IMAGE_URI} doesn't contain the image digest. Fetching from the registry..."

-             def metadataText = sh(returnStdout: true, script: 'skopeo inspect ${IMAGE_URI}').trim()

-             def metadata = readJSON text: metadataText

-             env.IMAGE_DIGEST = metadata.Digest

-           }

-           if (!env.IMAGE_DIGEST) {

-             error "Couldn't get digest of image '${env.IMAGE}'"

-           }

-           echo "Digest of image '${env.IMAGE}': ${env.IMAGE_DIGEST}"

- 

-           // TODO: in the short term, we don't run integration tests here

-           // but trigger the integration test job in the c3i project.

-           openshift.withCluster() {

-             openshift.withProject(params.BACKEND_INTEGRATION_TEST_JOB_NAMESPACE) {

-               c3i.buildAndWait(script: this, objs: "bc/${params.BACKEND_INTEGRATION_TEST_JOB}",

-                 '-e', "WAIVERDB_IMAGE=${env.IMAGE}",

-                 '-e', "TARGET_IMAGE_REPO=factory2/waiverdb",

-                 '-e', "TARGET_IMAGE_DIGEST=${env.IMAGE_DIGEST}",

-                 '-e', "TARGET_IMAGE_IS_SCRATCH=${env.IMAGE_IS_SCRATCH}",

-                 '-e', "TARGET_IMAGE_VERREL=${env.BUILD_TAG}",

-                 '-e', "TESTCASE_CATEGORY=${env.ENVIRONMENT}",

-                 )

-               echo "Integration test passed."

-             }

-           }

-         }

-       }

-     }

-   }

- }

- 

- // Extract digest from the image URI

- // e.g. factory2/waiverdb@sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

- //   -> sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

- @NonCPS

- def getImageDigest(String image) {

-   def matcher = (env.IMAGE =~ /@(sha256:\w+)$/)

-   return matcher ? matcher[0][1] : ''

- }

@@ -1,83 +1,123 @@ 

  // Use scripted syntax because CIBuildTrigger currently doesn't support the declarative syntax

- library identifier: 'c3i@master', changelog: false,

-   retriever: modernSCM([$class: 'GitSCMSource', remote: 'https://pagure.io/c3i-library.git'])

- 

- properties([

-   disableConcurrentBuilds(),

-   pipelineTriggers([

-     // example: https://github.com/jenkinsci/jms-messaging-plugin/blob/9b9387c3a52f037ba0d019c2ebcf2a2796fc6397/src/test/java/com/redhat/jenkins/plugins/ci/integration/AmqMessagingPluginIntegrationTest.java

-     [$class: 'CIBuildTrigger',

-       providerData: [$class: 'ActiveMQSubscriberProviderData',

-         name: params.MESSAGING_PROVIDER,

-         overrides: [topic: params.MESSAGING_TOPIC],

-         checks: [

-           [field: '$.msg.subject_type', expectedValue: 'container-image'],

-           [field: '$.msg.subject_identifier', expectedValue: params.SUBJECT_IDENTIFIER_REGEX],

-           [field: '$.msg.decision_context', expectedValue: params.DECISION_CONTEXT_REGEX],

-           [field: '$.msg.policies_satisfied', expectedValue: 'true'],

-         ],

-       ],

-     ],

-   ]),

- ])

- 

- if (!params.CI_MESSAGE) {

-   echo 'This build is not started by a CI message. Only configurations were done.'

-   return

- }

- 

- def label = "jenkins-slave-${UUID.randomUUID().toString()}"

- podTemplate(

-   cloud: "${params.OPENSHIFT_CLOUD_NAME}",

-   label: label,

-   serviceAccount: "${env.JENKINS_AGENT_SERVICE_ACCOUNT}",

-   defaultContainer: 'jnlp',

-   yaml: """

-     apiVersion: v1

-     kind: Pod

-     metadata:

-       labels:

-         app: "jenkins-${env.JOB_BASE_NAME}"

-         factory2-pipeline-kind: "waiverdb-greenwave-trigger"

-         factory2-pipeline-build-number: "${env.BUILD_NUMBER}"

-     spec:

-       containers:

-       - name: jnlp

-         image: ${params.JENKINS_AGENT_IMAGE}

-         imagePullPolicy: Always

-         tty: true

-         resources:

-           requests:

-             memory: 256Mi

-             cpu: 200m

-           limits:

-             memory: 512Mi

-             cpu: 300m

-     """

- ) {

-   node(label) {

-     stage('trigger promotion') {

-       def message = readJSON text: params.CI_MESSAGE

-       // Extract the digest of the image to be promoted.

-       // e.g. factory2/waiverdb@sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

-       //   -> sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

-       def digest = (message.msg.subject_identifier =~ /@(sha256:\w+)$/)[0][1]

-       // Generate the pull spec of the image

-       // e.g. quay.io/factory2/waiverdb@sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

-       def image = params.SOURCE_CONTAINER_REPO + '@' + digest

-       // The target tag name (stage, prod) is determined by `decision_context` field in the Greenwave message.

-       // e.g. If decision_context == 'c3i_promote_dev_to_stage', the image will be promoted to 'stage'.

-       def targetTag = params.TARGET_TAG

-       def promotionJob = params.IMAGE_PROMOTION_JOB ?: "waiverdb-promoting-to-${targetTag}"

-       echo "Starting a new build to promote image ${image} to :${targetTag}..."

-       openshift.withCluster() {

-         def build = c3i.build(script: this, objs: "bc/${promotionJob}",

-           '-e', "IMAGE=${image}",

-           '-e', "DEST_TAG=${targetTag}",

+ {% include "snippets/c3i-library.groovy" %}

+ pipeline {

+   {% include "snippets/default-agent.groovy" %}

+   options {

+     timestamps()

+     timeout(time: 30, unit: 'MINUTES')

+     buildDiscarder(logRotator(numToKeepStr: '10'))

+   }

+   environment {

+     PIPELINE_NAMESPACE = readFile(file: '/run/secrets/kubernetes.io/serviceaccount/namespace').trim()

+     SERVICE_ACCOUNT_TOKEN = readFile(file: '/run/secrets/kubernetes.io/serviceaccount/token').trim()

+   }

+   triggers {

+     ciBuildTrigger(

+       noSquash: false,

+       providerList: [

+         activeMQSubscriber(

+           name: params.MESSAGING_PROVIDER,

+           overrides: [topic: params.MESSAGING_TOPIC],

+           checks: [

+             [field: '$.msg.subject_type', expectedValue: 'container-image'],

+             [field: '$.msg.subject_identifier', expectedValue: params.SUBJECT_IDENTIFIER_REGEX],

+             [field: '$.msg.decision_context', expectedValue: params.DECISION_CONTEXT_REGEX],

+             [field: '$.msg.policies_satisfied', expectedValue: 'true'],

+           ]

          )

-         c3i.waitForBuildStart(script: this, build: build)

-         buildInfo = build.object()

-         echo "Build ${buildInfo.metadata.annotations['openshift.io/jenkins-build-uri'] ?: buildInfo.metadata.name} started."

+       ]

+     )

+   }

+   stages {

+     stage("Message Check and setup") {

+       steps {

+         script {

+           if (!params.CI_MESSAGE) {

+             error("This build is not started by a CI message. Only configurations were done.")

+           }

+           def message = readJSON text: params.CI_MESSAGE

+           // Extract the digest of the image to be promoted.

+           // e.g. factory2/waiverdb@sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

+           //   -> sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

+           def digest = (message.msg.subject_identifier =~ /@(sha256:\w+)$/)[0][1]

+           // Generate the pull spec of the image

+           // e.g. quay.io/factory2/waiverdb@sha256:35201c572fc8a137862b7a256476add8d7465fa5043d53d117f4132402f8ef6b

+           env.IMAGE = "${params.SOURCE_CONTAINER_REPO}@${digest}"

+           echo "Starting promotion of image ${env.IMAGE} to :${params.TARGET_TAG}..."

+           // Setting up registry credentials

+           dir ("${env.HOME}/.docker") {

+             // for the OpenShift internal registry

+             def dockerConfig = readJSON text: '{ "auths": {} }'

+             dockerConfig.auths['docker-registry.default.svc:5000'] = [

+               'email': '',

+               'auth': sh(returnStdout: true, script: 'set +x; echo -n "serviceaccount:$SERVICE_ACCOUNT_TOKEN" | base64 -').trim()

+               ]

+             // merging user specified credentials

+             if (params.CONTAINER_REGISTRY_CREDENTIALS) {

+               openshift.withCluster() {

+                 def dockerconf = openshift.selector('secret', params.CONTAINER_REGISTRY_CREDENTIALS).object().data['.dockerconfigjson']

+                 def dockerString = new String(dockerconf.decodeBase64())

+                 toBeMerged = readJSON text: dockerString

+                 dockerConfig.auths.putAll(toBeMerged.auths)

+               }

+             }

+             // writing to ~/.docker/config.json

+             writeJSON file: 'config.json', json: dockerConfig

+           }

+         }

+       }

+     }

+     stage('Pull image') {

+       steps {

+         echo "Pulling container image ${env.IMAGE}..."

+         withEnv(["SOURCE_IMAGE_REF=${env.IMAGE}"]) {

+           sh '''

+             set -e +x # hide the token from Jenkins console

+             mkdir -p _image

+             skopeo copy docker://"$SOURCE_IMAGE_REF" dir:_image

+           '''

+         }

+       }

+     }

+     stage('Promote image') {

+       steps {

+         script {

+           def destinations = params.PROMOTING_DESTINATIONS ? params.PROMOTING_DESTINATIONS.split(',') : []

+           openshift.withCluster() {

+             def pushTasks = destinations.collectEntries {

+               ["Pushing ${it}" : {

+                 def dest = "${it}:${params.TARGET_TAG}"

+                 // Only docker and atomic registries are allowed

+                 if (!dest.startsWith('atomic:') && !dest.startsWith('docker://')) {

+                   dest = "docker://${dest}"

+                 }

+                 echo "Pushing container image to ${dest}..."

+                 withEnv(["DEST_IMAGE_REF=${dest}"]) {

+                   retry(5) {

+                     sh 'skopeo copy dir:_image "$DEST_IMAGE_REF"'

+                   }

+                 }

+               }]

+             }

+             parallel pushTasks

+           }

+         }

+       }

+     }

+     stage('Tag ImageStream') {

+       when {

+         expression {

+           return params.DEST_IMAGESTREAM_NAME && params.TAG_INTO_IMAGESTREAM == "true"

+         }

+       }

+       steps {

+         script {

+           def destRef = "${params.DEST_IMAGESTREAM_NAMESPACE ?: env.PIPELINE_NAMESPACE}/${params.DEST_IMAGESTREAM_NAME}:${params.TARGET_TAG}"

+           openshift.withCluster() {

+             echo "Tagging ${env.IMAGE} into ${destRef}..."

+             openshift.tag('--source=docker', env.IMAGE, destRef)

+           }

+         }

        }

      }

    }

@@ -12,14 +12,6 @@ 

    displayName: Short unique identifier for the templated instances

    description: This field is used to deploy multiple pipelines to one OpenShift project from this template.

    value: waiverdb-greenwave-trigger

- - name: WAIVERDB_GIT_REPO

-   displayName: WaiverDB Git repo URL

-   description: Default WaiverDB Git repo URL in which to run dev tests against

-   value: "https://pagure.io/waiverdb.git"

- - name: WAIVERDB_GIT_REF

-   displayName: WaiverDB Git repo ref

-   description: Default WaiverDB Git repo ref in which to run dev tests against

-   value: master

  - name: DECISION_CONTEXT_REGEX

    displayName: Regex pattern for Greenwave decision context in CI message

    required: true
@@ -32,9 +24,28 @@ 

  - name: TARGET_TAG

    displayName: Tag name to promote the image to

    required: true

- - name: IMAGE_PROMOTION_JOB

-   displayName: Downstream image promotion job to trigger

+ - name: CONTAINER_REGISTRY_CREDENTIALS

+   displayName: Secret name of container registries used for pulling and pushing images

+   value: factory2-pipeline-registry-credentials

+   required: false

+ - name: TAG_INTO_IMAGESTREAM

+   displayName: Whether to tag the image into an ImageStream

+   value: "false"

    required: true

+ - name: PROMOTING_DESTINATIONS

+   displayName: Comma seperated list of container repositories (without tags) to which the image will be promoted

+   description: OpenShift registries must be prefixed with 'atomic:'

+   required: false

+   value: "quay.io/factory2/waiverdb"

+ - name: DEST_IMAGESTREAM_NAME

+   displayName: Name of the ImageStream to be tagged

+   required: false

+   value: waiverdb

+ - name: DEST_IMAGESTREAM_NAMESPACE

+   displayName: Namespace of the ImageStream to be tagged

+   description: Leaving blank means using the same namespace as the pipeline build

+   required: false

+   value: waiverdb-stage

  - name: MESSAGING_PROVIDER

    displayName: Name of the JMS messaging provider

    value: Red Hat UMB
@@ -47,6 +58,7 @@ 

  - name: OPENSHIFT_CLOUD_NAME

    displayName: Name of OpenShift cloud in Jenkins master configuration

    value: openshift

+ {% include "snippets/c3i-library-parameters.yaml" %}

  objects:

  - kind: ServiceAccount

    apiVersion: v1
@@ -74,20 +86,22 @@ 

    spec:

      runPolicy: "Serial"

      completionDeadlineSeconds: 1800

-     source:

-       git:

-         uri: "${WAIVERDB_GIT_REPO}"

-         ref: "${WAIVERDB_GIT_REF}"

      strategy:

        type: JenkinsPipeline

        jenkinsPipelineStrategy:

          env:

-         - name: WAIVERDB_GIT_REPO

-           value: "${WAIVERDB_GIT_REPO}"

-         - name: WAIVERDB_GIT_REF

-           value: "${WAIVERDB_GIT_REF}"

          - name: OPENSHIFT_CLOUD_NAME

            value: "${OPENSHIFT_CLOUD_NAME}"

+         - name: PROMOTING_DESTINATIONS

+           value: "${PROMOTING_DESTINATIONS}"

+         - name: CONTAINER_REGISTRY_CREDENTIALS

+           value: "${CONTAINER_REGISTRY_CREDENTIALS}"

+         - name: TAG_INTO_IMAGESTREAM

+           value: "${TAG_INTO_IMAGESTREAM}"

+         - name: DEST_IMAGESTREAM_NAME

+           value: "${DEST_IMAGESTREAM_NAME}"

+         - name: DEST_IMAGESTREAM_NAMESPACE

+           value: "${DEST_IMAGESTREAM_NAMESPACE}"

          - name: JENKINS_AGENT_IMAGE

            value:  "${JENKINS_AGENT_IMAGE}"

          - name: JENKINS_AGENT_SERVICE_ACCOUNT
@@ -96,8 +110,6 @@ 

            value: "${SOURCE_CONTAINER_REPO}"

          - name: TARGET_TAG

            value: "${TARGET_TAG}"

-         - name: IMAGE_PROMOTION_JOB

-           value: "${IMAGE_PROMOTION_JOB}"

          - name: DECISION_CONTEXT_REGEX

            value: "${DECISION_CONTEXT_REGEX}"

          - name: SUBJECT_IDENTIFIER_REGEX
@@ -111,4 +123,5 @@ 

            value:

          - name: MESSAGE_HEADERS

            value:

-         jenkinsfilePath: openshift/pipelines/templates/waiverdb-greenwave-trigger.Jenkinsfile

+         jenkinsfile: |

+           {% filter indent(width=10) %}{% include "waiverdb-greenwave-trigger.Jenkinsfile" %}{% endfilter %}

@@ -1,123 +0,0 @@ 

- # Template to produce a pipeline for promoting images between environments

- #

- # The pipeline pulls the image to be promoted, then pushes it to destinations with promoted tags.

- # Optionally, it tags the promoted image into an image stream after pushes.

- ---

- apiVersion: v1

- kind: Template

- metadata:

-   name: waiverdb-image-promotion

- labels:

-   template: waiverdb-image-promotion

- parameters:

- - name: NAME

-   displayName: Short unique identifier for the templated instances

-   description: This field is used to deploy multiple pipelines to one OpenShift project from this template.

-   required: true

-   value: waiverdb-promoting-to-stage-pipeline

- - name: IMAGE

-   displayName: The container image to be promoted

-   description: This field must be in repo:tag or repo@sha256 format

-   value: quay.io/factory2/waiverdb:latest

- - name: PROMOTING_DESTINATIONS

-   displayName: Comma seperated list of container repositories (without tags) to which the image will be promoted

-   description: OpenShift registries must be prefixed with 'atomic:'

-   required: false

-   value: "quay.io/factory2/waiverdb"

- - name: CONTAINER_REGISTRY_CREDENTIALS

-   displayName: Secret name of container registries used for pulling and pushing images

-   value: factory2-pipeline-registry-credentials

-   required: false

- - name: TAG_INTO_IMAGESTREAM

-   displayName: Whether to tag the image into an ImageStream

-   value: "false"

-   required: true

- - name: DEST_IMAGESTREAM_NAME

-   displayName: Name of the ImageStream to be tagged

-   required: false

-   value: waiverdb

- - name: DEST_IMAGESTREAM_NAMESPACE

-   displayName: Namespace of the ImageStream to be tagged

-   description: Leaving blank means using the same namespace as the pipeline build

-   required: false

-   value: waiverdb-stage

- - name: DEST_TAG

-   displayName: Name of the new tag

-   value: "stage"

-   required: true

- - name: WAIVERDB_GIT_REPO

-   displayName: WaiverDB Git repo URL

-   description: Default WaiverDB Git repo URL in which to run functional tests against

-   required: true

-   value: "https://pagure.io/waiverdb.git"

- - name: WAIVERDB_GIT_REF

-   displayName: WaiverDB Git repo ref

-   description: Default WaiverDB Git repo ref in which to run functional tests against

-   required: true

-   value: master

- - name: JENKINS_AGENT_IMAGE

-   displayName: Container image for Jenkins slave pods

-   required: true

-   value: docker-registry.upshift.redhat.com/factory2/waiverdb-jenkins-slave:latest

- - name: JENKINS_AGENT_CLOUD_NAME

-   displayName: Name of OpenShift cloud in Jenkins master configuration

-   required: true

-   value: openshift

- objects:

- - kind: ServiceAccount

-   apiVersion: v1

-   metadata:

-     name: "${NAME}-jenkins-slave"

-     labels:

-       app: "${NAME}"

- - kind: RoleBinding

-   apiVersion: v1

-   metadata:

-     name: "${NAME}-jenkins-slave_edit"

-     labels:

-       app: "${NAME}"

-   subjects:

-   - kind: ServiceAccount

-     name: "${NAME}-jenkins-slave"

-   roleRef:

-     name: edit

- - kind: "BuildConfig"

-   apiVersion: "v1"

-   metadata:

-     name: "${NAME}"

-     labels:

-       app: "${NAME}"

-   spec:

-     runPolicy: "Serial" # FIXME: Parallel is supported, but we have limited quota in UpShift.

-     completionDeadlineSeconds: 1800

-     source:

-       git:

-         uri: "${WAIVERDB_GIT_REPO}"

-         ref: "${WAIVERDB_GIT_REF}"

-     strategy:

-       type: JenkinsPipeline

-       source:

-         type: None

-       jenkinsPipelineStrategy:

-         env:

-         - name: "IMAGE"

-           value: "${IMAGE}"

-         - name: "PROMOTING_DESTINATIONS"

-           value: "${PROMOTING_DESTINATIONS}"

-         - name: "CONTAINER_REGISTRY_CREDENTIALS"

-           value: "${CONTAINER_REGISTRY_CREDENTIALS}"

-         - name: "TAG_INTO_IMAGESTREAM"

-           value: "${TAG_INTO_IMAGESTREAM}"

-         - name: "DEST_IMAGESTREAM_NAME"

-           value: "${DEST_IMAGESTREAM_NAME}"

-         - name: "DEST_IMAGESTREAM_NAMESPACE"

-           value: "${DEST_IMAGESTREAM_NAMESPACE}"

-         - name: "DEST_TAG"

-           value: "${DEST_TAG}"

-         - name: JENKINS_AGENT_IMAGE

-           value: "${JENKINS_AGENT_IMAGE}"

-         - name: JENKINS_AGENT_CLOUD_NAME

-           value: "${JENKINS_AGENT_CLOUD_NAME}"

-         - name: JENKINS_AGENT_SERVICE_ACCOUNT

-           value: "${NAME}-jenkins-slave"

-         jenkinsfilePath: openshift/pipelines/templates/waiverdb-image-promotion.Jenkinsfile

@@ -1,128 +0,0 @@ 

- 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: "waiverdb-image-promotion-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: 512Mi

-               cpu: 200m

-             limits:

-               memory: 768Mi

-               cpu: 500m

-       """

-     }

-   }

-   options {

-     timestamps()

-     timeout(time: 30, unit: 'MINUTES')

-   }

-   environment {

-     PIPELINE_NAMESPACE = readFile(file: '/run/secrets/kubernetes.io/serviceaccount/namespace').trim()

-     SERVICE_ACCOUNT_TOKEN = readFile(file: '/var/run/secrets/kubernetes.io/serviceaccount/token').trim()

-   }

-   stages {

-     stage ('Prepare') {

-       steps {

-         script {

-           // Setting up registry credentials

-           dir ("${env.HOME}/.docker") {

-             // for the OpenShift internal registry

-             def dockerConfig = readJSON text: '{ "auths": {} }'

-             dockerConfig.auths['docker-registry.default.svc:5000'] = [

-               'email': '',

-               'auth': sh(returnStdout: true, script: 'set +x; echo -n "serviceaccount:$SERVICE_ACCOUNT_TOKEN" | base64 -').trim()

-               ]

-             // merging user specified credentials

-             if (env.REGISTRY_CREDENTIALS) {

-               toBeMerged = readJSON text: env.REGISTRY_CREDENTIALS

-               dockerConfig.auths.putAll(toBeMerged.auths)

-             }

-             // writing to ~/.docker/config.json

-             writeJSON file: 'config.json', json: dockerConfig

-           }

-         }

-       }

-     }

-     stage('Pull Container') {

-       steps {

-         echo "Pulling container image ${params.IMAGE}..."

-         sh '''set -e +x # hide the token from Jenkins console

-         rm -rf _build/container

-         mkdir -p _build

-         skopeo copy \

-           --src-cert-dir=/var/run/secrets/kubernetes.io/serviceaccount \

-           docker://"$IMAGE" dir:_build/container

-         '''

-       }

-     }

-     stage('Promote') {

-       steps {

-         script {

-           def destinations = params.PROMOTING_DESTINATIONS ?

-             params.PROMOTING_DESTINATIONS.split(',') : []

-           openshift.withCluster() {

-             def pushTasks = destinations.collectEntries {

-               ["Pushing ${it}" : {

-                 def dest = it

-                 // Only docker and atomic registries are allowed

-                 if (!it.startsWith('atomic:') && !it.startsWith('docker://')) {

-                   dest = 'docker://' + it

-                 }

-                 dest += ':' + params.DEST_TAG

-                 echo "Pushing container to ${dest}..."

-                 withEnv(["DEST_IMAGE_REF=${dest}"]) {

-                   /* Pushes to the internal registry can sometimes randomly fail

-                   * with "unknown blob" due to a known issue with the registry

-                   * storage configuration. So we retry up to 5 times. */

-                   retry(5) {

-                     sh 'skopeo copy dir:_build/container "$DEST_IMAGE_REF"'

-                   }

-                 }

-               }]

-             }

-             parallel pushTasks

-           }

-         }

-       }

-     }

-     stage('Tag Image Stream') {

-       when {

-         expression {

-           return params.DEST_IMAGESTREAM_NAME && params.TAG_INTO_IMAGESTREAM == "true"

-         }

-       }

-       steps {

-         script {

-           def destRef = "${params.DEST_IMAGESTREAM_NAMESPACE ?: env.PIPELINE_NAMESPACE }/${params.DEST_IMAGESTREAM_NAME}:${params.DEST_TAG}"

-           openshift.withCluster() {

-             echo "Tagging ${params.IMAGE} into ${destRef}..."

-             openshift.tag('--source=docker', params.IMAGE, destRef)

-           }

-         }

-       }

-     }

-   }

- }

@@ -1,106 +0,0 @@ 

- # Template to produce a new OpenShift pipeline for running integration tests

- #

- ---

- apiVersion: v1

- kind: Template

- metadata:

-   name: waiverdb-integration-test

- labels:

-   template: waiverdb-integration-test

- parameters:

- - name: NAME

-   displayName: Short unique identifier for the templated instances

-   description: This field is used to deploy multiple pipelines to one OpenShift project from this template.

-   required: true

-   value: waiverdb-integration-test

- - name: IMAGE