]> git.pld-linux.org Git - projects/pld-builder.new.git/blame - PLD_Builder/file_sender.py
Fix iterators assumptions that are no longer valid in python3
[projects/pld-builder.new.git] / PLD_Builder / file_sender.py
CommitLineData
dfff8bd5
MM
1# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
2
4dd00642
MM
3import glob
4import re
5import string
6import os
7import time
8import shutil
63212346 9import sys
a170e629 10import traceback
63319e0a 11import urllib2
4dd00642 12
4dd00642
MM
13from config import config, init_conf
14import mailer
15import path
0ea52c57 16import log
3f446d8f 17import loop
0ea52c57 18import status
3f446d8f 19import lock
4dd00642 20
38cc26f9 21retries_times = [5 * 60, 5 * 60, 10 * 60, 10 * 60, 30 * 60, 60 * 60]
4dd00642
MM
22
23def read_name_val(file):
dfff8bd5
MM
24 f = open(file)
25 r = {'_file': file[:-5], '_desc': file}
26 rx = re.compile(r"^([^:]+)\s*:(.*)$")
8b63d7eb 27 for l in f:
dfff8bd5
MM
28 if l == "END\n":
29 f.close()
30 return r
31 m = rx.search(l)
32 if m:
33 r[m.group(1)] = string.strip(m.group(2))
34 else:
35 break
36 f.close()
37 return None
4dd00642
MM
38
39def scp_file(src, target):
115a41fc 40 global problems
828e87a1 41 f = os.popen("scp -v -B %s %s 2>&1 < /dev/null" % (src, target))
1c077aad
AM
42 p = f.read()
43 ret = f.close()
44 if ret:
1d17ddb1 45 problems[src] = p
1c077aad 46 return ret
4dd00642
MM
47
48def copy_file(src, target):
dfff8bd5
MM
49 try:
50 shutil.copyfile(src, target)
51 return 0
52 except:
115a41fc 53 global problems
dfff8bd5 54 exctype, value = sys.exc_info()[:2]
87696e31 55 problems[src] = "cannot copy file: %s" % traceback.format_exception_only(exctype, value)
dfff8bd5 56 return 1
4dd00642 57
6db97676 58def rsync_file(src, target, host):
115a41fc 59 global problems
af279159 60
dfff8bd5 61 p = open(path.rsync_password_file, "r")
af279159 62 password = ""
8b63d7eb 63 for l in p:
dfff8bd5
MM
64 l = string.split(l)
65 if len(l) >= 2 and l[0] == host:
66 password = l[1]
6db97676 67 p.close()
af279159
ER
68
69 # NOTE: directing STDIN to /dev/null, does not make rsync to skip asking
70 # password, it opens /dev/tty and still asks if password is needed and
71 # missing, therefore we always set RSYNC_PASSWORD env var
72 os.environ["RSYNC_PASSWORD"] = password
63f310aa 73 rsync = "rsync --verbose --archive --timeout=360 --contimeout=360"
af279159 74 f = os.popen("%s %s %s 2>&1" % (rsync, src, target))
1c077aad 75 p = f.read()
1c077aad
AM
76 ret = f.close()
77 if ret:
78 problems[src] = p
af279159 79 del os.environ["RSYNC_PASSWORD"];
1c077aad 80 return ret
63319e0a 81
a43956d8 82def rsync_ssh_file(src, target):
115a41fc 83 global problems
2b80a862 84 rsync = "rsync --verbose --archive --timeout=360 -e ssh"
8a108792 85 f = os.popen("%s %s %s 2>&1 < /dev/null" % (rsync, src, target))
1c077aad
AM
86 p = f.read()
87 ret = f.close()
88 if ret:
89 problems[src] = p
90 return ret
8a108792 91
63319e0a 92def post_file(src, url):
115a41fc 93 global problems
63319e0a
AM
94 try:
95 f = open(src, 'r')
96 data = f.read()
97 f.close()
98 req = urllib2.Request(url, data)
4dcdc5af 99 req.add_header('X-Filename', os.path.basename(src))
63319e0a 100 f = urllib2.urlopen(req)
63319e0a
AM
101 f.close()
102 except Exception, e:
115a41fc 103 problems[src] = e
63319e0a 104 return e
264be85c 105 return 0
63319e0a 106
4dd00642 107def send_file(src, target):
115a41fc 108 global problems
be3b9c0e
AM
109 try:
110 log.notice("sending %s to %s (size %d bytes)" % (src, target, os.stat(src).st_size))
111 m = re.match('rsync://([^/]+)/.*', target)
112 if m:
860792bf 113 return not rsync_file(src, target, host = m.group(1))
be3b9c0e 114 if target != "" and target[0] == '/':
860792bf 115 return not copy_file(src, target)
be3b9c0e
AM
116 m = re.match('scp://([^@:]+@[^/:]+)(:|)(.*)', target)
117 if m:
860792bf 118 return not scp_file(src, m.group(1) + ":" + m.group(3))
be3b9c0e
AM
119 m = re.match('ssh\+rsync://([^@:]+@[^/:]+)(:|)(.*)', target)
120 if m:
860792bf 121 return not rsync_ssh_file(src, m.group(1) + ":" + m.group(3))
c87a0ffa 122 m = re.match('(http|https)://.*', target)
be3b9c0e 123 if m:
860792bf 124 return not post_file(src, target)
be3b9c0e
AM
125 log.alert("unsupported protocol: %s" % target)
126 except OSError, e:
115a41fc 127 problems[src] = e
38e23c91 128 log.error("send_file(%s, %s): %s" % (src, target, e))
be3b9c0e
AM
129 return False
130 return True
4dd00642
MM
131
132def maybe_flush_queue(dir):
dfff8bd5
MM
133 retry_delay = 0
134 try:
9be34149 135 f = open(dir + "/retry-at")
dfff8bd5
MM
136 last_retry = int(string.strip(f.readline()))
137 retry_delay = int(string.strip(f.readline()))
138 f.close()
139 if last_retry + retry_delay > time.time():
140 return
9be34149 141 os.unlink(dir + "/retry-at")
dfff8bd5
MM
142 except:
143 pass
e6376553 144
dfff8bd5 145 status.push("flushing %s" % dir)
4dd00642 146
dfff8bd5 147 if flush_queue(dir):
9be34149 148 f = open(dir + "/retry-at", "w")
dfff8bd5
MM
149 if retry_delay in retries_times:
150 idx = retries_times.index(retry_delay)
151 if idx < len(retries_times) - 1: idx += 1
152 else:
153 idx = 0
154 f.write("%d\n%d\n" % (time.time(), retries_times[idx]))
155 f.close()
4dd00642 156
dfff8bd5 157 status.pop()
0ea52c57 158
4dd00642 159def flush_queue(dir):
dfff8bd5
MM
160 q = []
161 os.chdir(dir)
162 for f in glob.glob(dir + "/*.desc"):
163 d = read_name_val(f)
164 if d != None: q.append(d)
165 def mycmp(x, y):
166 rc = cmp(x['Time'], y['Time'])
fe60a597 167 if rc == 0 and x.has_key('Type') and y.has_key('Type'):
dfff8bd5
MM
168 return cmp(x['Type'], y['Type'])
169 else:
170 return rc
171 q.sort(mycmp)
e6376553 172
dfff8bd5 173 error = None
be3b9c0e
AM
174 # copy of q
175 remaining = q[:]
dfff8bd5 176 for d in q:
be3b9c0e 177 if not send_file(d['_file'], d['Target']):
dfff8bd5 178 error = d
be3b9c0e 179 continue
dfff8bd5 180 if os.access(d['_file'] + ".info", os.F_OK):
be3b9c0e 181 if not send_file(d['_file'] + ".info", d['Target'] + ".info"):
dfff8bd5 182 error = d
be3b9c0e 183 continue
36ca4e53 184 os.unlink(d['_file'] + ".info")
dfff8bd5
MM
185 os.unlink(d['_file'])
186 os.unlink(d['_desc'])
be3b9c0e 187 remaining.remove(d)
e6376553 188
dfff8bd5
MM
189 if error != None:
190 emails = {}
191 emails[config.admin_email] = 1
115a41fc 192 pr = ""
0adcdbc2 193 for src, msg in problems.items():
45eeec56 194 pr = pr + "[src: %s]\n\n%s\n" % (src, msg)
dfff8bd5
MM
195 for d in remaining:
196 if d.has_key('Requester'):
197 emails[d['Requester']] = 1
198 e = emails.keys()
199 m = mailer.Message()
e6376553 200 m.set_headers(to = string.join(e, ", "),
d7b0d9d2 201 subject = "[%s] builder queue problem" % config.builder)
dfff8bd5 202 m.write("there were problems sending files from queue %s:\n" % dir)
115a41fc 203 m.write("problems:\n")
d9efe31a 204 m.write("%s\n" % pr)
dfff8bd5 205 m.send()
115a41fc 206 log.error("error sending files from %s:\n%s\n" % (dir, pr))
dfff8bd5 207 return 1
4dd00642 208
dfff8bd5 209 return 0
4dd00642 210
115a41fc 211problems = {}
4dd00642
MM
212
213def main():
dfff8bd5
MM
214 if lock.lock("sending-files", non_block = 1) == None:
215 return
032526d0 216 init_conf()
63319e0a 217 maybe_flush_queue(path.notify_queue_dir)
dfff8bd5
MM
218 maybe_flush_queue(path.buildlogs_queue_dir)
219 maybe_flush_queue(path.ftp_queue_dir)
4dd00642 220
e8ee9db8 221if __name__ == '__main__':
dfff8bd5 222 loop.run_loop(main)
This page took 3.49077 seconds and 4 git commands to generate.