xref: /aosp_15_r20/prebuilts/sdk/update_prebuilts/buildserver.py (revision 344a7f5ef16c479e7a7f54ee6567a9d112f9e72b)
1#!/usr/bin/python3
2
3import os
4import subprocess
5import zipfile
6
7from utils import print_e, mv
8
9# See go/fetch_artifact for details on this script.
10FETCH_ARTIFACT = '/google/data/ro/projects/android/fetch_artifact'
11FETCH_ARTIFACT_BEYOND_CORP = '/usr/bin/fetch_artifact'
12
13
14class BuildId(object):
15    def __init__(self, url_id, fs_id):
16        # id when used in build server urls
17        self.url_id = url_id
18        # id when used in build commands
19        self.fs_id = fs_id
20
21
22def fetch_artifact(target, build_id, artifact_path, beyond_corp):
23    download_to = os.path.join('.', os.path.dirname(artifact_path))
24    print(f'Fetching {artifact_path} from {target}...')
25    if not os.path.exists(download_to):
26        os.makedirs(download_to)
27    if beyond_corp:
28        fetch_cmd = [FETCH_ARTIFACT_BEYOND_CORP, '--use_oauth2',
29                     '--bid', str(build_id), '--target', target, artifact_path, download_to]
30    else:
31        fetch_cmd = [FETCH_ARTIFACT,
32                     '--bid', str(build_id), '--target', target, artifact_path, download_to]
33    print('Running: ' + ' '.join(fetch_cmd))
34    try:
35        subprocess.check_output(fetch_cmd, stderr=subprocess.STDOUT)
36    except subprocess.CalledProcessError:
37        print_e(f'FAIL: Unable to retrieve {artifact_path} artifact for build ID {build_id}')
38        print_e('Please make sure you are authenticated for build server access!')
39        return None
40    return artifact_path
41
42
43def fetch_artifacts(target, build_id, artifact_dict, beyond_corp):
44    for artifact, target_path in artifact_dict.items():
45        artifact_path = fetch_artifact(target, build_id.url_id, artifact, beyond_corp)
46        if not artifact_path:
47            return False
48        mv(artifact_path, target_path)
49    return True
50
51
52def extract_artifact(artifact_path):
53    # Unzip the repo archive into a separate directory.
54    repo_dir = os.path.splitext(artifact_path)[0]
55    with zipfile.ZipFile(artifact_path) as zipFile:
56        zipFile.extractall(repo_dir)
57    return repo_dir
58
59
60def fetch_and_extract(target, build_id, file, beyond_corp, artifact_path=None):
61    if not artifact_path:
62        artifact_path = fetch_artifact(target, build_id, file, beyond_corp)
63    if not artifact_path:
64        return None
65    return extract_artifact(artifact_path)
66
67
68def parse_build_id(source):
69    # must be in the format 12345 or P12345
70    number_text = source
71    presubmit = False
72    if number_text.startswith('P'):
73        presubmit = True
74        number_text = number_text[1:]
75    if not number_text.isnumeric():
76        return None
77    url_id = source
78    fs_id = url_id
79    if presubmit:
80        fs_id = '0'
81    return BuildId(url_id, fs_id)
82