From 955a51011e38a21870a80109c737756c930bd9a5 Mon Sep 17 00:00:00 2001
From: Michal Kovarik <mkovarik@redhat.com>
Date: Apr 15 2020 10:37:19 +0000
Subject: Run job to update triggers


Run job on master without other actions to update triggers, then update
to proper job.
Greenwave image promotion process improved to be handled in generic way.

C3I-96

---

diff --git a/roles/c3i/defaults/main.yml b/roles/c3i/defaults/main.yml
index cfe4e1f..3741482 100644
--- a/roles/c3i/defaults/main.yml
+++ b/roles/c3i/defaults/main.yml
@@ -97,3 +97,11 @@ c3i_ocp_namespace: "{{ lookup('file', '/run/secrets/kubernetes.io/serviceaccount
 
 # Jenkins for Jenkinsfile validation - has to have read access for anonymous
 c3i_jenkins_master_validation: jenkins-c3i.cloud.paas.psi.redhat.com
+
+# Internal variable, overriden in Jenkins jobs with triggers.
+# Jobs with triggers are applied in this way:
+#   1) Configured to run on master node and stages part is replaced by noop stages part.
+#   2) Job is executed and triggers are set on the job.
+#   3) Build from noop stages is removed.
+#   4) Job is reconfigured with final configuration.
+c3i_trigger_update_only: false
diff --git a/roles/c3i/tasks/build.yml b/roles/c3i/tasks/build.yml
index ad0b927..c4e3fe9 100644
--- a/roles/c3i/tasks/build.yml
+++ b/roles/c3i/tasks/build.yml
@@ -1,5 +1,5 @@
 ---
-- name: Service account {{ job_vars.name }}
+- name: Create service account {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
     host: "{{ c3i_ocp_host }}"
@@ -15,7 +15,7 @@
           app: "{{ job_vars.name }}"
   when: not c3i_skip_service_accounts
 
-- name: Role binding {{ job_vars.name }}
+- name: Create role binding {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
     host: "{{ c3i_ocp_host }}"
@@ -65,6 +65,12 @@
   tags:
     - validate
 
+- name: Trigger update for {{ job_vars.name }}
+  include_tasks: trigger-update.yml
+  vars:
+    build_config: "{{ job_vars.name }}"
+  when: "'messaging_fedmsg_topics' in job_vars"
+
 - name: Build config {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
diff --git a/roles/c3i/tasks/greenwave-promote-image.yml b/roles/c3i/tasks/greenwave-promote-image.yml
new file mode 100644
index 0000000..e9b5310
--- /dev/null
+++ b/roles/c3i/tasks/greenwave-promote-image.yml
@@ -0,0 +1,79 @@
+---
+- name: Update facts
+  set_fact:
+    image_name: "{{ image }}-{{ job_vars.name_post }}"
+
+- name: Create service account {{ image_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: "{{ image_name }}-jenkins-slave"
+        labels:
+          app: "{{ image_name }}"
+
+- name: Create role binding {{ image_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: "{{ image_name }}-jenkins-slave_edit"
+        labels:
+          app: "{{ image_name }}"
+      subjects:
+      - kind: ServiceAccount
+        name: "{{ image_name }}-jenkins-slave"
+      roleRef:
+        name: edit
+  when: not c3i_skip_service_accounts
+
+- name: Generate Jenkins file {{ image_name }}
+  template:
+    src: greenwave-promote.Jenkinsfile
+    dest: "{{ image_name }}.Jenkinsfile"
+  tags:
+    - validate
+
+- name: Validate Jenkins file {{ image_name }}
+  uri:
+    url: "https://{{ c3i_jenkins_master_validation }}/pipeline-model-converter/validate"
+    method: POST
+    body:
+      jenkinsfile: "{{ lookup('file', '{{ image_name }}.Jenkinsfile')}}"
+    return_content: yes
+    body_format: form-urlencoded
+  register: this
+  failed_when: "'Jenkinsfile successfully validated.' not in this.content"
+  tags:
+    - validate
+
+- name: Cleanup validation for {{ image_name }}
+  file:
+    path: "{{ image_name }}.Jenkinsfile"
+    state: absent
+  tags:
+    - validate
+
+- name: Trigger update for {{ image_name }}
+  include_tasks: trigger-update.yml
+
+- name: Build config for {{ image_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) }}"
diff --git a/roles/c3i/tasks/greenwave-promote.yml b/roles/c3i/tasks/greenwave-promote.yml
index 6ac2467..565765b 100644
--- a/roles/c3i/tasks/greenwave-promote.yml
+++ b/roles/c3i/tasks/greenwave-promote.yml
@@ -1,76 +1,6 @@
 ---
-- 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: Generate Jenkins file {{ job_vars.name_post }}
-  template:
-    src: greenwave-promote.Jenkinsfile
-    dest: "{{ job_vars.name_post }}.Jenkinsfile"
-  tags:
-    - validate
-
-- name: Validate Jenkins file {{ job_vars.name_post }}
-  uri:
-    url: "https://{{ c3i_jenkins_master_validation }}/pipeline-model-converter/validate"
-    method: POST
-    body:
-      jenkinsfile: "{{ lookup('file', '{{ job_vars.name_post }}.Jenkinsfile')}}"
-    return_content: yes
-    body_format: form-urlencoded
-  register: this
-  failed_when: "'Jenkinsfile successfully validated.' not in this.content"
-  tags:
-    - validate
-
-- name: Cleanup validation for {{ job_vars.name_post }}
-  file:
-    path: "{{ job_vars.name_post }}.Jenkinsfile"
-    state: absent
-  tags:
-    - validate
-
-- 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) }}"
+- name: Greenwave promote per image
+  include_tasks: greenwave-promote-image.yml
   loop: "{{ c3i_images_for_promotion }}"
+  loop_control:
+    loop_var: image
diff --git a/roles/c3i/tasks/main.yml b/roles/c3i/tasks/main.yml
index 35a4ecb..e46a493 100644
--- a/roles/c3i/tasks/main.yml
+++ b/roles/c3i/tasks/main.yml
@@ -18,4 +18,4 @@
     namespace: "{{ c3i_ocp_namespace }}"
     state: present
     definition: "{{ lookup('template', 'jenkins_agent_build_config.yml') }}"
-  when: build_config_dockerfile.stat.exists
+  when: build_config_dockerfile.stat.isreg
diff --git a/roles/c3i/tasks/trigger-on-tag.yml b/roles/c3i/tasks/trigger-on-tag.yml
index 572f9b3..4a1adcd 100644
--- a/roles/c3i/tasks/trigger-on-tag.yml
+++ b/roles/c3i/tasks/trigger-on-tag.yml
@@ -1,5 +1,5 @@
 ---
-- name: Service account {{ job_vars.name }}
+- name: Create service account {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
     host: "{{ c3i_ocp_host }}"
@@ -15,7 +15,7 @@
           app: "{{ job_vars.name }}"
   when: not c3i_skip_service_accounts
 
-- name: Role binding {{ job_vars.name }}
+- name: Create role binding {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
     host: "{{ c3i_ocp_host }}"
@@ -65,6 +65,9 @@
   tags:
     - validate
 
+- name: Trigger update for {{ job_vars.name }}
+  include_tasks: trigger-update.yml
+
 - name: Build config {{ job_vars.name }}
   k8s:
     api_key: "{{ c3i_ocp_token }}"
diff --git a/roles/c3i/tasks/trigger-update.yml b/roles/c3i/tasks/trigger-update.yml
new file mode 100644
index 0000000..f40ecfa
--- /dev/null
+++ b/roles/c3i/tasks/trigger-update.yml
@@ -0,0 +1,20 @@
+- set_fact:
+    job_vars_name: "{{ job_vars.name | default(image_name) }}"
+
+- name: Build config for trigger update for {{ 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:
+    c3i_trigger_update_only: true
+
+- name: Update triggers for {{ job_vars_name }}
+  shell: "oc start-build --wait -n {{ c3i_ocp_namespace }} {{ job_vars_name }}"
+  register: result
+
+- name: Delete triggers update build for {{ job_vars_name }}
+  shell: "oc -n {{ c3i_ocp_namespace }} delete {{ result.stdout_lines[0].split()[0] }}"
diff --git a/roles/c3i/templates/build.Jenkinsfile b/roles/c3i/templates/build.Jenkinsfile
index e0fe9cc..cf9a65a 100644
--- a/roles/c3i/templates/build.Jenkinsfile
+++ b/roles/c3i/templates/build.Jenkinsfile
@@ -2,7 +2,9 @@ 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 %}
+  {% if c3i_trigger_update_only %}
+  {% include "master-agent.groovy" %}
+  {% elif "job-updater" in job_vars.name %}
   {% include c3i_default_agent_snippet %}
   {% else %}
   {% include c3i_build_agent_snippet %}
@@ -53,6 +55,10 @@ pipeline {
     )
   }
   {% endif %}
+  {% if c3i_trigger_update_only %}
+  {% include "trigger-update-stages.groovy" %}
+  {% else %}
+
   stages {
     stage('Proceeding CI_MESSAGE') {
       when {
@@ -290,4 +296,5 @@ pipeline {
     }
     {% endif %}
   }
+  {% endif %}
 }
diff --git a/roles/c3i/templates/greenwave-promote.Jenkinsfile b/roles/c3i/templates/greenwave-promote.Jenkinsfile
index 3bb39df..10691b4 100644
--- a/roles/c3i/templates/greenwave-promote.Jenkinsfile
+++ b/roles/c3i/templates/greenwave-promote.Jenkinsfile
@@ -1,7 +1,11 @@
 library identifier: "c3i@{{ c3i_lib_branch }}", changelog: false,
   retriever: modernSCM([$class: 'GitSCMSource', remote: "{{ c3i_lib_url }}"])
 pipeline {
+  {% if c3i_trigger_update_only %}
+  {% include "master-agent.groovy" %}
+  {% else %}
   {% include c3i_default_agent_snippet %}
+  {% endif %}
 
   options {
     timestamps()
@@ -29,6 +33,10 @@ pipeline {
       ]
     )
   }
+  {% if c3i_trigger_update_only %}
+  {% include "trigger-update-stages.groovy" %}
+  {% else %}
+
   stages {
     stage("Check semaphore") {
       steps {
@@ -123,6 +131,8 @@ pipeline {
       }
     }
   }
+  {% endif %}
+
   post {
     failure {
       script {
diff --git a/roles/c3i/templates/greenwave-promote.yml b/roles/c3i/templates/greenwave-promote.yml
index 9f6e961..4f1d0b1 100644
--- a/roles/c3i/templates/greenwave-promote.yml
+++ b/roles/c3i/templates/greenwave-promote.yml
@@ -1,9 +1,9 @@
 kind: "BuildConfig"
 apiVersion: "v1"
 metadata:
-  name: {{ item }}-{{ job_vars.name_post }}
+  name: {{ job_vars_name }}
   labels:
-    app: {{ item }}-{{ job_vars.name_post }}
+    app: {{ job_vars_name }}
 spec:
   runPolicy: "Serial"
   completionDeadlineSeconds: 1800
@@ -18,7 +18,7 @@ spec:
       - name: JENKINS_AGENT_IMAGE
         value: {{ c3i_workflow_jenkins_image }} 
       - name: JENKINS_AGENT_SERVICE_ACCOUNT
-        value:  {{ item }}-{{ job_vars.name_post }}-jenkins-slave
+        value:  {{ job_vars_name }}-jenkins-slave
       - name: CONTAINER_REGISTRY_CREDENTIALS
         value: {{ c3i_container_registry_credentials }}
       - name: PIPELINE_AS_A_SERVICE_BUILD_NAMESPACE
@@ -30,13 +30,13 @@ spec:
       - name: TARGET_TAG
         value: {{ job_vars.target_tag }}
       - name: SUBJECT_IDENTIFIER_REGEX
-        value: "^{{ c3i_quay_namespace }}/{{ item }}@sha256:"
+        value: "^{{ c3i_quay_namespace }}/{{ image }}@sha256:"
       - name: PROMOTING_DESTINATION
-        value: {{ job_vars.promoting_destination_prefix }}/{{ item }}
+        value: {{ job_vars.promoting_destination_prefix }}/{{ image }}
       - name: SOURCE_CONTAINER_REPO
-        value: {{ job_vars.source_container_repo_prefix }}/{{ item }}
+        value: {{ job_vars.source_container_repo_prefix }}/{{ image }}
       - name: MESSAGING_TOPIC
-        value: {{ c3i_messaging_topic_consumer_part }}.c3i-{{ item }}-{{ job_vars.name_post }}{{ c3i_test_subscriber }}.{{ c3i_messaging_greenwave_topic_virtualtopic_part }}
+        value: {{ c3i_messaging_topic_consumer_part }}.c3i-{{ job_vars_name }}{{ c3i_test_subscriber }}.{{ c3i_messaging_greenwave_topic_virtualtopic_part }}
       - name: MAIL_ADDRESS
         value: {{ c3i_mail_address }}
       - name: SEMAPHORE_CHECK
diff --git a/roles/c3i/templates/master-agent.groovy b/roles/c3i/templates/master-agent.groovy
new file mode 100644
index 0000000..f61964d
--- /dev/null
+++ b/roles/c3i/templates/master-agent.groovy
@@ -0,0 +1,5 @@
+agent {
+  node {
+    label "master"
+  }
+}
diff --git a/roles/c3i/templates/trigger-on-tag.Jenkinsfile b/roles/c3i/templates/trigger-on-tag.Jenkinsfile
index 4fe2f89..84103f0 100644
--- a/roles/c3i/templates/trigger-on-tag.Jenkinsfile
+++ b/roles/c3i/templates/trigger-on-tag.Jenkinsfile
@@ -1,7 +1,11 @@
 library identifier: "c3i@{{ c3i_lib_branch }}", changelog: false,
   retriever: modernSCM([$class: 'GitSCMSource', remote: "{{ c3i_lib_url }}"])
 pipeline {
+  {% if c3i_trigger_update_only %}
+  {% include "master-agent.groovy" %}
+  {% else %}
   {% include c3i_default_agent_snippet %}
+  {% endif %}
 
   options {
     timestamps()
@@ -20,6 +24,10 @@ pipeline {
       ]
     )
   }
+  {% if c3i_trigger_update_only %}
+  {% include "trigger-update-stages.groovy" %}
+  {% else %}
+
   stages {
     stage("Message Check and setup") {
       steps {
@@ -61,6 +69,8 @@ pipeline {
     }
     {{ task_var_integration_test }}
   }
+  {% endif %}
+
   post {
     failure {
       script {
diff --git a/roles/c3i/templates/trigger-update-stages.groovy b/roles/c3i/templates/trigger-update-stages.groovy
new file mode 100644
index 0000000..eb206c6
--- /dev/null
+++ b/roles/c3i/templates/trigger-update-stages.groovy
@@ -0,0 +1,10 @@
+stages {
+  stage("Trigger update") {
+    steps {
+      script {
+        echo "Updating triggers"
+        currentBuild.displayName = "Trigger update"
+      }
+    }
+  }
+}

