diff --git a/image_to_live.sh b/image_to_live.sh new file mode 100755 index 0000000000..17c1514656 --- /dev/null +++ b/image_to_live.sh @@ -0,0 +1,204 @@ +#!/bin/bash + +# Copyright (c) 2009 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Script to convert the output of build_image.sh to a usb image. + +# Load common constants. This should be the first executable line. +# The path to common.sh should be relative to your script's location. +. "$(dirname "$0")/common.sh" + +assert_outside_chroot + +cd $(dirname "$0") + +DEFAULT_PRIVATE_KEY="$SRC_ROOT/platform/testing/testing_rsa" + +DEFINE_string ip "" "IP address of running Chromium OS instance" +DEFINE_boolean ignore_version $FLAGS_TRUE \ + "Ignore existing version on running instance and always update" +DEFINE_boolean ignore_hostname $FLAGS_TRUE \ + "Ignore existing AU hostname on running instance use this hostname" +DEFINE_string private_key "$DEFAULT_PRIVATE_KEY" \ + "Private key of root account on instance" + +FLAGS "$@" || exit 1 +eval set -- "${FLAGS_ARGV}" + +set -e + +if [ -z "$FLAGS_ip" ]; then + echo "Please specify the IP of the Chromium OS instance" + exit 1 +fi + +TMP=$(mktemp -d /tmp/image_to_live.XXXX) +TMP_PRIVATE_KEY=$TMP/private_key +TMP_KNOWN_HOSTS=$TMP/known_hosts + +function kill_all_devservers { + ! pkill -f 'python devserver.py' +} + +function cleanup { + kill_all_devservers + rm -rf $TMP +} + +trap cleanup EXIT + +function remote_sh { + # Disable strict host checking so that we don't prompt the user when + # the host key file is removed and just go ahead and add it. + REMOTE_OUT=$(ssh -o StrictHostKeyChecking=no -o \ + UserKnownHostsFile=$TMP_KNOWN_HOSTS root@$FLAGS_ip "$@") + return ${PIPESTATUS[0]} +} + +function remote_reboot_sh { + rm -f $TMP_KNOWN_HOSTS + remote_sh "$@" +} + +function set_up_remote_access { + if [ -z "$SSH_AGENT_PID" ]; then + eval `ssh-agent` + fi + cp $FLAGS_private_key $TMP_PRIVATE_KEY + chmod 0400 $TMP_PRIVATE_KEY + ssh-add $TMP_PRIVATE_KEY + + # Verify the client is reachable before continuing + remote_sh "true" +} + +function start_dev_server { + kill_all_devservers + sudo -v + ./enter_chroot.sh "cd ../platform/dev; ./start-devserver.sh>/dev/null 2>&1" & + echo -n "Waiting on devserver to start" + until netstat -anp 2>&1 | grep 8080 > /dev/null; do + sleep .5 + echo -n "." + done + echo "" +} + +function prepare_update_metadata { + remote_sh "mount -norw,remount /" + + if [ $FLAGS_ignore_version -eq $FLAGS_TRUE ]; then + echo "Forcing update independent of the current version" + remote_sh "cat /etc/lsb-release |\ + grep -v CHROMEOS_RELEASE_VERSION > /etc/lsb-release~;\ + mv /etc/lsb-release~ /etc/lsb-release; \ + echo 'CHROMEOS_RELEASE_VERSION=0.0.0.0' >> /etc/lsb-release" + fi + + if [ $FLAGS_ignore_hostname -eq $FLAGS_TRUE ]; then + echo "Forcing update from $HOSTNAME" + remote_sh "cat /etc/lsb-release |\ + grep -v '^CHROMEOS_AUSERVER=' |\ + grep -v '^CHROMEOS_DEVSERVER=' > /etc/lsb-release~;\ + mv /etc/lsb-release~ /etc/lsb-release; \ + echo 'CHROMEOS_AUSERVER=http://$HOSTNAME:8080/update' >> \ + /etc/lsb-release; \ + echo 'CHROMEOS_DEVSERVER=http://$HOSTNAME:8080' >> /etc/lsb-release" + fi + + remote_sh "mount -noro,remount /" +} + +function run_auto_update { + echo "Starting update and clear away prior" + UPDATE_FILE=/var/log/softwareupdate.log + # Clear it out so we don't see a prior run and make sure it + # exists so the first tail below can't fail if it races the + # memento updater first write and wins. + remote_sh "rm -f $UPDATE_FILE; touch $UPDATE_FILE; \ + /opt/google/memento_updater/memento_updater.sh&/dev/null&" + + local update_error + local output_file + local progress + + update_error=1 + output_file=$TMP/output + + while true; do + # The softwareupdate.log gets pretty bit with download progress + # lines so only look in the last 100 lines for status. + remote_sh "tail -100 $UPDATE_FILE" + echo "$REMOTE_OUT" > $output_file + progress=$(tail -4 $output_file | grep 0K | head -1) + if [ -n "$progress" ]; then + echo "Image fetching progress: $progress" + fi + if grep -q 'updatecheck status="noupdate"' $output_file; then + echo "devserver is claiming there is no update available." + echo "Consider setting --ignore_version." + break + fi + if grep -q 'Autoupdate applied. You should now reboot' $output_file; then + echo "Autoupdate was successful." + update_error=0 + fi + if grep -q 'Memento AutoUpdate terminating' $output_file; then + break + fi + # Sleep for a while so that ssh handling doesn't slow down the install + sleep 2 + done + + return $update_error +} + +function remote_reboot { + echo "Rebooting." + remote_sh "touch /tmp/awaiting_reboot; reboot" + local output_file + output_file=$TMP/output + + while true; do + REMOTE_OUT="" + # This may fail while the machine is done so generate output and a + # boolean result to distinguish between down/timeout and real failure + ! remote_reboot_sh "echo 0; [ -e /tmp/awaiting_reboot ] && echo '1'; true" + echo "$REMOTE_OUT" > $output_file + if grep -q "0" $output_file; then + if grep -q "1" $output_file; then + echo "Not yet rebooted" + else + echo "Rebooted and responding" + break + fi + fi + sleep .5 + done +} + +set_up_remote_access + +if remote_sh [ -e /tmp/memento_autoupdate_completed ]; then + echo "Machine has been updated but not yet rebooted. Rebooting it now." + echo "Rerun this script if you still wish to update it." + remote_reboot + exit 1 +fi + +start_dev_server + +prepare_update_metadata + +if ! run_auto_update; then + echo "Update was not successful." + exit +fi + +remote_reboot + +remote_sh "grep ^CHROMEOS_RELEASE_DESCRIPTION= /etc/lsb-release" +RELEASE_DESCRIPTION=$(echo $REMOTE_OUT | cut -d '=' -f 2) +echo "Update was successful and rebooted to $RELEASE_DESCRIPTION"