blob: 089cde53c9c05bf0e51804ebed1656bb9342d05d [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.
4
Xixuan Wu8929a302017-12-07 18:09:31 -08005"""Module for setup environemtn for local testing & Google App Engine."""
Xixuan Wu26d06e02017-09-20 14:50:28 -07006
7
Xixuan Wu8929a302017-12-07 18:09:31 -08008from __future__ import print_function
9
Xixuan Wu26d06e02017-09-20 14:50:28 -070010import argparse
11import os
Xixuan Wu30244f92019-03-21 09:49:17 -070012import shutil
Xixuan Wu26d06e02017-09-20 14:50:28 -070013import subprocess
14
15import file_getter
16
17import local_import # pylint: disable=unused-import
18try:
Xinan Lincd6d40b2019-08-09 15:53:43 -070019 from chromite.lib import gs, git, osutils # pylint: disable=g-import-not-at-top
Xixuan Wu26d06e02017-09-20 14:50:28 -070020except ImportError:
Xixuan Wu8929a302017-12-07 18:09:31 -080021 print('Cannot import chromite')
Xixuan Wu26d06e02017-09-20 14:50:28 -070022 gs = None
Xinan Lincd6d40b2019-08-09 15:53:43 -070023 git = None
24 osutils = None
Xixuan Wu26d06e02017-09-20 14:50:28 -070025
26
27# The credentials folder for suite-scheduler service.
28CREDS_GS_PATH = 'gs://suite-scheduler.google.com.a.appspot.com/credentials/'
29
Xinan Lincd6d40b2019-08-09 15:53:43 -070030# Remote repositories of luci-py and Chromite.
31LUCI_REPO = 'https://chromium.googlesource.com/infra/luci/luci-py'
32CHROMITE_REPO = 'https://chromium.googlesource.com/chromiumos/chromite'
Xixuan Wu26d06e02017-09-20 14:50:28 -070033
Xinan Lin3ba18a02019-08-13 15:44:55 -070034
Xixuan Wu26d06e02017-09-20 14:50:28 -070035def _install_third_party_lib(input_args):
36 """Install useful third-party lib.
37
38 The libraries are specified in requirement.txt. They're used in both local
39 development environment and Google App Engine, which means they will be
40 uploaded to GAE.
41
42 Args:
43 input_args: the arguments passed in by users.
44 """
45 third_party_lib_path = file_getter.THIRD_PARTY_LIB_PATH
46 if input_args.update_lib and os.path.exists(third_party_lib_path):
47 os.rmdir(third_party_lib_path)
48
49 if not os.path.exists(third_party_lib_path):
Xixuan Wu8929a302017-12-07 18:09:31 -080050 print('Creating lib path: %s' % third_party_lib_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -070051 os.mkdir(third_party_lib_path)
Xixuan Wu8929a302017-12-07 18:09:31 -080052 print('Installing packages')
53 cmd = ['pip', 'install', '-t', 'lib', '-r', 'requirements.txt']
54 try:
55 subprocess.check_call(cmd)
56 except subprocess.CalledProcessError:
57 # TODO(crbug.com/792690): this is a workround of fixing installing
58 # third-party packages on different versions of Ubuntu/Debian.
59 print("Failed to run '%s'; trying a different command." % ' '.join(cmd))
60 subprocess.check_call(['pip', 'install', '-t', 'lib', '--system',
61 '-r', 'requirements.txt'])
Xixuan Wu26d06e02017-09-20 14:50:28 -070062
Xinan Lin3ba18a02019-08-13 15:44:55 -070063
Xinan Lin83c1a312020-04-13 23:31:47 -070064def _install_infra_libs():
Xinan Lincd6d40b2019-08-09 15:53:43 -070065 """Install useful libs from Chromium infra and Chromite.
66
67 infra_libs consists of prpc client from luci and necessary proto files from
68 Chromite. Suite scheduler relies on those libs to conduct prpc call to
69 Buildbucket.
Xinan Lincd6d40b2019-08-09 15:53:43 -070070 """
Xinan Lincd6d40b2019-08-09 15:53:43 -070071 print('Recreate infra_libs directory if already exists...')
72 if os.path.exists(file_getter.INFRA_LIBS_PATH):
73 osutils.RmDir(file_getter.INFRA_LIBS_PATH)
74 os.mkdir(file_getter.INFRA_LIBS_PATH)
75 os.mkdir(file_getter.LUCI_PATH)
76 os.mkdir(file_getter.CHROMITE_PATH)
77
78 print('Fetching prpc client from luci-py lib...')
79 luci_checkout = [
80 '/appengine/components/components/auth/**/*.py',
81 '/appengine/components/components/datastore_utils/**/*.py',
82 '/appengine/components/components/prpc/**/*.py',
83 '/appengine/components/components/*.py',
84 '!*test.py']
85 git.ShallowFetch(file_getter.LUCI_PATH, LUCI_REPO,
86 sparse_checkout=luci_checkout)
87
88 print('Fetching proto files from Chromite...')
89 chromite_checkout = [
90 '/api/gen/**/*.py',
91 '/api/__init__.py',
92 '/third_party/infra_libs/*',
93 '/third_party/google/*',
94 '/third_party/__init__.py',
95 '/__init__.py',
96 '!*test.py']
97 git.ShallowFetch(file_getter.CHROMITE_PATH, CHROMITE_REPO,
98 sparse_checkout=chromite_checkout)
Xixuan Wu26d06e02017-09-20 14:50:28 -070099
Xinan Lin3ba18a02019-08-13 15:44:55 -0700100
Xinan Lin83c1a312020-04-13 23:31:47 -0700101def _fetch_service_credentials():
Xixuan Wu26d06e02017-09-20 14:50:28 -0700102 """Fetch service credentials from GS bucket.
103
Xixuan Wu26d06e02017-09-20 14:50:28 -0700104 Raises:
105 ValueError: if credentials cannot be fetched due to no valid gs package.
106 """
107 credentials_path = file_getter.CREDENTIALS_PATH
Xinan Lin83c1a312020-04-13 23:31:47 -0700108 if os.path.exists(credentials_path):
109 print('The credential folder already exists: %s. '
110 'Delete it if you want to reload the service accounts.' %
111 credentials_path)
112 return
Xixuan Wu26d06e02017-09-20 14:50:28 -0700113
Xinan Lin83c1a312020-04-13 23:31:47 -0700114 if gs is None:
115 raise ValueError(
116 'Chromite cannot be imported.\nPlease download the credentials '
117 'manually:\n\tgsutil cp -r %s %s' %
118 (CREDS_GS_PATH, os.path.dirname(credentials_path)))
Xixuan Wu26d06e02017-09-20 14:50:28 -0700119
Xinan Lin83c1a312020-04-13 23:31:47 -0700120 os.mkdir(credentials_path)
121 try:
122 ctx = gs.GSContext(init_boto=True)
123 ctx.Copy(CREDS_GS_PATH + '*', credentials_path)
124 except gs.GSCommandError as e:
125 print('The GS credentials is not configured properly. '
126 'Please contact ChromeOS Infrastructure'
127 'team for more info about it.')
128 print('Failed to get suite_scheduler service credentials: %r.'
129 'Deleting %s' % (str(e), credentials_path))
130 os.rmdir(credentials_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700131
132
133def _verify():
134 """Verify the credentials & third_party lib work."""
135 subprocess.check_call(['python', 'runner.py'])
136
137
138def _make_parser():
139 """Return parser."""
140 parser = argparse.ArgumentParser(
141 description=__doc__,
142 formatter_class=argparse.RawDescriptionHelpFormatter)
143 parser.add_argument(
Xixuan Wu26d06e02017-09-20 14:50:28 -0700144 '--update_lib',
145 action='store_true',
146 help='Force to reinstall all required third-party libraries.')
147 parser.add_argument(
Xinan Lin83c1a312020-04-13 23:31:47 -0700148 '--load_cred',
Xixuan Wu26d06e02017-09-20 14:50:28 -0700149 action='store_true',
Xinan Lin83c1a312020-04-13 23:31:47 -0700150 help='Load credentials from Google Storage.')
Xinan Lincd6d40b2019-08-09 15:53:43 -0700151 parser.add_argument(
Xinan Lin83c1a312020-04-13 23:31:47 -0700152 '--load_infra_libs', action='store_true', help='Install infra libs.')
153 parser.add_argument(
154 '--run_unit_test', action='store_true', help='Run unit test.')
Xixuan Wu26d06e02017-09-20 14:50:28 -0700155 return parser
156
157
158if __name__ == '__main__':
159 setup_parser = _make_parser()
160 setup_args = setup_parser.parse_args()
161 _install_third_party_lib(setup_args)
Xinan Lin83c1a312020-04-13 23:31:47 -0700162 if setup_args.load_cred:
163 _fetch_service_credentials()
164 if setup_args.load_infra_libs:
165 _install_infra_libs()
166 if setup_args.run_unit_test:
167 _verify()