4 Functions related debian binary packages
6 @contact: Debian FTPMaster <ftpmaster@debian.org>
7 @copyright: 2009 Mike O'Connor <stew@debian.org>
8 @license: GNU General Public License version 2 or later
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 ################################################################################
27 # <Ganneff> are we going the xorg way?
28 # <Ganneff> a dak without a dak.conf?
29 # <stew> automatically detect the wrong settings at runtime?
31 # <mhy> well, we'll probably always need dak.conf (how do you get the database setting
32 # <mhy> but removing most of the config into the database seems sane
33 # <Ganneff> mhy: dont spoil the fun
34 # <Ganneff> mhy: and i know how. we nmap localhost and check all open ports
35 # <Ganneff> maybe one answers to sql
36 # <stew> we will discover projectb via avahi
37 # <mhy> you're both sick
38 # <mhy> really fucking sick
40 ################################################################################
50 from debian_bundle import deb822
51 from dbconn import DBConn
52 from config import Config
57 def __init__(self, filename, reject=None):
59 @ptype filename: string
60 @param filename: path of a .deb
62 @ptype reject: function
63 @param reject: a function to log reject messages to
65 self.filename = filename
68 self.wrapped_reject = reject
70 def reject(self, message):
72 if we were given a reject function, send the reject message,
73 otherwise send it to stderr.
75 print >> sys.stderr, message
76 if self.wrapped_reject:
77 self.wrapped_reject(message)
81 make sure we cleanup when we are garbage collected.
87 we need to remove the temporary directory, if we created one
89 if self.tmpdir and os.path.exists(self.tmpdir):
90 shutil.rmtree(self.tmpdir)
94 # get a list of the ar contents
97 cmd = "ar t %s" % (self.filename)
98 (result, output) = commands.getstatusoutput(cmd)
101 print("%s: 'ar t' invocation failed." % (self.filename))
102 self.reject("%s: 'ar t' invocation failed." % (self.filename))
103 self.reject(utils.prefix_multi_line_string(output, " [ar output:] "))
104 self.chunks = output.split('\n')
109 # Internal function which extracts the contents of the .ar to
110 # a temporary directory
113 tmpdir = utils.temp_dirname()
117 cmd = "ar x %s %s %s" % (os.path.join(cwd,self.filename), self.chunks[1], self.chunks[2])
118 (result, output) = commands.getstatusoutput(cmd)
120 print("%s: '%s' invocation failed." % (self.filename, cmd))
121 self.reject("%s: '%s' invocation failed." % (self.filename, cmd))
122 self.reject(utils.prefix_multi_line_string(output, " [ar output:] "))
125 atexit.register( self._cleanup )
132 Check deb contents making sure the .deb contains:
135 3. data.tar.gz or data.tar.bz2
136 in that order, and nothing else.
139 rejected = not self.chunks
140 if len(self.chunks) != 3:
142 self.reject("%s: found %d chunks, expected 3." % (self.filename, len(self.chunks)))
143 if self.chunks[0] != "debian-binary":
145 self.reject("%s: first chunk is '%s', expected 'debian-binary'." % (self.filename, self.chunks[0]))
146 if not rejected and self.chunks[1] != "control.tar.gz":
148 self.reject("%s: second chunk is '%s', expected 'control.tar.gz'." % (self.filename, self.chunks[1]))
149 if not rejected and self.chunks[2] not in [ "data.tar.bz2", "data.tar.gz" ]:
151 self.reject("%s: third chunk is '%s', expected 'data.tar.gz' or 'data.tar.bz2'." % (self.filename, self.chunks[2]))
155 def scan_package(self, bootstrap_id=0):
157 Unpack the .deb, do sanity checking, and gather info from it.
159 Currently information gathering consists of getting the contents list. In
160 the hopefully near future, it should also include gathering info from the
163 @ptype bootstrap_id: int
164 @param bootstrap_id: the id of the binary these packages
165 should be associated or zero meaning we are not bootstrapping
166 so insert into a temporary table
168 @return True if the deb is valid and contents were imported
171 rejected = not self.valid_deb()
177 if not rejected and self.tmpdir:
179 os.chdir(self.tmpdir)
180 if self.chunks[1] == "control.tar.gz":
181 control = tarfile.open(os.path.join(self.tmpdir, "control.tar.gz" ), "r:gz")
182 control.extract('./control', self.tmpdir )
183 if self.chunks[2] == "data.tar.gz":
184 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.gz"), "r:gz")
185 elif self.chunks[2] == "data.tar.bz2":
186 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.bz2" ), "r:bz2")
189 result = DBConn().insert_content_paths(bootstrap_id, [tarinfo.name for tarinfo in data if not tarinfo.isdir()])
191 pkgs = deb822.Packages.iter_paragraphs(file(os.path.join(self.tmpdir,'control')))
193 result = DBConn().insert_pending_content_paths(pkg, [tarinfo.name for tarinfo in data if not tarinfo.isdir()])
196 traceback.print_exc()
201 def check_utf8_package(self, package):
203 Unpack the .deb, do sanity checking, and gather info from it.
205 Currently information gathering consists of getting the contents list. In
206 the hopefully near future, it should also include gathering info from the
209 @ptype bootstrap_id: int
210 @param bootstrap_id: the id of the binary these packages
211 should be associated or zero meaning we are not bootstrapping
212 so insert into a temporary table
214 @return True if the deb is valid and contents were imported
216 rejected = not self.valid_deb()
219 if not rejected and self.tmpdir:
222 os.chdir(self.tmpdir)
223 if self.chunks[1] == "control.tar.gz":
224 control = tarfile.open(os.path.join(self.tmpdir, "control.tar.gz" ), "r:gz")
225 control.extract('control', self.tmpdir )
226 if self.chunks[2] == "data.tar.gz":
227 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.gz"), "r:gz")
228 elif self.chunks[2] == "data.tar.bz2":
229 data = tarfile.open(os.path.join(self.tmpdir, "data.tar.bz2" ), "r:bz2")
233 unicode( tarinfo.name )
235 print >> sys.stderr, "E: %s has non-unicode filename: %s" % (package,tarinfo.name)
238 traceback.print_exc()
243 if __name__ == "__main__":
244 Binary( "/srv/ftp.debian.org/queue/accepted/halevt_0.1.3-2_amd64.deb" ).scan_package()