Holger Levsen: > Hi ftp folks, > Hi, > while we still appreciate your comments on this proposal as last week > described in https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=763822 I'd like > to make a intermediate very simple proposal, so that reproducible builds in > Debian get one step forward: > I have started a git branch, build-info-support, available from: * ssh://release.debian.org/~nthykier/dak I realise that not every one have access to that machine, so the patches are also attached (@FTP: The branch have signed commits, so you may prefer merging form that). > - modify dak, so that it will not rejects uploads with a .buildinfo file > included. I got patches to have dak accept these and do some trivial validation (but not every validation proposed). I will extend my branch as time permits with additional checks. > - still, for now, throw the .buildinfo file immediately away. I have assumed this happens if you do no nothing explicitly with the file after it being accepted. * @FTP: If not, please let me know how I can have dak discard the file. > - only do this for experimental at the beginning. (maybe this restriction is > not even needed/useful.) > * Given the file is discarded, I have not added any such restrictions in my patch series. > That's it. > > This would allow the dpkg maintainers to enable .buildinfo file creation, at > least for builds for experimental. > > What do you think? > FWIW, I agree. :) > As I see it, this should be a rather trivial code change for dak and yet bring > us forward quite enourmously. Also it should be rather uncontroversial as we > all agreed in Heidelberg at DebConf15 that we want .buildinfo files in Debian… > > > cheers, > Holger > Thanks, ~Niels
From 10bc29c42eb36916aba1290c155126755837d903 Mon Sep 17 00:00:00 2001
From: Niels Thykier <niels@thykier.net>
Date: Mon, 14 Dec 2015 20:46:28 +0000
Subject: [PATCH 1/2] daklib/upload.py: Silently accept and discard .buildinfo
files
Besides some very trivial validation of the filename, accept
.buildinfo files without really looking at them.
Signed-off-by: Niels Thykier <niels@thykier.net>
---
daklib/regexes.py | 4 ++++
daklib/upload.py | 2 ++
2 files changed, 6 insertions(+)
diff --git a/daklib/regexes.py b/daklib/regexes.py
index ae8fd91..63d2ee6 100644
--- a/daklib/regexes.py
+++ b/daklib/regexes.py
@@ -141,6 +141,10 @@ re_file_source = re.compile(_re_file_prefix + r'(?:(?:\.orig(?:-[a-zA-Z0-9-]+)?|
# Groups: package, version
re_file_orig = re.compile(_re_file_prefix + r'\.orig(?:-[a-zA-Z0-9-]+)?(?:\.tar\.(?:bz2|gz|xz)|\.asc)')
+# Match buildinfo file
+# Groups: package, version, suffix
+re_file_buildinfo = re.compile(_re_file_prefix + r'_(?P<suffix>[a-zA-Z0-9+]+)\.changes$')
+
######################################################################
# Patterns matching fields #
######################################################################
diff --git a/daklib/upload.py b/daklib/upload.py
index b78d100..4c10f45 100644
--- a/daklib/upload.py
+++ b/daklib/upload.py
@@ -374,6 +374,8 @@ class Changes(object):
for f in self.files.itervalues():
if re_file_dsc.match(f.filename) or re_file_source.match(f.filename) or re_file_binary.match(f.filename):
continue
+ if re_file_buildinfo.match(f.filename):
+ continue
if f.section != 'byhand' and f.section[:4] != 'raw-':
raise InvalidChangesException("{0}: {1} looks like a byhand package, but is in section {2}".format(self.filename, f.filename, f.section))
byhand.append(f)
--
2.6.2
From 603ab424528a6f698332636ef3c80031a4e8c39c Mon Sep 17 00:00:00 2001
From: Niels Thykier <niels@thykier.net>
Date: Mon, 14 Dec 2015 21:06:55 +0000
Subject: [PATCH 2/2] Do very basic validation of .buildinfo files
Validate that .buildinfo:
* Have a valid signature (if signed)
* Are Deb822 control files (UTF-8 encoded)
* Have a Source and Version field equal to that of the .changes
file.
---
daklib/archive.py | 1 +
daklib/checks.py | 25 +++++++++++++++++++++++++
daklib/upload.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)
diff --git a/daklib/archive.py b/daklib/archive.py
index 4226ce9..6a044db 100644
--- a/daklib/archive.py
+++ b/daklib/archive.py
@@ -951,6 +951,7 @@ class ArchiveUpload(object):
checks.BinaryCheck,
checks.BinaryTimestampCheck,
checks.SingleDistributionCheck,
+ checks.BuildinfoCheck,
):
chk().check(self)
diff --git a/daklib/checks.py b/daklib/checks.py
index b187f03..07c43f9 100644
--- a/daklib/checks.py
+++ b/daklib/checks.py
@@ -500,6 +500,31 @@ class SourceCheck(Check):
return True
+
+class BuildinfoCheck(Check):
+ """Check buildinfo file for syntax errors."""
+
+ def check(self, upload):
+ buildinfo_files = upload.changes.buildinfo_files
+ if not buildinfo_files:
+ return True
+
+ changes = upload.changes.changes
+
+ for buildinfo_file in buildinfo_files:
+ control = buildinfo_file.buildinfo
+ bi_fn = buildinfo_file.filename
+ check_fields_for_valid_utf8(bi_fn, control)
+
+ # check fields
+ if not re_field_package.match(control['Source']):
+ raise Reject('{0}: Invalid Source field'.format(bi_fn))
+ if control['Source'] != changes['Source']:
+ raise Reject('{0}: Source field does not match Source field in changes'.format(bi_fn))
+ if control['Version'] != changes['Version']:
+ raise Reject('{0}: Version field does not match Version field in changes'.format(bi_fn))
+ return True
+
class SingleDistributionCheck(Check):
"""Check that the .changes targets only a single distribution."""
def check(self, upload):
diff --git a/daklib/upload.py b/daklib/upload.py
index 4c10f45..361febf 100644
--- a/daklib/upload.py
+++ b/daklib/upload.py
@@ -276,6 +276,7 @@ class Changes(object):
self._binaries = None
self._source = None
+ self._buildinfo_files = None
self._files = None
self._keyrings = keyrings
self._require_signature = require_signature
@@ -365,6 +366,16 @@ class Changes(object):
return self._binaries
@property
+ def buildinfo_files(self):
+ if self._buildinfo_files is None:
+ buildinfo_files = []
+ for f in self.files.itervalues():
+ if re_file_buildinfo.match(f.filename):
+ buildinfo_files.append(Binary(self.directory, f))
+ self._buildinfo_files = buildinfo_files
+ return self._buildinfo_files
+
+ @property
def byhand_files(self):
"""included byhand files
@type: list of L{daklib.upload.HashedFile}
@@ -596,3 +607,41 @@ class Source(object):
@type: str
"""
return self._dsc_file.filename
+
+
+class Buildinfo(object):
+ """Representation of a buildinfo file
+ """
+ def __init__(self, directory, hashed_file):
+ self.hashed_file = hashed_file
+ """the buildinfo file
+ @type: L{HashedFile}
+ """
+
+ buildinfo_file_path = os.path.join(directory, self.hashed_file.input_filename)
+ with open(buildinfo_file_path, 'r') as fd:
+ data = fd.read()
+ self._buildinfo = apt_pkg.TagSection(data)
+ """dict to access fields in the .dsc file
+ @type: dict-like
+ """
+
+ @classmethod
+ def from_file(cls, directory, filename):
+ hashed_file = HashedFile.from_file(directory, filename)
+ return cls(directory, hashed_file)
+
+ @property
+ def buildinfo(self):
+ """dict mapping of the .buildinfo file as a deb822 control file
+
+ @type: dict
+ """
+ return self._buildinfo
+
+ @property
+ def filename(self):
+ """filename of .buildinfo file
+ @type: str
+ """
+ return self.hashed_file.filename
--
2.6.2
Attachment:
signature.asc
Description: OpenPGP digital signature