]>
Commit | Line | Data |
---|---|---|
3ea4b156 MM |
1 | import sys |
2 | import os | |
3 | import atexit | |
4 | import time | |
deda9a51 | 5 | import string |
3ea4b156 MM |
6 | import urllib |
7 | ||
8 | from config import config, init_conf | |
9 | from bqueue import B_Queue | |
3ea4b156 MM |
10 | import lock |
11 | import util | |
3f446d8f | 12 | import loop |
3ea4b156 MM |
13 | import path |
14 | import status | |
15 | import log | |
16 | import chroot | |
17 | import ftp | |
e2cad913 | 18 | import buildlogs |
59ce7cd6 | 19 | import notify |
17f23d66 MM |
20 | import build |
21 | import report | |
deda9a51 MM |
22 | import upgrade |
23 | import install_br | |
3ea4b156 | 24 | |
53989cf3 MM |
25 | # *HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK* |
26 | import socket | |
27 | ||
28 | socket.myorigsocket=socket.socket | |
29 | ||
30 | def mysocket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): | |
31 | s=socket.myorigsocket(family, type, proto) | |
32 | s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) | |
33 | return s | |
34 | ||
35 | socket.socket=mysocket | |
36 | # *HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK*HACK* | |
37 | ||
3ea4b156 MM |
38 | # this code is duplicated in srpm_builder, but we |
39 | # might want to handle some cases differently here | |
40 | def pick_request(q): | |
41 | def mycmp(r1, r2): | |
42 | if r1.kind != 'group' or r2.kind != 'group': | |
43 | raise "non-group requests" | |
44 | pri_diff = cmp(r1.priority, r2.priority) | |
45 | if pri_diff == 0: | |
46 | return cmp(r1.time, r2.time) | |
47 | else: | |
48 | return pri_diff | |
49 | q.requests.sort(mycmp) | |
50 | ret = q.requests[0] | |
51 | q.requests = q.requests[1:] | |
52 | return ret | |
53 | ||
17f23d66 MM |
54 | def fetch_src(r, b): |
55 | src_url = config.control_url + "/srpms/" + r.id + "/" + b.src_rpm | |
56 | b.log_line("fetching %s" % src_url) | |
57 | start = time.time() | |
f69c13dc MM |
58 | good=False |
59 | while not good: | |
60 | try: | |
61 | good=True | |
62 | f = urllib.urlopen(src_url) | |
63 | except IOError, error: | |
e581d526 | 64 | if error[1][0] == 60 or error[1][0] == 110 or error[1][0] == -3 or error[1][0] == 111 or error[1][0] == 61: |
f69c13dc | 65 | good=False |
e581d526 | 66 | b.log_line("unable to connect... trying again") |
f69c13dc MM |
67 | else: |
68 | f = urllib.urlopen(src_url) # So we get the exception logged :) | |
69 | ||
17f23d66 MM |
70 | o = chroot.popen("cat > %s" % b.src_rpm, mode = "w") |
71 | bytes = util.sendfile(f, o) | |
72 | f.close() | |
73 | o.close() | |
74 | t = time.time() - start | |
75 | if t == 0: | |
76 | b.log_line("fetched %d bytes" % bytes) | |
77 | else: | |
78 | b.log_line("fetched %d bytes, %.1f K/s" % (bytes, bytes / 1024.0 / t)) | |
3ea4b156 | 79 | |
17f23d66 MM |
80 | def build_rpm(r, b): |
81 | status.push("building %s" % b.spec) | |
82 | b.log_line("request from: %s" % r.requester) | |
83 | b.log_line("started at: %s" % time.asctime()) | |
84 | fetch_src(r, b) | |
85 | b.log_line("installing srpm: %s" % b.src_rpm) | |
86 | res = chroot.run("rpm -U %s" % b.src_rpm, logfile = b.logfile) | |
87 | chroot.run("rm -f %s" % b.src_rpm, logfile = b.logfile) | |
deda9a51 | 88 | b.files = [] |
16fd9901 | 89 | tmpdir = "/tmp/B." + b.b_id[0:6] |
17f23d66 MM |
90 | if res: |
91 | b.log_line("error: installing src rpm failed") | |
92 | res = 1 | |
93 | else: | |
cbe03402 | 94 | chroot.run("install -m 700 -d %s" % tmpdir) |
15cba670 | 95 | rpmbuild_opt = "%s --target %s-pld-linux" % (b.bconds_string(), config.arch) |
5d307ff8 | 96 | cmd = "cd rpm/SPECS; TMPDIR=%s nice -n %s rpmbuild -bb %s %s" % \ |
97 | (tmpdir, config.nice, rpmbuild_opt, b.spec) | |
a7d6f499 | 98 | if ("no-install-br" not in r.flags) and install_br.install_br(r, b): |
17f23d66 | 99 | res = 1 |
deda9a51 MM |
100 | else: |
101 | b.log_line("building RPM using: %s" % cmd) | |
102 | res = chroot.run(cmd, logfile = b.logfile) | |
103 | files = util.collect_files(b.logfile) | |
104 | if len(files) > 0: | |
105 | r.chroot_files.extend(files) | |
106 | else: | |
107 | b.log_line("error: No files produced.") | |
108 | res = 1 # FIXME: is it error? | |
109 | b.files = files | |
cbe03402 | 110 | chroot.run("rm -rf %s; cd rpm/SPECS; rpmbuild --nodeps --nobuild " \ |
17f23d66 | 111 | "--clean --rmspec --rmsource %s" % \ |
af98c142 | 112 | (tmpdir, b.spec), logfile = b.logfile) |
304753f5 | 113 | chroot.run("rm -rf $HOME/rpm/BUILD/*") |
deda9a51 MM |
114 | |
115 | def ll(l): | |
116 | util.append_to(b.logfile, l) | |
117 | ||
118 | if b.files != []: | |
10cdcdf2 | 119 | chroot.run("cp -f %s /spools/ready/; poldek --nodiff --mkidxz -s /spools/ready/" % \ |
181b50a5 | 120 | string.join(b.files), logfile = b.logfile, user = "root") |
deda9a51 MM |
121 | ll("Begin-PLD-Builder-Info") |
122 | if "upgrade" in r.flags: | |
123 | upgrade.upgrade_from_batch(r, b) | |
124 | else: | |
125 | ll("not upgrading") | |
126 | ll("End-PLD-Builder-Info") | |
127 | ||
17f23d66 MM |
128 | for f in b.files: |
129 | local = r.tmp_dir + os.path.basename(f) | |
130 | chroot.run("cat %s; rm -f %s" % (f, f), logfile = local) | |
131 | ftp.add(local) | |
1051562e MM |
132 | |
133 | def uploadinfo(b): | |
5c8a95e5 | 134 | c="file:SRPMS:%s\n" % b.src_rpm |
1051562e | 135 | for f in b.files: |
5c8a95e5 | 136 | c=c + "file:ARCH:%s\n" % os.path.basename(f) |
1051562e MM |
137 | c=c + "END\n" |
138 | return c | |
139 | ||
4bc2d67e MM |
140 | if b.files != []: |
141 | fname = r.tmp_dir + b.src_rpm + ".uploadinfo" | |
142 | f = open(fname, "w") | |
143 | f.write(uploadinfo(b)) | |
144 | f.close() | |
145 | ftp.add(fname, "uploadinfo") | |
1051562e | 146 | |
17f23d66 | 147 | status.pop() |
3ea4b156 | 148 | |
17f23d66 | 149 | return res |
3ea4b156 | 150 | |
17f23d66 | 151 | def handle_request(r): |
0638381b | 152 | ftp.init(r) |
e2cad913 | 153 | buildlogs.init(r) |
17f23d66 | 154 | build.build_all(r, build_rpm) |
f6009d01 | 155 | report.send_report(r, is_src = False) |
3ea4b156 | 156 | ftp.flush() |
59ce7cd6 | 157 | notify.send() |
3ea4b156 MM |
158 | |
159 | def check_load(): | |
3f446d8f | 160 | do_exit = 0 |
3ea4b156 MM |
161 | try: |
162 | f = open("/proc/loadavg") | |
163 | if float(string.split(f.readline())[2]) > config.max_load: | |
3f446d8f | 164 | do_exit = 1 |
3ea4b156 MM |
165 | except: |
166 | pass | |
3f446d8f MM |
167 | if do_exit: |
168 | sys.exit(0) | |
3ea4b156 | 169 | |
e8ee9db8 MM |
170 | def main_for(builder): |
171 | init_conf(builder) | |
3ea4b156 MM |
172 | # allow only one build in given builder at once |
173 | if not lock.lock("building-rpm-for-%s" % config.builder, non_block = 1): | |
174 | return | |
175 | # don't kill server | |
176 | check_load() | |
177 | # not more then job_slots builds at once | |
178 | locked = 0 | |
179 | for slot in range(config.job_slots): | |
180 | if lock.lock("building-rpm-slot-%d" % slot, non_block = 1): | |
181 | locked = 1 | |
182 | break | |
183 | if not locked: | |
184 | return | |
185 | ||
186 | status.push("picking request for %s" % config.builder) | |
187 | q = B_Queue(path.queue_file + "-" + config.builder) | |
188 | q.lock(0) | |
189 | q.read() | |
190 | if q.requests == []: | |
191 | return | |
192 | r = pick_request(q) | |
193 | q.write() | |
194 | q.unlock() | |
195 | status.pop() | |
196 | ||
197 | # record fact that we got lock for this builder, load balancer | |
198 | # will use it for fair-queuing | |
199 | l = lock.lock("got-lock") | |
200 | f = open(path.got_lock_file, "a") | |
201 | f.write(config.builder + "\n") | |
202 | f.close() | |
203 | l.close() | |
204 | ||
205 | msg = "handling request %s (%d) for %s from %s" \ | |
206 | % (r.id, r.no, config.builder, r.requester) | |
207 | log.notice(msg) | |
208 | status.push(msg) | |
209 | handle_request(r) | |
210 | status.pop() | |
211 | ||
e8ee9db8 MM |
212 | def main(): |
213 | if len(sys.argv) < 2: | |
214 | raise "fatal: need to have builder name as first arg" | |
215 | return main_for(sys.argv[1]) | |
216 | ||
217 | if __name__ == '__main__': | |
3f446d8f | 218 | loop.run_loop(main) |