blob: 8a8aa4d00e68172ae31cd474a604f338164d6496 [file] [log] [blame]
#!/bin/sh
# Emergency Recovery Mode.
#
# The recovery image will be streamed using ginstall from a Google property
# over HTTPS. If the 'emergency' boot flag is set then we will immediately break
# out of emergency mode and allow the device to fully boot into the emergency
# recovery image.
. /etc/utils.sh
# The URL where our recovery GI images are hosted.
DOMAIN="https://storage.googleapis.com/gfiber-emergency-images/current"
# The number of times we will retry an operation before giving up and rebooting.
MAX_RETRIES="3"
# Host to ping to verify we have external reachability.
PING_HOST="8.8.8.8"
log() {
echo "$(basename $0):" "$@" >&2
}
is_emergency_debug() {
# If boot flag is set, allow the box to boot fully.
if grep -Fq "emergency_debug=1" /proc/cmdline; then
return 0
fi
return 1
}
do_reboot() {
# Ensure we don't reboot when we are supposed to allow a complete boot up.
if ! is_emergency_debug; then
log "Rebooting..."
reboot || log "Failed to reboot!"
fi
}
on_exit() {
do_reboot
}
# We can't trap ERR because it's a POSIX extension that dash does not implement.
trap on_exit EXIT
image_file() {
local model=$(cat /etc/platform)
log "model: ${model}"
# TODO(cgibson): Add support for more platforms.
# TODO(cgibson): Pass model name in URL and let the server decide what
# image we get.
case "${model}" in
GFRG2*0)
echo "gfrg200.gi"
;;
GFHD200)
echo "gftv200.gi"
;;
*)
log "Unsupported platform: ${model}"
;;
esac
}
log "Starting emergency recovery mode!"
if is_emergency_debug; then
log "emergency boot flag is set, allowing device to fully boot."
exit 0
fi
log "Checking platform support for emergency recovery image..."
GINSTALL_IMAGE_FILE=$(image_file)
if [ -z ${GINSTALL_IMAGE_FILE} ]; then
log "Failed to identify a recovery image for this platform!"
exit 1
fi
# We may not have a publically routable IP address yet, so wait for a while
# until we can ping the outside world.
log "Waiting for external connectivity..."
i="0"
while [ ${i} -lt ${MAX_RETRIES} ]; do
i=$((i+1))
if ping -c5 ${PING_HOST}; then
log " ...success!"
break
fi
if [ ${i} -ge ${MAX_RETRIES} ]; then
log " ...timed out waiting to ping ${PING_HOST}"
do_reboot
fi
sleep 3
done
DOWNLOAD_URL="${DOMAIN}/${GINSTALL_IMAGE_FILE}"
log "New emergency recovery image will be downloaded from: ${DOWNLOAD_URL}"
i="0"
while [ ${i} -lt ${MAX_RETRIES} ]; do
i=$((i+1))
if ginstall -t "${DOWNLOAD_URL}"; then
log " ...ginstall was successful!"
break
else
if [ ${i} -ge ${MAX_RETRIES} ]; then
log " ...ginstall failed to fetch requested image; giving up."
exit 1
else
log " ...ginstall failed, retrying..."
fi
fi
done