diff --git a/docs/posts/debian-11-nspawn-flutter-integration-test-server.md b/docs/posts/debian-11-nspawn-flutter-integration-test-server.md new file mode 100644 index 0000000..6d6f481 --- /dev/null +++ b/docs/posts/debian-11-nspawn-flutter-integration-test-server.md @@ -0,0 +1,206 @@ +--- +title: "Flutter Integration Test Server in Debian 11 Nspawn Container" +date: 2021-09-24 +draft: false +tags: ["debian", "nspawn", "android", "flutter"] +authors: ["trent"] +post: 22 +--- +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) +1. install `systemd-container` and `debootstrap` +2. enable unprivileged user namespaces + * `echo 'kernel.unprivileged_userns_clone=1' >/etc/sysctl.d/nspawn.conf` + * `systemctl restart systemd-sysctl.service` +3. you might as well allow debootstrap to user your apt-cacher-ng proxy + * `export http_proxy=http://:3142` +### br0 bridge +describe br0 bridge in `/etc/systemd/nspawn/ftest.nspawn` (optional). +```cfg +# /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 +```shell +# for apt-cacher-ng proxy +export http_proxy=http://:3142 + +debootstrap --include=systemd-container stable /var/list/machines/ftest +``` + +## preboot config +1. delete container's package cache +2. copy `/etc/apt/apt.conf` to container +2. copy `/root/.bashrc` to container +2. copy `/root/.inputrc` to container +2. edit `/etc/hostname` in container +2. [write nspawn file on host](#br0-bridge) +2. copy `/etc/locale.gen` to `/etc/locale.gen.bak` on container + +## first interactive boot +1. `systemd-nspawn -D /var/lib/machines/ftest -U --machine ftest` +2. set passwd: `passwd` +2. stop container: `logout` + +## run as service +1. `systemctl start systemd-nspawn@ftest` +2. login: `machinectl login ftest` +2. start/enable network `systemctl enable --now systemd-networkd` +2. add regular user `useradd ` + +## install applications +### locale +* install locales +* edit `/etc/locale.gen` to taste and then run the command `locale-gen` +### essential apps +```shell +apt-get install openssh-server git unzip wget sudo curl file rsync +``` +### add regular user to sudo group +`usermod -a -G sudo ` +### other apps +```shell +apt-get install mosh htop haveged byobu needrestart tree bash-completion +``` +### install openjdk-8 from stretch repo +1. add following to `/etc/apt/sources.list` +```cfg +deb http://security.debian.org/debian-security stretch/updates main +``` +2. `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/` +```shell +cd ; cd .local +git clone https://github.com/flutter/flutter.git +``` +### downgrade flutter +if needed: +```shell +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/` +```shell +mkdir -p ~/.local/share/Android/Sdk +``` +### temporary installation of cmdline-tools +[Command line tools only Scroll half way down](https://developer.android.com/studio){target="_blank"} +```shell +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` +```cfg +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` +```cfg +alias sdkmanager='sdkmanager --sdk_root=~/.local/share/Android/Sdk' +``` + + +Confirm by logging out and then back in and: +```shell +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 +```shell +sdkmanager --list +``` +and then install them +(platform-tools: adb and fastboot will be pulled in automatically) +```shell +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: +```shell +flutter drive --driver integration_test/driver.dart \ + --target integration_test/app_test.dart --profile +``` diff --git a/mkdocs.yml b/mkdocs.yml index 0e3a313..789ef8c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,7 @@ markdown_extensions: nav: - Home: - Home: index.md + - "Flutter Integration Test Server in Debian 11 Nspawn Container": posts/debian-11-nspawn-flutter-integration-test-server.md - "Debian 11 TT-RSS": posts/debian-11-ttrss.md - "Trent's Favorite Podcasts": posts/trents-favorite-podcasts.md - "Test QR SVG Django": posts/test-qr-svg-django.md @@ -59,6 +60,7 @@ nav: - FreeCodeCampChallenges: https://trentspalmer.github.io/fcc-challenges/ - DeviceLayout: https://trentpalmer.work/6a57bbe24d8244289610bf57533d6c6f/ - Posts: + - "Flutter Integration Test Server in Debian 11 Nspawn Container": posts/debian-11-nspawn-flutter-integration-test-server.md - "Debian 11 TT-RSS": posts/debian-11-ttrss.md - "Trent's Favorite Podcasts": posts/trents-favorite-podcasts.md - "Test QR SVG Django": posts/test-qr-svg-django.md