1#!/bin/bash
2
3# Copyright 2020 Google Inc. All rights reserved.
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# vm_shell.sh: utilities to interact with Microdroid VMs
18
19function print_help() {
20    echo "vm_shell.sh provides utilities to interact with Microdroid VMs"
21    echo ""
22    echo "Available commands:"
23    echo "    connect [cid] - establishes adb connection with the VM"
24    echo "      cid - cid of the VM to connect to. If not specified user will "
25    echo "            be promted to select one from the list of available cids"
26    echo ""
27    echo "    start-microdroid [--auto-connect] [-- extra_args]"
28    echo "        Starts a Microdroid VM. Args after the -- will be"
29    echo "        passed through to the invocation of the "
30    echo "        /apex/com.android.virt/bin/vm run-microdroid binary."
31    echo ""
32    echo "        E.g.:"
33    echo "            vm_shell start-microdroid -- --protected --debug full"
34    echo ""
35    echo "        --auto-connect - automatically connects to the started VMs"
36    echo ""
37    echo "    help - prints this help message"
38}
39
40function connect_vm() {
41    cid=$1
42    echo Connecting to CID ${cid}
43    adb disconnect localhost:8000 2>/dev/null
44    adb forward tcp:8000 vsock:${cid}:5555
45    adb connect localhost:8000
46    adb -s localhost:8000 root
47    adb -s localhost:8000 wait-for-device
48    adb -s localhost:8000 shell
49    exit 0
50}
51
52function list_cids() {
53    local selected_cid=$1
54    local available_cids=$(adb shell /apex/com.android.virt/bin/vm list | awk 'BEGIN { FS="[:,]" } /cid/ { print $2; }')
55    echo "${available_cids}"
56}
57
58function handle_connect_cmd() {
59    selected_cid=$1
60
61    available_cids=$(list_cids)
62
63    if [ -z "${available_cids}" ]; then
64        echo No VM is available
65        exit 1
66    fi
67
68    if [ ! -n "${selected_cid}" ]; then
69        if [ ${#selected_cid[@]} -eq 1 ]; then
70            selected_cid=${available_cids[0]}
71        else
72            PS3="Select CID of VM to adb-shell into: "
73            select cid in ${available_cids}
74            do
75                selected_cid=${cid}
76                break
77            done
78        fi
79    fi
80
81    if [[ ! " ${available_cids[*]} " =~ " ${selected_cid} " ]]; then
82        echo VM of CID $selected_cid does not exist. Available CIDs: ${available_cids}
83        exit 1
84    fi
85
86    connect_vm ${selected_cid}
87}
88
89function handle_start_microdroid_cmd() {
90    while [[ "$#" -gt 0 ]]; do
91        case $1 in
92          --auto-connect) auto_connect=true; ;;
93          --) shift; passthrough_args="$@"; break ;;
94          *) echo "Unknown argument: $1"; exit 1 ;;
95        esac
96        shift
97    done
98    if [[ "${auto_connect}" == true ]]; then
99        adb shell /apex/com.android.virt/bin/vm run-microdroid "${passthrough_args}" &
100        trap "kill $!" EXIT
101        sleep 2
102        handle_connect_cmd
103    else
104        adb shell /apex/com.android.virt/bin/vm run-microdroid "${passthrough_args}"
105    fi
106}
107
108cmd=$1
109shift
110
111case $cmd in
112  connect) handle_connect_cmd "$@" ;;
113  start-microdroid) handle_start_microdroid_cmd "$@" ;;
114  help) print_help ;;
115  *) print_help; exit 1 ;;
116esac
117