Skip to content

Commit e3ec3f7

Browse files
committed
linux: write tar files deterministically
Oh, I wish Docker would do this by default then all we'd need to do is set mtimes inside the containers. But alas it doesn't. This should make it a bit easier to compare built binaries.
1 parent f7b5195 commit e3ec3f7

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

cpython-linux/build.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import contextlib
88
import io
99
import json
10+
import operator
1011
import os
1112
import pathlib
1213
import sys
@@ -173,6 +174,30 @@ def container_exec(container, command, user='build',
173174
command))
174175

175176

177+
# 2019-01-01T00:00:00
178+
DEFAULT_MTIME = 1546329600
179+
180+
181+
def container_get_archive(container, path):
182+
"""Get a deterministic tar archive from a container."""
183+
data, stat = container.get_archive(path)
184+
old_data = io.BytesIO()
185+
for chunk in data:
186+
old_data.write(chunk)
187+
188+
old_data.seek(0)
189+
190+
new_data = io.BytesIO()
191+
192+
with tarfile.open(fileobj=old_data) as itf, tarfile.open(fileobj=new_data, mode='w') as otf:
193+
for member in sorted(itf.getmembers(), key=operator.attrgetter('name')):
194+
file_data = itf.extractfile(member) if not member.linkname else None
195+
member.mtime = DEFAULT_MTIME
196+
otf.addfile(member, file_data)
197+
198+
return new_data.getvalue()
199+
200+
176201
def install_tools_archive(container, source: pathlib.Path):
177202
copy_file_to_container(source, container, '/build')
178203
container_exec(
@@ -208,11 +233,10 @@ def copy_rust(container):
208233

209234
def download_tools_archive(container, dest, name):
210235
log('copying container files to %s' % dest)
211-
data, stat = container.get_archive('/build/out/tools/%s' % name)
236+
data = container_get_archive(container, '/build/out/tools/%s' % name)
212237

213238
with open(dest, 'wb') as fh:
214-
for chunk in data:
215-
fh.write(chunk)
239+
fh.write(data)
216240

217241

218242
def add_target_env(env, platform):
@@ -784,11 +808,10 @@ def build_cpython(client, image, platform, debug=False, optimized=False, musl=Fa
784808
basename += '.tar'
785809

786810
dest_path = BUILD / basename
787-
data, stat = container.get_archive('/build/out/python')
811+
data = container_get_archive(container, '/build/out/python')
788812

789813
with dest_path.open('wb') as fh:
790-
for chunk in data:
791-
fh.write(chunk)
814+
fh.write(data)
792815

793816

794817
def main():

0 commit comments

Comments
 (0)