1#!/usr/bin/env python3
2# Copyright (C) 2019 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16# This file should do the same thing when being invoked in any of these ways:
17# ./trace_processor
18# python trace_processor
19# bash trace_processor
20# cat ./trace_processor | bash
21# cat ./trace_processor | python -
22
23BASH_FALLBACK = """ "
24exec python3 - "$@" <<'#'EOF
25#"""
26
27import hashlib
28import os
29import sys
30import tempfile
31import subprocess
32import platform
33
34TRACE_PROCESSOR_SHELL_SHAS = {
35    'linux': 'a3ce2cbf4cbe4f86cc10b02957db727cecfafae8',
36    'mac': 'c39a5be9a3831911ef2e50d66d11c12d877688f3',
37}
38TRACE_PROCESSOR_SHELL_PATH = tempfile.gettempdir()
39TRACE_PROCESSOR_SHELL_BASE_URL = ('https://storage.googleapis.com/perfetto/')
40
41
42def DownloadURL(url, out_file):
43  subprocess.check_call(['curl', '-L', '-#', '-o', out_file, url])
44
45
46def check_hash(file_name, sha_value):
47  with open(file_name, 'rb') as fd:
48    file_hash = hashlib.sha1(fd.read()).hexdigest()
49    return file_hash == sha_value
50
51
52def load_trace_processor_shell(platform):
53  sha_value = TRACE_PROCESSOR_SHELL_SHAS[platform]
54  file_name = 'trace_processor_shell-' + platform + '-' + sha_value
55  local_file = os.path.join(TRACE_PROCESSOR_SHELL_PATH, file_name)
56
57  if os.path.exists(local_file):
58    if not check_hash(local_file, sha_value):
59      os.remove(local_file)
60    else:
61      return local_file
62
63  url = TRACE_PROCESSOR_SHELL_BASE_URL + file_name
64  DownloadURL(url, local_file)
65  if not check_hash(local_file, sha_value):
66    os.remove(local_file)
67    raise ValueError("Invalid signature.")
68  os.chmod(local_file, 0o755)
69  return local_file
70
71
72def main(argv):
73  os_name = None
74  if sys.platform.startswith('linux'):
75    os_name = 'linux'
76  elif sys.platform.startswith('darwin'):
77    os_name = 'mac'
78  else:
79    print("Invalid platform: {}".format(sys.platform))
80    return 1
81
82  arch = platform.machine()
83  if arch not in ['x86_64', 'amd64']:
84    print("Prebuilts are only available for x86_64 (found '{}' instead).".format(arch))
85    print("Follow https://perfetto.dev/docs/contributing/build-instructions to build locally.")
86    return 1
87
88  trace_processor_shell_binary = load_trace_processor_shell(os_name)
89  os.execv(trace_processor_shell_binary,
90           [trace_processor_shell_binary] + argv[1:])
91
92
93if __name__ == '__main__':
94  sys.exit(main(sys.argv))
95
96#EOF
97