add docker supported builds and tests

BUG=None
TEST=docker/build_crosvm_base.sh
     docker/build_crosvm.sh
     docker/wrapped_smoke_test.sh
     docker/crosvm_wrapper.sh
     kokoro/kokoro_simulator.sh
     bin/smoke_test

Change-Id: I55a805ba6326c3c58973d1fe21172a5e3551c1e2
Reviewed-on: https://chromium-review.googlesource.com/1593723
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
Zach Reizner 2019-05-02 12:26:24 -07:00 committed by chrome-bot
parent 050af40382
commit 6868c0a72f
16 changed files with 203 additions and 30 deletions

4
.dockerignore Normal file
View file

@ -0,0 +1,4 @@
docker
*/*/target
target
.git

View file

@ -7,6 +7,11 @@ safety within the programming language and a sandbox around the virtual
devices to protect the kernel from attack in case of an exploit in the devices to protect the kernel from attack in case of an exploit in the
devices. devices.
## Building with Docker
See the [README](docker/README.md) from the `docker` subdirectory to learn how
to build crosvm in enviroments outside of the Chrome OS chroot.
## Usage ## Usage
To see the usage information for your version of crosvm, run `crosvm` or `crosvm To see the usage information for your version of crosvm, run `crosvm` or `crosvm

19
bin/smoke_test Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "$(dirname "${BASH_SOURCE[0]}")"
cd ../
rustup default "$(cat rust-toolchain)"
rustup component add rustfmt-preview
cargo --version && rustc --version && rustfmt --version
echo "Running cargo test"
cargo test --no-fail-fast --features plugin,default-no-sandbox,wl-dmabuf,gpu,tpm,gpu-forward \
--all --exclude aarch64 $TEST_FLAGS -- \
--test-threads=1 $TEST_RUNNER_FLAGS
echo "Running cargo fmt"
bin/fmt --check

View file

@ -61,7 +61,7 @@ WORKDIR /scratch
# minijail does not exist in upstream linux distros. # minijail does not exist in upstream linux distros.
RUN git clone https://android.googlesource.com/platform/external/minijail \ RUN git clone https://android.googlesource.com/platform/external/minijail \
&& cd minijail \ && cd minijail \
&& make -j24 \ && make -j$(nproc) \
&& cp libminijail.so /usr/lib/x86_64-linux-gnu/ && cp libminijail.so /usr/lib/x86_64-linux-gnu/
# The gbm used by upstream linux distros is not compatible with crosvm, which must use Chrome OS's # The gbm used by upstream linux distros is not compatible with crosvm, which must use Chrome OS's
@ -70,18 +70,20 @@ RUN dpkg --force-depends -r libgbm1
RUN git clone https://chromium.googlesource.com/chromiumos/platform/minigbm \ RUN git clone https://chromium.googlesource.com/chromiumos/platform/minigbm \
&& cd minigbm \ && cd minigbm \
&& sed 's/-Wall/-Wno-maybe-uninitialized/g' -i Makefile \ && sed 's/-Wall/-Wno-maybe-uninitialized/g' -i Makefile \
&& make install -j24 && make install -j$(nproc)
# New libepoxy requires newer meson than is in Debian stretch. # New libepoxy requires newer meson than is in Debian stretch.
ARG MESON_COMMIT=master
RUN git clone https://github.com/mesonbuild/meson \ RUN git clone https://github.com/mesonbuild/meson \
&& cd meson \ && cd meson \
&& git checkout 0a5ff338012a00f32c3aa9d8773835accc3e4e5b \ && git checkout $MESON_COMMIT \
&& ln -s $PWD/meson.py /usr/bin/meson && ln -s $PWD/meson.py /usr/bin/meson
# New libepoxy has EGL_KHR_DEBUG entry points needed by crosvm. # New libepoxy has EGL_KHR_DEBUG entry points needed by crosvm.
ARG LIBEPOXY_COMMIT=master
RUN git clone https://github.com/anholt/libepoxy.git \ RUN git clone https://github.com/anholt/libepoxy.git \
&& cd libepoxy \ && cd libepoxy \
&& git checkout 707f50e680ab4f1861b1e54ca6e2907aaca56c12 \ && git checkout $LIBEPOXY_COMMIT \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& meson \ && meson \
@ -91,20 +93,22 @@ RUN git clone https://github.com/anholt/libepoxy.git \
RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git \ RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git \
&& cd virglrenderer \ && cd virglrenderer \
&& ./autogen.sh \ && ./autogen.sh \
&& make install -j24 && make install -j$(nproc)
# Install libtpm2 so that tpm2-sys/build.rs does not try to build it in place in # Install libtpm2 so that tpm2-sys/build.rs does not try to build it in place in
# the read-only source directory. # the read-only source directory.
ARG TPM2_COMMIT=master
RUN git clone https://chromium.googlesource.com/chromiumos/third_party/tpm2 \ RUN git clone https://chromium.googlesource.com/chromiumos/third_party/tpm2 \
&& cd tpm2 \ && cd tpm2 \
&& git checkout 15260c8cd98eb10b4976d2161cd5cb9bc0c3adac \ && git checkout $TPM2_COMMIT \
&& make -j24 \ && make -j$(nproc) \
&& cp build/libtpm2.a /lib && cp build/libtpm2.a /lib
# Install librendernodehost # Install librendernodehost
ARG PLATFORM2_COMMIT=master
RUN git clone https://chromium.googlesource.com/chromiumos/platform2 \ RUN git clone https://chromium.googlesource.com/chromiumos/platform2 \
&& cd platform2 \ && cd platform2 \
&& git checkout 226fc35730a430344a68c34d7fe7d613f758f417 \ && git checkout $PLATFORM2_COMMIT \
&& cd rendernodehost \ && cd rendernodehost \
&& gcc -c src.c -o src.o \ && gcc -c src.c -o src.o \
&& ar rcs librendernodehost.a src.o \ && ar rcs librendernodehost.a src.o \
@ -140,12 +144,3 @@ RUN git clone https://chromium.googlesource.com/chromiumos/third_party/adhd $THI
ENV CARGO_TARGET_DIR=/build ENV CARGO_TARGET_DIR=/build
RUN mkdir -p $CARGO_TARGET_DIR RUN mkdir -p $CARGO_TARGET_DIR
WORKDIR /platform/crosvm WORKDIR /platform/crosvm
CMD rustup default "$(cat rust-toolchain)" && \
rustup component add rustfmt-preview && \
cargo --version && rustc --version && rustfmt --version && \
echo "Running cargo test" && \
cargo test --no-fail-fast --features plugin,default-no-sandbox,wl-dmabuf,gpu,tpm,gpu-forward \
--all --exclude aarch64 $TEST_FLAGS -- \
--test-threads=1 $TEST_RUNNER_FLAGS && \
echo "Running cargo fmt" && \
bin/fmt --check

16
docker/Dockerfile.crosvm Normal file
View file

@ -0,0 +1,16 @@
FROM crosvm-base
COPY . /platform/crosvm
RUN cargo install --features 'default-no-sandbox wl-dmabuf gpu' --path . --root /usr
ARG UID=1000
ARG GID=1000
RUN export uid=$UID gid=$GID && \
mkdir -p /home/chronos && \
echo "chronos:x:${uid}:${gid}:Developer,,,:/home/chronos:/bin/bash" >> /etc/passwd && \
echo "chronos:x:${uid}:" >> /etc/group && \
chown ${uid}:${gid} -R /home/chronos
ENTRYPOINT ["crosvm"]

47
docker/README.md Normal file
View file

@ -0,0 +1,47 @@
# Docker for Building/Running crosvm
This module contains various pieces of Docker infrastructure for supporting crosvm outside of Chrome
OS environments. This includes the kokoro build environment.
[TOC]
## Introduction
Ordinarily, crosvm is built using the standard `cargo build` command inside of a Chrome OS chroot.
The chroot requirement is there because of various path dependencies in the crosvm `Cargo.toml` are
targeted to paths outside of the crosvm repo itself. If one were to checkout crosvm in isolation,
`cargo build` would be inadequate, failing with an error related to these missing paths.
Additionally, crosvm depends on native packages that are not ordinarily available from an OS package
manager (e.g. minijail) or have been forked in the Chrome OS project in an incompatible fashion
(libusb).
## `crosvm-base` Docker Image
To support building crosvm outside of a Chrome OS chroot, this modules contains a `Dockerfile` that
is used to build the `crosvm-base` docker image. Part of that image build process is downloading
various repos, checking out pinned commits (specified in `checkout_commits.env`), and installing
them. For the path dependencies in the `Cargo.toml`, the `Dockerfile` downloads and places the
source code in the correct spot relative to the crosvm source repository. The `crosvm-base` build
step stops short of actually building crosvm. It doesn't even have the source code for crosvm. The
intent here is to use `crosvm-base` for building and running any version of crosvm.
To build the `crosvm-base` image, run `build_crosvm_base.sh`. The script will automatically use the
checkouts from `checkout_commits.env` which can be reconfigured to point to any commit desired. To
upgrade `checkout_commits.sh` to the HEAD of each remote master branch, run the
`upgrade_checkout_commits.sh` script.
## `crosvm` Docker Image
After generating a `crosvm-base`, the system is ready to build crosvm into its own `crosvm` docker
image. The resulting docker image will be capable of running VMs without fear of missing native
dependencies. Run the `build_crosvm.sh` script to build crosvm into a docker image. Once that
completes, use the `crosvm_wrapper.sh` script to run crosvm within the docker image. That script
will pass the arguments given to it verbatim to crosvm. In addition, the current working directory
is bind mounted into the container so that file paths passed to `crosvm_wrapper.sh` should work as
long as they are relative paths to files contained in the working directory.
## `smoke_test`
There is a convenience wrapper for `smoke_test` that uses the `crosvm` docker image to execute
all the tests. Run `wrapped_smoke_test.sh` after building `crosvm-base` docker image to run the
`smoke_test` within docker.

11
docker/build_crosvm.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "${0%/*}"
src_root="$(realpath ..)"
docker build -t crosvm -f Dockerfile.crosvm --build-arg UID --build-arg GID "${src_root}"

15
docker/build_crosvm_base.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "${0%/*}"
gen_build_args() {
for arg in $(cat ./checkout_commits.env); do
echo --build-arg "${arg}"
done
}
docker build $(gen_build_args) -t crosvm-base .

View file

@ -0,0 +1,4 @@
MESON_COMMIT=0a5ff338012a00f32c3aa9d8773835accc3e4e5b
LIBEPOXY_COMMIT=707f50e680ab4f1861b1e54ca6e2907aaca56c12
TPM2_COMMIT=15260c8cd98eb10b4976d2161cd5cb9bc0c3adac
PLATFORM2_COMMIT=226fc35730a430344a68c34d7fe7d613f758f417

17
docker/crosvm_wrapper.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "${0%/*}"
exec docker run -it --rm \
--privileged \
-e DISPLAY=$DISPLAY -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
-v /dev/log:/dev/log \
-v /tmp/.X11-unix:/tmp/.X11-unix \
--volume "$PWD":/wd \
--workdir /wd \
crosvm \
"$@"

View file

@ -0,0 +1,27 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "${0%/*}"
remotes=(
"https://github.com/mesonbuild/meson"
"https://github.com/anholt/libepoxy.git"
"https://chromium.googlesource.com/chromiumos/third_party/tpm2"
"https://chromium.googlesource.com/chromiumos/platform2"
)
keys=(
"MESON_COMMIT"
"LIBEPOXY_COMMIT"
"TPM2_COMMIT"
"PLATFORM2_COMMIT"
)
for remote in "${remotes[@]}"; do
remote_chunk=$(git ls-remote --exit-code "${remote}" refs/heads/master)
commit=$(echo "${remote_chunk}" | cut -f 1 -)
echo $commit
done

19
docker/wrapped_smoke_test.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -ex
cd "${0%/*}"
src_root="$(realpath ..)"
docker run \
--rm \
--privileged \
-e TEST_RUNNER_FLAGS='--format terse' \
-v /dev/log:/dev/log \
-v "${src_root}":/platform/crosvm:ro \
crosvm-base \
bin/smoke_test

View file

@ -3,7 +3,7 @@
For presubmit testing, each change posted for Gerrit on the master branch of crosvm will be tried by For presubmit testing, each change posted for Gerrit on the master branch of crosvm will be tried by
Kokoro. The configuration is found in [`presubmit.cfg`](presubmit.cfg) and the build script is at Kokoro. The configuration is found in [`presubmit.cfg`](presubmit.cfg) and the build script is at
[`build.sh`](build.sh). A Docker image called `crosvm-base` is used as the testing environment which [`build.sh`](build.sh). A Docker image called `crosvm-base` is used as the testing environment which
is built with a [`Dockerfile`](Dockerfile). is built with a [`Dockerfile`](../docker/Dockerfile).
[TOC] [TOC]
@ -12,17 +12,17 @@ is built with a [`Dockerfile`](Dockerfile).
Assuming a Docker daemon is already running, build the `crosvm-base` image: Assuming a Docker daemon is already running, build the `crosvm-base` image:
```shell ```shell
docker build -t crosvm-base path/to/crosvm/kokoro path/to/crosvm/docker/build_crosvm_base.sh
``` ```
Here is how to use the image to test a crosvm repository located at `$CROSVM_SRC`: Here is how to use the image to test a crosvm repository located at `$CROSVM_SRC`:
```shell ```shell
docker run --privileged -v /dev/log:/dev/log -v "${CROSVM_SRC}":/platform/crosvm:ro crosvm-base $CROSVM_SRC/docker/wrapped_smoke_test.sh
``` ```
> **WARNING**: > **WARNING**:
> The `--privileged` is so that the container will have `/dev/kvm` access. > The `--privileged` flag is used in that script so that the container will have `/dev/kvm` access.
## How to update `crosvm-base` ## How to update `crosvm-base`
@ -32,7 +32,7 @@ If an update or new library is needed or any other adjustment is required, a new
generated as follows: generated as follows:
```shell ```shell
docker build -t crosvm-base path/to/crosvm/kokoro path/to/crosvm/docker/build_crosvm_base.sh
docker save crosvm-base | xz -T 0 -z >crosvm-base.tar.xz docker save crosvm-base | xz -T 0 -z >crosvm-base.tar.xz
``` ```

View file

@ -18,13 +18,7 @@ main() {
if [[ "$(docker images -q ${base_image} 2> /dev/null)" == "" ]]; then if [[ "$(docker images -q ${base_image} 2> /dev/null)" == "" ]]; then
docker load -i "${base_image_tarball}" docker load -i "${base_image_tarball}"
fi fi
docker run \ "${src_root}"/docker/wrapped_smoke_test.sh
--rm \
--privileged \
-e TEST_RUNNER_FLAGS='--format terse' \
-v /dev/log:/dev/log \
-v "${src_root}":/platform/crosvm:ro \
${base_image}
return 0 return 0
} }

View file

@ -16,7 +16,7 @@ main() {
mkdir -p "${kokoro_simulator_root}" mkdir -p "${kokoro_simulator_root}"
if [[ ! -e "${base_image_tarball}" ]]; then if [[ ! -e "${base_image_tarball}" ]]; then
if [[ "$(docker images -q ${base_image} 2> /dev/null)" == "" ]]; then if [[ "$(docker images -q ${base_image} 2> /dev/null)" == "" ]]; then
docker build -t ${base_image} . ../docker/build_crosvm_base.sh
fi fi
docker save ${base_image} | xz -T 0 -z >"${base_image_tarball}" docker save ${base_image} | xz -T 0 -z >"${base_image_tarball}"
fi fi