Package dak :: Module import
[hide private]
[frames] | no frames]

Source Code for Module dak.import

  1  #! /usr/bin/env python3 
  2  # 
  3  # Copyright (C) 2012, Ansgar Burchardt <ansgar@debian.org> 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License along 
 16  # with this program; if not, write to the Free Software Foundation, Inc., 
 17  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 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   
42 -def usage():
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
327 -def export_dump(transaction, suite, component):
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