Hi!

Here's an initial draft of the pristine-tar support. More than something 
intended to be merged in, this is just a way to get some feedback, 
trying to understand if I'm on the right track.

I did two things:

1. Added a new pristine-tar=commit_id metadata field to the signed tag 
   generated by git-debpush
2. If a pristine-tar commitid is present, the git repo is hard-reset to 
   it, then the tarball name is obtained from the tree, and
   `pristine-tar checkout` is invoked to generate the tarball.

I believe this is safe security-wise because the commit id represented 
the expected status of the pristine-tar branch on the developer's 
machine is signed at the time of the upload. If for some reason the 
branch gets in-between the upload, and the expected commit is lost, 
things will just fail instead of generating a "wrong" tarball. Do you 
see flaws in this reasoning?

Note: I did not test that my implementation is actually correct and 
working. I did not add any new test either. I believe there are no 
regressions in old tests but I'm testing this on a plane and didn't look 
too much into the log output.

Let me know that you think! Bye :)

---
 git-debpush             | 12 +++++++++++-
 infra/dgit-repos-server |  5 ++++-
 tag2upload-obtain-origs | 23 ++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/git-debpush b/git-debpush
index e3a4ba39..1782513e 100755
--- a/git-debpush
+++ b/git-debpush
@@ -457,6 +457,16 @@ if $upstream; then
     to_push+=("$upstream_tag")
 fi
 
+# TODO: pristine-tar
+# I obtain the commit ID at the time of the upload, so that I can be sure that
+# the tag2upload service generates the tarball with the expected pristine-tar
+# branch state
+pristine_tar_info=''
+if pristine_tar_commit=$(git rev-parse --verify --quiet 
'refs/heads/pristine-tar'); then
+    pristine_tar_info=" pristine-tar=$pristine_tar_commit"
+fi
+
+
 #**** Useful sanity checks ****
 
 #---- UNRELEASED suite
@@ -837,7 +847,7 @@ fi
 tagmessage="$source release $version for $target
 
 [dgit distro=$distro split$quilt_mode_text]
-[dgit please-upload source=$source version=$version$upstream_info]
+[dgit please-upload source=$source 
version=$version$upstream_info$pristine_tar_info]
 "
 
 git_tag_main_opts_args=(-m "$tagmessage" "$debian_tag" "$branch_commit")
diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server
index f6a3716c..e797123b 100755
--- a/infra/dgit-repos-server
+++ b/infra/dgit-repos-server
@@ -1304,7 +1304,7 @@ our ($t2u_email_noreply, $t2u_email_noreply_addr, 
$t2u_email_reply_to,
      @t2u_email_copies, $t2u_jid, $t2u_url, $t2u_putative_package);
 our ($t2u_tagger, $t2u_tagger_addr, $t2u_timeout);
 our ($t2u_signing_keyid);
-our ($t2u_upstreamc, $t2u_upstreamt, $t2u_quilt);
+our ($t2u_upstreamc, $t2u_upstreamt, $t2u_quilt, $t2u_pristinetar);
 
 sub t2u_dgit_cmd () {
     (
@@ -1840,6 +1840,8 @@ sub tag2upload_parsetag ($) {
            $package = $1;
        } elsif (s/^version=(\S+) //) {
            $tagversion = $1;
+       } elsif (s/^pristine-tar=(\w+) //) {
+           $t2u_pristinetar = $1;
        } else {
            return 0;
        }
@@ -2030,6 +2032,7 @@ END
         "v=$version",
         "s=$suite",
         "u=$t2u_upstreamc",
+       "pristinetar=$t2u_pristinetar",
     );
     flush EMAIL_REPORT or confess $!;
     open STDOUT, ">& EMAIL_REPORT" or confess $!;
diff --git a/tag2upload-obtain-origs b/tag2upload-obtain-origs
index 016fa655..0453c2de 100755
--- a/tag2upload-obtain-origs
+++ b/tag2upload-obtain-origs
@@ -16,6 +16,7 @@
 # optional settings:
 #
 #     bpd                          defaults to ../bpd
+#     pristinetar=PRISTINE-TAR-COMMITID
 
 set -eu -o pipefail
 shopt -s inherit_errexit # #514862, wtf
@@ -96,7 +97,27 @@ case "$rc" in
        ;;
 esac
 
-x git deborig "$s_u"
+if [ -n "$s_pristinetar" ]; then
+    old_head=$(git rev-parse --verify HEAD)
+    git reset --hard -- "$s_pristinetar"
+
+    # Only get the first tarball file matching the current package version.
+    # pristine-tar does not disallow having two tarballs for the same package
+    # version using different compression algorithms, so this will just pick a
+    # random one. It might make sense to error out instead in such cases.
+    tarball=$(git ls-tree --name-only | while IFS= read -r file; do
+        case "$file" in
+            "${s_p}_${fversion}.orig.*.id") printf '%s\n' "${file%.id}"
+            break ;;
+        esac
+    done)
+
+    x pristine-tar checkout "$tarball"
+    git reset --hard -- "$old_head"
+else
+    x git deborig "$s_u"
+fi
+
 
 report 'created orig'
 
-- 
2.47.2

Reply via email to