Verified Commit 62d40036 authored by Jim Newsome's avatar Jim Newsome
Browse files

Add reproduce_pipeline.py

parent 458a2754
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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:

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()