mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-12 15:36:58 +02:00
Currently, if set -e spots a nonzero exit we basically have no real debug information- it just stops immediately without stating where or why. This forces our scripts to be stupidly verbose so we can track roughly where they were, thus when they fail we can use that information to localize the rough exit point. Instead we should be traping that set -e induced exit and outputing necessary debug information to run it down. This includes outputing the relevant stack trace, or at least what we can get of it. The 'die' function is now enhanced to automatically dump the trace that lead to it. For most consumers this is desired- however for commandline parsing induced dies ("--board is missing" for example), the trace is noise. For those cases, a 'die_notrace' function was added that retains the original non-backtrace behaviour. Example output via instrumenting cros_generate_breakpad_symbols w/ the failing command '/bin/false' (nonzero exit code). Before: ./cros_generate_breakpad_symbols monkeys --board=x86-alex <no output at all, just exit code 1> With this CL: ./cros_generate_breakpad_symbols monkeys --board=x86-alex ERROR : script called: ./cros_generate_breakpad_symbols 'monkeys' '--board=x86-alex' ERROR : Backtrace: (most recent call is last) ERROR : file cros_generate_breakpad_symbols, line 207, called: main 'monkeys' '--board=x86-alex' ERROR : file cros_generate_breakpad_symbols, line 163, called: die_err_trap '/bin/false' '1' ERROR : ERROR : Command failed: ERROR : Command '/bin/false' exited with nonzero code: 1 BUG=chromium-os:30598 TEST=inject a failing command into a script, verify the output. TEST=inject a 'command not found', verify the output TEST=cbuildbot x86-generic-full --remote TEST=cbuildbot arm-tegra2-full --remote TEST=cbuildbot chromiumos-sdk --remote Change-Id: I517ffde4d1bb7e2310a74f5a6455b53ba2dea86c Reviewed-on: https://gerrit.chromium.org/gerrit/17225 Reviewed-by: Brian Harring <ferringb@chromium.org> Tested-by: Brian Harring <ferringb@chromium.org> Commit-Ready: Brian Harring <ferringb@chromium.org>
290 lines
11 KiB
Bash
Executable File
290 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (c) 2012 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 build a bootable keyfob-based chromeos system image from within
|
|
# a chromiumos setup. This assumes that all needed packages have been built into
|
|
# the given target's root with binary packages turned on. This script will
|
|
# build the Chrome OS image using only pre-built binary packages.
|
|
|
|
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
|
|
. "${SCRIPT_ROOT}/build_library/build_common.sh" || exit 1
|
|
|
|
|
|
# Developer-visible flags.
|
|
DEFINE_string board "${DEFAULT_BOARD}" \
|
|
"The board to build an image for."
|
|
DEFINE_string boot_args "noinitrd" \
|
|
"Additional boot arguments to pass to the commandline"
|
|
DEFINE_boolean enable_rootfs_verification ${FLAGS_TRUE} \
|
|
"Default all bootloaders to use kernel-based root fs integrity checking."
|
|
DEFINE_string output_root "${DEFAULT_BUILD_ROOT}/images" \
|
|
"Directory in which to place image result directories (named by version)"
|
|
DEFINE_integer rootfs_hash_pad 8 \
|
|
"MiBs reserved at the end of the rootfs image. \
|
|
ceil(0.01 * rootfs_size) is a good minimum."
|
|
DEFINE_integer rootfs_partition_size 1024 \
|
|
"rootfs partition size in MiBs."
|
|
DEFINE_integer rootfs_size 850 \
|
|
"rootfs filesystem size in MiBs."
|
|
DEFINE_integer rootfs_boost_size 0 \
|
|
"MiBs by which to increase the rootfs allocations."
|
|
DEFINE_boolean standard_backdoor ${FLAGS_TRUE} \
|
|
"Install standard backdoor credentials for testing"
|
|
DEFINE_integer statefulfs_size 1024 \
|
|
"stateful filesystem size in MiBs."
|
|
DEFINE_string usb_disk /dev/sdb3 \
|
|
"Path syslinux should use to do a usb boot. Default: /dev/sdb3"
|
|
|
|
FLAGS_HELP="USAGE: build_image [flags] [list of images to build].
|
|
This script is used to build a Chromium OS image. Chromium OS comes in many
|
|
different forms. This scripts can be used to build the following:
|
|
|
|
base - Pristine Chromium OS image. As similar to Chrome OS as possible.
|
|
dev - Developer image. Like base but with additional developer packages.
|
|
test - Like dev, but with additional test specific packages and can be easily
|
|
used for automated testing using scripts like run_remote_tests, etc.
|
|
factory_test - Like test but with extra packages and modifications used to
|
|
test images in a factory setting. Cannot be built along with a test image.
|
|
factory_install - Install shim for bootstrapping the factory test process.
|
|
Cannot be built along with any other image.
|
|
|
|
Examples:
|
|
|
|
build_image --board=<board> dev test - builds developer and test images.
|
|
build_image --board=<board> factory_install - builds a factory install shim.
|
|
...
|
|
"
|
|
show_help_if_requested "$@"
|
|
|
|
# The following options are advanced options, only available to those willing
|
|
# to read the source code. They are not shown in help output, since they are
|
|
# not needed for the typical developer workflow.
|
|
DEFINE_integer build_attempt 1 \
|
|
"The build attempt for this image build."
|
|
DEFINE_string version "" \
|
|
"Overrides version number in name to this version."
|
|
DEFINE_integer jobs -1 \
|
|
"How many packages to build in parallel at maximum."
|
|
DEFINE_boolean replace ${FLAGS_FALSE} \
|
|
"Overwrite existing output, if any."
|
|
DEFINE_string symlink "latest" \
|
|
"Symlink name to use for this image."
|
|
DEFINE_integer verity_error_behavior 3 \
|
|
"Kernel verified boot error behavior (0: I/O errors, 1: panic, 2: nothing, \
|
|
3: cros) Default: 3"
|
|
DEFINE_integer verity_max_ios -1 \
|
|
"Number of outstanding I/O operations dm-verity caps at. Default: -1"
|
|
DEFINE_string verity_algorithm "sha1" \
|
|
"Cryptographic hash algorithm used for kernel vboot. Default : sha1"
|
|
DEFINE_string verity_salt "" \
|
|
"Root filesystem salt. Default: randomly generated."
|
|
|
|
# Parse command line.
|
|
FLAGS "$@" || exit 1
|
|
eval set -- "${FLAGS_ARGV}"
|
|
|
|
# Only now can we die on error. shflags functions leak non-zero error codes,
|
|
# so will die prematurely if 'switch_to_strict_mode' is specified before now.
|
|
switch_to_strict_mode
|
|
|
|
# Determine build version.
|
|
OVERLAY_CHROMEOS_DIR="${SRC_ROOT}/third_party/chromiumos-overlay/chromeos"
|
|
. "${OVERLAY_CHROMEOS_DIR}/config/chromeos_version.sh" || exit 1
|
|
# N.B. Ordering matters for some of the libraries below, because
|
|
# some of the files contain initialization used by later files.
|
|
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/build_gpt.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/mount_gpt_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/base_image_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/dev_image_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/test_image_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/test_image_content.sh" || exit 1
|
|
|
|
parse_build_image_args
|
|
|
|
# Tweak sizes defaulted or given based on any boost given (or defaulted).
|
|
# This is syntactic sugar to separate concerns in callers, and unify
|
|
# default values here.
|
|
if [[ $FLAGS_rootfs_boost_size -gt 0 ]]; then
|
|
max() {
|
|
echo $(( $1 > $2 ? $1 : $2 ))
|
|
}
|
|
root_boost() {
|
|
echo $(( $1 + ( $1 * $FLAGS_rootfs_boost_size + $FLAGS_rootfs_size - 1 ) \
|
|
/ $FLAGS_rootfs_size ))
|
|
}
|
|
FLAGS_rootfs_hash_pad=$(root_boost $FLAGS_rootfs_hash_pad)
|
|
FLAGS_rootfs_partition_size=$(root_boost $FLAGS_rootfs_partition_size)
|
|
FLAGS_rootfs_size=$(root_boost $FLAGS_rootfs_size)
|
|
FLAGS_rootfs_boost_size=0
|
|
# Push up to the recommended minimum if we did not get there.
|
|
FLAGS_rootfs_hash_pad=$(max $FLAGS_rootfs_hash_pad \
|
|
$(( ( $FLAGS_rootfs_size + 99 ) / 100 )))
|
|
fi
|
|
|
|
# Tweak flags, configure extra USE flags, and add packages for the factory
|
|
# install shim.
|
|
EXTRA_PACKAGES=""
|
|
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
|
|
# TODO: Build a separated ebuild for the install shim to reduce size.
|
|
INSTALL_MASK="${FACTORY_SHIM_INSTALL_MASK}"
|
|
|
|
# Reduce the size of factory install shim.
|
|
info "Fixing the rootfs size at 320 MiB for install shim"
|
|
FLAGS_rootfs_size=300
|
|
FLAGS_rootfs_partition_size=320
|
|
info "Fixing the statefulfs size at 140 MiB for install shim"
|
|
FLAGS_statefulfs_size=140
|
|
|
|
# Add the cros_factory_install boot arg.
|
|
FLAGS_boot_args="${FLAGS_boot_args} cros_factory_install"
|
|
|
|
# Factory install needs to have the factory installer added.
|
|
EXTRA_PACKAGES="${EXTRA_PACKAGES} chromeos-base/chromeos-factoryinstall"
|
|
# On x86/amd64, we boot the factory install shim from an SD card using
|
|
# initramfs for our root. On ARM, we boot the factory install shim over the
|
|
# network, so we don't require initramfs, but we do require fbconsole to fix
|
|
# a display driver bug.
|
|
if [ "${ARCH}" = "x86" -o "${ARCH}" = "amd64" ] ; then
|
|
export USE="${USE} initramfs"
|
|
fi
|
|
# CONFIG_BLK_DEV_RAM is disabled by default.
|
|
# But tftp install needs it to mount rootfs in ram
|
|
if [ "${ARCH}" = "arm" ] ; then
|
|
export USE="${USE} fbconsole blkdevram"
|
|
fi
|
|
fi
|
|
|
|
if [ $((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad)) -gt \
|
|
${FLAGS_rootfs_partition_size} ] ; then
|
|
die_notrace "rootfs ($((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad)) MiB) is" \
|
|
"bigger than partition (${FLAGS_rootfs_partition_size} MiB)."
|
|
fi
|
|
|
|
# If we are creating a developer image, also create a pristine image with a
|
|
# different name.
|
|
PRISTINE_IMAGE_NAME=
|
|
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
|
|
PRISTINE_IMAGE_NAME=${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}
|
|
else
|
|
PRISTINE_IMAGE_NAME=${CHROMEOS_BASE_IMAGE_NAME}
|
|
fi
|
|
|
|
ROOT_FS_DIR="${BUILD_DIR}/rootfs"
|
|
STATEFUL_FS_DIR="${BUILD_DIR}/stateful_partition"
|
|
ESP_FS_DIR=${BUILD_DIR}/esp
|
|
|
|
DEVKEYSDIR="/usr/share/vboot/devkeys"
|
|
|
|
# ${DEV_IMAGE_ROOT} specifies the location of where developer packages will
|
|
# be installed on the stateful dir. On a Chromium OS system, this will
|
|
# translate to /usr/local.
|
|
DEV_IMAGE_ROOT="${STATEFUL_FS_DIR}/dev_image"
|
|
|
|
eclean-$BOARD -d packages
|
|
|
|
check_blacklist
|
|
|
|
# Check that the build root is sane.
|
|
"${BUILD_LIBRARY_DIR}/test_build_root" --root="${BOARD_ROOT}"
|
|
|
|
# Hack to fix bug where x86_64 CHOST line gets incorrectly added.
|
|
# ToDo(msb): remove this hack.
|
|
PACKAGES_FILE="${BOARD_ROOT}/packages/Packages"
|
|
sudo sed -e "s/CHOST: x86_64-pc-linux-gnu//" -i "${PACKAGES_FILE}"
|
|
|
|
# Handle existing directory.
|
|
if [[ -e "${BUILD_DIR}" ]]; then
|
|
if [[ ${FLAGS_replace} -eq ${FLAGS_TRUE} ]]; then
|
|
sudo rm -rf "${BUILD_DIR}"
|
|
else
|
|
error "Directory ${BUILD_DIR} already exists."
|
|
error "Use --build_attempt option to specify an unused attempt."
|
|
error "Or use --replace if you want to overwrite this directory."
|
|
die "Unwilling to overwrite ${BUILD_DIR}."
|
|
fi
|
|
fi
|
|
|
|
# Create the output directory and temporary mount points.
|
|
mkdir -p "${BUILD_DIR}"
|
|
mkdir -p "${ROOT_FS_DIR}" "${STATEFUL_FS_DIR}" "${ESP_FS_DIR}"
|
|
|
|
# Create the boot.desc file which stores the build-time configuration
|
|
# information needed for making the image bootable after creation with
|
|
# cros_make_image_bootable.
|
|
create_boot_desc
|
|
|
|
create_base_image ${PRISTINE_IMAGE_NAME}
|
|
|
|
|
|
BOOT_FLAG=
|
|
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
|
|
BOOT_FLAG="-b 1" # BOOT_FLAG_DEVELOPER value defined in load_kernel_fw.h
|
|
info "--factory_install set, pass BOOT_FLAG_DEVELOPER flag to" \
|
|
"load_kernel_test"
|
|
fi
|
|
|
|
# Verify pristine image if we built it.
|
|
if should_build_image "${PRISTINE_IMAGE_NAME}"; then
|
|
load_kernel_test "${BUILD_DIR}/${PRISTINE_IMAGE_NAME}" \
|
|
"${DEVKEYSDIR}/recovery_key.vbpubk" ${BOOT_FLAG}
|
|
fi
|
|
|
|
# Create a developer image if an image that is based on it is requested.
|
|
if should_build_image ${CHROMEOS_DEVELOPER_IMAGE_NAME} \
|
|
${CHROMEOS_TEST_IMAGE_NAME} ${CHROMEOS_FACTORY_TEST_IMAGE_NAME}; then
|
|
copy_image ${CHROMEOS_BASE_IMAGE_NAME} ${CHROMEOS_DEVELOPER_IMAGE_NAME}
|
|
install_dev_packages ${CHROMEOS_DEVELOPER_IMAGE_NAME}
|
|
fi
|
|
|
|
# From a developer image create a test|factory_test image.
|
|
if should_build_image ${CHROMEOS_TEST_IMAGE_NAME}; then
|
|
copy_image ${CHROMEOS_DEVELOPER_IMAGE_NAME} ${CHROMEOS_TEST_IMAGE_NAME}
|
|
mod_image_for_test ${CHROMEOS_TEST_IMAGE_NAME}
|
|
fi
|
|
if should_build_image ${CHROMEOS_FACTORY_TEST_IMAGE_NAME}; then
|
|
copy_image ${CHROMEOS_DEVELOPER_IMAGE_NAME} \
|
|
${CHROMEOS_FACTORY_TEST_IMAGE_NAME}
|
|
mod_image_for_test ${CHROMEOS_FACTORY_TEST_IMAGE_NAME}
|
|
fi
|
|
|
|
rmdir "${ROOT_FS_DIR}" "${STATEFUL_FS_DIR}" "${ESP_FS_DIR}"
|
|
|
|
# Generating AU generator zip file to run outside chroot
|
|
generate_au_zip || echo "Failed generating AU zip file - ignoring Error..."
|
|
|
|
# Create a named symlink.
|
|
LINK_NAME="${FLAGS_output_root}/${BOARD}/${FLAGS_symlink}"
|
|
ln -sfT $(basename ${BUILD_DIR}) ${LINK_NAME}
|
|
|
|
echo "Done. Image(s) created in ${BUILD_DIR}"
|
|
|
|
# Print out the images we generated.
|
|
if should_build_image ${CHROMEOS_BASE_IMAGE_NAME}; then
|
|
echo "Non-developer Chromium OS image created as ${PRISTINE_IMAGE_NAME}"
|
|
fi
|
|
if should_build_image ${CHROMEOS_FACTORY_SHIM_NAME}; then
|
|
echo "Chromium OS Factory install shim created as ${PRISTINE_IMAGE_NAME}"
|
|
fi
|
|
if should_build_image ${CHROMEOS_DEVELOPER_IMAGE_NAME}; then
|
|
echo "Developer image created as ${CHROMEOS_DEVELOPER_IMAGE_NAME}"
|
|
fi
|
|
if should_build_image ${CHROMEOS_FACTORY_TEST_IMAGE_NAME}; then
|
|
echo "Factory test image created as ${CHROMEOS_FACTORY_TEST_IMAGE_NAME}"
|
|
fi
|
|
if should_build_image ${CHROMEOS_TEST_IMAGE_NAME}; then
|
|
echo "Test image created as ${CHROMEOS_TEST_IMAGE_NAME}"
|
|
fi
|
|
|
|
print_time_elapsed
|
|
|
|
echo "To copy to USB keyfob, do something like:"
|
|
echo " ./image_to_usb.sh --from=${OUTSIDE_OUTPUT_DIR} --to=/dev/sdX"
|
|
echo "To convert to VMWare image, INSIDE the chroot, do something like:"
|
|
echo " ./image_to_vm.sh --from=${OUTSIDE_OUTPUT_DIR} --board=${BOARD}"
|
|
echo "from the scripts directory where you entered the chroot."
|