File scripts/worker.php changed (mode: 100644) (index 3f1f677..7238259) |
... |
... |
require_once($INC . "/conn.inc.php"); |
22 |
22 |
|
|
23 |
23 |
rg_prof_start('MAIN'); |
rg_prof_start('MAIN'); |
24 |
24 |
|
|
25 |
|
if (!isset($_SERVER['argv'][1])) |
|
26 |
|
$name = 'main'; |
|
27 |
|
else |
|
28 |
|
$name = $_SERVER['argv'][1]; |
|
|
25 |
|
if (!isset($_SERVER['argv'][1])) { |
|
26 |
|
$id = 'main'; |
|
27 |
|
} else { |
|
28 |
|
$id = $_SERVER['argv'][1]; |
|
29 |
|
} |
29 |
30 |
|
|
30 |
|
if (!isset($_SERVER['argv'][2])) |
|
|
31 |
|
if (!isset($_SERVER['argv'][2])) { |
31 |
32 |
$conf_file = '/etc/rocketgit/worker.conf'; |
$conf_file = '/etc/rocketgit/worker.conf'; |
32 |
|
else |
|
|
33 |
|
} else { |
33 |
34 |
$conf_file = $_SERVER['argv'][2]; |
$conf_file = $_SERVER['argv'][2]; |
|
35 |
|
} |
34 |
36 |
|
|
35 |
|
rg_log_set_file($rg_log_dir . '/worker-' . $name . '.log'); |
|
|
37 |
|
rg_log_set_file($rg_log_dir . '/worker-' . $id . '.log'); |
36 |
38 |
rg_log_set_sid("000000"); // to spread the logs |
rg_log_set_sid("000000"); // to spread the logs |
37 |
39 |
|
|
38 |
|
rg_log('name=' . $name . ' conf_file=' . $conf_file); |
|
39 |
40 |
|
|
40 |
41 |
/* |
/* |
41 |
42 |
* Load configuration file |
* Load configuration file |
|
... |
... |
function reload_config() |
95 |
96 |
} |
} |
96 |
97 |
} |
} |
97 |
98 |
|
|
|
99 |
|
if (!isset($conf['master'])) { |
|
100 |
|
rg_log('master line not present in the conf file!'); |
|
101 |
|
sleep(60); |
|
102 |
|
exit(1); |
|
103 |
|
} |
|
104 |
|
|
|
105 |
|
if (!strstr($conf['master'], '://')) { |
|
106 |
|
$conf['master_proto'] = 'tcp'; |
|
107 |
|
$conf['master_host'] = $conf['master']; |
|
108 |
|
$conf['master_port'] = isset($conf['port']) ? $conf['port'] : 65000; |
|
109 |
|
$conf['master_url'] = ''; |
|
110 |
|
} else { |
|
111 |
|
$_t = explode('://', $conf['master']); |
|
112 |
|
$conf['master_proto'] = trim($_t[0]); |
|
113 |
|
$_t = explode('/', $_t[1]); // _t[1]: host[:port][/url] |
|
114 |
|
$_x = explode(':', $_t[0]); // _t[0]: host[:port] |
|
115 |
|
$conf['master_host'] = $_x[0]; |
|
116 |
|
$conf['master_port'] = isset($_x[1]) ? $_x[1] : 443; |
|
117 |
|
$conf['master_url'] = isset($_t[1]) ? $_t[1] : ''; |
|
118 |
|
} |
|
119 |
|
unset($conf['master']); |
|
120 |
|
unset($conf['port']); |
|
121 |
|
|
98 |
122 |
if (!file_exists($conf['state'] . '/key.pub')) { |
if (!file_exists($conf['state'] . '/key.pub')) { |
99 |
123 |
rg_log('Creating SSH key...'); |
rg_log('Creating SSH key...'); |
100 |
124 |
$cmd = 'ssh-keygen -t rsa -b 4096 -N \'\'' |
$cmd = 'ssh-keygen -t rsa -b 4096 -N \'\'' |
|
... |
... |
function reload_config() |
104 |
128 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
105 |
129 |
rg_log('Cannot create key: ' . $r['errmsg'] . '!'); |
rg_log('Cannot create key: ' . $r['errmsg'] . '!'); |
106 |
130 |
sleep(60); |
sleep(60); |
107 |
|
exit(0); |
|
|
131 |
|
exit(1); |
108 |
132 |
} |
} |
109 |
133 |
} |
} |
110 |
134 |
$conf['ssh_key'] = @file_get_contents($conf['state'] . '/key.pub'); |
$conf['ssh_key'] = @file_get_contents($conf['state'] . '/key.pub'); |
111 |
135 |
if ($conf['ssh_key'] === FALSE) { |
if ($conf['ssh_key'] === FALSE) { |
112 |
136 |
rg_log('Cannot load key!'); |
rg_log('Cannot load key!'); |
113 |
|
sleep(60); |
|
|
137 |
|
sleep(1); |
114 |
138 |
exit(0); |
exit(0); |
115 |
139 |
} |
} |
116 |
140 |
|
|
117 |
141 |
rg_log_ml('conf: ' . print_r($conf, TRUE)); |
rg_log_ml('conf: ' . print_r($conf, TRUE)); |
118 |
142 |
} |
} |
119 |
143 |
|
|
|
144 |
|
/* |
|
145 |
|
* Save a job |
|
146 |
|
*/ |
|
147 |
|
function save_job($job) |
|
148 |
|
{ |
|
149 |
|
global $conf; |
|
150 |
|
|
|
151 |
|
$ret = array('ok' => 0); |
|
152 |
|
while (1) { |
|
153 |
|
$j_job = @json_encode($job); |
|
154 |
|
if ($j_job === FALSE) { |
|
155 |
|
$ret['errstr'] = 'cannot encode json: ' . json_last_error(); |
|
156 |
|
break; |
|
157 |
|
} |
|
158 |
|
|
|
159 |
|
$f = $conf['state'] . '/job-' . $job['id'] . '.ser'; |
|
160 |
|
$r = @file_put_contents($f . '.tmp', $j_job); |
|
161 |
|
if ($r === FALSE) { |
|
162 |
|
$ret['errstr'] = 'cannot store job: ' . rg_php_err(); |
|
163 |
|
break; |
|
164 |
|
} |
|
165 |
|
|
|
166 |
|
$r = @rename($f . '.tmp', $f); |
|
167 |
|
if ($r !== TRUE) { |
|
168 |
|
$ret['errstr'] = 'cannot rename job file [' |
|
169 |
|
. $f . ']: ' . rg_php_err(); |
|
170 |
|
break; |
|
171 |
|
} |
|
172 |
|
|
|
173 |
|
$ret['ok'] = 1; |
|
174 |
|
break; |
|
175 |
|
} |
|
176 |
|
|
|
177 |
|
return $ret; |
|
178 |
|
} |
|
179 |
|
|
120 |
180 |
/* |
/* |
121 |
181 |
* Starts an worker |
* Starts an worker |
122 |
182 |
*/ |
*/ |
|
... |
... |
function start_worker($job) |
126 |
186 |
global $php_errormsg; |
global $php_errormsg; |
127 |
187 |
|
|
128 |
188 |
$env = $conf['env'][$job['env']]; |
$env = $conf['env'][$job['env']]; |
129 |
|
rg_log_ml('DEBUG: env: ' . print_r($env, TRUE)); |
|
|
189 |
|
rg_log_ml('DEBUG: start_worker: env: ' . print_r($env, TRUE)); |
130 |
190 |
|
|
131 |
191 |
$jid = $job['id']; |
$jid = $job['id']; |
132 |
192 |
$emain = escapeshellarg($job['main']); |
$emain = escapeshellarg($job['main']); |
|
... |
... |
function start_worker($job) |
134 |
194 |
$name = 'rg-worker-' . $job['id']; |
$name = 'rg-worker-' . $job['id']; |
135 |
195 |
$ename = escapeshellarg($name); |
$ename = escapeshellarg($name); |
136 |
196 |
$master = escapeshellarg($env['image']); |
$master = escapeshellarg($env['image']); |
137 |
|
$img = escapeshellarg($job['main'] . '/image.qcow2'); |
|
138 |
|
$img2 = escapeshellarg($job['main'] . '/image2.raw'); |
|
|
197 |
|
$img = $job['main'] . '/image.qcow2'; |
|
198 |
|
$eimg = escapeshellarg($img); |
|
199 |
|
$img2 = $job['main'] . '/image2.raw'; |
|
200 |
|
$eimg2 = escapeshellarg($img2); |
139 |
201 |
// TODO: add bellow configuration to the web form |
// TODO: add bellow configuration to the web form |
140 |
202 |
if (!isset($job['disk_size_gib'])) |
if (!isset($job['disk_size_gib'])) |
141 |
203 |
$job['disk_size_gib'] = '10'; |
$job['disk_size_gib'] = '10'; |
|
... |
... |
function start_worker($job) |
148 |
210 |
$err = TRUE; |
$err = TRUE; |
149 |
211 |
$reason = ''; $reason2 = ''; |
$reason = ''; $reason2 = ''; |
150 |
212 |
while (1) { |
while (1) { |
151 |
|
rg_exec('virsh destroy ' . $ename, '', FALSE, FALSE, FALSE); |
|
152 |
|
rg_exec('virsh undefine --nvram ' . $ename, '', FALSE, FALSE, FALSE); |
|
153 |
|
|
|
154 |
213 |
$r = rg_del_tree($job['main']); |
$r = rg_del_tree($job['main']); |
155 |
214 |
if ($r === FALSE) { |
if ($r === FALSE) { |
156 |
|
rg_log('Cannot delete main dir (' . $job['main'] . ')!'); |
|
|
215 |
|
$reason = 'cannot delete main dir'; |
|
216 |
|
$reason2 = 'cannot delete main dir (' . $job['main'] . ')'; |
157 |
217 |
break; |
break; |
158 |
218 |
} |
} |
159 |
219 |
|
|
160 |
220 |
$r = @mkdir($job['main'], 0700); |
$r = @mkdir($job['main'], 0700); |
161 |
221 |
if ($r === FALSE) { |
if ($r === FALSE) { |
162 |
|
rg_log('Cannot create main dir (' . $job['main'] . '):' |
|
163 |
|
. ' ' . $php_errormsg . '!'); |
|
|
222 |
|
$reason = 'cannot create main dir'; |
|
223 |
|
$reason2 = 'cannot create main dir (' . $job['main'] . '):' |
|
224 |
|
. ' (' . rg_php_err() . ')'; |
|
225 |
|
break; |
|
226 |
|
} |
|
227 |
|
|
|
228 |
|
$r = save_job($job); |
|
229 |
|
if ($r['ok'] !== 1) { |
|
230 |
|
$reason = 'cannot save job'; |
|
231 |
|
$reason2 = 'cannot save job: ' . $r['errstr']; |
164 |
232 |
break; |
break; |
165 |
233 |
} |
} |
166 |
234 |
|
|
167 |
235 |
// We need to allow libvirt access to the image |
// We need to allow libvirt access to the image |
|
236 |
|
// TODO: 'qemu' must be read from the conf file (on Fedora it is qemu) |
168 |
237 |
$r = rg_exec('chown qemu:qemu ' |
$r = rg_exec('chown qemu:qemu ' |
169 |
238 |
. escapeshellarg($job['main']), '', FALSE, FALSE, FALSE); |
. escapeshellarg($job['main']), '', FALSE, FALSE, FALSE); |
170 |
239 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
171 |
|
$reason = 'cannot chown build dir to qemu user: ' . $r['errmsg']; |
|
172 |
|
$reason2 = $r['stderr']; |
|
|
240 |
|
$reason = 'cannot chown build dir to qemu user'; |
|
241 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
173 |
242 |
break; |
break; |
174 |
243 |
} |
} |
175 |
244 |
|
|
176 |
|
// TODO: This will be used to clean up on a restart |
|
177 |
|
$r = @file_put_contents($job['main'] . '/job.ser.tmp', |
|
178 |
|
serialize($job)); |
|
179 |
|
if ($r === FALSE) { |
|
180 |
|
$reason = 'cannot store job'; |
|
181 |
|
break; |
|
182 |
|
} |
|
183 |
|
$r = @rename($job['main'] . '/job.ser.tmp', $job['main'] . '/job.ser'); |
|
184 |
|
if ($r === FALSE) { |
|
185 |
|
$reason = 'cannot rename job file'; |
|
186 |
|
break; |
|
187 |
|
} |
|
|
245 |
|
rg_exec('virsh destroy ' . $ename, '', FALSE, FALSE, FALSE); |
|
246 |
|
rg_exec('virsh undefine --nvram ' . $ename, '', FALSE, FALSE, FALSE); |
188 |
247 |
|
|
189 |
248 |
$r = rg_exec('qemu-img create -o lazy_refcounts=on,cluster_size=256K' |
$r = rg_exec('qemu-img create -o lazy_refcounts=on,cluster_size=256K' |
190 |
249 |
. ' -b ' . $master |
. ' -b ' . $master |
191 |
|
. ' -f qcow2 ' . $img, '', FALSE, FALSE, FALSE); |
|
|
250 |
|
. ' -f qcow2 ' . $eimg, '', FALSE, FALSE, FALSE); |
192 |
251 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
193 |
|
$reason = 'cannot create image: ' . $r['errmsg']; |
|
194 |
|
$reason2 = $r['stderr']; |
|
|
252 |
|
$reason = 'cannot create VM image'; |
|
253 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
195 |
254 |
break; |
break; |
196 |
255 |
} |
} |
197 |
256 |
|
|
198 |
257 |
// TODO: let the user specify the maximum disk space? |
// TODO: let the user specify the maximum disk space? |
199 |
|
$r = rg_exec('qemu-img create -f raw ' . $img2 |
|
|
258 |
|
$r = rg_exec('qemu-img create -f raw ' . $eimg2 |
200 |
259 |
. ' ' . escapeshellarg($job['disk_size_gib'] . 'G'), |
. ' ' . escapeshellarg($job['disk_size_gib'] . 'G'), |
201 |
260 |
'', FALSE, FALSE, FALSE); |
'', FALSE, FALSE, FALSE); |
202 |
261 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
203 |
|
$reason = 'cannot create image2: ' . $r['errmsg']; |
|
204 |
|
$reason2 = $r['stderr']; |
|
|
262 |
|
$reason = 'cannot create VM image2'; |
|
263 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
205 |
264 |
break; |
break; |
206 |
265 |
} |
} |
207 |
266 |
|
|
|
... |
... |
function start_worker($job) |
209 |
268 |
$path = getenv('PATH'); |
$path = getenv('PATH'); |
210 |
269 |
putenv('PATH=' . $path . ':/usr/sbin'); |
putenv('PATH=' . $path . ':/usr/sbin'); |
211 |
270 |
|
|
212 |
|
$r = rg_exec('mkfs.ext4 -L RG ' . $img2, '', FALSE, FALSE, FALSE); |
|
|
271 |
|
// TODO: let user choose fs type? |
|
272 |
|
$r = rg_exec('mkfs.ext4 -L RG ' . $eimg2, '', FALSE, FALSE, FALSE); |
213 |
273 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
214 |
|
$reason = 'cannot create fs: ' . $r['errmsg']; |
|
215 |
|
$reason2 = $r['stderr']; |
|
|
274 |
|
$reason = 'cannot create fs'; |
|
275 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
216 |
276 |
break; |
break; |
217 |
277 |
} |
} |
218 |
278 |
|
|
219 |
279 |
$r = @mkdir($job['main'] . '/root', 0700); |
$r = @mkdir($job['main'] . '/root', 0700); |
220 |
280 |
if ($r === FALSE) { |
if ($r === FALSE) { |
221 |
|
$reason = 'Cannot create root dir: ' . $php_errormsg . '!'; |
|
|
281 |
|
$reason = 'cannot create root dir'; |
|
282 |
|
$reason2 = 'cannot create root dir (' . rg_php_err() . ')'; |
222 |
283 |
break; |
break; |
223 |
284 |
} |
} |
224 |
285 |
|
|
225 |
|
$r = rg_exec('mount ' . $img2 . ' ' . $emain . '/root', |
|
|
286 |
|
$r = rg_exec('mount ' . $eimg2 . ' ' . $emain . '/root', |
226 |
287 |
'', FALSE, FALSE, FALSE); |
'', FALSE, FALSE, FALSE); |
227 |
288 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
228 |
|
$reason = 'cannot mount fs: ' . $r['errmsg']; |
|
229 |
|
$reason2 = $r['stderr']; |
|
|
289 |
|
$reason = 'cannot mount fs'; |
|
290 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
230 |
291 |
break; |
break; |
231 |
292 |
} |
} |
232 |
293 |
$do_umount = TRUE; |
$do_umount = TRUE; |
|
... |
... |
function start_worker($job) |
243 |
304 |
$cmd = ' git clone --depth 1' |
$cmd = ' git clone --depth 1' |
244 |
305 |
. ' --recurse-submodules' |
. ' --recurse-submodules' |
245 |
306 |
. ' --shallow-submodules' |
. ' --shallow-submodules' |
|
307 |
|
. ' --no-checkout' |
246 |
308 |
. ' ' . escapeshellarg($job['url']) |
. ' ' . escapeshellarg($job['url']) |
247 |
309 |
. ' ' . $emain . '/root/git'; |
. ' ' . $emain . '/root/git'; |
248 |
310 |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
249 |
311 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
250 |
|
$reason = 'cannot clone: ' . $r['errmsg']; |
|
251 |
|
$reason2 = $r['stderr']; |
|
|
312 |
|
$reason = 'git clone error'; |
|
313 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
252 |
314 |
break; |
break; |
253 |
315 |
} |
} |
254 |
316 |
|
|
255 |
317 |
// Build command list |
// Build command list |
256 |
318 |
// TODO: document how a user can add labels in configure or make |
// TODO: document how a user can add labels in configure or make |
257 |
|
$s = 'export RG_LABELS=/mnt/status/RG_LABELS' . "\n\n"; |
|
|
319 |
|
$s = '#!/bin/bash' . "\n"; |
|
320 |
|
$s .= 'export RG_LABELS=/mnt/status/RG_LABELS' . "\n\n"; |
258 |
321 |
$s .= 'cd /mnt/git' . "\n\n"; |
$s .= 'cd /mnt/git' . "\n\n"; |
259 |
|
$s .= 'git checkout ' . escapeshellarg($job['head']) . "\n"; |
|
260 |
|
foreach ($job['cmds'] as $name => $i) { |
|
|
322 |
|
$s .= 'git checkout -b rgw ' . escapeshellarg($job['head']) . "\n"; |
|
323 |
|
foreach ($job['cmds'] as $_name => $i) { |
261 |
324 |
if (empty($i['cmd'])) |
if (empty($i['cmd'])) |
262 |
325 |
continue; |
continue; |
263 |
326 |
|
|
264 |
327 |
$prefix = '/mnt/status/' |
$prefix = '/mnt/status/' |
265 |
|
. escapeshellarg($name); |
|
|
328 |
|
. escapeshellarg($_name); |
266 |
329 |
|
|
267 |
330 |
if (empty($i['label_ok'])) |
if (empty($i['label_ok'])) |
268 |
331 |
$lok = ''; |
$lok = ''; |
|
... |
... |
function start_worker($job) |
279 |
342 |
. ' >>/mnt/status/RG_LABELS' . "\n"; |
. ' >>/mnt/status/RG_LABELS' . "\n"; |
280 |
343 |
|
|
281 |
344 |
$s .= 'date +%s > ' . $prefix . '.start' . "\n" |
$s .= 'date +%s > ' . $prefix . '.start' . "\n" |
282 |
|
. '(' . $i['cmd'] . ') 1>' . $prefix . '.log 2>&1' . "\n" |
|
|
345 |
|
. 'echo "Executing [' . $i['cmd'] . ']..."' . "\n" |
|
346 |
|
. '(' . $i['cmd'] . ') &>' . $prefix . '.log' . "\n" |
283 |
347 |
. 'E=${?}' . "\n" |
. 'E=${?}' . "\n" |
|
348 |
|
. 'echo ${E} > ' . $prefix . ".status\n" |
284 |
349 |
. 'date +%s > ' . $prefix . '.done' . "\n" |
. 'date +%s > ' . $prefix . '.done' . "\n" |
285 |
350 |
. 'if [ "${E}" != "0" ]; then' . "\n" |
. 'if [ "${E}" != "0" ]; then' . "\n" |
286 |
|
. ' echo ${E} > ' . $prefix . ".status\n" |
|
287 |
|
. $lnok |
|
288 |
|
. ($i['abort'] ? ' exit 0' . "\n" : '') |
|
|
351 |
|
. ' echo -n # just to not have an empty if branch' . "\n" |
|
352 |
|
. $lnok |
|
353 |
|
. ($i['abort'] ? ' exit 0' . "\n" : '') |
289 |
354 |
. 'else' . "\n" |
. 'else' . "\n" |
290 |
|
. ' echo 0 > ' . $prefix . ".status\n" |
|
291 |
|
. $lok |
|
|
355 |
|
. ' echo -n # just to not have an empty if branch' . "\n" |
|
356 |
|
. $lok |
292 |
357 |
. 'fi' . "\n\n"; |
. 'fi' . "\n\n"; |
293 |
358 |
} |
} |
294 |
359 |
rg_log_ml('DEBUG: build.sh: ' . $s); |
rg_log_ml('DEBUG: build.sh: ' . $s); |
295 |
360 |
$r = @file_put_contents($job['main'] . '/root/build.sh', $s); |
$r = @file_put_contents($job['main'] . '/root/build.sh', $s); |
296 |
361 |
if ($r === FALSE) { |
if ($r === FALSE) { |
297 |
|
$reason = 'cannot store build commands!'; |
|
|
362 |
|
$reason = 'cannot store build commands'; |
|
363 |
|
$reason2 = 'cannot store build commands (' . rg_php_err() . ')'; |
298 |
364 |
break; |
break; |
299 |
365 |
} |
} |
300 |
366 |
$r = @chmod($job['main'] . '/root/build.sh', 0755); |
$r = @chmod($job['main'] . '/root/build.sh', 0755); |
301 |
367 |
if ($r === FALSE) { |
if ($r === FALSE) { |
302 |
|
$reason = 'cannot chmod build.sh!'; |
|
|
368 |
|
$reason = 'cannot chmod build.sh'; |
|
369 |
|
$reason2 = 'cannot chmod build.sh (' . rg_php_err() . ')'; |
303 |
370 |
break; |
break; |
304 |
371 |
} |
} |
305 |
372 |
|
|
|
... |
... |
function start_worker($job) |
318 |
385 |
} |
} |
319 |
386 |
|
|
320 |
387 |
// Store commands |
// Store commands |
|
388 |
|
// TODO: set TMP somewhere on /mnt? (bind mount /mnt/tmp into /tmp)? |
321 |
389 |
$r = @file_put_contents($job['main'] . '/root/rg.sh', |
$r = @file_put_contents($job['main'] . '/root/rg.sh', |
322 |
|
'mkdir /mnt/status' . "\n" |
|
|
390 |
|
'#!/bin/bash' . "\n" |
|
391 |
|
. 'mkdir /mnt/status' . "\n" |
323 |
392 |
. 'chown -R build:build /mnt/git /mnt/status' . "\n" |
. 'chown -R build:build /mnt/git /mnt/status' . "\n" |
|
393 |
|
. 'echo "PATH=${PATH}"' . "\n" |
|
394 |
|
. 'ERR=""' . "\n" |
|
395 |
|
. 'id' . "\n" |
324 |
396 |
. 'date +%s > /mnt/T_START' . "\n" |
. 'date +%s > /mnt/T_START' . "\n" |
325 |
397 |
. '# Waiting for net...' . "\n" |
. '# Waiting for net...' . "\n" |
326 |
398 |
. 'while [ "`ip ro li | grep ^default`" = "" ]; do' . "\n" |
. 'while [ "`ip ro li | grep ^default`" = "" ]; do' . "\n" |
327 |
|
. ' (date; ip ro) &>>/mnt/status/wait_net.log' . "\n" |
|
|
399 |
|
. ' (date; ip ro li) &>>/mnt/status/wait_net.log' . "\n" |
328 |
400 |
. ' sleep 1' . "\n" |
. ' sleep 1' . "\n" |
329 |
401 |
. 'done' . "\n" |
. 'done' . "\n" |
330 |
|
. 'ip ro li >/mnt/status/iproli.log' . "\n" |
|
331 |
402 |
. 'date +%s > /mnt/T_NET_OK' . "\n\n" |
. 'date +%s > /mnt/T_NET_OK' . "\n\n" |
|
403 |
|
. '' . "\n" |
332 |
404 |
. $p_i_cmd |
. $p_i_cmd |
333 |
405 |
. 'date +%s > /mnt/T_PKGS_OK' . "\n\n" |
. 'date +%s > /mnt/T_PKGS_OK' . "\n\n" |
334 |
|
. 'su - build -c /mnt/build.sh &>/mnt/status/build.log' . "\n\n" |
|
335 |
|
. 'sync' . "\n" |
|
|
406 |
|
. '' . "\n" |
|
407 |
|
. '# Disabling further module loading.' . "\n" |
|
408 |
|
. 'echo 1 > /proc/sys/kernel/modules_disabled' . "\n" |
|
409 |
|
. '# Disabling root login' . "\n" |
|
410 |
|
. 'chage -E 0 root' . "\n" |
|
411 |
|
. 'if [ "${?}" != "0" ]; then' . "\n" |
|
412 |
|
. ' ERR="cannot disable root account"' . "\n" |
|
413 |
|
. 'fi' . "\n" |
|
414 |
|
. 'if [ "${ERR}" = "" ]; then' . "\n" |
|
415 |
|
. ' su - build -c "bash /mnt/build.sh" &>/mnt/status/build.log' . "\n" |
|
416 |
|
. ' sync' . "\n" |
|
417 |
|
. 'else' . "\n" |
|
418 |
|
. ' echo "${ERR}" > /mnt/status/err' . "\n" |
|
419 |
|
. 'fi' . "\n" |
336 |
420 |
. 'date +%s > /mnt/T_DONE' . "\n\n" |
. 'date +%s > /mnt/T_DONE' . "\n\n" |
337 |
|
. 'xxxshutdown -h now' |
|
|
421 |
|
. 'shutdown -h now' |
338 |
422 |
); |
); |
339 |
423 |
if ($r === FALSE) { |
if ($r === FALSE) { |
340 |
|
$reason = 'cannot store commands!'; |
|
|
424 |
|
$reason = 'cannot store commands'; |
|
425 |
|
$reason2 = 'cannot store commands (' . rg_php_err() . ')'; |
341 |
426 |
break; |
break; |
342 |
427 |
} |
} |
343 |
428 |
$r = @chmod($job['main'] . '/root/rg.sh', 0700); |
$r = @chmod($job['main'] . '/root/rg.sh', 0700); |
344 |
429 |
if ($r === FALSE) { |
if ($r === FALSE) { |
345 |
|
$reason = 'cannot to chmod on rg.sh!'; |
|
|
430 |
|
$reason = 'cannot to chmod on rg.sh'; |
|
431 |
|
$reason2 = 'cannot to chmod on rg.sh (' . rg_php_err() . ')'; |
346 |
432 |
break; |
break; |
347 |
433 |
} |
} |
348 |
434 |
|
|
349 |
435 |
$r = rg_exec('umount ' . $emain . '/root', '', FALSE, FALSE, FALSE); |
$r = rg_exec('umount ' . $emain . '/root', '', FALSE, FALSE, FALSE); |
350 |
436 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
351 |
|
$reason = 'cannot umount fs: ' . $r['errmsg']; |
|
352 |
|
$reason2 = $r['stderr']; |
|
|
437 |
|
$reason = 'cannot umount fs'; |
|
438 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
353 |
439 |
break; |
break; |
354 |
440 |
} |
} |
355 |
441 |
$do_umount = FALSE; |
$do_umount = FALSE; |
356 |
442 |
|
|
357 |
443 |
// We need to allow libvirt access to the image |
// We need to allow libvirt access to the image |
358 |
|
$r = rg_exec('chown qemu:qemu ' . $img2, '', FALSE, FALSE, FALSE); |
|
|
444 |
|
$r = rg_exec('chown qemu:qemu ' . $eimg2, '', FALSE, FALSE, FALSE); |
359 |
445 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
360 |
|
$reason = 'cannot chown image to qemu user: ' . $r['errmsg']; |
|
361 |
|
$reason2 = $r['stderr']; |
|
|
446 |
|
$reason = 'cannot chown image to qemu user'; |
|
447 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
362 |
448 |
break; |
break; |
363 |
449 |
} |
} |
364 |
450 |
|
|
365 |
451 |
// TODO: store the path to the templates in the configuration file. |
// TODO: store the path to the templates in the configuration file. |
366 |
|
$template = @file_get_contents('/var/lib/libvirt/images/rgw/templates/' |
|
367 |
|
. escapeshellarg($env['arch']) . '.xml'); |
|
|
452 |
|
$_f = '/var/lib/libvirt/images/rgw/templates/' . $env['arch'] . '.xml'; |
|
453 |
|
$template = @file_get_contents($_f); |
368 |
454 |
if ($template === FALSE) { |
if ($template === FALSE) { |
369 |
455 |
$reason = 'cannot load template'; |
$reason = 'cannot load template'; |
|
456 |
|
$reason2 = 'cannot load template from ' . $_f . ': ' . rg_php_err(); |
370 |
457 |
break; |
break; |
371 |
458 |
} |
} |
372 |
|
str_replace('@@name@@', $name, $template); |
|
373 |
|
str_replace('@@mem@@', $job['mem_mib'], $template); |
|
374 |
|
str_replace('@@cpus@@', $job['cpus'], $template); |
|
375 |
|
str_replace('@@disk0@@', $img, $template); |
|
376 |
|
str_replace('@@disk1@@', $img2, $template); |
|
|
459 |
|
$template = str_replace('@@name@@', $name, $template); |
|
460 |
|
$template = str_replace('@@mem@@', $job['mem_mib'], $template); |
|
461 |
|
$template = str_replace('@@cpus@@', $job['cpus'], $template); |
|
462 |
|
$template = str_replace('@@disk0@@', $img, $template); |
|
463 |
|
$template = str_replace('@@disk0_type@@', 'qcow2', $template); |
|
464 |
|
$template = str_replace('@@disk1@@', $img2, $template); |
|
465 |
|
$template = str_replace('@@disk1_type@@', 'raw', $template); |
377 |
466 |
// TODO: allow firewall specification |
// TODO: allow firewall specification |
378 |
|
str_replace('@@net0@@', '<interface type=\'network\'><source network=\'default\'/><model type=\'virtio\'/></interface>', $template); |
|
|
467 |
|
$template = str_replace('@@net0@@', '<interface type=\'network\'><source network=\'default\'/><model type=\'virtio\'/></interface>', $template); |
379 |
468 |
// TODO: take care of XML injection? |
// TODO: take care of XML injection? |
380 |
|
str_replace('@@chan1_path@@', $job['main'] . '/x.chan', $template); |
|
381 |
|
$r = @file_put_contents($job['main'] . '/machine.xml'); |
|
|
469 |
|
$template = str_replace('@@chan1_path@@', $job['main'] . '/x.chan', $template); |
|
470 |
|
$_xml = $job['main'] . '/machine.xml'; |
|
471 |
|
$r = @file_put_contents($_xml, $template); |
382 |
472 |
if ($r === FALSE) { |
if ($r === FALSE) { |
383 |
|
$reason = 'cannot store template file.'; |
|
384 |
|
break; |
|
385 |
|
} |
|
386 |
|
|
|
387 |
|
$r = rg_exec('virsh define ' . escapeshellarg($job['main'] . '/machine.xml')); |
|
388 |
|
if ($r['ok'] !== 1) { |
|
389 |
|
$reason = 'cannot define machine: ' . $r['errmsg']; |
|
390 |
|
$reason2 = $r['stderr']; |
|
|
473 |
|
$reason = 'cannot store template file'; |
|
474 |
|
$reason2 = 'cannot store template in ' . $_xml . ': ' . rg_php_err(); |
391 |
475 |
break; |
break; |
392 |
476 |
} |
} |
393 |
477 |
|
|
394 |
|
$r = rg_exec('virsh start ' . $ename); |
|
|
478 |
|
$r = rg_exec('virsh create ' . escapeshellarg($_xml), |
|
479 |
|
'', FALSE, FALSE, FALSE); |
395 |
480 |
if ($r['ok'] !== 1) { |
if ($r['ok'] !== 1) { |
396 |
|
$reason = 'cannot start machine: ' . $r['errmsg']; |
|
397 |
|
$reason2 = $r['stderr']; |
|
|
481 |
|
$reason = 'cannot define VM'; |
|
482 |
|
$reason2 = $r['errmsg'] . ': ' . $r['stderr']; |
398 |
483 |
break; |
break; |
399 |
484 |
} |
} |
400 |
485 |
|
|
|
... |
... |
function start_worker($job) |
404 |
489 |
if ($do_umount) |
if ($do_umount) |
405 |
490 |
rg_exec('umount ' . $emain . '/root', '', FALSE, FALSE, FALSE); |
rg_exec('umount ' . $emain . '/root', '', FALSE, FALSE, FALSE); |
406 |
491 |
|
|
407 |
|
// Seems that any error above must retrigger the build on other worker |
|
|
492 |
|
// Any error above must retrigger the build on other worker |
408 |
493 |
if ($err) { |
if ($err) { |
|
494 |
|
rg_log('error: ' . $reason); |
|
495 |
|
rg_log('error2: ' . $reason2); |
409 |
496 |
@file_put_contents($job['main'] . '/error.log', $reason); |
@file_put_contents($job['main'] . '/error.log', $reason); |
410 |
497 |
@file_put_contents($job['main'] . '/error2.log', $reason2); |
@file_put_contents($job['main'] . '/error2.log', $reason2); |
411 |
498 |
} |
} |
|
499 |
|
|
|
500 |
|
rg_log('Done'); |
412 |
501 |
} |
} |
413 |
502 |
|
|
414 |
503 |
/* |
/* |
415 |
|
* Handle received commands |
|
|
504 |
|
* Handle received commands (one JSON) |
416 |
505 |
*/ |
*/ |
417 |
|
function xhandle($key, $cmd0) |
|
|
506 |
|
function xhandle_one($key, $data) |
418 |
507 |
{ |
{ |
|
508 |
|
global $rg_log_dir; |
419 |
509 |
global $jobs; |
global $jobs; |
420 |
510 |
global $conf; |
global $conf; |
421 |
511 |
global $pid_to_jid; |
global $pid_to_jid; |
422 |
512 |
|
|
423 |
|
$cmd = substr($cmd0, 0, 4); |
|
424 |
|
$data = stripcslashes(trim(substr($cmd0, 4))); |
|
425 |
|
$job = @unserialize($data); |
|
426 |
|
if ($job === FALSE) { |
|
427 |
|
rg_log('Cannot unserialize [' . $data . ']'); |
|
|
513 |
|
$job = @json_decode($data, TRUE); |
|
514 |
|
if ($job === NULL) { |
|
515 |
|
rg_log_ml('Cannot decode JSON: ' . json_last_error_msg()); |
|
516 |
|
$err = array('errstr' => 'cannot decode json'); |
|
517 |
|
rg_conn_enq('master', json_encode($err) . "\n"); |
428 |
518 |
rg_conn_destroy($key); |
rg_conn_destroy($key); |
429 |
519 |
return; |
return; |
430 |
520 |
} |
} |
431 |
521 |
|
|
432 |
522 |
$jid = $job['id']; |
$jid = $job['id']; |
433 |
523 |
|
|
434 |
|
if (strcmp($cmd, 'BLD ') == 0) { |
|
|
524 |
|
if (strcmp($job['op'], 'BLD') == 0) { |
435 |
525 |
// TODO: should we confirm quickly if the job is accepted, |
// TODO: should we confirm quickly if the job is accepted, |
436 |
526 |
// even if we could not fork? |
// even if we could not fork? |
|
527 |
|
|
437 |
528 |
if (isset($jobs[$jid])) { |
if (isset($jobs[$jid])) { |
438 |
529 |
// TODO: this should not happen, right? |
// TODO: this should not happen, right? |
439 |
530 |
rg_log('Job ' . $jid . ' already in queue!'); |
rg_log('Job ' . $jid . ' already in queue!'); |
|
... |
... |
function xhandle($key, $cmd0) |
454 |
545 |
break; |
break; |
455 |
546 |
} |
} |
456 |
547 |
if ($pid == 0) { // child |
if ($pid == 0) { // child |
|
548 |
|
rg_log_set_file($rg_log_dir . '/worker-' . $conf['id'] |
|
549 |
|
. '-' . $jid . '.log'); |
457 |
550 |
start_worker($jobs[$jid]); |
start_worker($jobs[$jid]); |
458 |
551 |
exit(0); |
exit(0); |
459 |
552 |
} |
} |
|
... |
... |
function xhandle($key, $cmd0) |
466 |
559 |
} |
} |
467 |
560 |
$a = array('id' => $jid); |
$a = array('id' => $jid); |
468 |
561 |
if ($err) { |
if ($err) { |
|
562 |
|
$a['op'] = 'ABR'; |
469 |
563 |
$a['reason'] = $reason; |
$a['reason'] = $reason; |
470 |
|
rg_conn_enq('master', 'ABR ' . rg_conn_prepare($a) . "\n"); |
|
|
564 |
|
rg_conn_enq('master', json_encode($a) . "\n"); |
471 |
565 |
unset($pid_to_jid[$pid]); |
unset($pid_to_jid[$pid]); |
472 |
566 |
unset($jobs[$jid]); |
unset($jobs[$jid]); |
473 |
567 |
return; |
return; |
474 |
568 |
} |
} |
475 |
|
rg_conn_enq('master', 'STA ' . rg_conn_prepare($a) . "\n"); |
|
476 |
|
} else if (strcmp($cmd, 'DRE ') == 0) { // DRE = done received |
|
|
569 |
|
$a['op'] = 'STA'; |
|
570 |
|
rg_conn_enq('master', json_encode($a) . "\n"); |
|
571 |
|
} else if (strcmp($job['op'], 'DRE') == 0) { // DRE = done received |
477 |
572 |
// So, we can clean up everything related to this job |
// So, we can clean up everything related to this job |
478 |
573 |
// TODO: do we clear the state file? |
// TODO: do we clear the state file? |
479 |
574 |
rg_log('DRE command'); |
rg_log('DRE command'); |
480 |
|
$job = &$jobs[$jid]; |
|
481 |
|
unset($pid_to_jid[$job['pid']]); |
|
|
575 |
|
$_job = &$jobs[$jid]; |
|
576 |
|
unset($pid_to_jid[$_job['pid']]); |
482 |
577 |
unset($jobs[$jid]); |
unset($jobs[$jid]); |
483 |
|
@unlink($job['main'] . '/job.ser'); |
|
|
578 |
|
@unlink($conf['state'] . '/job-' . $jid . '.ser'); |
484 |
579 |
} else { |
} else { |
485 |
|
rg_log('Cannot handle[' . $key . ']: ' . $cmd); |
|
|
580 |
|
rg_log($key . ': cannot handle op: ' . $job['op']); |
486 |
581 |
} |
} |
487 |
582 |
} |
} |
488 |
583 |
|
|
|
584 |
|
/* |
|
585 |
|
* Handle received commands |
|
586 |
|
*/ |
|
587 |
|
function xhandle($key, $data) |
|
588 |
|
{ |
|
589 |
|
$ret = 0; |
|
590 |
|
while (1) { |
|
591 |
|
$pos = strpos($data, "\n"); |
|
592 |
|
if ($pos === FALSE) |
|
593 |
|
return $ret; |
|
594 |
|
|
|
595 |
|
$one = substr($data, 0, $pos); |
|
596 |
|
xhandle_one($key, $one); |
|
597 |
|
$data = substr($data, $pos + 1); |
|
598 |
|
$ret += $pos + 1; |
|
599 |
|
} |
|
600 |
|
|
|
601 |
|
return $ret; |
|
602 |
|
} |
|
603 |
|
|
489 |
604 |
/* |
/* |
490 |
605 |
* Extracts info from the virtual disk |
* Extracts info from the virtual disk |
491 |
606 |
* TODO: if something fails, we may keep the file mounted! |
* TODO: if something fails, we may keep the file mounted! |
|
... |
... |
function rg_job_extract_info(&$job) |
512 |
627 |
break; |
break; |
513 |
628 |
} |
} |
514 |
629 |
|
|
|
630 |
|
// Extract how much disk space was used |
|
631 |
|
$r = stat($job['main'] . '/image2.raw'); |
|
632 |
|
if ($r === FALSE) { |
|
633 |
|
$job['error'] = 'Missing image2 file'; |
|
634 |
|
break; |
|
635 |
|
} |
|
636 |
|
$job['status']['disk_used_mib'] = intval($r['blocks'] / 2 / 1024); |
|
637 |
|
// TODO - remove this |
|
638 |
|
$cmd = 'ln -f ' . $emain . '/image2.raw ' . $emain . '/..'; |
|
639 |
|
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
|
640 |
|
|
515 |
641 |
$cmd = 'mount ' . $emain . '/image2.raw ' . $emain . '/root'; |
$cmd = 'mount ' . $emain . '/image2.raw ' . $emain . '/root'; |
516 |
642 |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
517 |
643 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
|
... |
... |
function rg_job_extract_info(&$job) |
519 |
645 |
break; |
break; |
520 |
646 |
} |
} |
521 |
647 |
|
|
|
648 |
|
$r = @file_get_contents($job['main'] . '/root/status/err'); |
|
649 |
|
if ($r !== FALSE) { |
|
650 |
|
$job['error'] = $r; |
|
651 |
|
break; |
|
652 |
|
} |
|
653 |
|
|
522 |
654 |
$labels = @file($job['main'] . '/root/status/RG_LABELS'); |
$labels = @file($job['main'] . '/root/status/RG_LABELS'); |
523 |
655 |
if ($labels === FALSE) |
if ($labels === FALSE) |
524 |
656 |
$labels = array(); |
$labels = array(); |
|
... |
... |
function rg_job_extract_info(&$job) |
543 |
675 |
|
|
544 |
676 |
$sd = $job['main'] . '/root/status/' . $cmd; |
$sd = $job['main'] . '/root/status/' . $cmd; |
545 |
677 |
$job['status']['cmds'][$cmd] = array( |
$job['status']['cmds'][$cmd] = array( |
546 |
|
'start' => @trim(file_get_contents($sd . '.start')), |
|
547 |
|
'done' => @trim(file_get_contents($sd . '.done')), |
|
548 |
|
'log' => @file_get_contents($sd . '.log', FALSE, |
|
549 |
|
NULL, -1, 4 * 4096) |
|
|
678 |
|
'cmd' => $i['cmd'], |
|
679 |
|
'start' => trim(file_get_contents($sd . '.start')), |
|
680 |
|
'done' => trim(file_get_contents($sd . '.done')), |
|
681 |
|
'status' => trim(file_get_contents($sd . '.status')), |
|
682 |
|
'log' => trim(rg_file_get_tail($sd . '.log', 4 * 4096)) |
550 |
683 |
); |
); |
551 |
684 |
} |
} |
552 |
685 |
unset($job['cmds']); |
unset($job['cmds']); |
553 |
686 |
unset($job['url']); |
unset($job['url']); |
554 |
687 |
unset($job['head']); |
unset($job['head']); |
555 |
688 |
unset($job['env']); |
unset($job['env']); |
|
689 |
|
break; |
|
690 |
|
} |
|
691 |
|
|
|
692 |
|
$cmd = 'umount ' . $emain . '/root'; |
|
693 |
|
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
|
694 |
|
if ($r['ok'] != 1) |
|
695 |
|
rg_log('Cannot unmount [' . $job['main'] . '/root]: ' . $r['errmsg'] . '!'); |
|
696 |
|
|
|
697 |
|
rg_del_tree($job['main']); |
|
698 |
|
|
|
699 |
|
rg_log_ml('DEBUG: job: ' . print_r($job, TRUE)); |
|
700 |
|
return TRUE; |
|
701 |
|
} |
556 |
702 |
|
|
557 |
|
$cmd = 'umount ' . $emain . '/root'; |
|
|
703 |
|
/* |
|
704 |
|
* Extract blk/net/cpu/mem info from a VM |
|
705 |
|
*/ |
|
706 |
|
function vm_extract_info($name) |
|
707 |
|
{ |
|
708 |
|
$ret = array(); |
|
709 |
|
while (1) { |
|
710 |
|
$cmd = 'virsh domstats --raw ' . escapeshellarg($name); |
558 |
711 |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
559 |
712 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
560 |
|
rg_log('Cannot unmount: ' . $r['errmsg'] . '!'); |
|
|
713 |
|
rg_log('Could not get dom stats: ' . $r['errmsg']); |
561 |
714 |
break; |
break; |
562 |
715 |
} |
} |
563 |
716 |
|
|
564 |
|
rg_del_tree($job['main']); |
|
|
717 |
|
//rg_log_ml('DEBUG: domstats: ' . print_r($r['data'], TRUE)); |
|
718 |
|
$data = array(); |
|
719 |
|
$t = explode("\n", $r['data']); |
|
720 |
|
foreach ($t as $line) { |
|
721 |
|
$line = trim($line); |
|
722 |
|
$x = explode('=', $line, 2); |
|
723 |
|
if (!isset($x[1])) |
|
724 |
|
continue; |
|
725 |
|
$data[$x[0]] = $x[1]; |
|
726 |
|
} |
|
727 |
|
|
|
728 |
|
$ret['rx_bytes'] = $data['net.0.rx.bytes']; |
|
729 |
|
$ret['rx_pkts'] = $data['net.0.rx.pkts']; |
|
730 |
|
$ret['tx_bytes'] = $data['net.0.tx.bytes']; |
|
731 |
|
$ret['tx_pkts'] = $data['net.0.tx.pkts']; |
|
732 |
|
|
|
733 |
|
$ret['block_read_ops'] = $data['block.1.rd.reqs']; |
|
734 |
|
$ret['block_read_bytes'] = $data['block.1.rd.bytes']; |
|
735 |
|
$ret['block_write_ops'] = $data['block.1.wr.reqs']; |
|
736 |
|
$ret['block_write_bytes'] = $data['block.1.wr.bytes']; |
|
737 |
|
$ret['block_physical_bytes'] = $data['block.1.physical']; |
|
738 |
|
$ret['block_allocation_bytes'] = $data['block.1.allocation']; |
|
739 |
|
|
|
740 |
|
$ret['cpu_time_ns'] = $data['cpu.time']; |
|
741 |
|
$ret['ballon_current_mib'] = intval($data['balloon.current'] / 1024); |
|
742 |
|
$ret['ballon_rss_mib'] = intval($data['balloon.rss'] / 1024); |
565 |
743 |
break; |
break; |
566 |
744 |
} |
} |
567 |
745 |
|
|
568 |
|
rg_log_ml('DEBUG: job: ' . print_r($job, TRUE)); |
|
569 |
|
return TRUE; |
|
|
746 |
|
return $ret; |
570 |
747 |
} |
} |
571 |
748 |
|
|
572 |
749 |
|
|
573 |
750 |
reload_config(); |
reload_config(); |
|
751 |
|
$conf['id'] = $id; |
|
752 |
|
|
|
753 |
|
rg_log('Connecting to ' . $conf['master_host'] . '/' . $conf['master_port'] |
|
754 |
|
. ' with proto ' . $conf['master_proto'] |
|
755 |
|
. ' with url [' . $conf['master_url'] . ']' . '...'); |
|
756 |
|
if (strcmp($conf['master_proto'], 'tcp') == 0) { |
|
757 |
|
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); |
|
758 |
|
if ($socket === FALSE) { |
|
759 |
|
rg_log('Cannot create socket: ' . rg_php_err()); |
|
760 |
|
exit(1); |
|
761 |
|
} |
574 |
762 |
|
|
|
763 |
|
$r = @socket_connect($socket, $conf['master_host'], $conf['master_port']); |
|
764 |
|
if ($r === FALSE) { |
|
765 |
|
rg_log('Cannot connect: ' . rg_php_err()); |
|
766 |
|
exit(1); |
|
767 |
|
} |
|
768 |
|
} else if (strcmp($conf['master_proto'], 'proxy_tls') == 0) { |
|
769 |
|
$context = stream_context_create(); |
|
770 |
|
// TODO: make timeout configurable |
|
771 |
|
$socket = @stream_socket_client('tls://' . $conf['master_host'] |
|
772 |
|
. ':' . $conf['master_port'], $errno, $errstr, 30, |
|
773 |
|
STREAM_CLIENT_CONNECT, $context); |
|
774 |
|
if ($socket === FALSE) { |
|
775 |
|
rg_log('Cannot connect: ' . $errstr); |
|
776 |
|
exit(1); |
|
777 |
|
} |
575 |
778 |
|
|
576 |
|
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); |
|
577 |
|
if ($socket === FALSE) { |
|
578 |
|
rg_log('Cannot create socket!'); |
|
579 |
|
exit(1); |
|
580 |
|
} |
|
|
779 |
|
$s = "GET " . $conf['maser_url'] . " HTTP/1.1\r\n" |
|
780 |
|
. "Host: " . $conf['master_host'] . ':' . $conf['master_port'] . "\r\n" |
|
781 |
|
. "Connection: keep-alive, Upgrade\r\n" |
|
782 |
|
. "Pragma: no-cache\r\n" |
|
783 |
|
. "Cache-Control: no-cache\r\n" |
|
784 |
|
. "Upgrade: websocket\r\n" |
|
785 |
|
. "\r\n"; |
|
786 |
|
$r = @fwrite($socket, $s); |
|
787 |
|
if ($r === FALSE) { |
|
788 |
|
rg_log('Cannot write HTTP request: ' . rg_php_err()); |
|
789 |
|
exit(1); |
|
790 |
|
} |
581 |
791 |
|
|
582 |
|
$r = @socket_connect($socket, $conf['master'], $conf['port']); |
|
583 |
|
if ($r === FALSE) { |
|
584 |
|
rg_log('Cannot connect to ' . $conf['master'] . '/' |
|
585 |
|
. $conf['port'] . '!'); |
|
|
792 |
|
$buf = ''; |
|
793 |
|
while (1) { |
|
794 |
|
$r = @fread($socket, 4096); |
|
795 |
|
if ($r === FALSE) { |
|
796 |
|
rg_log('Cannot read HTTP answer: ' . rg_php_err()); |
|
797 |
|
exit(1); |
|
798 |
|
} |
|
799 |
|
$buf .= $r; |
|
800 |
|
rg_log_ml('Answer: ' . $buf); |
|
801 |
|
if (strstr($buf, "\r\n\r\n") || strstr($buf, "\n\n")) |
|
802 |
|
break; |
|
803 |
|
} |
|
804 |
|
} else { |
|
805 |
|
rg_log('Invalid master protocol: ' . $conf['master_proto'] . '!'); |
|
806 |
|
sleep(60); |
586 |
807 |
exit(1); |
exit(1); |
587 |
808 |
} |
} |
588 |
809 |
rg_log('Connected.'); |
rg_log('Connected.'); |
589 |
810 |
|
|
590 |
811 |
rg_conn_new('master', $socket); |
rg_conn_new('master', $socket); |
591 |
812 |
$rg_conns['master']['exit_on_close'] = 1; |
$rg_conns['master']['exit_on_close'] = 1; |
592 |
|
$rg_conns['master']['func_cmd'] = 'xhandle'; |
|
|
813 |
|
$rg_conns['master']['func_data'] = 'xhandle'; |
593 |
814 |
|
|
594 |
815 |
// announce ourselves |
// announce ourselves |
595 |
816 |
$key = $conf['key']; unset($conf['key']); |
$key = $conf['key']; unset($conf['key']); |
596 |
817 |
$ann = $conf; |
$ann = $conf; |
|
818 |
|
$ann['op'] = 'ANN'; |
597 |
819 |
$ann['uname'] = php_uname('a'); |
$ann['uname'] = php_uname('a'); |
598 |
820 |
$ann['host'] = php_uname('n'); |
$ann['host'] = php_uname('n'); |
599 |
821 |
$ann['arch'] = php_uname('m'); |
$ann['arch'] = php_uname('m'); |
600 |
822 |
$ann['boot_time'] = time(); |
$ann['boot_time'] = time(); |
601 |
823 |
$ann['sign'] = hash_hmac('sha512', $ann['boot_time'], $key); |
$ann['sign'] = hash_hmac('sha512', $ann['boot_time'], $key); |
602 |
|
rg_conn_enq('master', 'ANN ' . rg_conn_prepare($ann) . "\n"); |
|
|
824 |
|
$j_ann = json_encode($ann); |
|
825 |
|
if ($j_ann === FALSE) { |
|
826 |
|
rg_log('Cannot encode json: ' . json_last_error_msg()); |
|
827 |
|
exit(1); |
|
828 |
|
} |
|
829 |
|
rg_conn_enq('master', $j_ann . "\n"); |
603 |
830 |
|
|
604 |
831 |
$jobs = array(); |
$jobs = array(); |
605 |
832 |
$pid_to_jid = array(); |
$pid_to_jid = array(); |
|
... |
... |
while(1) { |
633 |
860 |
break; |
break; |
634 |
861 |
|
|
635 |
862 |
$vms_loaded = TRUE; |
$vms_loaded = TRUE; |
636 |
|
rg_log_ml('vms: ' . print_r($vms, TRUE)); |
|
|
863 |
|
//rg_log_ml('vms: ' . print_r($vms, TRUE)); |
637 |
864 |
} |
} |
638 |
865 |
|
|
639 |
866 |
$name = 'rg-worker-' . $jid; |
$name = 'rg-worker-' . $jid; |
|
... |
... |
while(1) { |
643 |
870 |
// TODO: if too much time, abort (kill |
// TODO: if too much time, abort (kill |
644 |
871 |
// worker and destroy virtual machine) |
// worker and destroy virtual machine) |
645 |
872 |
//TODO: $job['error'] = 'too much time'; |
//TODO: $job['error'] = 'too much time'; |
|
873 |
|
// TODO: Signal from inside VM that we finished and extracts stats at that time |
|
874 |
|
$job['stats'] = vm_extract_info($name); |
646 |
875 |
continue; |
continue; |
647 |
876 |
} |
} |
648 |
877 |
|
|
649 |
878 |
rg_log('VM ' . $jid . ' finished'); |
rg_log('VM ' . $jid . ' finished'); |
650 |
879 |
|
|
651 |
880 |
rg_job_extract_info($job); |
rg_job_extract_info($job); |
|
881 |
|
|
652 |
882 |
if (isset($job['error'])) |
if (isset($job['error'])) |
653 |
883 |
$job['state'] = RG_JOB_ERROR; |
$job['state'] = RG_JOB_ERROR; |
654 |
884 |
else |
else |
|
... |
... |
while(1) { |
656 |
886 |
|
|
657 |
887 |
// TODO: store in fs to be able to still inform the |
// TODO: store in fs to be able to still inform the |
658 |
888 |
// master if we are crashing. |
// master if we are crashing. |
659 |
|
@file_put_contents($job['main'] . '/job.ser', serialize($job)); |
|
|
889 |
|
save_job($job); |
660 |
890 |
|
|
661 |
891 |
$xjob = $job; |
$xjob = $job; |
|
892 |
|
$xjob['op'] = 'DON'; |
662 |
893 |
unset($xjob['debug']); |
unset($xjob['debug']); |
663 |
894 |
unset($xjob['packages']); |
unset($xjob['packages']); |
664 |
895 |
unset($xjob['main']); |
unset($xjob['main']); |
665 |
|
rg_conn_enq('master', 'DON ' . rg_conn_prepare($xjob) . "\n"); |
|
666 |
|
|
|
667 |
|
// // TODO: do we clean the machine in case of crash? |
|
668 |
|
// $cmd = 'virsh undefine --nvram rg-worker-' . escapeshellarg($jid); |
|
669 |
|
// $r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
|
670 |
|
// if ($r['ok'] != 1) { |
|
671 |
|
// $job['error'] = 'Could not undefine machine: ' . $r['errmsg']; |
|
672 |
|
// rg_log('Error: ' . $job['error']); |
|
673 |
|
// //break; TODO |
|
674 |
|
// } |
|
675 |
|
|
|
676 |
|
// $cmd = 'virsh destroy rocketgit-j-' . $jid; |
|
677 |
|
// $r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
|
678 |
|
// if ($r['ok'] != 1) { |
|
679 |
|
// $job['error'] = 'Could not destroy: ' . $r['errmsg']; |
|
680 |
|
// rg_log('Error: ' . $job['error']); |
|
681 |
|
// } |
|
|
896 |
|
$j_xjob = json_encode($xjob); |
|
897 |
|
if ($j_xjob === FALSE) { |
|
898 |
|
rg_log('Cannot encode json: ' . json_last_error_msg()); |
|
899 |
|
} else { |
|
900 |
|
rg_conn_enq('master', $j_xjob . "\n"); |
|
901 |
|
} |
|
902 |
|
|
|
903 |
|
$cmd = 'virsh destroy rocketgit-j-' . $jid; |
|
904 |
|
$r = rg_exec($cmd, '', FALSE, FALSE, FALSE); |
|
905 |
|
if ($r['ok'] != 1) { |
|
906 |
|
// If error, probably the machine was not running, so, this is just a warning |
|
907 |
|
$job['error'] = 'Could not destroy: ' . $r['errmsg']; |
|
908 |
|
rg_log('Error: ' . $job['error']); |
|
909 |
|
} |
682 |
910 |
} |
} |
683 |
911 |
} |
} |
684 |
912 |
|
|
685 |
|
rg_prof_end("MAIN"); |
|
|
913 |
|
rg_prof_end('MAIN'); |
686 |
914 |
rg_prof_log(); |
rg_prof_log(); |
687 |
915 |
?> |
?> |