Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: image_to_live.sh

Issue 3389009: Add ability for image_to_live to control most of dev_servers abilities. (Closed) Base URL: http://git.chromium.org/git/crosutils.git
Patch Set: Fix nits Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/bash 1 #!/bin/bash
2 2
3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 3 # Copyright (c) 2009-2010 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 update an image onto a live running ChromiumOS instance. 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 11
12 . "$(dirname $0)/common.sh" 12 . "$(dirname $0)/common.sh"
13 . "$(dirname $0)/remote_access.sh" 13 . "$(dirname $0)/remote_access.sh"
14 14
15 # Flags to control image_to_live.
16 DEFINE_boolean ignore_hostname ${FLAGS_TRUE} \
17 "Ignore existing AU hostname on running instance use this hostname."
15 DEFINE_boolean ignore_version ${FLAGS_TRUE} \ 18 DEFINE_boolean ignore_version ${FLAGS_TRUE} \
16 "Ignore existing version on running instance and always update" 19 "Ignore existing version on running instance and always update."
17 DEFINE_boolean ignore_hostname ${FLAGS_TRUE} \ 20 DEFINE_string server_log "dev_server.log" \
18 "Ignore existing AU hostname on running instance use this hostname" 21 "Path to log for the devserver."
22 DEFINE_boolean update "${FLAGS_TRUE}" \
23 "Perform update of root partition."
19 DEFINE_boolean update_known_hosts ${FLAGS_FALSE} \ 24 DEFINE_boolean update_known_hosts ${FLAGS_FALSE} \
20 "Update your known_hosts with the new remote instance's key" 25 "Update your known_hosts with the new remote instance's key."
21 DEFINE_boolean verbose ${FLAGS_FALSE} \ 26 DEFINE_string update_log "update_engine.log" \
22 "Whether to output verbose information for debugging." 27 "Path to log for the update_engine."
28
29 # Flags for devserver.
30 DEFINE_string archive_dir "" \
31 "Update using the test image in the image.zip in this directory." a
23 DEFINE_integer devserver_port 8080 \ 32 DEFINE_integer devserver_port 8080 \
24 "Port to use for devserver" 33 "Port to use for devserver."
25 DEFINE_string update_url "" "Full url of an update image" 34 DEFINE_string image "" \
35 "Update with this image path that is in this source checkout." i
36 DEFINE_string update_url "" "Full url of an update image."
37
38 # Flags for stateful update.
39 DEFINE_string stateful_update_flag "" \
40 "Flag to pass to stateful update e.g. old, clean, etc." s
26 41
27 UPDATER_BIN='/usr/bin/update_engine_client' 42 UPDATER_BIN='/usr/bin/update_engine_client'
28 UPDATER_IDLE='UPDATE_STATUS_IDLE' 43 UPDATER_IDLE='UPDATE_STATUS_IDLE'
29 UPDATER_NEED_REBOOT='UPDATE_STATUS_UPDATED_NEED_REBOOT' 44 UPDATER_NEED_REBOOT='UPDATE_STATUS_UPDATED_NEED_REBOOT'
45 UPDATER_UPDATE_CHECK='UPDATE_STATUS_CHECKING_FOR_UPDATE'
46 UPDATER_DOWNLOADING='UPDATE_STATUS_DOWNLOADING'
30 47
31 function kill_all_devservers { 48 function kill_all_devservers {
32 # Using ! here to avoid exiting with set -e is insufficient, so use 49 # Using ! here to avoid exiting with set -e is insufficient, so use
33 # || true instead. 50 # || true instead.
34 sudo pkill -f devserver\.py || true 51 sudo pkill -f devserver\.py || true
35 } 52 }
36 53
37 function cleanup { 54 function cleanup {
38 if [ -z "${FLAGS_update_url}" ]; then 55 if [ -z "${FLAGS_update_url}" ]; then
39 kill_all_devservers 56 kill_all_devservers
40 fi 57 fi
41 cleanup_remote_access 58 cleanup_remote_access
42 rm -rf "${TMP}" 59 rm -rf "${TMP}"
43 } 60 }
44 61
45 function remote_reboot_sh { 62 function remote_reboot_sh {
46 rm -f "${TMP_KNOWN_HOSTS}" 63 rm -f "${TMP_KNOWN_HOSTS}"
47 remote_sh "$@" 64 remote_sh "$@"
48 } 65 }
49 66
67 # Reinterprets path from outside the chroot for use inside.
68 # $1 - The path to reinterpret.
69 function reinterpret_path_for_chroot() {
70 local path_abs_path=$(readlink -f "${1}")
71 local gclient_root_abs_path=$(readlink -f "${GCLIENT_ROOT}")
72
73 # Strip the repository root from the path.
74 local relative_path=$(echo ${path_abs_path} \
75 | sed s:${gclient_root_abs_path}/::)
76
77 if [ "${relative_path}" = "${path_abs_path}" ]; then
78 die "Error reinterpreting path. Path ${1} is not within your source tree."
79 fi
80
81 # Prepend the chroot repository path.
82 echo "/home/${USER}/trunk/${relative_path}"
83 }
84
50 function start_dev_server { 85 function start_dev_server {
51 kill_all_devservers 86 kill_all_devservers
52 if [ ${FLAGS_verbose} -eq ${FLAGS_FALSE} ]; then 87 local devserver_flags=${FLAGS_devserver_port}
53 ./enter_chroot.sh "sudo ./start_devserver ${FLAGS_devserver_port} \ 88 # Parse devserver flags.
54 --client_prefix=ChromeOSUpdateEngine > dev_server.log 2>&1" & 89 if [ -n "${FLAGS_image}" ]; then
55 else 90 devserver_flags="${devserver_flags} \
56 ./enter_chroot.sh "sudo ./start_devserver ${FLAGS_devserver_port} \ 91 --image $(reinterpret_path_for_chroot ${FLAGS_image})"
57 --client_prefix=ChromeOSUpdateEngine &" 92 elif [ -n "${FLAGS_archive_dir}" ]; then
93 devserver_flags="${devserver_flags} \
94 --archive_dir $(reinterpret_path_for_chroot ${FLAGS_archive_dir}) -t"
58 fi 95 fi
96
97 info "Starting devserver with flags ${devserver_flags}"
98 ./enter_chroot.sh "sudo ./start_devserver ${devserver_flags} \
99 --client_prefix=ChromeOSUpdateEngine > ${FLAGS_server_log} 2>&1" &
100
59 echo -n "Waiting on devserver to start" 101 echo -n "Waiting on devserver to start"
60 until netstat -anp 2>&1 | grep 0.0.0.0:${FLAGS_devserver_port} > /dev/null 102 until netstat -anp 2>&1 | grep 0.0.0.0:${FLAGS_devserver_port} > /dev/null
61 do 103 do
62 sleep .5 104 sleep .5
63 echo -n "." 105 echo -n "."
64 done 106 done
65 echo "" 107 echo ""
66 } 108 }
67 109
68 # Copys stateful update script which fetches the newest stateful update 110 # Copies stateful update script which fetches the newest stateful update
69 # from the dev server and prepares the update. chromeos_startup finishes 111 # from the dev server and prepares the update. chromeos_startup finishes
70 # the update on next boot. 112 # the update on next boot.
71 function copy_stateful_update { 113 function run_stateful_update {
72 local dev_url=$(get_devserver_url) 114 local dev_url=$(get_devserver_url)
73 local stateful_url="" 115 local stateful_url=""
116 local stateful_update_args=""
117
118 # Parse stateful update flag.
119 if [ -n "${FLAGS_stateful_update_flag}" ]; then
120 stateful_update_args="${stateful_update_args} \
121 --stateful_change ${FLAGS_stateful_update_flag}"
122 fi
74 123
75 # Assume users providing an update url are using an archive_dir path. 124 # Assume users providing an update url are using an archive_dir path.
76 if [ -n "${FLAGS_update_url}" ]; then 125 if [ -n "${FLAGS_update_url}" ]; then
77 stateful_url=$(echo ${dev_url} | sed -e "s/update/static\/archive/") 126 stateful_url=$(echo ${dev_url} | sed -e "s/update/static\/archive/")
78 else 127 else
79 stateful_url=$(echo ${dev_url} | sed -e "s/update/static/") 128 stateful_url=$(echo ${dev_url} | sed -e "s/update/static/")
80 fi 129 fi
81 130
82 info "Starting stateful update using URL ${stateful_url}" 131 info "Starting stateful update using URL ${stateful_url}"
83 132
84 # Copy over update script and run update. 133 # Copy over update script and run update.
85 local dev_dir="$(dirname $0)/../platform/dev" 134 local dev_dir="$(dirname $0)/../platform/dev"
86 remote_cp_to "${dev_dir}/stateful_update" "/tmp" 135 remote_cp_to "${dev_dir}/stateful_update" "/tmp"
87 remote_sh "/tmp/stateful_update ${stateful_url}" 136 remote_sh "/tmp/stateful_update ${stateful_update_args} ${stateful_url}"
88 } 137 }
89 138
90 function get_update_args { 139 function get_update_args {
91 if [ -z ${1} ]; then 140 if [ -z ${1} ]; then
92 die "No url provided for update." 141 die "No url provided for update."
93 fi 142 fi
94 local update_args="--omaha_url ${1}" 143 local update_args="--omaha_url ${1}"
95 if [[ ${FLAGS_ignore_version} -eq ${FLAGS_TRUE} ]]; then 144 if [[ ${FLAGS_ignore_version} -eq ${FLAGS_TRUE} ]]; then
96 info "Forcing update independent of the current version" 145 info "Forcing update independent of the current version"
97 update_args="--update ${update_args}" 146 update_args="--update ${update_args}"
98 fi 147 fi
99 148
100 echo "${update_args}" 149 echo "${update_args}"
101 } 150 }
102 151
103 function get_devserver_url { 152 function get_devserver_url {
104 local devserver_url="" 153 local devserver_url=""
105 if [ ${FLAGS_ignore_hostname} -eq ${FLAGS_TRUE} ]; then 154 if [ ${FLAGS_ignore_hostname} -eq ${FLAGS_TRUE} ]; then
106 if [ -z ${FLAGS_update_url} ]; then 155 if [ -z ${FLAGS_update_url} ]; then
107 devserver_url="http://$HOSTNAME:${FLAGS_devserver_port}/update" 156 devserver_url="http://$HOSTNAME:${FLAGS_devserver_port}/update"
108 else 157 else
109 devserver_url="${FLAGS_update_url}" 158 devserver_url="${FLAGS_update_url}"
110 fi 159 fi
111 fi 160 fi
112 echo "${devserver_url}" 161 echo "${devserver_url}"
113 } 162 }
114 163
115 function get_update_status { 164 function truncate_update_log {
116 remote_sh "${UPDATER_BIN} -status | 165 remote_sh "> /var/log/update_engine.log"
117 grep CURRENT_OP | 166 }
167
168 function get_update_log {
169 remote_sh "cat /var/log/update_engine.log"
170 echo "${REMOTE_OUT}" > "${FLAGS_update_log}"
171 }
172
173
174 # Returns ${1} reported by the update client e.g. PROGRESS, CURRENT_OP.
175 function get_update_var {
176 remote_sh "${UPDATER_BIN} --status 2> /dev/null |
177 grep ${1} |
118 cut -f 2 -d =" 178 cut -f 2 -d ="
119 echo "${REMOTE_OUT}" 179 echo "${REMOTE_OUT}"
120 } 180 }
121 181
182 # Returns the current status / progress of the update engine.
183 # This is expected to run in its own thread.
184 function status_thread {
185 local timeout=5
186 # Let update engine receive call to ping the dev server.
187 info "Devserver handling ping. Check ${FLAGS_server_log} for more info."
188 sleep ${timeout}
189
190 # The devserver generates images when the update engine checks for updates.
191 while [ $(get_update_var CURRENT_OP) = ${UPDATER_UPDATE_CHECK} ]; do
192 echo -n "." && sleep ${timeout}
193 done
194
195 info "Update generated. Update engine downloading update."
196 while [ $(get_update_var CURRENT_OP) = ${UPDATER_DOWNLOADING} ]; do
197 echo "Download progress $(get_update_var PROGRESS)" && sleep ${timeout}
198 done
199
200 info "Download complete."
201 }
202
203
122 function run_auto_update { 204 function run_auto_update {
205 # Truncate the update log so our log file is clean.
206 truncate_update_log
207
123 local update_args="$(get_update_args "$(get_devserver_url)")" 208 local update_args="$(get_update_args "$(get_devserver_url)")"
124 info "Starting update using args ${update_args}" 209 info "Starting update using args ${update_args}"
210
211 # Sets up a secondary thread to track the update progress.
212 status_thread &
213 local status_thread_pid=$!
214 trap "kill ${status_thread_pid} && cleanup" EXIT
215
216 # Actually run the update. This is a blocking call.
125 remote_sh "${UPDATER_BIN} ${update_args}" 217 remote_sh "${UPDATER_BIN} ${update_args}"
126 218
127 local update_status="$(get_update_status)" 219 # Clean up secondary thread.
220 ! kill ${status_thread_pid} 2> /dev/null
221 trap cleanup EXIT
222
223 # We get the log file now.
224 get_update_log
225
226 local update_status="$(get_update_var CURRENT_OP)"
128 if [ "${update_status}" = ${UPDATER_NEED_REBOOT} ]; then 227 if [ "${update_status}" = ${UPDATER_NEED_REBOOT} ]; then
129 info "Autoupdate was successful." 228 info "Autoupdate was successful."
130 return 0 229 return 0
131 else 230 else
132 warn "Autoupdate was unsuccessful. Status returned was ${update_status}." 231 warn "Autoupdate was unsuccessful. Status returned was ${update_status}."
133 return 1 232 return 1
134 fi 233 fi
135 } 234 }
136 235
137 function remote_reboot { 236 function remote_reboot {
(...skipping 30 matching lines...) Expand all
168 eval set -- "${FLAGS_ARGV}" 267 eval set -- "${FLAGS_ARGV}"
169 268
170 set -e 269 set -e
171 270
172 trap cleanup EXIT 271 trap cleanup EXIT
173 272
174 TMP=$(mktemp -d /tmp/image_to_live.XXXX) 273 TMP=$(mktemp -d /tmp/image_to_live.XXXX)
175 274
176 remote_access_init 275 remote_access_init
177 276
178 if [ "$(get_update_status)" = "${UPDATER_NEED_REBOOT}" ]; then 277 if [ "$(get_update_var CURRENT_OP)" != "${UPDATER_IDLE}" ]; then
179 warn "Machine has been updated but not yet rebooted. Rebooting it now." 278 warn "Machine is in a bad state. Rebooting it now."
180 warn "Rerun this script if you still wish to update it."
181 remote_reboot 279 remote_reboot
182 exit 1
183 fi 280 fi
184 281
185 if [ -z "${FLAGS_update_url}" ]; then 282 if [ -z "${FLAGS_update_url}" ]; then
186 # only start local devserver if no update url specified. 283 # Start local devserver if no update url specified.
187 start_dev_server 284 start_dev_server
188 fi 285 fi
189 286
190 if ! run_auto_update; then 287 if [ "${FLAGS_update}" -eq "${FLAGS_TRUE}" ] && ! run_auto_update; then
191 die "Update was not successful." 288 die "Update was not successful."
192 fi 289 fi
193 290
194 if ! copy_stateful_update; then 291 if ! run_stateful_update; then
195 warn "Stateful update was not successful." 292 warn "Stateful update was not successful."
196 fi 293 fi
197 294
198 remote_reboot 295 remote_reboot
199 296
200 if [[ ${FLAGS_update_hostkey} -eq ${FLAGS_TRUE} ]]; then 297 if [[ ${FLAGS_update_hostkey} -eq ${FLAGS_TRUE} ]]; then
201 local known_hosts="${HOME}/.ssh/known_hosts" 298 local known_hosts="${HOME}/.ssh/known_hosts"
202 cp "${known_hosts}" "${known_hosts}~" 299 cp "${known_hosts}" "${known_hosts}~"
203 grep -v "^${FLAGS_remote} " "${known_hosts}" > "${TMP}/new_known_hosts" 300 grep -v "^${FLAGS_remote} " "${known_hosts}" > "${TMP}/new_known_hosts"
204 cat "${TMP}/new_known_hosts" "${TMP_KNOWN_HOSTS}" > "${known_hosts}" 301 cat "${TMP}/new_known_hosts" "${TMP_KNOWN_HOSTS}" > "${known_hosts}"
205 chmod 0640 "${known_hosts}" 302 chmod 0640 "${known_hosts}"
206 info "New updated in ${known_hosts}, backup made." 303 info "New updated in ${known_hosts}, backup made."
207 fi 304 fi
208 305
209 remote_sh "grep ^CHROMEOS_RELEASE_DESCRIPTION= /etc/lsb-release" 306 remote_sh "grep ^CHROMEOS_RELEASE_DESCRIPTION= /etc/lsb-release"
210 local release_description=$(echo ${REMOTE_OUT} | cut -d '=' -f 2) 307 local release_description=$(echo ${REMOTE_OUT} | cut -d '=' -f 2)
211 info "Update was successful and rebooted to $release_description" 308 info "Update was successful and rebooted to $release_description"
212 309
213 return 0 310 return 0
214 } 311 }
215 312
216 main $@ 313 main $@
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698