From d5b1961ad5e25fddb81fbafa417c7f5a7d5f973d Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Fri, 8 Aug 2025 12:20:25 +0200 Subject: [PATCH] Fix reproducibility issue for tarballs with symlink Bulk-removing of user and group permissions on MacOS is not a good idea for symlinks for reproducibility, because symlinks on linux cannot have other/group permissions changed but on MacOS they can even if it has no effect. Instead of bulk-change with chmod command we now change the permissions individually on all files except symlinks --- .../src/airflow_breeze/utils/reproducible.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/dev/breeze/src/airflow_breeze/utils/reproducible.py b/dev/breeze/src/airflow_breeze/utils/reproducible.py index 496f56e5e8f72..a48f6b048b8be 100644 --- a/dev/breeze/src/airflow_breeze/utils/reproducible.py +++ b/dev/breeze/src/airflow_breeze/utils/reproducible.py @@ -37,6 +37,7 @@ import locale import os import shutil +import stat import tarfile from argparse import ArgumentParser from pathlib import Path @@ -106,15 +107,6 @@ def reset(tarinfo): if result.returncode != 0: return result dest_archive.unlink(missing_ok=True) - result = run_command( - [ - "chmod", - "-R", - "go=", - REPRODUCIBLE_PATH.as_posix(), - ], - check=False, - ) with cd(REPRODUCIBLE_PATH): current_dir = "." file_list = [current_dir] @@ -133,6 +125,20 @@ def reset(tarinfo): with gzip.GzipFile(fileobj=out_file, mtime=0, mode="wb") as gzip_file: with tarfile.open(fileobj=gzip_file, mode="w:") as tar_file: for entry in file_list: + entry_path = Path(entry) + if not entry_path.is_symlink(): + # For non symlinks clear other and group permission bits, + # keep others unchanged + current_mode = entry_path.stat().st_mode + new_mode = current_mode & ~(stat.S_IRWXO | stat.S_IRWXG) + entry_path.chmod(new_mode) + else: + # for symlinks on the other hand set rwx for all - to match Linux on MacOS + try: + entry_path.chmod(0o777, follow_symlinks=False) + except NotImplementedError: + # on platforms like Linux symlink permissions cannot be changed + pass arcname = entry if prepend_path is not None: arcname = os.path.normpath(os.path.join(prepend_path, arcname))