blob: 98b788ef7fd546b37115cee231ce1abb0b24f07b [file] [log] [blame]
Primiano Tuccif7647392019-10-04 00:42:11 +01001#!/usr/bin/env python
2# Copyright (C) 2019 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import print_function
17import argparse
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010018import distutils
19import grp
20import os
21import readline
Primiano Tuccif7647392019-10-04 00:42:11 +010022import sys
23import shutil
24import subprocess
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010025from pipes import quote
26
27try:
28 from shutil import which as find_executable
29except AttributeError:
30 from distutils.spawn import find_executable
Primiano Tuccif7647392019-10-04 00:42:11 +010031
32REPO_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
33sys.path.append(os.path.join(REPO_ROOT, 'infra', 'ci'))
34from config import JOB_CONFIGS, SANDBOX_IMG
35
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010036try:
37 input = raw_input
38except NameError:
39 pass
40
41
42def user_in_docker_group():
43 try:
44 group = grp.getgrnam('docker')
45 except KeyError:
46 return False
47 else:
48 return group.gr_gid in os.getgroups()
49
50
51def decision(question='Would you like to continue', confirm=True, default='n'):
52 default = default.lower().strip()
53 yes = default in {'y', 'yes'}
54 no = default in {'n', 'no'}
55 default = 'y' if yes else 'n'
56 prompt = '%s? [%s/%s]: ' % (question, 'Y' if yes else 'y', 'N' if no else 'n')
57 if not confirm:
58 print('%sy' % prompt)
59 return
60 while True:
61 choice = input(prompt).lower().strip()
62 if not choice:
63 choice = default
64 if choice in {'y', 'yes'}:
65 return
66 elif choice in {'n', 'no'}:
67 sys.exit(3)
68
Primiano Tuccif7647392019-10-04 00:42:11 +010069
70def main():
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010071 parser = argparse.ArgumentParser(
72 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
Matthew Clarkson63028d62019-10-10 15:48:23 +010073 parser.add_argument('config', choices=JOB_CONFIGS.keys())
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010074 parser.add_argument(
75 '--runner',
76 help='The container runner executable to use',
77 choices=('podman', 'docker'),
78 default='podman' if find_executable('podman') else 'docker')
79 parser.add_argument(
80 '--image', default=SANDBOX_IMG, help='The image to use to run the tests')
81 group = parser.add_mutually_exclusive_group()
82 group.add_argument(
83 '--confirm',
84 action='store_true',
85 default=True,
86 help='User confirmation of decision prompts')
87 group.add_argument(
88 '--no-confirm',
89 dest='confirm',
90 action='store_false',
91 help='Forces confirmation of decision prompts')
Matthew Clarkson63028d62019-10-10 15:48:23 +010092 args = parser.parse_args()
Primiano Tuccif7647392019-10-04 00:42:11 +010093
Matthew Clarkson63028d62019-10-10 15:48:23 +010094 # Check that the directory is clean.
95 git_cmd = ['git', '-C', REPO_ROOT, 'status', '--porcelain']
Matthew Clarkson1ed6a042019-10-25 11:18:05 +010096 modified_files = subprocess.check_output(git_cmd).decode()
Matthew Clarkson63028d62019-10-10 15:48:23 +010097 if modified_files:
98 print('The current Git repo has modified/untracked files.')
99 print('The sandboxed VM will fetch the HEAD of your current git repo.')
100 print('This is probably not the state you want to be in.')
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100101 print('I suggest you stop, commit and then re-run this script')
Matthew Clarkson63028d62019-10-10 15:48:23 +0100102 print('Modified files:\n' + modified_files)
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100103 decision('Do you know what you are doing', confirm=args.confirm)
Primiano Tuccif7647392019-10-04 00:42:11 +0100104
Matthew Clarkson63028d62019-10-10 15:48:23 +0100105 env = {
106 'PERFETTO_TEST_GIT_REF': 'file:///ci/source',
107 }
108 env.update(JOB_CONFIGS[args.config])
Primiano Tuccif7647392019-10-04 00:42:11 +0100109
Matthew Clarkson63028d62019-10-10 15:48:23 +0100110 workdir = os.path.join(REPO_ROOT, 'out', 'tmp.ci')
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100111 cmd = []
112 if args.runner == 'docker' and not user_in_docker_group():
113 cmd += ['sudo', '--']
114 cmd += [
115 args.runner, 'run', '-it', '--name', 'perfetto_ci', '--cap-add',
116 'SYS_PTRACE', '--rm', '--volume',
Matthew Clarkson63028d62019-10-10 15:48:23 +0100117 '%s:/ci/ramdisk' % workdir, '--tmpfs', '/tmp:exec',
118 '--volume=%s:/ci/source:ro' % REPO_ROOT
119 ]
120 for kv in env.items():
121 cmd += ['--env', '%s=%s' % kv]
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100122 cmd += [args.image]
Matthew Clarkson63028d62019-10-10 15:48:23 +0100123 cmd += [
124 'bash', '-c',
125 'cd /ci/ramdisk; bash /ci/init.sh || sudo -u perfetto -EH bash -i'
126 ]
Primiano Tuccif7647392019-10-04 00:42:11 +0100127
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100128 print(
129 'About to run\n',
130 ' '.join('\n ' + c if c.startswith('--') or c == 'bash' else quote(c)
131 for c in cmd))
Matthew Clarkson63028d62019-10-10 15:48:23 +0100132 print('')
133 print('The VM will have read-only acess to: %s, mounted as /ci/source' %
134 REPO_ROOT)
135 print('The VM workdir /ci/ramdisk will be mounted into: %s' % workdir)
136 print('The contents of %s will be deleted before starting the VM' % workdir)
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100137 decision(confirm=args.confirm)
Primiano Tuccif7647392019-10-04 00:42:11 +0100138
Matthew Clarkson63028d62019-10-10 15:48:23 +0100139 shutil.rmtree(workdir, ignore_errors=True)
140 os.makedirs(workdir)
Matthew Clarkson1ed6a042019-10-25 11:18:05 +0100141 os.execvp(cmd[0], cmd)
Primiano Tuccif7647392019-10-04 00:42:11 +0100142
143
144if __name__ == '__main__':
Matthew Clarkson63028d62019-10-10 15:48:23 +0100145 sys.exit(main())