Switching point for rsync_download job 97/175697/3
authorhyokeun <hyokeun.jeon@samsung.com>
Wed, 11 Apr 2018 12:35:51 +0000 (21:35 +0900)
committerhyokeun <hyokeun.jeon@samsung.com>
Fri, 13 Apr 2018 07:20:42 +0000 (16:20 +0900)
This job will monitor the rsync_download job.
The default quiet period is reasonably long.
If no running builds exists for the same project
 this job will cancel the first queue
 and re trigger the same with delay zero.
With this scenario we can ensure one build per project.

Change-Id: I7bc2b3735c9ba81c558d0a8d890e7a4c707e089c

debian/jenkins-scripts.install
job_rsync_download_switch.py [new file with mode: 0644]
packaging/jenkins-scripts.spec

index f0118da..ebe32e9 100644 (file)
@@ -54,3 +54,4 @@ debian/tmp/job_gbs_build_dispatcher.py /var/lib/jenkins/jenkins-scripts/
 debian/tmp/job_gbsdbbuild_update_meta.py /var/lib/jenkins/jenkins-scripts/
 debian/tmp/job_add_new_node.groovy /var/lib/jenkins/jenkins-scripts/
 debian/tmp/job_purge_tools_services_tester_projects.py /var/lib/jenkins/jenkins-scripts/
+debian/tmp/job_rsync_download_switch.py /var/lib/jenkins/jenkins-scripts/
diff --git a/job_rsync_download_switch.py b/job_rsync_download_switch.py
new file mode 100644 (file)
index 0000000..89065c4
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+# vim: ai ts=4 sts=4 et sw=4
+#
+# Copyright (C) 2010, 2011, 2012, 2013, 2014 Intel, Inc.
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""
+This code run the rsync job immediately if no running builds exists.
+"""
+
+import os
+import sys
+import json
+import base64
+from urllib import quote_plus
+
+from common.buildtrigger import trigger_info, trigger_next, get_pending_builds_with_parameter, get_running_builds_with_parameter, remote_jenkins_build_job, cancel_pending_build_with_id
+
+JOB_NAME = 'rsync_download'
+
+def pending_build_exists(job_name):
+
+    pending_builds = []
+
+    pending_build_queue = get_pending_builds_with_parameter()
+    if not pending_build_queue:
+        print 'No pending builds'
+        return pending_builds
+    for _queue in pending_build_queue:
+        if 'task' not in _queue or 'name' not in _queue.get('task') \
+            or job_name != _queue.get('task').get('name'):
+            continue
+        for action in _queue.get('actions'):
+            if not 'parameters' in action:
+                continue
+            for param in action.get('parameters'):
+                name = param.get('name')
+                value = param.get('value')
+                if name == 'TRIGGER_INFO' and value:
+                    pending_info = trigger_info(value, show=False)
+                    pending_builds.append({_queue.get('id'): pending_info})
+
+    return pending_builds
+
+def running_build_exists(job_name):
+
+    running_builds = []
+
+    running_build_jobs = get_running_builds_with_parameter(job_name)
+    if not running_build_jobs:
+        print 'No running builds'
+        return running_builds
+    for _run in running_build_jobs.get('builds'):
+        if _run.get('building', False) == False:
+            continue
+        for action in _run.get('actions'):
+            if not 'parameters' in action:
+                continue
+            for param in action.get('parameters'):
+                name = param.get('name')
+                value = param.get('value')
+                if name == 'TRIGGER_INFO' and value:
+                    running_info = trigger_info(value, show=False)
+                    running_builds.append({_run.get('queueId'): running_info})
+
+    return running_builds
+
+def find_trigger_info(pool, queue_id):
+
+    for x in pool:
+        qid = x.keys()[0]
+        if queue_id == qid:
+            return x[queue_id]
+
+    raise False
+
+def main():
+    """Script entry point.
+       Parameters:
+          action - cleanup or create_images
+    """
+
+    num_max_concurrent = 4
+
+    project_map = {}
+
+    pending_builds = pending_build_exists(JOB_NAME)
+
+    if not pending_builds or pending_builds is None or len(pending_builds) == 0:
+        return
+
+    running_builds = running_build_exists(JOB_NAME)
+
+    if running_builds and len(running_builds) >= num_max_concurrent:
+        print 'Maximum concurrent reached %d' % len(running_builds)
+        return
+
+    for x in pending_builds:
+        queue_id = x.keys()[0]
+        project = x[queue_id].get('project')
+        if not project in project_map:
+            project_map[project] = {'queue': [], 'build': []}
+        project_map[project].get('queue').append(queue_id)
+
+    for x in running_builds:
+        queue_id = x.keys()[0]
+        project = x[queue_id].get('project')
+        if not project in project_map:
+            project_map[project] = {'queue': [], 'build': []}
+        project_map[project].get('build').append(queue_id)
+
+    sys.stdout.flush()
+
+    num_new_assigned = 0
+    for x in project_map:
+        project = x
+        queue_list = project_map[project].get('queue')
+        print queue_list
+        build_list = project_map[project].get('build')
+        if build_list is None or len(build_list) == 0 \
+            and queue_list and len(queue_list) > 0:
+            queue_id = sorted(queue_list)[0]
+            ti = find_trigger_info(pending_builds, queue_id)
+            encoded_data = base64.b64encode(json.dumps(ti))
+            print '\n********'
+            print '  Lets cancel %s(%d) and re-trigger\n  [%s]' \
+                % (project, queue_id, encoded_data) 
+            sys.stdout.flush()
+            cancel_pending_build_with_id(queue_id)
+            remote_jenkins_build_job(os.getenv('JENKINS_URL_INTERNAL'), \
+                                     os.getenv('JENKINS_USER'), \
+                                     os.getenv('JENKINS_PW'), \
+                                     jobname=JOB_NAME, \
+                                     data='TRIGGER_INFO="%s"&delay=0' % (quote_plus(encoded_data)))
+            num_new_assigned += 1
+            if ( num_new_assigned + len(running_builds) ) >= num_max_concurrent:
+                print 'Slots reached Full!'
+                break
+        else:
+            print '\n********'
+            print '  Still running %s(%d)' \
+                % (project, queue_id)
+
+    print '\n"TitleDisplay": "%d"\n' % num_new_assigned
+
+if __name__ == '__main__':
+    sys.exit(main())
+
+
index 3d819e6..3e3ba17 100644 (file)
@@ -246,6 +246,7 @@ fi
 %{destdir}/job_gbs_build_dispatcher.py
 %{destdir}/job_add_new_node.groovy
 %{destdir}/job_purge_tools_services_tester_projects.py
+%{destdir}/job_rsync_download_switch.py
 
 %files dependsgraph
 %defattr(-,jenkins,jenkins)