9.2.2
by Stevan Radakovic
Add jenkins_server model. Add lib/ to the pythonpath. |
1 |
#!/usr/bin/env python
|
2 |
# Copyright (C) 2012 Linaro
|
|
3 |
#
|
|
4 |
# This file is part of linaro-ci-dashboard.
|
|
5 |
#
|
|
6 |
# linaro-ci-dashboard is free software: you can redistribute it and/or modify
|
|
7 |
# it under the terms of the GNU Affero General Public License as published by
|
|
8 |
# the Free Software Foundation, either version 3 of the License, or
|
|
9 |
# (at your option) any later version.
|
|
10 |
#
|
|
11 |
# linaro-ci-dashboard is distributed in the hope that it will be useful,
|
|
12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
# GNU Affero General Public License for more details.
|
|
15 |
#
|
|
16 |
# You should have received a copy of the GNU Affero General Public License
|
|
17 |
# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
|
|
18 |
||
19 |
from django.db import models |
|
12.1.1
by Deepti B. Kalakeri
Adding changes to create /delete job on jenkins server |
20 |
from django.conf import settings |
41.2.1
by Stevan Radakovic
Add extended Jenkins library, add test file and empty custom command. |
21 |
from lib.jenkins_dashboard import JenkinsDashboard |
19.1.6
by Paul Sokolovsky
Move helpers.getClassLogger() to lib.logger.Logger.getClassLogger(). |
22 |
from lib.logger import Logger |
24.2.1
by Georgy Redkozubov
Added initial job config support suggested by pfalcon for android-build. |
23 |
from lib.template import TextTemplate, XMLTemplate |
9.2.16
by Stevan Radakovic
Helper methods for sync and tests. |
24 |
|
25.1.3
by Milo Casagrande
Fixed problem with android_build job send, cleaned imports. |
25 |
|
9.2.2
by Stevan Radakovic
Add jenkins_server model. Add lib/ to the pythonpath. |
26 |
class JenkinsServer(models.Model): |
27 |
class Meta: |
|
9.2.29
by Stevan Radakovic
Rename jenkins server application, reset migrations. |
28 |
app_label = 'jenkinsserver' |
9.2.2
by Stevan Radakovic
Add jenkins_server model. Add lib/ to the pythonpath. |
29 |
|
30 |
url = models.CharField(max_length=255) |
|
9.2.3
by Stevan Radakovic
Create new app. Move models to it. Try to resolve jenkinsapi dependency problems. |
31 |
username = models.CharField(max_length=100) |
32 |
password = models.CharField(max_length=100) |
|
9.2.2
by Stevan Radakovic
Add jenkins_server model. Add lib/ to the pythonpath. |
33 |
|
9.2.13
by Stevan Radakovic
Add encoding to __init and non implemented sync_jobs. |
34 |
def __init__(self, *args, **kwargs): |
35 |
super(JenkinsServer, self).__init__(*args, **kwargs) |
|
19.1.6
by Paul Sokolovsky
Move helpers.getClassLogger() to lib.logger.Logger.getClassLogger(). |
36 |
self.log = Logger.getClassLogger(self) |
41.2.1
by Stevan Radakovic
Add extended Jenkins library, add test file and empty custom command. |
37 |
self.jenkins = JenkinsDashboard(self.url, |
9.2.29
by Stevan Radakovic
Rename jenkins server application, reset migrations. |
38 |
self.username.encode('utf-8'), |
39 |
self.password.encode('utf-8')) |
|
9.2.13
by Stevan Radakovic
Add encoding to __init and non implemented sync_jobs. |
40 |
|
25.1.12
by Milo Casagrande
Refactored method name. |
41 |
def create_or_update_loop(self, loop): |
14.2.1
by Stevan Radakovic
Separate integration loop model from loop model. |
42 |
""" Create integration loop if it doesn't exist on Jenkins.
|
43 |
Otherwise, update the existing one with new XML."""
|
|
44 |
||
19.1.3
by Paul Sokolovsky
Log when we create/update Jenkins job for a loop. |
45 |
self.log.info("Creating/updating Jenkins job for loop: %r", loop) |
24.2.1
by Georgy Redkozubov
Added initial job config support suggested by pfalcon for android-build. |
46 |
jxml = self.create_job_xml(loop) |
14.2.1
by Stevan Radakovic
Separate integration loop model from loop model. |
47 |
if not self.jenkins.job_exists(loop.name): |
48 |
self.create_job(loop.name, jxml) |
|
49 |
else: |
|
50 |
self.update_job(loop.name, jxml) |
|
51 |
||
52 |
def sync_jobs_and_builds(self): |
|
53 |
"""Sync loops and builds with jobs on jenkins server.
|
|
54 |
||
55 |
Query only ci-dashboard existing jobs and builds on jenkins
|
|
14.2.4
by Stevan Radakovic
Add new sync command for jenkins and CI loop build sync. Also refactor the sync method in jenkinsserver model. |
56 |
and update fields.
|
57 |
This method contains few hacks for build info gathering since
|
|
58 |
python-jenkins library does not support the get build info method.
|
|
59 |
"""
|
|
60 |
||
61 |
# Go through all the loops in CI
|
|
62 |
for loop in self.loop_set.all(): |
|
63 |
||
14.2.1
by Stevan Radakovic
Separate integration loop model from loop model. |
64 |
if self.jenkins.job_exists(loop.name): |
14.2.4
by Stevan Radakovic
Add new sync command for jenkins and CI loop build sync. Also refactor the sync method in jenkinsserver model. |
65 |
# Get the jenkins build dict for each loop.
|
66 |
job_info = self.jenkins.get_job_info(loop.name) |
|
67 |
jenkins_builds = job_info["builds"] |
|
68 |
for build in loop.loopbuild_set.all(): |
|
69 |
for jenkins_build in jenkins_builds: |
|
14.2.9
by Stevan Radakovic
Add remote_number functionality to CI loop build. |
70 |
# If the build number and loop remote_number match,
|
71 |
# update the build info in CI.
|
|
72 |
if build.remote_number and \ |
|
73 |
jenkins_build["number"] == build.remote_number: |
|
41.2.5
by Stevan Radakovic
A bit of refactoring. |
74 |
self.get_build_info() |
75 |
||
76 |
def get_build_info(self, build): |
|
77 |
jenkins_build = self.jenkins.get_build_info(build.loop.name, |
|
78 |
build.remote_number) |
|
79 |
# Duration in jenkins is presented in milliseconds
|
|
48.1.4
by Stevan Radakovic
Fix from code review. |
80 |
if jenkins_build.get("duration", None): |
81 |
build.duration = float(jenkins_build.get("duration", None)) / 1000 |
|
48.1.2
by Stevan Radakovic
Fix non-existing fields in jenkins build json case. |
82 |
|
48.1.4
by Stevan Radakovic
Fix from code review. |
83 |
if jenkins_build.get("result", None): |
84 |
build.status = jenkins_build.get("result", None).lower() |
|
41.2.5
by Stevan Radakovic
A bit of refactoring. |
85 |
# TODO: Add build result xml, but from where?
|
86 |
build.save() |
|
87 |
||
88 |
def sync_unfinished_builds(self): |
|
41.2.3
by Stevan Radakovic
Implement get_build_output and finish custom command implementation. |
89 |
from frontend.models.loop_build import LoopBuild |
90 |
builds = LoopBuild.objects.filter( |
|
91 |
status__in=LoopBuild.NON_FINISHED_STATUSES) |
|
92 |
for build in builds: |
|
41.2.5
by Stevan Radakovic
A bit of refactoring. |
93 |
self.get_build_info(build) |
41.2.3
by Stevan Radakovic
Implement get_build_output and finish custom command implementation. |
94 |
|
12.1.1
by Deepti B. Kalakeri
Adding changes to create /delete job on jenkins server |
95 |
def create_job(self, jname, jxml): |
96 |
""" Creates a new job on jenkins if its not already present """
|
|
12.1.4
by Deepti B. Kalakeri
Addressing the review comments |
97 |
jname = jname.replace(' ', '%20').strip() |
14.2.1
by Stevan Radakovic
Separate integration loop model from loop model. |
98 |
self.jenkins.create_job(jname, jxml) |
99 |
self.jenkins.enable_job(jname) |
|
100 |
||
101 |
def update_job(self, jname, jxml): |
|
102 |
""" Creates a new job on jenkins if its not already present """
|
|
103 |
jname = jname.replace(' ', '%20').strip() |
|
104 |
self.jenkins.reconfig_job(jname, jxml) |
|
12.1.1
by Deepti B. Kalakeri
Adding changes to create /delete job on jenkins server |
105 |
|
106 |
def delete_job(self, jname): |
|
107 |
""" Deleted a job on jenkins if present """
|
|
108 |
if self.jenkins.job_exists(jname): |
|
109 |
self.jenkins.delete_job(jname) |
|
14.2.5
by Stevan Radakovic
PEP8 fixes. |
110 |
|
24.2.1
by Georgy Redkozubov
Added initial job config support suggested by pfalcon for android-build. |
111 |
def create_job_xml(self, loop): |
112 |
"Prepare the config.xml to be used for the job."
|
|
25.1.1
by Milo Casagrande
Merged gesha code, and fixes. |
113 |
# Get generic serialization data.
|
114 |
loop_params = loop.json() |
|
51.1.2
by Paul Sokolovsky
Make default 'assigned_node' param be equal to loop class name. |
115 |
# If loop didn't specify label expression for build slave selection,
|
116 |
# by default use loop class as such.
|
|
117 |
if 'assigned_node' not in loop_params: |
|
51.1.3
by Paul Sokolovsky
Use loop.type instead of Python class name as default assigned_node value. |
118 |
loop_params['assigned_node'] = loop.type |
53
by Paul Sokolovsky
Use Loop type instead of Python class name as job/script template names. |
119 |
template_name = loop.type |
25.1.11
by Milo Casagrande
Fixed JenkinsServer to use new parameters. |
120 |
|
121 |
# We need to handle the CONFIG parameter as a base64 encoded string.
|
|
122 |
# At the moment used only by Android builds.
|
|
123 |
loop_params['base64_config'] = loop.base64_config() |
|
124 |
||
125 |
# Check if the build is restricted, assign appropriate nodes.
|
|
51.1.2
by Paul Sokolovsky
Make default 'assigned_node' param be equal to loop class name. |
126 |
# TODO: This should be handled on the level on particular Loop,
|
127 |
# not here!
|
|
25.1.11
by Milo Casagrande
Fixed JenkinsServer to use new parameters. |
128 |
if loop.is_restricted: |
129 |
loop_params['assigned_node'] = 'private && natty' |
|
25.1.1
by Milo Casagrande
Merged gesha code, and fixes. |
130 |
|
131 |
build_script = TextTemplate(settings.BUILD_SCRIPT_TEMPLATE\ |
|
132 |
% template_name).render(loop_params) |
|
133 |
loop_params['build_script'] = build_script |
|
134 |
||
24.2.1
by Georgy Redkozubov
Added initial job config support suggested by pfalcon for android-build. |
135 |
xml = XMLTemplate(settings.JENKINS_JOB_TEMPLATE \ |
25.1.1
by Milo Casagrande
Merged gesha code, and fixes. |
136 |
% template_name).render(loop_params) |
137 |
||
24.2.1
by Georgy Redkozubov
Added initial job config support suggested by pfalcon for android-build. |
138 |
return xml |
14
by Stevan Radakovic
Add list and detail page for CI loops. Integrate jQuery and implement 'Schedule Build' functionality. Reviewed by deeptik, dooferlad. |
139 |
|
25.1.2
by Milo Casagrande
Added parameters for build, fixed string concat problem. |
140 |
def schedule_job_build(self, jobname, parameters=None): |
14.2.9
by Stevan Radakovic
Add remote_number functionality to CI loop build. |
141 |
"""Trigger build job on jenkins. Return the next build number."""
|
25.1.2
by Milo Casagrande
Added parameters for build, fixed string concat problem. |
142 |
self.jenkins.build_job(jobname, parameters) |
14.2.9
by Stevan Radakovic
Add remote_number functionality to CI loop build. |
143 |
job_info = self.jenkins.get_job_info(jobname) |
144 |
return job_info["nextBuildNumber"] |