flatcar-scripts/cros_generate_update_payload
Andrew de los Reyes 45c24df9a3 AU update generator script: support for new style full updates
A corresponding CL adds support for the delta generator to generate
new style full updates. This CL adds support for creating new style
full updates to the common update payload generator script.

This does not change the defaults, so generating a full update still uses
the old style.

BUG=7248
TEST=generated/applied full update on host

Review URL: http://codereview.chromium.org/3604011
2010-10-07 19:57:12 -07:00

236 lines
6.9 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 generate a Chromium OS update for use by the update engine.
# If a source .bin is specified, the update is assumed to be a delta update.
# 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"
# Load functions and constants for chromeos-install
. "$(dirname "$0")/chromeos-common.sh"
SRC_MNT=""
DST_MNT=""
SRC_KERNEL=""
SRC_ROOT=""
DST_KERNEL=""
DST_ROOT=""
STATE_MNT=""
STATE_LOOP_DEV=""
# Pass an arg to not exit 1 at the end
cleanup() {
set +e
echo "Cleaning up"
if [ -n "$SRC_MNT" ]; then
sudo umount -d "$SRC_MNT"
[ -d "$SRC_MNT" ] && rmdir "$SRC_MNT"
SRC_MNT=""
fi
if [ -n "$DST_MNT" ]; then
sudo umount -d "$DST_MNT"
[ -d "$DST_MNT" ] && rmdir "$DST_MNT"
DST_MNT=""
fi
if [ -n "$STATE_MNT" ]; then
sudo umount "$STATE_MNT"
[ -d "$STATE_MNT" ] && rmdir "$STATE_MNT"
STATE_MNT=""
fi
if [ -n "$STATE_LOOP_DEV" ]; then
sudo losetup -d "$STATE_LOOP_DEV"
STATE_LOOP_DEV=""
fi
rm -f "$SRC_KERNEL"
rm -f "$SRC_ROOT"
rm -f "$DST_KERNEL"
rm -f "$DST_ROOT"
[ -n "$1" ] || exit 1
}
extract_partition_to_temp_file() {
local filename="$1"
local partition="$2"
local temp_file="$3"
if [ -z "$temp_file" ]; then
temp_file=$(mktemp /tmp/cros_generate_update_payload.XXXXXX)
echo "$temp_file"
fi
local offset=$(partoffset "${filename}" ${partition}) # 512-byte sectors
local length=$(partsize "${filename}" ${partition}) # 512-byte sectors
local bs=512
local sectors_per_two_mib=$((2 * 1024 * 1024 / 512))
if [ $(( $offset % $sectors_per_two_mib )) -eq 0 -a \
$(( $length % $sectors_per_two_mib )) -eq 0 ]; then
bs=$((2 * 1024 * 1024))
offset=$(($offset / $sectors_per_two_mib))
length=$(($length / $sectors_per_two_mib))
else
warn "partition offset or length not at 2MiB boundary"
fi
dd if="$filename" of="$temp_file" bs=$bs count="$length" skip="$offset"
}
patch_kernel() {
local IMAGE="$1"
local KERN_FILE="$2"
STATE_LOOP_DEV=$(sudo losetup -f)
[ -n "$STATE_LOOP_DEV" ] || die "no free loop device"
local offset=$(partoffset "${IMAGE}" 1)
offset=$(($offset * 512))
sudo losetup -o "$offset" "$STATE_LOOP_DEV" "$IMAGE"
STATE_MNT=$(mktemp -d /tmp/state.XXXXXX)
sudo mount "$STATE_LOOP_DEV" "$STATE_MNT"
dd if="$STATE_MNT"/vmlinuz_hd.vblock of="$KERN_FILE" conv=notrunc
sudo umount "$STATE_MNT"
STATE_MNT=""
sudo losetup -d "$STATE_LOOP_DEV"
STATE_LOOP_DEV=""
}
extract_kern_root() {
local bin_file="$1"
local kern_out="$2"
local root_out="$3"
if [ -z "$kern_out" ]; then
die "missing kernel output filename"
fi
if [ -z "$root_out" ]; then
die "missing root output filename"
fi
extract_partition_to_temp_file "$bin_file" 2 "$kern_out"
if [ "$FLAGS_patch_kernel" -eq "$FLAGS_TRUE" ]; then
patch_kernel "$bin_file" "$kern_out"
fi
extract_partition_to_temp_file "$bin_file" 3 "$root_out"
}
DEFINE_string image "" "The image that should be sent to clients."
DEFINE_string src_image "" "Optional: a source image. If specified, this makes\
a delta update."
DEFINE_boolean old_style "$FLAGS_TRUE" "Generate an old-style .gz full update."
DEFINE_string output "" "Output file"
DEFINE_boolean patch_kernel "$FLAGS_FALSE" "Whether or not to patch the kernel \
with the patch from the stateful partition (default: false)"
DEFINE_string private_key "" "Path to private key in .pem format."
DEFINE_boolean extract "$FLAGS_FALSE" "If set, extract old/new kernel/rootfs \
to [old|new]_[kern|root].dat. Useful for debugging (default: false)"
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
set -e
if [ -n "$FLAGS_src_image" ]; then
# We need to be in the chroot for generating delta images
assert_inside_chroot
fi
locate_gpt
if [ "$FLAGS_extract" -eq "$FLAGS_TRUE" ]; then
if [ -n "$FLAGS_src_image" ]; then
extract_kern_root "$FLAGS_src_image" old_kern.dat old_root.dat
fi
if [ -n "$FLAGS_image" ]; then
extract_kern_root "$FLAGS_image" new_kern.dat new_root.dat
fi
echo Done extracting kernel/root
exit 0
fi
DELTA=$FLAGS_TRUE
[ -n "$FLAGS_output" ] || die \
"Error: you must specify an output filename with --output FILENAME"
if [ -z "$FLAGS_src_image" ]; then
DELTA=$FLAGS_FALSE
if [ "$FLAGS_old_style" = "$FLAGS_TRUE" ]; then
echo "Generating an old-style full update"
else
echo "Generating a new-style full update"
fi
fi
if [ "$DELTA" -eq "$FLAGS_TRUE" -o "$FLAGS_old_style" -eq "$FLAGS_FALSE" ]; then
echo "Generating a delta update"
# Sanity check that the real generator exists:
GENERATOR="$(dirname "$0")/../platform/update_engine/delta_generator"
[ -x "$GENERATOR" ] || die "$GENERATOR doesn't exist, or isn't executable"
trap cleanup INT TERM EXIT
if [ "$DELTA" -eq "$FLAGS_TRUE" ]; then
SRC_KERNEL=$(extract_partition_to_temp_file "$FLAGS_src_image" 2)
if [ "$FLAGS_patch_kernel" -eq "$FLAGS_TRUE" ]; then
patch_kernel "$FLAGS_src_image" "$SRC_KERNEL"
fi
SRC_ROOT=$(extract_partition_to_temp_file "$FLAGS_src_image" 3)
echo md5sum of src kernel:
md5sum "$SRC_KERNEL"
echo md5sum of src root:
md5sum "$SRC_ROOT"
fi
DST_KERNEL=$(extract_partition_to_temp_file "$FLAGS_image" 2)
if [ "$FLAGS_patch_kernel" -eq "$FLAGS_TRUE" ]; then
patch_kernel "$FLAGS_image" "$DST_KERNEL"
fi
DST_ROOT=$(extract_partition_to_temp_file "$FLAGS_image" 3)
if [ "$DELTA" -eq "$FLAGS_TRUE" ]; then
SRC_MNT=$(mktemp -d /tmp/src_root.XXXXXX)
sudo mount -o loop,ro "$SRC_ROOT" "$SRC_MNT"
DST_MNT=$(mktemp -d /tmp/src_root.XXXXXX)
sudo mount -o loop,ro "$DST_ROOT" "$DST_MNT"
sudo "$GENERATOR" \
-new_dir "$DST_MNT" -new_image "$DST_ROOT" -new_kernel "$DST_KERNEL" \
-old_dir "$SRC_MNT" -old_image "$SRC_ROOT" -old_kernel "$SRC_KERNEL" \
-out_file "$FLAGS_output" -private_key "$FLAGS_private_key"
else
"$GENERATOR" \
-new_image "$DST_ROOT" -new_kernel "$DST_KERNEL" \
-out_file "$FLAGS_output" -private_key "$FLAGS_private_key"
fi
trap - INT TERM EXIT
cleanup noexit
if [ "$DELTA" -eq "$FLAGS_TRUE" ]; then
echo "Done generating delta."
else
echo "Done generating new style full update."
fi
else
echo "Generating full update"
trap cleanup INT TERM EXIT
DST_KERNEL=$(extract_partition_to_temp_file "$FLAGS_image" 2)
if [ "$FLAGS_patch_kernel" -eq "$FLAGS_TRUE" ]; then
patch_kernel "$FLAGS_image" "$DST_KERNEL"
fi
DST_ROOT=$(extract_partition_to_temp_file "$FLAGS_image" 3)
GENERATOR="$(dirname "$0")/mk_memento_images.sh"
CROS_GENERATE_UPDATE_PAYLOAD_CALLED=1 "$GENERATOR" "$DST_KERNEL" "$DST_ROOT"
mv "$(dirname "$DST_KERNEL")/update.gz" "$FLAGS_output"
trap - INT TERM EXIT
cleanup noexit
echo "Done generating full update."
fi