This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new bf3de538bd GH-49988: [CI][Packaging] Enable reproducible builds on 
host for APT based Linux packages (#48148)
bf3de538bd is described below

commit bf3de538bd89b2925bb8fdfedcc866028aa9710c
Author: Raúl Cumplido <[email protected]>
AuthorDate: Fri May 22 09:42:40 2026 +0200

    GH-49988: [CI][Packaging] Enable reproducible builds on host for APT based 
Linux packages (#48148)
    
    ### Rationale for this change
    
    Reproducible builds are a requirement to be able to add automated signing. 
We would like to be able to do automated signing for our Linux packages too as 
discussed here:
    https://github.com/apache/arrow/issues/47058#issuecomment-3243601724
    
    ### What changes are included in this PR?
    
    Some minor changes to our build to fix some Reproducible tests errors 
found. The main addition is adding a new step to our Linux Packaging GitHub 
actions workflow to run reprotest on the rake tasks to build the packages and 
compare the artifacts built.
    
    ### Are these changes tested?
    
    Yes on CI as part of the APT Packaging Linux jobs.
    
    ### Are there any user-facing changes?
    
    * GitHub Issue: #49988
    
    Lead-authored-by: Raúl Cumplido <[email protected]>
    Co-authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 .github/workflows/package_linux.yml                | 45 ++++++++++++++++------
 cpp/cmake_modules/ThirdpartyToolchain.cmake        | 21 +++++++++-
 .../google-cloud-cpp-reproducible-builds.patch     | 42 ++++++++++++++++++++
 cpp/src/arrow/CMakeLists.txt                       |  3 ++
 .../apache-arrow-apt-source/Rakefile               | 17 +++++++-
 .../apt/debian-bookworm/Dockerfile                 |  1 +
 .../apt/debian-forky/Dockerfile                    |  1 +
 .../apt/debian-trixie/Dockerfile                   |  1 +
 .../apt/ubuntu-jammy/Dockerfile                    |  1 +
 .../apt/ubuntu-noble/Dockerfile                    |  1 +
 .../apt/ubuntu-resolute/Dockerfile                 |  1 +
 .../apache-arrow-apt-source/debian/rules           |  2 +
 .../apache-arrow/apt/debian-bookworm/Dockerfile    |  1 +
 .../apache-arrow/apt/debian-forky/Dockerfile       |  1 +
 .../apache-arrow/apt/debian-trixie/Dockerfile      |  2 +
 .../apache-arrow/apt/ubuntu-jammy/Dockerfile       |  1 +
 .../apache-arrow/apt/ubuntu-noble/Dockerfile       |  1 +
 .../apache-arrow/apt/ubuntu-resolute/Dockerfile    |  1 +
 dev/tasks/linux-packages/apt/build.sh              | 36 +++++++++++++++--
 dev/tasks/linux-packages/package-task.rb           | 17 +++++++-
 20 files changed, 176 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/package_linux.yml 
b/.github/workflows/package_linux.yml
index cdf8138ced..d02baba975 100644
--- a/.github/workflows/package_linux.yml
+++ b/.github/workflows/package_linux.yml
@@ -85,7 +85,7 @@ jobs:
       needs.check-labels.outputs.force == 'true' ||
       contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 
'CI: Extra') ||
       contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 
'CI: Extra: Package: Linux')
-    timeout-minutes: 120
+    timeout-minutes: 160
     strategy:
       fail-fast: false
       matrix:
@@ -113,7 +113,7 @@ jobs:
           - ubuntu-resolute-amd64
           - ubuntu-resolute-arm64
     env:
-      DOCKER_VOLUME_PREFIX: ".docker/"
+      BUILD_DIR: "${{ github.workspace }}/packages.build"
     steps:
       - name: Checkout Arrow
         uses: actions/checkout@v6
@@ -186,19 +186,29 @@ jobs:
             version="${GITHUB_REF_NAME#apache-arrow-}"
             echo "ARROW_VERSION=${version}" >> "${GITHUB_ENV}"
           fi
-      - name: Cache Docker Volumes
+      - name: Cache ccache
         uses: actions/cache@v5
         with:
-          path: .docker
+          path: ${{ env.BUILD_DIR }}/ccache
           key:  package-linux-${{ matrix.id }}-${{ hashFiles('cpp/**', 
'c_glib/**') }}
           restore-keys: package-linux-${{ matrix.id }}-
-      - name: Set up Ruby
+      - name: Install dependencies
         run: |
           sudo apt update
           sudo apt install -y \
             rake \
+            reprotest \
             ruby \
             ruby-dev
+      - name: Allow unprivileged user namespaces
+        if: env.TASK_NAMESPACE == 'apt'
+        # Reprotest's domain_host variation uses `unshare -r --uts`,
+        # which writes to /proc/self/uid_map. Ubuntu 24.04 restricts
+        # unprivileged user namespaces via AppArmor by default, so
+        # the call fails. Try to lift the restriction so reprotest
+        # can run the full set of variations.
+        run: |
+          sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
       - name: Prepare apache-arrow-apt-source for arm64
         if: env.ARCHITECTURE == 'arm64'
         run: |
@@ -239,10 +249,8 @@ jobs:
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
-          pushd dev/tasks/linux-packages
-          rake docker:pull || :
-          rake --trace ${TASK_NAMESPACE}:build BUILD_DIR=build
-          popd
+          rake -C dev/tasks/linux-packages docker:pull || :
+          rake -C dev/tasks/linux-packages ${TASK_NAMESPACE}:build
       - name: Docker Push
         continue-on-error: true
         if: >-
@@ -250,9 +258,7 @@ jobs:
           github.event_name == 'push' &&
           github.ref_name == 'main'
         run: |
-          pushd dev/tasks/linux-packages
-          rake docker:push
-          popd
+          rake -C dev/tasks/linux-packages docker:push
       - name: Build artifact tarball
         run: |
           mkdir -p "${DISTRIBUTION}"
@@ -328,6 +334,21 @@ jobs:
           pushd dev/tasks/linux-packages
           rake --trace ${TASK_NAMESPACE}:test
           popd
+      - name: Verify Reproducibility
+        if: env.TASK_NAMESPACE == 'apt'
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        run: |
+          rake -C dev/tasks/linux-packages docker:pull || :
+          # Validate reproducibility. Reprotest runs the build twice
+          # inside its own tempdir and doesn't copy artifacts back,
+          # so this is purely a verification step.
+          reprotest \
+            --vary=-fileordering \
+            --build-command \
+              "rake -C dev/tasks/linux-packages ${TASK_NAMESPACE}:build" \
+            "${PWD}" \
+            
"dev/tasks/linux-packages/*/apt/repositories/${DISTRIBUTION}/pool/${DISTRIBUTION_CODE_NAME}/*/*/*/*.deb"
 
   report-package-linux:
     if: github.event_name == 'schedule' && always()
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake 
b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index 8542e73c34..d6256d9363 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -3582,9 +3582,9 @@ function(build_google_cloud_cpp_storage)
   # Workaround missing BCRYPT_RSA_ALG_HANDLE macro in older MinGW-w64 headers.
   # google-cloud-cpp v3+ uses it without guards in sign_using_sha256.cc.
   set(GOOGLE_CLOUD_CPP_PATCH_COMMAND)
+  find_program(PATCH patch)
   if(MINGW AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11")
     # This is for RTools 40.
-    find_program(PATCH patch)
     if(PATCH)
       set(GOOGLE_CLOUD_CPP_PATCH_COMMAND
           ${PATCH} -p1 -i 
${CMAKE_CURRENT_LIST_DIR}/google-cloud-cpp-bcrypt-mingw.patch)
@@ -3597,6 +3597,16 @@ function(build_google_cloud_cpp_storage)
     endif()
   endif()
 
+  # Reproducible builds are only a requirement for the Linux packaging jobs.
+  if(PATCH AND NOT WIN32)
+    list(APPEND
+         GOOGLE_CLOUD_CPP_PATCH_COMMAND
+         ${PATCH}
+         -p1
+         -i
+         ${CMAKE_CURRENT_LIST_DIR}/google-cloud-cpp-reproducible-builds.patch)
+  endif()
+
   fetchcontent_declare(google_cloud_cpp
                        ${FC_DECLARE_COMMON_OPTIONS}
                        PATCH_COMMAND ${GOOGLE_CLOUD_CPP_PATCH_COMMAND}
@@ -4027,6 +4037,15 @@ function(build_awssdk)
   prepare_fetchcontent()
   set(BUILD_DEPS OFF)
   set(BUILD_TOOL OFF)
+  # This is for aws-lc. -ffile-prefix-map is needed for reproducible
+  # builds. If ASM flags doesn't have --file-prefix-map, it may
+  # produce different binaries. Only aws-lc uses assembler. So this is
+  # for aws-lc.
+  if(CMAKE_CXX_FLAGS MATCHES "-ffile-prefix-map=" AND NOT CMAKE_ASM_FLAGS 
MATCHES
+                                                      "-ffile-prefix-map=")
+    string(REGEX MATCH " -ffile-prefix-map=[^ ]+ " FFILE_PREFIX_MAP 
"${CMAKE_CXX_FLAGS}")
+    string(APPEND CMAKE_ASM_FLAGS "${FFILE_PREFIX_MAP}")
+  endif()
   set(CMAKE_UNITY_BUILD OFF) # Unity build causes some build errors.
   set(ENABLE_TESTING OFF)
   set(IN_SOURCE_BUILD ON)
diff --git a/cpp/cmake_modules/google-cloud-cpp-reproducible-builds.patch 
b/cpp/cmake_modules/google-cloud-cpp-reproducible-builds.patch
new file mode 100644
index 0000000000..6164b1463b
--- /dev/null
+++ b/cpp/cmake_modules/google-cloud-cpp-reproducible-builds.patch
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+From 252064718ccbeec5e4dee45d017036a84ab0c61c Mon Sep 17 00:00:00 2001
+From: Sutou Kouhei <[email protected]>
+Date: Sat, 31 Jan 2026 21:18:30 +0900
+Subject: [PATCH] Don't embed compiler flags for reproducible builds
+
+---
+ google/cloud/internal/build_info.cc.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/google/cloud/internal/build_info.cc.in 
b/google/cloud/internal/build_info.cc.in
+index 3251870130..d120f580de 100644
+--- a/google/cloud/internal/build_info.cc.in
++++ b/google/cloud/internal/build_info.cc.in
+@@ -30,7 +30,7 @@ std::string compiler() {
+ // NOLINTNEXTLINE(readability-identifier-naming)
+ std::string compiler_flags() {
+   static char const kCompilerFlags[] =
+-      R"""(@CMAKE_CXX_FLAGS@ 
${CMAKE_CXX_FLAGS_${GOOGLE_CLOUD_CPP_BUILD_TYPE_UPPER}})""";
++      R"""(REDACTED FOR REPRODUCIBLE BUILDS)""";
+   return kCompilerFlags;
+ }
+ 
+-- 
+2.51.0
+
diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt
index 0839cc1fa8..45cd7e8381 100644
--- a/cpp/src/arrow/CMakeLists.txt
+++ b/cpp/src/arrow/CMakeLists.txt
@@ -369,6 +369,9 @@ string(REPLACE "${CMAKE_SOURCE_DIR}" "<CMAKE_SOURCE_DIR>" 
REDACTED_CXX_FLAGS
                ${CMAKE_CXX_FLAGS})
 string(REPLACE "${CMAKE_BINARY_DIR}" "<CMAKE_BINARY_DIR>" REDACTED_CXX_FLAGS
                ${REDACTED_CXX_FLAGS})
+cmake_path(GET PROJECT_SOURCE_DIR PARENT_PATH ARROW_PROJECT_SOURCE_DIR)
+string(REPLACE "${ARROW_PROJECT_SOURCE_DIR}" "<ARROW_PROJECT_SOURCE_DIR>"
+               REDACTED_CXX_FLAGS ${REDACTED_CXX_FLAGS})
 configure_file("util/config.h.cmake" "util/config.h" ESCAPE_QUOTES)
 configure_file("util/config_internal.h.cmake" "util/config_internal.h" 
ESCAPE_QUOTES)
 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/util/config.h"
diff --git a/dev/tasks/linux-packages/apache-arrow-apt-source/Rakefile 
b/dev/tasks/linux-packages/apache-arrow-apt-source/Rakefile
index 0be9d85c28..01a1bf2141 100644
--- a/dev/tasks/linux-packages/apache-arrow-apt-source/Rakefile
+++ b/dev/tasks/linux-packages/apache-arrow-apt-source/Rakefile
@@ -36,8 +36,21 @@ class ApacheArrowAptSourcePackageTask < PackageTask
     file @archive_name do
       rm_rf(@archive_base_name)
       mkdir(@archive_base_name)
-      
download("https://www.apache.org/dyn/closer.lua?action=download&filename=arrow/KEYS";,
-               "#{@archive_base_name}/KEYS")
+
+      # Fetch KEYS in a subprocess with LD_PRELOAD stripped so any
+      # LD_PRELOAD'd libfaketime (e.g. from reprotest's time variation)
+      # doesn't fake the clock during TLS certificate verification.
+      # Clearing ENV["FAKETIME"] in this Ruby process is not enough:
+      # libfaketime parses FAKETIME once at library load and caches
+      # the offset.
+      sh({"LD_PRELOAD" => nil},
+         "curl",
+         "--silent",
+         "--show-error",
+         "--fail",
+         "--location",
+         "--output", "#{@archive_base_name}/KEYS",
+         
"https://www.apache.org/dyn/closer.lua?action=download&filename=arrow/KEYS";)
       sh("tar", "czf", @archive_name, @archive_base_name)
       rm_rf(@archive_base_name)
     end
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-bookworm/Dockerfile
 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-bookworm/Dockerfile
index f9541efdee..5251b18f59 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-bookworm/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-bookworm/Dockerfile
@@ -36,5 +36,6 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-forky/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-forky/Dockerfile
index e4bbab4a16..10295623eb 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-forky/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-forky/Dockerfile
@@ -37,5 +37,6 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-trixie/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-trixie/Dockerfile
index 1cab2169f4..e52c81360f 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-trixie/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/debian-trixie/Dockerfile
@@ -37,5 +37,6 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-jammy/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-jammy/Dockerfile
index df911b918c..f16898d312 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-jammy/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-jammy/Dockerfile
@@ -36,6 +36,7 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean && \
   rm -rf /var/lib/apt/lists/*
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-noble/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-noble/Dockerfile
index 0e37ee94bb..5af76d13e3 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-noble/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-noble/Dockerfile
@@ -36,6 +36,7 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean && \
   rm -rf /var/lib/apt/lists/*
diff --git 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-resolute/Dockerfile
 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-resolute/Dockerfile
index 3420047ee2..25f750891a 100644
--- 
a/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-resolute/Dockerfile
+++ 
b/dev/tasks/linux-packages/apache-arrow-apt-source/apt/ubuntu-resolute/Dockerfile
@@ -36,6 +36,7 @@ RUN \
     devscripts \
     fakeroot \
     gnupg \
+    libfaketime \
     lsb-release && \
   apt clean && \
   rm -rf /var/lib/apt/lists/*
diff --git a/dev/tasks/linux-packages/apache-arrow-apt-source/debian/rules 
b/dev/tasks/linux-packages/apache-arrow-apt-source/debian/rules
index 1e3be48c31..2a3c14c558 100755
--- a/dev/tasks/linux-packages/apache-arrow-apt-source/debian/rules
+++ b/dev/tasks/linux-packages/apache-arrow-apt-source/debian/rules
@@ -12,10 +12,12 @@ export DH_OPTIONS
 override_dh_auto_build:
        gpg \
          --no-default-keyring \
+         --homedir /tmp \
          --keyring ./apache-arrow-apt-source.kbx \
          --import KEYS
        gpg \
          --no-default-keyring \
+         --homedir /tmp \
          --keyring ./apache-arrow-apt-source.kbx \
          --armor \
          --export > apache-arrow-apt-source.asc
diff --git 
a/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
index ec3bf7751d..9a068b674a 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-bookworm/Dockerfile
@@ -50,6 +50,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/debian-forky/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/debian-forky/Dockerfile
index 1f05244713..1b1283895a 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-forky/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-forky/Dockerfile
@@ -51,6 +51,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/debian-trixie/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/debian-trixie/Dockerfile
index 257d005656..8f7c37f725 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/debian-trixie/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/debian-trixie/Dockerfile
@@ -39,6 +39,7 @@ RUN \
   apt install -y -V ${quiet} \
     base-files \
     build-essential \
+    ccache \
     clang \
     cmake \
     debhelper \
@@ -51,6 +52,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
index 40e1d0ab4a..20f66ee32b 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-jammy/Dockerfile
@@ -45,6 +45,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-noble/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-noble/Dockerfile
index f5f5e12f4d..5a9a55000c 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-noble/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-noble/Dockerfile
@@ -45,6 +45,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git 
a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-resolute/Dockerfile 
b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-resolute/Dockerfile
index 4df30814f7..ecee7c38e6 100644
--- a/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-resolute/Dockerfile
+++ b/dev/tasks/linux-packages/apache-arrow/apt/ubuntu-resolute/Dockerfile
@@ -45,6 +45,7 @@ RUN \
     libbz2-dev \
     libc-ares-dev \
     libcurl4-openssl-dev \
+    libfaketime \
     libgirepository1.0-dev \
     libglib2.0-doc \
     libgmock-dev \
diff --git a/dev/tasks/linux-packages/apt/build.sh 
b/dev/tasks/linux-packages/apt/build.sh
index bc4c61e622..43c7e8cc39 100755
--- a/dev/tasks/linux-packages/apt/build.sh
+++ b/dev/tasks/linux-packages/apt/build.sh
@@ -33,6 +33,22 @@ run()
 
 . /host/env.sh
 
+umask "${UMASK}"
+
+if [ -n "${CPU_LIST:-}" ]; then
+  taskset -a -c "${CPU_LIST}"
+fi
+
+if [ -n "${FAKETIME:-}" ]; then
+  lib_dir="/usr/lib/$(dpkg-architecture -q DEB_BUILD_MULTIARCH)"
+  libfaketime="${lib_dir}/faketime/libfaketime.so.1"
+  if [ ! -f "${libfaketime}" ]; then
+    echo "You must install libfaketime: ${libfaketime} doesn't exist"
+    exit 1
+  fi
+  export LD_PRELOAD="${libfaketime}"
+fi
+
 distribution=$(lsb_release --id --short | tr 'A-Z' 'a-z')
 code_name=$(lsb_release --codename --short)
 case "${distribution}" in
@@ -48,8 +64,9 @@ architecture=$(dpkg-architecture -q DEB_BUILD_ARCH)
 debuild_options=()
 dpkg_buildpackage_options=(-us -uc)
 
-run mkdir -p /build
-run cd /build
+build_root_dir="/build"
+run mkdir -p "${build_root_dir}"
+run pushd "${build_root_dir}"
 find . -not -path ./ccache -a -not -path "./ccache/*" -delete
 if which ccache > /dev/null 2>&1; then
   export CCACHE_COMPILERCHECK=content
@@ -67,6 +84,14 @@ if which ccache > /dev/null 2>&1; then
     debuild_options+=(--prepend-path=/usr/lib/ccache)
   fi
 fi
+# Temporarily use a fixed build directory name instead of mktemp's random 
suffix.
+# c_glib's meson generates pkgconfig files that bake the absolute
+# build-tree path into Libs.private, so a random suffix breaks
+# reproducibility across reprotest runs.
+# TODO: Move to a random subdirectory, see: GH-49987
+build_dir="${build_root_dir}/package"
+run mkdir -p "${build_dir}"
+run pushd "${build_dir}"
 run cp /host/tmp/${PACKAGE}-${VERSION}.tar.gz \
   ${PACKAGE}_${VERSION}.orig.tar.gz
 run tar xfz ${PACKAGE}_${VERSION}.orig.tar.gz
@@ -80,7 +105,7 @@ case "${VERSION}" in
         ${PACKAGE}-${VERSION}
     ;;
 esac
-run cd ${PACKAGE}-${VERSION}/
+run pushd ${PACKAGE}-${VERSION}/
 platform="${distribution}-${code_name}"
 if [ -d "/host/tmp/debian.${platform}-${architecture}" ]; then
   run cp -rp "/host/tmp/debian.${platform}-${architecture}" debian
@@ -102,7 +127,7 @@ df -h
 if which ccache > /dev/null 2>&1; then
   ccache --show-stats --verbose || :
 fi
-run cd -
+run popd
 
 repositories="/host/repositories"
 package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/')
@@ -116,3 +141,6 @@ run \
   -exec cp '{}' "${pool_dir}/" ';'
 
 run chown -R "$(stat --format "%u:%g" "${repositories}")" "${repositories}"
+
+run popd
+rm -rf "${build_dir}"
diff --git a/dev/tasks/linux-packages/package-task.rb 
b/dev/tasks/linux-packages/package-task.rb
index 404f0d8c78..87d7cd49ed 100644
--- a/dev/tasks/linux-packages/package-task.rb
+++ b/dev/tasks/linux-packages/package-task.rb
@@ -152,11 +152,26 @@ class PackageTask
       "DEB_BUILD_OPTIONS",
       "RPM_BUILD_NCPUS",
     ]
+    # The following environment variables carry the build variations that
+    # reprotest injects to verify reproducibility.
+    if File.basename(Dir.pwd) == apt_dir
+      pass_through_env_names += [
+        "CPU_LIST",
+        "FAKETIME",
+        "HOME",
+        "LANG",
+        "LANGUAGE",
+        "LC_ALL",
+        "NO_FAKE_STAT",
+        "TZ",
+      ]
+    end
     pass_through_env_names.each do |name|
       value = ENV[name]
       next unless value
       run_command_line.concat(["--env", "#{name}=#{value}"])
     end
+    run_command_line.concat(["--env", "UMASK=%04o" % File.umask])
     if File.exist?(File.join(id, "Dockerfile"))
       docker_context = id
     else
@@ -188,7 +203,7 @@ class PackageTask
     run_command_line << image
     run_command_line << "/host/build.sh" unless console
 
-    sh(*build_command_line)
+    sh(*build_command_line) if Dir.exist?(ENV["HOME"])
     sh(*run_command_line)
   end
 

Reply via email to