From e2da1d9f1987bdeb74d97c930ad5487b877fb762 Mon Sep 17 00:00:00 2001 From: hyokeun Date: Wed, 11 Apr 2018 21:35:51 +0900 Subject: [PATCH] Switching point for rsync_download job 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 | 1 + job_rsync_download_switch.py | 162 +++++++++++++++++++++++++++++++++++++++++ packaging/jenkins-scripts.spec | 1 + 3 files changed, 164 insertions(+) create mode 100644 job_rsync_download_switch.py diff --git a/debian/jenkins-scripts.install b/debian/jenkins-scripts.install index f0118da..ebe32e9 100644 --- a/debian/jenkins-scripts.install +++ b/debian/jenkins-scripts.install @@ -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 index 0000000..89065c4 --- /dev/null +++ b/job_rsync_download_switch.py @@ -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()) + + diff --git a/packaging/jenkins-scripts.spec b/packaging/jenkins-scripts.spec index 3d819e6..3e3ba17 100644 --- a/packaging/jenkins-scripts.spec +++ b/packaging/jenkins-scripts.spec @@ -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) -- 2.7.4