1
+ #!/usr/bin/env python
2
+
1
3
import builder
2
4
import uploader
3
5
import sys
12
14
import subprocess
13
15
import urllib
14
16
import urllib2
17
+ import logging
15
18
16
19
try :
17
20
import gearman
18
21
except ImportError :
19
22
sys .path .append (r"c:\devel\python-gearman" )
20
23
import gearman
21
24
22
- secret_key = None
23
- if 'SECRET_KEY' in os .environ :
24
- secret_key = os .environ ['SECRET_KEY' ].strip ()
25
- else :
26
- secret_key_path = os .path .split (sys .argv [0 ])[0 ]
27
- secret_key_path = os .path .join (secret_key_path , 'secret_key.txt' )
28
- try :
29
- with open (secret_key_path ) as f :
30
- secret_key = f .readline ().strip ()
31
- except :
32
- print "You must create the file `%s'" % (secret_key_path ,)
33
- print "and fill it with the build system password on the top line."
34
- print "(or put it in the SECRET_KEY environment variable.)"
35
- sys .exit (1 )
25
+ logger = logging .getLogger ("Worker" )
26
+ logger .setLevel (logging .DEBUG )
27
+ logging_handler = logging .StreamHandler ()
28
+ logger .addHandler (logging_handler )
29
+
30
+ formatter = logging .Formatter ("%(asctime)s - %(name)s - %(levelname)s - %(message)s" )
31
+ logging_handler .setFormatter (formatter )
32
+
33
+ try :
34
+ import worker_config
35
+ except ImportError , e :
36
+ logger .exception ('Error importing worker config file' )
37
+ sys .exit (1 )
36
38
37
39
#upload = uploader.S3Uploader()
38
40
upload = uploader .OverviewerOrgUploader ()
39
- gm_worker = gearman .GearmanWorker ([ "192.168.1.4:9092" , "em32.net:9092" ] )
41
+ gm_worker = gearman .GearmanWorker (worker_config . gearman_hosts )
40
42
41
43
def package_hook (platform , repo , checkout , commit , version , url ):
42
- hook = "http://overviewer.org/hooks/package"
43
- data = urllib .urlencode ({'platform' :platform , 'repo' :repo , 'checkout' :checkout , 'commit' :commit , 'version' :version , 'url' :url })
44
- key = urllib .urlencode ({'key' :secret_key })
45
-
44
+ hook = worker_config .package_hook_url
45
+ data = urllib .urlencode ({
46
+ 'platform' : platform ,
47
+ 'repo' : repo ,
48
+ 'checkout' : checkout ,
49
+ 'commit' : commit ,
50
+ 'version' : version ,
51
+ 'url' : url ,
52
+ })
53
+ key = urllib .urlencode ({'key' : worker_config .secret_key })
54
+
46
55
try :
47
56
f = urllib2 .urlopen (hook + '?' + key , data )
48
57
f .read ()
49
58
f .close ()
50
59
except Exception , e :
51
- print " could not do POST hook:" , e
60
+ logger . exception ( ' could not do POST hook' )
52
61
pass # couldn't contact the server, ack!
53
62
54
63
def signAndPickle (d ):
55
64
data = cPickle .dumps (d )
56
- h = hmac .new (secret_key , data , hashlib .sha256 )
65
+ h = hmac .new (worker_config . secret_key , data , hashlib .sha256 )
57
66
return h .digest () + data
58
67
59
68
def uploadLogs (b , result ):
@@ -62,49 +71,56 @@ def uploadLogs(b, result):
62
71
63
72
err_log = "build_logs/%s.stderr.txt" % now
64
73
result ['build_log_stderr' ] = upload .upload (err_log , b .stderr_log [1 ])
65
-
74
+
66
75
out_log = "build_logs/%s.stdout.txt" % now
67
76
result ['build_log_stdout' ] = upload .upload (out_log , b .stdout_log [1 ])
68
77
69
78
def build (worker , job ):
70
- print " got a job!"
79
+ logger . info ( ' got a job!' )
71
80
result = dict (status = None )
72
81
73
82
if len (job .data ) < 33 :
74
- result ['status' ] = 'ERROR'
75
- print "ERROR: job data is not valid. too short"
76
- result ['msg' ] = "ERROR: job data is not valid. too short"
83
+ status = 'ERROR'
84
+ msg = 'Job data is not valid: too short'
85
+ result ['status' ] = status
86
+ result ['msg' ] = '%s: %s' % (status , msg )
87
+ logger .error (msg )
77
88
return signAndPickle (result )
78
89
79
90
received_h = job .data [0 :32 ]
80
91
# calc hmac of the resulting data
81
92
data = job .data [32 :]
82
- h = hmac .new (secret_key , data , hashlib .sha256 )
93
+ h = hmac .new (worker_config . secret_key , data , hashlib .sha256 )
83
94
if (h .digest () != received_h ):
84
- result ['status' ] = 'ERROR'
85
- print "ERROR: job data is not valid. bad signature"
86
- result ['msg' ] = "ERROR: job data is not valid. bad signature"
95
+ status = 'ERROR'
96
+ msg = 'Job data is not valid: bad signature'
97
+ result ['status' ] = status
98
+ logger .error (msg )
99
+ result ['msg' ] = '%s: %s' % (status , msg )
87
100
return signAndPickle (result )
88
101
89
- print " Data is valid, doing to depickle"
102
+ logger . info ( ' Data is valid, depickling' )
90
103
try :
91
104
depick = cPickle .loads (data )
92
-
93
- except :
94
- result ['status' ] = 'ERROR'
95
- result ['msg' ] = "ERROR: can't depickle"
96
- print "ERROR: can't depickle"
105
+ except :
106
+ status = 'ERROR'
107
+ msg = 'Can\' t depickle'
108
+ result ['status' ] = status
109
+ result ['msg' ] = '%s: %s' % (status , msg )
110
+ logger .error (msg )
97
111
return signAndPickle (result )
98
112
99
113
if type (depick ) != dict :
100
- result ['status' ] = 'ERROR'
101
- result ['msg' ] = "ERROR: input must be a dictionary"
102
- print "ERROR: input must be a dictionary"
114
+ status = 'ERROR'
115
+ msg = 'Input must be a dictionary'
116
+ result ['status' ] = status
117
+ result ['msg' ] = '%s: %s' % (status , msg )
118
+ logger .error (msg )
103
119
return signAndPickle (result )
104
120
105
121
106
122
defaults = depick
107
- print defaults
123
+ logger . debug ( defaults )
108
124
109
125
platform = job .task .split ("_" , 1 )[1 ]
110
126
b = builder .Builder .builders [platform ](** defaults )
@@ -120,20 +136,21 @@ def build(worker, job):
120
136
except :
121
137
result ['status' ] = 'ERROR'
122
138
result ['msg' ] = 'Error in either the clone or the checkout'
123
- uploadLogs (b , result )
139
+ logger .exception ('Error in either the clone or checkout' )
140
+ uploadLogs (b , result )
124
141
return signAndPickle (result )
125
142
126
143
zipname = b .filename ()
127
- print " zipname -->%s<--" % zipname
128
-
144
+ logger . debug ( ' zipname: %s' % zipname )
145
+
129
146
# before we take the time to build, first see if a copy of this
130
147
# already exists on S3:
131
148
if upload .check_exists (zipname ):
132
149
result ['status' ] = 'SUCCESS'
133
150
result ['built' ] = False
134
- print "found a copy already!"
151
+ logger . info ( 'zipname already exists on upload target' )
135
152
result ['url' ] = upload .get_url (zipname )
136
- uploadLogs (b , result )
153
+ uploadLogs (b , result )
137
154
return signAndPickle (result )
138
155
139
156
try :
@@ -143,55 +160,56 @@ def build(worker, job):
143
160
144
161
b .post_build ()
145
162
except :
146
- print "something failed"
163
+ logger . exception ( 'build failed' )
147
164
result ['status' ] = 'ERROR'
148
165
result ['msg' ] = "ERROR: build failed. Check the build logs for info"
149
- uploadLogs (b , result )
166
+ uploadLogs (b , result )
150
167
return signAndPickle (result )
151
168
152
169
153
170
archive = b .package ()
154
171
worker .send_job_status (job , 3 + num_phases , 4 + num_phases )
155
- print " archive: -->%s<--" % archive
156
- print " done!"
172
+ logger . debug ( ' archive: %s' % archive )
173
+ logger . info ( 'Build done!' )
157
174
158
175
# upload
159
176
try :
160
177
url = upload .upload (zipname , archive )
161
178
result ['status' ] = 'SUCCESS'
162
179
result ['built' ] = True
163
180
result ['url' ] = url
164
- uploadLogs (b , result )
165
-
166
- package_hook (platform , defaults .get ('repo' , '' ), defaults .get ('checkout' , 'master' ), b .getCommit (), b .getVersion (), url )
167
-
181
+ uploadLogs (b , result )
182
+
183
+ package_hook (platform , defaults .get ('repo' , '' ),
184
+ defaults .get ('checkout' , 'master' ), b .getCommit (),
185
+ b .getVersion (), url )
186
+
168
187
return signAndPickle (result )
169
188
170
189
except :
171
- print "failed to upload to S3"
172
- traceback .print_exc ()
190
+ logger .exception ('Failed to upload to S3' )
173
191
result ['status' ] = 'ERROR'
174
192
result ['msg' ] = "ERROR: failed to upload to S3"
175
193
return signAndPickle (result )
176
194
177
195
if __name__ == "__main__" :
178
196
if not builder .Builder .builders :
179
- print "no supported builders found, exiting..."
197
+ logger . error ( 'No supported builders found, exiting' )
180
198
sys .exit (1 )
181
-
199
+
182
200
this_plat = builder .Builder .builders .keys ()[0 ]
201
+ logger .info ('Identifying as %s_worker' , this_plat )
183
202
gm_worker .set_client_id ("%s_worker" % this_plat )
184
203
for platform in builder .Builder .builders :
204
+ logger .info ('Register builder: %s' % platform )
185
205
gm_worker .register_task ("build_%s" % platform , build )
186
206
187
207
while (1 ):
188
- print " Starting worker for %s" % this_plat
208
+ logger . info ( ' Starting worker' )
189
209
try :
190
210
gm_worker .work ()
191
211
except gearman .errors .ServerUnavailable :
192
- print "Server disconnected. Trying again"
193
-
194
- sys .exit (0 )
195
-
196
-
212
+ logger .warning ('Server disconnected. Trying again' )
213
+ time .sleep (1 )
197
214
215
+ sys .exit (0 )
0 commit comments