xref: /aosp_15_r20/external/perfetto/tools/ssh_into_gce_vm (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2024 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker#
4*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the 'License');
5*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker#
8*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker#
10*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an 'AS IS' BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker
16*6dbdd20aSAndroid Build Coastguard Workerimport argparse
17*6dbdd20aSAndroid Build Coastguard Workerimport os
18*6dbdd20aSAndroid Build Coastguard Workerimport subprocess
19*6dbdd20aSAndroid Build Coastguard Workerimport sys
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Worker
22*6dbdd20aSAndroid Build Coastguard Workerdef list_instances(project_id):
23*6dbdd20aSAndroid Build Coastguard Worker  try:
24*6dbdd20aSAndroid Build Coastguard Worker    result = subprocess.run([
25*6dbdd20aSAndroid Build Coastguard Worker        'gcloud', 'compute', 'instances', 'list', '--project', project_id,
26*6dbdd20aSAndroid Build Coastguard Worker        '--format', 'table(name,zone)'
27*6dbdd20aSAndroid Build Coastguard Worker    ],
28*6dbdd20aSAndroid Build Coastguard Worker                            check=True,
29*6dbdd20aSAndroid Build Coastguard Worker                            stdout=subprocess.PIPE,
30*6dbdd20aSAndroid Build Coastguard Worker                            stderr=subprocess.PIPE,
31*6dbdd20aSAndroid Build Coastguard Worker                            text=True)
32*6dbdd20aSAndroid Build Coastguard Worker    lines = result.stdout.strip().split('\n')
33*6dbdd20aSAndroid Build Coastguard Worker    instances = [tuple(line.split()) for line in lines[1:]]  # Skip the header
34*6dbdd20aSAndroid Build Coastguard Worker    return instances
35*6dbdd20aSAndroid Build Coastguard Worker  except subprocess.CalledProcessError as e:
36*6dbdd20aSAndroid Build Coastguard Worker    print(f'Error retrieving instances: {e.stderr}')
37*6dbdd20aSAndroid Build Coastguard Worker    sys.exit(1)
38*6dbdd20aSAndroid Build Coastguard Worker
39*6dbdd20aSAndroid Build Coastguard Worker
40*6dbdd20aSAndroid Build Coastguard Workerdef main():
41*6dbdd20aSAndroid Build Coastguard Worker  DEFAULT_PROJECT_ID = 'perfetto-ci'
42*6dbdd20aSAndroid Build Coastguard Worker  # project_id = os.getenv('CLOUDSDK_CORE_PROJECT', DEFAULT_PROJECT_ID)
43*6dbdd20aSAndroid Build Coastguard Worker
44*6dbdd20aSAndroid Build Coastguard Worker  parser = argparse.ArgumentParser()
45*6dbdd20aSAndroid Build Coastguard Worker  parser.add_argument(
46*6dbdd20aSAndroid Build Coastguard Worker      '-p',
47*6dbdd20aSAndroid Build Coastguard Worker      '--project-id',
48*6dbdd20aSAndroid Build Coastguard Worker      metavar='PROJECT_ID',
49*6dbdd20aSAndroid Build Coastguard Worker      required=False,
50*6dbdd20aSAndroid Build Coastguard Worker      help='The Cloud project id. Defaults to CLOUDSDK_CORE_PROJECT',
51*6dbdd20aSAndroid Build Coastguard Worker      default=os.getenv('CLOUDSDK_CORE_PROJECT', DEFAULT_PROJECT_ID))
52*6dbdd20aSAndroid Build Coastguard Worker  args = parser.parse_args()
53*6dbdd20aSAndroid Build Coastguard Worker  project_id = args.project_id
54*6dbdd20aSAndroid Build Coastguard Worker
55*6dbdd20aSAndroid Build Coastguard Worker  print('Using Cloud project: %s' % project_id)
56*6dbdd20aSAndroid Build Coastguard Worker  print('If this script fail ensure that:')
57*6dbdd20aSAndroid Build Coastguard Worker  print(' - The cloud project has been configured as per go/gce-beyondcorp-ssh')
58*6dbdd20aSAndroid Build Coastguard Worker  print(' - Register your key as per "Ensure that you are registered with OS')
59*6dbdd20aSAndroid Build Coastguard Worker
60*6dbdd20aSAndroid Build Coastguard Worker  instances = list_instances(project_id)
61*6dbdd20aSAndroid Build Coastguard Worker  if not instances:
62*6dbdd20aSAndroid Build Coastguard Worker    print('No GCE instances found.')
63*6dbdd20aSAndroid Build Coastguard Worker    sys.exit(0)
64*6dbdd20aSAndroid Build Coastguard Worker
65*6dbdd20aSAndroid Build Coastguard Worker  print('Available VMs:')
66*6dbdd20aSAndroid Build Coastguard Worker  for idx, (name, zone) in enumerate(instances, start=1):
67*6dbdd20aSAndroid Build Coastguard Worker    print(f'{idx}. {name} ({zone})')
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker  try:
70*6dbdd20aSAndroid Build Coastguard Worker    vm_number = int(input('Enter the number of the VM you want to ssh into: '))
71*6dbdd20aSAndroid Build Coastguard Worker    if vm_number < 1 or vm_number > len(instances):
72*6dbdd20aSAndroid Build Coastguard Worker      raise ValueError
73*6dbdd20aSAndroid Build Coastguard Worker  except ValueError:
74*6dbdd20aSAndroid Build Coastguard Worker    print('Invalid selection. Please run the script again.')
75*6dbdd20aSAndroid Build Coastguard Worker    sys.exit(1)
76*6dbdd20aSAndroid Build Coastguard Worker
77*6dbdd20aSAndroid Build Coastguard Worker  # Get the selected VM's name and zone
78*6dbdd20aSAndroid Build Coastguard Worker  selected_instance = instances[vm_number - 1]
79*6dbdd20aSAndroid Build Coastguard Worker  vm_name, vm_zone = selected_instance
80*6dbdd20aSAndroid Build Coastguard Worker  user = os.getenv('USER', 'username')
81*6dbdd20aSAndroid Build Coastguard Worker  ssh_arg = '%s_google_com@nic0.%s.%s.c.%s.internal.gcpnode.com' % (
82*6dbdd20aSAndroid Build Coastguard Worker      user, vm_name, vm_zone, project_id)
83*6dbdd20aSAndroid Build Coastguard Worker  print('ssh ' + ssh_arg)
84*6dbdd20aSAndroid Build Coastguard Worker  os.execvp('ssh', ['ssh', ssh_arg])
85*6dbdd20aSAndroid Build Coastguard Worker
86*6dbdd20aSAndroid Build Coastguard Worker
87*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__':
88*6dbdd20aSAndroid Build Coastguard Worker  main()
89