Created
September 9, 2015 10:41
-
-
Save dexX7/4fed3b3e1177097110c5 to your computer and use it in GitHub Desktop.
Python script to verify Gitian build results
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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