use standards-compliant tags php
[mdv_bs_web.git] / package.inc.php
blob8cfcbe8557136cb97749c1a27f71e99b6168e47a
1 <?php
2 require_once "common.inc.php";
3 require_once "ssh.inc.php";
5 class Package {
6 public $pkgname;
7 public $version;
8 public $commit;
9 public $distro;
10 public $repository;
11 public $submitter;
12 public $id;
13 public $submithost;
14 public $submitpid;
15 public $summary;
16 public $infofile;
18 // Status
19 public $builds;
20 public $done;
21 public $failed;
22 public $excluded;
24 private $brief;
25 private $repos_dir;
26 public $base;
27 public $srpm;
28 private $ls_donedir;
30 function __construct ($id, $brief=True, $infofile=Null) {
31 $this->id = $id;
32 $this->brief = $brief;
33 $this->infofile = $infofile;
34 $this->parse_info();
35 $this->init_fs_caches();
36 $this->buildtime = 0;
37 $this->probe_build();
38 $this->probe_done();
39 $this->probe_failed();
40 $this->probe_excluded();
41 $this->sync_archs();
45 * parse_info()
46 * Parses .src.rpm information
48 function parse_info()
50 global $queuedir;
51 // /home/mandrake/uploads/todo/*/*/*/20061031181650.user.host.pid_*.src.rpm.info
52 if (!$this->infofile) {
53 @exec("find -L $queuedir -mindepth 4 -maxdepth 4 -type f -name '".
54 $this->id."_*.src.rpm.info'",
55 $info_list);
57 if (!count($info_list)) {
58 // Not found
59 return;
62 $this->infofile = str_replace ("$queuedir", "", $info_list[0]);
63 $this->infofile = ltrim ($this->infofile, "/");
66 $infos = parse_info($this->infofile);
67 list ($this->pkgname,
68 $this->version,
69 $this->commit,
70 $this->distro,
71 $this->repository,
72 $this->submitter,
73 , // job id
74 $this->submitpid,
75 $this->submithost,
76 $this->summary
77 ) = $infos;
79 // Repos dir
80 $this->repos_dir = $this->distro."/".$this->repository;
82 // Base string
83 $this->base = $this->repos_dir."/".$this->id;
85 // src.rpm
86 $this->srpm = substr ($this->infofile, 0, -5);
90 * init_fs_caches()
91 * Do some caching, avoiding too many exec calls
93 function init_fs_caches()
95 global $donedir;
96 // Cache ls donedir
97 $path = "$donedir/".$this->base."_";
98 $path_len = strlen ($path);
99 $ls_donedir = glob ("$path*", GLOB_NOSORT);
101 $this->ls_donedir = array();
102 foreach ($ls_donedir as $item) {
103 $item = trim ($item);
104 $this->ls_donedir[] = substr ($item, $path_len);
109 * probe_build()
110 * Checks if our id (timestamp) is building and properly sets:
111 * $this->chroot
113 function probe_build()
115 global $queuedir;
116 $this->builds = array();
117 // $queuedir/cooker/main/release/20061101142126.claudio.monstro.26213_i586.iurt.frohike.20061101163646.4273.lock
118 $locklist = glob ("$queuedir/".$this->base."_*.lock", GLOB_NOSORT);
119 $path_len = strlen ($queuedir);
121 foreach ($locklist as $lockinfo) {
122 $lockinfo = substr ($lockinfo, $path_len);
123 $nodeinfo = $this->parse_lock($lockinfo);
124 $arch = array_shift ($nodeinfo);
125 $this->builds[$arch] = $nodeinfo;
130 * parse_lock($lockfile)
131 * Parses a given lock file: grab the arch locked and build status if
132 * wanted.
134 function parse_lock($lockfile) {
135 $lockinfo = parse_lock_item ($lockfile);
136 list ($arch,
137 $buildnode,
138 $buildstart,
139 $pid_builder) = $lockinfo;
141 if (!$this->brief) {
142 $buildnodeinfo = $this->parse_buildnode($buildnode);
144 else {
145 $buildnodeinfo = Null;
147 $myinfo = array (
148 $arch,
149 $buildnode,
150 $buildstart,
151 $pid_builder,
152 $buildnodeinfo
154 return $myinfo;
158 * parse_buildnode
159 * Grabs compilation status given a buildnode.
161 function parse_buildnode($buildnode)
163 $ssh = new SSH($buildnode);
164 $ret = $ssh->connect();
165 if ($ret) {
166 echo "Failed to contact buildnode: code $ret.";
167 return;
170 $build_list = $ssh->exec("find -L /export/home/mandrake/iurt/".$this->repos_dir." -type f -name '*.src.rpm' | fgrep '/".$this->id."/' | sed 's@/export/home/mandrake/iurt/*@@'");
172 // /home/mandrake/iurt/*/*/*/20061031181650*/*.src.rpm
173 if (!$build_list) {
174 // Locked, but not building.
175 echo "Locked, but not building.";
176 return;
179 $uploaded = True;
181 // Check building stage
182 $logdir = '/export/home/mandrake/iurt' . "/" . dirname ($build_list[0]) . "/log";
184 // Check for buildrequires stage
185 // ./log/@73471:perl-POE-0.3601-2mdv2007.1.src.rpm/install_deps_@73471:perl-POE-0.3601-2mdv2007.1.src.rpm-1.0.20061106203005.log
186 $buildreqfile = $logdir . "/*/install_deps*.log";
187 $buildrequires = $ssh->exec("/bin/ls -sl $buildreqfile 2> /dev/null | wc -l");
188 $buildrequires = (bool)$buildrequires[0];
190 // real build stage
191 $buildfile = $logdir . "/*/build.*.log";
192 $building = $ssh->exec("/bin/ls -sl $buildfile 2> /dev/null | wc -l");
193 $building = (bool)$building[0];
195 // package built
196 $statuslog = $logdir . "/status.log";
197 $built = $ssh->exec("cut -d ' ' -f 2 $statuslog 2> /dev/null");
198 $built = $built[0];
199 if (count ($built) and $built != "ok") {
200 if ($building) {
201 $building = 2;
202 $built = 0;
204 elseif ($buildrequires) {
205 $buildrequires = 2;
206 $built = 0;
208 elseif ($uploaded) {
209 $uploaded = 2;
210 $built = 0;
213 if ($built) {
214 $built = count($built);
217 return array (
218 $uploaded,
219 $buildrequires,
220 $building,
221 $built,
222 $ssh,
227 * tail_buildlog(lines=15)
228 * Tails the last lines from build.log:
229 * $this->chroot
231 function tail_buildlog($arch, $nlines=15)
233 $ssh = $this->builds[$arch][3][4];
234 $buildlogfile = '/export/home/mandrake/iurt/'.$this->base.
235 "/log/".$this->pkgname."*/build.*.log";
236 $section = $ssh->exec("sed -n 's/^Executing(\\(.*\\)).*/\\1/p' $buildlogfile 2> /dev/null | tail -n 1");
237 array_map("trim", $section);
238 $section = $section[0];
239 $lines = $ssh->exec("tail -n 15 $buildlogfile 2>&1");
240 return "Section <b>$section</b>:\n".join ("\n", $lines);
244 * probe_done
245 * Search archs already done.
247 function probe_done()
249 global $donedir;
250 $this->done = array();
251 foreach ($this->ls_donedir as $item) {
252 if (!strstr ($item, ".done")) {
253 continue;
256 $arch = str_replace (".done", "", $item);
257 $filename = "$donedir/".$this->base."_$item";
258 $fp = fopen ($filename, "r");
259 if (!$fp) {
260 echo "Failed to open .done file ($filename).";
261 return;
263 $buildnode = fgets ($fp);
264 $buildnode = substr ($buildnode, 5);
265 fclose($fp);
267 $this->done[$arch] = $buildnode;
268 $ctime = filectime ($filename);
269 if ($ctime > $this->buildtime) {
270 $this->buildtime = $ctime;
276 * probe_failed
277 * Search archs that failed.
279 function probe_failed()
281 global $donedir;
282 $this->failed = array();
283 foreach ($this->ls_donedir as $item) {
284 if (!strstr ($item, ".fail")) {
285 continue;
287 $arch = str_replace (".fail", "", $item);
289 $filename = "$donedir/".$this->base."_$item";
290 $fp = fopen ($filename, "r");
291 if (!$fp) {
292 echo "Failed to open .fail file ($filename).";
293 return;
295 $buildnode = fgets ($fp);
296 fclose($fp);
297 $buildnode = substr ($buildnode, 5);
299 $this->failed[$arch] = $buildnode;
301 $ctime = filectime ($filename);
302 if ($ctime > $this->buildtime) {
303 $this->buildtime = $ctime;
306 $buildstart = "";
307 $pid_builder = "";
309 $buildnodeinfo = Null;
310 if (!$this->brief) {
311 $buildnodeinfo = $this->parse_failed_build_info();
313 $myinfo = array (
314 $buildnode,
315 $buildstart,
316 $pid_builder,
317 $buildnodeinfo
319 $this->builds[$arch] = $myinfo;
323 function parse_failed_build_info()
325 global $faileddir;
327 $uploaded = True;
329 // Check building stage
330 $logdir = "$faileddir/" . $this->base . "/log";
332 // Check for buildrequires stage
333 // ./log/@73471:perl-POE-0.3601-2mdv2007.1.src.rpm/install_deps_@73471:perl-POE-0.3601-2mdv2007.1.src.rpm-1.0.20061106203005.log
334 $buildreqfile = $logdir . "/*/install_deps*.log";
335 @exec("/bin/ls -sl $buildreqfile 2> /dev/null", $buildrequires);
336 $buildrequires = (bool)count($buildrequires);
338 // real build stage
339 $buildfile = $logdir . "/*/build.*.log";
340 @exec("/bin/ls -sl $buildfile 2> /dev/null", $building);
341 $building = (bool)count($building);
343 // package built
344 $statuslog = $logdir . "/status.log";
345 @exec("cut -d \\ -f 2 $statuslog 2> /dev/null", $built);
346 $built = $built[0];
347 if (count ($built) and $built != "ok") {
348 if ($building) {
349 $building = 2;
350 $built = 0;
352 elseif ($buildrequires) {
353 $buildrequires = 2;
354 $built = 0;
356 elseif ($uploaded) {
357 $uploaded = 2;
358 $built = 0;
361 if ($built) {
362 $built = count($built);
365 return array (
366 $uploaded,
367 $buildrequires,
368 $building,
369 $built,
370 Null // ssh
375 * probe_excluded()
376 * Search excluded archs
378 function probe_excluded()
380 $this->excluded = array();
381 foreach ($this->ls_donedir as $item) {
382 if (!strstr ($item, ".excluded")) {
383 continue;
385 $this->excluded[] = str_replace (".excluded", "", $item);
390 * sync_archs()
391 * Merge all known archs into a single list
393 function sync_archs()
395 global $sufficientarchs, $requiredarchs;
397 $this->archs = array_merge(array_keys($this->builds),
398 array_keys ($this->done),
399 array_keys ($this->failed),
400 $this->excluded);
402 foreach ($sufficientarchs as $arch) {
403 if (in_array ($arch, $this->archs)) {
404 $this->excluded = array_unique (array_merge ($this->excluded, $requiredarchs));
405 break;
408 $this->archs = array_merge(array_keys($this->builds),
409 array_keys ($this->done),
410 array_keys ($this->failed),
411 $this->excluded);
413 $this->archs = array_unique($this->archs);