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