#45 Add c3i ansible role
Merged 4 years ago by mikeb. Opened 4 years ago by mkovarik.
mkovarik/c3i-library c3i-role  into  master

file modified
+4
@@ -32,3 +32,7 @@ 

  ```

  gradle test # or `gradle test --info` to be more verbose

  ```

+ 

+ # C3I Ansible role

+ 

+ Repository contains [c3i ansible role](c3i-library/roles/c3i/README.md) for deploying C3I workflows.

file added
+100
@@ -0,0 +1,100 @@ 

+ C3I role

+ =========

+ 

+ C3I role is providing C3I workflows:

+ * premerge

+ * postmerge

+ * image promotions

+ 

+ Role is configurable with role varibales starting `c3i_`. Component developers are expected to provide Jenkinsfile snippets with stages for building their component container and tests for their promotin workflows.

+ 

+ Requirements

+ ------------

+ 

+ Integration with pagure.io:

+ * Projects have to set 'Fedmsg notificitaions' in 'Project Options'

+ * Projects have to activate 'Hooks' -> 'Fedmsg'

+ * Openshift namespace contains secret defined by `c3i_pagure_api_key_secret`

+   - Token permissons: Flag a commit, Comment on a pull-request, Flag a pull-request

+ 

+ Jenkins master is listening on Fedmsg and UMB.

+ 

+ Secret creation:

+ ```

+ oc delete secret pagure-api-key --ignore-not-found=true

+ oc create secret generic pagure-api-key --from-literal=secrettext=${KEY}

+ oc label secret pagure-api-key credential.sync.jenkins.openshift.io=true

+ ```

+ 

+ Workflows

+ ---------

+ ### Pre-merge

+ Job is listening on PR changes - new, update, rebase, reopen. New changes are checkouted into current directory. Pagure PR is marked as `Pending` in pagure. Snippet `c3i_build_and_test_snippet` is executed. Test results should be sent as part of `c3i_build_and_test_snippet`. Pagure PR state is updated. Temporary images are deleted.

+ 

+ ### Post-merge

+ Job is listening on commits in master branch. New changes are checkouted into current directory. Pagure PR is marked as `Pending` in pagure. Snippet `c3i_build_and_test_snippet` is executed. Test results should be sent as

+ part of `c3i_build_and_test_snippet`. Pagure PR state is updated. Temporary images are promoted to final destination with `latest` tag.

+ 

+ ### Promotion

+ Repotracker job listens on image change for specified tag - latest or stage. The repotracker job deployes environment and run tests defined in `c3i_integration_test_snippet`. Test results should be sent as

+ part of `c3i_integration_test_snippet`.

+ 

+ Greenwave promotion job listens on container tests result. Job is promoting image from latest to stage or from stage to prod.

+ 

+ Role Variables

+ --------------

+ 

+ Check [defaults/main.yml](defaults/main.yml)

+ 

+ Stage snippets

+ --------------

+ 

+ Snippets used defining custom parts of Jenkins files. It's expected stage part in declarative syntax.

+ 

+ ### c3i\_build\_and\_test\_snippet

+ Path to snippet for Build container and test acceptance for 'latest' tag.

+ 

+ Git repository is checkout into current working directory.

+ 

+ Input parameters are defined in [templates/build.yml](templates/build.yml). Input parameters can be extended by `c3i_build_custom_parameters`, eg.:

+ ```yaml

+ c3i_build_custom_parameters:

+   - name: MBS_BACKEND_IMAGESTREAM_NAME

+     value: mbs-backend

+   - name: MBS_FRONTEND_IMAGESTREAM_NAME

+     value: mbs-frontend

+   - name: MBS_SPEC_FILE

+     value: https://src.fedoraproject.org/rpms/module-build-service/raw/master/f/module-build-service.spec

+ ```

+ 

+ Expected output variables:

+ * RESULTING\_IMAGE\_REPOS - provides list of repos cotaining generated images separated by ','.

+ * RESULTING\_TAG - provides tag used on generated images

+ 

+ 

+ ### c3i\_integration\_test\_snippet

+ Path to snippet for building testing environment and running tests for promotion workflow.

+ 

+ Input parameters are defined in [templates/trigger-on-tag.yml](templates/trigger-on-tag.yml). Input parameters can be extended by `c3i_integration_test_custom_parameters`.

+ 

+ 

+ Example Playbook

+ ----------------

+ 

+ ```yaml

+ - name: Deplomyent playbook

+   hosts: localhost

+   vars_files:

+     - c3i-role-vars.yml

+   tasks:

+     - git:

+         repo: "{{ c3i_lib_url }}"

+         dest: c3i-library

+         version: "{{ c3i_lib_branch }}"

+     - file:

+         src: c3i-library/roles

+         dest: roles

+         state: link

+     - include_role:

+         name: c3i

+ ```

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

+ ---

+ # defaults file for c3i

+ 

+ # Name of component

+ c3i_component:

+ 

+ # List of images for promotion workflow

+ c3i_images_for_promotion:

+   - "{{ c3i_component }}"

+ 

+ # Git repo for build

+ c3i_git_repo: https://pagure.io/{{ c3i_component }}.git

+ # Main branch used for triggering post merge workflow.

+ c3i_git_main_branch: master

+ 

+ # Path to dockerfile for Jenkins agent

+ c3i_jenkins_agent_buildconfig_contextdir: .

+ c3i_jenkins_agent_buildconfig_dockerfile: openshift/containers/jenkins-slave/Dockerfile

+ 

+ 

+ # Set custom parameters for build worflow, list of dicts with 'key' and 'value'

+ c3i_build_custom_parameters: []

+ # Set custom parameters for test promotion worflow, list of dicts with 'key' and 'value'

+ c3i_integration_test_custom_parameters: []

+ # Email address for notification

+ c3i_mail_address:

+ # Path to Jenkinsfile snippet for premerge and postmerge workflow

+ c3i_build_and_test_snippet: 

+ # Path to Jenkinsfile snippet for integration tests used by promotion workflow

+ c3i_integration_test_snippet:

+ 

+ c3i_definition_dir: openshift/pipelines

+ c3i_definition_update_script: ansible-playbook deploy.yml -e c3i_skip_service_accounts=true

+ 

+ # Api key for pagure - has to have permissions for: Flag a commit, Comment on a pull-request, Flag a pull-request

+ c3i_pagure_api_key_secret: pagure-api-key

+ 

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

+ c3i_pagure_doc_repo_name:

+ c3i_pagure_doc_secret: pagure-doc-secret

+ 

+ 

+ c3i_default_agent_snippet: default-agent.groovy

+ c3i_build_agent_snippet: "{{ c3i_default_agent_snippet }}"

+ 

+ # Secret name in openshift namespace for pushing images

+ c3i_container_registry_credentials: factory2-pipeline-registry-credentials

+ 

+ c3i_test_subscriber:

+ 

+ # Create service accounts and role bindings - can be done only by admin

+ c3i_skip_service_accounts: false

+ 

+ c3i_imagestream_namespace: "{{ c3i_ocp_namespace }}"

+ c3i_imagestream_name: "{{ c3i_component }}"

+ 

+ c3i_quay_address: quay.io

+ c3i_quay_namespace: factory2

+ 

+ c3i_dev_image_tag: "latest"

+ 

+ c3i_lib_branch: master

+ c3i_lib_url: https://pagure.io/c3i-library.git

+ 

+ c3i_jenkins_agent_image: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}/{{ c3i_component }}-jenkins-slave:latest"

+ c3i_jenkins_build_agent_image: "{{ c3i_jenkins_agent_image }}"

+ c3i_jenkins_test_agent_image: "{{ c3i_jenkins_agent_image }}"

+ c3i_workflow_jenkins_image: docker-registry.upshift.redhat.com/factory2/pipeline-jenkins-agent:latest

+ 

+ c3i_tracked_container_repo: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}/{{ c3i_component }}"

+ 

+ c3i_pipeline_as_a_service_namespace: c3i 

+ c3i_messaging_provider: Red Hat UMB

+ c3i_fedmsg_provider: fedmsg

+ c3i_cloud_name: openshift

+ 

+ # Openshift connection

+ c3i_ocp_token: "{{ lookup('file', '/run/secrets/kubernetes.io/serviceaccount/token', errors='ignore') | default(lookup('pipe', 'oc whoami -t'), true) }}"

+ c3i_ocp_host: https://paas.psi.redhat.com

+ c3i_ocp_verify_ssl: true

+ c3i_ocp_namespace: "{{ lookup('file', '/run/secrets/kubernetes.io/serviceaccount/namespace', errors='ignore') | default(lookup('pipe', \"awk '/current-context/ {print $2}' ~/.kube/config | cut -f1 -d'/'\"), true) }}"

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

+ ---

+ - name: Service account {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: ServiceAccount

+       apiVersion: v1

+       metadata:

+         name: "{{ job_vars.name }}-jenkins-slave"

+         labels:

+           app: "{{ job_vars.name }}"

+   when: not c3i_skip_service_accounts

+ 

+ - name: Role binding {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: RoleBinding

+       apiVersion: v1

+       metadata:

+         name: "{{ job_vars.name }}-jenkins-slave_edit"

+         labels:

+           app: "{{ job_vars.name }}"

+       subjects:

+       - kind: ServiceAccount

+         name: "{{ job_vars.name }}-jenkins-slave"

+       roleRef:

+         name: edit

+   when: not c3i_skip_service_accounts

+ 

+ - name: Build config {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: "{{ lookup('template', job_vars.template) }}"

+   vars:

+     task_var_build_and_test: "{{ lookup('template', c3i_build_and_test_snippet)}}"

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

+ ---

+ - name: Service account greenwave-promote

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: ServiceAccount

+       apiVersion: v1

+       metadata:

+         name: "{{ item }}-{{ job_vars.name_post }}-jenkins-slave"

+         labels:

+           app: "{{ item }}-{{ job_vars.name_post }}"

+   when: not c3i_skip_service_accounts

+   loop: "{{ c3i_images_for_promotion }}"

+ 

+ - name: Role binding greenwave-promote

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: RoleBinding

+       apiVersion: v1

+       metadata:

+         name: "{{ item }}-{{ job_vars.name_post }}-jenkins-slave_edit"

+         labels:

+           app: "{{ item }}-{{ job_vars.name_post }}"

+       subjects:

+       - kind: ServiceAccount

+         name: "{{ item }}-{{ job_vars.name_post }}-jenkins-slave"

+       roleRef:

+         name: edit

+   when: not c3i_skip_service_accounts

+   loop: "{{ c3i_images_for_promotion }}"

+ 

+ - name: Build config greenwave-promote

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: "{{ lookup('template', job_vars.template) }}"

+   loop: "{{ c3i_images_for_promotion }}"

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

+ ---

+ - name: Including jobs

+   include_tasks: proceed.yml

+   with_filetree: ../templates/jobs

+   loop_control:

+     loop_var: job_item

+ - name: Load dockerfile for jenkins agent buildConfig

+   stat:

+     path: "{{ lookup('pipe', 'git rev-parse --show-toplevel') }}/{{ c3i_jenkins_agent_buildconfig_contextdir }}/{{ c3i_jenkins_agent_buildconfig_dockerfile }}"

+   register: build_config_dockerfile

+ - name: Create jenkins agent buildConfig

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: "{{ lookup('template', 'jenkins_agent_build_config.yml') }}"

+   when: build_config_dockerfile.stat.exists

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

+ ---

+ - name: Including job vars {{ job_item.src }}

+   include_vars:

+     name: job_vars

+     file: "{{ job_item.src }}"

+ - include_tasks: "{{ job_vars.template }}"

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

+ ---

+ - name: Service account {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: ServiceAccount

+       apiVersion: v1

+       metadata:

+         name: "{{ job_vars.name }}-jenkins-slave"

+         labels:

+           app: "{{ job_vars.name }}"

+   when: not c3i_skip_service_accounts

+ 

+ - name: Role binding {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: |

+       kind: RoleBinding

+       apiVersion: v1

+       metadata:

+         name: "{{ job_vars.name }}-jenkins-slave_edit"

+         labels:

+           app: "{{ job_vars.name }}"

+       subjects:

+       - kind: ServiceAccount

+         name: "{{ job_vars.name }}-jenkins-slave"

+       roleRef:

+         name: edit

+   when: not c3i_skip_service_accounts

+ 

+ - name: Build config {{ job_vars.name }}

+   k8s:

+     api_key: "{{ c3i_ocp_token }}"

+     host: "{{ c3i_ocp_host }}"

+     verify_ssl: "{{ c3i_ocp_verify_ssl }}"

+     namespace: "{{ c3i_ocp_namespace }}"

+     state: present

+     definition: "{{ lookup('template', job_vars.template) }}"

+   vars:

+     task_var_integration_test: "{{ lookup('template', c3i_integration_test_snippet) }}"

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

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

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

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

+ pipeline {

+   {% if "job-updater" in job_vars.name %}

+   {% include c3i_default_agent_snippet %}

+   {% else %}

+   {% include c3i_build_agent_snippet %}

+   {% endif %}

+ 

+   options {

+     timestamps()

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

+   }

+   environment {

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

+     // needed by c3i pagure client

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

+     PAGURE_REPO_NAME = env.GIT_REPO.split('/')[3..-1].join('/').replace('forks/', '').replaceAll(/.git$/, '')

+     PAGURE_URL = env.GIT_REPO.split('/')[0..2].join('/')

+     PAGURE_API = "${env.PAGURE_URL}/api/0"

+     PAGURE_REPO_IS_FORK = "${env.GIT_REPO.contains('/forks/') ? 'true': 'false'}"

+   }

+   {% if "postmerge" not in job_vars.name %}

+   triggers {

+     ciBuildTrigger(

+       noSquash: true,

+       providerList: [

+         {% if "premerge" in job_vars.name %}

+         {% for topic in job_vars.messaging_fedmsg_topics %}

+         fedmsgSubscriber(

+           name: params.MESSAGING_FEDMSG_PROVIDER,

+           overrides: [topic: "{{ topic }}"],

+           checks: [

+             [field: '$.pullrequest.project.url_path', expectedValue: params.GIT_REPO.split('/')[3..-1].join('/').replace('forks/', 'fork/').replaceAll(/.git$/, '')],

+             [field: '$.pullrequest.branch', expectedValue: params.GIT_MAIN_BRANCH],

+           ]

+         ),

+         {% endfor %}

+         {% elif "job-updater" in job_vars.name %}

+         {% for topic in job_vars.messaging_fedmsg_topics %}

+         fedmsgSubscriber(

+           name: params.MESSAGING_FEDMSG_PROVIDER,

+           overrides: [topic: "{{ topic }}"],

+           checks: [

+             [field: '$.repo.url_path', expectedValue: params.GIT_REPO.split('/')[3..-1].join('/').replace('forks/', 'fork/').replaceAll(/.git$/, '')],

+             [field: '$.branch', expectedValue: params.GIT_MAIN_BRANCH],

+           ]

+         )

+         {% endfor %}

+         {% endif %}

+       ]

+     )

+   }

+   {% endif %}

+   stages {

+     stage('Proceeding CI_MESSAGE') {

+       when {

+         expression { env.CI_MESSAGE }

+       }

+       steps {

+         script {

+           def message = readJSON text: params.CI_MESSAGE

+           if (env.GIT_REPO_REF != params.GIT_MAIN_BRANCH) {

+             env.GIT_REPO_REF = "pull/${message.pullrequest.id}/head"

+           }

+         }

+       }

+     }

+     stage('Update Build Info') {

+       steps {

+         script {

+           if (!env.GIT_REPO_REF) {

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

+           }

+ 

+           // FIXME: Due to a bug described in https://issues.jenkins-ci.org/browse/JENKINS-45489

+           checkout([$class: 'GitSCM',

+             branches: [[name: env.GIT_REPO_REF]],

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

+           ])

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

+           echo "Build ${env.GIT_REPO_REF}, commit=${env.GIT_COMMIT}"

+ 

+           // Set friendly display name and description

+           def pagure_repo_home = env.GIT_REPO.replace('/forks/', '/fork/').replaceAll(/.git$/,'')

+           {% if "premerge" in job_vars.name %}

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

+           env.PR_NO = env.GIT_REPO_REF.split('/')[1] // return X from pull/X/head

+           env.PR_URL = "${pagure_repo_home}/pull-request/${env.PR_NO}"

+           echo "Building PR #${env.PR_NO}: ${env.PR_URL}"

+           // NOTE: Old versions of OpenShift Client Jenkins plugin are buggy to handle arguments

+           // with special bash characters (like whitespaces, #, etc).

+           // https://bugzilla.redhat.com/show_bug.cgi?id=1625518

+           currentBuild.displayName = "PR#${env.PR_NO}"

+           // 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 = 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)

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

+           } catch (Exception e) {

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

+           }

+           currentBuild.description = pagureLink

+           {% else %}

+           currentBuild.displayName = "${env.GIT_REPO_REF}: ${env.GIT_COMMIT.substring(0, 7)}"

+           currentBuild.description = """<a href="${pagure_repo_home}/c/${env.GIT_COMMIT}">${currentBuild.displayName}</a>"""

+           if (params.PAGURE_API_KEY_SECRET_NAME) {

+             try {

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

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

+             } catch (e) {

+               echo "Error updating commit ${env.GIT_COMMIT} status to PENDING: ${e}"

+             }

+           }

+           {% endif %}

+           {% include "get_paas_domain.groovy" %}

+         }

+       }

+     }

+     {% if "job-updater" in job_vars.name %}

+     stage('Update pipeline jobs') {

+       steps {

+         script {

+           dir("{{ c3i_definition_dir }}") {

+             sh '{{ c3i_definition_update_script }}'

+           }

+         }

+       }

+     }

+     stage('Trigger postmerge') {

+       steps {

+         script {

+           openshift.withCluster() {

+             def build = c3i.build(script: this, objs: "bc/${env.POSTMERGE_JOB}")

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

+             def devBuildInfo = build.object()

+             def downstreamBuildName = devBuildInfo.metadata.name

+             def downstreamBuildUrl = devBuildInfo.metadata.annotations['openshift.io/jenkins-build-uri']

+             echo "Downstream build ${downstreamBuildName}(${downstreamBuildUrl}) started."

+           }

+         }

+       }

+     }

+     {% else %}

+     {{ task_var_build_and_test }}

+     stage('Push container') {

+       when {

+         expression {

+           return env.GIT_REPO_REF == params.GIT_MAIN_BRANCH

+         }

+       }

+       steps {

+         script {

+           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

+           }

+           env.RESULTING_IMAGE_REPOS.tokenize(',').each {

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

+             def imageName = it.split('/').last()

+             def destImage = "${env.IMAGE_DESTINATION_NAMESPACE}/${imageName}:${env.IMAGE_TAG}"

+             // copy between registies

+             echo "Copying container from ${sourceImage} to ${destImage}"

+             sh "skopeo copy --src-cert-dir=/var/run/secrets/kubernetes.io/serviceaccount/ docker://${sourceImage} docker://${destImage}"

+           }

+         }

+       }

+     }

+   }

+   post {

+     cleanup {

+       script {

+         if (env.RESULTING_TAG) {

+           echo "Removing tag ${env.RESULTING_TAG} from the ImageStream..."

+           openshift.withCluster() {

+             openshift.withProject("${params.IMAGESTREAM_NAMESPACE}") {

+               openshift.tag("${params.IMAGESTREAM_NAME}:${env.RESULTING_TAG}",

+                 "-d")

+             }

+           }

+         }

+       }

+     }

+     success {

+       script {

+         // on pre-merge workflow success

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

+           try {

+             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}"

+           }

+         }

+         // on post-merge workflow success

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

+           try {

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

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

+           } catch (e) {

+             echo "Error updating commit ${env.GIT_COMMIT} status to PASS: ${e}"

+           }

+         }

+       }

+     }

+     failure {

+       script {

+         // on pre-merge workflow failure

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

+           // updating Pagure PR flag

+           try {

+             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 {

+             pagure.commentOnPR("""

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

+             Rebase or make new commits to rebuild.

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

+             echo "Comment made."

+           } catch (e) {

+             echo "Error making a comment on PR #${env.PR_NO}: ${e}"

+           }

+         }

+         // on post-merge workflow failure

+         if (!env.PR_NO) {

+           // updating Pagure commit flag

+           if (params.PAGURE_API_KEY_SECRET_NAME) {

+             try {

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

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

+             } catch (e) {

+               echo "Error updating commit ${env.GIT_COMMIT} status to FAILURE: ${e}"

+             }

+           }

+           // sending email

+           if (params.MAIL_ADDRESS){

+             try {

+               def recipient = params.MAIL_ADDRESS

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

+               def body = "Build URL: ${env.BUILD_URL}"

+               if (env.PR_NO) {

+                 subject = "Jenkins job ${env.JOB_NAME}, PR #${env.PR_NO} ${status}."

+                 body += "\nPull Request: ${env.PR_URL}"

+               }

+               emailext to: recipient, subject: subject, body: body

+             } catch (e) {

+               echo "Error sending email: ${e}"

+             }

+           }

+         }

+       }

+     }

+     {% endif %}

+   }

+ }

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

+ kind: "BuildConfig"

+ apiVersion: "v1"

+ metadata:

+   name: {{ job_vars.name }}

+   labels:

+     app: {{ job_vars.name }}

+ spec:

+   runPolicy: "Serial"

+   completionDeadlineSeconds: 1800

+   strategy:

+     type: JenkinsPipeline

+     jenkinsPipelineStrategy:

+       env:

+       - name: GIT_REPO

+         value: {{ c3i_git_repo }}

+       - name: GIT_REPO_REF

+         value: {{ job_vars.git_repo_ref }}

+       - name: GIT_MAIN_BRANCH

+         value: {{ c3i_git_main_branch }}

+       - name: OPENSHIFT_CLOUD_NAME

+         value: {{ c3i_cloud_name }}

+       - name: JENKINS_AGENT_IMAGE

+         value: {{ c3i_workflow_jenkins_image if "job-updater" in job_vars.name else c3i_jenkins_build_agent_image }}

+       - name: JENKINS_AGENT_SERVICE_ACCOUNT

+         value:  {{ job_vars.name }}-jenkins-slave

+       - name: IMAGE_DESTINATION_NAMESPACE

+         value: {{ c3i_quay_address }}/{{ c3i_quay_namespace }}

+       - name: CONTAINER_REGISTRY_CREDENTIALS

+         value: {{ c3i_container_registry_credentials }}

+       - name: IMAGE_TAG

+         value: {{ c3i_dev_image_tag }}

+       - name: PAGURE_DOC_REPO_NAME

+         value: {{ c3i_pagure_doc_repo_name }}

+       - name: PAGURE_DOC_SECRET

+         value: {{ c3i_pagure_doc_secret }} 

+       - name: MESSAGING_PROVIDER

+         value: {{ c3i_messaging_provider }}

+       - name: POSTMERGE_JOB

+         value: {{ c3i_component }}-postmerge

+       - name: MESSAGING_FEDMSG_PROVIDER

+         value: {{ c3i_fedmsg_provider }}

+       - name: PAGURE_API_KEY_SECRET_NAME

+         value: {{ c3i_pagure_api_key_secret }}

+       - name: IMAGESTREAM_NAMESPACE

+         value: {{ c3i_imagestream_namespace }}

+       - name: IMAGESTREAM_NAME

+         value: {{ c3i_imagestream_name }}

+       - name: MAIL_ADDRESS

+         value: {{ c3i_mail_address }}

+ {% for param in c3i_build_custom_parameters %}

+       - name: {{ param.name }}

+         value: {{ param.value }}

+ {% endfor %}

+       # CI_MESSAGE is used internally by JMS messaging plugin

+       - name: CI_MESSAGE

+         value:

+       jenkinsfile: |

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

@@ -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,14 @@ 

+ 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}"

+ }

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

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

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

+ pipeline {

+   {% include c3i_default_agent_snippet %}

+ 

+   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: true,

+       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'],

+           ]

+         )

+       ]

+     )

+   }

+   stages {

+     stage("Message Check and setup") {

+       steps {

+         script {

+           if (params.CI_MESSAGE) {

+             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}"

+           } else if (!params.IMAGE) {

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

+           }

+           echo "Starting promotion of image ${env.IMAGE} to ${env.PROMOTING_DESTINATION}:${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('Copy image') {

+       steps {

+         echo "Copy container image ${env.IMAGE} to ${env.PROMOTING_DESTINATION}:${env.TARGET_TAG}"

+         sh "skopeo copy docker://${env.IMAGE} docker://${env.PROMOTING_DESTINATION}:${env.TARGET_TAG}"

+       }

+     }

+   }

+ }

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

+ kind: "BuildConfig"

+ apiVersion: "v1"

+ metadata:

+   name: {{ item }}-{{ job_vars.name_post }}

+   labels:

+     app: {{ item }}-{{ job_vars.name_post }}

+ spec:

+   runPolicy: "Serial"

+   completionDeadlineSeconds: 1800

+   strategy:

+     type: JenkinsPipeline

+     jenkinsPipelineStrategy:

+       env:

+       - name: IMAGE

+         value:

+       - name: OPENSHIFT_CLOUD_NAME

+         value: {{ c3i_cloud_name }}

+       - name: JENKINS_AGENT_IMAGE

+         value: {{ c3i_workflow_jenkins_image }} 

+       - name: JENKINS_AGENT_SERVICE_ACCOUNT

+         value:  {{ item }}-{{ job_vars.name_post }}-jenkins-slave

+       - name: CONTAINER_REGISTRY_CREDENTIALS

+         value: {{ c3i_container_registry_credentials }}

+       - name: PIPELINE_AS_A_SERVICE_BUILD_NAMESPACE

+         value: {{ c3i_pipeline_as_a_service_namespace }}

+       - name: MESSAGING_PROVIDER

+         value: {{ c3i_messaging_provider }}

+       - name: DECISION_CONTEXT_REGEX

+         value: {{ job_vars.decision_context_regex }}

+       - name: TARGET_TAG

+         value: {{ job_vars.target_tag }}

+       - name: SUBJECT_IDENTIFIER_REGEX

+         value: "^{{ c3i_quay_namespace }}/{{ item }}@sha256:"

+       - name: PROMOTING_DESTINATION

+         value: {{ job_vars.promoting_destination_prefix }}/{{ item }}

+       - name: SOURCE_CONTAINER_REPO

+         value: {{ job_vars.source_container_repo_prefix }}/{{ item }}

+       - name: MESSAGING_TOPIC

+         value: {{ job_vars.messaging_greenwave_topic_pre }}-{{ item }}{{ c3i_test_subscriber }}-{{ job_vars.messaging_greenwave_topic_post }}

+       - name: MAIL_ADDRESS

+         value: {{ c3i_mail_address }}

+       # CI_MESSAGE is used internally by JMS messaging plugin

+       - name: CI_MESSAGE

+         value:

+       jenkinsfile: |

+         {% filter indent(width=10) %}{% include "templates/greenwave-promote.Jenkinsfile" %}{% endfilter %}

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

+ kind: "BuildConfig"

+ apiVersion: "v1"

+ metadata:

+   name: "{{ c3i_component }}-jenkins-slave"

+   labels:

+     app: "{{ c3i_component }}"

+ spec:

+   runPolicy: "Serial"

+   completionDeadlineSeconds: 1800

+   strategy:

+     dockerStrategy:

+       buildArgs:

+       - name: CA_URLS

+         value: https://password.corp.redhat.com/RH-IT-Root-CA.crt

+       forcePull: true

+       dockerfilePath: {{ c3i_jenkins_agent_buildconfig_dockerfile }}

+   resources:

+     requests:

+       memory: "512Mi"

+       cpu: "300m"

+     limits:

+      memory: "768Mi"

+      cpu: "500m"

+   source:

+     git:

+       uri: "{{ c3i_git_repo }}"

+       ref: "{{ c3i_git_main_branch }}"

+     contextDir: "{{ c3i_jenkins_agent_buildconfig_contextdir }}"

+   output:

+     to:

+       kind: "DockerImage"

+       name: "{{ c3i_jenkins_build_agent_image }}"

+     pushSecret:

+       name: "{{ c3i_container_registry_credentials }}"

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

+ ---

+ name_post: "greenwave-promote-to-prod"

+ template: greenwave-promote.yml

+ messaging_greenwave_topic_pre: "Consumer.rh-jenkins-ci-plugin.c3i"

+ messaging_greenwave_topic_post: "greenwave-promote-to-prod.VirtualTopic.eng.greenwave.decision.update"

+ decision_context_regex: c3i_promote_stage_to_prod

+ target_tag: prod

+ promoting_destination_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"

+ source_container_repo_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"

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

+ ---

+ name_post: "greenwave-promote-to-stage"

+ template: greenwave-promote.yml

+ messaging_greenwave_topic_pre: "Consumer.rh-jenkins-ci-plugin.c3i-"

+ messaging_greenwave_topic_post: "greenwave-promote-to-stage.VirtualTopic.eng.greenwave.decision.update"

+ decision_context_regex: c3i_promote_dev_to_stage

+ target_tag: stage

+ promoting_destination_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"

+ source_container_repo_prefix: "{{ c3i_quay_address }}/{{ c3i_quay_namespace }}"

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

+ ---

+ name: "{{ c3i_component }}-job-updater"

+ template: build.yml

+ messaging_fedmsg_topics:

+   - io.pagure.prod.pagure.git.receive

+ git_repo_ref: master

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

+ ---

+ name: "{{ c3i_component }}-postmerge"

+ template: build.yml

+ git_repo_ref: master

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

+ ---

+ name: "{{ c3i_component }}-premerge"

+ template: build.yml

+ messaging_fedmsg_topics:

+   - io.pagure.prod.pagure.pull-request.new

+   - io.pagure.prod.pagure.pull-request.updated

+   - io.pagure.prod.pagure.pull-request.reopened

+   - io.pagure.prod.pagure.pull-request.rebased

+ git_repo_ref:

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

+ ---

+ name: "{{ c3i_component }}-trigger-on-latest-tag"

+ template: trigger-on-tag.yml

+ messaging_repotracker_topic: Consumer.rh-jenkins-ci-plugin.c3i-{{ c3i_test_subscriber | default(c3i_component) }}-trigger-on-latest-tag.VirtualTopic.eng.repotracker.container.tag.>

+ environment: stage

+ tracked_tag: latest

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

+ ---

+ name: "{{ c3i_component }}-trigger-on-stage-tag"

+ template: trigger-on-tag.yml

+ messaging_repotracker_topic: Consumer.rh-jenkins-ci-plugin.c3i-{{ c3i_test_subscriber | default(c3i_component) }}-trigger-on-stage-tag.VirtualTopic.eng.repotracker.container.tag.>

+ environment: prod

+ tracked_tag: stage

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

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

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

+ pipeline {

+   {% include c3i_default_agent_snippet %}

+ 

+   options {

+     timestamps()

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

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

+   }

+   triggers {

+     ciBuildTrigger(

+       noSquash: true,

+       providerList: [

+         activeMQSubscriber(

+           name: params.MESSAGING_PROVIDER,

+           overrides: [topic: params.MESSAGING_TOPIC],

+           selector: "repo = '${params.TRACKED_CONTAINER_REPO}' AND action IN ('added', 'updated') AND tag = '${params.TRACKED_TAG}'",

+         )

+       ]

+     )

+   }

+   stages {

+     stage("Message Check and setup") {

+       steps {

+         script {

+           if (params.CI_MESSAGE) {

+             def message = readJSON text: params.CI_MESSAGE

+             echo "Tag :${message.tag} is ${message.action} in ${message.repo}. New digest: ${message.digest}"

+             env.IMAGE = "${message.repo}@${message.digest}"

+             env.PIPELINE_ID = "c3i-{{ c3i_component }}-tag-${params.TRACKED_TAG}-${message.digest[-9..-1]}"

+           } else if (params.IMAGE) {

+             env.PIPELINE_ID = "c3i-{{ c3i_component }}-tag-${params.TRACKED_TAG}-manual-${UUID.randomUUID().toString().substring(0, 4)}"

+           } else {

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

+           }

+           echo "Triggering a job to test if ${env.IMAGE} meets all criteria of desired tag :${params.TRACKED_TAG}"

+           env.IMAGE_IS_SCRATCH = false

+           {% include "get_paas_domain.groovy" %}

+         }

+       }

+     }

+     {{ task_var_integration_test }}

+   }

+ }

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

+ kind: "BuildConfig"

+ apiVersion: "v1"

+ metadata:

+   name: {{ job_vars.name }}

+   labels:

+     app: {{ job_vars.name }}

+ spec:

+   runPolicy: "Serial"

+   completionDeadlineSeconds: 1800

+   strategy:

+     type: JenkinsPipeline

+     jenkinsPipelineStrategy:

+       env:

+       - name: GIT_REPO

+         value: {{ c3i_git_repo }}

+       - name: GIT_REPO_REF

+         value: {{ c3i_git_main_branch }}

+       - name: MESSAGING_TOPIC

+         value: {{ job_vars.messaging_repotracker_topic }}

+       - name: IMAGE

+         value:

+       - name: OPENSHIFT_CLOUD_NAME

+         value: {{ c3i_cloud_name }}

+       - name: JENKINS_AGENT_IMAGE

+         value: {{ c3i_jenkins_test_agent_image }} 

+       - name: JENKINS_AGENT_SERVICE_ACCOUNT

+         value:  {{ job_vars.name }}-jenkins-slave

+       - name: CONTAINER_REGISTRY_CREDENTIALS

+         value: {{ c3i_container_registry_credentials }}

+       - name: PIPELINE_AS_A_SERVICE_BUILD_NAMESPACE

+         value: {{ c3i_pipeline_as_a_service_namespace }}

+       - name: TRACKED_CONTAINER_REPO

+         value: {{ c3i_tracked_container_repo }}

+       - name: TRACKED_TAG

+         value: {{ job_vars.tracked_tag }}

+       - name: ENVIRONMENT

+         value: {{ job_vars.environment }}

+       - name: MESSAGING_PROVIDER

+         value: {{ c3i_messaging_provider }}

+       - name: MAIL_ADDRESS

+         value: {{ c3i_mail_address }}

+ {% for param in c3i_integration_test_custom_parameters %}

+       - name: {{ param.name }}

+         value: {{ param.value }}

+ {% endfor %}

+       # CI_MESSAGE is used internally by JMS messaging plugin

+       - name: CI_MESSAGE

+         value:

+       jenkinsfile: |

+         {% filter indent(width=10) %}{% include "templates/trigger-on-tag.Jenkinsfile" %}{% endfilter %}

file modified
+72 -4
@@ -212,14 +212,82 @@ 

  

  /**

   * Send message with container testing results.

-  * @param args.imageRepo Name of the image.

-  * @param args.imageDigest Digest of the image.

-  * @param args.imageVerRel Version of the image. E.g. 1.2.3-1

-  * @param args.imageIsScratchBuild Boolean value.

+  * @param args.imageRef Full path to image - can be with tag or digest.

+  * @param args.digest Digest of the image.

+  * @param args.environment Environment of tests - stage, prod, dev

+  * @param args.scratch Boolean value.

   * @param args.provider UMB provider name defined in Jenkins.

+  * @param args.docs Documentation link

+  * @param args.email Contact email

   * @return Result from sendCIMessage.

   */

+ def sendResultToMessageBus(Map args) {

+   def email = args.email ?: 'pnt-factory2-devel@redhat.com'

+   def environment = args.environment ?: env.ENVIRONMENT

+   def docs = args.docs ?: ""

+   def repourl = args.imageRef.tokenize('@')[0].replaceAll(':[^/]*$', '')

+   def (registry, reponame) = repourl.split('/', 2)

+   def image = reponame.split('/').last()

+   def provider = args.provider ?: 'Red Hat UMB'

+   boolean scratch = args.containsKey('scratch') ? args.scratch : true

  

+   def sendResult = sendCIMessage \

+     providerName: provider, \

+     overrides: [topic: 'VirtualTopic.eng.ci.container-image.test.complete'], \

+     messageType: 'Custom', \

+     messageProperties: '', \

+     messageContent: """

+     {

+       "ci": {

+         "name": "C3I Jenkins",

+         "team": "DevOps",

+         "url": "${env.JENKINS_URL}",

+         "docs": "${docs}",

+         "irc": "#pnt-devops-dev",

+         "email": "${email}",

+         "environment": "${environment}"

+       },

+       "run": {

+         "url": "${env.BUILD_URL}",

+         "log": "${env.BUILD_URL}/console",

+         "debug": "",

+         "rebuild": "${env.BUILD_URL}/rebuild/parametrized"

+       },

+       "artifact": {

+         "type": "container-image",

+         "repository": "${reponame}",

+         "digest": "${args.digest}",

+         "nvr": "${repourl}@${args.digest}",

+         "issuer": "c3i-jenkins",

+         "scratch": ${scratch},

+         "id": "${image}@${args.digest}"

+       },

+       "system":

+          [{

+             "os": "${params.JENKINS_AGENT_IMAGE}",

+             "provider": "openshift",

+             "architecture": "x86_64"

+          }],

+       "type": "integration",

+       "category": "${environment}",

+       "status": "${currentBuild.result == null || currentBuild.result == 'SUCCESS' ? 'passed':'failed'}",

+       "xunit": "",

+       "generated_at": "${new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone('UTC'))}",

+       "namespace": "c3i",

+       "version": "0.1.0"

+     }

+     """

+   if (sendResult.getMessageId()) {

+     // echo sent message id and content

+     echo 'Successfully sent the test result to ResultsDB.'

+     echo "Message ID: ${sendResult.getMessageId()}"

+     echo "Message content: ${sendResult.getMessageContent()}"

+   } else {

+     echo 'Failed to sent the test result to ResultsDB.'

+   }

+ }

+ 

+ //old way can be removed after update of dependent components

  def sendResultToMessageBus(

    String imageRepo, // e.g. 'waiverdb'

    String imageDigest, // e.g. 'sha256:79bd800433a1965d970dfa17b518c3b58e1e1c1528df77900d57c0fbc7dd5949'

Providing unified workflows for components in pagure. Jobs are triggered
by messages from UMB or fedmsg.

rebased onto 50f427c

4 years ago

Pull-Request has been merged by mikeb

4 years ago