mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-07 21:16:57 +02:00
228 lines
6.8 KiB
Bash
Executable File
228 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (c) 2009 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 convert the output of build_image.sh to a usb image.
|
|
|
|
# Load common constants. This should be the first executable line.
|
|
# The path to common.sh should be relative to your script's location.
|
|
. "$(dirname "$0")/common.sh"
|
|
|
|
get_default_board
|
|
|
|
# Flags
|
|
DEFINE_string board "$DEFAULT_BOARD" "Board for which the image was built"
|
|
DEFINE_string from "" \
|
|
"Directory containing rootfs.image and mbr.image"
|
|
DEFINE_string to "" "$DEFAULT_TO_HELP"
|
|
DEFINE_boolean yes $FLAGS_FALSE "Answer yes to all prompts" "y"
|
|
DEFINE_boolean install_autotest $FLAGS_FALSE \
|
|
"Whether to install autotest to the stateful partition."
|
|
DEFINE_boolean copy_kernel $FLAGS_FALSE \
|
|
"Copy the kernel to the fourth partition."
|
|
|
|
# Parse command line
|
|
FLAGS "$@" || exit 1
|
|
eval set -- "${FLAGS_ARGV}"
|
|
|
|
# Inside the chroot, so output to usb.img in the same dir as the other
|
|
# Script can be run either inside or outside the chroot.
|
|
if [ $INSIDE_CHROOT -eq 1 ]
|
|
then
|
|
AUTOTEST_SRC="/usr/local/autotest/${FLAGS_board}"
|
|
else
|
|
AUTOTEST_SRC="${DEFAULT_CHROOT_DIR}/usr/local/autotest/${FLAGS_board}"
|
|
fi
|
|
|
|
# Die on any errors.
|
|
set -e
|
|
|
|
# No board, no default and no image set then we can't find the image
|
|
if [ -z $FLAGS_from ] && [ -z $FLAGS_board ] ; then
|
|
setup_board_warning
|
|
exit 1
|
|
fi
|
|
|
|
# We have a board name but no image set. Use image at default location
|
|
if [ -z "$FLAGS_from" ]; then
|
|
IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}"
|
|
FLAGS_from="${IMAGES_DIR}/$(ls -t $IMAGES_DIR 2>&-| head -1)"
|
|
fi
|
|
|
|
if [ ! -d "$FLAGS_from" ] ; then
|
|
echo "Cannot find image directory $FLAGS_from"
|
|
exit 1
|
|
fi
|
|
|
|
# If to isn't explicitly set
|
|
if [ -z "$FLAGS_to" ]; then
|
|
# Script can be run either inside or outside the chroot.
|
|
if [ $INSIDE_CHROOT -eq 1 ]
|
|
then
|
|
# Inside the chroot, so output to usb.img in the same dir as the other
|
|
# images.
|
|
FLAGS_to="${FLAGS_from}/usb.img"
|
|
else
|
|
# Outside the chroot, so output to the default device for a usb key.
|
|
FLAGS_to="/dev/sdb"
|
|
fi
|
|
fi
|
|
|
|
# Convert args to paths. Need eval to un-quote the string so that shell
|
|
# chars like ~ are processed; just doing FOO=`readlink -f $FOO` won't work.
|
|
FLAGS_from=`eval readlink -f $FLAGS_from`
|
|
FLAGS_to=`eval readlink -f $FLAGS_to`
|
|
|
|
function do_cleanup {
|
|
sudo losetup -d "$LOOP_DEV"
|
|
}
|
|
|
|
STATEFUL_DIR=${FLAGS_from}/stateful_partition
|
|
mkdir -p "${STATEFUL_DIR}"
|
|
|
|
function install_autotest {
|
|
if [ -d ${AUTOTEST_SRC} ]
|
|
then
|
|
echo -ne "Install autotest into stateful partition..."
|
|
local autotest_client="/home/autotest-client"
|
|
sudo mkdir -p "${STATEFUL_DIR}${autotest_client}"
|
|
sudo cp -fpru ${AUTOTEST_SRC}/client/* \
|
|
"${STATEFUL_DIR}${autotest_client}"
|
|
sudo chmod 755 "${STATEFUL_DIR}${autotest_client}"
|
|
sudo chown -R 1000:1000 "${STATEFUL_DIR}${autotest_client}"
|
|
echo "Done."
|
|
sudo umount "${STATEFUL_DIR}"
|
|
else
|
|
echo "/usr/local/autotest under ${DEFAULT_CHROOT_DIR} is not installed."
|
|
echo "Please call make_autotest.sh inside chroot first."
|
|
sudo umount "${STATEFUL_DIR}"
|
|
exit -1
|
|
fi
|
|
}
|
|
|
|
# Copy MBR and rootfs to output image
|
|
if [ -b "$FLAGS_to" ]
|
|
then
|
|
# Output to a block device (i.e., a real USB key), so need sudo dd
|
|
echo "Copying USB image ${FLAGS_from} to device ${FLAGS_to}..."
|
|
|
|
# Warn if it looks like they supplied a partition as the destination.
|
|
if echo $FLAGS_to | grep -q '[0-9]$'; then
|
|
drive=$(echo $FLAGS_to | sed -re 's/[0-9]+$//')
|
|
if [ -b "$drive" ]; then
|
|
echo
|
|
echo "NOTE: It looks like you may have supplied a partition as the "
|
|
echo "destination. This script needs to write to the drive's device "
|
|
echo "node instead (i.e. ${drive} rather than ${FLAGS_to})."
|
|
echo
|
|
fi
|
|
fi
|
|
|
|
# Make sure this is really what the user wants, before nuking the device
|
|
if [ $FLAGS_yes -ne $FLAGS_TRUE ]
|
|
then
|
|
echo "This will erase all data on this device:"
|
|
sudo fdisk -l "$FLAGS_to" | grep Disk | head -1
|
|
read -p "Are you sure (y/N)? " SURE
|
|
SURE="${SURE:0:1}" # Get just the first character
|
|
if [ "$SURE" != "y" ]
|
|
then
|
|
echo "Ok, better safe than sorry."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "attempting to unmount any mounts on the USB device"
|
|
for i in "$FLAGS_to"*
|
|
do
|
|
! sudo umount "$i"
|
|
done
|
|
sleep 3
|
|
|
|
PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image") # Bytes
|
|
|
|
echo "Copying root fs..."
|
|
sudo "${SCRIPTS_DIR}"/file_copy.py \
|
|
if="${FLAGS_from}/rootfs.image" \
|
|
of="$FLAGS_to" bs=4M \
|
|
seek_bytes=$(( ($PART_SIZE * 2) + 512 ))
|
|
|
|
# Set up loop device
|
|
LOOP_DEV=$(sudo losetup -f)
|
|
if [ -z "$LOOP_DEV" ]
|
|
then
|
|
echo "No free loop device. Free up a loop device or reboot. exiting."
|
|
exit 1
|
|
fi
|
|
|
|
trap do_cleanup EXIT
|
|
|
|
echo "Creating stateful partition..."
|
|
sudo losetup -o 512 "$LOOP_DEV" "$FLAGS_to"
|
|
sudo mkfs.ext3 -F -b 4096 -L C-STATE "$LOOP_DEV" $(( $PART_SIZE / 4096 ))
|
|
if [ $FLAGS_install_autotest -eq $FLAGS_TRUE ]
|
|
then
|
|
sudo mount "${LOOP_DEV}" "${STATEFUL_DIR}"
|
|
install_autotest
|
|
fi
|
|
sync
|
|
sudo losetup -d "$LOOP_DEV"
|
|
sync
|
|
|
|
trap - EXIT
|
|
|
|
if [ $FLAGS_copy_kernel -eq $FLAGS_TRUE ]
|
|
then
|
|
echo "Copying Kernel..."
|
|
"${SCRIPTS_DIR}"/kernel_fetcher.sh \
|
|
--from "${FLAGS_from}" \
|
|
--to "${FLAGS_to}" \
|
|
--offset "$(( ($PART_SIZE * 3) + 512 ))"
|
|
fi
|
|
|
|
echo "Copying MBR..."
|
|
sudo "${SCRIPTS_DIR}"/file_copy.py \
|
|
if="${FLAGS_from}/mbr.image" of="$FLAGS_to"
|
|
sync
|
|
echo "Done."
|
|
else
|
|
# Output to a file, so just cat the source images together
|
|
|
|
PART_SIZE=$(stat -c%s "${FLAGS_from}/rootfs.image")
|
|
|
|
echo "Creating empty stateful partition"
|
|
dd if=/dev/zero of="${FLAGS_from}/stateful_partition.image" bs=1 count=1 \
|
|
seek=$(($PART_SIZE - 1))
|
|
mkfs.ext3 -F -L C-STATE "${FLAGS_from}/stateful_partition.image"
|
|
|
|
if [ $FLAGS_install_autotest -eq $FLAGS_TRUE ]
|
|
then
|
|
sudo mount -o loop "${FLAGS_from}/stateful_partition.image" \
|
|
"${STATEFUL_DIR}"
|
|
install_autotest
|
|
fi
|
|
|
|
# Create a sparse output file
|
|
dd if=/dev/zero of="${FLAGS_to}" bs=1 count=1 \
|
|
seek=$(( ($PART_SIZE * 2) + 512 - 1))
|
|
|
|
echo "Copying USB image to file ${FLAGS_to}..."
|
|
|
|
dd if="${FLAGS_from}/mbr.image" of="$FLAGS_to" conv=notrunc
|
|
dd if="${FLAGS_from}/stateful_partition.image" of="$FLAGS_to" seek=1 bs=512 \
|
|
conv=notrunc
|
|
cat "${FLAGS_from}/rootfs.image" >> "$FLAGS_to"
|
|
|
|
echo "Done. To copy to USB keyfob, outside the chroot, do something like:"
|
|
echo " sudo dd if=${FLAGS_to} of=/dev/sdb bs=4M"
|
|
echo "where /dev/sdb is the entire keyfob."
|
|
if [ $INSIDE_CHROOT -eq 1 ]
|
|
then
|
|
echo "NOTE: Since you are currently inside the chroot, and you'll need to"
|
|
echo "run dd outside the chroot, the path to the USB image will be"
|
|
echo "different (ex: ~/chromeos/trunk/src/build/images/SOME_DIR/usb.img)."
|
|
fi
|
|
fi
|