Merge lp:~mrazik/cupstream2distro-config/jenkins-per-project into lp:cupstream2distro-config

Proposed by Martin Mrazik
Status: Rejected
Rejected by: Loïc Minier
Proposed branch: lp:~mrazik/cupstream2distro-config/jenkins-per-project
Merge into: lp:cupstream2distro-config
Diff against target: 207 lines (+94/-21)
5 files modified
c2dconfigutils/cu2dUpdateCi.py (+39/-20)
ci/config/defaults.conf (+1/-0)
credentials (+4/-0)
stacks/phablet/ubuntu-touch-coreapps.cfg (+1/-0)
tests/test_cu2dUpdateCi.py (+49/-1)
To merge this branch: bzr merge lp:~mrazik/cupstream2distro-config/jenkins-per-project
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Francis Ginther Approve
Review via email: mp+156784@code.launchpad.net

Commit message

This implements a per-job jenkins ci server (with default to ci-jenkins from the current configuration) and moves stacks/phablet/ubuntu-touch-coreapps.cfg to "touch-coreapps-jenkins" jenkins.

Description of the change

This implements a per-job jenkins ci server (with default to ci-jenkins from the current configuration) and moves stacks/phablet/ubuntu-touch-coreapps.cfg to "touch-coreapps-jenkins" jenkins.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Francis Ginther (fginther) wrote :

I would prefer to see
63 + credentials = load_jenkins_credentials(
64 + os.path.expanduser(self.credentialsfile),
65 + jenkins_name)
66 + if not credentials:
67 + logging.error(
68 + 'Credentials for "{}" not found.'.format(jenkins_name))
69 + return None
kept inside of __call__ and store the parsed credentials as 'self.credentials'.

This will cause a bad credentials file to fail the script before any stack processing is done. Should also make testing easier as you can use a pre-made credentials dictionary instead of patching load_jenkins_credentials.

Otherwise I like this change.

review: Needs Fixing
Revision history for this message
Martin Mrazik (mrazik) wrote :

> I would prefer to see
> 63 + credentials = load_jenkins_credentials(
> 64 + os.path.expanduser(self.credentialsfile),
> 65 + jenkins_name)
> 66 + if not credentials:
> 67 + logging.error(
> 68 + 'Credentials for "{}" not
> found.'.format(jenkins_name))
> 69 + return None
> kept inside of __call__ and store the parsed credentials as
> 'self.credentials'.
>
> This will cause a bad credentials file to fail the script before any stack
> processing is done. Should also make testing easier as you can use a pre-made
> credentials dictionary instead of patching load_jenkins_credentials.

I would need to modify load_jenkins_credentials to load _all_ jenkins credentials and not just the specified. The thing is that you also don't know the credentials name _before_ you process the stack.

Revision history for this message
Francis Ginther (fginther) wrote :

My mistake. I was thinking that 'credentials' was simply the entire contents of the credentials file, but now I see that 'credentials' is just the portion specific to the jenkins_name. So, my suggestion would require more refactoring which isn't really necessary.

Approving as is.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Francis Ginther (fginther) wrote :

Dropping to a work in progress. This just needs to be re-done from scratch.

Revision history for this message
Loïc Minier (lool) wrote :

(Rejecting to drop out of active reviews)

Unmerged revisions

139. By Martin Mrazik

minor change to improve logging

138. By Martin Mrazik

added tests for _get_jenkins_handle

137. By Martin Mrazik

fixed a test

136. By Martin Mrazik

Some adjustments

135. By Martin Mrazik

first attempt to make jenkins server configurable per project

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'c2dconfigutils/cu2dUpdateCi.py'
2--- c2dconfigutils/cu2dUpdateCi.py 2013-03-21 12:51:16 +0000
3+++ c2dconfigutils/cu2dUpdateCi.py 2013-04-03 09:23:22 +0000
4@@ -53,6 +53,11 @@
5 class UpdateCi(object):
6 DEFAULT_CREDENTIALS = os.path.expanduser('~/.cu2d.cred')
7 JENKINS_CI_CONFIG_NAME = 'ci-jenkins'
8+ # directory of handles for different jenkins servers
9+ # this is in the form of jenkins_name: jenkins_handle
10+ # the directory is lazy-initialized. When a stack/job needs
11+ # a specific jenkins for the first time the handle is created.
12+ JENKINS_HANDLES = {}
13
14 # Please keep list sorted
15 TEMPLATE_CONTEXT_KEYS = [
16@@ -75,6 +80,7 @@
17 'team',
18 'use_description_for_commit',
19 'log_rotator',
20+ 'jenkins_ci_server',
21 'days_to_keep_builds',
22 'num_to_keep_builds',
23 ]
24@@ -284,23 +290,49 @@
25 autolanding_dict, autolanding_template,
26 build_template)
27
28- def update_jenkins(self, jenkins_handle, jjenv, stack, update=False):
29+ def update_jenkins(self, jjenv, stack, update=False):
30 """ Add/update jenkins jobs
31
32- :param jenkins_handle: jenkins access handle
33 :param jjenv: jinja2 template environment handle
34 :param stack: dictionary with configuration of the stack
35 :param update: Update existing jobs if true
36
37 :return: True on success
38 """
39+
40+ result = True
41 if stack['projects']:
42 job_list = []
43 self.process_stack(job_list, stack)
44 for job in job_list:
45- setup_job(jenkins_handle, jjenv, job['name'], job['template'],
46- job['ctx'], update)
47- return True
48+ jenkins_handle = self._get_jenkins_handle(job)
49+ if jenkins_handle:
50+ setup_job(jenkins_handle, jjenv, job['name'],
51+ job['template'], job['ctx'], update)
52+ else:
53+ result = False
54+ logging.error(
55+ 'Unable to acquire jenkins. Skipping this job.')
56+ return result
57+
58+ def _get_jenkins_handle(self, job_config):
59+ jenkins_name = job_config['ctx']['jenkins_ci_server']
60+ if jenkins_name in self.JENKINS_HANDLES:
61+ return self.JENKINS_HANDLES[jenkins_name]
62+
63+ credentials = load_jenkins_credentials(
64+ os.path.expanduser(self.credentialsfile),
65+ jenkins_name)
66+ if not credentials:
67+ logging.error(
68+ 'Credentials for "{}" not found.'.format(jenkins_name))
69+ return None
70+ jenkins_handle = get_jenkins_handle(credentials)
71+ if not jenkins_handle:
72+ logging.error('Could not acquire connection to jenkins.')
73+ return None
74+ self.JENKINS_HANDLES[jenkins_name] = jenkins_handle
75+ return jenkins_handle
76
77 def __call__(self, default_config_path):
78 """Entry point for cu2d-update-ci"""
79@@ -315,23 +347,10 @@
80 logging.error('Stack configuration failed to load. Aborting!')
81 return 1
82
83- credentials = None
84 if args.credentials:
85- credentialsfile = args.credentials
86- credentials = load_jenkins_credentials(
87- os.path.expanduser(credentialsfile),
88- self.JENKINS_CI_CONFIG_NAME)
89- if not credentials:
90- logging.error('Credentials not found. Aborting!')
91- return 1
92- jenkins_handle = get_jenkins_handle(credentials)
93- if not jenkins_handle:
94- logging.error('Could not acquire connection to jenkins. ' +
95- 'Aborting!')
96- return 1
97+ self.credentialsfile = args.credentials
98 jjenv = get_jinja_environment(default_config_path, stackcfg)
99- if not self.update_jenkins(jenkins_handle, jjenv, stackcfg,
100- args.update_jobs):
101+ if not self.update_jenkins(jjenv, stackcfg, args.update_jobs):
102 logging.error('Failed to configure jenkins jobs. Aborting!')
103 return 2
104 return 0
105
106=== modified file 'ci/config/defaults.conf'
107--- ci/config/defaults.conf 2013-03-21 12:51:16 +0000
108+++ ci/config/defaults.conf 2013-04-03 09:23:22 +0000
109@@ -1,5 +1,6 @@
110 stack:
111 ci_default:
112+ jenkins_ci_server: 'ci-jenkins'
113 ci_template: ci-config.xml.tmpl
114 autolanding_template: autolanding-config.xml.tmpl
115 build_template: pbuilder-config.xml.tmpl
116
117=== modified file 'credentials'
118--- credentials 2013-02-28 16:31:58 +0000
119+++ credentials 2013-04-03 09:23:22 +0000
120@@ -8,3 +8,7 @@
121 password: JENKINS_PASSWORD
122 url: JENKINS_URL
123 token: JENKINS_TOKEN
124+touch-coreapps-jenkins:
125+ username: JENKINS_USERNAME
126+ password: JENKINS_PASSWORD
127+ url: JENKINS_URL
128
129=== modified file 'stacks/phablet/ubuntu-touch-coreapps.cfg'
130--- stacks/phablet/ubuntu-touch-coreapps.cfg 2013-03-26 13:37:50 +0000
131+++ stacks/phablet/ubuntu-touch-coreapps.cfg 2013-04-03 09:23:22 +0000
132@@ -9,6 +9,7 @@
133 daily_release_default:
134 daily_release: False # Disable all for daily release process
135 ci_default:
136+ jenkins_ci_server: 'touch-coreapps-jenkins'
137 autolanding:
138 ppa_target: ppa:ubuntu-touch-coreapps-drivers/daily
139 distributions: quantal,raring
140
141=== modified file 'tests/test_cu2dUpdateCi.py'
142--- tests/test_cu2dUpdateCi.py 2013-03-15 15:27:32 +0000
143+++ tests/test_cu2dUpdateCi.py 2013-04-03 09:23:22 +0000
144@@ -220,6 +220,54 @@
145 self.assertEqual(expected, actual)
146
147
148+class TestGetJenkinsHandle(TestCase):
149+ def setUp(self):
150+ self.update_ci = UpdateCi()
151+ self.update_ci.credentialsfile = '~/.cu2d.cred'
152+
153+ def test_handle_exists(self):
154+ jenkins_name = 'test_handle_exists'
155+ self.update_ci.JENKINS_HANDLES[jenkins_name] = MagicMock()
156+ jenkins_handle = self.update_ci._get_jenkins_handle(
157+ {'ctx': {'jenkins_ci_server': jenkins_name}})
158+ self.assertEqual(jenkins_handle,
159+ self.update_ci.JENKINS_HANDLES[jenkins_name])
160+
161+ def test_no_credentials(self):
162+ jenkins_name = 'test_no_credentials'
163+ load_jenkins_credentials = lambda x, y: None
164+ with patch('c2dconfigutils.cu2dUpdateCi.load_jenkins_credentials',
165+ load_jenkins_credentials):
166+ jenkins_handle = self.update_ci._get_jenkins_handle(
167+ {'ctx': {'jenkins_ci_server': jenkins_name}})
168+ self.assertIsNone(jenkins_handle)
169+
170+ def test_no_jenkins_handle(self):
171+ jenkins_name = 'test_no_jenkins_handle'
172+ load_jenkins_credentials = lambda x, y: object()
173+ get_jenkins_handle = lambda x: None
174+ with patch('c2dconfigutils.cu2dUpdateCi.load_jenkins_credentials',
175+ load_jenkins_credentials), \
176+ patch('c2dconfigutils.cu2dUpdateCi.get_jenkins_handle',
177+ get_jenkins_handle):
178+ jenkins_handle = self.update_ci._get_jenkins_handle(
179+ {'ctx': {'jenkins_ci_server': jenkins_name}})
180+ self.assertIsNone(jenkins_handle)
181+
182+ def test_get_jenkins_handle(self):
183+ jenkins_name = 'test_get_jenkins_handle'
184+ jenkins_handle = object()
185+ load_jenkins_credentials = lambda x, y: object()
186+ get_jenkins_handle = lambda x: jenkins_handle
187+ with patch('c2dconfigutils.cu2dUpdateCi.load_jenkins_credentials',
188+ load_jenkins_credentials), \
189+ patch('c2dconfigutils.cu2dUpdateCi.get_jenkins_handle',
190+ get_jenkins_handle):
191+ result = self.update_ci._get_jenkins_handle(
192+ {'ctx': {'jenkins_ci_server': jenkins_name}})
193+ self.assertEqual(jenkins_handle, result)
194+
195+
196 class TestUpdateJenkins(TestCase):
197 def setUp(self):
198 self.jenkins = MagicMock()
199@@ -233,7 +281,7 @@
200
201 def test_empty_stack(self):
202 stack = {'projects': None}
203- self.update_ci.update_jenkins(None, None, stack)
204+ self.update_ci.update_jenkins(None, stack)
205
206 def test_stack(self):
207 stack = {

Subscribers

People subscribed via source and target branches

to all changes: