blob: d003f4f1a397b5c3eb1d698a84f7c320dd3a373e [file] [log] [blame]
Xixuan Wu26d06e02017-09-20 14:50:28 -07001# 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 Prabhu8dff3e22020-06-23 13:49:45 -07004"""Module for setup environemtn for local testing & Google App Engine.
5
6DO NOT RUN THIS MODULE DIRECTLY.
7
8Use bin/setup_environment instead.
9See [README.md].
10"""
Xixuan Wu26d06e02017-09-20 14:50:28 -070011
Xixuan Wu8929a302017-12-07 18:09:31 -080012from __future__ import print_function
13
Xixuan Wu26d06e02017-09-20 14:50:28 -070014import argparse
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -070015import collections
Xixuan Wu26d06e02017-09-20 14:50:28 -070016import os
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070017import pipes
Xixuan Wu30244f92019-03-21 09:49:17 -070018import shutil
Xixuan Wu26d06e02017-09-20 14:50:28 -070019import subprocess
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070020import sys
Xixuan Wu26d06e02017-09-20 14:50:28 -070021
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070022_ROOT = os.path.dirname(os.path.realpath(__file__))
Xixuan Wu26d06e02017-09-20 14:50:28 -070023
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070024_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 Wu26d06e02017-09-20 14:50:28 -070028
Xinan Lin3ba18a02019-08-13 15:44:55 -070029
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070030def _install_third_party_lib():
Xixuan Wu26d06e02017-09-20 14:50:28 -070031 """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 Wu26d06e02017-09-20 14:50:28 -070036 """
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070037 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 Prabhu4a880bc2020-06-22 13:38:50 -070050
51
52# _GitDep specifies a dependency in the form of a particular reference in a git
53# project.
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070054#
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 Prabhu4a880bc2020-06-22 13:38:50 -070064
65# List of all git project dependencies.
66_GIT_DEPS = [
67 _GitDep(
68 'chromite',
69 'https://chromium.googlesource.com/chromiumos/chromite',
70 'bf296fb827fe998bc174ad7e456534d4c7847ea5',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070071 [
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 Prabhu4a880bc2020-06-22 13:38:50 -070076 ),
77 _GitDep(
78 'luci',
79 'https://chromium.googlesource.com/infra/luci/luci-py',
80 '33a910c714948a5189f9c58101ce9b131f01c1fd',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070081 [
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 Prabhu4a880bc2020-06-22 13:38:50 -070087 ),
88]
Xixuan Wu26d06e02017-09-20 14:50:28 -070089
Xinan Lin3ba18a02019-08-13 15:44:55 -070090
Xinan Lin83c1a312020-04-13 23:31:47 -070091def _install_infra_libs():
Xinan Lincd6d40b2019-08-09 15:53:43 -070092 """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 Lincd6d40b2019-08-09 15:53:43 -070097 """
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070098 if os.path.exists(_INFRA_LIBS_PATH):
99 shutil.rmtree(_INFRA_LIBS_PATH)
100 os.mkdir(_INFRA_LIBS_PATH)
Xinan Lincd6d40b2019-08-09 15:53:43 -0700101
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -0700102 for dep in _GIT_DEPS:
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700103 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 Prabhu4a880bc2020-06-22 13:38:50 -0700111 subprocess.check_call(['git', 'checkout', dep.git_ref], cwd=dep_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700112
Xinan Lin3ba18a02019-08-13 15:44:55 -0700113
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700114def _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 Wu26d06e02017-09-20 14:50:28 -0700125
126
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700127def _load_credentials():
128 subprocess.check_call([_REFRESH_CREDENTIALS_SCRIPT])
Xixuan Wu26d06e02017-09-20 14:50:28 -0700129
130
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700131def main():
132 """Entry point of the script"""
Xixuan Wu26d06e02017-09-20 14:50:28 -0700133 parser = argparse.ArgumentParser(
134 description=__doc__,
135 formatter_class=argparse.RawDescriptionHelpFormatter)
136 parser.add_argument(
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700137 '--load-creds',
Xixuan Wu26d06e02017-09-20 14:50:28 -0700138 action='store_true',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700139 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 Wu26d06e02017-09-20 14:50:28 -0700147
148
149if __name__ == '__main__':
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700150 main()