Fix setting of GIT_SSH for timer merge jobs

Problem is that merge jobs triggered by timer don't supply
"refspec" event attribute, and, naturally, nothing is merged
but the repo is updated.
But, in such case, no connection info is passed to merger,
and GIT_SSH is not set.
So, the merge job will fail (perhaps, until some
other change events with "refspec" defined will
make this merger to set GIT_SSH properly)

Change-Id: I6dd96ae0bdcdf4c3db4c931a8c6ef7d5edfc1257
This commit is contained in:
Evgeny Antyshev 2017-02-08 08:42:59 +00:00
parent 08de693416
commit da90a50b79
7 changed files with 63 additions and 15 deletions

View File

@ -26,13 +26,13 @@ logserver_prefix=http://logs.example.org/server.app/
driver=gerrit
server=review.example.com
user=jenkins
sshkey=none
sshkey=fake_id_rsa1
[connection alt_voting_gerrit]
driver=gerrit
server=review.example.com
user=civoter
sshkey=none
sshkey=fake_id_rsa2
[connection outgoing_smtp]
driver=smtp

View File

@ -26,7 +26,7 @@ logserver_prefix=http://logs.example.org/server.app/
driver=gerrit
server=review.example.com
user=jenkins
sshkey=none
sshkey=fake_id_rsa_path
[connection smtp]
driver=smtp

View File

@ -3020,6 +3020,49 @@ jobs:
self.worker.release('.*')
self.waitUntilSettled()
def test_timer_sshkey(self):
"Test that a periodic job can setup SSH key authentication"
self.worker.hold_jobs_in_build = True
self.config.set('zuul', 'layout_config',
'tests/fixtures/layout-timer.yaml')
self.sched.reconfigure(self.config)
self.registerJobs()
# The pipeline triggers every second, so we should have seen
# several by now.
time.sleep(5)
self.waitUntilSettled()
self.assertEqual(len(self.builds), 2)
ssh_wrapper = os.path.join(self.git_root, ".ssh_wrapper_gerrit")
self.assertTrue(os.path.isfile(ssh_wrapper))
with open(ssh_wrapper) as f:
ssh_wrapper_content = f.read()
self.assertIn("fake_id_rsa", ssh_wrapper_content)
# In the unit tests Merger runs in the same process,
# so we see its' environment variables
self.assertEqual(os.environ['GIT_SSH'], ssh_wrapper)
self.worker.release('.*')
self.waitUntilSettled()
self.assertEqual(len(self.history), 2)
self.assertEqual(self.getJobFromHistory(
'project-bitrot-stable-old').result, 'SUCCESS')
self.assertEqual(self.getJobFromHistory(
'project-bitrot-stable-older').result, 'SUCCESS')
# Stop queuing timer triggered jobs and let any that may have
# queued through so that end of test assertions pass.
self.config.set('zuul', 'layout_config',
'tests/fixtures/layout-no-timer.yaml')
self.sched.reconfigure(self.config)
self.registerJobs()
self.waitUntilSettled()
self.worker.release('.*')
self.waitUntilSettled()
def test_client_enqueue_change(self):
"Test that the RPC client can enqueue a change"
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')

View File

@ -97,9 +97,10 @@ class MergeClient(object):
data = dict(items=items)
self.submitJob('merger:merge', data, build_set, precedence)
def updateRepo(self, project, url, build_set,
def updateRepo(self, project, connection_name, url, build_set,
precedence=zuul.model.PRECEDENCE_NORMAL):
data = dict(project=project,
connection_name=connection_name,
url=url)
self.submitJob('merger:update', data, build_set, precedence)

View File

@ -223,6 +223,14 @@ class Merger(object):
fd.close()
os.chmod(name, 0o755)
def _setGitSsh(self, connection_name):
wrapper_name = '.ssh_wrapper_%s' % connection_name
name = os.path.join(self.working_root, wrapper_name)
if os.path.isfile(name):
os.environ['GIT_SSH'] = name
elif 'GIT_SSH' in os.environ:
del os.environ['GIT_SSH']
def addProject(self, project, url):
repo = None
try:
@ -242,7 +250,8 @@ class Merger(object):
" without a url" % (project,))
return self.addProject(project, url)
def updateRepo(self, project, url):
def updateRepo(self, project, connection_name, url):
self._setGitSsh(connection_name)
repo = self.getRepo(project, url)
try:
self.log.info("Updating local repository %s", project)
@ -279,14 +288,6 @@ class Merger(object):
return commit
def _setGitSsh(self, connection_name):
wrapper_name = '.ssh_wrapper_%s' % connection_name
name = os.path.join(self.working_root, wrapper_name)
if os.path.isfile(name):
os.environ['GIT_SSH'] = name
elif 'GIT_SSH' in os.environ:
del os.environ['GIT_SSH']
def _mergeItem(self, item, recent):
self.log.debug("Processing refspec %s for project %s / %s ref %s" %
(item['refspec'], item['project'], item['branch'],

View File

@ -109,7 +109,9 @@ class MergeServer(object):
def update(self, job):
args = json.loads(job.arguments)
self.merger.updateRepo(args['project'], args['url'])
self.merger.updateRepo(args['project'],
args['connection_name'],
args['url'])
result = dict(updated=True,
zuul_url=self.zuul_url)
job.sendWorkComplete(json.dumps(result))

View File

@ -1501,8 +1501,9 @@ class BasePipelineManager(object):
else:
self.log.debug("Preparing update repo for: %s" % item.change)
url = self.pipeline.source.getGitUrl(item.change.project)
connection_name = self.pipeline.source.connection.connection_name
self.sched.merger.updateRepo(item.change.project.name,
url, build_set,
connection_name, url, build_set,
self.pipeline.precedence)
# merge:merge has been emitted properly:
build_set.merge_state = build_set.PENDING