blob: 088838600a58f5e8c35216a46ef35d13b5c0e0fc [file] [log] [blame]
asharif4d2b7162013-02-15 05:14:57 +00001#!/usr/bin/python2.6
2#
ashariffc33cd92013-02-15 06:31:21 +00003# Copyright 2011 Google Inc. All Rights Reserved.
asharif4d2b7162013-02-15 05:14:57 +00004
ashariffc33cd92013-02-15 06:31:21 +00005"""Script to image a ChromeOS device.
asharif4d2b7162013-02-15 05:14:57 +00006
ashariffc33cd92013-02-15 06:31:21 +00007This script images a remote ChromeOS device with a specific image."
asharif4d2b7162013-02-15 05:14:57 +00008"""
9
ashariffc33cd92013-02-15 06:31:21 +000010__author__ = "asharif@google.com (Ahmad Sharif)"
asharif4d2b7162013-02-15 05:14:57 +000011
ashariffc33cd92013-02-15 06:31:21 +000012import filecmp
13import glob
asharif4d2b7162013-02-15 05:14:57 +000014import optparse
15import os
ashariffc33cd92013-02-15 06:31:21 +000016import shutil
asharif4d2b7162013-02-15 05:14:57 +000017import sys
ashariffc33cd92013-02-15 06:31:21 +000018import tempfile
asharif4d2b7162013-02-15 05:14:57 +000019import tc_enter_chroot
20from utils import command_executer
21from utils import logger
22from utils import utils
23
asharif0e0e2682013-02-15 05:15:29 +000024checksum_file = "/home/chronos/osimage_checksum_file"
asharif4d2b7162013-02-15 05:14:57 +000025
26
27def Usage(parser, message):
28 print "ERROR: " + message
29 parser.print_help()
30 sys.exit(0)
31
asharif0e0e2682013-02-15 05:15:29 +000032def ImageChromeOS(argv):
asharif4d2b7162013-02-15 05:14:57 +000033 """Build ChromeOS."""
34 # Common initializations
35 cmd_executer = command_executer.GetCommandExecuter()
ashariffc33cd92013-02-15 06:31:21 +000036 l = logger.GetLogger()
asharif4d2b7162013-02-15 05:14:57 +000037
38 parser = optparse.OptionParser()
39 parser.add_option("-c", "--chromeos_root", dest="chromeos_root",
40 help="Target directory for ChromeOS installation.")
41 parser.add_option("-r", "--remote", dest="remote",
42 help="Target device.")
asharif8de2c732013-02-15 05:15:25 +000043 parser.add_option("-i", "--image", dest="image",
44 help="Image binary file.")
asharif7cbe0692013-02-15 06:17:33 +000045 parser.add_option("-b", "--board", dest="board",
46 help="Target board override.")
asharif4d2b7162013-02-15 05:14:57 +000047
48 options = parser.parse_args(argv[1:])[0]
49
50 if options.chromeos_root is None:
51 Usage(parser, "--chromeos_root must be set")
52
53 if options.remote is None:
54 Usage(parser, "--remote must be set")
55
56 options.chromeos_root = os.path.expanduser(options.chromeos_root)
57
asharif7cbe0692013-02-15 06:17:33 +000058 if options.board is None:
59 board = cmd_executer.CrosLearnBoard(options.chromeos_root, options.remote)
60 else:
61 board = options.board
asharif8de2c732013-02-15 05:15:25 +000062
63 if options.image is None:
asharif67966872013-02-15 05:15:44 +000064 image = (options.chromeos_root +
65 "/src/build/images/" + board +
asharif8de2c732013-02-15 05:15:25 +000066 "/latest/" +
67 "/chromiumos_image.bin")
68 else:
69 image = options.image
asharifc380f612013-02-15 09:13:07 +000070 image = os.path.expanduser(image)
asharif8de2c732013-02-15 05:15:25 +000071
72 image = os.path.realpath(image)
73
74 if not os.path.exists(image):
75 Usage(parser, "Image file: " + image + " does not exist!")
76
77 image_checksum = utils.Md5File(image)
asharif4d2b7162013-02-15 05:14:57 +000078
79 command = "cat " + checksum_file
80 retval, device_checksum, err = cmd_executer.CrosRunCommand(command,
81 return_output=True,
82 chromeos_root=options.chromeos_root,
83 machine=options.remote)
84
85 device_checksum = device_checksum.strip()
86 image_checksum = str(image_checksum)
87
ashariffc33cd92013-02-15 06:31:21 +000088 l.LogOutput("Image checksum: " + image_checksum)
89 l.LogOutput("Device checksum: " + device_checksum)
asharif4d2b7162013-02-15 05:14:57 +000090
91 if image_checksum != device_checksum:
ashariffc33cd92013-02-15 06:31:21 +000092 [found, located_image] = LocateOrCopyImage(options.chromeos_root,
93 image,
94 board=board)
95
96 l.LogOutput("Checksums do not match. Re-imaging...")
asharif4d2b7162013-02-15 05:14:57 +000097 command = (options.chromeos_root +
98 "/src/scripts/image_to_live.sh --remote=" +
asharif8de2c732013-02-15 05:15:25 +000099 options.remote +
ashariffc33cd92013-02-15 06:31:21 +0000100 " --image=" + located_image)
asharif4d2b7162013-02-15 05:14:57 +0000101
asharif7cbe0692013-02-15 06:17:33 +0000102 retval = cmd_executer.RunCommand(command)
ashariffc33cd92013-02-15 06:31:21 +0000103
104 if found == False:
105 temp_dir = os.path.dirname(located_image)
106 l.LogOutput("Deleting temp image dir: %s" % temp_dir)
107 shutil.rmtree(temp_dir)
108
asharif7cbe0692013-02-15 06:17:33 +0000109 utils.AssertExit(retval == 0, "Image command failed")
asharif4d2b7162013-02-15 05:14:57 +0000110 command = "'echo " + image_checksum + " > " + checksum_file
111 command += "&& chmod -w " + checksum_file + "'"
asharif7cbe0692013-02-15 06:17:33 +0000112 retval = cmd_executer.CrosRunCommand(command,
113 chromeos_root=options.chromeos_root,
asharif4d2b7162013-02-15 05:14:57 +0000114 machine=options.remote)
asharif7cbe0692013-02-15 06:17:33 +0000115 utils.AssertExit(retval == 0, "Writing checksum failed.")
asharif4d2b7162013-02-15 05:14:57 +0000116 else:
ashariffc33cd92013-02-15 06:31:21 +0000117 l.LogOutput("Checksums match. Skipping reimage")
asharif4d2b7162013-02-15 05:14:57 +0000118
119 return retval
120
ashariffc33cd92013-02-15 06:31:21 +0000121
122def LocateOrCopyImage(chromeos_root, image, board=None):
123 l = logger.GetLogger()
124 if board is None:
125 board_glob = "*"
126 else:
127 board_glob = board
128
129 chromeos_root_realpath = os.path.realpath(chromeos_root)
130
131
132 if image.startswith(chromeos_root_realpath):
133 return [True, image]
134
135 # First search within the existing build dirs for any matching files.
136 images_glob = ("%s/src/build/images/%s/*/*.bin" %
137 (chromeos_root_realpath,
138 board_glob))
139 images_list = glob.glob(images_glob)
140 for potential_image in images_list:
141 if filecmp.cmp(potential_image, image):
142 l.LogOutput("Found matching image %s in chromeos_root." % potential_image)
143 return [True, potential_image]
144 # We did not find an image. Copy it in the src dir and return the copied file.
145 if board is None:
146 board = ""
147 temp_dir = tempfile.mkdtemp(prefix="%s/src/build/images/%s/tmp" %
148 (chromeos_root_realpath,
149 board))
150 new_image = "%s/%s" % (temp_dir, os.path.basename(image))
151 l.LogOutput("No matching image found. Copying %s to %s" %
152 (image, new_image))
153 shutil.copyfile(image, new_image)
asharifedff23f2013-02-15 09:14:34 +0000154 return [False, new_image]
ashariffc33cd92013-02-15 06:31:21 +0000155
156
asharif4d2b7162013-02-15 05:14:57 +0000157if __name__ == "__main__":
asharif0e0e2682013-02-15 05:15:29 +0000158 ImageChromeOS(sys.argv)