|
7 | 7 | import contextlib
|
8 | 8 | import io
|
9 | 9 | import json
|
| 10 | +import operator |
10 | 11 | import os
|
11 | 12 | import pathlib
|
12 | 13 | import sys
|
@@ -173,6 +174,30 @@ def container_exec(container, command, user='build',
|
173 | 174 | command))
|
174 | 175 |
|
175 | 176 |
|
| 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 | + |
176 | 201 | def install_tools_archive(container, source: pathlib.Path):
|
177 | 202 | copy_file_to_container(source, container, '/build')
|
178 | 203 | container_exec(
|
@@ -208,11 +233,10 @@ def copy_rust(container):
|
208 | 233 |
|
209 | 234 | def download_tools_archive(container, dest, name):
|
210 | 235 | 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) |
212 | 237 |
|
213 | 238 | with open(dest, 'wb') as fh:
|
214 |
| - for chunk in data: |
215 |
| - fh.write(chunk) |
| 239 | + fh.write(data) |
216 | 240 |
|
217 | 241 |
|
218 | 242 | def add_target_env(env, platform):
|
@@ -784,11 +808,10 @@ def build_cpython(client, image, platform, debug=False, optimized=False, musl=Fa
|
784 | 808 | basename += '.tar'
|
785 | 809 |
|
786 | 810 | dest_path = BUILD / basename
|
787 |
| - data, stat = container.get_archive('/build/out/python') |
| 811 | + data = container_get_archive(container, '/build/out/python') |
788 | 812 |
|
789 | 813 | with dest_path.open('wb') as fh:
|
790 |
| - for chunk in data: |
791 |
| - fh.write(chunk) |
| 814 | + fh.write(data) |
792 | 815 |
|
793 | 816 |
|
794 | 817 | def main():
|
|
0 commit comments