mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-23 06:31:18 +02:00
Lots of things are either unused or meaningless. A particularly creative one is the fact that there are command line flags for mount point locations that are then overwritten.
216 lines
7.0 KiB
Bash
Executable File
216 lines
7.0 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 which ensures that a given image has an up-to-date
|
|
# kernel partition, rootfs integrity hashes, and legacy bootloader configs.
|
|
|
|
# --- 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=("$(dirname "$(readlink -f "$0")")/.." /usr/lib/crosutils)
|
|
local path
|
|
|
|
SCRIPT_ROOT="${common_paths[0]}"
|
|
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" || exit 1
|
|
# --- END COMMON.SH BOILERPLATE ---
|
|
|
|
# Need to be inside the chroot to load chromeos-common.sh
|
|
assert_inside_chroot
|
|
|
|
# Load functions and constants for chromeos-install
|
|
. /usr/lib/installer/chromeos-common.sh || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1
|
|
. "${BUILD_LIBRARY_DIR}/build_image_util.sh" || exit 1
|
|
|
|
switch_to_strict_mode
|
|
|
|
if [ $# -lt 2 ]; then
|
|
echo "Usage: ${0} /PATH/TO/IMAGE IMAGE.BIN [shflags overrides]"
|
|
exit 1
|
|
fi
|
|
|
|
IMAGE_DIR="$(readlink -f "${1}")"
|
|
BOOT_DESC_FILE="${IMAGE_DIR}/boot.desc"
|
|
IMAGE="${IMAGE_DIR}/${2}"
|
|
shift
|
|
shift
|
|
FLAG_OVERRIDES="${@}"
|
|
|
|
if [ ! -r "${BOOT_DESC_FILE}" ]; then
|
|
warn "${BOOT_DESC_FILE} cannot be read!"
|
|
warn "Falling back to command line parsing"
|
|
BOOT_DESC="${@}"
|
|
else
|
|
BOOT_DESC="$(cat ${BOOT_DESC_FILE} | tr -s '\n' ' ')"
|
|
info "Boot-time configuration for $(dirname "${IMAGE}"): "
|
|
cat ${BOOT_DESC_FILE} | while read line; do
|
|
info " ${line}"
|
|
done
|
|
fi
|
|
|
|
if [ ! -r "${IMAGE}" ]; then
|
|
die "${IMAGE} cannot be read!"
|
|
fi
|
|
|
|
|
|
locate_gpt
|
|
set +e
|
|
|
|
# Now parse the build settings from ${OUTPUT_DIR}/boot.desc
|
|
DEFINE_string board "${DEFAULT_BOARD}" \
|
|
"Board we're building for."
|
|
DEFINE_string image "coreos_base.img" \
|
|
"Full path to the coreos image to make bootable."
|
|
DEFINE_string arch "x86" \
|
|
"Architecture to make bootable for: arm, x86, or amd64"
|
|
DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \
|
|
"Default all bootloaders to NOT use kernel-based root fs integrity checking."
|
|
DEFINE_string au_key "" \
|
|
"Filename of the au_key to install"
|
|
DEFINE_string production_track "" \
|
|
"Use production values and a given track for update service."
|
|
DEFINE_boolean fsck_rootfs ${FLAGS_FALSE} \
|
|
"Check integrity of the rootfs on the modified image."
|
|
|
|
|
|
# Parse the boot.desc and any overrides
|
|
eval set -- "${BOOT_DESC} ${FLAG_OVERRIDES}"
|
|
FLAGS "${@}" || exit 1
|
|
|
|
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
|
|
|
|
# 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 -u
|
|
|
|
mount_gpt_cleanup() {
|
|
"${SCRIPTS_DIR}/mount_gpt_image.sh" \
|
|
-u -r "${rootfs_mountpoint}" \
|
|
-s "${statefs_mountpoint}" -e "${espfs_mountpoint}"
|
|
}
|
|
|
|
make_image_bootable() {
|
|
local image="$1"
|
|
|
|
# Default to non-verified
|
|
local enable_rootfs_verification_flag=--noenable_rootfs_verification
|
|
if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then
|
|
enable_rootfs_verification_flag=--enable_rootfs_verification
|
|
fi
|
|
|
|
trap "mount_gpt_cleanup" EXIT
|
|
"${SCRIPTS_DIR}/mount_gpt_image.sh" --from "$(dirname "${image}")" \
|
|
--image "$(basename ${image})" -r "${rootfs_mountpoint}" \
|
|
-s "${statefulfs_mountpoint}"
|
|
|
|
legacy_offset_size_export ${image}
|
|
|
|
if [ -n "${FLAGS_production_track}" ]; then
|
|
# Replace /etc/lsb-release on the image.
|
|
"${BUILD_LIBRARY_DIR}/set_lsb_release" \
|
|
--production_track="${FLAGS_production_track}" \
|
|
--root="${rootfs_mountpoint}" \
|
|
--board="${BOARD}"
|
|
fi
|
|
|
|
# Install an auto update key on the root before sealing it off
|
|
if [ ! -z "${FLAGS_au_key}" ]; then
|
|
local key_location=${rootfs_mountpoint}"/usr/share/update_engine/"
|
|
sudo mkdir -p "${key_location}"
|
|
sudo cp "${FLAGS_au_key}" "$key_location/update-payload-key.pub.pem"
|
|
sudo chown root:root "$key_location/update-payload-key.pub.pem"
|
|
sudo chmod 644 "$key_location/update-payload-key.pub.pem"
|
|
echo "AU verification key was installed. Do not forget to resign the image!"
|
|
fi
|
|
|
|
# The rootfs should never be mounted rw again after this point without
|
|
# re-calling make_image_bootable.
|
|
sudo mount -o remount,ro "${rootfs_mountpoint}"
|
|
# Newer `mount` will decode the filename backing the loop device,
|
|
# so we need to dig deeper and find the answer ourselves.
|
|
root_dev=$(awk -v mnt="${rootfs_mountpoint}" \
|
|
'$2 == mnt { print $1 }' /proc/mounts)
|
|
|
|
# Make the filesystem un-mountable as read-write.
|
|
# mount_gpt_image.sh will undo this as needed.
|
|
# TODO(wad) make sure there is parity in the signing scripts.
|
|
if [ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]; then
|
|
# TODO(wad) this would be a good place to reset any other ext2 metadata.
|
|
warn "Disabling r/w mount of the root filesystem"
|
|
disable_rw_mount "$root_dev"
|
|
fi
|
|
|
|
# We should update the esp in place in the image.
|
|
local bootloader_to="${image}"
|
|
local esp_offset="$(partoffset ${image} ${NUM_ESP})"
|
|
esp_offset=$((esp_offset * 512)) # sectors to bytes
|
|
local esp_size="$(partsize ${image} ${NUM_ESP})"
|
|
esp_size=$((esp_size * 512)) # sectors to bytes
|
|
local bootloader_to_flags="--to_offset=${esp_offset} --to_size=${esp_size}"
|
|
|
|
# Update ESP partition
|
|
# NOTE: Boot kernel is identical to regular kernel for now
|
|
${SCRIPTS_DIR}/update_bootloaders.sh \
|
|
--arch=${FLAGS_arch} \
|
|
--to="${bootloader_to}" \
|
|
--from="${rootfs_mountpoint}"/boot \
|
|
--vmlinuz_boot_kernel="${rootfs_mountpoint}"/boot/vmlinuz \
|
|
--vmlinuz="${rootfs_mountpoint}"/boot/vmlinuz \
|
|
${bootloader_to_flags}
|
|
|
|
trap - EXIT
|
|
${SCRIPTS_DIR}/mount_gpt_image.sh -u -r "${rootfs_mountpoint}" \
|
|
-s "${statefulfs_mountpoint}"
|
|
}
|
|
|
|
verify_image_rootfs() {
|
|
local image=$1
|
|
local rootfs_offset="$(partoffset ${image} 3)"
|
|
|
|
local rootfs_tmp_file=$(mktemp)
|
|
trap "rm ${rootfs_tmp_file}" EXIT
|
|
sudo dd if="${image}" of="${rootfs_tmp_file}" bs=512 skip="${rootfs_offset}" \
|
|
status=none
|
|
|
|
# This flips the read-only compatibility flag, so that
|
|
# e2fsck does not complain about unknown file system capabilities.
|
|
enable_rw_mount "${rootfs_tmp_file}"
|
|
info "Running e2fsck to check root file system for errors"
|
|
sudo e2fsck -fn "${rootfs_tmp_file}" ||
|
|
die "Root file system has errors, please ensure boot.desc and/or \
|
|
command line parameters are correct"
|
|
}
|
|
|
|
# Store output and temporary files next to image.
|
|
rootfs_mountpoint="${IMAGE_DIR}/rootfs_dir"
|
|
statefulfs_mountpoint="${IMAGE_DIR}/stateful_dir"
|
|
espfs_mountpoint="${IMAGE_DIR}/esp"
|
|
|
|
# Create the directories if they don't exist.
|
|
mkdir -p ${rootfs_mountpoint}
|
|
mkdir -p ${statefulfs_mountpoint}
|
|
mkdir -p ${espfs_mountpoint}
|
|
|
|
make_image_bootable "${IMAGE}"
|
|
if [ ${FLAGS_fsck_rootfs} -eq ${FLAGS_TRUE} ]; then
|
|
verify_image_rootfs "${IMAGE}"
|
|
fi
|
|
|
|
rmdir ${rootfs_mountpoint}
|
|
rmdir ${statefulfs_mountpoint}
|
|
rmdir ${espfs_mountpoint}
|