flatcar-scripts/archive_build.sh
Chris Sosa e1b5bfad0e Cp testtarball to outdir and upload from there.
This solves this issue where if we don't upload to gsutil and instead
just archive locally we still have the test tarball.

BUG=chromium-os:16014
TEST=Ran with no gsutil option set and a tarball file.

Change-Id: I5e14801f7b0a58f589a400278274fb566e580bea
Reviewed-on: http://gerrit.chromium.org/gerrit/1921
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Chris Sosa <sosa@chromium.org>
2011-06-01 16:39:10 -07:00

373 lines
13 KiB
Bash
Executable File

#!/bin/bash
# Copyright (c) 2010 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.
# Script to archive build results. Used by the buildbots.
# --- BEGIN COMMON.SH BOILERPLATE ---
# Load common CrOS utilities. Inside the chroot this file is installed in
# /usr/lib/crosutils. Outside the chroot we find it relative to the script's
# location.
find_common_sh() {
local common_paths=(/usr/lib/crosutils $(dirname "$(readlink -f "$0")"))
local path
SCRIPT_ROOT=
for path in "${common_paths[@]}"; do
if [ -r "${path}/common.sh" ]; then
SCRIPT_ROOT=${path}
break
fi
done
}
find_common_sh
. "${SCRIPT_ROOT}/common.sh" || (echo "Unable to load common.sh" && exit 1)
# --- END COMMON.SH BOILERPLATE ---
# Script must be run outside the chroot
assert_outside_chroot
IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images"
# Default to the most recent image
DEFAULT_TO="${GCLIENT_ROOT}/archive"
DEFAULT_FROM="${IMAGES_DIR}/$DEFAULT_BOARD/$(ls -t1 \
$IMAGES_DIR/$DEFAULT_BOARD 2>&-| head -1)"
# The set of environment assignment we need to pass to enter_chroots for this
# build. e.g. USE flags alter some of the commands' effect.
CHROOT_ENV=""
# Flags
DEFINE_boolean archive_debug $FLAGS_TRUE \
"Archive debug information for build"
DEFINE_string board "$DEFAULT_BOARD" \
"The board to build packages for."
DEFINE_string build_number "" \
"The build-bot build number (when called by buildbot only)." "b"
DEFINE_string chroot "$DEFAULT_CHROOT_DIR" \
"The chroot of the build to archive."
DEFINE_boolean debug $FLAGS_FALSE "Run, but don't upload anything."
DEFINE_boolean factory_install_mod $FLAGS_FALSE \
"Modify image for factory install purposes"
DEFINE_boolean factory_test_mod $FLAGS_FALSE \
"Modify image for factory testing purposes"
DEFINE_string from "$DEFAULT_FROM" \
"Directory to archive"
DEFINE_string gsutil "gsutil" \
"Location of gsutil"
DEFINE_string gsd_gen_index "" \
"Location of gsd_generate_index.py"
DEFINE_string acl "private" \
"ACL to set on GSD archives"
DEFINE_string gsutil_archive "" \
"Optional datastore archive location"
DEFINE_boolean gsutil_append_last_change $FLAGS_TRUE \
"Optional Whether to append build # and chrome os hash to GS uploads"
DEFINE_integer keep_max 0 "Maximum builds to keep in archive (0=all)"
DEFINE_boolean official_build $FLAGS_FALSE \
"Set CHROMEOS_OFFICIAL=1 for release builds."
DEFINE_string test_tarball "" "Optional path to test tarball to archive"
DEFINE_boolean test_mod $FLAGS_TRUE "Modify image for testing purposes"
DEFINE_boolean prebuilt_upload $FLAGS_FALSE "Upload prebuilt binary packages."
DEFINE_boolean remove_dev $FLAGS_TRUE "Remove the de image during archive."
DEFINE_string to "$DEFAULT_TO" "Directory of build archive"
DEFINE_string zipname "image.zip" "Name of zip file to create."
DEFINE_string useflags "" "USE flags to pass into mod_image_* and build_image."
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Set if default from path is used
DEFAULT_USED=
# Reset "default" FLAGS_from based on passed-in board if not set on cmd-line
if [ "$FLAGS_from" = "$DEFAULT_FROM" ]; then
# Keep the directory name of the current image set (*.bin).
IMG_DIR="$(readlink ${IMAGES_DIR}/${FLAGS_board}/latest)"
FLAGS_from="${IMAGES_DIR}/${FLAGS_board}/${IMG_DIR}"
DEFAULT_USED=1
fi
# Die on any errors.
set -e
if [ -n "${FLAGS_useflags}" ]; then
CHROOT_ENV="${CHROOT_ENV} USE='${FLAGS_useflags}'"
fi
if [ -z "$DEFAULT_USED" ]; then
if [ $FLAGS_test_mod -eq $FLAGS_TRUE ] || \
[ $FLAGS_factory_install_mod -eq $FLAGS_TRUE ] || \
[ $FLAGS_factory_test_mod -eq $FLAGS_TRUE ]
then
echo "test_mod requires that the default from path be used."
echo "If non default behavior is desired, run mod_image_for_test manually"
echo "re-run archive build without test_mod"
exit 1
fi
fi
if [ ! -d "$FLAGS_from" ]; then
echo "$FLAGS_from does not exist. Exiting..."
exit 1
fi
if [ $FLAGS_official_build -eq $FLAGS_TRUE ]; then
CHROMEOS_OFFICIAL=1
fi
# Get version information
. ${SRC_ROOT}/third_party/chromiumos-overlay/chromeos/config/chromeos_version.sh
# Get git hash
# Use git:8 chars of sha1
REVISION=$(git rev-parse HEAD)
REVISION=${REVISION:0:8}
# Use the version number plus revision as the last change. (Need both, since
# trunk builds multiple times with the same version string.)
LAST_CHANGE="${CHROMEOS_VERSION_STRING}-r${REVISION}"
if [ -n "$FLAGS_build_number" ]; then
LAST_CHANGE="$LAST_CHANGE-b${FLAGS_build_number}"
fi
# The Chromium buildbot scripts only create a clickable link to the archive
# if an output line of the form "last change: XXX" exists
echo "last change: $LAST_CHANGE"
echo "archive from: $FLAGS_from"
# Create the output directory
OUTDIR="${FLAGS_to}/${LAST_CHANGE}"
ZIPFILE="${OUTDIR}/${FLAGS_zipname}"
FACTORY_ZIPFILE="${OUTDIR}/factory_${FLAGS_zipname}"
echo "archive to dir: $OUTDIR"
echo "archive to file: $ZIPFILE"
rm -rf "$OUTDIR"
mkdir -p "$OUTDIR"
# Modify image for test if flag set.
if [ $FLAGS_test_mod -eq $FLAGS_TRUE ]; then
echo "Modifying image for test"
./enter_chroot.sh $CHROOT_ENV -- ./mod_image_for_test.sh \
--board $FLAGS_board --noinplace --yes
pushd "${FLAGS_chroot}/build/${FLAGS_board}/usr/local"
echo "Archiving autotest build artifacts"
tar cjf "${FLAGS_from}/autotest.tar.bz2" --checkpoint=1000 autotest
popd
fi
# Modify for recovery
if [ $FLAGS_official_build -eq $FLAGS_TRUE ]; then
BUILDVER="$(readlink ${IMAGES_DIR}/${FLAGS_board}/latest)"
CHROOT_IMAGE_DIR=/home/$USER/trunk/src/build/images/$FLAGS_board/$BUILDVER
./enter_chroot.sh $CHROOT_ENV -- ./mod_image_for_recovery.sh \
--board $FLAGS_board --image $CHROOT_IMAGE_DIR/chromiumos_base_image.bin
fi
# Remove the developer build if test image is also built.
if [ $FLAGS_remove_dev -eq $FLAGS_TRUE ]; then
rm -f "${FLAGS_from}/${CHROMEOS_IMAGE_NAME}"
fi
if [ $FLAGS_factory_test_mod -eq $FLAGS_TRUE ]; then
echo "Generating image for factory test"
# HACK: The build system can't currently handle more than one image size
# at a time. Therefore it's necessary to do another round of build after
# archiving the original build. This should be fixed in Chromite.
# HACK: cbuild has a special case when running on chrome-bot that
# zeroes out the current revision, which makes calling build_image directly
# fail. You must explictly call replace and specify a unique name numerically
# using build_attempt.
./enter_chroot.sh $CHROOT_ENV -- ./build_image --board $FLAGS_board \
--replace --noenable_rootfs_verification --build_attempt 4
./enter_chroot.sh $CHROOT_ENV -- ./mod_image_for_test.sh \
--board $FLAGS_board --yes --noinplace --factory
# Get the factory test dir: It is the newest build.
# This is the output dir for the factory shim, the factory test and
# release images will remain in IMG_DIR, defined previously.
FACTORY_DIR="$(readlink ${IMAGES_DIR}/${FLAGS_board}/latest)"
echo "Factory image dir: ${FACTORY_DIR}"
fi
# Build differently sized shims. Currently only factory install shim is
# supported, TODO(tgao): Add developer shim.
if [ $FLAGS_factory_install_mod -eq $FLAGS_TRUE ]; then
echo "Building factory install shim."
# HACK: The build system can't currently handle more than one image size
# at a time. Therefore it's necessary to do another round of build after
# archiving the original build. This should be fixed in Chromite.
# HACK: cbuild has a special case when running on chrome-bot that
# zeroes out the current revision, which makes calling build_image directly
# fail. You must explictly call replace and specify a unique name numerically
# using build_attempt.
./enter_chroot.sh $CHROOT_ENV -- ./build_image --board $FLAGS_board \
--factory_install --replace --build_attempt 7
# Get the install shim dir: It is the newest build.
# This is the output dir for the factory shim, the factory test and
# release images will remain in IMG_DIR, defined previously.
SHIM_DIR="$(readlink ${IMAGES_DIR}/${FLAGS_board}/latest)"
echo "Factory install shim dir: ${SHIM_DIR}"
fi
# Zip the build
echo "Compressing and archiving build..."
cd "$FLAGS_from"
MANIFEST=`ls | grep -v factory`
zip -r "${ZIPFILE}" ${MANIFEST}
if [ $FLAGS_factory_test_mod -eq $FLAGS_TRUE ] || \
[ $FLAGS_factory_install_mod -eq $FLAGS_TRUE ]; then
# We need to have directory structure for factory package, as
# signing and packaging utilities need unpack_partitions.sh.
echo "Compressing factory software"
pushd ..
[ -n "${SHIM_DIR}" ] && rm -f factory_shim && \
ln -s "${SHIM_DIR}" factory_shim
[ -n "${FACTORY_DIR}" ] && rm -f factory_test && \
ln -s "${FACTORY_DIR}" factory_test
# Restore "latest" status to the original image.
# The "latest" symlink and latest timestamp are used extensively
# throughout the build scripts rather than explicitly specifying an image.
touch "${IMG_DIR}"
[ -n "${IMG_DIR}" ] && rm -f latest && ln -s "${IMG_DIR}" latest
FACTORY_MANIFEST=`find factory_shim factory_test -follow \
-type f | grep -E "(factory_image|factory_install|partition)"`
zip "${FACTORY_ZIPFILE}" ${FACTORY_MANIFEST}
echo "Zipped"
popd
chmod 644 "${FACTORY_ZIPFILE}"
fi
cd -
# Update LATEST file
echo "$LAST_CHANGE" > "${FLAGS_to}/LATEST"
# Make sure files are readable
chmod 644 "$ZIPFILE" "${FLAGS_to}/LATEST"
chmod 755 "$OUTDIR"
cp -f "${FLAGS_from}/au-generator.zip" "${OUTDIR}/"
function gsutil_archive() {
IN_PATH="$1"
OUT_PATH="$2"
if [ ${FLAGS_gsutil_append_last_change} -eq ${FLAGS_TRUE} ]; then
OUT_PATH="${LAST_CHANGE}/${OUT_PATH}"
fi
echo "Using gsutil to archive to ${OUT_PATH}..."
if [ -z "$FLAGS_gsutil_archive" -o ${FLAGS_debug} -eq ${FLAGS_TRUE} ]; then
echo -n "In debug mode. Would have run: "
echo "gsutil cp ${IN_PATH} <gsutil_archive>/${OUT_PATH}"
return
fi
FULL_OUT_PATH="${FLAGS_gsutil_archive}/${OUT_PATH}"
${FLAGS_gsutil} cp ${IN_PATH} ${FULL_OUT_PATH}
${FLAGS_gsutil} setacl ${FLAGS_acl} ${FULL_OUT_PATH}
if [ -n "$FLAGS_gsd_gen_index" ]; then
echo "Updating indexes..."
${FLAGS_gsd_gen_index} \
--gsutil=${FLAGS_gsutil} \
-a ${FLAGS_acl} \
-p ${FULL_OUT_PATH} ${FLAGS_gsutil_archive}
fi
}
if [ $FLAGS_test_mod -eq $FLAGS_TRUE -a $FLAGS_official_build -eq $FLAGS_TRUE ]
then
echo "Creating hwqual archive"
HWQUAL_NAME="chromeos-hwqual-${FLAGS_board}-${CHROMEOS_VERSION_STRING}"
"${SCRIPTS_DIR}/archive_hwqual" --from "${OUTDIR}" \
--output_tag "${HWQUAL_NAME}"
gsutil_archive "${OUTDIR}/${HWQUAL_NAME}.tar.bz2" \
"${HWQUAL_NAME}.tar.bz2"
fi
if [ $FLAGS_prebuilt_upload -eq $FLAGS_TRUE ]; then
# Construct prebuilt upload command.
# This will upload prebuilt packages to Google Storage.
prebuilt_cmd="${GCLIENT_ROOT}/chromite/buildbot/prebuilt.py"
prebuilt_cmd="$prebuilt_cmd -u gs://chromeos-prebuilt --git-sync -V master"
prebuilt_cmd="$prebuilt_cmd -p ${GCLIENT_ROOT} -b ${FLAGS_board}"
if [ "${FLAGS_board}" == "x86-generic" ]
then
prebuilt_cmd="$prebuilt_cmd --sync-host"
fi
if [ ${FLAGS_debug} -eq ${FLAGS_FALSE} ]; then
echo "Running $prebuilt_cmd"
$prebuilt_cmd
else
echo "Would have run $prebuilt_cmd"
fi
fi
gsutil_archive "${ZIPFILE}" "${FLAGS_zipname}"
if [ $FLAGS_archive_debug -eq $FLAGS_TRUE ]; then
echo "Generating Breakpad symbols"
! ${SCRIPTS_DIR}/cros_generate_breakpad_symbols --board=${FLAGS_board}
echo "Creating debug archive"
pushd "${FLAGS_chroot}/build/${FLAGS_board}/usr/lib"
sudo tar czf "${OUTDIR}/debug.tgz" --checkpoint=1000 --exclude\
debug/usr/local/autotest --exclude debug/tests debug
CMD="chown \${SUDO_UID}:\${SUDO_GID} ${OUTDIR}/debug.tgz"
sudo sh -c "${CMD}"
popd
gsutil_archive "${OUTDIR}/debug.tgz" "debug.tgz"
fi
if [ $FLAGS_factory_test_mod -eq $FLAGS_TRUE ] || \
[ $FLAGS_factory_install_mod -eq $FLAGS_TRUE ]; then
gsutil_archive "${FACTORY_ZIPFILE}" \
"factory_${FLAGS_zipname}"
fi
gsutil_archive "${FLAGS_to}/LATEST" "LATEST"
if [ -n "${FLAGS_gsutil_archive}" ]; then
if [ ${FLAGS_gsutil_append_last_change} -eq ${FLAGS_TRUE} ]; then
FULL_INDEX_PATH="${FLAGS_gsutil_archive}/${LAST_CHANGE}/_index.html"
else
FULL_INDEX_PATH="${FLAGS_gsutil_archive}/_index.html"
fi
RELATIVE_ARCHIVE_URL_PATH="${FULL_INDEX_PATH#gs://}"
echo "CROS_ARCHIVE_URL=\
https://sandbox.google.com/storage/${RELATIVE_ARCHIVE_URL_PATH}"
fi
if [ -n "${FLAGS_test_tarball}" ]; then
# Copy to local outdir first.
TEST_TARBALL_OUT="${OUTDIR}/$(basename "${FLAGS_test_tarball}")"
cp "${FLAGS_test_tarball}" "${TEST_TARBALL_OUT}"
chmod 644 "${TEST_TARBALL_OUT}"
gsutil_archive "${TEST_TARBALL_OUT}" "test_results.tgz"
fi
# Purge old builds if necessary
if [ $FLAGS_keep_max -gt 0 ]; then
echo "Deleting old builds (all but the newest ${FLAGS_keep_max})..."
cd "$FLAGS_to"
# +2 because line numbers start at 1 and need to skip LATEST file
rm -rf `ls -t1 | tail --lines=+$(($FLAGS_keep_max + 2))`
cd -
fi
echo "Done."