1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import os
20 import sys
21
22 import apt_pkg
23
24 import daklib.archive
25 import daklib.config
26 import daklib.daklog
27 import daklib.regexes
28 import daklib.upload
29 from daklib.dbconn import (
30 Component,
31 Fingerprint,
32 Keyring,
33 Override,
34 OverrideType,
35 Priority,
36 Section,
37 Suite,
38 get_or_set_maintainer,
39 )
40
41
43 print(
44 """Usage:
45
46 dak import <suite> <component> <files...>
47 dak import -D|--dump <file> <suite> <component>
48 dak import -E|--export-dump <suite> <component>
49
50 WARNING: This command does no sanity checks. Only use it on trusted packages.
51
52 Options:
53 -h, --help: show this help message
54 -a, --add-overrides: add missing overrides automatically
55 -c, --changed-by: Changed-By for imported source packages
56 (default: maintainer)
57 -D, --dump <file>: Import all files listed in <file>. The format
58 is described below.
59 -E, --export-dump: Export list of files in the format required
60 by dak import --dump.
61 -s, --ignore-signature: ignore signature for imported source packages
62
63 File format used by --dump:
64
65 <filename>:<md5>:<sha1>:<sha256>:[<fingerprint>]:[<changed-by>]
66 """
67 )
68
69
70 -def import_source(
71 log,
72 transaction,
73 suite,
74 component,
75 directory,
76 hashed_file,
77 fingerprint=None,
78 changed_by=None,
79 keyrings=None,
80 require_signature=True,
81 add_overrides=False,
82 ):
83 if keyrings is None:
84 keyrings = []
85 filename = hashed_file.filename
86 session = transaction.session
87
88 source = daklib.upload.Source(directory, [hashed_file], keyrings, require_signature)
89 if source.valid_signature:
90 fingerprint = (
91 session.query(Fingerprint)
92 .filter_by(fingerprint=source.primary_fingerprint)
93 .first()
94 )
95 if changed_by is None:
96 changed_by = source.dsc["Maintainer"]
97 db_changed_by = get_or_set_maintainer(changed_by, session)
98
99 transaction.install_source(
100 directory, source, suite, component, db_changed_by, fingerprint=fingerprint
101 )
102 log.log(["import-source", suite.suite_name, component.component_name, filename])
103
104 if (
105 add_overrides
106 and not session.query(Override)
107 .filter_by(
108 suite=suite.get_overridesuite(),
109 component=component,
110 package=source.dsc["Source"],
111 )
112 .join(OverrideType)
113 .filter(OverrideType.overridetype == "dsc")
114 .first()
115 ):
116 overridetype = session.query(OverrideType).filter_by(overridetype="dsc").one()
117 overridesuite = suite.get_overridesuite()
118 section_name = "misc"
119 if component.component_name != "main":
120 section_name = "{0}/{1}".format(component.component_name, section_name)
121 section = session.query(Section).filter_by(section=section_name).one()
122 priority = session.query(Priority).filter_by(priority="optional").one()
123
124 override = Override(
125 package=source.dsc["Source"],
126 suite=overridesuite,
127 component=component,
128 section=section,
129 priority=priority,
130 overridetype=overridetype,
131 )
132 session.add(override)
133 log.log(
134 [
135 "add-source-override",
136 suite.suite_name,
137 component.component_name,
138 source.dsc["Source"],
139 section.section,
140 priority.priority,
141 ]
142 )
143
144
145 -def import_binary(
146 log,
147 transaction,
148 suite,
149 component,
150 directory,
151 hashed_file,
152 fingerprint=None,
153 add_overrides=False,
154 ):
155 filename = hashed_file.filename
156 session = transaction.session
157
158 binary = daklib.upload.Binary(directory, hashed_file)
159 transaction.install_binary(
160 directory, binary, suite, component, fingerprint=fingerprint
161 )
162 log.log(["import-binary", suite.suite_name, component.component_name, filename])
163
164 if (
165 add_overrides
166 and not session.query(Override)
167 .filter_by(
168 suite=suite.get_overridesuite(),
169 component=component,
170 package=binary.control["Package"],
171 )
172 .join(OverrideType)
173 .filter(OverrideType.overridetype == binary.type)
174 .first()
175 ):
176 overridetype = (
177 session.query(OverrideType).filter_by(overridetype=binary.type).one()
178 )
179 overridesuite = suite.get_overridesuite()
180 section = (
181 session.query(Section).filter_by(section=binary.control["Section"]).one()
182 )
183 priority = (
184 session.query(Priority)
185 .filter_by(priority=binary.control.get("Priority", "optional"))
186 .one()
187 )
188
189 override = Override(
190 package=binary.control["Package"],
191 suite=overridesuite,
192 component=component,
193 section=section,
194 priority=priority,
195 overridetype=overridetype,
196 )
197 session.add(override)
198 log.log(
199 [
200 "add-binary-override",
201 suite.suite_name,
202 component.component_name,
203 binary.control["Package"],
204 section.section,
205 priority.priority,
206 ]
207 )
208
209
210 -def import_file(
211 log,
212 transaction,
213 suite,
214 component,
215 directory,
216 hashed_file,
217 fingerprint=None,
218 changed_by=None,
219 keyrings=None,
220 require_signature=True,
221 add_overrides=False,
222 ):
223 filename = hashed_file.filename
224 if daklib.regexes.re_file_binary.match(filename):
225 import_binary(
226 log,
227 transaction,
228 suite,
229 component,
230 directory,
231 hashed_file,
232 fingerprint=fingerprint,
233 add_overrides=add_overrides,
234 )
235 elif daklib.regexes.re_file_dsc.match(filename):
236 import_source(
237 log,
238 transaction,
239 suite,
240 component,
241 directory,
242 hashed_file,
243 fingerprint=fingerprint,
244 changed_by=changed_by,
245 keyrings=keyrings,
246 require_signature=require_signature,
247 add_overrides=add_overrides,
248 )
249 else:
250 raise Exception(
251 "File is neither source nor binary package: {0}".format(filename)
252 )
253
254
255 -def import_dump(
256 log,
257 transaction,
258 suite,
259 component,
260 fh,
261 keyrings=None,
262 require_signature=True,
263 add_overrides=False,
264 ):
265 session = transaction.session
266 for line in fh:
267 path, size, md5, sha1, sha256, fpr, changed_by = line.strip().split(":", 6)
268 directory, filename = os.path.split(os.path.abspath(path))
269
270 if not changed_by:
271 changed_by = None
272 fingerprint = None
273 if fpr:
274 fingerprint = session.query(Fingerprint).filter_by(fingerprint=fpr).first()
275 if fingerprint is None:
276 print("W: {0}: unknown fingerprint {1}".format(filename, fpr))
277
278 hashed_file = daklib.upload.HashedFile(filename, int(size), md5, sha1, sha256)
279 hashed_file.check(directory)
280
281 import_file(
282 log,
283 transaction,
284 suite,
285 component,
286 directory,
287 hashed_file,
288 fingerprint=fingerprint,
289 changed_by=changed_by,
290 keyrings=keyrings,
291 require_signature=require_signature,
292 add_overrides=add_overrides,
293 )
294
295 transaction.commit()
296
297
298 _export_query = r"""
299 WITH
300 tmp AS
301 (SELECT 1 AS order, s.file AS file_id, s.sig_fpr AS fingerprint_id, s.changedby AS changed_by, sa.suite AS suite_id
302 FROM source s
303 JOIN src_associations sa ON sa.source = s.id
304 UNION
305 SELECT 2 AS order, b.file AS file_id, b.sig_fpr AS fingerprint_id, NULL, ba.suite AS suite_id
306 FROM binaries b
307 JOIN bin_associations ba ON ba.bin = b.id
308 )
309
310 SELECT
311 f.filename, f.size::TEXT, f.md5sum, f.sha1sum, f.sha256sum, COALESCE(fpr.fingerprint, ''), COALESCE(m.name, '')
312 FROM files f
313 JOIN tmp ON f.id = tmp.file_id
314 JOIN suite ON suite.id = tmp.suite_id
315 JOIN files_archive_map fam ON fam.file_id = f.id AND fam.archive_id = suite.archive_id
316 LEFT JOIN fingerprint fpr ON fpr.id = tmp.fingerprint_id
317 LEFT JOIN maintainer m ON m.id = tmp.changed_by
318
319 WHERE
320 suite.id = :suite_id
321 AND fam.component_id = :component_id
322
323 ORDER BY tmp.order, f.filename;
324 """
325
326
328 session = transaction.session
329 query = session.execute(
330 _export_query,
331 {"suite_id": suite.suite_id, "component_id": component.component_id},
332 )
333 for row in query:
334 print(":".join(row))
335
336
337 -def main(argv=None):
338 if argv is None:
339 argv = sys.argv
340
341 arguments = [
342 ("h", "help", "Import::Options::Help"),
343 ("a", "add-overrides", "Import::Options::AddOverrides"),
344 ("c", "changed-by", "Import::Options::ChangedBy", "HasArg"),
345 ("D", "dump", "Import::Options::Dump", "HasArg"),
346 ("E", "export-dump", "Import::Options::Export"),
347 ("s", "ignore-signature", "Import::Options::IgnoreSignature"),
348 ]
349
350 cnf = daklib.config.Config()
351 cnf["Import::Options::Dummy"] = ""
352 argv = apt_pkg.parse_commandline(cnf.Cnf, arguments, argv)
353 options = cnf.subtree("Import::Options")
354
355 if "Help" in options or len(argv) < 2:
356 usage()
357 sys.exit(0)
358
359 suite_name = argv[0]
360 component_name = argv[1]
361
362 add_overrides = options.find_b("AddOverrides")
363 require_signature = not options.find_b("IgnoreSignature")
364 changed_by = options.find("ChangedBy") or None
365
366 log = daklib.daklog.Logger("import")
367
368 with daklib.archive.ArchiveTransaction() as transaction:
369 session = transaction.session
370 suite = session.query(Suite).filter_by(suite_name=suite_name).one()
371 component = (
372 session.query(Component).filter_by(component_name=component_name).one()
373 )
374 keyrings = (
375 session.query(Keyring).filter_by(active=True).order_by(Keyring.priority)
376 )
377 keyring_files = [k.keyring_name for k in keyrings]
378
379 dump = options.find("Dump") or None
380 if options.find_b("Export"):
381 export_dump(transaction, suite, component)
382 transaction.rollback()
383 elif dump is not None:
384 with open(dump, "r") as fh:
385 import_dump(
386 log,
387 transaction,
388 suite,
389 component,
390 fh,
391 keyring_files,
392 require_signature=require_signature,
393 add_overrides=add_overrides,
394 )
395 transaction.commit()
396 else:
397 files = argv[2:]
398 for f in files:
399 directory, filename = os.path.split(os.path.abspath(f))
400 hashed_file = daklib.upload.HashedFile.from_file(directory, filename)
401 import_file(
402 log,
403 transaction,
404 suite,
405 component,
406 directory,
407 hashed_file,
408 changed_by=changed_by,
409 keyrings=keyring_files,
410 require_signature=require_signature,
411 add_overrides=add_overrides,
412 )
413 transaction.commit()
414
415 log.close()
416
417
418 if __name__ == "__main__":
419 main()
420