Flutter Integration Test Server in Debian 11 Nspawn Container
+ +date: 2021-09-24
+Introduction
+Performance
+Your Debian Server is way more powerful than your laptop or desktop +and flutter integration_tests suck.
+Ergonomics
+You have an Android Emulator (or a real device) connected to the machine +that you are sitting in front of for reference, and now you can run +integration_tests on a different device without having to juggle adb +connections on the same machine.
+Nspawn Tho?
+Because containers unlike virtual machines access the full power of the +host, but nspawn containers are peristent like virtual machines, sparing +you the cognitive overhead of dealing with the ephemerality of docker +containers and/or of herding cats.
+And you already have nspawn, it's build into systemd. Even including the +(virtual) network interfaces.
+Documentation
+Let's face it: setting up an Android Development Environment is a nightmare.
+So don't just follow this guide; follow this guide a repetition of three +times, building your own step-by-step for yourself as you go. Your brain +will thank you.
+Host Preparation (Debian 11)
+-
+
- install
systemd-container
anddebootstrap
+ - enable unprivileged user namespaces
-
+
echo 'kernel.unprivileged_userns_clone=1' >/etc/sysctl.d/nspawn.conf
+systemctl restart systemd-sysctl.service
+
+ - you might as well allow debootstrap to user your apt-cacher-ng proxy
-
+
export http_proxy=http://<ip address>:3142
+
+
br0 bridge
+describe br0 bridge in /etc/systemd/nspawn/ftest.nspawn
(optional).
+
# /etc/systemd/nspawn/ftest.nspawn
+[Network]
+VirtualEthernet=yes
+Bridge=br0
+
ZFS mountpoint
+This is optional, obviously; you might not even use zfs.
+-
+
zfs create vm_pool/nspawn/ftest
+zfs set mountpoint=/var/lib/machines/ftest vm_pool/nspawn/ftest
+- sanity check
zfs list -r vm_pool/nspawn
+
bootstrap container
+# for apt-cacher-ng proxy
+export http_proxy=http://<ip address>:3142
+
+debootstrap --include=systemd-container stable /var/list/machines/ftest
+
preboot config
+-
+
- delete container's package cache +
- copy
/etc/apt/apt.conf
to container
+ - copy
/root/.bashrc
to container
+ - copy
/root/.inputrc
to container
+ - edit
/etc/hostname
in container
+ - write nspawn file on host +
- copy
/etc/locale.gen
to/etc/locale.gen.bak
on container
+
first interactive boot
+-
+
systemd-nspawn -D /var/lib/machines/ftest -U --machine ftest
+- set passwd:
passwd
+ - stop container:
logout
+
run as service
+-
+
systemctl start systemd-nspawn@ftest
+- login:
machinectl login ftest
+ - start/enable network
systemctl enable --now systemd-networkd
+ - add regular user
useradd <username>
+
install applications
+locale
+-
+
- install locales +
- edit
/etc/locale.gen
to taste and then run the commandlocale-gen
+
essential apps
+apt-get install openssh-server git unzip wget sudo curl file rsync
+
add regular user to sudo group
+usermod -a -G sudo <user>
other apps
+apt-get install mosh htop haveged byobu needrestart tree bash-completion
+
install openjdk-8 from stretch repo
+-
+
- add following to
/etc/apt/sources.list
+deb http://security.debian.org/debian-security stretch/updates main +
+ apt-get update && apt-get install openjdk-8-jdk-headless
+
user environment
+You can now ssh into your container.
+scp your favorite environment files over to the container
+-
+
- ~/.byobu/ +
- ~/.bashrc +
- ~/.bash_aliases +
- ~/.inputrc +
install flutter
+Pick a location to taste; I prefer ~/.local/
+
cd ; cd .local
+git clone https://github.com/flutter/flutter.git
+
downgrade flutter
+if needed: +
cd ~/.local/flutter
+git checkout 2.2.3
+
install command-line-tools
+The schuck and jive here is absurd, but here goes.
+Now is the time to decide where ANDROID_HOME and ANDROID_SDK_ROOT
+are going to be; I prefer ~/.local/share/Android/Sdk/
+
mkdir -p ~/.local/share/Android/Sdk
+
temporary installation of cmdline-tools
+Command line tools only Scroll half way down +
cd ~/.local/share/Android/Sdk
+wget https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip
+unzip commandlinetools-linux-7583922_latest.zip
+mkdir 5.0
+mv cmdline-tools/* 5.0/
+mv 5.0 cmdline-tools/
+
flutter and sdk environment
+add the following to ~/.bashrc
+
function addToPATH {
+ case ":$PATH:" in
+ *":$1:"*) :;; # already there
+ *) PATH="$PATH:$1";; # or PATH="$PATH:$1"
+ esac
+}
+
+addToPATH ~/.local/flutter/bin
+addToPATH ~/.local/share/Android/Sdk/cmdline-tools/latest/bin
+addToPATH ~/.local/share/Android/Sdk/platform-tools
+
+# temporary path to temporary version of cmdline-tools
+addToPATH ~/.local/share/Android/Sdk/cmdline-tools/5.0/bin
+
add the following to ~/.bash_aliases
+
alias sdkmanager='sdkmanager --sdk_root=~/.local/share/Android/Sdk'
+
Confirm by logging out and then back in and: +
which flutter ; which sdkmanager ; alias
+
now install cmdline-tools for real
+sdkmanager --install "cmdline-tools;latest"
and then logout and log back in
+cleanup
+At this point I think you can remove or comment the temporary PATH
+statement from ~/.bashrc
for the temporary location of cmdline-tools
install Android SDK
+review your options +
sdkmanager --list
+
sdkmanager --install "platforms;android-30" \
+ "build-tools;31.0.0" "build-tools;30.0.3"
+
confirm flutter installation
+flutter doctor
run tests
+At this point you shoud be able to rsync a flutter app over to the container, connect to a device using network adb, +and run something like: +
flutter drive --driver integration_test/driver.dart \
+ --target integration_test/app_test.dart --profile
+