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 convert the output of build_image.sh to a usb image. | 7 # Script to update an image onto a live running ChromiumOS instance. |
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" | |
12 | 11 |
13 assert_outside_chroot | 12 . "$(dirname $0)/common.sh" |
| 13 . "$(dirname $0)/remote_access.sh" |
14 | 14 |
15 cd $(dirname "$0") | 15 DEFINE_boolean ignore_version ${FLAGS_TRUE} \ |
16 | |
17 DEFAULT_PRIVATE_KEY="$SRC_ROOT/platform/testing/testing_rsa" | |
18 | |
19 DEFINE_string ip "" "IP address of running Chromium OS instance" | |
20 DEFINE_boolean ignore_version $FLAGS_TRUE \ | |
21 "Ignore existing version on running instance and always update" | 16 "Ignore existing version on running instance and always update" |
22 DEFINE_boolean ignore_hostname $FLAGS_TRUE \ | 17 DEFINE_boolean ignore_hostname ${FLAGS_TRUE} \ |
23 "Ignore existing AU hostname on running instance use this hostname" | 18 "Ignore existing AU hostname on running instance use this hostname" |
24 DEFINE_string private_key "$DEFAULT_PRIVATE_KEY" \ | 19 DEFINE_boolean update_known_hosts ${FLAGS_FALSE} \ |
25 "Private key of root account on instance" | 20 "Update your known_hosts with the new remote instance's key" |
26 | |
27 FLAGS "$@" || exit 1 | |
28 eval set -- "${FLAGS_ARGV}" | |
29 | |
30 set -e | |
31 | |
32 if [ -z "$FLAGS_ip" ]; then | |
33 echo "Please specify the IP of the Chromium OS instance" | |
34 exit 1 | |
35 fi | |
36 | |
37 TMP=$(mktemp -d /tmp/image_to_live.XXXX) | |
38 TMP_PRIVATE_KEY=$TMP/private_key | |
39 TMP_KNOWN_HOSTS=$TMP/known_hosts | |
40 | 21 |
41 function kill_all_devservers { | 22 function kill_all_devservers { |
42 ! pkill -f 'python devserver.py' | 23 ! pkill -f 'python devserver.py' |
43 } | 24 } |
44 | 25 |
45 function cleanup { | 26 function cleanup { |
46 kill_all_devservers | 27 kill_all_devservers |
47 rm -rf $TMP | 28 rm -rf "${TMP}" |
48 } | |
49 | |
50 trap cleanup EXIT | |
51 | |
52 function remote_sh { | |
53 # Disable strict host checking so that we don't prompt the user when | |
54 # the host key file is removed and just go ahead and add it. | |
55 REMOTE_OUT=$(ssh -o StrictHostKeyChecking=no -o \ | |
56 UserKnownHostsFile=$TMP_KNOWN_HOSTS root@$FLAGS_ip "$@") | |
57 return ${PIPESTATUS[0]} | |
58 } | 29 } |
59 | 30 |
60 function remote_reboot_sh { | 31 function remote_reboot_sh { |
61 rm -f $TMP_KNOWN_HOSTS | 32 rm -f "${TMP_KNOWN_HOSTS}" |
62 remote_sh "$@" | 33 remote_sh "$@" |
63 } | 34 } |
64 | 35 |
65 function set_up_remote_access { | |
66 if [ -z "$SSH_AGENT_PID" ]; then | |
67 eval `ssh-agent` | |
68 fi | |
69 cp $FLAGS_private_key $TMP_PRIVATE_KEY | |
70 chmod 0400 $TMP_PRIVATE_KEY | |
71 ssh-add $TMP_PRIVATE_KEY | |
72 | |
73 # Verify the client is reachable before continuing | |
74 remote_sh "true" | |
75 } | |
76 | |
77 function start_dev_server { | 36 function start_dev_server { |
78 kill_all_devservers | 37 kill_all_devservers |
79 sudo -v | 38 sudo -v |
80 ./enter_chroot.sh "cd ../platform/dev; ./start-devserver.sh>/dev/null 2>&1" & | 39 ./enter_chroot.sh "cd ../platform/dev; ./start-devserver.sh>/dev/null 2>&1" & |
81 echo -n "Waiting on devserver to start" | 40 echo -n "Waiting on devserver to start" |
82 until netstat -anp 2>&1 | grep 8080 > /dev/null; do | 41 until netstat -anp 2>&1 | grep 8080 > /dev/null; do |
83 sleep .5 | 42 sleep .5 |
84 echo -n "." | 43 echo -n "." |
85 done | 44 done |
86 echo "" | 45 echo "" |
87 } | 46 } |
88 | 47 |
89 function prepare_update_metadata { | 48 function prepare_update_metadata { |
90 remote_sh "mount -norw,remount /" | 49 remote_sh "mount -norw,remount /" |
91 | 50 |
92 if [ $FLAGS_ignore_version -eq $FLAGS_TRUE ]; then | 51 if [[ ${FLAGS_ignore_version} -eq ${FLAGS_TRUE} ]]; then |
93 echo "Forcing update independent of the current version" | 52 echo "Forcing update independent of the current version" |
94 remote_sh "cat /etc/lsb-release |\ | 53 remote_sh "cat /etc/lsb-release |\ |
95 grep -v CHROMEOS_RELEASE_VERSION > /etc/lsb-release~;\ | 54 grep -v CHROMEOS_RELEASE_VERSION > /etc/lsb-release~;\ |
96 mv /etc/lsb-release~ /etc/lsb-release; \ | 55 mv /etc/lsb-release~ /etc/lsb-release; \ |
97 echo 'CHROMEOS_RELEASE_VERSION=0.0.0.0' >> /etc/lsb-release" | 56 echo 'CHROMEOS_RELEASE_VERSION=0.0.0.0' >> /etc/lsb-release" |
98 fi | 57 fi |
99 | 58 |
100 if [ $FLAGS_ignore_hostname -eq $FLAGS_TRUE ]; then | 59 if [ ${FLAGS_ignore_hostname} -eq ${FLAGS_TRUE} ]; then |
101 echo "Forcing update from $HOSTNAME" | 60 echo "Forcing update from ${HOSTNAME}" |
102 remote_sh "cat /etc/lsb-release |\ | 61 remote_sh "cat /etc/lsb-release |\ |
103 grep -v '^CHROMEOS_AUSERVER=' |\ | 62 grep -v '^CHROMEOS_AUSERVER=' |\ |
104 grep -v '^CHROMEOS_DEVSERVER=' > /etc/lsb-release~;\ | 63 grep -v '^CHROMEOS_DEVSERVER=' > /etc/lsb-release~;\ |
105 mv /etc/lsb-release~ /etc/lsb-release; \ | 64 mv /etc/lsb-release~ /etc/lsb-release; \ |
106 echo 'CHROMEOS_AUSERVER=http://$HOSTNAME:8080/update' >> \ | 65 echo 'CHROMEOS_AUSERVER=http://$HOSTNAME:8080/update' >> \ |
107 /etc/lsb-release; \ | 66 /etc/lsb-release; \ |
108 echo 'CHROMEOS_DEVSERVER=http://$HOSTNAME:8080' >> /etc/lsb-release" | 67 echo 'CHROMEOS_DEVSERVER=http://$HOSTNAME:8080' >> /etc/lsb-release" |
109 fi | 68 fi |
110 | 69 |
111 remote_sh "mount -noro,remount /" | 70 remote_sh "mount -noro,remount /" |
112 } | 71 } |
113 | 72 |
114 function run_auto_update { | 73 function run_auto_update { |
115 echo "Starting update and clear away prior" | 74 echo "Starting update" |
116 UPDATE_FILE=/var/log/softwareupdate.log | 75 local update_file=/var/log/softwareupdate.log |
117 # Clear it out so we don't see a prior run and make sure it | 76 # Clear it out so we don't see a prior run and make sure it |
118 # exists so the first tail below can't fail if it races the | 77 # exists so the first tail below can't fail if it races the |
119 # memento updater first write and wins. | 78 # memento updater first write and wins. |
120 remote_sh "rm -f $UPDATE_FILE; touch $UPDATE_FILE; \ | 79 remote_sh "rm -f ${update_file}; touch ${update_file}; \ |
121 /opt/google/memento_updater/memento_updater.sh</dev/null>&/dev/null&" | 80 /opt/google/memento_updater/memento_updater.sh</dev/null>&/dev/null&" |
122 | 81 |
123 local update_error | 82 local update_error |
124 local output_file | 83 local output_file |
125 local progress | 84 local progress |
126 | 85 |
127 update_error=1 | 86 update_error=1 |
128 output_file=$TMP/output | 87 output_file="${TMP}/output" |
129 | 88 |
130 while true; do | 89 while true; do |
131 # The softwareupdate.log gets pretty bit with download progress | 90 # The softwareupdate.log gets pretty bit with download progress |
132 # lines so only look in the last 100 lines for status. | 91 # lines so only look in the last 100 lines for status. |
133 remote_sh "tail -100 $UPDATE_FILE" | 92 remote_sh "tail -100 ${update_file}" |
134 echo "$REMOTE_OUT" > $output_file | 93 echo "${REMOTE_OUT}" > "${output_file}" |
135 progress=$(tail -4 $output_file | grep 0K | head -1) | 94 progress=$(tail -4 "${output_file}" | grep 0K | head -1) |
136 if [ -n "$progress" ]; then | 95 if [ -n "${progress}" ]; then |
137 echo "Image fetching progress: $progress" | 96 echo "Image fetching progress: ${progress}" |
138 fi | 97 fi |
139 if grep -q 'updatecheck status="noupdate"' $output_file; then | 98 if grep -q 'updatecheck status="noupdate"' "${output_file}"; then |
140 echo "devserver is claiming there is no update available." | 99 echo "devserver is claiming there is no update available." |
141 echo "Consider setting --ignore_version." | 100 echo "Consider setting --ignore_version." |
142 break | 101 break |
143 fi | 102 fi |
144 if grep -q 'Autoupdate applied. You should now reboot' $output_file; then | 103 if grep -q 'Autoupdate applied. You should now reboot' "${output_file}" |
| 104 then |
145 echo "Autoupdate was successful." | 105 echo "Autoupdate was successful." |
146 update_error=0 | 106 update_error=0 |
147 fi | 107 fi |
148 if grep -q 'Memento AutoUpdate terminating' $output_file; then | 108 if grep -q 'Memento AutoUpdate terminating' "${output_file}"; then |
149 break | 109 break |
150 fi | 110 fi |
151 # Sleep for a while so that ssh handling doesn't slow down the install | 111 # Sleep for a while so that ssh handling doesn't slow down the install |
152 sleep 2 | 112 sleep 2 |
153 done | 113 done |
154 | 114 |
155 return $update_error | 115 return ${update_error} |
156 } | 116 } |
157 | 117 |
158 function remote_reboot { | 118 function remote_reboot { |
159 echo "Rebooting." | 119 echo "Rebooting." |
160 remote_sh "touch /tmp/awaiting_reboot; reboot" | 120 remote_sh "touch /tmp/awaiting_reboot; reboot" |
161 local output_file | 121 local output_file |
162 output_file=$TMP/output | 122 output_file="${TMP}/output" |
163 | 123 |
164 while true; do | 124 while true; do |
165 REMOTE_OUT="" | 125 REMOTE_OUT="" |
166 # This may fail while the machine is done so generate output and a | 126 # This may fail while the machine is done so generate output and a |
167 # boolean result to distinguish between down/timeout and real failure | 127 # boolean result to distinguish between down/timeout and real failure |
168 ! remote_reboot_sh "echo 0; [ -e /tmp/awaiting_reboot ] && echo '1'; true" | 128 ! remote_sh_allow_changed_host_key \ |
169 echo "$REMOTE_OUT" > $output_file | 129 "echo 0; [ -e /tmp/awaiting_reboot ] && echo '1'; true" |
170 if grep -q "0" $output_file; then | 130 echo "${REMOTE_OUT}" > "${output_file}" |
171 if grep -q "1" $output_file; then | 131 if grep -q "0" "${output_file}"; then |
| 132 if grep -q "1" "${output_file}"; then |
172 echo "Not yet rebooted" | 133 echo "Not yet rebooted" |
173 else | 134 else |
174 echo "Rebooted and responding" | 135 echo "Rebooted and responding" |
175 break | 136 break |
176 fi | 137 fi |
177 fi | 138 fi |
178 sleep .5 | 139 sleep .5 |
179 done | 140 done |
180 } | 141 } |
181 | 142 |
182 set_up_remote_access | 143 function main() { |
| 144 assert_outside_chroot |
183 | 145 |
184 if remote_sh [ -e /tmp/memento_autoupdate_completed ]; then | 146 cd $(dirname "$0") |
185 echo "Machine has been updated but not yet rebooted. Rebooting it now." | 147 |
186 echo "Rerun this script if you still wish to update it." | 148 FLAGS "$@" || exit 1 |
| 149 eval set -- "${FLAGS_ARGV}" |
| 150 |
| 151 set -e |
| 152 |
| 153 trap cleanup EXIT |
| 154 |
| 155 TMP=$(mktemp -d /tmp/image_to_live.XXXX) |
| 156 |
| 157 remote_access_init |
| 158 |
| 159 if remote_sh [ -e /tmp/memento_autoupdate_completed ]; then |
| 160 echo "Machine has been updated but not yet rebooted. Rebooting it now." |
| 161 echo "Rerun this script if you still wish to update it." |
| 162 remote_reboot |
| 163 exit 1 |
| 164 fi |
| 165 |
| 166 start_dev_server |
| 167 |
| 168 prepare_update_metadata |
| 169 |
| 170 if ! run_auto_update; then |
| 171 echo "Update was not successful." |
| 172 exit |
| 173 fi |
| 174 |
187 remote_reboot | 175 remote_reboot |
188 exit 1 | |
189 fi | |
190 | 176 |
191 start_dev_server | 177 if [[ ${FLAGS_update_hostkey} -eq ${FLAGS_TRUE} ]]; then |
| 178 local known_hosts="${HOME}/.ssh/known_hosts" |
| 179 cp "${known_hosts}" "${known_hosts}~" |
| 180 grep -v "^${FLAGS_remote} " "${known_hosts}" > "${TMP}/new_known_hosts" |
| 181 cat "${TMP}/new_known_hosts" "${TMP_KNOWN_HOSTS}" > "${known_hosts}" |
| 182 chmod 0640 "${known_hosts}" |
| 183 echo "New updated in ${known_hosts}, backup made." |
| 184 fi |
192 | 185 |
193 prepare_update_metadata | 186 remote_sh "grep ^CHROMEOS_RELEASE_DESCRIPTION= /etc/lsb-release" |
| 187 local release_description=$(echo $REMOTE_OUT | cut -d '=' -f 2) |
| 188 echo "Update was successful and rebooted to $release_description" |
| 189 |
| 190 return 0 |
| 191 } |
194 | 192 |
195 if ! run_auto_update; then | 193 main $@ |
196 echo "Update was not successful." | |
197 exit | |
198 fi | |
199 | |
200 remote_reboot | |
201 | |
202 remote_sh "grep ^CHROMEOS_RELEASE_DESCRIPTION= /etc/lsb-release" | |
203 RELEASE_DESCRIPTION=$(echo $REMOTE_OUT | cut -d '=' -f 2) | |
204 echo "Update was successful and rebooted to $RELEASE_DESCRIPTION" | |
OLD | NEW |