+++ /dev/null
-#!/usr/bin/env python
-# vim: ai ts=4 sts=4 et sw=4
-
-"""This script will sync a merged change in gerrit to OBS corresponding project.
-"""
-
-import os
-import tempfile
-import glob
-import shutil
-import re
-from time import sleep
-
-# internal module
-from common import runner
-from common import utils
-from common import git
-from common import obspkg
-from common.envparas import *
-from common import errors
-from common import mysql
-from common.send_mail import prepare_mail
-
-import gbp.rpm
-
-envparas = ['GERRIT_EVENT_TYPE',
- 'GERRIT_PROJECT',
- 'GERRIT_BRANCH',
- 'GERRIT_SSHPORT',
- 'GERRIT_USERNAME',
- 'GERRIT_HOSTNAME',
- 'GERRIT_CHANGE_NUMBER',
- 'GERRIT_PATCHSET_NUMBER',
- 'GERRIT_PATCHSET_REVISION',
- 'GERRIT_OLDREV',
- 'GERRIT_NEWREV',
- 'GERRIT_REFNAME',
- 'WORKSPACE',
- 'JENKINS_HOME',
- 'OBS_URL',
- 'OBS_API_URL',
- 'OBS_OSCRC_PATH',
- 'BUILD_TAG',
- 'MYSQL_HOSTNAME',
- 'MYSQL_USERNAME',
- 'MYSQL_PASSWORD',
- 'MYSQL_DB_NAME',
- 'GIT_CACHE_DIR',
- 'MAPPING_PRJ',
- 'NOREPLY_EMAIL_SENDER']
-export(envparas, locals())
-GERRIT_CMD = 'ssh -p %s %s@%s gerrit' % (GERRIT_SSHPORT, GERRIT_USERNAME, GERRIT_HOSTNAME)
-GIT_URL = 'ssh://%s@%s:%s' % (GERRIT_USERNAME, GERRIT_HOSTNAME, GERRIT_SSHPORT)
-ret = { 'rc' : {'success' : 0, 'failure' : 0, 'retry' : 1},
- 'dbstate' : {'success' : 'TRIGGER_SUCCESS',
- 'failure' : 'TRIGGER_FAILURE',
- 'retry' : 'TRIGGER_RETRY'},
- 'dbtable' : {'CHANGE_MERGED' : 'ChangeMerged_Event',
- 'REF_UPDATED' : 'RefUpdated_Event'},
- 'dbkey' : {'CHANGE_MERGED' : {'changeNum' : GERRIT_CHANGE_NUMBER,
- 'patchsetNum' : GERRIT_PATCHSET_NUMBER},
- 'REF_UPDATED' : {'oldRev' : GERRIT_OLDREV,
- 'newRev' : GERRIT_NEWREV}},
- }
-
-
-def update_gerritinfo(obspkg, gitprj, commitid):
- """ update the _gerritinfo file """
- workdingdir = obspkg.get_workdir()
-
- lines = 'PROJECT: %s\nCOMMIT_ID: %s' % (gitprj, commitid)
- print '_gerritinfo:\n', lines
- gerritinfo = os.path.join(workdingdir, '_gerritinfo')
- with open(gerritinfo, 'w') as log:
- for line in lines:
- log.write(line)
-
-def end(result = 'success'):
- print 'execute result: %s' % result
- # cleanup workspace
- shutil.rmtree(tmpdir)
- exit(ret['rc'][result])
-
-if __name__ == '__main__':
-
- print '---[JOB STARTED]----------------------------------------'
- tmpdir = tempfile.mkdtemp(prefix=WORKSPACE+'/')
- prjdir = os.path.join(tmpdir, GERRIT_PROJECT)
- prjpath, prj = os.path.split(GERRIT_PROJECT)
-
- # check whether tag name is start with 'submit/'
- if GERRIT_EVENT_TYPE == "REF_UPDATED":
- if not GERRIT_REFNAME.startswith('refs/tags/build/'):
- print '\nREFNAME "%s" isn\'t start with refs/tags/build, exit now' % GERRIT_REFNAME
- end('success')
-
- # check whether exist git-obs-mapping.xml in local
- if GERRIT_PROJECT == MAPPING_PRJ or not os.path.isfile('%s/%s/git-obs-mapping.xml' % (GIT_CACHE_DIR, MAPPING_PRJ)):
- print('Update %s/git-obs-mapping.xml to local.' % MAPPING_PRJ)
- if not utils.retry(git.update_git_project, (GIT_CACHE_DIR, MAPPING_PRJ, GIT_URL)):
- end('retry')
- if GERRIT_PROJECT == MAPPING_PRJ:
- print '\nPulled scm/git-obs-mapping change to local, exit now'
- end('success')
-
- # update local git tree from remote
- try:
- if os.path.exists(os.path.join(GIT_CACHE_DIR, GERRIT_PROJECT)):
- print '\nuse local repo as reference to clone'
- if runner.show('git clone %s/%s --reference %s %s' % (GIT_URL, GERRIT_PROJECT, os.path.join(GIT_CACHE_DIR, GERRIT_PROJECT), '%s/%s' % (tmpdir,GERRIT_PROJECT)))[0]:
- print 'use local repo as reference to clone: Failed.'
- shutil.rmtree(os.path.join(GIT_CACHE_DIR, GERRIT_PROJECT))
- except Exception, ex:
- print '\nExcept occur when use reference repo to clone code'
- print ex
- if not utils.retry(git.update_git_project, (tmpdir, GERRIT_PROJECT, GIT_URL)):
- end('retry')
-
- packagingdir = utils.parse_link('%s/%s' % (prjdir, 'packaging'))
- print('packaging dir is %s/%s' % (prjdir, packagingdir))
- mygit = git.Git(prjdir)
-
- checktagmsg = ''
- if GERRIT_EVENT_TYPE == "REF_UPDATED":
- tag = GERRIT_REFNAME[len('refs/tags/'):]
- title = '[Submit Request Succeed]: improper tag %s in %s' % (tag, GERRIT_PROJECT)
- checktagmsg = 'Warning: The submission tag %s pushed in %s project, please use new tag format: annotated tag submit/{version}/{date.time}. Example: submit/trunk/20120803.174859. Suggest to use gbs submit to trigger submission.' % (tag, GERRIT_PROJECT)
- else:
- needsr = False
- tag = mygit.describe('--exact-match --tags --match "build/*"', GERRIT_PATCHSET_REVISION)
- if tag:
- files = mygit.show('--pretty="format:" --name-only', GERRIT_PATCHSET_REVISION)
- p = re.compile('^%s/.*\.changes$' % packagingdir)
- for filename in files:
- if p.match(filename):
- needsr = True
- break
- print 'submit tag : %s, on branch %s' % (tag, GERRIT_BRANCH)
- else:
- print '\nThis change don\'t contain build/* tag, exit now'
- if not needsr:
- end('success')
-
- tagger = mygit.get_tag(tag)
- if not GERRIT_PATCHSET_REVISION:
- GERRIT_PATCHSET_REVISION = mygit.rev_parse(tag)
- commitinfo = mygit.get_commit_info(GERRIT_PATCHSET_REVISION)
- if GERRIT_EVENT_TYPE == "REF_UPDATED":
- gerritinfo = utils.get_gerrit_info(GERRIT_PROJECT, commitinfo['id'])
- print 'gerritinfo', gerritinfo
- if gerritinfo:
- GERRIT_CHANGE_NUMBER = gerritinfo['changenum']
- GERRIT_PATCHSET_NUMBER = gerritinfo['patchsetnum']
-
- if checktagmsg and title:
- if GERRIT_CHANGE_NUMBER and GERRIT_CHANGE_NUMBER:
- print '%s %s %s,%s --message \'"%s"\'' % (GERRIT_CMD, 'review', GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER, checktagmsg)
- runner.show('%s %s %s,%s --message \'"%s"\'' % (GERRIT_CMD, 'review', GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER, checktagmsg))
- if tagger.has_key('author') and tagger.has_key('email'):
- print checktagmsg
- checktagmsg = 'Hi, %s,\n\n' % tagger['author'] + checktagmsg + '\n\n----------------------------------------------------------------\nAutomatically generated by backend service.\nPlease DO NOT Reply!'
- prepare_mail("%s.env" %(BUILD_TAG), title, checktagmsg, NOREPLY_EMAIL_SENDER, tagger['email'])
- end('success')
-
- if tagger.has_key('author') and tagger.has_key('email'):
- msg = 'Submitter: %s <%s>\nComments: %s\nGit project: %s\nTag:%s\nCommit: %s %s' % (tagger['author'], tagger['email'], tagger['message'], GERRIT_PROJECT, tag, commitinfo['id'], commitinfo['subject'])
- else:
- msg = 'Git project: %s\nTag:%s\nCommit: %s %s' % (GERRIT_PROJECT, tag, commitinfo['id'], commitinfo['subject'])
-
- mygit.checkout(tag)
-
- mapping = utils.parse_mapping('%s/git/%s/git-obs-mapping.xml' % (JENKINS_HOME, MAPPING_PRJ), GERRIT_PROJECT, GERRIT_BRANCH)
- print 'git-obs-mapping:', mapping
-
- for target in mapping:
- mygit.clean('-fd')
- (obs_dst_prj, obs_stg_prj, obs_pkg) = target
- if not obs_dst_prj:
- continue
-
- if not obs_stg_prj:
- obs_stg_prj = obs_dst_prj
-
- if obs_pkg:
- specfile = '%s/%s/%s.spec' % (prjdir, packagingdir, obs_pkg)
- else:
- specfile = utils.guess_spec('%s/%s' % (prjdir, packagingdir))
- if not specfile:
- specfile = '%s/%s/%s.spec' % (prjdir, packagingdir, prj)
- print('specfile %s' % specfile)
-
- if not os.path.isfile(specfile):
- continue
- try:
- # use gbp to parse specfile
- spec = gbp.rpm.parse_spec(specfile)
- # use gbs export to generate tarball
- outdir = tempfile.mkdtemp(prefix=tmpdir+'/')
- with utils.Workdir(prjdir):
- runner.show('gbs export --spec=%s -o %s' % (specfile, outdir))
- except Exception, exc:
- print('gbp parse spec failed. %s' % exc)
- end('failure')
-
- print '\ngbs export --spec=%s -o %s' % (specfile, outdir)
- tarballdir = os.path.join(outdir, os.listdir(outdir)[0])
-
- if obs_stg_prj != obs_dst_prj:
- print "check whether tmp package exist in build project"
- tmppkg = obspkg.ObsPackage(tmpdir, obs_stg_prj, 'tmp',
- apiurl = OBS_API_URL, oscrc = OBS_OSCRC_PATH)
- if tmppkg.is_new_pkg():
- tmppkg.commit("Leave an empty package in this project to prevent OBS delete it automatically when all request from here are accepted.")
-
- print '\nCheckout %s/%s to local' % (obs_stg_prj, spec.name)
- print tmpdir, obs_stg_prj, spec.name, OBS_API_URL, OBS_OSCRC_PATH
- localpkg = obspkg.ObsPackage(tmpdir, obs_stg_prj, spec.name,
- apiurl = OBS_API_URL, oscrc = OBS_OSCRC_PATH)
- oscworkdir = localpkg.get_workdir()
- localpkg.remove_all()
- for myfile in os.listdir(tarballdir):
- shutil.copy2(os.path.join(tarballdir, myfile), os.path.join(oscworkdir, myfile))
-
- # update gerritinfo with git info
- update_gerritinfo(localpkg, GERRIT_PROJECT, GERRIT_PATCHSET_REVISION)
-
- localpkg.update_local()
-
- retry_count = 3
- while retry_count > 0:
- try:
- # submit local pkg to obs and create sr
- print '\nSubmit local pkg to obs...'
- localpkg.commit(msg)
- if obs_stg_prj != obs_dst_prj:
- #for req in localpkg.query_req(obs_dst_prj):
- # msg += '\n\n%s' % req.description
- # print 'supersede previous SR %s' % req.reqid
- print '\nsr msg:\n%s' % msg
- newreq = localpkg.submit_req(obs_dst_prj, msg=msg)
- print 'New request %s is created' % newreq
- break
- except Exception, exc:
- print('obs operation failed, retrying...')
- print exc
- sleep(1)
- retry_count -= 1
-
- if not retry_count:
- end('retry')
-
- # post sr info back to gerrit
- requrl = ' %s/request/show/%s' % (OBS_URL, newreq)
- if tagger.has_key('author') and tagger.has_key('email'):
- comment = 'A SR (Submit Request) has been trigger to submit the commit to OBS %s project.\n- Submitter: %s <%s>\n- Comments: %s\n- Git project: %s\n- Tag:%s\n- Commit: %s %s\n- Request URL:%s' % (obs_dst_prj, tagger['author'], tagger['email'], tagger['message'], GERRIT_PROJECT, tag, commitinfo['id'], commitinfo['subject'], requrl)
- else:
- comment = 'A SR (Submit Request) has been trigger to submit the commit to OBS %s project.\n- Git project: %s\n- Tag:%s\n- Commit: %s %s\n- Request URL:%s' % (obs_dst_prj, GERRIT_PROJECT, tag, commitinfo['id'], commitinfo['subject'], requrl)
-
- if GERRIT_CHANGE_NUMBER and GERRIT_CHANGE_NUMBER:
- print '%s %s %s,%s --message \'"%s"\'' % (GERRIT_CMD, 'review', GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER, comment)
- runner.show('%s %s %s,%s --message \'"%s"\'' % (GERRIT_CMD, 'review', GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER, comment))
- else:
- print 'GERRIT_CHANGE_NUMBER %s and GERRIT_CHANGE_NUMBER %s is empty.' % (GERRIT_CHANGE_NUMBER, GERRIT_CHANGE_NUMBER)
-
- if tagger.has_key('author') and tagger.has_key('email'):
- comment = 'Hi, %s,\n\n' % tagger['author'] + comment + '\n\n----------------------------------------------------------------\nAutomatically generated by backend service.\nPlease DO NOT Reply!'
- prepare_mail("%s.env" %(BUILD_TAG), '[Submit Request]: changes to %s/%s' % (obs_dst_prj, spec.name), comment, NOREPLY_EMAIL_SENDER, tagger['email'])
-
- end('success')