blob: 8a010121756e821ec19fc6d86e6d8ce2fd17b1b1 [file] [log] [blame]
#!/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 manipulate the tag files in the output of build_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"
load_shflags
DEFINE_string from "chromiumos_image.bin" \
"Input file name of Chrome OS image to tag/stamp."
DEFINE_string dev_mode "" \
"(build-info) Tag as a developer mode build (1 to enable, 0 to disable)"
DEFINE_string update_firmware "" \
"(auto-update) Force updating firmware (1 to enable, 0 to disable)"
DEFINE_string leave_firmware_alone "" \
"(auto-update) For BIOS development use ONLY (1 to enable, 0 to disable)"
DEFINE_string leave_core "" \
"(crash-reporter) Leave core dumps (1 to enable, 0 to disable)"
# Parameters for manipulating /etc/lsb-release.
DEFINE_boolean remove_test_label false \
"(build-info) Remove 'test' suffix in /etc/lsb-release"
DEFINE_boolean change_dev_to_beta false \
"(build-info) Change 'dev' -> 'beta' in /etc/lsb-release"
# TODO(hungte) we can add factory_installer and factory_test,
# but I don't see any reason to tweak/check these values.
# Parse command line.
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Abort on error.
set -e
if [ -z "${FLAGS_from}" ] || [ ! -s "${FLAGS_from}" ] ; then
echo "Error: need a valid file by --from"
exit 1
fi
# Global variable to track if the image is modified.
g_modified=${FLAGS_FALSE}
# Processes (enable, disable, or simply report) a tag file.
# Args: DO_MODIFICATION NAME ROOT TAG_FILE ACTION
#
# When DO_MODIFICATION=${FLAGS_TRUE},
# Creates (ACTION=1) the TAG_FILE in ROOT, or
# removes (ACTION=0) the TAG_FILE in ROOT, then
# reports the status (and change) to the tag file.
# When DO_MODIFICATION=${FLAGS_FALSE},
# make a dry-run and only change ${g_modified}
function process_tag() {
local tag_status_text=""
local do_modification="$1"
local name="$2"
local root="$3"
local tag_file_path="$3/$4"
local action="$5"
local do_enable=${FLAGS_FALSE}
local do_disable=${FLAGS_FALSE}
# only 1, 0, and "" are valid params to action.
case "${action}" in
"1" )
do_enable=${FLAGS_TRUE}
;;
"0" )
do_disable=${FLAGS_TRUE}
;;
"" )
;;
* )
echo "Error: invalid param to ${name}: ${action} (must be 1 or 0)."
exit 1
;;
esac
if [ -f "${tag_file_path}" ]; then
tag_status_text="ENABLED"
if [ "${do_disable}" = ${FLAGS_TRUE} ]; then
# disable the tag
if [ "${do_modification}" = ${FLAGS_TRUE} ]; then
sudo rm "${tag_file_path}"
fi
g_modified=${FLAGS_TRUE}
tag_status_text="${tag_status_text} => disabled"
elif [ "${do_disable}" != ${FLAGS_FALSE} ]; then
# internal error
echo "Internal error for tag ${name}: need disable param." 1>&2
exit 1
fi
else
tag_status_text="disabled"
if [ "${do_enable}" = ${FLAGS_TRUE} ]; then
# enable the tag
if [ "${do_modification}" = ${FLAGS_TRUE} ]; then
sudo touch "${tag_file_path}"
fi
g_modified=${FLAGS_TRUE}
tag_status_text="${tag_status_text} => ENABLED"
elif [ "${do_enable}" != ${FLAGS_FALSE} ]; then
# internal error
echo "Internal error for tag ${name}: need enable param." 1>&2
exit 1
fi
fi
# report tag status
if [ "${do_modification}" != ${FLAGS_TRUE} ]; then
echo "${name}: ${tag_status_text}"
fi
}
# Iterates all tags to a given partition root.
# Args: ROOTFS DO_MODIFICATION
#
# Check process_tag for the meaning of parameters.
process_all_tags() {
local rootfs="$1"
local do_modification="$2"
process_tag "${do_modification}" \
"(build-info) dev_mode" \
"${rootfs}" \
/root/.dev_mode \
"${FLAGS_dev_mode}"
process_tag "${do_modification}" \
"(auto-update) update_firmware" \
"${rootfs}" \
/root/.force_update_firmware \
"${FLAGS_update_firmware}"
process_tag "${do_modification}" \
"(auto-update) leave_firmware_alone" \
"${rootfs}" \
/root/.leave_firmware_alone \
"${FLAGS_leave_firmware_alone}"
process_tag "${do_modification}" \
"(crash-reporter) leave_core" \
"${rootfs}" \
/root/.leave_core \
"${FLAGS_leave_core}"
}
# Iterates through all options for manipulating the lsb-release.
# Args: ROOTFS DO_MODIFICATION
process_all_lsb_mods() {
local rootfs="$1"
local do_modifications="$2"
local lsb="${rootfs}/etc/lsb-release"
local sudo
if [ ! -w "${lsb}" ]; then
sudo="sudo"
fi
if [ ${FLAGS_remove_test_label} = ${FLAGS_TRUE} ]; then
if grep -wq "test" "${lsb}"; then
g_modified=${FLAGS_TRUE}
fi
if [ ${do_modifications} = ${FLAGS_TRUE} ]; then
${sudo} sed -i 's/\btest\b//' "${lsb}" &&
restore_lsb_selinux "${lsb}" &&
echo "Test Label removed from /etc/lsb-release"
fi
fi
if [ ${FLAGS_change_dev_to_beta} = ${FLAGS_TRUE} ]; then
if grep -wq "dev" "${lsb}"; then
g_modified=${FLAGS_TRUE}
fi
if [ ${do_modifications} = ${FLAGS_TRUE} ]; then
${sudo} sed -i 's/\bdev\b/beta/' "${lsb}" &&
restore_lsb_selinux "${lsb}" &&
echo "Dev Channel Label was changed to Beta"
fi
fi
}
IMAGE=$(readlink -f "${FLAGS_from}")
if [[ -z "${IMAGE}" || ! -f "${IMAGE}" ]]; then
echo "Missing required argument: --from (image to update)"
usage
exit 1
fi
# First round, mount as read-only and check if we need any modifications.
loopdev=$(loopback_partscan "${IMAGE}")
rootfs=$(make_temp_dir)
mount_loop_image_partition_ro "${loopdev}" 3 "${rootfs}"
# we don't have tags in stateful partition yet...
# stateful_dir=$(make_temp_dir)
# mount_loop_image_partition "${loopdev}" 1 "${stateful_dir}"
process_all_tags "${rootfs}" ${FLAGS_FALSE}
process_all_lsb_mods "${rootfs}" ${FLAGS_FALSE}
if [ ${g_modified} = ${FLAGS_TRUE} ]; then
# Remount as RW. We can't use `mount -o rw,remount` because of the bits in
# the ext4 header we've set to block that. See enable_rw_mount for details.
sudo umount "${rootfs}"
mount_loop_image_partition "${loopdev}" 3 "${rootfs}"
# second round, apply the modification to image.
process_all_tags "${rootfs}" ${FLAGS_TRUE}
process_all_lsb_mods "${rootfs}" ${FLAGS_TRUE}
# This is supposed to be automatically done in mount_loop_image_partition,
# but it's no harm to explicitly make it again here.
tag_as_needs_to_be_resigned "${rootfs}"
echo "IMAGE IS MODIFIED. PLEASE REMEMBER TO RESIGN YOUR IMAGE."
else
echo "Image is not modified."
fi