Use docker for all crosvm build modes
-- Move GCE and ARM-board build to containers
-- Use debian-10 containers
-- Known limitations: --docker_arch=aarch64 builds do not work on GCE;
--docker_arch=x86_64 builds do not work on ARM
To build using GCE:
./device/google/cuttlefish_vmm/rebuild.sh --gce
To build using a previously-set-up GCE instance:
./device/google/cuttlefish_vmm/rebuild.sh --gce --reuse
To build locally:
./device/google/cuttlefish_vmm/rebuild.sh --docker
To build locally for aarch64:
./device/google/cuttlefish_vmm/rebuild.sh --docker \
--docker_arch aarch64
To reuse a previously-set-up local docker image:
./device/google/cuttlefish_vmm/rebuild.sh --docker --reuse
To reuse a previously-set-up local docker image for aarch64:
./device/google/cuttlefish_vmm/rebuild.sh --docker --reuse \
--docker_arch aarch64
To build using an ARM board reachable at cf@192.168.0.6:
./device/google/cuttlefish_vmm/rebuild.sh \
--arm --arm_instance 192.168.0.6 --arm_user cf \
--docker_arch aarch64
To build using the same previously-set-up ARM board:
./device/google/cuttlefish_vmm/rebuild.sh \
--arm --arm_instance 192.168.0.6 --arm_user cf \
--docker_arch aarch64 \
--reuse
Bug: 148642775 Clean up the crosvm build
Test: built with GCE, ARM board, and locally
Change-Id: I75c4109be5ee72544580cc6a4374d1fdcc47d07f
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/.dockerignore b/.dockerignore
index f33aa59..178260b 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -5,3 +5,4 @@
!rebuild-internal.sh
!x86_64-linux-gnu/manifest.xml
!aarch64-linux-gnu/manifest.xml
+!custom.xml
diff --git a/Dockerfile b/Dockerfile
index 86c6827..24142d6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,6 +34,7 @@
COPY --chown=$USER x86_64-linux-gnu/manifest.xml /static/x86_64-linux-gnu/manifest.xml
COPY --chown=$USER aarch64-linux-gnu/manifest.xml /static/aarch64-linux-gnu/manifest.xml
+COPY --chown=$USER custom.xml /static/custom.xml
COPY --chown=$USER rebuild-internal.sh /static/rebuild-internal.sh
RUN TOOLS_DIR=/static/tools /static/rebuild-internal.sh install_packages
diff --git a/rebuild.sh b/rebuild.sh
index aa0edf3..59f6404 100755
--- a/rebuild.sh
+++ b/rebuild.sh
@@ -27,7 +27,7 @@
DEFINE_string docker_container "docker_vmm" "Name of docker container to create"
DEFINE_string docker_source "" "Path to sources checked out using manifest"
DEFINE_string docker_working "" "Path to working directory"
-DEFINE_string docker_output "${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm/${FLAGS_docker_arch}-linux-gnu" "Output directory"
+DEFINE_string docker_output "" "Output directory (when --docker is specified)"
DEFINE_string docker_user "${USER}" "Docker-container user"
DEFINE_string docker_uid "${UID}" "Docker-container user ID"
@@ -43,11 +43,7 @@
# Common options
-# The /./ pattern in the path defition below is interpreted by rsync; do not
-# remove it!
-DEFINE_string manifest \
- "${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm/./$(uname -m)-linux-gnu/manifest.xml" \
- "manifest to use for the build"
+DEFINE_string manifest "" "Path to custom manifest to use for the build"
DEFINE_boolean reuse false "Set to true to reuse a previously-set-up instance."
DEFINE_boolean reuse_resync false "Reuse a previously-set-up instance, but clean and re-sync the sources. Overrides --reuse if both are specified."
@@ -70,6 +66,14 @@
echo Options --docker_container must not be empty 1>&2
fail=1
fi
+ if [[ -z "${FLAGS_docker_user}" ]]; then
+ echo Options --docker_user must not be empty 1>&2
+ fail=1
+ fi
+ if [[ -z "${FLAGS_docker_uid}" ]]; then
+ echo Options --docker_uid must not be empty 1>&2
+ fail=1
+ fi
# Volume mapping are specified only when a container is created. With
# --reuse, an already-created persistent container is reused, which implies
# that we cannot change the volume maps. For non-persistent containers, we
@@ -78,11 +82,15 @@
# that we passed when we ran the non-persistent continer the first time.
if [[ ${_reuse} -eq 1 && ${FLAGS_docker_persistent} -eq ${FLAGS_TRUE} ]]; then
if [ -n "${FLAGS_docker_source}" ]; then
- echo Option --docker_source may not be specified with --reuse 1>&2
+ echo Option --docker_source may not be specified with --reuse and --docker_persistent 1>&2
fail=1
fi
if [ -n "${FLAGS_docker_working}" ]; then
- echo Option --docker_working may not be specified with --reuse 1>&2
+ echo Option --docker_working may not be specified with --reuse and --docker_persistent 1>&2
+ fail=1
+ fi
+ if [ -n "${FLAGS_docker_output}" ]; then
+ echo Option --docker_output may not be specified with --reuse and --docker_persistent 1>&2
fail=1
fi
fi
@@ -100,30 +108,34 @@
fail=1
;;
esac
- if [[ -z "${FLAGS_docker_user}" ]]; then
- echo Options --docker_user must not be empty 1>&2
- fail=1
- fi
- if [[ -z "${FLAGS_docker_uid}" ]]; then
- echo Options --docker_uid must not be empty 1>&2
- fail=1
- fi
if [[ "${fail}" -ne 0 ]]; then
exit "${fail}"
fi
local -i _persistent=0
- if [[ ${FLAGS_persistent} -eq ${FLAGS_TRUE} ]]; then
+ if [[ ${FLAGS_docker_persistent} -eq ${FLAGS_TRUE} ]]; then
_persistent=1
fi
+
local -i _build_image=0
if [[ ${FLAGS_docker_build_image} -eq ${FLAGS_TRUE} ]]; then
_build_image=1
fi
- local _docker_output="${FLAGS_docker_output}"
- if [[ "${_docker_output}" == "${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm/$(uname -m)-linux-gnu" && \
- "$(uname -m)" != ${FLAGS_docker_arch} ]]; then
+
+ local _docker_output=""
+ if [ -z "${FLAGS_docker_output}" ]; then
_docker_output="${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm/${FLAGS_docker_arch}-linux-gnu"
+ else
+ _docker_output="${FLAGS_docker_output}"
fi
+
+ local _temp="$(mktemp -d)"
+ rsync -avR "${relative_source_files[@]/#/${DIR}/./}" "${_temp}"
+ if [ -n "${custom_manifest}" ]; then
+ cp "${custom_manifest}" "${_temp}"/custom.xml
+ else
+ touch "${_temp}"/custom.xml
+ fi
+
${DIR}/rebuild-docker.sh "${FLAGS_docker_image}" \
"${FLAGS_docker_container}" \
"${FLAGS_docker_arch}" \
@@ -135,13 +147,16 @@
"x${_docker_output}" \
"${_reuse}" \
"${_build_image}" \
- "${DIR}/Dockerfile" \
- "${DIR}" \
+ "${_temp}/Dockerfile" \
+ "${_temp}" \
"${#docker_flags[@]}" "${docker_flags[@]}" \
"${#_prepare_source[@]}" "${_prepare_source[@]}"
+
+ rm -rf "${_temp}"
}
function build_on_gce() {
+ check_common_docker_options
if [[ -z "${FLAGS_gce_instance}" ]]; then
echo Must specify instance 1>&2
fail=1
@@ -161,18 +176,73 @@
if [ ${_reuse} -eq 0 ]; then
delete_instances=("${FLAGS_gce_instance}")
gcloud compute instances delete -q \
+ "${delete_instances[@]}" \
+ "${project_zone_flags[@]}" || \
+ echo Instance does not exist
+ gcloud compute images delete -q \
+ "${delete_instances[@]/%/-image}" \
+ --project "${FLAGS_gce_project}" || \
+ echo Image does not exist
+ gcloud compute disks delete -q \
+ "${delete_instances[@]/%/-disk}" \
+ "${project_zone_flags[@]}" || \
+ echo Disk does not exist
+
+ gcloud compute disks create \
+ "${delete_instances[@]/%/-disk}" \
"${project_zone_flags[@]}" \
- "${delete_instances[@]}" || \
- echo Not running
- gcloud compute instances create \
- "${project_zone_flags[@]}" \
- --boot-disk-size=200GB \
- --machine-type=n1-standard-4 \
- --image-family="${FLAGS_gce_source_image_family}" \
--image-project="${FLAGS_gce_source_image_project}" \
- "${FLAGS_gce_instance}"
- wait_for_instance "${FLAGS_gce_instance}"
+ --image-family="${FLAGS_gce_source_image_family}"
+ gcloud compute images create \
+ "${delete_instances[@]/%/-image}" \
+ --source-disk "${delete_instances[@]/%/-disk}" \
+ --project "${FLAGS_gce_project}" --source-disk-zone "${FLAGS_gce_zone}" \
+ --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
+ gcloud compute instances create \
+ "${delete_instances[@]}" \
+ "${project_zone_flags[@]}" \
+ --image "${delete_instances[@]/%/-image}" \
+ --boot-disk-size=200GB \
+ --machine-type=n1-standard-8 \
+ --min-cpu-platform "Intel Skylake"
+
+ wait_for_instance "${FLAGS_gce_instance}" "${project_zone_flags[@]}"
+
+ # install docker
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ 'curl -fsSL https://get.docker.com | /bin/bash'
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ sudo usermod -aG docker "${FLAGS_gce_user}"
+
+ # beta for the --internal-ip flag that may be passed via SSH_FLAGS
+
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ mkdir -p '$PWD/docker $PWD/docker/source $PWD/docker/working $PWD/docker/output'
+
+ tar czv -C "${DIR}" -f - "${relative_source_files[@]}" | \
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ 'tar xzv -C ~/docker -f -'
+ if [ -n "${custom_manifest}" ]; then
+ gcloud beta compute scp "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${custom_manifest}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}:~/docker/custom.xml"
+ else
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ "touch ~/docker/custom.xml"
+ fi
fi
+
local _status=$(gcloud compute instances list \
--project="${FLAGS_gce_project}" \
--zones="${FLAGS_gce_zone}" \
@@ -182,32 +252,40 @@
echo "Instance ${FLAGS_gce_instance} is not running."
exit 1;
fi
- # beta for the --internal-ip flag that may be passed via SSH_FLAGS
- gcloud beta compute scp "${SSH_FLAGS[@]}" \
- "${project_zone_flags[@]}" \
- "${source_files[@]}" \
- "${FLAGS_gce_user}@${FLAGS_gce_instance}:"
- if [ ${_reuse} -eq 0 ]; then
- gcloud compute ssh "${SSH_FLAGS[@]}" \
- "${project_zone_flags[@]}" \
- "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
- ./rebuild-internal.sh install_packages
+
+ local -i _persistent=0
+ if [[ ${FLAGS_docker_persistent} -eq ${FLAGS_TRUE} ]]; then
+ _persistent=1
fi
- if [ ${_reuse} -eq 0 ]; then
- gcloud compute ssh "${SSH_FLAGS[@]}" \
- "${project_zone_flags[@]}" \
- "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
- ./rebuild-internal.sh "${gce_flags[@]}" ${_prepare_source[@]} '$(uname -m)_build'
- else
- gcloud compute ssh "${SSH_FLAGS[@]}" \
- "${project_zone_flags[@]}" \
- "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
- ./rebuild-internal.sh "${gce_flags[@]}" ${_prepare_source[@]} '$(uname -m)_retry'
+ local -i _build_image=0
+ if [[ ${FLAGS_docker_build_image} -eq ${FLAGS_TRUE} ]]; then
+ _build_image=1
fi
- gcloud beta compute scp --recurse "${SSH_FLAGS[@]}" \
- "${project_zone_flags[@]}" \
- "${FLAGS_gce_user}@${FLAGS_gce_instance}":x86_64-linux-gnu \
- "${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm"
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" -- \
+ ./docker/rebuild-docker.sh "${FLAGS_docker_image}" \
+ "${FLAGS_docker_container}" \
+ "${FLAGS_docker_arch}" \
+ '${USER}' \
+ '${UID}' \
+ "${_persistent}" \
+ 'x$PWD/docker/source' \
+ 'x$PWD/docker/working' \
+ 'x$PWD/docker/output' \
+ "${_reuse}" \
+ "${_build_image}" \
+ '~/docker/Dockerfile' \
+ '~/docker/' \
+ "${#docker_flags[@]}" "${docker_flags[@]}" \
+ "${#_prepare_source[@]}" "${_prepare_source[@]}"
+
+ gcloud beta compute ssh "${SSH_FLAGS[@]}" \
+ "${project_zone_flags[@]}" \
+ "${FLAGS_gce_user}@${FLAGS_gce_instance}" --command \
+ 'tar czv -C $PWD/docker/output -f - $(find $PWD/docker/output -printf "%P\n")' | \
+ tar xzv -C ${DIR}/${FLAGS_docker_arch}-linux-gnu -f -
+
gcloud compute disks describe \
"${project_zone_flags[@]}" "${FLAGS_gce_instance}" | \
grep ^sourceImage: > "${DIR}"/x86_64-linux-gnu/builder_image.txt
@@ -235,11 +313,18 @@
rm -rf '$PWD/docker'
fi
rsync -avR -e ssh \
- "${source_files[@]}" \
+ "${relative_source_files[@]/#/${DIR}/./}" \
"${FLAGS_arm_user}@${FLAGS_arm_instance}:~/docker/"
+ if [ -n "${custom_manifest}" ]; then
+ scp "${custom_manifest}" "${FLAGS_arm_user}@${FLAGS_arm_instance}":~/docker/custom.xml
+ else
+ ssh -t "${FLAGS_arm_user}@${FLAGS_arm_instance}" -- \
+ "touch ~/docker/custom.xml"
+ fi
+
local -i _persistent=0
- if [[ ${FLAGS_persistent} -eq ${FLAGS_TRUE} ]]; then
+ if [[ ${FLAGS_docker_persistent} -eq ${FLAGS_TRUE} ]]; then
_persistent=1
fi
local -i _build_image=0
@@ -273,18 +358,14 @@
set -o errexit
set -x
fail=0
- # The /./ patterns in the path defitions below are interpreted by rsync; do not
- # remove them!
- source_files=("${DIR}"/./rebuild-docker.sh \
- "${DIR}"/./rebuild-internal.sh \
- "${DIR}"/./Dockerfile \
- "${DIR}"/./x86_64-linux-gnu/manifest.xml \
- "${DIR}"/./aarch64-linux-gnu/manifest.xml \
- "${DIR}"/./.dockerignore)
+ relative_source_files=(rebuild-docker.sh \
+ rebuild-internal.sh \
+ Dockerfile \
+ x86_64-linux-gnu/manifest.xml \
+ aarch64-linux-gnu/manifest.xml \
+ .dockerignore)
# These must match the definitions in the Dockerfile
docker_flags=("-eSOURCE_DIR=/source" "-eWORKING_DIR=/working" "-eOUTPUT_DIR=/output" "-eTOOLS_DIR=/static/tools")
- gce_flags=()
- arm_flags=()
if [[ $(( $((${FLAGS_gce}==${FLAGS_TRUE})) + $((${FLAGS_arm}==${FLAGS_TRUE})) + $((${FLAGS_docker}==${FLAGS_TRUE})) )) > 1 ]]; then
echo You may specify only one of --gce, --docker, or --arm 1>&2
@@ -296,16 +377,23 @@
echo custom manifest not found: ${FLAGS_manifest} 1>&1
exit 2
fi
- source_files+=("${FLAGS_manifest}")
- docker_flags+=("-eCUSTOM_MANIFEST=/static/${FLAGS_docker_arch}-linux-gnu/$(basename ${FLAGS_manifest})")
- gce_flags+=("CUSTOM_MANIFEST=/home/${FLAGS_gce_user}/$(basename "${FLAGS_manifest}")")
- arm_flags+=("CUSTOM_MANIFEST=/home/${FLAGS_arm_user}/$(basename "${FLAGS_manifest}")")
+ custom_manifest="${FLAGS_manifest}"
+ docker_flags+=("-eCUSTOM_MANIFEST=/static/custom.xml")
+ else
+ custom_manifest="${DIR}/${FLAGS_docker_arch}-linux-gnu/manifest.xml"
+ docker_flags+=("-eCUSTOM_MANIFEST=/static/${FLAGS_docker_arch}-linux-gnu/manifest.xml")
fi
local -a _prepare_source=(setup_env fetch_source);
local -i _reuse=0
if [[ ${FLAGS_reuse} -eq ${FLAGS_TRUE} ]]; then
# neither install packages, nor sync sources; skip to building them
_prepare_source=(setup_env)
+ # unless you're setting up a non-persistent container and --docker_source is
+ # the empty string; in this case, --reuse implies --reuse_resync
+ if [[ "${FLAGS_docker_persistent}" -eq ${FLAGS_FALSE} && \
+ -z "${FLAGS_docker_source}" ]]; then
+ _prepare_source+=(resync_source)
+ fi
_reuse=1
fi
if [[ ${FLAGS_reuse_resync} -eq ${FLAGS_TRUE} ]]; then