1#!/usr/bin/python
2#
3# Copyright 2018 The Android Open-Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18"""Upload a local build to Google Compute Engine and run it."""
19
20import argparse
21import glob
22import os
23import subprocess
24
25
26def gcloud_ssh(args):
27  command = 'gcloud compute ssh %s@%s ' % (args.user, args.instance)
28  if args.zone:
29    command += '--zone=%s ' % args.zone
30  return command
31
32
33def upload_artifacts(args):
34  dir = os.getcwd()
35  try:
36    os.chdir(args.image_dir)
37    artifacts = []
38    artifact_patterns = ['*.img', 'bootloader']
39    for artifact_pattern in artifact_patterns:
40      artifacts.extend(glob.glob(artifact_pattern))
41    if len(artifacts) == 0:
42      raise OSError('No images found in: %s' + args.image_dir)
43    subprocess.check_call(
44        'tar -c -f - --lzop -S ' + ' '.join(artifacts) +
45        ' | ' +
46        gcloud_ssh(args) + '-- tar -x -f - --lzop -S',
47        shell=True)
48  finally:
49    os.chdir(dir)
50
51  host_package = os.path.join(args.host_dir, 'cvd-host_package.tar.gz')
52  subprocess.check_call(
53      gcloud_ssh(args) + '-- tar -x -z -f - < %s' % host_package,
54      shell=True)
55
56
57def launch_cvd(args):
58  launch_cvd_args = ''
59  if args.data_image:
60    launch_cvd_args = (
61      '--data-image %s '
62      '--data-policy create_if_missing '
63      '--blank-data-image-mb %d ' % (args.data_image, args.blank_data_image_mb))
64
65  subprocess.check_call(
66      gcloud_ssh(args) + '-- ./bin/launch_cvd ' + launch_cvd_args,
67      shell=True)
68
69
70def stop_cvd(args):
71  subprocess.call(
72      gcloud_ssh(args) + '-- ./bin/stop_cvd',
73      shell=True)
74
75
76def __get_default_hostdir():
77  return os.environ.get('ANDROID_HOST_OUT', '.')
78
79
80def main():
81  parser = argparse.ArgumentParser(
82      description='Upload a local build to Google Compute Engine and run it')
83  parser.add_argument(
84      '-host_dir',
85      type=str,
86      default=__get_default_hostdir(),
87      help='path to the dist directory')
88  parser.add_argument(
89      '-image_dir',
90      type=str,
91      default=os.environ.get('ANDROID_PRODUCT_OUT', '.'),
92      help='path to the img files')
93  parser.add_argument(
94      '-instance', type=str, required=True,
95      help='instance to update')
96  parser.add_argument(
97      '-zone', type=str, default=None,
98      help='zone containing the instance')
99  parser.add_argument(
100      '-user', type=str, default=os.environ.get('USER', 'vsoc-01'),
101      help='user to update on the instance')
102  parser.add_argument(
103      '-data-image', type=str, default=None,
104      help='userdata image file name, this file will be used instead of default one')
105  parser.add_argument(
106      '-blank-data-image-mb', type=int, default=4098,
107      help='custom userdata image size in megabytes')
108  parser.add_argument(
109      '-launch', default=False,
110      action='store_true',
111      help='launch the device')
112  args = parser.parse_args()
113  stop_cvd(args)
114  upload_artifacts(args)
115  if args.launch:
116    launch_cvd(args)
117
118
119if __name__ == '__main__':
120  main()
121