1 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
3 import os, config, string, urllib, re, rpm
4 from common import fileexists, noarchcachedir
5 from baseftptree import BasePkg, BaseFtpTree
13 print "%d error(s) encountered... aborting" % errnum
32 os.rename(src, dst+'/'+src.split('/')[-1])
33 #print "mv: %s %s" % (src, dst+'/'+src.split('/')[-1])
36 def __init__(self, nvr, tree):
37 BasePkg.__init__(self, nvr, tree)
38 self.name=string.join(nvr.split('-')[:-2], '-')
39 self.version=nvr.split('-')[-2]
40 self.release=nvr.split('-')[-1]
41 self.marked4removal=False
42 self.marked4moving=False
46 def __cmp__(self, pkg):
47 if self.name > pkg.name:
49 elif self.name < pkg.name:
52 return rpm.labelCompare(('0', self.version, self.release),
53 ('0', pkg.version, pkg.release))
55 def mark4moving(self):
56 if not self.marked4moving:
57 self.tree.marked4moving.append(self)
58 self.marked4moving=True
60 def mark4removal(self):
61 if not self.marked4removal:
62 self.tree.marked4removal.append(self)
63 self.marked4removal=True
66 self.errors.append(msg)
68 perror('%s %s' % (self.nvr, msg))
70 def warning(self, msg):
71 self.warnings.append(msg)
73 pwarning('%s %s' % (self.nvr, msg))
75 def load(self, content=None):
76 BasePkg.load(self, content)
77 if self.info.has_key('move'):
81 f=open(self.tree.basedir+'/SRPMS/.metadata/'+self.nvr+'.src.rpm.info', 'w')
82 for bid in self.build.keys():
83 f.write("info:build:%s:requester:%s\ninfo:build:%s:requester_email:%s\n" % (bid, self.build[bid].requester, bid, self.build[bid].requester_email))
84 for key in self.info.keys():
85 f.write("info:%s:%s\n" % (key, string.join(self.info[key], ':')))
86 for arch in self.files.keys():
87 for rpm in self.files[arch]:
88 f.write("file:%s:%s\n" % (arch, rpm))
91 for arch in self.files.keys():
92 for rpm in self.files[arch]:
93 rm(self.tree.basedir+'/'+arch+'/RPMS/'+rpm)
95 if fileexists(noarchcachedir+rpm+'.filelist'):
96 rm(noarchcachedir+rpm+'.filelist')
97 if fileexists(noarchcachedir+rpm+'.reqlist'):
98 rm(noarchcachedir+rpm+'.reqlist')
99 rm(self.tree.basedir+'/SRPMS/.metadata/'+self.nvr+'.src.rpm.info')
101 def move(self, dsttree):
102 if dsttree.has_key(self.nvr):
104 for arch in self.files.keys():
105 if arch in dsttree[self.nvr].files.keys():
106 pinfo("Arch %s for %s is already present in dest tree; removing from srctree" % (arch, self.nvr))
107 for rpm in self.files[arch]:
108 rm(self.tree.basedir+'/'+arch+'/RPMS/'+rpm)
111 dsttree[self.nvr].files[arch]=self.files[arch]
112 for rpm in self.files[arch]:
113 mv(self.tree.basedir+'/'+arch+'/RPMS/'+rpm, dsttree.basedir+'/'+arch+'/RPMS/')
115 for bid in self.build.keys():
116 dsttree[self.nvr].build[bid]=self.build[bid]
117 dsttree[self.nvr].writeinfo()
118 rm(self.tree.basedir+'/SRPMS/.metadata/'+self.nvr+'.src.rpm.info')
120 for arch in self.files.keys():
121 for rpm in self.files[arch]:
122 mv(self.tree.basedir+'/'+arch+'/RPMS/'+rpm, dsttree.basedir+'/'+arch+'/RPMS/')
123 mv(self.tree.basedir+'/SRPMS/.metadata/'+self.nvr+'.src.rpm.info', dsttree.basedir+'/SRPMS/.metadata/')
126 class FtpTree(BaseFtpTree):
127 def __init__(self, tree, loadall=False):
128 BaseFtpTree.__init__(self, tree)
130 self.marked4removal=[]
131 self.marked4moving=[]
133 self.__loadpkgnames()
135 for pkgname in self.pkgnames:
136 self.loadedpkgs[pkgname]=Pkg(pkgname, self)
138 self.do_checkbuild=True
140 def __getitem__(self, key):
141 if self.loadedpkgs.has_key(key):
142 return self.loadedpkgs[key]
143 elif key in self.pkgnames:
145 self.loadedpkgs[key]=pkg
150 def has_key(self, key):
151 if key in self.pkgnames:
160 return self.loadedpkgs.values()
162 def checktree(self, dsttree):
163 self.__checkbuild(self.loadedpkgs.values())
164 self.__checkarchs(dsttree, self.loadedpkgs.values())
166 def testmove(self, dsttree):
167 self.__checkbuild(self.marked4moving)
168 self.__checkarchs(dsttree, self.marked4moving)
170 def movepkgs(self, dsttree):
171 if self.do_checkbuild:
172 self.__checkbuild(self.marked4moving)
174 self.__checkarchs(dsttree, self.marked4moving)
176 self.__rmolderfromsrc()
177 self.__rmotherfromdst(dsttree)
179 for pkg in self.marked4moving:
182 def removepkgs(self):
183 if self.do_checkbuild:
184 self.__checkbuild(self.marked4removal)
186 for pkg in self.marked4removal:
189 def mark4removal(self, wannabepkgs):
190 self.__mark4something(wannabepkgs, Pkg.mark4removal)
192 def mark4moving(self, wannabepkgs):
193 self.__mark4something(wannabepkgs, Pkg.mark4moving)
196 # Internal functions below
198 def __loadpkgnames(self):
199 def checkfiletype(name):
200 if name[-13:]=='.src.rpm.info':
204 list=filter(checkfiletype, os.listdir(self.basedir+'/SRPMS/.metadata'))
205 self.pkgnames=map((lambda x: x[:-13]), list)
207 def __mark4something(self, wannabepkgs, markfunction):
208 def chopoffextension(pkg):
209 found=pkg.find('.src.rpm')
214 for wannabepkg in wannabepkgs:
215 pkgname=chopoffextension(wannabepkg)
216 if pkgname in self.pkgnames:
217 if not pkgname in self.loadedpkgs.keys():
218 self.loadedpkgs[pkgname]=Pkg(pkgname, self)
219 markfunction(self.loadedpkgs[pkgname])
221 perror('%s not found in source tree' % pkgname)
224 def __checkbuild(self, marked):
225 f=urllib.urlopen(config.builderqueue)
228 reid=re.compile(r'^.*id=(.*) pri.*$')
229 regb=re.compile(r'^group:.*$|builders:.*$', re.M)
230 for i in re.findall(regb, f.read()):
232 id=reid.sub(r'\1', i)
235 requests[id]=requests[id]+i
238 for bid in pkg.build.keys():
239 if requests.has_key(bid) and not requests[bid].find('?') == -1:
240 pkg.error("(buildid %s) building not finished" % bid)
242 def __checkarchs(self, dsttree, marked):
244 if len(pkg.files.keys()) <= 1:
245 pkg.error('has only src.rpm built')
247 otherpkgnames=self.__find_other_pkgs(pkg, dsttree)
248 if otherpkgnames: # check if we're not removing some archs
251 for somepkg in otherpkgnames:
252 curarchs.extend(Pkg(somepkg, dsttree).files.keys())
253 for arch in curarchs:
254 if arch not in pkg.files.keys():
255 missingarchs.append(arch)
257 pkg.error('moving would remove archs: %s' % missingarchs)
258 else: # warn if a package isn't built for all archs
259 if (config.separate_noarch and 'noarch' in pkg.files.keys() and
260 len(pkg.files.keys())==2):
262 elif len(pkg.files.keys()) != len(config.ftp_archs)+1:
264 for arch in config.ftp_archs:
265 if arch not in pkg.files.keys():
266 missingarchs.append(arch)
267 pkg.warning('not built for archs: %s' % missingarchs)
269 def __rmolderfromsrc(self):
270 for pkg in self.marked4moving:
271 olderpkgnames=self.__find_older_pkgs(pkg)
272 for i in olderpkgnames:
273 Pkg(i, self).remove()
275 def __rmotherfromdst(self, dsttree):
276 for pkg in self.marked4moving:
277 pkgnames=self.__find_other_pkgs(pkg, dsttree)
279 Pkg(i, dsttree).remove()
281 # Used more than once filter functions
283 def __find_other_pkgs(self, pkg, tree):
284 escapedpkgname=pkg.name.replace('.', '\.').replace('+', '\+')
285 ziewre=re.compile(escapedpkgname+'-[^-]*-[^-]*$')
286 def filter_other_pkgs(x):
287 if ziewre.match(x) and not x == pkg.nvr:
291 return filter(filter_other_pkgs, tree.pkgnames)
293 def __find_older_pkgs(self, pkg):
294 def filter_older_pkgs(x):
296 rc = rpm.labelCompare(('0', pkg.version, pkg.release),
298 if rc == 1: # pkg > x
302 return filter(filter_older_pkgs, self.__find_other_pkgs(pkg, self))