Skip to content

Instantly share code, notes, and snippets.

@dexX7
Created September 9, 2015 10:41
Show Gist options
  • Save dexX7/4fed3b3e1177097110c5 to your computer and use it in GitHub Desktop.
Save dexX7/4fed3b3e1177097110c5 to your computer and use it in GitHub Desktop.
Python script to verify Gitian build results
#!/usr/bin/env python
import glob
import os
import subprocess
import sys
import yaml
yaml.add_constructor('!omap',
yaml.constructor.SafeConstructor.construct_yaml_omap)
def get_build_descriptions(path):
return glob.glob(path + '/*/*/*.assert')
def get_gitian_descriptors(path):
return glob.glob(path + '/contrib/gitian-descriptors/*.y*ml')
def extract_value(description, key):
for kv in description:
if len(kv) < 2:
continue
if kv[0] == key:
return kv[1]
raise AssertionError('%s not found in description' % key)
def extract_commit(description):
manifest = extract_value(description, 'in_manifest')
for line in manifest.splitlines():
if line.startswith('git:'):
return line[4:44]
raise AssertionError('git commit not found in description')
def find_build_descriptions(results_path):
descriptions = []
for path in get_build_descriptions(results_path):
with open(path, 'r') as stream:
description = yaml.load(stream)
result = {
'commit': extract_commit(description),
'name': extract_value(description, 'name'),
'release': extract_value(description, 'release'),
}
descriptions.append(result)
return descriptions
def find_gitian_descriptors(project_path):
descriptors = {}
for path in get_gitian_descriptors(project_path):
with open(path, 'r') as stream:
descriptor = yaml.load(stream)
assert ('name' in descriptor)
descriptors[descriptor['name']] = path
return descriptors
def get_gitian_results(results_path, project_path):
results = []
descriptors = find_gitian_descriptors(project_path)
for description in find_build_descriptions(results_path):
assert ('name' in description)
assert (description['name'] in descriptors)
result = description
result['path'] = descriptors[description['name']]
results.append(result)
return results
def git_checkout_commit(commit, project_path):
initial_working_dir = os.getcwd()
os.chdir(project_path)
subprocess.check_call(['git', 'checkout', commit])
os.chdir(initial_working_dir)
def check_result(result, gverify, destination, project_path):
print('######################################################')
print('# name: ' + result['name'])
print('# release: ' + result['release'])
print('# commit: ' + result['commit'])
print('######################################################')
# this can throw
git_checkout_commit(result['commit'], project_path)
descriptors = find_gitian_descriptors(project_path)
result['path'] = descriptors[result['name']]
subprocess.check_call([gverify, '--verbose', '--destination', destination,
'--release', result['release'], result['path']])
def check_all_results(gverify, results_path, project_path):
for result in find_build_descriptions(results_path):
check_result(result, gverify, results_path, project_path)
def show_help():
print("gveryify_all \"gverifybin\" \"resultpath\" \"projectpath\"\n")
print("Verifies all Gitian build results and GPG signatures.")
print("Note: this checks out specific commits of the project, which may")
print("result in a different state than before program execution!\n")
print("gpg and git are required, and the GPG keys of all signers must be")
print("available.\n")
print("Arguments:\n")
print("1. \"gverifybin\" path to gverify binary")
print("2. \"resultpath\" path to Gitian build results (e.g. gitian.sigs)")
print("3. \"projectpath\" path to project root (e.g. Omni Core)\n")
print("Example:")
print("gveryify_all ~/gitian-builder/bin/gverify ~/gitian.sigs ~/omnicore")
exit()
def main():
if len(sys.argv) != 4:
show_help()
check_all_results(sys.argv[1], sys.argv[2], sys.argv[3])
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment