Loading README.md +8 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,14 @@ do so. Other parameters (such as which commit to use) are controlled by environment variables. See the top of `reproduce.sh`. Alternatively: ``` ./reproduce_pipeline.py ``` reproduces and validates the build from a specific run of the project pipeline. ## Status Running the script twice consecutively: Loading reproduce_pipeline.py 0 → 100755 +67 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 # Reproduces the build from a specific gitlab pipeline, # and validates checksums of the built tor binaries. import os import requests import subprocess # Project id for https://gitlab.torproject.org/tpo/core/debian/tor.git project=1218 # Current most-recent stable build. pipeline=38207 # Where we'll put our build output. build_dir=f'reproduce-{pipeline}' # Where we'll download and unpack artifacts from the original pipeline. artifact_dir=f'artifacts-{pipeline}' def build(): req = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/pipelines/{pipeline}') env = dict(os.environ) env.update({ 'OUTPUT_DIR': build_dir, 'DEBIAN_BUILD_BRANCH': req.json()['ref'], 'DEBIAN_BUILD_REV': req.json()['sha'], }) subprocess.check_call(['./reproduce.sh'], env=env) def download_artifacts(): req = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/pipelines/{pipeline}/jobs?per_page=100') jobs = filter(lambda j: j['status'] == 'success' and j['name'] == 'build_binary: [debian, bullseye, amd64, amd64, -slim]', req.json()) job = next(jobs) job_id = job['id'] artifacts = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/jobs/{job_id}/artifacts') os.mkdir(artifact_dir) f = open(f'{artifact_dir}/artifacts.zip', 'wb') f.write(artifacts.content) f.close() def unpack_artifacts(): subprocess.check_call(['unzip', 'artifacts.zip'], cwd=artifact_dir) subprocess.check_call('ar -x binary-packages/debian-amd64-bullseye/tor_*d11.bullseye+1_amd64.deb', shell=True, cwd=artifact_dir) subprocess.check_call('tar -xJvf data.tar.xz', shell=True, cwd=artifact_dir) def unpack_build(): subprocess.check_call('ar -x binary-packages/debian-amd64-bullseye/tor_*d11.bullseye+1_amd64.deb', shell=True, cwd=build_dir) subprocess.check_call('tar -xJvf data.tar.xz', shell=True, cwd=build_dir) def validate(): our_md5 = subprocess.check_output(['md5sum', f'{build_dir}/usr/bin/tor'], text=True).split()[0] artifact_md5 = subprocess.check_output(['md5sum', f'{artifact_dir}/usr/bin/tor'], text=True).split()[0] print(our_md5, f'{build_dir}/usr/bin/tor') print(artifact_md5, f'{artifact_dir}/usr/bin/tor') if __name__ == '__main__': build() unpack_build() download_artifacts() unpack_artifacts() validate() Loading
README.md +8 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,14 @@ do so. Other parameters (such as which commit to use) are controlled by environment variables. See the top of `reproduce.sh`. Alternatively: ``` ./reproduce_pipeline.py ``` reproduces and validates the build from a specific run of the project pipeline. ## Status Running the script twice consecutively: Loading
reproduce_pipeline.py 0 → 100755 +67 −0 Original line number Diff line number Diff line #!/usr/bin/env python3 # Reproduces the build from a specific gitlab pipeline, # and validates checksums of the built tor binaries. import os import requests import subprocess # Project id for https://gitlab.torproject.org/tpo/core/debian/tor.git project=1218 # Current most-recent stable build. pipeline=38207 # Where we'll put our build output. build_dir=f'reproduce-{pipeline}' # Where we'll download and unpack artifacts from the original pipeline. artifact_dir=f'artifacts-{pipeline}' def build(): req = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/pipelines/{pipeline}') env = dict(os.environ) env.update({ 'OUTPUT_DIR': build_dir, 'DEBIAN_BUILD_BRANCH': req.json()['ref'], 'DEBIAN_BUILD_REV': req.json()['sha'], }) subprocess.check_call(['./reproduce.sh'], env=env) def download_artifacts(): req = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/pipelines/{pipeline}/jobs?per_page=100') jobs = filter(lambda j: j['status'] == 'success' and j['name'] == 'build_binary: [debian, bullseye, amd64, amd64, -slim]', req.json()) job = next(jobs) job_id = job['id'] artifacts = requests.get(f'https://gitlab.torproject.org/api/v4/projects/{project}/jobs/{job_id}/artifacts') os.mkdir(artifact_dir) f = open(f'{artifact_dir}/artifacts.zip', 'wb') f.write(artifacts.content) f.close() def unpack_artifacts(): subprocess.check_call(['unzip', 'artifacts.zip'], cwd=artifact_dir) subprocess.check_call('ar -x binary-packages/debian-amd64-bullseye/tor_*d11.bullseye+1_amd64.deb', shell=True, cwd=artifact_dir) subprocess.check_call('tar -xJvf data.tar.xz', shell=True, cwd=artifact_dir) def unpack_build(): subprocess.check_call('ar -x binary-packages/debian-amd64-bullseye/tor_*d11.bullseye+1_amd64.deb', shell=True, cwd=build_dir) subprocess.check_call('tar -xJvf data.tar.xz', shell=True, cwd=build_dir) def validate(): our_md5 = subprocess.check_output(['md5sum', f'{build_dir}/usr/bin/tor'], text=True).split()[0] artifact_md5 = subprocess.check_output(['md5sum', f'{artifact_dir}/usr/bin/tor'], text=True).split()[0] print(our_md5, f'{build_dir}/usr/bin/tor') print(artifact_md5, f'{artifact_dir}/usr/bin/tor') if __name__ == '__main__': build() unpack_build() download_artifacts() unpack_artifacts() validate()