• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# Copyright 2022 The Chromium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Check out the Fuchsia SDK from a given GCS path. Should be used in a
6'hooks_os' entry so that it only runs when .gclient's custom_vars includes
7'fuchsia'."""
8
9import argparse
10import json
11import logging
12import os
13import platform
14import subprocess
15import sys
16from typing import Optional
17
18from gcs_download import DownloadAndUnpackFromCloudStorage
19
20sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),
21                                             'test')))
22
23from common import SDK_ROOT, get_host_os, make_clean_directory
24
25_VERSION_FILE = os.path.join(SDK_ROOT, 'meta', 'manifest.json')
26
27
28def _GetHostArch():
29  host_arch = platform.machine()
30  # platform.machine() returns AMD64 on 64-bit Windows.
31  if host_arch in ['x86_64', 'AMD64']:
32    return 'amd64'
33  elif host_arch == 'aarch64':
34    return 'arm64'
35  raise Exception('Unsupported host architecture: %s' % host_arch)
36
37
38def GetSDKOverrideGCSPath(path: Optional[str] = None) -> Optional[str]:
39  """Fetches the sdk override path from a file.
40
41  Args:
42    path: the full file path to read the data from.
43      defaults to sdk_override.txt in the directory of this file.
44
45  Returns:
46    The contents of the file, stripped of white space.
47      Example: gs://fuchsia-artifacts/development/some-id/sdk
48  """
49  if not path:
50    path = os.path.join(os.path.dirname(__file__), 'sdk_override.txt')
51
52  if not os.path.isfile(path):
53    return None
54
55  with open(path, 'r') as f:
56    return f.read().strip()
57
58
59def _GetTarballPath(gcs_tarball_prefix: str) -> str:
60  """Get the full path to the sdk tarball on GCS"""
61  platform = get_host_os()
62  arch = _GetHostArch()
63  return f'{gcs_tarball_prefix}/{platform}-{arch}/core.tar.gz'
64
65
66def main():
67  parser = argparse.ArgumentParser()
68  parser.add_argument('--cipd-prefix', help='CIPD base directory for the SDK.')
69  parser.add_argument('--version', help='Specifies the SDK version.')
70  parser.add_argument('--verbose',
71                      '-v',
72                      action='store_true',
73                      help='Enable debug-level logging.')
74  args = parser.parse_args()
75
76  logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
77
78  # Exit if there's no SDK support for this platform.
79  try:
80    host_plat = get_host_os()
81  except:
82    logging.warning('Fuchsia SDK is not supported on this platform.')
83    return 0
84
85  gcs_tarball_prefix = GetSDKOverrideGCSPath()
86  new_version = gcs_tarball_prefix if gcs_tarball_prefix else args.version
87  curr_version = None
88  if os.path.exists(_VERSION_FILE):
89    with open(_VERSION_FILE) as f:
90      curr_version = json.load(f)['id']
91
92  if new_version == curr_version:
93    return
94  make_clean_directory(SDK_ROOT)
95
96  # Download from CIPD if there is no override file.
97  if not gcs_tarball_prefix:
98    if not args.cipd_prefix:
99      parser.exit(1, '--cipd-prefix must be specified.')
100    if not args.version:
101      parser.exit(2, '--version must be specified.')
102    logging.info('Downloading SDK from CIPD...')
103    ensure_file = '%s%s-%s %s' % (args.cipd_prefix, host_plat, _GetHostArch(),
104                                  args.version)
105    subprocess.run(('cipd', 'ensure', '-ensure-file', '-', '-root', SDK_ROOT,
106                    '-log-level', 'warning'),
107                   check=True,
108                   text=True,
109                   input=ensure_file)
110  else:
111    logging.info('Downloading SDK from GCS...')
112    DownloadAndUnpackFromCloudStorage(_GetTarballPath(gcs_tarball_prefix),
113                                      SDK_ROOT)
114
115  # Build rules (e.g. fidl_library()) depend on updates to the top-level
116  # manifest to spot when to rebuild for an SDK update. Ensure that ninja
117  # sees that the SDK manifest has changed, regardless of the mtime set by
118  # the download & unpack steps above, by setting mtime to now.
119  # See crbug.com/1457463
120  os.utime(os.path.join(SDK_ROOT, 'meta', 'manifest.json'), None)
121
122  root_dir = os.path.dirname(os.path.realpath(__file__))
123  build_def_cmd = [
124      os.path.join(root_dir, 'gen_build_defs.py'),
125  ]
126  subprocess.run(build_def_cmd, check=True)
127
128  return 0
129
130
131if __name__ == '__main__':
132  sys.exit(main())
133