Categories
Status

Running x86 Android Emulators in the Cloud (Incomplete)

The problem

I was recently presented with the problem of testing a system that required two android emulators running side by side in coordination. Our QA team had set this up to work on a local windows machine, but we were exploring alternatives and desired moving our testing activities to the cloud.

Attempts

We started out exploring CircleCI. This is a familiar Cloud CI tool, but they do not support emulators. We also explored using their MacOS variants, which appear to be hosted on ESX, but I ran into GPU driver issues.

EC2 instances did not have any virtualization extensions exposed to the VM. This left us with only being able to use ARM emulation which is extremely slow and would probably take us an entire day or more to run our entire test suite.

After reading the docs on how to configure hardware acceleration for the Android Emulator, I realized that we needed to have access to virtualization extensions inside our VM/container. In virtualization speak, we needed “nested virtualization.” Both Google Cloud and Azure support nested virtualization, but I am more familiar with Google Cloud Platform so I started out on GCP.

The solution

A virtual machine hosted inside GCP that supports nested virtualization. We are going to setup our solution on Debian, but I have also had it working on Ubuntu. Let’s get started.

To begin, we will follow the instructions defined here

Create a disk to use:

gcloud compute disks create disk1 --size=30gb --image-project ubuntu-os-cloud --image-family ubuntu-1604-lts  --zone us-central1-b

Create an image from the disk and enable nested virtualization

gcloud compute images create android-emulator-image \
  --source-disk disk1 --source-disk-zone us-central1-b \
  --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"

Create an instance from the image. It needs to be at least Haswell and we are using a machine-type that has a few extra cores which will help us run both emulators at the same time.

gcloud compute instances create android-emulator-vm --zone us-central1-b \
	      --machine-type n1-standard-4 \
              --min-cpu-platform "Intel Haswell" \
              --image android-emulator-image

Let’s SSH to the instance and make sure that we have virtualization available

gcloud compute ssh android-emulator-vm

#! Inside VM
grep -cw vmx /proc/cpuinfo

You should get a non zero value to indicate that nested virtualization is enabled.

Now, let’s configure our VM so that we can connect to it using VNC and use virtualization.

sudo apt-get update -y

sudo apt-get install xfce4 qemu-kvm tightvncserver iceweasel -y

We can now start our VNC server using the following command. We will be prompted for a password. Enter in a password and remember it.

vncserver

Once we start the server it will create a few configuration files for us. We need to stop our VNC server nad update our config files so that we get a more usable display when we connect to our VNC server.

vncserver -kill :1
vi ~/.vnc/xstartup

Inside xstartup, enter in the following details:

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &

Let’s startup our VNC server with the new config and connect to it.

vncserver

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.