"""
from daklib.config import Config
+import daklib.daksubprocess
from daklib.dbconn import *
import daklib.dbconn as dbconn
from daklib.regexes import *
from apt_pkg import version_compare
import errno
import os
+import subprocess
+import textwrap
import time
import yaml
-# TODO: replace by subprocess
-import commands
-
def check_fields_for_valid_utf8(filename, control):
"""Check all fields of a control file for valid UTF-8"""
for field in control.keys():
return False
class SignatureAndHashesCheck(Check):
+ def check_replay(self, upload):
+ # Use private session as we want to remember having seen the .changes
+ # in all cases.
+ session = upload.session
+ history = SignatureHistory.from_signed_file(upload.changes)
+ r = history.query(session)
+ if r is not None:
+ raise Reject('Signature for changes file was already seen at {0}.\nPlease refresh the signature of the changes file if you want to upload it again.'.format(r.seen))
+ return True
+
"""Check signature of changes and dsc file (if included in upload)
Make sure the signature is valid and done by a known user.
changes = upload.changes
if not changes.valid_signature:
raise Reject("Signature for .changes not valid.")
+ self.check_replay(upload)
self._check_hashes(upload, changes.filename, changes.files.itervalues())
source = None
if transitions is None:
return True
+ session = upload.session
+
control = upload.changes.changes
source = re_field_source.match(control['Source']).group('package')
for trans in transitions:
t = transitions[trans]
- source = t["source"]
+ transition_source = t["source"]
expected = t["new"]
# Will be None if nothing is in testing.
- current = get_source_in_suite(source, "testing", session)
+ current = get_source_in_suite(transition_source, "testing", session)
if current is not None:
compare = apt_pkg.version_compare(current.version, expected)
Release Team, and {3} is the Release-Team member responsible for it.
Please mail debian-release@lists.debian.org or contact {3} directly if you
need further assistance. You might want to upload to experimental until this
-transition is done.""".format(source, currentlymsg, expected,t["rm"])))
+transition is done.""".format(transition_source, currentlymsg, expected,t["rm"])))
raise Reject(rejectmsg)
contents = file(path, 'r').read()
try:
- transitions = yaml.load(contents)
+ transitions = yaml.safe_load(contents)
return transitions
except yaml.YAMLError as msg:
utils.warn('Not checking transitions, the transitions file is broken: {0}'.format(msg))
return None
class NoSourceOnlyCheck(Check):
+ def is_source_only_upload(self, upload):
+ changes = upload.changes
+ if changes.source is not None and len(changes.binaries) == 0:
+ return True
+ return False
+
"""Check for source-only upload
Source-only uploads are only allowed if Dinstall::AllowSourceOnlyUploads is
set. Otherwise they are rejected.
+
+ Source-only uploads are only accepted for source packages having a
+ Package-List field that also lists architectures per package. This
+ check can be disabled via
+ Dinstall::AllowSourceOnlyUploadsWithoutPackageList.
+
+ Source-only uploads to NEW are only allowed if
+ Dinstall::AllowSourceOnlyNew is set.
+
+ Uploads not including architecture-independent packages are only
+ allowed if Dinstall::AllowNoArchIndepUploads is set.
+
"""
def check(self, upload):
- if Config().find_b("Dinstall::AllowSourceOnlyUploads"):
+ if not self.is_source_only_upload(upload):
return True
+
+ allow_source_only_uploads = Config().find_b('Dinstall::AllowSourceOnlyUploads')
+ allow_source_only_uploads_without_package_list = Config().find_b('Dinstall::AllowSourceOnlyUploadsWithoutPackageList')
+ allow_source_only_new = Config().find_b('Dinstall::AllowSourceOnlyNew')
+ allow_no_arch_indep_uploads = Config().find_b('Dinstall::AllowNoArchIndepUploads')
changes = upload.changes
- if changes.source is not None and len(changes.binaries) == 0:
+
+ if not allow_source_only_uploads:
raise Reject('Source-only uploads are not allowed.')
+ if not allow_source_only_uploads_without_package_list \
+ and changes.source.package_list.fallback:
+ raise Reject('Source-only uploads are only allowed if a Package-List field that also list architectures is included in the source package. dpkg (>= 1.17.7) includes this information.')
+ if not allow_source_only_new and upload.new:
+ raise Reject('Source-only uploads to NEW are not allowed.')
+
+ if not allow_no_arch_indep_uploads \
+ and 'all' not in changes.architectures \
+ and changes.source.package_list.has_arch_indep_packages():
+ raise Reject('Uploads not including architecture-independent packages are not allowed.')
+
return True
class LintianCheck(Check):
with open(tagfile, 'r') as sourcefile:
sourcecontent = sourcefile.read()
try:
- lintiantags = yaml.load(sourcecontent)['lintian']
+ lintiantags = yaml.safe_load(sourcecontent)['lintian']
except yaml.YAMLError as msg:
raise Exception('Could not read lintian tags file {0}, YAML error: {1}'.format(tagfile, msg))
changespath = os.path.join(upload.directory, changes.filename)
try:
cmd = []
+ result = 0
user = cnf.get('Dinstall::UnprivUser') or None
if user is not None:
cmd.extend(['sudo', '-H', '-u', user])
- cmd.extend(['LINTIAN_COLL_UNPACKED_SKIP_SIG=1', '/usr/bin/lintian', '--show-overrides', '--tags-from-file', temp_filename, changespath])
- result, output = commands.getstatusoutput(" ".join(cmd))
+ cmd.extend(['/usr/bin/lintian', '--show-overrides', '--tags-from-file', temp_filename, changespath])
+ output = daklib.daksubprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ result = e.returncode
+ output = e.output
finally:
os.unlink(temp_filename)