blob: 94276445e5644130f699435eb1e73a975f9ce486 [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(
Sean McAllister79297a62021-07-15 19:36:41 -060063 '_GitDep',
64 'local_name git_project git_ref sparse_checkout_paths post_process')
65
66
67def create_file(fname):
68 """Create an empty file by opening it for writing and closing."""
69 open(fname, 'w').close()
70
71
72def fixup_chromite_init_files():
73 """Fixup/overwrite __init__.py files for chromite.
74
75 Chromite has moved to python3 which causes import errors. We don't need
76 the logging setup, just the ability to import, so we'll create our own.
77
78 Similarly, python3 supports implicit namespaces and python2 doesn't, so
79 add __init__.py files needed to work around that.
80 """
81 create_file('infra_libs/chromite/__init__.py')
82 create_file('infra_libs/chromite/third_party/__init__.py')
83 create_file('infra_libs/chromite/third_party/google/api/__init__.py')
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -070084
85# List of all git project dependencies.
86_GIT_DEPS = [
87 _GitDep(
88 'chromite',
89 'https://chromium.googlesource.com/chromiumos/chromite',
Sean McAllister79297a62021-07-15 19:36:41 -060090 'b81fbbf389c289a35aecfdc52a50ae53fb624db0',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070091 [
92 '/api/gen/**/*.py', '/api/__init__.py',
93 '/third_party/infra_libs/*', '/third_party/google/*',
Sean McAllister79297a62021-07-15 19:36:41 -060094 '/third_party/six/*',
95 '!*test.py'
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -070096 ],
Sean McAllister79297a62021-07-15 19:36:41 -060097 fixup_chromite_init_files
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -070098 ),
99 _GitDep(
100 'luci',
101 'https://chromium.googlesource.com/infra/luci/luci-py',
102 '33a910c714948a5189f9c58101ce9b131f01c1fd',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700103 [
104 '/appengine/components/components/auth/**/*.py',
105 '/appengine/components/components/datastore_utils/**/*.py',
106 '/appengine/components/components/prpc/**/*.py',
107 '/appengine/components/components/*.py', '!*test.py'
108 ],
Sean McAllister79297a62021-07-15 19:36:41 -0600109 None
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -0700110 ),
111]
Xixuan Wu26d06e02017-09-20 14:50:28 -0700112
Xinan Lin3ba18a02019-08-13 15:44:55 -0700113
Xinan Lin83c1a312020-04-13 23:31:47 -0700114def _install_infra_libs():
Xinan Lincd6d40b2019-08-09 15:53:43 -0700115 """Install useful libs from Chromium infra and Chromite.
116
117 infra_libs consists of prpc client from luci and necessary proto files from
118 Chromite. Suite scheduler relies on those libs to conduct prpc call to
119 Buildbucket.
Xinan Lincd6d40b2019-08-09 15:53:43 -0700120 """
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700121 if os.path.exists(_INFRA_LIBS_PATH):
122 shutil.rmtree(_INFRA_LIBS_PATH)
123 os.mkdir(_INFRA_LIBS_PATH)
Xinan Lincd6d40b2019-08-09 15:53:43 -0700124
Prathmesh Prabhu4a880bc2020-06-22 13:38:50 -0700125 for dep in _GIT_DEPS:
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700126 dep_path = os.path.join(_INFRA_LIBS_PATH, dep.local_name)
127 print('Creating sparse checkout of %s at %s in %s' %
128 (dep.git_project, dep.git_ref, dep_path))
129 subprocess.check_call(
130 ['git', 'clone', '--no-checkout', dep.git_project, dep.local_name],
131 cwd=_INFRA_LIBS_PATH)
132 subprocess.check_call(['git', 'sparse-checkout', 'init'], cwd=dep_path)
133 _set_sparse_checkout_paths(dep_path, dep.sparse_checkout_paths)
Xinan Lind37e6222020-07-07 22:37:57 -0700134 subprocess.check_call(
135 ['git', 'checkout', dep.git_ref, '-b', 'deploy', '-f'], cwd=dep_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700136
Sean McAllister79297a62021-07-15 19:36:41 -0600137 if dep.post_process is not None:
138 dep.post_process()
139
Xinan Lin3ba18a02019-08-13 15:44:55 -0700140
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700141def _set_sparse_checkout_paths(checkout_dir, sparse_checkout_paths):
142 """Set the path patterns to checkout in a git checkout."""
143 # Pass in path patterns via stdin to avoid shell escaping issues.
144 proc = subprocess.Popen(['git', 'sparse-checkout', 'set', '--stdin'],
145 stdin=subprocess.PIPE,
146 cwd=checkout_dir)
147 proc.communicate(input='\n'.join(sparse_checkout_paths))
148 if proc.poll() is None:
149 raise Exception('Leaked process when setting sparse checkout paths')
150 if proc.poll() != 0:
151 raise Exception('Failed to set sparse checkout paths')
Xixuan Wu26d06e02017-09-20 14:50:28 -0700152
153
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700154def _load_credentials():
155 subprocess.check_call([_REFRESH_CREDENTIALS_SCRIPT])
Xixuan Wu26d06e02017-09-20 14:50:28 -0700156
157
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700158def main():
159 """Entry point of the script"""
Xixuan Wu26d06e02017-09-20 14:50:28 -0700160 parser = argparse.ArgumentParser(
161 description=__doc__,
162 formatter_class=argparse.RawDescriptionHelpFormatter)
163 parser.add_argument(
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700164 '--load-creds',
Xixuan Wu26d06e02017-09-20 14:50:28 -0700165 action='store_true',
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700166 help='Also install credentials needed for releasing suite '
167 'scheduler. Not needed to modify config/*')
168
169 args = parser.parse_args()
170 _install_third_party_lib()
171 _install_infra_libs()
172 if args.load_creds:
173 _load_credentials()
Xixuan Wu26d06e02017-09-20 14:50:28 -0700174
175
176if __name__ == '__main__':
Prathmesh Prabhu8dff3e22020-06-23 13:49:45 -0700177 main()