| OLD | NEW |
| 1 #!/bin/bash | 1 #!/bin/bash |
| 2 | 2 |
| 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 # Script to modify a keyfob-based chromeos system image for testability. | 7 # Script to modify a keyfob-based chromeos system image for testability. |
| 8 | 8 |
| 9 # Load common constants. This should be the first executable line. | 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. | 10 # The path to common.sh should be relative to your script's location. |
| 11 . "$(dirname "$0")/common.sh" | 11 . "$(dirname "$0")/common.sh" |
| 12 | 12 |
| 13 # Load functions and constants for chromeos-install | 13 # Load functions and constants for chromeos-install |
| 14 . "$(dirname "$0")/chromeos-common.sh" | 14 . "$(dirname "$0")/chromeos-common.sh" |
| 15 | 15 |
| 16 # We need to be in the chroot to emerge test packages. |
| 17 assert_inside_chroot |
| 18 |
| 16 get_default_board | 19 get_default_board |
| 17 | 20 |
| 18 DEFINE_string board "$DEFAULT_BOARD" "Board for which the image was built" | 21 DEFINE_string board "$DEFAULT_BOARD" "Board for which the image was built" b |
| 19 DEFINE_string qualdb "/tmp/run_remote_tests.*" \ | 22 DEFINE_boolean factory $FLAGS_FALSE \ |
| 20 "Location of qualified component file" | 23 "Modify the image for manufacturing testing" f |
| 21 DEFINE_string image "" "Location of the rootfs raw image file" | |
| 22 DEFINE_boolean factory $FLAGS_FALSE "Modify the image for manufacturing testing" | |
| 23 DEFINE_boolean factory_install $FLAGS_FALSE \ | 24 DEFINE_boolean factory_install $FLAGS_FALSE \ |
| 24 "Modify the image for factory install shim" | 25 "Modify the image for factory install shim" |
| 25 DEFINE_boolean yes $FLAGS_FALSE "Answer yes to all prompts" "y" | 26 DEFINE_string image "" "Location of the rootfs raw image file" i |
| 27 DEFINE_boolean installmask $FLAGS_TRUE \ |
| 28 "Use INSTALL_MASK to shrink the resulting image." m |
| 29 DEFINE_integer jobs -1 \ |
| 30 "How many packages to build in parallel at maximum." j |
| 31 DEFINE_string qualdb "/tmp/run_remote_tests.*" \ |
| 32 "Location of qualified component file" d |
| 33 DEFINE_boolean yes $FLAGS_FALSE "Answer yes to all prompts" y |
| 26 | 34 |
| 27 # Parse command line | 35 # Parse command line |
| 28 FLAGS "$@" || exit 1 | 36 FLAGS "$@" || exit 1 |
| 29 eval set -- "${FLAGS_ARGV}" | 37 eval set -- "${FLAGS_ARGV}" |
| 30 | 38 |
| 31 # No board, no default and no image set then we can't find the image | 39 # No board, no default and no image set then we can't find the image |
| 32 if [ -z $FLAGS_image ] && [ -z $FLAGS_board ] ; then | 40 if [ -z $FLAGS_image ] && [ -z $FLAGS_board ] ; then |
| 33 setup_board_warning | 41 setup_board_warning |
| 34 echo "*** mod_image_for_test failed. No board set and no image set" | 42 die "mod_image_for_test failed. No board set and no image set" |
| 35 exit 1 | |
| 36 fi | 43 fi |
| 37 | 44 |
| 38 # We have a board name but no image set. Use image at default location | 45 # We have a board name but no image set. Use image at default location |
| 39 if [ -z $FLAGS_image ] ; then | 46 if [ -z $FLAGS_image ] ; then |
| 40 IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}" | 47 IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}" |
| 41 FILENAME="chromiumos_image.bin" | 48 FILENAME="chromiumos_image.bin" |
| 42 FLAGS_image="${IMAGES_DIR}/$(ls -t $IMAGES_DIR 2>&-| head -1)/${FILENAME}" | 49 FLAGS_image="${IMAGES_DIR}/$(ls -t $IMAGES_DIR 2>&-| head -1)/${FILENAME}" |
| 43 fi | 50 fi |
| 44 | 51 |
| 52 # Turn path into an absolute path. |
| 53 FLAGS_image=`eval readlink -f ${FLAGS_image}` |
| 54 |
| 45 # Abort early if we can't find the image | 55 # Abort early if we can't find the image |
| 46 if [ ! -f $FLAGS_image ] ; then | 56 if [ ! -f $FLAGS_image ] ; then |
| 47 echo "No image found at $FLAGS_image" | 57 echo "No image found at $FLAGS_image" |
| 48 exit 1 | 58 exit 1 |
| 49 fi | 59 fi |
| 50 | 60 |
| 51 # Make sure anything mounted in the rootfs/stateful is cleaned up ok on exit. | 61 # Make sure anything mounted in the rootfs/stateful is cleaned up ok on exit. |
| 52 cleanup_mounts() { | 62 cleanup_mounts() { |
| 53 # Occasionally there are some daemons left hanging around that have our | 63 # Occasionally there are some daemons left hanging around that have our |
| 54 # root/stateful image file system open. We do a best effort attempt to kill | 64 # root/stateful image file system open. We do a best effort attempt to kill |
| 55 # them. | 65 # them. |
| 56 PIDS=`sudo lsof -t "$1" | sort | uniq` | 66 PIDS=`sudo lsof -t "$1" | sort | uniq` |
| 57 for pid in ${PIDS} | 67 for pid in ${PIDS} |
| 58 do | 68 do |
| 59 local cmdline=`cat /proc/$pid/cmdline` | 69 local cmdline=`cat /proc/$pid/cmdline` |
| 60 echo "Killing process that has open file on the mounted directory: $cmdline" | 70 echo "Killing process that has open file on the mounted directory: $cmdline" |
| 61 sudo kill $pid || /bin/true | 71 sudo kill $pid || /bin/true |
| 62 done | 72 done |
| 63 } | 73 } |
| 64 | 74 |
| 65 cleanup_loop() { | 75 cleanup() { |
| 66 sudo umount "$1" | 76 "$SCRIPTS_DIR/mount_gpt_image.sh" -u -r "$ROOT_FS_DIR" -s "$STATEFUL_DIR" |
| 67 sleep 1 # in case the loop device is in use | |
| 68 sudo losetup -d "$1" | |
| 69 } | 77 } |
| 70 | 78 |
| 71 cleanup() { | 79 # Emerges chromeos-test onto the image. |
| 72 # Disable die on error. | 80 emerge_chromeos_test() { |
| 73 set +e | 81 INSTALL_MASK="" |
| 82 if [[ $FLAGS_installmask -eq ${FLAGS_TRUE} ]]; then |
| 83 INSTALL_MASK="$DEFAULT_INSTALL_MASK" |
| 84 fi |
| 74 | 85 |
| 75 cleanup_mounts "${ROOT_FS_DIR}" | 86 # Determine the root dir for test packages. |
| 76 if [ -n "${ROOT_LOOP_DEV}" ] | 87 ROOT_DEV_DIR="$ROOT_FS_DIR/usr/local" |
| 77 then | |
| 78 sudo umount "${ROOT_FS_DIR}/var" | |
| 79 cleanup_loop "${ROOT_LOOP_DEV}" | |
| 80 fi | |
| 81 rmdir "${ROOT_FS_DIR}" | |
| 82 | 88 |
| 83 cleanup_mounts "${STATEFUL_DIR}" | 89 INSTALL_MASK="$INSTALL_MASK" emerge-${FLAGS_board} \ |
| 84 if [ -n "${STATEFUL_LOOP_DEV}" ] | 90 --root="$ROOT_DEV_DIR" --root-deps=rdeps \ |
| 85 then | 91 --usepkgonly chromeos-test $EMERGE_JOBS |
| 86 cleanup_loop "${STATEFUL_LOOP_DEV}" | |
| 87 fi | |
| 88 rmdir "${STATEFUL_DIR}" | |
| 89 | |
| 90 # Turn die on error back on. | |
| 91 set -e | |
| 92 } | 92 } |
| 93 | 93 |
| 94 # main process begins here. | 94 # main process begins here. |
| 95 | 95 |
| 96 # Make sure this is really what the user wants, before nuking the device | 96 # Make sure this is really what the user wants, before nuking the device |
| 97 if [ $FLAGS_yes -ne $FLAGS_TRUE ]; then | 97 if [ $FLAGS_yes -ne $FLAGS_TRUE ]; then |
| 98 read -p "Modifying image ${FLAGS_image} for test; are you sure (y/N)? " SURE | 98 read -p "Modifying image ${FLAGS_image} for test; are you sure (y/N)? " SURE |
| 99 SURE="${SURE:0:1}" # Get just the first character | 99 SURE="${SURE:0:1}" # Get just the first character |
| 100 if [ "$SURE" != "y" ]; then | 100 if [ "$SURE" != "y" ]; then |
| 101 echo "Ok, better safe than sorry." | 101 echo "Ok, better safe than sorry." |
| 102 exit 1 | 102 exit 1 |
| 103 fi | 103 fi |
| 104 else | 104 else |
| 105 echo "Modifying image ${FLAGS_image} for test..." | 105 echo "Modifying image ${FLAGS_image} for test..." |
| 106 fi | 106 fi |
| 107 | 107 |
| 108 set -e | 108 set -e |
| 109 | 109 |
| 110 ROOT_FS_DIR=$(dirname "${FLAGS_image}")/rootfs | 110 IMAGE_DIR="$(dirname "$FLAGS_image")" |
| 111 mkdir -p "${ROOT_FS_DIR}" | 111 IMAGE_NAME="$(basename "$FLAGS_image")" |
| 112 | 112 ROOT_FS_DIR="$IMAGE_DIR/rootfs" |
| 113 STATEFUL_DIR=$(dirname "${FLAGS_image}")/stateful_partition | 113 STATEFUL_DIR="$IMAGE_DIR/stateful_partition" |
| 114 mkdir -p "${STATEFUL_DIR}" | 114 SCRIPTS_DIR=$(dirname "$0") |
| 115 | 115 |
| 116 trap cleanup EXIT | 116 trap cleanup EXIT |
| 117 | 117 |
| 118 # Figure out how to loop mount the rootfs partition. It should be partition 3 | 118 # Mounts gpt image and sets up var, /usr/local and symlinks. |
| 119 # on the disk image. | 119 "$SCRIPTS_DIR/mount_gpt_image.sh" -i "$IMAGE_NAME" -f "$IMAGE_DIR" \ |
| 120 offset=$(partoffset "${FLAGS_image}" 3) | 120 -r "$ROOT_FS_DIR" -s "$STATEFUL_DIR" |
| 121 | 121 |
| 122 ROOT_LOOP_DEV=$(sudo losetup -f) | 122 emerge_chromeos_test |
| 123 if [ -z "$ROOT_LOOP_DEV" ]; then | |
| 124 echo "No free loop device" | |
| 125 exit 1 | |
| 126 fi | |
| 127 sudo losetup -o $(( $offset * 512 )) "${ROOT_LOOP_DEV}" "${FLAGS_image}" | |
| 128 sudo mount "${ROOT_LOOP_DEV}" "${ROOT_FS_DIR}" | |
| 129 | |
| 130 # The stateful partition should be partition 1 on the disk image. | |
| 131 offset=$(partoffset "${FLAGS_image}" 1) | |
| 132 | |
| 133 STATEFUL_LOOP_DEV=$(sudo losetup -f) | |
| 134 if [ -z "$STATEFUL_LOOP_DEV" ]; then | |
| 135 echo "No free loop device" | |
| 136 exit 1 | |
| 137 fi | |
| 138 sudo losetup -o $(( $offset * 512 )) "${STATEFUL_LOOP_DEV}" "${FLAGS_image}" | |
| 139 sudo mount "${STATEFUL_LOOP_DEV}" "${STATEFUL_DIR}" | |
| 140 sudo mount --bind "${STATEFUL_DIR}/var" "${ROOT_FS_DIR}/var" | |
| 141 STATEFUL_DIR="${STATEFUL_DIR}" | |
| 142 | 123 |
| 143 MOD_TEST_ROOT="${GCLIENT_ROOT}/src/scripts/mod_for_test_scripts" | 124 MOD_TEST_ROOT="${GCLIENT_ROOT}/src/scripts/mod_for_test_scripts" |
| 144 # Run test setup script to modify the image | 125 # Run test setup script to modify the image |
| 145 sudo GCLIENT_ROOT="${GCLIENT_ROOT}" ROOT_FS_DIR="${ROOT_FS_DIR}" \ | 126 sudo GCLIENT_ROOT="${GCLIENT_ROOT}" ROOT_FS_DIR="${ROOT_FS_DIR}" \ |
| 146 "${MOD_TEST_ROOT}/test_setup.sh" | 127 "${MOD_TEST_ROOT}/test_setup.sh" |
| 147 | 128 |
| 148 if [ ${FLAGS_factory} -eq ${FLAGS_TRUE} ]; then | 129 if [ ${FLAGS_factory} -eq ${FLAGS_TRUE} ]; then |
| 149 MOD_FACTORY_ROOT="${GCLIENT_ROOT}/src/scripts/mod_for_factory_scripts" | 130 MOD_FACTORY_ROOT="${GCLIENT_ROOT}/src/scripts/mod_for_factory_scripts" |
| 150 # Run factory setup script to modify the image | 131 # Run factory setup script to modify the image |
| 151 sudo GCLIENT_ROOT="${GCLIENT_ROOT}" ROOT_FS_DIR="${ROOT_FS_DIR}" \ | 132 sudo GCLIENT_ROOT="${GCLIENT_ROOT}" ROOT_FS_DIR="${ROOT_FS_DIR}" \ |
| 152 STATEFUL_DIR="${STATEFUL_DIR}/dev_image" QUALDB="${FLAGS_qualdb}" \ | 133 STATEFUL_DIR="${STATEFUL_DIR}/dev_image" QUALDB="${FLAGS_qualdb}" \ |
| 153 "${MOD_FACTORY_ROOT}/factory_setup.sh" | 134 "${MOD_FACTORY_ROOT}/factory_setup.sh" |
| 154 fi | 135 fi |
| 155 | 136 |
| 156 if [ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]; then | 137 if [ ${FLAGS_factory_install} -eq ${FLAGS_TRUE} ]; then |
| 157 # Run factory setup script to modify the image. | 138 # Run factory setup script to modify the image. |
| 158 sudo emerge-${FLAGS_board} --root=$ROOT_FS_DIR --usepkgonly \ | 139 sudo emerge-${FLAGS_board} --root=$ROOT_FS_DIR --usepkgonly \ |
| 159 --root-deps=rdeps chromeos-factoryinstall | 140 --root-deps=rdeps chromeos-factoryinstall |
| 160 | 141 |
| 161 # Set factory server if necessary. | 142 # Set factory server if necessary. |
| 162 if [ "${FACTORY_SERVER}" != "" ]; then | 143 if [ "${FACTORY_SERVER}" != "" ]; then |
| 163 sudo sed -i \ | 144 sudo sed -i \ |
| 164 "s/CHROMEOS_AUSERVER=.*$/CHROMEOS_AUSERVER=\ | 145 "s/CHROMEOS_AUSERVER=.*$/CHROMEOS_AUSERVER=\ |
| 165 http:\/\/${FACTORY_SERVER}:8080\/update/" \ | 146 http:\/\/${FACTORY_SERVER}:8080\/update/" \ |
| 166 ${ROOT_FS_DIR}/etc/lsb-release | 147 ${ROOT_FS_DIR}/etc/lsb-release |
| 167 fi | 148 fi |
| 168 fi | 149 fi |
| 169 | 150 |
| 170 cleanup | 151 cleanup |
| 171 trap - EXIT | 152 trap - EXIT |
| 172 | 153 |
| OLD | NEW |