-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbuildGenerator.py
More file actions
152 lines (131 loc) · 6 KB
/
buildGenerator.py
File metadata and controls
152 lines (131 loc) · 6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
from ConfigParser import ConfigParser
from jenkinsapi import api, jenkins, job
from time import sleep as delay
import jenkinsapi
import logging
import os
class BuildGenerator(object):
"""
1. Create a job on Hudson/Jenkins
2. Poll for job status
3. Fetch latest successful job
4. Resolve Job to Repo URL/fetch artifact
"""
def __init__(self, username=None, passwd=None, url="http://hudson.lab.vmops.com", job='CloudStack-PRIVATE'):
#TODO: Change the username to "vogon" for automation
self.hudsonurl = url
self.tarball = None
self.build_number = 0
#self.jenkinsurl = "http://jenkins.jobclient.org"
if username and passwd:
self.username = username
self.password = passwd
else:
logging.warning("no username given, logging in with default creds")
self.username = "marvin"
self.password = "marvin"
try:
j = jenkins.Jenkins(self.hudsonurl, self.username, self.password)
self.jobclient = j.get_job(job)
except Exception, e:
logging.error("Failed to login to Hudson")
raise e
else:
logging.debug("successfully logged into hudson instance %s \
using username, passwd : %s, %s" \
%(self.hudsonurl, self.username, self.password))
def readBuildConfiguration(self, cfg_file):
cfg = ConfigParser()
cfg.optionxform = str
if cfg.read(cfg_file):
logging.debug("Using config file found at %s"%cfg_file)
self.config = cfg
else:
raise IOError("Cannot find file %s"%cfg_file)
def parseConfigParams(self):
#TODO: passing a config file should be allowed as cmd line args
params = {}
if self.config:
logging.debug("build params found:")
for k,v in dict(self.config.items('build_params')).iteritems():
logging.debug("%s : %s"%(k,v))
return dict(self.config.items('build_params'))
else:
logging.debug("build config not found")
raise ValueError("Build configuration was not initialized")
def build(self, wait=20):
if self.config and self.jobclient:
while self.jobclient.is_queued_or_running():
logging.debug("Waiting %ss for running/queued build to complete"%wait)
delay(wait)
self.jobclient.invoke(params=self.parseConfigParams())
self.build_number = self.jobclient.get_last_buildnumber()
self.paramlist = self.parseConfigParams()
logging.info("Started build : %d"%self.jobclient.get_last_buildnumber())
while self.jobclient.is_running():
logging.debug("Polling build status in %ss"%wait)
delay(wait)
logging.info("Completed build : %d"%self.jobclient.get_last_buildnumber())
logging.debug("Last Good Build : %d, Last Build : %d, Our Build : \
%d"%(self.jobclient.get_last_good_buildnumber(), \
self.jobclient.get_last_buildnumber(), \
self.build_number))
if self.jobclient.get_last_good_buildnumber() == self.build_number:
return self.build_number
else: #lastGoodBuild != ourBuild
our_build = self.getBuildWithNumber(self.build_number)
if our_build is not None and our_build.get_status() == 'SUCCESS':
logging.debug("Our builds' %d status %s"%(self.build_number,
our_build.get_status()))
return self.build_number
else:
logging.debug("Our builds' %d status %s"%(self.build_number,
our_build.get_status()))
return 0
def getLastGoodBuild(self):
return self.jobclient.get_build(self.build_number)
def getBuildWithNumber(self, number):
if number > 0:
bld = self.jobclient.get_build(number)
self.build_number = number
self.paramlist = self.getBuildParamList(bld)
return bld
def getBuildParamValue(self, name):
return self.paramlist[name]
def getTarballName(self):
if self.tarball is not None:
return self.tarball
else:
self.resolveRepoPath()
return self.getTarballName()
def getArtifacts(self):
artifact_dict = self.getLastGoodBuild().get_artifact_dict()
if artifact_dict is not None:
return artifact_dict
def sift(self, dic):
return dic['name'], dic['value']
def getBuildParamList(self, bld):
params = bld.get_actions()['parameters']
return dict(map(self.sift, params))
def resolveRepoPath(self):
tarball_list = ['CloudStack-' ,
self.getBuildParamValue('PACKAGE_VERSION') ,
'-0.', str(self.build_number) , '-' ,
self.getBuildParamValue('DO_DISTRO_PACKAGES') ,
'.tar.gz']
self.tarball = ''.join(tarball_list)
path = os.path.join('yumrepo.lab.vmops.com', 'releases', 'rhel', \
self.getBuildParamValue('DO_DISTRO_PACKAGES').strip('rhel'), \
self.getBuildParamValue('PUSH_TO_REPO'), \
self.tarball)
logging.debug("resolved last good build generated by us to: %s"%path)
return path
if __name__ == '__main__':
# hudson = BuildGenerator(job="marvin")
# hudson.readBuildConfiguration('build.cfg')
# hudson.build()
hudson = BuildGenerator("CloudStack-PRIVATE")
hudson.readBuildConfiguration('build.cfg')
hudson.build(wait=60)
# hudson.getBuildWithNumber(2586)