blob: 150c7de09af9a068fda4717d9caa345c9a0e18cb [file] [log] [blame]
Zhizhou Yang5534af82020-01-15 16:25:04 -08001#!/usr/bin/env python3
Manoj Gupta1d1de432019-04-26 11:30:14 -07002# -*- coding: utf-8 -*-
Ahmad Sharif70de27b2011-06-15 17:51:24 -07003#
George Burgess IV2124be52022-04-21 10:27:37 -07004# Copyright 2019 The ChromiumOS Authors. All rights reserved.
Manoj Gupta1d1de432019-04-26 11:30:14 -07005# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
Ahmad Sharif70de27b2011-06-15 17:51:24 -07008"""Script to image a ChromeOS device.
9
10This script images a remote ChromeOS device with a specific image."
11"""
12
Caroline Tice88272d42016-01-13 09:48:29 -080013from __future__ import print_function
14
George Burgess IV74bd3802022-09-02 16:59:27 -070015
16__author__ = "asharif@google.com (Ahmad Sharif)"
Ahmad Sharif70de27b2011-06-15 17:51:24 -070017
Caroline Tice88272d42016-01-13 09:48:29 -080018import argparse
Ahmad Sharif70de27b2011-06-15 17:51:24 -070019import filecmp
Caroline Ticed0f7a732018-03-02 16:31:17 -080020import getpass
Ahmad Sharif70de27b2011-06-15 17:51:24 -070021import glob
Ahmad Sharif70de27b2011-06-15 17:51:24 -070022import os
Ahmad Shariff395c262012-10-09 17:48:09 -070023import re
Ahmad Sharif70de27b2011-06-15 17:51:24 -070024import shutil
25import sys
26import tempfile
Ahmad Sharif4467f002012-12-20 12:09:49 -080027import time
28
Caroline Tice88272d42016-01-13 09:48:29 -080029from cros_utils import command_executer
30from cros_utils import locks
31from cros_utils import logger
32from cros_utils import misc
33from cros_utils.file_utils import FileUtils
Ahmad Sharif70de27b2011-06-15 17:51:24 -070034
George Burgess IV74bd3802022-09-02 16:59:27 -070035
36checksum_file = "/usr/local/osimage_checksum_file"
37lock_file = "/tmp/image_chromeos_lock/image_chromeos_lock"
Luis Lozanof2a3ef42015-12-15 13:49:30 -080038
Ahmad Sharif70de27b2011-06-15 17:51:24 -070039
40def Usage(parser, message):
George Burgess IV74bd3802022-09-02 16:59:27 -070041 print("ERROR: %s" % message)
42 parser.print_help()
43 sys.exit(0)
Ahmad Sharif70de27b2011-06-15 17:51:24 -070044
Ahmad Shariff395c262012-10-09 17:48:09 -070045
cmtice13909242014-03-11 13:38:07 -070046def CheckForCrosFlash(chromeos_root, remote, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -070047 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
cmtice0cc4e772014-01-30 15:52:37 -080048
George Burgess IV74bd3802022-09-02 16:59:27 -070049 # Check to see if remote machine has cherrypy, ctypes
50 command = "python -c 'import cherrypy, ctypes'"
51 ret = cmd_executer.CrosRunCommand(
52 command, chromeos_root=chromeos_root, machine=remote
53 )
54 logger.GetLogger().LogFatalIf(
55 ret == 255, "Failed ssh to %s (for checking cherrypy)" % remote
56 )
57 logger.GetLogger().LogFatalIf(
58 ret != 0,
59 "Failed to find cherrypy or ctypes on remote '{}', "
60 "cros flash cannot work.".format(remote),
61 )
Luis Lozano54db5382015-05-20 15:57:19 -070062
cmtice0cc4e772014-01-30 15:52:37 -080063
Manoj Gupta1282e842017-05-17 12:57:56 -070064def DisableCrosBeeps(chromeos_root, remote, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -070065 """Disable annoying chromebooks beeps after reboots."""
66 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
Manoj Gupta1282e842017-05-17 12:57:56 -070067
George Burgess IV74bd3802022-09-02 16:59:27 -070068 command = "/usr/share/vboot/bin/set_gbb_flags.sh 0x1"
69 logger.GetLogger().LogOutput("Trying to disable beeping.")
Manoj Gupta1282e842017-05-17 12:57:56 -070070
George Burgess IV74bd3802022-09-02 16:59:27 -070071 ret, o, _ = cmd_executer.CrosRunCommandWOutput(
72 command, chromeos_root=chromeos_root, machine=remote
73 )
74 if ret != 0:
75 logger.GetLogger().LogOutput(o)
76 logger.GetLogger().LogOutput("Failed to disable beeps.")
Manoj Gupta1282e842017-05-17 12:57:56 -070077
78
Caroline Ticed0f7a732018-03-02 16:31:17 -080079def FindChromeOSImage(image_file, chromeos_root):
George Burgess IV74bd3802022-09-02 16:59:27 -070080 """Find path for ChromeOS image inside chroot.
Caroline Ticed0f7a732018-03-02 16:31:17 -080081
George Burgess IV74bd3802022-09-02 16:59:27 -070082 This function could be called with image paths that are either inside
83 or outside the chroot. In either case the path needs to be translated
84 to an real/absolute path inside the chroot.
85 Example input paths:
86 /usr/local/google/home/uname/chromeos/chroot/tmp/my-test-images/image
87 ~/trunk/src/build/images/board/latest/image
88 /tmp/peppy-release/R67-1235.0.0/image
Caroline Ticed0f7a732018-03-02 16:31:17 -080089
George Burgess IV74bd3802022-09-02 16:59:27 -070090 Corresponding example output paths:
91 /tmp/my-test-images/image
92 /home/uname/trunk/src/build/images/board/latest/image
93 /tmp/peppy-release/R67-1235.0,0/image
94 """
Caroline Ticed0f7a732018-03-02 16:31:17 -080095
George Burgess IV74bd3802022-09-02 16:59:27 -070096 # Get the name of the user, for "/home/<user>" part of the path.
97 whoami = getpass.getuser()
98 # Get the full path for the chroot dir, including 'chroot'
99 real_chroot_dir = os.path.join(os.path.realpath(chromeos_root), "chroot")
100 # Get the full path for the chromeos root, excluding 'chroot'
101 real_chromeos_root = os.path.realpath(chromeos_root)
Caroline Ticed0f7a732018-03-02 16:31:17 -0800102
George Burgess IV74bd3802022-09-02 16:59:27 -0700103 # If path name starts with real_chroot_dir, remove that piece, but assume
104 # the rest of the path is correct.
105 if image_file.find(real_chroot_dir) != -1:
106 chroot_image = image_file[len(real_chroot_dir) :]
107 # If path name starts with chromeos_root, excluding 'chroot', replace the
108 # chromeos_root with the prefix: '/home/<username>/trunk'.
109 elif image_file.find(real_chromeos_root) != -1:
110 chroot_image = image_file[len(real_chromeos_root) :]
111 chroot_image = "/home/%s/trunk%s" % (whoami, chroot_image)
112 # Else assume the path is already internal, so leave it alone.
113 else:
114 chroot_image = image_file
Caroline Ticed0f7a732018-03-02 16:31:17 -0800115
George Burgess IV74bd3802022-09-02 16:59:27 -0700116 return chroot_image
Caroline Ticed0f7a732018-03-02 16:31:17 -0800117
118
Ahmad Sharif4467f002012-12-20 12:09:49 -0800119def DoImage(argv):
George Burgess IV74bd3802022-09-02 16:59:27 -0700120 """Image ChromeOS."""
Ahmad Sharif4467f002012-12-20 12:09:49 -0800121
George Burgess IV74bd3802022-09-02 16:59:27 -0700122 parser = argparse.ArgumentParser()
123 parser.add_argument(
124 "-c",
125 "--chromeos_root",
126 dest="chromeos_root",
127 help="Target directory for ChromeOS installation.",
128 )
129 parser.add_argument("-r", "--remote", dest="remote", help="Target device.")
130 parser.add_argument(
131 "-i", "--image", dest="image", help="Image binary file."
132 )
133 parser.add_argument(
134 "-b", "--board", dest="board", help="Target board override."
135 )
136 parser.add_argument(
137 "-f",
138 "--force",
139 dest="force",
140 action="store_true",
141 default=False,
142 help="Force an image even if it is non-test.",
143 )
144 parser.add_argument(
145 "-n",
146 "--no_lock",
147 dest="no_lock",
148 default=False,
149 action="store_true",
150 help="Do not attempt to lock remote before imaging. "
151 "This option should only be used in cases where the "
152 "exclusive lock has already been acquired (e.g. in "
153 "a script that calls this one).",
154 )
155 parser.add_argument(
156 "-l",
157 "--logging_level",
158 dest="log_level",
159 default="verbose",
160 help="Amount of logging to be used. Valid levels are "
161 "'quiet', 'average', and 'verbose'.",
162 )
163 parser.add_argument("-a", "--image_args", dest="image_args")
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700164
George Burgess IV74bd3802022-09-02 16:59:27 -0700165 options = parser.parse_args(argv[1:])
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700166
George Burgess IV74bd3802022-09-02 16:59:27 -0700167 if not options.log_level in command_executer.LOG_LEVEL:
168 Usage(parser, "--logging_level must be 'quiet', 'average' or 'verbose'")
cmtice0cc4e772014-01-30 15:52:37 -0800169 else:
George Burgess IV74bd3802022-09-02 16:59:27 -0700170 log_level = options.log_level
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700171
George Burgess IV74bd3802022-09-02 16:59:27 -0700172 # Common initializations
173 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
174 l = logger.GetLogger()
cmticeb1340082014-01-13 13:22:37 -0800175
George Burgess IV74bd3802022-09-02 16:59:27 -0700176 if options.chromeos_root is None:
177 Usage(parser, "--chromeos_root must be set")
cmticee5bc63b2015-05-27 16:59:37 -0700178
George Burgess IV74bd3802022-09-02 16:59:27 -0700179 if options.remote is None:
180 Usage(parser, "--remote must be set")
Manoj Gupta1282e842017-05-17 12:57:56 -0700181
George Burgess IV74bd3802022-09-02 16:59:27 -0700182 options.chromeos_root = os.path.expanduser(options.chromeos_root)
cmticee5bc63b2015-05-27 16:59:37 -0700183
George Burgess IV74bd3802022-09-02 16:59:27 -0700184 if options.board is None:
185 board = cmd_executer.CrosLearnBoard(
186 options.chromeos_root, options.remote
187 )
cmticee5bc63b2015-05-27 16:59:37 -0700188 else:
George Burgess IV74bd3802022-09-02 16:59:27 -0700189 board = options.board
Manoj Gupta1d1de432019-04-26 11:30:14 -0700190
George Burgess IV74bd3802022-09-02 16:59:27 -0700191 if options.image is None:
192 images_dir = misc.GetImageDir(options.chromeos_root, board)
193 image = os.path.join(images_dir, "latest", "chromiumos_test_image.bin")
194 if not os.path.exists(image):
195 image = os.path.join(images_dir, "latest", "chromiumos_image.bin")
196 is_xbuddy_image = False
197 else:
198 image = options.image
199 is_xbuddy_image = image.startswith("xbuddy://")
200 if not is_xbuddy_image:
201 image = os.path.expanduser(image)
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700202
George Burgess IV74bd3802022-09-02 16:59:27 -0700203 if not is_xbuddy_image:
204 image = os.path.realpath(image)
205
206 if not os.path.exists(image) and not is_xbuddy_image:
207 Usage(parser, "Image file: " + image + " does not exist!")
208
209 try:
210 should_unlock = False
211 if not options.no_lock:
212 try:
213 _ = locks.AcquireLock(
214 list(options.remote.split()), options.chromeos_root
215 )
216 should_unlock = True
217 except Exception as e:
218 raise RuntimeError("Error acquiring machine: %s" % str(e))
219
220 reimage = False
221 local_image = False
222 if not is_xbuddy_image:
223 local_image = True
224 image_checksum = FileUtils().Md5File(image, log_level=log_level)
225
226 command = "cat " + checksum_file
227 ret, device_checksum, _ = cmd_executer.CrosRunCommandWOutput(
228 command,
229 chromeos_root=options.chromeos_root,
230 machine=options.remote,
231 )
232
233 device_checksum = device_checksum.strip()
234 image_checksum = str(image_checksum)
235
236 l.LogOutput("Image checksum: " + image_checksum)
237 l.LogOutput("Device checksum: " + device_checksum)
238
239 if image_checksum != device_checksum:
240 [found, located_image] = LocateOrCopyImage(
241 options.chromeos_root, image, board=board
242 )
243
244 reimage = True
245 l.LogOutput("Checksums do not match. Re-imaging...")
246
247 chroot_image = FindChromeOSImage(
248 located_image, options.chromeos_root
249 )
250
251 is_test_image = IsImageModdedForTest(
252 options.chromeos_root, chroot_image, log_level
253 )
254
255 if not is_test_image and not options.force:
256 logger.GetLogger().LogFatal(
257 "Have to pass --force to image a " "non-test image!"
258 )
259 else:
260 reimage = True
261 found = True
262 l.LogOutput("Using non-local image; Re-imaging...")
263
264 if reimage:
265 # If the device has /tmp mounted as noexec, image_to_live.sh can fail.
266 command = "mount -o remount,rw,exec /tmp"
267 cmd_executer.CrosRunCommand(
268 command,
269 chromeos_root=options.chromeos_root,
270 machine=options.remote,
271 )
272
273 # Check to see if cros flash will work for the remote machine.
274 CheckForCrosFlash(options.chromeos_root, options.remote, log_level)
275
276 # Disable the annoying chromebook beeps after reboot.
277 DisableCrosBeeps(options.chromeos_root, options.remote, log_level)
278
279 cros_flash_args = [
280 "cros",
281 "flash",
282 "--board=%s" % board,
283 "--clobber-stateful",
284 options.remote,
285 ]
286 if local_image:
287 cros_flash_args.append(chroot_image)
288 else:
289 cros_flash_args.append(image)
290
291 command = " ".join(cros_flash_args)
292
293 # Workaround for crosbug.com/35684.
294 os.chmod(misc.GetChromeOSKeyFile(options.chromeos_root), 0o600)
295
296 if log_level == "average":
297 cmd_executer.SetLogLevel("verbose")
298 retries = 0
299 while True:
300 if log_level == "quiet":
301 l.LogOutput("CMD : %s" % command)
302 ret = cmd_executer.ChrootRunCommand(
303 options.chromeos_root, command, command_timeout=1800
304 )
305 if ret == 0 or retries >= 2:
306 break
307 retries += 1
308 if log_level == "quiet":
309 l.LogOutput("Imaging failed. Retry # %d." % retries)
310
311 if log_level == "average":
312 cmd_executer.SetLogLevel(log_level)
313
314 logger.GetLogger().LogFatalIf(ret, "Image command failed")
315
316 # Unfortunately cros_image_to_target.py sometimes returns early when the
317 # machine isn't fully up yet.
318 ret = EnsureMachineUp(
319 options.chromeos_root, options.remote, log_level
320 )
321
322 # If this is a non-local image, then the ret returned from
323 # EnsureMachineUp is the one that will be returned by this function;
324 # in that case, make sure the value in 'ret' is appropriate.
325 if not local_image and ret:
326 ret = 0
327 else:
328 ret = 1
329
330 if local_image:
331 if log_level == "average":
332 l.LogOutput("Verifying image.")
333 command = "echo %s > %s && chmod -w %s" % (
334 image_checksum,
335 checksum_file,
336 checksum_file,
337 )
338 ret = cmd_executer.CrosRunCommand(
339 command,
340 chromeos_root=options.chromeos_root,
341 machine=options.remote,
342 )
343 logger.GetLogger().LogFatalIf(ret, "Writing checksum failed.")
344
345 successfully_imaged = VerifyChromeChecksum(
346 options.chromeos_root,
347 chroot_image,
348 options.remote,
349 log_level,
350 )
351 logger.GetLogger().LogFatalIf(
352 not successfully_imaged, "Image verification failed!"
353 )
354 TryRemountPartitionAsRW(
355 options.chromeos_root, options.remote, log_level
356 )
357
358 if not found:
359 temp_dir = os.path.dirname(located_image)
360 l.LogOutput("Deleting temp image dir: %s" % temp_dir)
361 shutil.rmtree(temp_dir)
362 l.LogOutput("Image updated.")
363 else:
364 l.LogOutput("Checksums match, skip image update and reboot.")
365 command = "reboot && exit"
366 _ = cmd_executer.CrosRunCommand(
367 command,
368 chromeos_root=options.chromeos_root,
369 machine=options.remote,
370 )
371 # Wait 30s after reboot.
372 time.sleep(30)
373
374 finally:
375 if should_unlock:
376 locks.ReleaseLock(
377 list(options.remote.split()), options.chromeos_root
378 )
379
380 return ret
Denis Nikitin144f6992019-07-20 20:25:16 -0700381
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700382
383def LocateOrCopyImage(chromeos_root, image, board=None):
George Burgess IV74bd3802022-09-02 16:59:27 -0700384 l = logger.GetLogger()
385 if board is None:
386 board_glob = "*"
387 else:
388 board_glob = board
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700389
George Burgess IV74bd3802022-09-02 16:59:27 -0700390 chromeos_root_realpath = os.path.realpath(chromeos_root)
391 image = os.path.realpath(image)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800392
George Burgess IV74bd3802022-09-02 16:59:27 -0700393 if image.startswith("%s/" % chromeos_root_realpath):
394 return [True, image]
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700395
George Burgess IV74bd3802022-09-02 16:59:27 -0700396 # First search within the existing build dirs for any matching files.
397 images_glob = "%s/src/build/images/%s/*/*.bin" % (
398 chromeos_root_realpath,
399 board_glob,
400 )
401 images_list = glob.glob(images_glob)
402 for potential_image in images_list:
403 if filecmp.cmp(potential_image, image):
404 l.LogOutput(
405 "Found matching image %s in chromeos_root." % potential_image
406 )
407 return [True, potential_image]
408 # We did not find an image. Copy it in the src dir and return the copied
409 # file.
410 if board is None:
411 board = ""
412 base_dir = "%s/src/build/images/%s" % (chromeos_root_realpath, board)
413 if not os.path.isdir(base_dir):
414 os.makedirs(base_dir)
415 temp_dir = tempfile.mkdtemp(prefix="%s/tmp" % base_dir)
416 new_image = "%s/%s" % (temp_dir, os.path.basename(image))
417 l.LogOutput(
418 "No matching image found. Copying %s to %s" % (image, new_image)
419 )
420 shutil.copyfile(image, new_image)
421 return [False, new_image]
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700422
423
Manoj Gupta1d1de432019-04-26 11:30:14 -0700424def GetImageMountCommand(image, rootfs_mp, stateful_mp):
George Burgess IV74bd3802022-09-02 16:59:27 -0700425 image_dir = os.path.dirname(image)
426 image_file = os.path.basename(image)
427 mount_command = (
428 "cd /mnt/host/source/src/scripts &&"
429 "./mount_gpt_image.sh --from=%s --image=%s"
430 " --safe --read_only"
431 " --rootfs_mountpt=%s"
432 " --stateful_mountpt=%s"
433 % (image_dir, image_file, rootfs_mp, stateful_mp)
434 )
435 return mount_command
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700436
437
George Burgess IV74bd3802022-09-02 16:59:27 -0700438def MountImage(
439 chromeos_root,
440 image,
441 rootfs_mp,
442 stateful_mp,
443 log_level,
444 unmount=False,
445 extra_commands="",
446):
447 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
448 command = GetImageMountCommand(image, rootfs_mp, stateful_mp)
449 if unmount:
450 command = "%s --unmount" % command
451 if extra_commands:
452 command = "%s ; %s" % (command, extra_commands)
453 ret, out, _ = cmd_executer.ChrootRunCommandWOutput(chromeos_root, command)
454 logger.GetLogger().LogFatalIf(ret, "Mount/unmount command failed!")
455 return out
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700456
457
cmtice13909242014-03-11 13:38:07 -0700458def IsImageModdedForTest(chromeos_root, image, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -0700459 if log_level != "verbose":
460 log_level = "quiet"
461 command = "mktemp -d"
462 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
463 _, rootfs_mp, _ = cmd_executer.ChrootRunCommandWOutput(
464 chromeos_root, command
465 )
466 _, stateful_mp, _ = cmd_executer.ChrootRunCommandWOutput(
467 chromeos_root, command
468 )
469 rootfs_mp = rootfs_mp.strip()
470 stateful_mp = stateful_mp.strip()
471 lsb_release_file = os.path.join(rootfs_mp, "etc/lsb-release")
472 extra = "grep CHROMEOS_RELEASE_TRACK %s | grep -i test" % lsb_release_file
473 output = MountImage(
474 chromeos_root,
475 image,
476 rootfs_mp,
477 stateful_mp,
478 log_level,
479 extra_commands=extra,
480 )
481 is_test_image = re.search("test", output, re.IGNORECASE)
482 MountImage(
483 chromeos_root, image, rootfs_mp, stateful_mp, log_level, unmount=True
484 )
485 return is_test_image
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700486
487
cmtice13909242014-03-11 13:38:07 -0700488def VerifyChromeChecksum(chromeos_root, image, remote, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -0700489 command = "mktemp -d"
490 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
491 _, rootfs_mp, _ = cmd_executer.ChrootRunCommandWOutput(
492 chromeos_root, command
493 )
494 _, stateful_mp, _ = cmd_executer.ChrootRunCommandWOutput(
495 chromeos_root, command
496 )
497 rootfs_mp = rootfs_mp.strip()
498 stateful_mp = stateful_mp.strip()
499 chrome_file = "%s/opt/google/chrome/chrome" % rootfs_mp
500 extra = "md5sum %s" % chrome_file
501 out = MountImage(
502 chromeos_root,
503 image,
504 rootfs_mp,
505 stateful_mp,
506 log_level,
507 extra_commands=extra,
508 )
509 image_chrome_checksum = out.strip().split()[0]
510 MountImage(
511 chromeos_root, image, rootfs_mp, stateful_mp, log_level, unmount=True
512 )
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700513
George Burgess IV74bd3802022-09-02 16:59:27 -0700514 command = "md5sum /opt/google/chrome/chrome"
515 [_, o, _] = cmd_executer.CrosRunCommandWOutput(
516 command, chromeos_root=chromeos_root, machine=remote
517 )
518 device_chrome_checksum = o.split()[0]
519 return image_chrome_checksum.strip() == device_chrome_checksum.strip()
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700520
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800521
Luis Lozanof81680c2013-03-15 14:44:13 -0700522# Remount partition as writable.
523# TODO: auto-detect if an image is built using --noenable_rootfs_verification.
cmtice13909242014-03-11 13:38:07 -0700524def TryRemountPartitionAsRW(chromeos_root, remote, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -0700525 l = logger.GetLogger()
526 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
527 command = "sudo mount -o remount,rw /"
528 ret = cmd_executer.CrosRunCommand(
529 command,
530 chromeos_root=chromeos_root,
531 machine=remote,
532 terminated_timeout=10,
533 )
534 if ret:
535 ## Safely ignore.
536 l.LogWarning(
537 "Failed to remount partition as rw, "
538 "probably the image was not built with "
539 '"--noenable_rootfs_verification", '
540 "you can safely ignore this."
541 )
542 else:
543 l.LogOutput("Re-mounted partition as writable.")
Luis Lozanof81680c2013-03-15 14:44:13 -0700544
Ahmad Sharif70de27b2011-06-15 17:51:24 -0700545
cmtice13909242014-03-11 13:38:07 -0700546def EnsureMachineUp(chromeos_root, remote, log_level):
George Burgess IV74bd3802022-09-02 16:59:27 -0700547 l = logger.GetLogger()
548 cmd_executer = command_executer.GetCommandExecuter(log_level=log_level)
549 timeout = 600
550 magic = "abcdefghijklmnopqrstuvwxyz"
551 command = "echo %s" % magic
552 start_time = time.time()
553 while True:
554 current_time = time.time()
555 if current_time - start_time > timeout:
556 l.LogError(
557 "Timeout of %ss reached. Machine still not up. Aborting."
558 % timeout
559 )
560 return False
561 ret = cmd_executer.CrosRunCommand(
562 command, chromeos_root=chromeos_root, machine=remote
563 )
564 if not ret:
565 return True
Ahmad Sharif4467f002012-12-20 12:09:49 -0800566
567
George Burgess IV74bd3802022-09-02 16:59:27 -0700568if __name__ == "__main__":
569 retval = DoImage(sys.argv)
570 sys.exit(retval)