from urgencylog import UrgencyLog
from dbconn import *
from summarystats import SummaryStats
-from utils import parse_changes, check_dsc_files, build_package_set
+from utils import parse_changes, check_dsc_files, build_package_list
from textutils import fix_maintainer
from lintian import parse_lintian_output, generate_reject_messages
from contents import UnpackedSource
# Try to get the Package-Set field from an included .dsc file (if possible).
if dsc:
- for package, entry in build_package_set(dsc, session).items():
- if not new.has_key(package):
+ for package, entry in build_package_list(dsc, session).items():
+ if package not in new:
new[package] = entry
# Build up a list of potentially new things
def callback(self, member, data):
if member.mtime > self.future_cutoff:
- self.future_files[Name] = MTime
+ self.future_files[Name] = member.mtime
if member.mtime < self.past_cutoff:
- self.ancient_files[Name] = MTime
+ self.ancient_files[Name] = member.mtime
###############################################################################
###############################################################################
+# FIXME: Should move into the database
# suite names DMs can upload to
-dm_suites = ['unstable', 'experimental']
+dm_suites = ['unstable', 'experimental', 'squeeze-backports']
def get_newest_source(source, session):
'returns the newest DBSource object in dm_suites'
except CantOpenError:
self.rejects.append("%s: can't read file." % (filename))
return False
- except ParseChangesError, line:
+ except ParseChangesError as line:
self.rejects.append("%s: parse error, can't grok: %s." % (filename, line))
return False
except ChangesUnicodeError:
# Parse the Files field from the .changes into another dictionary
try:
self.pkg.files.update(utils.build_file_list(self.pkg.changes))
- except ParseChangesError, line:
+ except ParseChangesError as line:
self.rejects.append("%s: parse error, can't grok: %s." % (filename, line))
return False
- except UnknownFormatError, format:
+ except UnknownFormatError as format:
self.rejects.append("%s: unknown format '%s'." % (filename, format))
return False
self.pkg.changes["maintainername"],
self.pkg.changes["maintaineremail"]) = \
fix_maintainer (self.pkg.changes["maintainer"])
- except ParseMaintError, msg:
+ except ParseMaintError as msg:
self.rejects.append("%s: Maintainer field ('%s') failed to parse: %s" \
% (filename, self.pkg.changes["maintainer"], msg))
self.pkg.changes["changedbyname"],
self.pkg.changes["changedbyemail"]) = \
fix_maintainer (self.pkg.changes.get("changed-by", ""))
- except ParseMaintError, msg:
+ except ParseMaintError as msg:
self.pkg.changes["changedby822"] = ""
self.pkg.changes["changedby2047"] = ""
self.pkg.changes["changedbyname"] = ""
Cnf = Config()
# Handle suite mappings
- for m in Cnf.ValueList("SuiteMappings"):
+ for m in Cnf.value_list("SuiteMappings"):
args = m.split()
mtype = args[0]
if mtype == "map" or mtype == "silent-map":
# Extract package control information
deb_file = utils.open_file(f)
try:
- control = apt_pkg.ParseSection(apt_inst.debExtractControl(deb_file))
+ control = apt_pkg.TagSection(utils.deb_extract_control(deb_file))
except:
- self.rejects.append("%s: debExtractControl() raised %s." % (f, sys.exc_type))
+ self.rejects.append("%s: deb_extract_control() raised %s." % (f, sys.exc_info()[0]))
deb_file.close()
# Can't continue, none of the checks on control would work.
return
- # Check for mandantory "Description:"
- deb_file.seek(0)
- try:
- apt_pkg.ParseSection(apt_inst.debExtractControl(deb_file))["Description"] + '\n'
- except:
- self.rejects.append("%s: Missing Description in binary package" % (f))
- return
-
deb_file.close()
# Check for mandatory fields
- for field in [ "Package", "Architecture", "Version" ]:
- if control.Find(field) == None:
+ for field in [ "Package", "Architecture", "Version", "Description" ]:
+ if field not in control:
# Can't continue
self.rejects.append("%s: No %s field in control." % (f, field))
return
# Ensure the package name matches the one give in the .changes
- if not self.pkg.changes["binary"].has_key(control.Find("Package", "")):
- self.rejects.append("%s: control file lists name as `%s', which isn't in changes file." % (f, control.Find("Package", "")))
+ if not self.pkg.changes["binary"].has_key(control.find("Package", "")):
+ self.rejects.append("%s: control file lists name as `%s', which isn't in changes file." % (f, control.find("Package", "")))
# Validate the package field
- package = control.Find("Package")
+ package = control["Package"]
if not re_valid_pkg_name.match(package):
self.rejects.append("%s: invalid package name '%s'." % (f, package))
# Validate the version field
- version = control.Find("Version")
+ version = control["Version"]
if not re_valid_version.match(version):
self.rejects.append("%s: invalid version number '%s'." % (f, version))
# Ensure the architecture of the .deb is one we know about.
default_suite = cnf.get("Dinstall::DefaultSuite", "unstable")
- architecture = control.Find("Architecture")
+ architecture = control["Architecture"]
upload_suite = self.pkg.changes["distribution"].keys()[0]
if architecture not in [a.arch_string for a in get_suite_architectures(default_suite, session = session)] \
self.rejects.append("%s: control file lists arch as `%s', which isn't in changes file." % (f, architecture))
# Sanity-check the Depends field
- depends = control.Find("Depends")
+ depends = control.find("Depends")
if depends == '':
self.rejects.append("%s: Depends field is empty." % (f))
# Sanity-check the Provides field
- provides = control.Find("Provides")
- if provides:
+ provides = control.find("Provides")
+ if provides is not None:
provide = re_spacestrip.sub('', provides)
if provide == '':
self.rejects.append("%s: Provides field is empty." % (f))
# If there is a Built-Using field, we need to check we can find the
# exact source version
- built_using = control.Find("Built-Using")
- if built_using:
+ built_using = control.find("Built-Using")
+ if built_using is not None:
try:
entry["built-using"] = []
for dep in apt_pkg.parse_depends(built_using):
else:
entry["built-using"].append( (bu_so[0].source, bu_so[0].version, ) )
- except ValueError, e:
+ except ValueError as e:
self.rejects.append("%s: Cannot parse Built-Using field: %s" % (f, str(e)))
# Check the section & priority match those given in the .changes (non-fatal)
- if control.Find("Section") and entry["section"] != "" \
- and entry["section"] != control.Find("Section"):
+ if control.find("Section") and entry["section"] != "" \
+ and entry["section"] != control.find("Section"):
self.warnings.append("%s control file lists section as `%s', but changes file has `%s'." % \
- (f, control.Find("Section", ""), entry["section"]))
- if control.Find("Priority") and entry["priority"] != "" \
- and entry["priority"] != control.Find("Priority"):
+ (f, control.find("Section", ""), entry["section"]))
+ if control.find("Priority") and entry["priority"] != "" \
+ and entry["priority"] != control.find("Priority"):
self.warnings.append("%s control file lists priority as `%s', but changes file has `%s'." % \
- (f, control.Find("Priority", ""), entry["priority"]))
+ (f, control.find("Priority", ""), entry["priority"]))
entry["package"] = package
entry["architecture"] = architecture
entry["version"] = version
- entry["maintainer"] = control.Find("Maintainer", "")
+ entry["maintainer"] = control.find("Maintainer", "")
if f.endswith(".udeb"):
self.pkg.files[f]["dbtype"] = "udeb"
else:
self.rejects.append("%s is neither a .deb or a .udeb." % (f))
- entry["source"] = control.Find("Source", entry["package"])
+ entry["source"] = control.find("Source", entry["package"])
# Get the source version
source = entry["source"]
if entry["package"] != file_package:
self.rejects.append("%s: package part of filename (%s) does not match package name in the %s (%s)." % \
(f, file_package, entry["dbtype"], entry["package"]))
- epochless_version = re_no_epoch.sub('', control.Find("Version"))
+ epochless_version = re_no_epoch.sub('', control.find("Version"))
# version
file_version = m.group(2)
return
# Handle component mappings
- for m in cnf.ValueList("ComponentMappings"):
+ for m in cnf.value_list("ComponentMappings"):
(source, dest) = m.split()
if entry["component"] == source:
entry["original component"] = source
or (dbc.in_queue is not None
and dbc.in_queue.queue_name not in ["unchecked", "newstage"]):
self.rejects.append("%s file already known to dak" % base_filename)
- except NoResultFound, e:
+ except NoResultFound as e:
# not known, good
pass
if not has_source:
self.rejects.append("no source found and Architecture line in changes mention source.")
- if (not has_binaries) and (not cnf.FindB("Dinstall::AllowSourceOnlyUploads")):
+ if (not has_binaries) and (not cnf.find_b("Dinstall::AllowSourceOnlyUploads")):
self.rejects.append("source only uploads are not supported.")
###########################################################################
except CantOpenError:
if not action:
return False, "%s: can't read file." % (dsc_filename)
- except ParseChangesError, line:
+ except ParseChangesError as line:
return False, "%s: parse error, can't grok: %s." % (dsc_filename, line)
- except InvalidDscError, line:
+ except InvalidDscError as line:
return False, "%s: syntax error on line %s." % (dsc_filename, line)
except ChangesUnicodeError:
return False, "%s: dsc file not proper utf-8." % (dsc_filename)
if not self.pkg.changes["architecture"].has_key("source"):
return True
+ if session is None:
+ session = DBConn().session()
+
(status, reason) = self.load_dsc(action=action)
if not status:
self.rejects.append(reason)
except NoFilesFieldError:
self.rejects.append("%s: no Files: field." % (dsc_filename))
return False
- except UnknownFormatError, format:
+ except UnknownFormatError as format:
self.rejects.append("%s: unknown format '%s'." % (dsc_filename, format))
return False
- except ParseChangesError, line:
+ except ParseChangesError as line:
self.rejects.append("%s: parse error, can't grok: %s." % (dsc_filename, line))
return False
# Only a limited list of source formats are allowed in each suite
for dist in self.pkg.changes["distribution"].keys():
- allowed = [ x.format_name for x in get_suite_src_formats(dist, session) ]
+ suite = get_suite(dist, session=session)
+ if not suite:
+ self.rejects.append("%s: cannot find suite %s when checking source formats" % (dsc_filename, dist))
+ continue
+ allowed = [ x.format_name for x in suite.srcformats ]
if self.pkg.dsc["format"] not in allowed:
self.rejects.append("%s: source format '%s' not allowed in %s (accepted: %s) " % (dsc_filename, self.pkg.dsc["format"], dist, ", ".join(allowed)))
try:
# We ignore the return value
fix_maintainer(self.pkg.dsc["maintainer"])
- except ParseMaintError, msg:
+ except ParseMaintError as msg:
self.rejects.append("%s: Maintainer field ('%s') failed to parse: %s" \
% (dsc_filename, self.pkg.dsc["maintainer"], msg))
if field:
# Have apt try to parse them...
try:
- apt_pkg.ParseSrcDepends(field)
+ apt_pkg.parse_src_depends(field)
except:
self.rejects.append("%s: invalid %s field (can not be parsed by apt)." % (dsc_filename, field_name.title()))
# Extract the source
try:
unpacked = UnpackedSource(dsc_filename)
- except Exception, e:
+ except Exception as e:
self.rejects.append("'dpkg-source -x' failed for %s. (%s)" % (dsc_filename, str(e)))
return
- if not cnf.Find("Dir::BTSVersionTrack"):
+ if not cnf.find("Dir::BTSVersionTrack"):
return
# Get the upstream version
try:
shutil.rmtree(tmpdir)
- except OSError, e:
+ except OSError as e:
if e.errno != errno.EACCES:
print "foobar"
utils.fubar("%s: couldn't remove tmp dir for source tree." % (self.pkg.dsc["source"]))
if result != 0:
utils.fubar("'%s' failed with result %s." % (cmd, result))
shutil.rmtree(tmpdir)
- except Exception, e:
+ except Exception as e:
print "foobar2 (%s)" % e
utils.fubar("%s: couldn't remove tmp dir for source tree." % (self.pkg.dsc["source"]))
try:
lintiantags = yaml.load(sourcecontent)['lintian']
- except yaml.YAMLError, msg:
+ except yaml.YAMLError as msg:
utils.fubar("Can not read the lintian tags file %s, YAML error: %s." % (tagfile, msg))
return
if not self.pkg.changes.has_key("urgency"):
self.pkg.changes["urgency"] = cnf["Urgency::Default"]
self.pkg.changes["urgency"] = self.pkg.changes["urgency"].lower()
- if self.pkg.changes["urgency"] not in cnf.ValueList("Urgency::Valid"):
+ if self.pkg.changes["urgency"] not in cnf.value_list("Urgency::Valid"):
self.warnings.append("%s is not a valid urgency; it will be treated as %s by testing." % \
(self.pkg.changes["urgency"], cnf["Urgency::Default"]))
self.pkg.changes["urgency"] = cnf["Urgency::Default"]
self.rejects.append("%s: has %s file(s) with a time stamp too ancient (e.g. %s [%s])."
% (filename, num_ancient_files, ancient_file, time.ctime(ancient_date)))
except:
- self.rejects.append("%s: deb contents timestamp check failed [%s: %s]" % (filename, sys.exc_type, sys.exc_value))
+ self.rejects.append("%s: deb contents timestamp check failed [%s: %s]" % (filename, sys.exc_info()[0], sys.exc_info()[1]))
def check_if_upload_is_sponsored(self, uid_email, uid_name):
+ for key in "maintaineremail", "changedbyemail", "maintainername", "changedbyname":
+ if not self.pkg.changes.has_key(key):
+ return False
+ uid_email = '@'.join(uid_email.split('@')[:2])
if uid_email in [self.pkg.changes["maintaineremail"], self.pkg.changes["changedbyemail"]]:
sponsored = False
elif uid_name in [self.pkg.changes["maintainername"], self.pkg.changes["changedbyname"]]:
sponsored = True
else:
sponsored = True
+ sponsor_addresses = utils.gpg_get_key_addresses(self.pkg.changes["fingerprint"])
+ debian_emails = filter(lambda addr: addr.endswith('@debian.org'), sponsor_addresses)
+ if uid_email not in debian_emails:
+ if debian_emails:
+ uid_email = debian_emails[0]
if ("source" in self.pkg.changes["architecture"] and uid_email and utils.is_email_alias(uid_email)):
- sponsor_addresses = utils.gpg_get_key_addresses(self.pkg.changes["fingerprint"])
if (self.pkg.changes["maintaineremail"] not in sponsor_addresses and
self.pkg.changes["changedbyemail"] not in sponsor_addresses):
self.pkg.changes["sponsoremail"] = uid_email
r = get_newest_source(self.pkg.changes["source"], session)
if r is None:
- rej = "Could not find existing source package %s in unstable or experimental and this is a DM upload" % self.pkg.changes["source"]
+ rej = "Could not find existing source package %s in the DM allowed suites and this is a DM upload" % self.pkg.changes["source"]
self.rejects.append(rej)
return
sourcecontent = sourcefile.read()
try:
transitions = yaml.load(sourcecontent)
- except yaml.YAMLError, msg:
+ except yaml.YAMLError as msg:
# This shouldn't happen, there is a wrapper to edit the file which
# checks it, but we prefer to be safe than ending up rejecting
# everything.
# Will be None if nothing is in testing.
current = get_source_in_suite(source, "testing", session)
if current is not None:
- compare = apt_pkg.VersionCompare(current.version, expected)
+ compare = apt_pkg.version_compare(current.version, expected)
if current is None or compare < 0:
# This is still valid, the current version in testing is older than
# This is for direport's benefit...
f = re_fdnic.sub("\n .\n", self.pkg.changes.get("changes", ""))
- if byhand or new:
- summary += "Changes: " + f
+ summary += "\n\nChanges:\n" + f
summary += "\n\nOverride entries for your package:\n" + override_summary + "\n"
"""
cnf = Config()
- announcetemplate = os.path.join(cnf["Dir::Templates"], 'process-unchecked.announce')
+
+ # Skip all of this if not sending mail to avoid confusing people
+ if cnf.has_key("Dinstall::Options::No-Mail") and cnf["Dinstall::Options::No-Mail"]:
+ return ""
# Only do announcements for source uploads with a recent dpkg-dev installed
if float(self.pkg.changes.get("format", 0)) < 1.6 or not \
self.pkg.changes["architecture"].has_key("source"):
return ""
- lists_done = {}
- summary = ""
+ announcetemplate = os.path.join(cnf["Dir::Templates"], 'process-unchecked.announce')
- self.Subst["__SHORT_SUMMARY__"] = short_summary
+ lists_todo = {}
+ summary = ""
+ # Get a unique list of target lists
for dist in self.pkg.changes["distribution"].keys():
suite = get_suite(dist)
if suite is None: continue
- announce_list = suite.announce
- if announce_list == "" or lists_done.has_key(announce_list):
- continue
+ for tgt in suite.announce:
+ lists_todo[tgt] = 1
+
+ self.Subst["__SHORT_SUMMARY__"] = short_summary
- lists_done[announce_list] = 1
+ for announce_list in lists_todo.keys():
summary += "Announcing to %s\n" % (announce_list)
if action:
del self.Subst["__ANNOUNCE_LIST_ADDRESS__"]
- if cnf.FindB("Dinstall::CloseBugs") and cnf.has_key("Dinstall::BugServer"):
+ if cnf.find_b("Dinstall::CloseBugs") and cnf.has_key("Dinstall::BugServer"):
summary = self.close_bugs(summary, action)
del self.Subst["__SHORT_SUMMARY__"]
self.announce(short_summary, 1)
## Helper stuff for DebBugs Version Tracking
- if cnf.Find("Dir::BTSVersionTrack"):
+ if cnf.find("Dir::BTSVersionTrack"):
if self.pkg.changes["architecture"].has_key("source"):
(fd, temp_filename) = utils.temp_filename(cnf["Dir::BTSVersionTrack"], prefix=".")
version_history = os.fdopen(fd, 'w')
filename = "%s/%s" % (cnf["Dir::BTSVersionTrack"],
self.pkg.changes_file[:-8]+".versions")
os.rename(temp_filename, filename)
- os.chmod(filename, 0644)
+ os.chmod(filename, 0o644)
# Write out the binary -> source mapping.
(fd, temp_filename) = utils.temp_filename(cnf["Dir::BTSVersionTrack"], prefix=".")
filename = "%s/%s" % (cnf["Dir::BTSVersionTrack"],
self.pkg.changes_file[:-8]+".debinfo")
os.rename(temp_filename, filename)
- os.chmod(filename, 0644)
+ os.chmod(filename, 0o644)
session.commit()
cnf = Config()
# Abandon the check if override disparity checks have been disabled
- if not cnf.FindB("Dinstall::OverrideDisparityCheck"):
+ if not cnf.find_b("Dinstall::OverrideDisparityCheck"):
return
summary = self.pkg.check_override()
dest_file = os.path.join(cnf["Dir::Reject"], file_entry)
try:
- dest_fd = os.open(dest_file, os.O_RDWR | os.O_CREAT | os.O_EXCL, 0644)
- except OSError, e:
+ dest_fd = os.open(dest_file, os.O_RDWR | os.O_CREAT | os.O_EXCL, 0o644)
+ except OSError as e:
# File exists? Let's find a new name by adding a number
if e.errno == errno.EEXIST:
try:
# Make sure we really got it
try:
- dest_fd = os.open(dest_file, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644)
- except OSError, e:
+ dest_fd = os.open(dest_file, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0o644)
+ except OSError as e:
# Likewise
utils.warn("**WARNING** failed to claim %s in the reject directory." % (file_entry))
return
raise
# If we got here, we own the destination file, so we can
# safely overwrite it.
- utils.move(file_entry, dest_file, 1, perms=0660)
+ utils.move(file_entry, dest_file, 1, perms=0o660)
os.close(dest_fd)
###########################################################################
reason_filename = self.pkg.changes_file[:-8] + ".reason"
reason_filename = os.path.join(cnf["Dir::Reject"], reason_filename)
+ changesfile = os.path.join(cnf["Dir::Reject"], self.pkg.changes_file)
# Move all the files into the reject directory
reject_files = self.pkg.files.keys() + [self.pkg.changes_file]
self.force_reject(reject_files)
+ # Change permissions of the .changes file to be world readable
+ try:
+ os.chmod(changesfile, os.stat(changesfile).st_mode | stat.S_IROTH)
+ except OSError as (errno, strerror):
+ # Ignore 'Operation not permitted' error.
+ if errno != 1:
+ raise
+
# If we fail here someone is probably trying to exploit the race
# so let's just raise an exception ...
if os.path.exists(reason_filename):
os.unlink(reason_filename)
- reason_fd = os.open(reason_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644)
+ reason_fd = os.open(reason_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0o644)
rej_template = os.path.join(cnf["Dir::Templates"], "queue.rejected")
anysuite = [suite] + [ vc.reference.suite_name for vc in get_version_checks(suite, "Enhances") ]
for (s, v) in sv_list:
if s in [ x.lower() for x in anysuite ]:
- if not anyversion or apt_pkg.VersionCompare(anyversion, v) <= 0:
+ if not anyversion or apt_pkg.version_compare(anyversion, v) <= 0:
anyversion = v
return anyversion
must_be_newer_than.append(target_suite)
for (suite, existent_version) in sv_list:
- vercmp = apt_pkg.VersionCompare(new_version, existent_version)
+ vercmp = apt_pkg.version_compare(new_version, existent_version)
if suite in must_be_newer_than and sourceful and vercmp < 1:
self.rejects.append("%s: old version (%s) in %s >= new version (%s) targeted at %s." % (filename, existent_version, suite, new_version, target_suite))
# we could just stick with the "...old version..." REJECT
# for this, I think.
self.rejects.append("Won't propogate NEW packages.")
- elif apt_pkg.VersionCompare(new_version, add_version) < 0:
+ elif apt_pkg.version_compare(new_version, add_version) < 0:
# propogation would be redundant. no need to reject though.
self.warnings.append("ignoring versionconflict: %s: old version (%s) in %s <= new version (%s) targeted at %s." % (filename, existent_version, suite, new_version, target_suite))
cansave = 1
- elif apt_pkg.VersionCompare(new_version, add_version) > 0 and \
- apt_pkg.VersionCompare(add_version, target_version) >= 0:
+ elif apt_pkg.version_compare(new_version, add_version) > 0 and \
+ apt_pkg.version_compare(add_version, target_version) >= 0:
# propogate!!
self.warnings.append("Propogating upload to %s" % (addsuite))
self.pkg.changes.setdefault("propdistribution", {})