self.fs = FilesystemTransaction()
self.session = DBConn().session()
- def get_file(self, hashed_file, source_name):
+ def get_file(self, hashed_file, source_name, check_hashes=True):
"""Look for file C{hashed_file} in database
@type hashed_file: L{daklib.upload.HashedFile}
@param hashed_file: file to look for in the database
+ @type source_name: str
+ @param source_name: source package name
+
+ @type check_hashes: bool
+ @param check_hashes: check size and hashes match
+
@raise KeyError: file was not found in the database
@raise HashMismatchException: hash mismatch
poolname = os.path.join(utils.poolify(source_name), hashed_file.filename)
try:
poolfile = self.session.query(PoolFile).filter_by(filename=poolname).one()
- if poolfile.filesize != hashed_file.size or poolfile.md5sum != hashed_file.md5sum or poolfile.sha1sum != hashed_file.sha1sum or poolfile.sha256sum != hashed_file.sha256sum:
+ if check_hashes and (poolfile.filesize != hashed_file.size
+ or poolfile.md5sum != hashed_file.md5sum
+ or poolfile.sha1sum != hashed_file.sha1sum
+ or poolfile.sha256sum != hashed_file.sha256sum):
raise HashMismatchException('{0}: Does not match file already existing in the pool.'.format(hashed_file.filename))
return poolfile
except NoResultFound:
@type fingerprint: L{daklib.dbconn.Fingerprint}
@param fingerprint: optional fingerprint
- @type source_suites: list of L{daklib.dbconn.Suite} or C{True}
+ @type source_suites: SQLAlchemy subquery for C{daklib.dbconn.Suite} or C{True}
@param source_suites: suites to copy the source from if they are not
in C{suite} or C{True} to allow copying from any
suite.
- This can also be a SQLAlchemy (sub)query object.
@type extra_source_archives: list of L{daklib.dbconn.Archive}
@param extra_source_archives: extra archives to copy Built-Using sources from
# Uploaders are the maintainer and co-maintainers from the Uploaders field
db_source.uploaders.append(maintainer)
if 'Uploaders' in control:
- def split_uploaders(field):
- import re
- for u in re.sub(">[ ]*,", ">\t", field).split("\t"):
- yield u.strip()
-
+ from daklib.textutils import split_uploaders
for u in split_uploaders(control['Uploaders']):
db_source.uploaders.append(get_or_set_maintainer(u, session))
session.flush()
@type: bool
"""
+ self._checked = False
+ """checks passes. set by C{check}
+ @type: bool
+ """
+
self._new_queue = self.session.query(PolicyQueue).filter_by(queue_name='new').one()
self._new = self._new_queue.suite
cnf = Config()
session = self.transaction.session
- self.directory = tempfile.mkdtemp(dir=cnf.get('Dir::TempPath'))
+ self.directory = utils.temp_dirname(parent=cnf.get('Dir::TempPath'),
+ mode=0o2750, group=cnf.unprivgroup)
with FilesystemTransaction() as fs:
src = os.path.join(self.original_directory, self.original_changes.filename)
dst = os.path.join(self.directory, self.original_changes.filename)
- fs.copy(src, dst)
+ fs.copy(src, dst, mode=0o640)
self.changes = upload.Changes(self.directory, self.original_changes.filename, self.keyrings)
for f in self.changes.files.itervalues():
src = os.path.join(self.original_directory, f.filename)
dst = os.path.join(self.directory, f.filename)
- fs.copy(src, dst)
+ if not os.path.exists(src):
+ continue
+ fs.copy(src, dst, mode=0o640)
source = self.changes.source
if source is not None:
for f in source.files.itervalues():
src = os.path.join(self.original_directory, f.filename)
dst = os.path.join(self.directory, f.filename)
- if f.filename not in self.changes.files:
- db_file = self.transaction.get_file(f, source.dsc['Source'])
- db_archive_file = session.query(ArchiveFile).filter_by(file=db_file).first()
- fs.copy(db_archive_file.path, dst, symlink=True)
+ if not os.path.exists(dst):
+ try:
+ db_file = self.transaction.get_file(f, source.dsc['Source'], check_hashes=False)
+ db_archive_file = session.query(ArchiveFile).filter_by(file=db_file).first()
+ fs.copy(db_archive_file.path, dst, symlink=True)
+ except KeyError:
+ # Ignore if get_file could not find it. Upload will
+ # probably be rejected later.
+ pass
def unpacked_source(self):
"""Path to unpacked source
sourcedir = os.path.join(self.directory, 'source')
if not os.path.exists(sourcedir):
- subprocess.check_call(["dpkg-source", "--no-copy", "-x", dsc_path, sourcedir], shell=False)
+ devnull = open('/dev/null', 'w')
+ subprocess.check_call(["dpkg-source", "--no-copy", "--no-check", "-x", dsc_path, sourcedir], shell=False, stdout=devnull)
if not os.path.isdir(sourcedir):
raise Exception("{0} is not a directory after extracting source package".format(sourcedir))
return sourcedir
suites = session.query(Suite).filter(Suite.suite_name.in_(suite_names))
return suites
- def _mapped_component(self, component_name):
- """get component after mappings
-
- Evaluate component mappings from ComponentMappings in dak.conf for the
- given component name.
-
- @todo: ansgar wants to get rid of this. It's currently only used for
- the security archive
-
- @type component_name: str
- @param component_name: component name
-
- @rtype: L{daklib.dbconn.Component}
- @return: component after applying maps
- """
- cnf = Config()
- for m in cnf.value_list("ComponentMappings"):
- (src, dst) = m.split()
- if component_name == src:
- component_name = dst
- component = self.session.query(Component).filter_by(component_name=component_name).one()
- return component
-
def _check_new(self, suite):
"""Check if upload is NEW
return override.component
if only_overrides:
return None
- return self._mapped_component(binary.component)
+ return get_mapped_component(binary.component, self.session)
def check(self, force=False):
"""run checks against the upload
assert self.changes.valid_signature
try:
+ # Validate signatures and hashes before we do any real work:
for chk in (
checks.SignatureCheck,
checks.ChangesCheck,
- checks.TransitionCheck,
- checks.UploadBlockCheck,
checks.HashesCheck,
checks.SourceCheck,
checks.BinaryCheck,
checks.BinaryTimestampCheck,
- checks.ACLCheck,
checks.SingleDistributionCheck,
- checks.NoSourceOnlyCheck,
- checks.LintianCheck,
):
chk().check(self)
final_suites = self._final_suites()
if len(final_suites) == 0:
- self.reject_reasons.append('Ended with no suite to install to.')
+ self.reject_reasons.append('No target suite found. Please check your target distribution and that you uploaded to the right archive.')
return False
+ self.final_suites = final_suites
+
for chk in (
+ checks.TransitionCheck,
+ checks.ACLCheck,
+ checks.NoSourceOnlyCheck,
+ checks.LintianCheck,
+ ):
+ chk().check(self)
+
+ for chk in (
+ checks.ACLCheck,
checks.SourceFormatCheck,
checks.SuiteArchitectureCheck,
checks.VersionCheck,
if len(self.reject_reasons) != 0:
return False
- self.final_suites = final_suites
+ self._checked = True
return True
except checks.Reject as e:
self.reject_reasons.append(unicode(e))
changed_by = get_or_set_maintainer(control.get('Changed-By', control['Maintainer']), self.session)
if source_suites is None:
- source_suites = self.session.query(Suite).join((VersionCheck, VersionCheck.reference_id == Suite.suite_id)).filter(VersionCheck.suite == suite).subquery()
+ source_suites = self.session.query(Suite).join((VersionCheck, VersionCheck.reference_id == Suite.suite_id)).filter(VersionCheck.check == 'Enhances').filter(VersionCheck.suite == suite).subquery()
source = self.changes.source
if source is not None:
assert len(self.reject_reasons) == 0
assert self.changes.valid_signature
assert self.final_suites is not None
+ assert self._checked
byhand = self.changes.byhand_files
if len(byhand) == 0:
package, version, archext = parts
arch, ext = archext.split('.', 1)
- rule = automatic_byhand_packages.get(package)
- if rule is None:
+ try:
+ rule = automatic_byhand_packages.subtree(package)
+ except KeyError:
remaining.append(f)
continue
assert len(self.reject_reasons) == 0
assert self.changes.valid_signature
assert self.final_suites is not None
+ assert self._checked
assert not self.new
db_changes = self._install_changes()
if policy_queue is not None:
redirected_suite = policy_queue.suite
+ source_suites = self.session.query(Suite).filter(Suite.suite_id.in_([suite.suite_id, redirected_suite.suite_id])).subquery()
+
source_component_func = lambda source: self._source_override(overridesuite, source).component
binary_component_func = lambda binary: self._binary_component(overridesuite, binary)
- (db_source, db_binaries) = self._install_to_suite(redirected_suite, source_component_func, binary_component_func, extra_source_archives=[suite.archive])
+ (db_source, db_binaries) = self._install_to_suite(redirected_suite, source_component_func, binary_component_func, source_suites=source_suites, extra_source_archives=[suite.archive])
if policy_queue is not None:
self._install_policy(policy_queue, suite, db_changes, db_source, db_binaries)
# copy to build queues
if policy_queue is None or policy_queue.send_to_build_queues:
for build_queue in suite.copy_queues:
- self._install_to_suite(build_queue.suite, source_component_func, binary_component_func, extra_source_archives=[suite.archive])
+ self._install_to_suite(build_queue.suite, source_component_func, binary_component_func, source_suites=source_suites, extra_source_archives=[suite.archive])
self._do_bts_versiontracking()
binaries = self.changes.binaries
byhand = self.changes.byhand_files
- new_queue = self.transaction.session.query(PolicyQueue).filter_by(queue_name='new').one()
- if len(byhand) > 0:
- new_queue = self.transaction.session.query(PolicyQueue).filter_by(queue_name='byhand').one()
- new_suite = new_queue.suite
-
# we need a suite to guess components
suites = list(self.final_suites)
assert len(suites) == 1, "NEW uploads must be to a single suite"
suite = suites[0]
+ # decide which NEW queue to use
+ if suite.new_queue is None:
+ new_queue = self.transaction.session.query(PolicyQueue).filter_by(queue_name='new').one()
+ else:
+ new_queue = suite.new_queue
+ if len(byhand) > 0:
+ # There is only one global BYHAND queue
+ new_queue = self.transaction.session.query(PolicyQueue).filter_by(queue_name='byhand').one()
+ new_suite = new_queue.suite
+
+
def binary_component_func(binary):
return self._binary_component(suite, binary, only_overrides=False)
source_component_name = guess
break
if source_component_name is None:
- raise Exception('Could not guess source component.')
- source_component = self.session.query(Component).filter_by(component_name=source_component_name).one()
+ source_component = self.session.query(Component).order_by(Component.component_id).first()
+ else:
+ source_component = self.session.query(Component).filter_by(component_name=source_component_name).one()
source_component_func = lambda source: source_component
db_changes = self._install_changes()