blob: ff77959f912b87bb62ff70d563a49619b717ab43 [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 Lincd6d40b2019-08-09 15:53:43 -070064def _install_infra_libs(skip_install_infra_libs):
65 """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.
70
71 Args:
72 skip_install_infra_libs: A boolean variable to indicate whether to skip
73 downloading the infra libs.
74 """
75
76 if skip_install_infra_libs:
77 return
78
79 print('Recreate infra_libs directory if already exists...')
80 if os.path.exists(file_getter.INFRA_LIBS_PATH):
81 osutils.RmDir(file_getter.INFRA_LIBS_PATH)
82 os.mkdir(file_getter.INFRA_LIBS_PATH)
83 os.mkdir(file_getter.LUCI_PATH)
84 os.mkdir(file_getter.CHROMITE_PATH)
85
86 print('Fetching prpc client from luci-py lib...')
87 luci_checkout = [
88 '/appengine/components/components/auth/**/*.py',
89 '/appengine/components/components/datastore_utils/**/*.py',
90 '/appengine/components/components/prpc/**/*.py',
91 '/appengine/components/components/*.py',
92 '!*test.py']
93 git.ShallowFetch(file_getter.LUCI_PATH, LUCI_REPO,
94 sparse_checkout=luci_checkout)
95
96 print('Fetching proto files from Chromite...')
97 chromite_checkout = [
98 '/api/gen/**/*.py',
99 '/api/__init__.py',
100 '/third_party/infra_libs/*',
101 '/third_party/google/*',
102 '/third_party/__init__.py',
103 '/__init__.py',
104 '!*test.py']
105 git.ShallowFetch(file_getter.CHROMITE_PATH, CHROMITE_REPO,
106 sparse_checkout=chromite_checkout)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700107
Xinan Lin3ba18a02019-08-13 15:44:55 -0700108
Xixuan Wu30244f92019-03-21 09:49:17 -0700109def fetch_service_credentials(force_update_cred):
Xixuan Wu26d06e02017-09-20 14:50:28 -0700110 """Fetch service credentials from GS bucket.
111
112 Args:
Xinan Lincd6d40b2019-08-09 15:53:43 -0700113 force_update_cred: A boolean variable to indicate whether to force to
Xixuan Wu30244f92019-03-21 09:49:17 -0700114 re-download the creds.
Xixuan Wu26d06e02017-09-20 14:50:28 -0700115
116 Raises:
117 ValueError: if credentials cannot be fetched due to no valid gs package.
118 """
119 credentials_path = file_getter.CREDENTIALS_PATH
Xixuan Wu30244f92019-03-21 09:49:17 -0700120 if force_update_cred and os.path.exists(credentials_path):
121 shutil.rmtree(credentials_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700122
123 if not os.path.exists(credentials_path):
124 if gs is None:
125 raise ValueError(
Xixuan Wu30244f92019-03-21 09:49:17 -0700126 'Chromite cannot be imported.\nPlease download the credentials '
127 'manually:\n\tgsutil cp -r %s %s' % (
128 CREDS_GS_PATH, os.path.dirname(credentials_path)))
Xixuan Wu26d06e02017-09-20 14:50:28 -0700129
130 os.mkdir(credentials_path)
131 try:
132 ctx = gs.GSContext(init_boto=True)
Xixuan Wu30244f92019-03-21 09:49:17 -0700133 ctx.Copy(CREDS_GS_PATH + '*', credentials_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700134 except gs.GSCommandError as e:
Xixuan Wu8929a302017-12-07 18:09:31 -0800135 print('The GS credentials is not configured properly. '
136 'Please contact ChromeOS Infrastructure'
137 'team for more info about it.')
138 print('Failed to get suite_scheduler service credentials: %r.'
139 'Deleting %s' % (str(e), credentials_path))
Xixuan Wu26d06e02017-09-20 14:50:28 -0700140 os.rmdir(credentials_path)
141
142
143def _verify():
144 """Verify the credentials & third_party lib work."""
145 subprocess.check_call(['python', 'runner.py'])
146
147
148def _make_parser():
149 """Return parser."""
150 parser = argparse.ArgumentParser(
151 description=__doc__,
152 formatter_class=argparse.RawDescriptionHelpFormatter)
153 parser.add_argument(
Xixuan Wu26d06e02017-09-20 14:50:28 -0700154 '--update_lib',
155 action='store_true',
156 help='Force to reinstall all required third-party libraries.')
157 parser.add_argument(
158 '--update_cred',
159 action='store_true',
160 help='Force to re-copy the credentials from Google Storage.')
Xinan Lincd6d40b2019-08-09 15:53:43 -0700161 parser.add_argument(
162 '--skip_infra_libs',
163 action='store_true',
164 help='Skip to install infra libs.')
Xixuan Wu26d06e02017-09-20 14:50:28 -0700165 return parser
166
167
168if __name__ == '__main__':
169 setup_parser = _make_parser()
170 setup_args = setup_parser.parse_args()
171 _install_third_party_lib(setup_args)
Xixuan Wu30244f92019-03-21 09:49:17 -0700172 fetch_service_credentials(setup_args.update_cred)
Xinan Lincd6d40b2019-08-09 15:53:43 -0700173 _install_infra_libs(setup_args.skip_infra_libs)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700174 _verify()