]> TLD Linux GIT Repositories - tld-ftp-admin.git/blob - bin/pfa-from-incoming
- non-integer releases are ok in TLD
[tld-ftp-admin.git] / bin / pfa-from-incoming
1 #!/usr/bin/env python3
2 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
3
4 from __future__ import print_function
5
6 import sys, os, stat, time, re
7 sys.path.insert(0, os.environ['HOME']+'/tld-ftp-admin/modules')
8 from config import incoming_dir, default_to, ftp_archs
9 from config import value as cval
10 import config
11 from common import noarchcachedir, tmpdir, fileexists
12 from baseftptree import BaseFtpTree, BasePkg
13 from ftptree import FtpTree, Pkg
14 import ftpio
15
16 os.umask(0o022)
17
18 def rm(file):
19     os.remove(file)
20
21 def mv(src, dst):
22     os.rename(src, dst + '/' + src.split('/')[-1])
23
24 # duplicate code in ftptree.py
25 def is_debuginfo(nvr):
26     """
27     returns true if NVR is debuginfo package and separate debuginfo is enabled
28     """
29     if not config.separate_debuginfo:
30         return False
31     pkg = nvr.split('-')[:-2]
32     return pkg[-1] == 'debuginfo' or pkg[-1] == 'debugsource'
33
34 def findfiles(dir):
35     def filterinfos(x):
36         if x[-11:] == '.uploadinfo':
37             return True
38         else:
39             return False
40     return filter(filterinfos, os.listdir(dir))
41
42 def getcontent(file):
43     f = open(file, 'r')
44     content = f.read()
45     f.close()
46     if not content[-5:] == '\nEND\n':
47         return None
48     else:
49         return content[:-4]
50
51 def send_noarch_msg(files_differ, reqs_differ, pkg, rpmfile, arch):
52     req_email=pkg.build[pkg.lastbid].requester_email
53     req_bid=pkg.lastbid
54     cc_list=[]
55     if 'logs_list' in cval:
56         cc_list.append(cval['logs_list'])
57     m_subject="Noarch error: %s files differ among builders" % rpmfile
58     bids=pkg.build.keys()
59     if len(bids)>1:
60         for bid in bids:
61             newcc=pkg.build[bid].requester_email
62             if req_email!=newcc and newcc not in cc_list:
63                 cc_list.append(newcc)
64
65     msg="From: %s\nTo: %s\n" % (cval['from_field'], req_email)
66     if cc_list:
67         msg=msg+"Cc: %s\n" % ", ".join(cc_list)
68     msg=msg+"""X-PLD-Builder: %s
69 References: <%s@pld.src.builder>
70 In-Reply-To: <%s@pld.src.builder>
71 Subject: %s
72
73 """ % (cval['xpldbuilder'], req_bid, req_bid, m_subject)
74
75     sm = os.popen("/usr/sbin/sendmail -t", "w")
76
77     sm.write(msg)
78
79     if files_differ:
80         f=open("%s/files.diff" % tmpdir, 'r')
81         sm.write("Difference between %s (currently in %s) and %s FILES\n" %
82               (pkg.noarch_arch[rpmfile], repr(ftptree), arch)),
83         for line in f.readlines()[2:]:
84             sm.write(line)
85         f.close()
86
87     sm.write('\n')
88
89     if reqs_differ:
90         f=open("%s/reqs.diff" % tmpdir, 'r')
91         sm.write("Difference between %s (currently in %s) and %s REQS\n" %
92               (pkg.noarch_arch[rpmfile], repr(ftptree), arch)),
93         for line in f.readlines()[2:]:
94             sm.write(line)
95         f.close()
96
97     sm.close()
98
99 def move_noarch(f, arch, rpmfile, dstpkg):
100     if rpmfile in dstpkg.noarch_arch:
101         os.system("LC_ALL=C rpm -qlp %s | LC_ALL=C sort > %s/files.new" %
102                   (incoming_dir + arch + '/' + rpmfile, tmpdir))
103         os.system("rpm -qRp %s | LC_ALL=C sort | LC_ALL=C uniq > %s/reqs.new" %
104                   (incoming_dir + arch + '/' + rpmfile, tmpdir))
105
106         files_differ = False
107         reqs_differ = False
108
109         if os.system("diff -u %s/%s.filelist %s/files.new > %s/files.diff" %
110                      (noarchcachedir, rpmfile, tmpdir, tmpdir)):
111             files_differ = True
112         if os.system("diff -u %s/%s.reqlist %s/reqs.new > %s/reqs.diff" %
113                      (noarchcachedir, rpmfile, tmpdir, tmpdir)):
114             reqs_differ = True
115
116         if files_differ or reqs_differ:
117             send_noarch_msg(files_differ, reqs_differ, dstpkg, rpmfile, arch)
118
119         rm(incoming_dir + arch + '/' + rpmfile)
120     else:
121         os.system("LC_ALL=C rpm -qlp %s | LC_ALL=C sort > %s/%s.filelist" %
122                   (incoming_dir + arch + '/' + rpmfile, noarchcachedir, rpmfile))
123         os.system("rpm -qRp %s | LC_ALL=C sort | LC_ALL=C uniq > %s/%s.reqlist" %
124                   (incoming_dir + arch + '/' + rpmfile, noarchcachedir, rpmfile))
125         if arch not in dstpkg.files:
126             f.write("file:noarch:%s\ninfo:noarch_arch:%s:%s\n" % (rpmfile, rpmfile, arch))
127         mv(incoming_dir + arch + '/' + rpmfile, default_to + 'noarch/RPMS')
128
129 def send_vr_msg(snvr, anvr, pkg, arch):
130     req_email=pkg.build[pkg.lastbid].requester_email
131     req_bid=pkg.lastbid
132     cc_list=[]
133     if 'logs_list' in cval:
134         cc_list.append(cval['logs_list'])
135     m_subject="NVR error: %s version or relese differ among subpackages" % snvr[0]
136     bids=pkg.build.keys()
137     if len(bids)>1:
138         for bid in bids:
139             newcc=pkg.build[bid].requester_email
140             if req_email!=newcc and newcc not in cc_list:
141                 cc_list.append(newcc)
142
143     msg="From: %s\nTo: %s\n" % (cval['from_field'], req_email)
144     if cc_list:
145         msg=msg+"Cc: %s\n" % ", ".join(cc_list)
146     msg=msg+"""X-PLD-Builder: %s
147 References: <%s@pld.src.builder>
148 In-Reply-To: <%s@pld.src.builder>
149 Subject: %s
150
151 """ % (cval['xpldbuilder'], req_bid, req_bid, m_subject)
152
153     sm = os.popen("/usr/sbin/sendmail -t", "w")
154
155     sm.write(msg)
156
157     sm.write("Difference between %s SRPM (currently in %s) and %s RPM NVR:\n\n" %
158           (snvr[0], repr(ftptree), arch)),
159     sm.write("Expected (%s):\nV: %s\nR: %s\n\n" % snvr)
160     sm.write("RPM:\nN: %s\nV: %s\nR: %s\n" % anvr)
161     sm.write('\n')
162
163     sm.close()
164
165 # main()
166 try:
167     ftpio.connect('from-incoming-pid-%s' % os.getpid())
168 except:
169     print("Can't get ftpiod connection")
170     sys.exit(1)
171
172 ftptree = BaseFtpTree(cval['default_to'])
173
174 if not ftpio.lock(cval['default_to']):
175     print("Can't get lock: %s" % cval['default_to'])
176     sys.exit(1)
177
178 moved_anything = False
179
180 for uploadinfo in findfiles(incoming_dir + 'SRPMS'):
181     content = getcontent(incoming_dir + 'SRPMS/' + uploadinfo)
182     if not content:
183         continue # Uploading not finished
184
185     pkg = BasePkg(uploadinfo[:-19], content = content)
186     srpm = pkg.files['SRPMS'][0]
187
188     if not os.path.exists(incoming_dir + 'SRPMS/' + srpm):
189         ftpio.log("%s file missing; skipping move until next round" % (srpm))
190         continue
191
192     if ftptree.has_key(repr(pkg)):
193         ftpio.log("%s already present in %s; removing older files" % (srpm, ftptree))
194         rm(default_to + 'SRPMS/RPMS/' + srpm)
195         f = open(default_to + 'SRPMS/.metadata/' + srpm+'.info', 'a')
196         bid = list(pkg.build.keys())[0]
197         build = pkg.build[bid]
198         f.write("info:build:%s:requester:%s\ninfo:build:%s:requester_email:%s\n"
199                  % (bid, build.requester, bid, build.requester_email))
200         f.close()
201     else:
202         f = open(default_to + 'SRPMS/.metadata/' + srpm + '.info', 'w')
203         f.write(content)
204         f.close()
205
206     mv(incoming_dir + 'SRPMS/' + srpm, default_to + 'SRPMS/RPMS')
207     rm(incoming_dir + 'SRPMS/' + uploadinfo)
208
209 for arch in ftp_archs:
210     for uploadinfo in findfiles(incoming_dir + arch):
211         content = getcontent(incoming_dir + arch + '/' + uploadinfo)
212         if not content:
213             ftpio.log("%s not finished uploading" % uploadinfo)
214             continue # Uploading not finished
215
216         srcpkg = BasePkg(uploadinfo[:-19], content = content)
217         srpm = srcpkg.files['SRPMS'][0]
218
219         if not ftptree.has_key(repr(srcpkg)):
220             continue # We require the src.rpm to be present
221
222         renvr = re.compile(r'(.*)-(.*)-(.*)\.[^.]*\.rpm')
223         srcnvr = renvr.match(srpm).groups()
224
225         rpmfile_missing = [f for f in srcpkg.files['ARCH'] if not os.path.exists(incoming_dir + arch + '/'+f)]
226         if len(rpmfile_missing):
227             for filem in rpmfile_missing:
228                 ftpio.log("%s file missing; skipping move until next round" % (filem))
229             continue
230
231         dstpkg = BasePkg(repr(srcpkg), ftptree)
232
233         if arch in dstpkg.files:
234             ftpio.log("files from %s for arch %s already present in %s; removing older files" % (repr(srcpkg), arch, ftptree))
235             for rpmfile in dstpkg.files[arch]:
236                 if is_debuginfo(rpmfile):
237                     dstfile = default_to + arch + '/debuginfo'
238                 else:
239                     dstfile = default_to + arch + '/RPMS'
240                 try:
241                     rm(dstfile + '/' + rpmfile)
242                 except OSError as e:
243                     l = "Removing %s problem: %s" % (dstfile + '/' + rpmfile, e)
244                     ftpio.log(l)
245                     print(l)
246
247         f = open(default_to + 'SRPMS/.metadata/' + srpm + '.info', 'a')
248         for rpmfile in srcpkg.files['ARCH']:
249             moved_anything = True
250
251 # Too much noise, too little use
252 #            archnvr = renvr.match(rpmfile).groups()
253 #            if srcnvr[1] != archnvr[1] or srcnvr[2] != archnvr[2]:
254 #                send_vr_msg(srcnvr, archnvr, dstpkg, arch)
255
256             if rpmfile[-11:] == '.noarch.rpm' and config.separate_noarch:
257                 move_noarch(f, arch, rpmfile, dstpkg)
258             else:
259                 if arch not in dstpkg.files:
260                     f.write("file:%s:%s\n" % (arch, rpmfile))
261                 srcfile = incoming_dir + arch + '/' + rpmfile
262
263                 if is_debuginfo(rpmfile):
264                     dstfile = default_to + arch + '/debuginfo'
265                 else:
266                     dstfile = default_to + arch + '/RPMS'
267
268                 try:
269                     mv(srcfile, dstfile)
270                 except OSError as e:
271                     l = "Moving %s to %s problem: %s" % (srcfile, dstfile, e)
272                     ftpio.log(l)
273                     print(l)
274         f.close()
275
276         rm(incoming_dir + arch + '/' + uploadinfo)
277
278 ftpio.unlock(cval['default_to'])
279
280 if moved_anything:
281     os.system("%s/tld-ftp-admin/bin/pfa-genindex --quiet test > /dev/null" % (os.getenv("HOME")))