Home | History | Annotate | Download | only in image_signing
      1 #!/bin/bash
      2 
      3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 # Script to manipulate the tag files in the output of build_image
      8 
      9 # Load common constants.  This should be the first executable line.
     10 # The path to common.sh should be relative to your script's location.
     11 . "$(dirname "$0")/common.sh"
     12 
     13 load_shflags
     14 
     15 DEFINE_string from "chromiumos_image.bin" \
     16   "Input file name of Chrome OS image to tag/stamp."
     17 DEFINE_string dev_mode "" \
     18   "(build-info) Tag as a developer mode build (1 to enable, 0 to disable)"
     19 DEFINE_string update_firmware "" \
     20   "(auto-update) Force updating firmware (1 to enable, 0 to disable)"
     21 DEFINE_string leave_firmware_alone "" \
     22   "(auto-update) For BIOS development use ONLY (1 to enable, 0 to disable)"
     23 DEFINE_string leave_core "" \
     24   "(crash-reporter) Leave core dumps (1 to enable, 0 to disable)"
     25 DEFINE_string crosh_workarounds "" \
     26   "(crosh) Keep crosh (1 to keep, 0 to disable *irreversible*)"
     27 
     28 # Parameters for manipulating /etc/lsb-release.
     29 DEFINE_boolean remove_test_label false \
     30   "(build-info) Remove 'test' suffix in /etc/lsb-release"
     31 DEFINE_boolean change_dev_to_beta false \
     32   "(build-info) Change 'dev' -> 'beta' in /etc/lsb-release"
     33 
     34 
     35 # TODO(hungte) we can add factory_installer and factory_test,
     36 # but I don't see any reason to tweak/check these values.
     37 
     38 # Parse command line.
     39 FLAGS "$@" || exit 1
     40 eval set -- "${FLAGS_ARGV}"
     41 
     42 # Abort on error.
     43 set -e
     44 
     45 if [ -z "${FLAGS_from}" ] || [ ! -s "${FLAGS_from}" ] ; then
     46   echo "Error: need a valid file by --from"
     47   exit 1
     48 fi
     49 
     50 # Global variable to track if the image is modified.
     51 g_modified=${FLAGS_FALSE}
     52 
     53 # Processes (enable, disable, or simply report) a tag file.
     54 # Args: DO_MODIFICATION NAME ROOT TAG_FILE ACTION
     55 #
     56 # When DO_MODIFICATION=${FLAGS_TRUE},
     57 #  Creates (ACTION=1) the TAG_FILE in ROOT, or
     58 #  removes (ACTION=0) the TAG_FILE in ROOT, then
     59 #  reports the status (and change) to the tag file.
     60 # When DO_MODIFICATION=${FLAGS_FALSE},
     61 #  make a dry-run and only change ${g_modified}
     62 function process_tag() {
     63   local tag_status_text=""
     64   local do_modification="$1"
     65   local name="$2"
     66   local root="$3"
     67   local tag_file_path="$3/$4"
     68   local action="$5"
     69   local do_enable=${FLAGS_FALSE}
     70   local do_disable=${FLAGS_FALSE}
     71 
     72   # only 1, 0, and "" are valid params to action.
     73   case "${action}" in
     74     "1" )
     75       do_enable=${FLAGS_TRUE}
     76       ;;
     77     "0" )
     78       do_disable=${FLAGS_TRUE}
     79       ;;
     80     "" )
     81       ;;
     82     * )
     83       echo "Error: invalid param to ${name}: ${action} (must be 1 or 0)."
     84       exit 1
     85       ;;
     86   esac
     87 
     88   if [ -f "${tag_file_path}" ]; then
     89     tag_status_text="ENABLED"
     90     if [ "${do_disable}" = ${FLAGS_TRUE} ]; then
     91       # disable the tag
     92       if [ "${do_modification}" = ${FLAGS_TRUE} ]; then
     93         sudo rm "${tag_file_path}"
     94       fi
     95       g_modified=${FLAGS_TRUE}
     96       tag_status_text="${tag_status_text} => disabled"
     97     elif [ "${do_disable}" != ${FLAGS_FALSE} ]; then
     98       # internal error
     99       echo "Internal error for tag ${name}: need disable param." 1>&2
    100       exit 1
    101     fi
    102   else
    103     tag_status_text="disabled"
    104     if [ "${do_enable}" = ${FLAGS_TRUE} ]; then
    105       # enable the tag
    106       if [ "${do_modification}" = ${FLAGS_TRUE} ]; then
    107         sudo touch "${tag_file_path}"
    108       fi
    109       g_modified=${FLAGS_TRUE}
    110       tag_status_text="${tag_status_text} => ENABLED"
    111     elif [ "${do_enable}" != ${FLAGS_FALSE} ]; then
    112       # internal error
    113       echo "Internal error for tag ${name}: need enable param." 1>&2
    114       exit 1
    115     fi
    116   fi
    117 
    118   # report tag status
    119   if [ "${do_modification}" != ${FLAGS_TRUE} ]; then
    120     echo "${name}: ${tag_status_text}"
    121   fi
    122 }
    123 
    124 # Iterates all tags to a given partition root.
    125 # Args: ROOTFS DO_MODIFICATION
    126 #
    127 # Check process_tag for the meaning of parameters.
    128 process_all_tags() {
    129   local rootfs="$1"
    130   local do_modification="$2"
    131 
    132   process_tag "${do_modification}" \
    133     "(build-info) dev_mode" \
    134     "${rootfs}" \
    135     /root/.dev_mode \
    136     "${FLAGS_dev_mode}"
    137 
    138   process_tag "${do_modification}" \
    139     "(auto-update) update_firmware" \
    140     "${rootfs}" \
    141     /root/.force_update_firmware \
    142     "${FLAGS_update_firmware}"
    143 
    144   process_tag "${do_modification}" \
    145     "(auto-update) leave_firmware_alone" \
    146     "${rootfs}" \
    147     /root/.leave_firmware_alone \
    148     "${FLAGS_leave_firmware_alone}"
    149 
    150   process_tag "${do_modification}" \
    151     "(crash-reporter) leave_core" \
    152     "${rootfs}" \
    153     /root/.leave_core \
    154     "${FLAGS_leave_core}"
    155 
    156   process_tag "${do_modification}" \
    157     "(crosh) crosh_workarounds" \
    158     "${rootfs}" \
    159     /usr/bin/crosh-workarounds \
    160     "${FLAGS_crosh_workarounds}"
    161 }
    162 
    163 # Iterates through all options for manipulating the lsb-release.
    164 # Args: ROOTFS DO_MODIFICATION
    165 process_all_lsb_mods() {
    166   local rootfs="$1"
    167   local do_modifications="$2"
    168   local lsb="${rootfs}/etc/lsb-release"
    169   local sudo
    170 
    171   if [ ! -w "${lsb}" ]; then
    172     sudo="sudo"
    173   fi
    174 
    175   if [ ${FLAGS_remove_test_label} = ${FLAGS_TRUE} ]; then
    176     if grep -wq "test" "${lsb}"; then
    177       g_modified=${FLAGS_TRUE}
    178     fi
    179     if [ ${do_modifications} = ${FLAGS_TRUE} ]; then
    180       ${sudo} sed -i 's/\btest\b//' "${lsb}" &&
    181         echo "Test Label removed from /etc/lsb-release"
    182     fi
    183   fi
    184 
    185   if [ ${FLAGS_change_dev_to_beta} = ${FLAGS_TRUE} ]; then
    186     if grep -wq "dev" "${lsb}"; then
    187       g_modified=${FLAGS_TRUE}
    188     fi
    189     if [ ${do_modifications} = ${FLAGS_TRUE} ]; then
    190       ${sudo} sed -i 's/\bdev\b/beta/' "${lsb}" &&
    191         echo "Dev Channel Label was changed to Beta"
    192     fi
    193   fi
    194 }
    195 
    196 
    197 IMAGE=$(readlink -f "${FLAGS_from}")
    198 if [[ -z "${IMAGE}" || ! -f "${IMAGE}" ]]; then
    199   echo "Missing required argument: --from (image to update)"
    200   usage
    201   exit 1
    202 fi
    203 
    204 # First round, mount as read-only and check if we need any modifications.
    205 rootfs=$(make_temp_dir)
    206 mount_image_partition_ro "${IMAGE}" 3 "${rootfs}"
    207 
    208 # we don't have tags in stateful partition yet...
    209 # stateful_dir=$(make_temp_dir)
    210 # mount_image_partition ${IMAGE} 1 ${stateful_dir}
    211 
    212 process_all_tags "${rootfs}" ${FLAGS_FALSE}
    213 process_all_lsb_mods "${rootfs}" ${FLAGS_FALSE}
    214 
    215 if [ ${g_modified} = ${FLAGS_TRUE} ]; then
    216   # remount as RW (we can't use mount -o rw,remount because of loop device)
    217   sudo umount "${rootfs}"
    218   mount_image_partition "${IMAGE}" 3 "${rootfs}"
    219 
    220   # second round, apply the modification to image.
    221   process_all_tags "${rootfs}" ${FLAGS_TRUE}
    222   process_all_lsb_mods "${rootfs}" ${FLAGS_TRUE}
    223 
    224   # this is supposed to be automatically done in mount_image_partition,
    225   # but it's no harm to explicitly make it again here.
    226   tag_as_needs_to_be_resigned "${rootfs}"
    227   echo "IMAGE IS MODIFIED. PLEASE REMEMBER TO RESIGN YOUR IMAGE."
    228 else
    229   echo "Image is not modified."
    230 fi
    231