#!/usr/bin/env python # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # This script uploads a symbol zip file passed on the commandline # to the Socorro symbol upload API hosted on crash-stats.mozilla.org. # # Using this script requires you to have generated an authentication # token in the crash-stats web interface. You must put the token in a file # and set SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE to the path to the file in # the mozconfig you're using. from __future__ import print_function import os import redo import requests import sys try: from buildconfig import substs except ImportError: # Allow standalone use of this script, for use in TaskCluster from os import environ as substs url = 'https://symbols.mozilla.org/upload/' # Allow overwriting of the upload url with an environmental variable if 'SOCORRO_SYMBOL_UPLOAD_URL' in os.environ: url = os.environ['SOCORRO_SYMBOL_UPLOAD_URL'] MAX_RETRIES = 5 def print_error(r): if r.status_code < 400: print('Error: bad auth token? ({0}: {1})'.format(r.status_code, r.reason), file=sys.stderr) else: print('Error: got HTTP response {0}: {1}'.format(r.status_code, r.reason), file=sys.stderr) print('Response body:\n{sep}\n{body}\n{sep}\n'.format( sep='=' * 20, body=r.text )) def main(): if len(sys.argv) != 2: print('Usage: uploadsymbols.py ', file=sys.stderr) return 1 if not os.path.isfile(sys.argv[1]): print('Error: zip file "{0}" does not exist!'.format(sys.argv[1]), file=sys.stderr) return 1 symbols_zip = sys.argv[1] if 'SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE' not in substs: print('Error: you must set SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE in your mozconfig!', file=sys.stderr) return 1 token_file = substs['SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE'] if not os.path.isfile(token_file): print('Error: SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE "{0}" does not exist!'.format(token_file), file=sys.stderr) return 1 auth_token = open(token_file, 'r').read().strip() print('Uploading symbol file "{0}" to "{1}"'.format(sys.argv[1], url)) for i, _ in enumerate(redo.retrier(attempts=MAX_RETRIES), start=1): print('Attempt %d of %d...' % (i, MAX_RETRIES)) try: r = requests.post( url, files={'symbols.zip': open(sys.argv[1], 'rb')}, headers={'Auth-Token': auth_token}, allow_redirects=False, timeout=120) # 500 is likely to be a transient failure. # Break out for success or other error codes. if r.status_code < 500: break print_error(r) except requests.exceptions.RequestException as e: print('Error: {0}'.format(e)) print('Retrying...') else: print('Maximum retries hit, giving up!') return 1 if r.status_code >= 200 and r.status_code < 300: print('Uploaded successfully!') return 0 print_error(r) return 1 if __name__ == '__main__': sys.exit(main())