image_to_usb.sh: disallow --yes/-y without an explicit target (--to)

This should prevent situations where a wrongfully detected target device
(e.g. a hard drive) is being written to without any prompt. With this
change, the semantics of --yes changes to "don't ask me if I'm sure,
just write to the target device in --to". The help line was changed to
reflect this semantics.

Minor changes:

- Replaced die calls with die_notrace.

- Changed the default value for --to into an empty string (why should it
  be /dev/sdX anyway?).

- Fixed an unmount warning message so it's more descriptive (and fits in
  80 columns).

- Check that --install is only used inside the chroot earlier in the
  script.

BUG=None
TEST=Ran the script with different combinations of -y and --to.

Change-Id: I7a4d6eac9697f25d7e1eddb6c34f3c1725a83ef4
Reviewed-on: https://gerrit.chromium.org/gerrit/25404
Reviewed-by: Brian Harring <ferringb@chromium.org>
Commit-Ready: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/image_to_usb.sh b/image_to_usb.sh
index ff57aa6..fba9510 100755
--- a/image_to_usb.sh
+++ b/image_to_usb.sh
@@ -26,13 +26,13 @@
 DEFINE_string board "${DEFAULT_BOARD}" \
   "board for which the image was built"
 DEFINE_string from "" \
-  "directory containing the image, or image full pathname"
-DEFINE_string to "/dev/sdX" \
-  "write to a specific disk or image file"
+  "directory containing the image, or image full pathname (empty: latest found)"
+DEFINE_string to "" \
+  "write to a specific disk or image file (empty: auto-detect)"
 DEFINE_string to_product "" \
   "find target device with product name matching a string (accepts wildcards)"
 DEFINE_boolean yes ${FLAGS_FALSE} \
-  "answer yes to all prompts" \
+  "don't ask questions, just write to the target device specified by --to" \
   y
 DEFINE_boolean force_copy ${FLAGS_FALSE} \
   "always rebuild test image"
@@ -47,7 +47,7 @@
 DEFINE_boolean test_image "${FLAGS_FALSE}" \
   "copy normal image to ${CHROMEOS_TEST_IMAGE_NAME} and modify it for test"
 DEFINE_string image_name "" \
-  "image base name (auto-select if empty)" \
+  "image base name (empty: auto-detect)" \
   i
 DEFINE_boolean install ${FLAGS_FALSE} \
   "install to the USB/MMC device"
@@ -131,6 +131,11 @@
   exit 1
 fi
 
+# Install can only be done from inside the chroot.
+if [ ${FLAGS_install} -eq ${FLAGS_TRUE} ] && [ ${INSIDE_CHROOT} -ne 1 ]; then
+  die_notrace "--install can only be used inside the chroot"
+fi
+
 # We have a board name but no image set.  Use image at default location
 if [ -z "${FLAGS_from}" ]; then
   FLAGS_from="$($SCRIPT_ROOT/get_latest_image.sh --board=${FLAGS_board})"
@@ -141,7 +146,11 @@
 fi
 
 # No target provided, attempt autodetection.
-if [ "${FLAGS_to}" == "/dev/sdX" ]; then
+if [ -z "${FLAGS_to}" ]; then
+  if [ ${FLAGS_yes} -eq ${FLAGS_TRUE} ]; then
+    die_notrace "For your own safety, --yes can only be used with --to"
+  fi
+
   if [ -z "${FLAGS_to_product}" ]; then
     echo "No target device specified, autodetecting..."
   else
@@ -170,9 +179,9 @@
   # If no (matching) devices found, quit.
   if (( ! ${#disk_string_list[*]} )); then
     if [ -z "${FLAGS_to_product}" ]; then
-      die "No USB/MMC devices could be detected"
+      die_notrace "No USB/MMC devices could be detected"
     else
-      die "No matching USB/MMC devices could be detected"
+      die_notrace "No matching USB/MMC devices could be detected"
     fi
   fi
 
@@ -181,7 +190,7 @@
     PS3="Select a target device: "
     select disk_string in "${disk_string_list[@]}"; do
       if [ -z "${disk_string}" ]; then
-        die "Invalid selection"
+        die_notrace "Invalid selection"
       fi
       break
     done
@@ -272,7 +281,7 @@
     # Figure out what to do with the resulting list of images.
     declare -i num_images=${#image_list[*]}
     if (( num_images == 0 )); then
-      die "No candidate images could be detected"
+      die_notrace "No candidate images could be detected"
     elif (( num_images == 1 )) && [ ${is_got_default} == 1 ]; then
       # Found a single image that is the default image, just select it.
       image="${image_list[0]}"
@@ -282,7 +291,7 @@
       PS3="Select an image [1]: "
       choose image "${image_list[0]}" "ERROR" "${image_list[@]}"
       if [ "${image}" == "ERROR" ]; then
-        die "Invalid selection"
+        die_notrace "Invalid selection"
       fi
     fi
 
@@ -315,7 +324,7 @@
     fi
   fi
 
-  # Make sure this is really what the user wants, before nuking the device
+  # Make sure this is really what the user wants, before nuking the device.
   if [ ${FLAGS_yes} -ne ${FLAGS_TRUE} ]; then
     warning_str="this will erase all data on ${FLAGS_to}"
     if [ -n "${disk_string}" ]; then
@@ -332,7 +341,7 @@
     echo "Attempting to unmount any mounts on the target device..."
     for i in ${mount_list}; do
       if sudo umount "$i" 2>&1 >/dev/null | grep "not found"; then
-        die "Device ${FLAGS_to} needs to be unmounted outside the chroot"
+        die_notrace "$i needs to be unmounted outside the chroot"
       fi
     done
     sleep 3
@@ -343,10 +352,6 @@
       sudo dd of="${FLAGS_to}" bs=4M oflag=sync status=noxfer
     sync
   else
-    if [ ${INSIDE_CHROOT} -ne 1 ]; then
-      die "Installation must be done from inside the chroot"
-    fi
-
     "/build/${FLAGS_board}/usr/sbin/chromeos-install" \
       --yes \
       --skip_src_removable \
@@ -357,7 +362,7 @@
   fi
 elif [[ "${FLAGS_to}" == /dev/* ]]; then
   # Did the user attempt to write to a non-existent block device?
-  die "Target device ${FLAGS_to} does not exist"
+  die_notrace "Target device ${FLAGS_to} does not exist"
 else
   # Output to a file, so just make a copy.
   if [ "${SRC_IMAGE}" != "${FLAGS_to}" ]; then