Integrate Docker into the build

- Isolates us from the host -- no more accidentally using a feature
that's present on a newer distro but not the build machine; no more
relying on packages you didn't realize you installed
- Both continuous build and rootfs leverage this, as well as local
builds

Continuous and rootfs build results on Kokoro w/ this change:
- https://sponge.corp.google.com/target?id=c061e5b2-b94f-4056-bf25-c69e25a71ed3&target=spacepark/enterprise/continuous-test
- https://sponge.corp.google.com/target?id=d6f312f2-9610-4be1-b7f1-cc7e7c7db6d9&target=spacepark/enterprise/rootfs-test

Change-Id: I95b305054ed16269b83bbcbaf89d8b89d8628fad
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..c7f1c12
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,17 @@
+FROM debian:9.4
+MAINTAINER support-aiyprojects@google.com
+
+# Install Docker into this image, so we can run nested containers for ARM64 builds.
+RUN apt-get update -qq && apt-get install -qqy \
+        apt-transport-https \
+        ca-certificates \
+        curl \
+        lxc \
+        iptables
+RUN curl -sSL https://get.docker.com/ | sh
+
+# Install the prerequisite packages into the image.
+ADD . /build
+RUN /bin/bash -c 'apt-get update && apt-get install sudo make && ln -sfr /build/Makefile /Makefile && source /build/setup.sh && make -C /build prereqs'
+
+VOLUME /var/lib/docker
diff --git a/Makefile b/Makefile
index 5ffcef6..d64c3d8 100644
--- a/Makefile
+++ b/Makefile
@@ -43,6 +43,8 @@
 include $(ROOTDIR)/build/signing.mk
 include $(ROOTDIR)/build/u-boot.mk
 
+include $(ROOTDIR)/build/docker.mk
+
 clean::
 	rm -rf $(ROOTDIR)/out
 
diff --git a/docker.mk b/docker.mk
new file mode 100644
index 0000000..4ff6eb2
--- /dev/null
+++ b/docker.mk
@@ -0,0 +1,60 @@
+ifeq ($(ROOTDIR),)
+$(error $$ROOTDIR IS NOT DEFINED -- don\'t forget to source setup.sh)
+endif
+
+include $(ROOTDIR)/build/preamble.mk
+
+DOCKER_FETCH_TARBALL ?= true
+
+ifeq ($(DOCKER_FETCH_TARBALL),true)
+$(ROOTDIR)/cache/aiy-board-builder.tar: $(PREBUILT_DOCKER_ROOT)/aiy-board-builder.tar
+	mkdir -p $(ROOTDIR)/cache
+	cp $< $(ROOTDIR)/cache
+else
+$(ROOTDIR)/cache/aiy-board-builder.tar:
+	mkdir -p $(ROOTDIR)/cache
+	docker build -t aiy-board-builder $(ROOTDIR)/build
+	docker image save -o $@ aiy-board-builder:latest
+	docker rmi aiy-board-builder:latest
+endif
+
+docker-build: $(ROOTDIR)/cache/aiy-board-builder.tar
+
+define docker-run
+docker-$1: docker-build;
+	docker load -i $(ROOTDIR)/cache/aiy-board-builder.tar
+	docker run --rm --privileged --tty \
+	   -v /dev\:/dev \
+	   -v $(ROOTDIR)\:/build \
+	   -v $(TARBALL_FETCH_ROOT_DIRECTORY)\:/tarballs \
+	   -v $(PREBUILT_DOCKER_ROOT)\:/docker \
+	   -v $(PREBUILT_MODULES_ROOT)\:/modules \
+	   -w /build \
+		 -e "DEBOOTSTRAP_FETCH_TARBALL=$(DEBOOTSTRAP_FETCH_TARBALL)" \
+		 -e "ROOTFS_FETCH_TARBALL=$(ROOTFS_FETCH_TARBALL)" \
+		 -e "TARBALL_FETCH_ROOT_DIRECTORY=/tarballs" \
+		 -e "PREBUILT_DOCKER_ROOT=/docker" \
+		 -e "ROOTFS_REVISION=$(ROOTFS_REVISION)" \
+		 -e "DEBOOTSTRAP_TARBALL_REVISION=$(DEBOOTSTRAP_TARBALL_REVISION)" \
+		 -e "PREBUILT_MODULES_ROOT=/modules" \
+	   aiy-board-builder \
+	   /bin/bash -c \
+	   'groupadd --gid $$(shell id -g) $$(shell id -g -n); \
+	   useradd -m -e "" -s /bin/bash --gid $$(shell id -g) --uid $$(shell id -u) $$(shell id -u -n); \
+	   passwd -d $$(shell id -u -n); \
+	   echo "$$(shell id -u -n) ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers; \
+	   adduser $$(shell id -u -n) docker; \
+	   /etc/init.d/docker start; \
+	   sudo -E -u $$(shell id -u -n) /bin/bash -c "source build/setup.sh; m \
+		  -j$(shell nproc) $2";'
+endef
+
+$(call docker-run,bootstrap,make-bootstrap-tarball)
+$(call docker-run,rootfs,rootfs_raw)
+$(call docker-run,boot,boot)
+$(call docker-run,all,boot-targets)
+$(call docker-run,sdcard,sdcard)
+
+.DEFAULT_GOAL:=docker-all
+
+.PHONY:: docker-build
diff --git a/kernel-modules.mk b/kernel-modules.mk
index f5d5c5d..4f12ca7 100644
--- a/kernel-modules.mk
+++ b/kernel-modules.mk
@@ -19,7 +19,7 @@
 	$$(warning "No source for $1")
 	cp $(PREBUILT_MODULES_ROOT)/$1.deb $(PRODUCT_OUT)
 else
-$(PRODUCT_OUT)/.$1: $(shell find $(ROOTDIR)/modules/$1 -type f) $(KERNEL_OUT_DIR)/.config $(KERNEL_OUT_DIR)/arch/arm64/boot/Image
+$(PRODUCT_OUT)/.$1: $$(shell find $(ROOTDIR)/modules/$1 -type f) $(KERNEL_OUT_DIR)/.config $(KERNEL_OUT_DIR)/arch/arm64/boot/Image
 	mkdir -p $(PRODUCT_OUT)/obj/MODULE_OBJ/$1/debian
 	cp -afs $(ROOTDIR)/modules/$1/* $(PRODUCT_OUT)/obj/MODULE_OBJ/$1
 	cp -r $(ROOTDIR)/build/$1-debian/* $(PRODUCT_OUT)/obj/MODULE_OBJ/$1/debian/
diff --git a/kokoro/continuous.sh b/kokoro/continuous.sh
index 8d3a3ad..d33babf 100644
--- a/kokoro/continuous.sh
+++ b/kokoro/continuous.sh
@@ -18,10 +18,8 @@
 export DEBOOTSTRAP_TARBALL_REVISION=.
 export ROOTFS_REVISION=.
 
-m prereqs
-
-m
-m sdcard
+m docker-all
+m docker-sdcard
 
 pushd ${ROOTDIR}
 python3 ${ROOTDIR}/build/create_release_manifest.py \
diff --git a/kokoro/rootfs.cfg b/kokoro/rootfs.cfg
index ed75839..f285cd0 100644
--- a/kokoro/rootfs.cfg
+++ b/kokoro/rootfs.cfg
@@ -1,5 +1,7 @@
 build_file: "build/kokoro/rootfs.sh"
 
+gfile_resources: "/x20/teams/spacepark/enterprise/kokoro/prod/spacepark/enterprise/docker/aiy-board-builder.tar"
+
 action {
   define_artifacts {
     regex: "debootstrap.tgz"
diff --git a/kokoro/rootfs.sh b/kokoro/rootfs.sh
index 1a200b5..5d4936a 100644
--- a/kokoro/rootfs.sh
+++ b/kokoro/rootfs.sh
@@ -7,17 +7,12 @@
 source build/setup.sh
 popd
 
-# Debootstrap on 14.04 is very old and buggy. Update to the 16.04 version.
-echo "deb http://archive.ubuntu.com/ubuntu xenial main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
-sudo apt-get update
-sudo apt-get install --no-install-recommends -y debootstrap/xenial
-
 export DEBOOTSTRAP_FETCH_TARBALL=false
 export ROOTFS_FETCH_TARBALL=false
+export PREBUILT_DOCKER_ROOT=$KOKORO_GFILE_DIR
 
-m prereqs
-mm debootstrap make-bootstrap-tarball
-mm rootfs rootfs_raw
+m docker-bootstrap
+m docker-rootfs
 
 cp git/cache/debootstrap.tgz $KOKORO_ARTIFACTS_DIR
 cp git/cache/debootstrap.tgz.sha256sum $KOKORO_ARTIFACTS_DIR
diff --git a/preamble.mk b/preamble.mk
index 42e9da1..fe65a39 100644
--- a/preamble.mk
+++ b/preamble.mk
@@ -109,3 +109,5 @@
 
 TARBALL_FETCH_ROOT_DIRECTORY ?= \
 	/google/data/ro/teams/spacepark/enterprise/kokoro/prod/spacepark/enterprise/rootfs
+
+PREBUILT_DOCKER_ROOT ?= /google/data/ro/teams/spacepark/enterprise/kokoro/prod/spacepark/enterprise/docker
diff --git a/prereqs.mk b/prereqs.mk
index 7f06011..953a038 100644
--- a/prereqs.mk
+++ b/prereqs.mk
@@ -6,8 +6,10 @@
 
 REQUIRED_PACKAGES := \
 	bc \
+	binutils-aarch64-linux-gnu \
 	build-essential \
 	binfmt-support \
+	coreutils \
 	debhelper \
 	debian-archive-keyring \
 	debootstrap \
@@ -15,8 +17,13 @@
 	fakeroot \
 	genext2fs \
 	kpartx \
+	libwayland-dev \
 	mtools \
 	parted \
+	pkg-config \
+	python-minimal \
+	python2.7 \
+	python3 \
 	qemu-user-static \
 	reprepro \
 	rsync \
diff --git a/rootfs.mk b/rootfs.mk
index e80b117..73beac8 100644
--- a/rootfs.mk
+++ b/rootfs.mk
@@ -5,7 +5,6 @@
 include $(ROOTDIR)/build/preamble.mk
 
 ARM64_BUILDER_FETCH_TARBALL ?= true
-PREBUILT_DOCKER_ROOT ?= /google/data/ro/teams/spacepark/enterprise/kokoro/prod/spacepark/enterprise/docker
 
 GPU_VERSION := imx-gpu-viv-6.2.4.p1.0-aarch64
 GPU_DIR := $(ROOTDIR)/imx-gpu-viv/$(GPU_VERSION)
@@ -45,6 +44,7 @@
 	cd $(WAYLAND_PROTO_DIR)/wayland-protocols-imx-1.13; dpkg-buildpackage -uc -us -tc
 	mv $(WAYLAND_PROTO_DIR)/wayland-protocols-imx_1.13-0_all.deb $(PRODUCT_OUT)
 
+docker-build-arm64: $(ROOTDIR)/cache/arm64-builder.tar
 ifeq ($(ARM64_BUILDER_FETCH_TARBALL),true)
 $(ROOTDIR)/cache/arm64-builder.tar: $(PREBUILT_DOCKER_ROOT)/arm64-builder.tar
 	mkdir -p $(ROOTDIR)/cache