Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 1 | # Copyright 2017 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 4 | """Module for setup environemtn for local testing & Google App Engine. |
| 5 | |
| 6 | DO NOT RUN THIS MODULE DIRECTLY. |
| 7 | |
| 8 | Use bin/setup_environment instead. |
| 9 | See [README.md]. |
| 10 | """ |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 11 | |
Xixuan Wu | 8929a30 | 2017-12-07 18:09:31 -0800 | [diff] [blame] | 12 | from __future__ import print_function |
| 13 | |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 14 | import argparse |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 15 | import collections |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 16 | import os |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 17 | import pipes |
Xixuan Wu | 30244f9 | 2019-03-21 09:49:17 -0700 | [diff] [blame] | 18 | import shutil |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 19 | import subprocess |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 20 | import sys |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 21 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 22 | _ROOT = os.path.dirname(os.path.realpath(__file__)) |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 23 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 24 | _INFRA_LIBS_PATH = os.path.join(_ROOT, 'infra_libs') |
| 25 | _REFRESH_CREDENTIALS_SCRIPT = os.path.join(_ROOT, 'bin', 'refresh_credentials') |
| 26 | _REQUIREMENTS_PATH = os.path.join(_ROOT, "requirements.txt") |
| 27 | _THIRD_PARTY_LIB_PATH = os.path.join(_ROOT, 'lib') |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 28 | |
Xinan Lin | 3ba18a0 | 2019-08-13 15:44:55 -0700 | [diff] [blame] | 29 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 30 | def _install_third_party_lib(): |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 31 | """Install useful third-party lib. |
| 32 | |
| 33 | The libraries are specified in requirement.txt. They're used in both local |
| 34 | development environment and Google App Engine, which means they will be |
| 35 | uploaded to GAE. |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 36 | """ |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 37 | if os.path.exists(_THIRD_PARTY_LIB_PATH): |
| 38 | shutil.rmtree(_THIRD_PARTY_LIB_PATH) |
| 39 | os.mkdir(_THIRD_PARTY_LIB_PATH) |
| 40 | print('Installing third party dependencies in %s' % |
| 41 | (_THIRD_PARTY_LIB_PATH, )) |
| 42 | try: |
| 43 | subprocess.check_call([ |
| 44 | sys.executable, '-m', 'pip', 'install', '-t', _THIRD_PARTY_LIB_PATH, |
| 45 | '-r', _REQUIREMENTS_PATH |
| 46 | ]) |
| 47 | except OSError: |
| 48 | print('Please check that `pip` is installed. See README.md') |
| 49 | raise |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 50 | |
| 51 | |
| 52 | # _GitDep specifies a dependency in the form of a particular reference in a git |
| 53 | # project. |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 54 | # |
| 55 | # local_name: Name of the local directory to fetch into. |
| 56 | # project: URL to the git project to fetch from. |
| 57 | # ref: Git ref to fetch. |
| 58 | # sparse_checkout_paths: A list of paths to checkout. Some of the dependencies |
| 59 | # contain too many files and AppEngine does not allow uploading > 10K files. |
| 60 | # Thus, we checkout only required sub-packages. This list is passed in to |
| 61 | # (and interpreted by) `git sparse-checkout`. |
| 62 | _GitDep = collections.namedtuple( |
| 63 | '_GitDep', 'local_name git_project git_ref sparse_checkout_paths') |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 64 | |
| 65 | # List of all git project dependencies. |
| 66 | _GIT_DEPS = [ |
| 67 | _GitDep( |
| 68 | 'chromite', |
| 69 | 'https://chromium.googlesource.com/chromiumos/chromite', |
| 70 | 'bf296fb827fe998bc174ad7e456534d4c7847ea5', |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 71 | [ |
| 72 | '/api/gen/**/*.py', '/api/__init__.py', |
| 73 | '/third_party/infra_libs/*', '/third_party/google/*', |
| 74 | '/third_party/__init__.py', '/__init__.py', '!*test.py' |
| 75 | ], |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 76 | ), |
| 77 | _GitDep( |
| 78 | 'luci', |
| 79 | 'https://chromium.googlesource.com/infra/luci/luci-py', |
| 80 | '33a910c714948a5189f9c58101ce9b131f01c1fd', |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 81 | [ |
| 82 | '/appengine/components/components/auth/**/*.py', |
| 83 | '/appengine/components/components/datastore_utils/**/*.py', |
| 84 | '/appengine/components/components/prpc/**/*.py', |
| 85 | '/appengine/components/components/*.py', '!*test.py' |
| 86 | ], |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 87 | ), |
| 88 | ] |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 89 | |
Xinan Lin | 3ba18a0 | 2019-08-13 15:44:55 -0700 | [diff] [blame] | 90 | |
Xinan Lin | 83c1a31 | 2020-04-13 23:31:47 -0700 | [diff] [blame] | 91 | def _install_infra_libs(): |
Xinan Lin | cd6d40b | 2019-08-09 15:53:43 -0700 | [diff] [blame] | 92 | """Install useful libs from Chromium infra and Chromite. |
| 93 | |
| 94 | infra_libs consists of prpc client from luci and necessary proto files from |
| 95 | Chromite. Suite scheduler relies on those libs to conduct prpc call to |
| 96 | Buildbucket. |
Xinan Lin | cd6d40b | 2019-08-09 15:53:43 -0700 | [diff] [blame] | 97 | """ |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 98 | if os.path.exists(_INFRA_LIBS_PATH): |
| 99 | shutil.rmtree(_INFRA_LIBS_PATH) |
| 100 | os.mkdir(_INFRA_LIBS_PATH) |
Xinan Lin | cd6d40b | 2019-08-09 15:53:43 -0700 | [diff] [blame] | 101 | |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 102 | for dep in _GIT_DEPS: |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 103 | dep_path = os.path.join(_INFRA_LIBS_PATH, dep.local_name) |
| 104 | print('Creating sparse checkout of %s at %s in %s' % |
| 105 | (dep.git_project, dep.git_ref, dep_path)) |
| 106 | subprocess.check_call( |
| 107 | ['git', 'clone', '--no-checkout', dep.git_project, dep.local_name], |
| 108 | cwd=_INFRA_LIBS_PATH) |
| 109 | subprocess.check_call(['git', 'sparse-checkout', 'init'], cwd=dep_path) |
| 110 | _set_sparse_checkout_paths(dep_path, dep.sparse_checkout_paths) |
Prathmesh Prabhu | 4a880bc | 2020-06-22 13:38:50 -0700 | [diff] [blame] | 111 | subprocess.check_call(['git', 'checkout', dep.git_ref], cwd=dep_path) |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 112 | |
Xinan Lin | 3ba18a0 | 2019-08-13 15:44:55 -0700 | [diff] [blame] | 113 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 114 | def _set_sparse_checkout_paths(checkout_dir, sparse_checkout_paths): |
| 115 | """Set the path patterns to checkout in a git checkout.""" |
| 116 | # Pass in path patterns via stdin to avoid shell escaping issues. |
| 117 | proc = subprocess.Popen(['git', 'sparse-checkout', 'set', '--stdin'], |
| 118 | stdin=subprocess.PIPE, |
| 119 | cwd=checkout_dir) |
| 120 | proc.communicate(input='\n'.join(sparse_checkout_paths)) |
| 121 | if proc.poll() is None: |
| 122 | raise Exception('Leaked process when setting sparse checkout paths') |
| 123 | if proc.poll() != 0: |
| 124 | raise Exception('Failed to set sparse checkout paths') |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 125 | |
| 126 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 127 | def _load_credentials(): |
| 128 | subprocess.check_call([_REFRESH_CREDENTIALS_SCRIPT]) |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 129 | |
| 130 | |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 131 | def main(): |
| 132 | """Entry point of the script""" |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 133 | parser = argparse.ArgumentParser( |
| 134 | description=__doc__, |
| 135 | formatter_class=argparse.RawDescriptionHelpFormatter) |
| 136 | parser.add_argument( |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 137 | '--load-creds', |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 138 | action='store_true', |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 139 | help='Also install credentials needed for releasing suite ' |
| 140 | 'scheduler. Not needed to modify config/*') |
| 141 | |
| 142 | args = parser.parse_args() |
| 143 | _install_third_party_lib() |
| 144 | _install_infra_libs() |
| 145 | if args.load_creds: |
| 146 | _load_credentials() |
Xixuan Wu | 26d06e0 | 2017-09-20 14:50:28 -0700 | [diff] [blame] | 147 | |
| 148 | |
| 149 | if __name__ == '__main__': |
Prathmesh Prabhu | 8dff3e2 | 2020-06-23 13:49:45 -0700 | [diff] [blame] | 150 | main() |