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

Side by Side Diff: src/scripts/sync_build_test.sh

Issue 548094: Add a script to simplify some common developer workflows. (Closed)
Patch Set: Created 10 years, 11 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
« 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
(Empty)
1 #!/bin/bash
2
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 # Script to sync your checkout, build a Chromium OS image, and test it all
8 # with one command. Can also check out a new Chromium OS checkout and
9 # perform a subset of the above operations.
10 #
11 # Here are some example runs:
12 #
13 # sync_build_test.sh
14 # syncs, recreates local repo and chroot, builds, and masters an
15 # image in the checkout based on your current directory, or if you
16 # are not in a checkout, based on the top level directory the script
17 # is run from.
18 #
19 # sync_build_test.sh --image_to_usb=/dev/sdb -i
20 # same as above but then images USB device /dev/sdb with the image.
21 # Also prompt the user in advance of the steps we'll take to make
22 # sure they agrees.
23 #
24 # sync_build_test.sh --top=~/foo --nosync --remote 192.168.1.2
25 # builds and masters an image in ~/foo, and live updates the machine
26 # at 192.168.1.2 with that image.
27 #
28 # sync_build_test.sh --top=~/newdir --test "Pam BootPerfServer" \
29 # --remote=192.168.1.2
30 # creates a new checkout in ~/newdir, builds and masters an image
31 # which is live updated to 192.168.1.2 and then runs
32 # two tests (Pam and BootPerfServer) against that machine.
33 #
34 # sync_build_test.sh --grab_buildbot=LATEST --test Pam --remote=192.168.1.2
35 # grabs the latest build from the buildbot, properly modifies it,
36 # reimages 192.168.1.2, and runs the given test on it.
37 #
38 # Environment variables that may be useful:
39 # BUILDBOT_URI - default value for --buildbot_uri
40 # CHROMIUM_REPO - default value for --repo
41 # CHRONOS_PASSWD - default value for --chronos_passwd
42 #
43
44 # Load common constants. This should be the first executable line.
45 # The path to common.sh should be relative to your script's location.
46 . "$(dirname "$0")/common.sh"
47
48
49 DEFINE_string top "" \
50 "Root directory of your checkout (defaults to determining from your cwd)"
51 DEFINE_string repo "${CHROMIUMOS_REPO}" "gclient repo for chromiumos"
52 DEFINE_boolean sync ${FLAGS_TRUE} "Sync the checkout"
53 DEFINE_boolean force_make_local_repo ${FLAGS_FALSE} \
54 "Run make_local_repo indep of sync"
55 DEFINE_boolean force_make_chroot ${FLAGS_FALSE} "Run make_chroot indep of sync"
56 DEFINE_boolean build ${FLAGS_TRUE} \
57 "Build all code (but not necessarily master image)"
58 DEFINE_boolean master ${FLAGS_TRUE} "Master an image from built code"
59 DEFINE_string grab_buildbot "" \
60 "Instead of building, grab this full image.zip URI generated by the \
61 buildbot"
62 DEFINE_string chronos_passwd "${CHRONOS_PASSWD}" \
63 "Use this as the chronos user passwd (defaults to \$CHRONOS_PASSWD)"
64 DEFINE_boolean mod_image_for_test ${FLAGS_FALSE} "Modify the image for testing"
65 DEFINE_boolean image_to_live ${FLAGS_FALSE} \
66 "Put the resulting image on live instance (requires --remote)"
67 DEFINE_string remote "" \
68 "Use this hostname/IP for live updating and running tests"
69 DEFINE_string image_to_usb "" \
70 "Treat this device as USB and put the image on it after build"
71 DEFINE_string test "" \
72 "Test the built image with the given params to run_remote_tests"
73 DEFINE_string buildbot_uri "${BUILDBOT_URI}" \
74 "Base URI to buildbot build location which contains LATEST file"
75 DEFINE_boolean unittest ${FLAGS_TRUE} "Run unit tests"
76 DEFINE_boolean prompt ${FLAGS_FALSE} \
77 "Tell user what we plan to do and wait for input to proceed" i
78
79
80 # Returns a heuristic indicating if we believe this to be a google internal
81 # development environment.
82 # Returns:
83 # 0 if so, 1 otherwise
84 function is_google_environment() {
85 hostname | egrep -q .google.com\$
86 return $?
87 }
88
89
90 # Validates parameters and sets "intelligent" defaults based on other
91 # parameters.
92 function validate_and_set_param_defaults() {
93 if [[ -z "${FLAGS_top}" ]]; then
94 local test_dir=$(pwd)
95 while [[ "${test_dir}" != "/" ]]; do
96 if [[ -d "${test_dir}/src/platform/pam_google" ]]; then
97 FLAGS_top="${test_dir}"
98 break
99 fi
100 test_dir=$(dirname "${test_dir}")
101 done
102 fi
103
104 if [[ -z "${FLAGS_top}" ]]; then
105 # Use the top directory based on where this script runs from
106 FLAGS_top=$(dirname $(dirname $(dirname $0)))
107 fi
108
109 if [[ -z "${FLAGS_repo}" ]]; then
110 if is_google_environment; then
111 FLAGS_repo="ssh://git@chromiumos-git//chromeos"
112 else
113 FLAGS_repo="http://src.chromium.org/git/chromiumos.git"
114 fi
115 fi
116
117 if [[ -n "${FLAGS_test}" ]]; then
118 # If you specify that tests should be run, we assume the image
119 # is modified to run tests.
120 FLAGS_mod_image_for_test=${FLAGS_TRUE}
121 # If you specify that tests should be run, we assume you want
122 # to live update the image.
123 FLAGS_image_to_live=${FLAGS_TRUE}
124 fi
125
126 # If they gave us a remote host, then we assume they want us to do a live
127 # update.
128 if [[ -n "${FLAGS_remote}" ]]; then
129 FLAGS_image_to_live=${FLAGS_TRUE}
130 fi
131
132 # Grabbing a buildbot build is exclusive with building
133 if [[ -n "${FLAGS_grab_buildbot}" ]]; then
134 if [[ -z "${FLAGS_buildbot_uri}" ]]; then
135 echo "--grab_buildbot requires --buildbot_uri"
136 exit 1
137 fi
138 FLAGS_build=${FLAGS_FALSE}
139 FLAGS_master=${FLAGS_FALSE}
140 fi
141
142 if [[ ${FLAGS_image_to_live} -eq ${FLAGS_TRUE} ]]; then
143 if [[ ${FLAGS_mod_image_for_test} -eq ${FLAGS_FALSE} ]]; then
144 echo "WARNING: You have specified to live reimage a machine with"
145 echo "an image that is not modified for test (so it cannot be"
146 echo "later live reimaged)"
147 fi
148 if [[ -n "${FLAGS_image_to_usb}" ]]; then
149 echo "WARNING: You have specified to both live reimage a machine and"
150 echo "write a USB image. Is this what you wanted?"
151 fi
152 if [[ -z "${FLAGS_remote}" ]]; then
153 echo "Please specify --remote with --image_to_live"
154 exit 1
155 fi
156 fi
157
158 if [[ ${FLAGS_mod_image_for_test} -eq ${FLAGS_TRUE} ]]; then
159 # Override any specified chronos password with the test one
160 local test_file=$(dirname $0)"/mod_for_test_scripts/test_account.passwd"
161 FLAGS_chronos_passwd=$(head -1 "${test_file}")
162 fi
163
164 if [[ -n "${FLAGS_image_to_usb}" ]]; then
165 local device=${FLAGS_image_to_usb#/dev/}
166 if [[ -z "${device}" ]]; then
167 echo "Expected --image_to_usb option of /dev/* format"
168 exit 1
169 fi
170 local is_removable=$(cat /sys/block/${device}/removable)
171 if [[ "${is_removable}" != "1" ]]; then
172 echo "Could not verify that ${device} for image_to_usb is removable"
173 exit 1
174 fi
175 fi
176 }
177
178
179 # Prints a description of what we are doing or did
180 function describe_steps() {
181 if [[ ${FLAGS_sync} -eq ${FLAGS_true} ]]; then
182 echo " * Sync client (gclient sync)"
183 if is_google_environment; then
184 echo " * Create proper src/scripts/.chromeos_dev"
185 fi
186 fi
187 if [[ ${FLAGS_force_make_local_repo} -eq ${FLAGS_true} ]]; then
188 echo " * (Re-)create local package repository (make_local_repo.sh)"
189 fi
190 if [[ ${FLAGS_force_make_chroot} -eq ${FLAGS_true} ]]; then
191 echo " * (Re-)create development chroot (make_chroot.sh)"
192 fi
193 local set_passwd=${FLAGS_FALSE}
194 if [[ ${FLAGS_build} -eq ${FLAGS_true} ]]; then
195 echo " * Build image (build_platform_packages.sh, build_kernel.sh)"
196 set_passwd=${FLAGS_TRUE}
197 fi
198 if [[ ${FLAGS_master} -eq ${FLAGS_true} ]]; then
199 echo " * Master image (build_image.sh)"
200 fi
201 if [[ -n "${FLAGS_grab_buildbot}" ]]; then
202 if [[ "${FLAGS_grab_buildbot}" == "LATEST" ]]; then
203 echo " * Grabbing latest buildbot image under ${FLAGS_buildbot_uri}"
204 else
205 echo " * Grabbing buildbot image zip at URI ${FLAGS_grab_buildbot}"
206 fi
207 fi
208 if [[ ${FLAGS_mod_image_for_test} -eq ${FLAGS_TRUE} ]]; then
209 echo " * Make image able to run tests (mod_image_for_test)"
210 set_passwd=${FLAGS_TRUE}
211 fi
212 if [[ ${set_passwd} -eq ${FLAGS_TRUE} ]]; then
213 if [[ -n "${FLAGS_chronos_passwd}" ]]; then
214 echo " * Set chronos password to ${FLAGS_chronos_passwd}"
215 else
216 echo " * Set chronos password randomly"
217 fi
218 fi
219 if [[ -n "${FLAGS_image_to_usb}" ]]; then
220 echo " * Write the image to USB device ${FLAGS_image_to_usb}"
221 fi
222 if [[ ${FLAGS_image_to_live} -eq ${FLAGS_TRUE} ]]; then
223 echo " * Reimage live test Chromium OS instance at ${FLAGS_remote}"
224 fi
225 if [[ -n "${FLAGS_test}" ]]; then
226 echo " * Run tests (${FLAGS_test}) on machine at ${FLAGS_remote}"
227 fi
228 }
229
230
231 # Get user's permission on steps to take
232 function prompt() {
233 echo "Planning these steps on ${FLAGS_top}:"
234 describe_steps
235 read -p "Are you sure (y/N)? " SURE
236 # Get just the first character
237 if [[ "${SURE:0:1}" != "y" ]]; then
238 echo "Ok, better safe than sorry."
239 exit 1
240 fi
241 }
242
243
244 # Runs gclient config on a new checkout directory.
245 function config_new_checkout() {
246 # We only know how to check out to a pattern like ~/foo/chromeos so
247 # make sure that's the pattern the user has given.
248 echo "Checking out ${FLAGS_top}"
249 if [[ $(basename "${FLAGS_top}") != "chromeos" ]]; then
250 echo "The --top directory does not exist and to check it out requires"
251 echo "the name to end in chromeos (try --top=${FLAGS_top}/chromeos)"
252 exit 1
253 fi
254 local top_parent=$(dirname "${FLAGS_top}")
255 mkdir -p "${top_parent}"
256 cd "${top_parent}"
257 gclient config "${FLAGS_repo}"
258 }
259
260
261 # Changes to a directory relative to the top/root directory of
262 # the checkout.
263 # Arguments:
264 # $1 - relative path
265 function chdir_relative() {
266 local dir=$1
267 echo "+ cd ${dir}"
268 # Allow use of .. before the innermost directory of FLAGS_top exists
269 if [[ "${dir}" == ".." ]]; then
270 dir=$(dirname "${FLAGS_top}")
271 else
272 dir="${FLAGS_top}/${dir}"
273 fi
274 cd "${dir}"
275 }
276
277
278 # Describe to the user that a phase is running (and make it obviously when
279 # scrolling through lots of output).
280 # Arguments:
281 # $1 - phase description
282 function describe_phase() {
283 local desc="$1"
284 echo ""
285 echo "#"
286 echo "#"
287 echo "# ${desc}"
288 echo "#"
289 }
290
291
292 # Runs a phase, describing it first, and also updates the sudo timeout
293 # afterwards.
294 # Arguments:
295 # $1 - phase description
296 # $2.. - command/params to run
297 function run_phase() {
298 local desc="$1"
299 shift
300 describe_phase "${desc}"
301 echo "+ $@"
302 "$@"
303 sudo -v
304 }
305
306
307 # Runs gclient sync, setting up .chromeos_dev and preparing for
308 # local repo setup
309 function sync() {
310 # cd to the directory below
311 chdir_relative ..
312 run_phase "Synchronizing client" gclient sync
313 chdir_relative .
314 git cl config "file://$(pwd)/codereview.settings"
315 if is_google_environment; then
316 local base_dir=$(dirname $(dirname "${FLAGS_top}"))
317 echo <<EOF > src/scripts/.chromeos_dev
318 # Use internal chromeos-deb repository
319 CHROMEOS_EXT_MIRROR="http://chromeos-deb/ubuntu"
320 CHROMEOS_EXT_SUITE="karmic"
321
322 # Assume Chrome is checked out nearby
323 CHROMEOS_CHROME_DIR="${base_dir}/chrome"
324 EOF
325 fi
326 }
327
328
329 # Downloads a buildbot image
330 function grab_buildbot() {
331 if [[ "${FLAGS_grab_buildbot}" == "LATEST" ]]; then
332 local latest=$(curl "${FLAGS_buildbot_uri}/LATEST")
333 if [[ -z "${latest}" ]]; then
334 echo "Error finding latest."
335 exit 1
336 fi
337 FLAGS_grab_buildbot="${FLAGS_buildbot_uri}/${latest}/image.zip"
338 fi
339 local dl_dir=$(mktemp -d "/tmp/image.XXXX")
340 echo "Grabbing image from ${FLAGS_grab_buildbot} to ${dl_dir}"
341 run_phase "Downloading image" curl "${FLAGS_grab_buildbot}" \
342 -o "${dl_dir}/image.zip"
343 cd "${dl_dir}"
344 unzip image.zip
345 echo "Copying in local_repo/local_packages"
346 # TODO(kmixter): Make this architecture indep once buildbot is.
347 mv -f local_repo/local_packages/* "${FLAGS_top}/src/build/x86/local_packages"
348 local image_basename=$(basename $(dirname "${FLAGS_grab_buildbot}"))
349 local image_dir="${FLAGS_top}/src/build/images/${image_basename}"
350 echo "Copying in build image to ${image_dir}"
351 rm -rf "${image_dir}"
352 mkdir -p "${image_dir}"
353 # Note that if mbr.image does not exist, this image was not successful.
354 mv mbr.image rootfs.image "${image_dir}"
355 chdir_relative .
356 run_phase "Removing downloaded image" rm -rf "${dl_dir}"
357 }
358
359
360 function main() {
361 assert_outside_chroot
362 assert_not_root_user
363
364 # Parse command line
365 FLAGS "$@" || exit 1
366 eval set -- "${FLAGS_ARGV}"
367
368 # Die on any errors.
369 set -e
370
371 validate_and_set_param_defaults
372
373 # Cache up sudo status
374 sudo -v
375
376 if [[ ${FLAGS_prompt} -eq ${FLAGS_TRUE} ]]; then
377 prompt
378 fi
379
380 if [[ ! -e "${FLAGS_top}" ]]; then
381 config_new_checkout
382 fi
383
384 if [[ ${FLAGS_sync} -eq ${FLAGS_TRUE} ]]; then
385 sync
386 # The package repository is now potentially out of date, so
387 # reflect that.
388 run_phase "Removing existing package repo" sudo rm -rf repo
389 FLAGS_force_make_local_repo=${FLAGS_TRUE}
390 FLAGS_force_make_chroot=${FLAGS_TRUE}
391 fi
392
393 if [[ -n "${FLAGS_grab_buildbot}" ]]; then
394 grab_buildbot
395 fi
396
397 if [[ ${FLAGS_force_make_local_repo} -eq ${FLAGS_TRUE} ]]; then
398 chdir_relative src/scripts
399 run_phase "Refetching local repo" ./make_local_repo.sh
400 fi
401
402 if [[ ${FLAGS_force_make_chroot} -eq ${FLAGS_TRUE} ]]; then
403 chdir_relative src/scripts
404 run_phase "Replacing chroot" ./make_chroot.sh --replace
405 fi
406
407 if [[ ${FLAGS_build} -eq ${FLAGS_TRUE} ]]; then
408 chdir_relative src/scripts
409 run_phase "Building platform packages and kernel" ./enter_chroot.sh \
410 "./build_platform_packages.sh && ./build_kernel.sh"
411
412 if [[ ${FLAGS_build} -eq ${FLAGS_TRUE} ]]; then
413 run_phase "Building and running unit tests" ./enter_chroot.sh \
414 "./build_tests.sh && ./run_tests.sh"
415 fi
416 fi
417
418 if [[ ${FLAGS_master} -eq ${FLAGS_TRUE} ]]; then
419 chdir_relative src/scripts
420 if [[ -n "${FLAGS_chronos_passwd}" ]]; then
421 describe_phase "Setting default chronos password"
422 ./enter_chroot.sh "echo '${FLAGS_chronos_passwd}' | \
423 ./set_shared_user_password.sh"
424 fi
425 run_phase "Mastering image" ./enter_chroot.sh "./build_image.sh --replace"
426 fi
427
428 if [[ ${FLAGS_mod_image_for_test} -eq ${FLAGS_TRUE} ]]; then
429 chdir_relative src/scripts
430 run_phase "Modifying image for test" ./enter_chroot.sh \
431 "./mod_image_for_test.sh"
432 fi
433
434 if [[ -n "${FLAGS_image_to_usb}" ]]; then
435 chdir_relative src/scripts
436 run_phase "Installing image to USB" \
437 ./image_to_usb.sh --yes "--to=${FLAGS_image_to_usb}"
438 fi
439
440 if [[ ${FLAGS_image_to_live} -eq ${FLAGS_TRUE} ]]; then
441 chdir_relative src/scripts
442 run_phase "Re-imaging live Chromium OS machine ${FLAGS_remote}" \
443 ./image_to_live.sh "--remote=${FLAGS_remote}" --update_known_hosts
444 fi
445
446 if [[ -n "${FLAGS_test}" ]]; then
447 chdir_relative src/scripts
448 # We purposefully do not quote FLAGS_test below as we expect it may
449 # have multiple parameters
450 run_phase "Running tests on Chromium OS machine ${FLAGS_remote}" \
451 ./run_remote_tests.sh --remote="${FLAGS_remote}" ${FLAGS_test}
452 fi
453
454 echo "Successfully used ${FLAGS_top} to:"
455 describe_steps
456 }
457
458
459 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