blob: 7f1568f36d9f4cedb3412ac1c9e6fef185e4d171 [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
34def _install_third_party_lib(input_args):
35 """Install useful third-party lib.
36
37 The libraries are specified in requirement.txt. They're used in both local
38 development environment and Google App Engine, which means they will be
39 uploaded to GAE.
40
41 Args:
42 input_args: the arguments passed in by users.
43 """
44 third_party_lib_path = file_getter.THIRD_PARTY_LIB_PATH
45 if input_args.update_lib and os.path.exists(third_party_lib_path):
46 os.rmdir(third_party_lib_path)
47
48 if not os.path.exists(third_party_lib_path):
Xixuan Wu8929a302017-12-07 18:09:31 -080049 print('Creating lib path: %s' % third_party_lib_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -070050 os.mkdir(third_party_lib_path)
Xixuan Wu8929a302017-12-07 18:09:31 -080051 print('Installing packages')
52 cmd = ['pip', 'install', '-t', 'lib', '-r', 'requirements.txt']
53 try:
54 subprocess.check_call(cmd)
55 except subprocess.CalledProcessError:
56 # TODO(crbug.com/792690): this is a workround of fixing installing
57 # third-party packages on different versions of Ubuntu/Debian.
58 print("Failed to run '%s'; trying a different command." % ' '.join(cmd))
59 subprocess.check_call(['pip', 'install', '-t', 'lib', '--system',
60 '-r', 'requirements.txt'])
Xixuan Wu26d06e02017-09-20 14:50:28 -070061
Xinan Lincd6d40b2019-08-09 15:53:43 -070062def _install_infra_libs(skip_install_infra_libs):
63 """Install useful libs from Chromium infra and Chromite.
64
65 infra_libs consists of prpc client from luci and necessary proto files from
66 Chromite. Suite scheduler relies on those libs to conduct prpc call to
67 Buildbucket.
68
69 Args:
70 skip_install_infra_libs: A boolean variable to indicate whether to skip
71 downloading the infra libs.
72 """
73
74 if skip_install_infra_libs:
75 return
76
77 print('Recreate infra_libs directory if already exists...')
78 if os.path.exists(file_getter.INFRA_LIBS_PATH):
79 osutils.RmDir(file_getter.INFRA_LIBS_PATH)
80 os.mkdir(file_getter.INFRA_LIBS_PATH)
81 os.mkdir(file_getter.LUCI_PATH)
82 os.mkdir(file_getter.CHROMITE_PATH)
83
84 print('Fetching prpc client from luci-py lib...')
85 luci_checkout = [
86 '/appengine/components/components/auth/**/*.py',
87 '/appengine/components/components/datastore_utils/**/*.py',
88 '/appengine/components/components/prpc/**/*.py',
89 '/appengine/components/components/*.py',
90 '!*test.py']
91 git.ShallowFetch(file_getter.LUCI_PATH, LUCI_REPO,
92 sparse_checkout=luci_checkout)
93
94 print('Fetching proto files from Chromite...')
95 chromite_checkout = [
96 '/api/gen/**/*.py',
97 '/api/__init__.py',
98 '/third_party/infra_libs/*',
99 '/third_party/google/*',
100 '/third_party/__init__.py',
101 '/__init__.py',
102 '!*test.py']
103 git.ShallowFetch(file_getter.CHROMITE_PATH, CHROMITE_REPO,
104 sparse_checkout=chromite_checkout)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700105
Xixuan Wu30244f92019-03-21 09:49:17 -0700106def fetch_service_credentials(force_update_cred):
Xixuan Wu26d06e02017-09-20 14:50:28 -0700107 """Fetch service credentials from GS bucket.
108
109 Args:
Xinan Lincd6d40b2019-08-09 15:53:43 -0700110 force_update_cred: A boolean variable to indicate whether to force to
Xixuan Wu30244f92019-03-21 09:49:17 -0700111 re-download the creds.
Xixuan Wu26d06e02017-09-20 14:50:28 -0700112
113 Raises:
114 ValueError: if credentials cannot be fetched due to no valid gs package.
115 """
116 credentials_path = file_getter.CREDENTIALS_PATH
Xixuan Wu30244f92019-03-21 09:49:17 -0700117 if force_update_cred and os.path.exists(credentials_path):
118 shutil.rmtree(credentials_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700119
120 if not os.path.exists(credentials_path):
121 if gs is None:
122 raise ValueError(
Xixuan Wu30244f92019-03-21 09:49:17 -0700123 'Chromite cannot be imported.\nPlease download the credentials '
124 'manually:\n\tgsutil cp -r %s %s' % (
125 CREDS_GS_PATH, os.path.dirname(credentials_path)))
Xixuan Wu26d06e02017-09-20 14:50:28 -0700126
127 os.mkdir(credentials_path)
128 try:
129 ctx = gs.GSContext(init_boto=True)
Xixuan Wu30244f92019-03-21 09:49:17 -0700130 ctx.Copy(CREDS_GS_PATH + '*', credentials_path)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700131 except gs.GSCommandError as e:
Xixuan Wu8929a302017-12-07 18:09:31 -0800132 print('The GS credentials is not configured properly. '
133 'Please contact ChromeOS Infrastructure'
134 'team for more info about it.')
135 print('Failed to get suite_scheduler service credentials: %r.'
136 'Deleting %s' % (str(e), credentials_path))
Xixuan Wu26d06e02017-09-20 14:50:28 -0700137 os.rmdir(credentials_path)
138
139
140def _verify():
141 """Verify the credentials & third_party lib work."""
142 subprocess.check_call(['python', 'runner.py'])
143
144
145def _make_parser():
146 """Return parser."""
147 parser = argparse.ArgumentParser(
148 description=__doc__,
149 formatter_class=argparse.RawDescriptionHelpFormatter)
150 parser.add_argument(
Xixuan Wu26d06e02017-09-20 14:50:28 -0700151 '--update_lib',
152 action='store_true',
153 help='Force to reinstall all required third-party libraries.')
154 parser.add_argument(
155 '--update_cred',
156 action='store_true',
157 help='Force to re-copy the credentials from Google Storage.')
Xinan Lincd6d40b2019-08-09 15:53:43 -0700158 parser.add_argument(
159 '--skip_infra_libs',
160 action='store_true',
161 help='Skip to install infra libs.')
Xixuan Wu26d06e02017-09-20 14:50:28 -0700162 return parser
163
164
165if __name__ == '__main__':
166 setup_parser = _make_parser()
167 setup_args = setup_parser.parse_args()
168 _install_third_party_lib(setup_args)
Xixuan Wu30244f92019-03-21 09:49:17 -0700169 fetch_service_credentials(setup_args.update_cred)
Xinan Lincd6d40b2019-08-09 15:53:43 -0700170 _install_infra_libs(setup_args.skip_infra_libs)
Xixuan Wu26d06e02017-09-20 14:50:28 -0700171 _verify()