xref: /aosp_15_r20/external/perfetto/tools/roll-prebuilts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker#
4*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker#
8*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker#
10*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker"""Updates the python scripts in python/perfetto/prebuilts/manifests
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard WorkerThis script does the following, for each entry in MANIFESTS_TO_UPDATE:
18*6dbdd20aSAndroid Build Coastguard Worker  - Downloads the artifact by the LUCI infrastructure, one for each arch.
19*6dbdd20aSAndroid Build Coastguard Worker  - Computes the SHA-256 of each artifact.
20*6dbdd20aSAndroid Build Coastguard Worker  - Generates a manifest with URL, SHA-256 and other details.
21*6dbdd20aSAndroid Build Coastguard Worker  - Merges get_perfetto_prebuilt.py with the manifest and writes tools/xxx.
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard WorkerThis script is supposed to be run by Perfetto OWNERS after every monthly release
24*6dbdd20aSAndroid Build Coastguard Workerafter the LUCI jobs have completed.
25*6dbdd20aSAndroid Build Coastguard Worker"""
26*6dbdd20aSAndroid Build Coastguard Worker
27*6dbdd20aSAndroid Build Coastguard Workerimport argparse
28*6dbdd20aSAndroid Build Coastguard Workerimport hashlib
29*6dbdd20aSAndroid Build Coastguard Workerimport logging
30*6dbdd20aSAndroid Build Coastguard Workerimport os
31*6dbdd20aSAndroid Build Coastguard Workerimport subprocess
32*6dbdd20aSAndroid Build Coastguard Workerimport sys
33*6dbdd20aSAndroid Build Coastguard Worker
34*6dbdd20aSAndroid Build Coastguard Workerfrom concurrent.futures import ThreadPoolExecutor
35*6dbdd20aSAndroid Build Coastguard Worker
36*6dbdd20aSAndroid Build Coastguard WorkerGCS_URL = 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts'
37*6dbdd20aSAndroid Build Coastguard Worker
38*6dbdd20aSAndroid Build Coastguard WorkerROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
39*6dbdd20aSAndroid Build Coastguard WorkerMANIFESTS_DIR = os.path.join(ROOT_DIR, 'python/perfetto/prebuilts/manifests')
40*6dbdd20aSAndroid Build Coastguard Worker
41*6dbdd20aSAndroid Build Coastguard WorkerUNIX_ARCHS = [
42*6dbdd20aSAndroid Build Coastguard Worker    'mac-amd64',
43*6dbdd20aSAndroid Build Coastguard Worker    'mac-arm64',
44*6dbdd20aSAndroid Build Coastguard Worker    'linux-amd64',
45*6dbdd20aSAndroid Build Coastguard Worker    'linux-arm',
46*6dbdd20aSAndroid Build Coastguard Worker    'linux-arm64',
47*6dbdd20aSAndroid Build Coastguard Worker    'android-arm',
48*6dbdd20aSAndroid Build Coastguard Worker    'android-arm64',
49*6dbdd20aSAndroid Build Coastguard Worker    'android-x86',
50*6dbdd20aSAndroid Build Coastguard Worker    'android-x64',
51*6dbdd20aSAndroid Build Coastguard Worker]
52*6dbdd20aSAndroid Build Coastguard WorkerALL_ARCHS = UNIX_ARCHS + ['windows-amd64']
53*6dbdd20aSAndroid Build Coastguard Worker
54*6dbdd20aSAndroid Build Coastguard WorkerMANIFESTS_TO_UPDATE = [
55*6dbdd20aSAndroid Build Coastguard Worker    {
56*6dbdd20aSAndroid Build Coastguard Worker        'tool': 'trace_processor_shell',
57*6dbdd20aSAndroid Build Coastguard Worker        'archs': ALL_ARCHS
58*6dbdd20aSAndroid Build Coastguard Worker    },
59*6dbdd20aSAndroid Build Coastguard Worker    {
60*6dbdd20aSAndroid Build Coastguard Worker        'tool': 'traceconv',
61*6dbdd20aSAndroid Build Coastguard Worker        'archs': ALL_ARCHS
62*6dbdd20aSAndroid Build Coastguard Worker    },
63*6dbdd20aSAndroid Build Coastguard Worker    {
64*6dbdd20aSAndroid Build Coastguard Worker        'tool': 'tracebox',
65*6dbdd20aSAndroid Build Coastguard Worker        'archs': UNIX_ARCHS
66*6dbdd20aSAndroid Build Coastguard Worker    },
67*6dbdd20aSAndroid Build Coastguard Worker]
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker# Maps a 'os-arch' string (were arch follows LUCI conventions) into
70*6dbdd20aSAndroid Build Coastguard Worker# corresponding tuples that match against python's platform / machine API
71*6dbdd20aSAndroid Build Coastguard Worker# (see get_perfetto_prebuilt.py for usage).
72*6dbdd20aSAndroid Build Coastguard WorkerARCH_TO_PYTHON = {
73*6dbdd20aSAndroid Build Coastguard Worker    'mac-amd64': {
74*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'darwin',
75*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['x86_64'],
76*6dbdd20aSAndroid Build Coastguard Worker    },
77*6dbdd20aSAndroid Build Coastguard Worker    'mac-arm64': {
78*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'darwin',
79*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['arm64'],
80*6dbdd20aSAndroid Build Coastguard Worker    },
81*6dbdd20aSAndroid Build Coastguard Worker    'windows-amd64': {
82*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'win32',
83*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['amd64'],
84*6dbdd20aSAndroid Build Coastguard Worker    },
85*6dbdd20aSAndroid Build Coastguard Worker    'linux-amd64': {
86*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'linux',
87*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['x86_64'],
88*6dbdd20aSAndroid Build Coastguard Worker    },
89*6dbdd20aSAndroid Build Coastguard Worker    'linux-arm': {
90*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'linux',
91*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['armv6l', 'armv7l', 'armv8l'],
92*6dbdd20aSAndroid Build Coastguard Worker    },
93*6dbdd20aSAndroid Build Coastguard Worker    'linux-arm64': {
94*6dbdd20aSAndroid Build Coastguard Worker        'platform': 'linux',
95*6dbdd20aSAndroid Build Coastguard Worker        'machine': ['aarch64'],
96*6dbdd20aSAndroid Build Coastguard Worker    },
97*6dbdd20aSAndroid Build Coastguard Worker}
98*6dbdd20aSAndroid Build Coastguard Worker
99*6dbdd20aSAndroid Build Coastguard Worker
100*6dbdd20aSAndroid Build Coastguard Workerdef make_manifest(git_revision, tool, arch):
101*6dbdd20aSAndroid Build Coastguard Worker  ext = '.exe' if arch.startswith('windows') else ''
102*6dbdd20aSAndroid Build Coastguard Worker  file_name = tool + ext
103*6dbdd20aSAndroid Build Coastguard Worker  url = '%s/%s/%s/%s' % (GCS_URL, git_revision, arch, file_name)
104*6dbdd20aSAndroid Build Coastguard Worker  logging.info('Downloading %s', url)
105*6dbdd20aSAndroid Build Coastguard Worker  data = subprocess.check_output(['curl', '-fsL', '-o', '-', url])
106*6dbdd20aSAndroid Build Coastguard Worker  manifest = {
107*6dbdd20aSAndroid Build Coastguard Worker      'arch': arch,
108*6dbdd20aSAndroid Build Coastguard Worker      'file_name': file_name,
109*6dbdd20aSAndroid Build Coastguard Worker      'file_size': len(data),
110*6dbdd20aSAndroid Build Coastguard Worker      'url': url,
111*6dbdd20aSAndroid Build Coastguard Worker      'sha256': hashlib.sha256(data).hexdigest()
112*6dbdd20aSAndroid Build Coastguard Worker  }
113*6dbdd20aSAndroid Build Coastguard Worker  manifest.update(ARCH_TO_PYTHON.get(arch, {}))
114*6dbdd20aSAndroid Build Coastguard Worker  return manifest
115*6dbdd20aSAndroid Build Coastguard Worker
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Workerdef update_manifest(git_revision, tool_name, archs):
118*6dbdd20aSAndroid Build Coastguard Worker  with ThreadPoolExecutor(max_workers=8) as executor:
119*6dbdd20aSAndroid Build Coastguard Worker    manifests = list(
120*6dbdd20aSAndroid Build Coastguard Worker        executor.map(lambda arch: make_manifest(git_revision, tool_name, arch),
121*6dbdd20aSAndroid Build Coastguard Worker                     archs))
122*6dbdd20aSAndroid Build Coastguard Worker  out_file = os.path.join(MANIFESTS_DIR, tool_name + '.py')
123*6dbdd20aSAndroid Build Coastguard Worker
124*6dbdd20aSAndroid Build Coastguard Worker  content = '# This file has been generated by: {script} {git_revision}\n'
125*6dbdd20aSAndroid Build Coastguard Worker  content += '{tool_uppercase}_MANIFEST = {manifests}\n'
126*6dbdd20aSAndroid Build Coastguard Worker  content = content.format(
127*6dbdd20aSAndroid Build Coastguard Worker      script=os.path.relpath(__file__),
128*6dbdd20aSAndroid Build Coastguard Worker      tool_uppercase=tool_name.upper(),
129*6dbdd20aSAndroid Build Coastguard Worker      git_revision=git_revision,
130*6dbdd20aSAndroid Build Coastguard Worker      manifests=str(manifests))
131*6dbdd20aSAndroid Build Coastguard Worker
132*6dbdd20aSAndroid Build Coastguard Worker  with open(out_file + '.tmp', 'w') as f:
133*6dbdd20aSAndroid Build Coastguard Worker    f.write(content)
134*6dbdd20aSAndroid Build Coastguard Worker  subprocess.check_call(['yapf', '-i', out_file + '.tmp'])
135*6dbdd20aSAndroid Build Coastguard Worker  os.rename(out_file + '.tmp', out_file)
136*6dbdd20aSAndroid Build Coastguard Worker  os.chmod(out_file, 0o755)
137*6dbdd20aSAndroid Build Coastguard Worker
138*6dbdd20aSAndroid Build Coastguard Worker
139*6dbdd20aSAndroid Build Coastguard Workerdef main():
140*6dbdd20aSAndroid Build Coastguard Worker  usage = '%s v20.0 | 0a1b2c3d\n\n' % __file__
141*6dbdd20aSAndroid Build Coastguard Worker  usage += 'To list available revisions run\n'
142*6dbdd20aSAndroid Build Coastguard Worker  usage += 'gsutil ls gs://perfetto-luci-artifacts/\n'
143*6dbdd20aSAndroid Build Coastguard Worker  usage += 'or visit https://chrome-infra-packages.appspot.com/p/perfetto\n'
144*6dbdd20aSAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(usage=usage)
145*6dbdd20aSAndroid Build Coastguard Worker  parser.add_argument('version')
146*6dbdd20aSAndroid Build Coastguard Worker  args = parser.parse_args()
147*6dbdd20aSAndroid Build Coastguard Worker
148*6dbdd20aSAndroid Build Coastguard Worker  git_revision = args.version
149*6dbdd20aSAndroid Build Coastguard Worker  for spec in MANIFESTS_TO_UPDATE:
150*6dbdd20aSAndroid Build Coastguard Worker    logging.info('Updating %s', spec['tool'])
151*6dbdd20aSAndroid Build Coastguard Worker    update_manifest(git_revision, spec['tool'], spec['archs'])
152*6dbdd20aSAndroid Build Coastguard Worker
153*6dbdd20aSAndroid Build Coastguard Worker
154*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__':
155*6dbdd20aSAndroid Build Coastguard Worker  logging.basicConfig(level=logging.INFO)
156*6dbdd20aSAndroid Build Coastguard Worker  sys.exit(main())
157