1#! /bin/bash 2# 3# Copyright (C) 2023 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 17set -e 18 19ART_TEST_ON_VM=true . "$(dirname $0)/buildbot-utils.sh" 20SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 21 22known_actions="create|boot|geniso|install-keys|setup-ssh|connect|quit" 23 24if [[ -z $ANDROID_BUILD_TOP ]]; then 25 msgfatal "ANDROID_BUILD_TOP is not set" 26elif [[ ( $# -ne 1 ) || ! ( "$1" =~ ^($known_actions)$ ) ]]; then 27 msgfatal "usage: $0 <$known_actions>" 28fi 29 30action="$1" 31 32get_stable_binary() { 33 mkdir tmp && cd tmp 34 wget "http://security.ubuntu.com/ubuntu/pool/main/$1" 35 ar x "$(basename $1)" && zstd -d data.tar.zst && tar -xf data.tar 36 mv "$2" .. 37 cd .. && rm -rf tmp 38} 39 40if [[ $action = create ]]; then 41( 42 rm -rf "$ART_TEST_VM_DIR" 43 mkdir -p "$ART_TEST_VM_DIR" 44 cd "$ART_TEST_VM_DIR" 45 46 # sudo apt install qemu-system-<arch> qemu-efi cloud-image-utils 47 48 # Get the cloud image for Ubuntu 24.04 LTS (Noble Numbat) 49 wget "http://cloud-images.ubuntu.com/releases/24.04/release/$ART_TEST_VM_IMG" 50 51 if [[ "$TARGET_ARCH" = "riscv64" ]]; then 52 # Get U-Boot 53 get_stable_binary \ 54 u/u-boot/u-boot-qemu_2024.01+dfsg-5ubuntu2_all.deb \ 55 usr/lib/u-boot/qemu-riscv64_smode/uboot.elf 56 57 elif [[ "$TARGET_ARCH" = "arm64" ]]; then 58 # Get EFI (ARM64) 59 get_stable_binary \ 60 e/edk2/qemu-efi-aarch64_2024.05-2ubuntu0.1_all.deb \ 61 usr/share/qemu-efi-aarch64/QEMU_EFI.fd 62 63 dd if=/dev/zero of=flash0.img bs=1M count=64 64 dd if=QEMU_EFI.fd of=flash0.img conv=notrunc 65 dd if=/dev/zero of=flash1.img bs=1M count=64 66 fi 67 68 qemu-img resize "$ART_TEST_VM_IMG" +128G 69) 70elif [[ $action = geniso ]]; then 71( 72 #https://help.ubuntu.com/community/CloudInit 73 cat >user-data <<EOF 74#cloud-config 75ssh_pwauth: true 76chpasswd: 77 expire: false 78 users: 79 - name: $ART_TEST_SSH_USER 80 password: ubuntu 81 type: text 82users: 83 - default 84 - name: $ART_TEST_SSH_USER 85 ssh_authorized_keys: 86 - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCOYmwd9qoYd7rfYI6Q8zzqoZ3BtLC/SQo0WCvBFoJT6JzwU8F7nkN57KBQPLtvX2OBeDnFbtEY8uLtuNEp1Z19VcDbRd3LhyAMYFz6Ox/vWtPfl0hv0kUMQMAne1Bg0tawlNxawP2HXrLOh/FaXdSBSRUHNqMTQEnkIYw4faArDS/zKjVDs0/+e9mhtjL0akLcK04crlk2KD8Q2csya5givdAD7fVNOx7DtckRR47FLM1bERe0t0FlUESx/x7oLjNEmNUrPXV6GSkCoskmKSZC1vwgAf0VrxFADv1EywQXmlNaa4+rzqS4jMYuwi5QCtQXFFZl5qQ1Sh1rnliTRJvJzjXCeq3QPsPzUJInfVGzrPClfHG7whlJE/Uwv8UOF7WHzUt5OBOsW6nZrplldvfYif/qz6dR+RX2G0zi8tC/2Mzahr6toAqtsqbdp3coYvpi/OjHIV3RhyJxG1FtyGYQRnmGPs8R9ic3pupjLFWM9qIilUCjFrUoiw7QAgfUrUc= ubuntu_user@example.com 87 sudo: ALL=(ALL) NOPASSWD:ALL 88 groups: users, admin 89write_files: 90 - path: /etc/sysctl.d/60-apparmor.conf 91 permissions: 0644 92 owner: root 93 content: | 94 kernel.apparmor_restrict_unprivileged_userns=0 95runcmd: 96 - systemctl restart systemd-sysctl 97EOF 98 # meta-data is necessary, even if empty. 99 cat >meta-data <<EOF 100EOF 101 genisoimage -output user-data.img -volid cidata -joliet -rock user-data meta-data 102 mv user-data.img "$(dirname $0)/user-data.img" 103 rm user-data meta-data 104) 105elif [[ $action = boot ]]; then 106( 107 cp "$(dirname $0)/user-data.img" "$ART_TEST_VM_DIR/user-data.img" 108 cd "$ART_TEST_VM_DIR" 109 if [[ "$TARGET_ARCH" = "riscv64" ]]; then 110 echo -n > $SCRIPT_DIR/boot.out 111 ($ANDROID_BUILD_TOP/device/google/cuttlefish_vmm/qemu/x86_64-linux-gnu/bin/qemu-system-riscv64 \ 112 -M virt \ 113 -nographic \ 114 -m 16G \ 115 -smp 8 \ 116 -cpu rv64,v=true,elen=64,vlen=128,zba=true,zbb=true,zbs=true \ 117 -kernel uboot.elf \ 118 -drive file="$ART_TEST_VM_IMG",if=virtio \ 119 -drive file=user-data.img,format=raw,if=virtio \ 120 -device virtio-net-device,netdev=usernet \ 121 -netdev user,id=usernet,hostfwd=tcp::$ART_TEST_SSH_PORT-:22 >> $SCRIPT_DIR/boot.out &) 122 echo "Now listening for successful boot" 123 finish_str='.*finished at.*' 124 while IFS= read -d $'\0' -n 1 a ; do 125 line+="${a}" 126 if [[ "$line" =~ $finish_str ]] ; then 127 echo $line 128 echo "VM Successfully booted!" 129 exit 0 130 elif [[ $a = $'\n' ]] 131 then 132 echo $line 133 unset line 134 fi 135 done < <(tail -f $SCRIPT_DIR/boot.out) 136 137 elif [[ "$TARGET_ARCH" = "arm64" ]]; then 138 echo -n > $SCRIPT_DIR/boot.out 139 (qemu-system-aarch64 \ 140 -m 16G \ 141 -smp 8 \ 142 -cpu cortex-a710,sve=on \ 143 -M virt \ 144 -nographic \ 145 -drive if=none,file="$ART_TEST_VM_IMG",id=hd0 \ 146 -pflash flash0.img \ 147 -pflash flash1.img \ 148 -drive file=user-data.img,format=raw,id=cloud \ 149 -device virtio-blk-device,drive=hd0 \ 150 -device virtio-net-device,netdev=usernet \ 151 -netdev user,id=usernet,hostfwd=tcp::$ART_TEST_SSH_PORT-:22 >> $SCRIPT_DIR/boot.out &) 152 echo "Now listening for successful boot" 153 finish_str='.*finished at.*' 154 while IFS= read -d $'\0' -n 1 a ; do 155 line+="${a}" 156 if [[ "$line" =~ $finish_str ]] ; then 157 echo $line 158 echo "VM Successfully booted!" 159 exit 0 160 elif [[ $a = $'\n' ]] 161 then 162 echo $line 163 unset line 164 fi 165 done < <(tail -f $SCRIPT_DIR/boot.out) 166 fi 167 168) 169elif [[ $action = setup-ssh ]]; then 170 # Clean up mentions of this VM from known_hosts 171 sed -i -E "/\[$ART_TEST_SSH_HOST.*\]:$ART_TEST_SSH_PORT .*/d" $HOME/.ssh/known_hosts 172 ssh-copy-id -p "$ART_TEST_SSH_PORT" -o IdentityAgent=none -o StrictHostKeyChecking=no "$ART_TEST_SSH_USER@$ART_TEST_SSH_HOST" 173 174elif [[ $action = install-keys ]]; then 175 if [ -f "$HOME/.ssh/known_hosts" ]; then 176 sed -i -E "/\[$ART_TEST_SSH_HOST.*\]:$ART_TEST_SSH_PORT .*/d" $HOME/.ssh/known_hosts 177 fi 178 # This key is only used to authorize access to a local test VM and does 179 # not pose any security risk. 180 echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCOYmwd9qoYd7rfYI6Q8zzqoZ3BtLC/SQo0WCvBFoJT6JzwU8F7nkN57KBQPLtvX2OBeDnFbtEY8uLtuNEp1Z19VcDbRd3LhyAMYFz6Ox/vWtPfl0hv0kUMQMAne1Bg0tawlNxawP2HXrLOh/FaXdSBSRUHNqMTQEnkIYw4faArDS/zKjVDs0/+e9mhtjL0akLcK04crlk2KD8Q2csya5givdAD7fVNOx7DtckRR47FLM1bERe0t0FlUESx/x7oLjNEmNUrPXV6GSkCoskmKSZC1vwgAf0VrxFADv1EywQXmlNaa4+rzqS4jMYuwi5QCtQXFFZl5qQ1Sh1rnliTRJvJzjXCeq3QPsPzUJInfVGzrPClfHG7whlJE/Uwv8UOF7WHzUt5OBOsW6nZrplldvfYif/qz6dR+RX2G0zi8tC/2Mzahr6toAqtsqbdp3coYvpi/OjHIV3RhyJxG1FtyGYQRnmGPs8R9ic3pupjLFWM9qIilUCjFrUoiw7QAgfUrUc= ubuntu_user@example.com" > ~/.ssh/ubuntu.pub 181 echo "-----BEGIN OPENSSH PRIVATE KEY----- 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 218-----END OPENSSH PRIVATE KEY-----" > ~/.ssh/ubuntu 219 chmod 600 ~/.ssh/ubuntu 220 221elif [[ $action = connect ]]; then 222 $ART_SSH_CMD 223 224elif [[ $action = quit ]]; then 225 $ART_SSH_CMD "sudo poweroff" 226 227fi 228