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

Side by Side Diff: bin/cros_image_to_target.py

Issue 5176002: cros_image_to_target handles test images, less verbose (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils.git@master
Patch Set: Rebased to tip and removed tgz file Created 10 years, 1 month 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 | cros_generate_update_payload » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 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 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 """Create and copy update image to target host. 7 """Create and copy update image to target host.
8 8
9 auto-update and devserver change out from beneath us often enough 9 auto-update and devserver change out from beneath us often enough
10 that despite having to duplicate a litte code, it seems that the 10 that despite having to duplicate a litte code, it seems that the
(...skipping 12 matching lines...) Expand all
23 import sys 23 import sys
24 import tempfile 24 import tempfile
25 import time 25 import time
26 import traceback 26 import traceback
27 27
28 from xml.dom import minidom 28 from xml.dom import minidom
29 29
30 30
31 # This is the default filename within the image directory to load updates from 31 # This is the default filename within the image directory to load updates from
32 DEFAULT_IMAGE_NAME = 'chromiumos_image.bin' 32 DEFAULT_IMAGE_NAME = 'chromiumos_image.bin'
33 DEFAULT_IMAGE_NAME_TEST = 'chromiumos_test_image.bin'
33 34
34 # The filenames we provide to clients to pull updates 35 # The filenames we provide to clients to pull updates
35 UPDATE_FILENAME = 'update.gz' 36 UPDATE_FILENAME = 'update.gz'
36 STATEFUL_FILENAME = 'stateful.tgz' 37 STATEFUL_FILENAME = 'stateful.tgz'
37 38
38 # How long do we wait for the server to start before launching client 39 # How long do we wait for the server to start before launching client
39 SERVER_STARTUP_WAIT = 1 40 SERVER_STARTUP_WAIT = 1
40 41
41 42
42 class Command(object): 43 class Command(object):
43 """Shell command ease-ups for Python.""" 44 """Shell command ease-ups for Python."""
44 45
45 def __init__(self, env): 46 def __init__(self, env):
46 self.env = env 47 self.env = env
47 48
48 def RunPipe(self, pipeline, infile=None, outfile=None, 49 def RunPipe(self, pipeline, infile=None, outfile=None,
49 capture=False, oneline=False): 50 capture=False, oneline=False, hide_stderr=False):
50 """Perform a command pipeline, with optional input/output filenames.""" 51 """
52 Perform a command pipeline, with optional input/output filenames.
53
54 hide_stderr Don't allow output of stderr (default False)
55 """
51 56
52 last_pipe = None 57 last_pipe = None
53 while pipeline: 58 while pipeline:
54 cmd = pipeline.pop(0) 59 cmd = pipeline.pop(0)
55 kwargs = {} 60 kwargs = {}
56 if last_pipe is not None: 61 if last_pipe is not None:
57 kwargs['stdin'] = last_pipe.stdout 62 kwargs['stdin'] = last_pipe.stdout
58 elif infile: 63 elif infile:
59 kwargs['stdin'] = open(infile, 'rb') 64 kwargs['stdin'] = open(infile, 'rb')
60 if pipeline or capture: 65 if pipeline or capture:
61 kwargs['stdout'] = subprocess.PIPE 66 kwargs['stdout'] = subprocess.PIPE
62 elif outfile: 67 elif outfile:
63 kwargs['stdout'] = open(outfile, 'wb') 68 kwargs['stdout'] = open(outfile, 'wb')
69 if hide_stderr:
70 kwargs['stderr'] = open('/dev/null', 'wb')
64 71
65 self.env.Info('Running: %s' % ' '.join(cmd)) 72 self.env.Debug('Running: %s' % ' '.join(cmd))
66 last_pipe = subprocess.Popen(cmd, **kwargs) 73 last_pipe = subprocess.Popen(cmd, **kwargs)
67 74
68 if capture: 75 if capture:
69 ret = last_pipe.communicate()[0] 76 ret = last_pipe.communicate()[0]
70 if not ret: 77 if not ret:
71 return None 78 return None
72 elif oneline: 79 elif oneline:
73 return ret.rstrip('\r\n') 80 return ret.rstrip('\r\n')
74 else: 81 else:
75 return ret 82 return ret
(...skipping 27 matching lines...) Expand all
103 self.known_hosts = os.path.join(self.ssh_dir, 'known-hosts') 110 self.known_hosts = os.path.join(self.ssh_dir, 'known-hosts')
104 111
105 def Cleanup(self): 112 def Cleanup(self):
106 Command.RunPipe(self, [['rm', '-rf', self.ssh_dir]]) 113 Command.RunPipe(self, [['rm', '-rf', self.ssh_dir]])
107 self.ssh_dir = None 114 self.ssh_dir = None
108 115
109 def GetArgs(self): 116 def GetArgs(self):
110 if not self.ssh_dir: 117 if not self.ssh_dir:
111 self.Setup() 118 self.Setup()
112 119
120 # allow up to 3 seconds to connect
Paul Stewart 2010/11/23 22:49:07 Drop this comment. The associated code is gone.
113 return ['-o', 'Compression=no', 121 return ['-o', 'Compression=no',
114 '-o', 'ConnectTimeout=%d' % self.CONNECT_TIMEOUT, 122 '-o', 'ConnectTimeout=%d' % self.CONNECT_TIMEOUT,
115 '-o', 'StrictHostKeyChecking=no', 123 '-o', 'StrictHostKeyChecking=no',
116 '-o', 'UserKnownHostsFile=%s' % self.known_hosts, 124 '-o', 'UserKnownHostsFile=%s' % self.known_hosts,
117 '-i', self.identity] 125 '-i', self.identity]
118 126
119 def RunPipe(self, pipeline, **kwargs): 127 def RunPipe(self, pipeline, **kwargs):
120 args = ['ssh'] + self.GetArgs() 128 args = ['ssh'] + self.GetArgs()
121 if 'remote_tunnel' in kwargs: 129 if 'remote_tunnel' in kwargs:
122 ports = kwargs.pop('remote_tunnel') 130 ports = kwargs.pop('remote_tunnel')
123 args += ['-R %d:localhost:%d' % ports] 131 args += ['-R %d:localhost:%d' % ports]
124 pipeline[0] = args + ['root@%s' % self.remote] + list(pipeline[0]) 132 pipeline[0] = args + ['root@%s' % self.remote] + list(pipeline[0])
125 return Command.RunPipe(self, pipeline, **kwargs) 133 return Command.RunPipe(self, pipeline, **kwargs)
126 134
127 def Reset(self): 135 def Reset(self):
128 os.unlink(self.known_hosts) 136 os.unlink(self.known_hosts)
129 137
130 def Copy(self, src, dest): 138 def Copy(self, src, dest):
131 return Command.RunPipe(self, [['scp'] + self.GetArgs() + 139 return Command.RunPipe(self, [['scp'] + self.GetArgs() +
132 [src, 'root@%s:%s' % 140 [src, 'root@%s:%s' %
133 (self.remote, dest)]]) 141 (self.remote, dest)]])
134 142
135 143
136 class CrosEnv(object): 144 class CrosEnv(object):
137 """Encapsulates the ChromeOS build system environment functionality.""" 145 """Encapsulates the ChromeOS build system environment functionality."""
138 146
139 REBOOT_START_WAIT = 5 147 REBOOT_START_WAIT = 5
140 REBOOT_WAIT_TIME = 60 148 REBOOT_WAIT_TIME = 60
141 149
142 def __init__(self, verbose=False): 150 def __init__(self, verbose=0):
Paul Stewart 2010/11/23 22:49:07 Please make CrossEnv constants as above for SILENT
143 self.cros_root = os.path.dirname(os.path.abspath(sys.argv[0])) 151 self.cros_root = os.path.dirname(os.path.abspath(sys.argv[0]))
144 parent = os.path.dirname(self.cros_root) 152 parent = os.path.dirname(self.cros_root)
145 if os.path.exists(os.path.join(parent, 'chromeos-common.sh')): 153 if os.path.exists(os.path.join(parent, 'chromeos-common.sh')):
146 self.cros_root = parent 154 self.cros_root = parent
147 self.cmd = Command(self) 155 self.cmd = Command(self)
148 self.verbose = verbose 156 self.verbose = verbose
149 157
158 # do we have the pv progress tool? (sudo apt-get install pv)
159 self.have_pv = True
160 try:
161 self.cmd.Output('pv', '--help')
162 except OSError:
163 self.have_pv = False
164
150 def Error(self, msg): 165 def Error(self, msg):
151 print >> sys.stderr, 'ERROR: %s' % msg 166 print >> sys.stderr, 'ERROR: %s' % msg
152 167
153 def Fatal(self, msg=None): 168 def Fatal(self, msg=None):
154 if msg: 169 if msg:
155 self.Error(msg) 170 self.Error(msg)
156 sys.exit(1) 171 sys.exit(1)
157 172
158 def Info(self, msg): 173 def Info(self, msg):
159 if self.verbose: 174 if self.verbose > 0:
160 print 'INFO: %s' % msg 175 print 'INFO: %s' % msg
161 176
177 def Debug(self, msg):
178 if self.verbose > 1:
179 print 'DEBUG: %s' % msg
180
162 def CrosUtilsPath(self, filename): 181 def CrosUtilsPath(self, filename):
163 return os.path.join(self.cros_root, filename) 182 return os.path.join(self.cros_root, filename)
164 183
165 def ChrootPath(self, filename): 184 def ChrootPath(self, filename):
166 return self.CrosUtilsPath(os.path.join('..', '..', 'chroot', 185 return self.CrosUtilsPath(os.path.join('..', '..', 'chroot',
167 filename.strip(os.path.sep))) 186 filename.strip(os.path.sep)))
168 187
169 def FileOneLine(self, filename): 188 def FileOneLine(self, filename):
170 return file(filename).read().rstrip('\r\n') 189 return file(filename).read().rstrip('\r\n')
171 190
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 def CreateServer(self, port, update_file, stateful_file): 267 def CreateServer(self, port, update_file, stateful_file):
249 """Start the devserver clone.""" 268 """Start the devserver clone."""
250 269
251 PingUpdateResponse.Setup(self.GetHash(update_file), 270 PingUpdateResponse.Setup(self.GetHash(update_file),
252 self.GetSha256(update_file), 271 self.GetSha256(update_file),
253 self.GetSize(update_file)) 272 self.GetSize(update_file))
254 273
255 UpdateHandler.SetupUrl('/update', PingUpdateResponse()) 274 UpdateHandler.SetupUrl('/update', PingUpdateResponse())
256 UpdateHandler.SetupUrl('/%s' % UPDATE_FILENAME, 275 UpdateHandler.SetupUrl('/%s' % UPDATE_FILENAME,
257 FileUpdateResponse(update_file, 276 FileUpdateResponse(update_file,
258 verbose=self.verbose)) 277 verbose=self.verbose,
278 have_pv=self.have_pv))
259 UpdateHandler.SetupUrl('/%s' % STATEFUL_FILENAME, 279 UpdateHandler.SetupUrl('/%s' % STATEFUL_FILENAME,
260 FileUpdateResponse(stateful_file, 280 FileUpdateResponse(stateful_file,
261 verbose=self.verbose)) 281 verbose=self.verbose,
282 have_pv=self.have_pv))
262 283
263 self.http_server = BaseHTTPServer.HTTPServer(('', port), UpdateHandler) 284 self.http_server = BaseHTTPServer.HTTPServer(('', port), UpdateHandler)
264 285
265 def StartServer(self): 286 def StartServer(self):
266 self.Info('Starting http server') 287 self.Info('Starting http server')
267 self.http_server.serve_forever() 288 self.http_server.serve_forever()
268 289
269 def GetUpdateStatus(self): 290 def GetUpdateStatus(self):
270 status = self.ssh_cmd.Output('/usr/bin/update_engine_client', '--status') 291 status = self.ssh_cmd.Output('/usr/bin/update_engine_client', '--status')
271 if not status: 292 if not status:
(...skipping 18 matching lines...) Expand all
290 self.Info('Client has not yet restarted (try %d). Waiting...' % attempt) 311 self.Info('Client has not yet restarted (try %d). Waiting...' % attempt)
291 wait_time = SSHCommand.CONNECT_TIMEOUT - (time.time() - start) 312 wait_time = SSHCommand.CONNECT_TIMEOUT - (time.time() - start)
292 if wait_time > 0: 313 if wait_time > 0:
293 time.sleep(wait_time) 314 time.sleep(wait_time)
294 315
295 return False 316 return False
296 317
297 def StartClient(self, port): 318 def StartClient(self, port):
298 """Ask the client machine to update from our server.""" 319 """Ask the client machine to update from our server."""
299 320
321 self.Info("Starting client...")
300 status = self.GetUpdateStatus() 322 status = self.GetUpdateStatus()
301 if status != 'UPDATE_STATUS_IDLE': 323 if status != 'UPDATE_STATUS_IDLE':
302 self.Error('Client update status is not IDLE: %s' % status) 324 self.Error('Client update status is not IDLE: %s' % status)
303 return False 325 return False
304 326
305 url_base = 'http://localhost:%d' % port 327 url_base = 'http://localhost:%d' % port
306 update_url = '%s/update' % url_base 328 update_url = '%s/update' % url_base
307 fd, update_log = tempfile.mkstemp(prefix='image-to-target-') 329 fd, update_log = tempfile.mkstemp(prefix='image-to-target-')
308 self.Info('Starting update on client. Client output stored to %s' % 330 self.Info('Starting update on client. Client output stored to %s' %
309 update_log) 331 update_log)
332
333 # this will make the client read the files we have set up
310 self.ssh_cmd.Run('/usr/bin/update_engine_client', '--update', 334 self.ssh_cmd.Run('/usr/bin/update_engine_client', '--update',
311 '--omaha_url', update_url, remote_tunnel=(port, port), 335 '--omaha_url', update_url, remote_tunnel=(port, port),
312 outfile=update_log) 336 outfile=update_log)
313 337
314 if self.GetUpdateStatus() != 'UPDATE_STATUS_UPDATED_NEED_REBOOT': 338 if self.GetUpdateStatus() != 'UPDATE_STATUS_UPDATED_NEED_REBOOT':
315 self.Error('Client update failed') 339 self.Error('Client update failed')
316 return False 340 return False
317 341
342 self.Info('Update complete - running update script on client')
318 self.ssh_cmd.Copy(self.CrosUtilsPath('../platform/dev/stateful_update'), 343 self.ssh_cmd.Copy(self.CrosUtilsPath('../platform/dev/stateful_update'),
319 '/tmp') 344 '/tmp')
320 if not self.ssh_cmd.Run('/tmp/stateful_update', url_base, 345 if not self.ssh_cmd.Run('/tmp/stateful_update', url_base,
321 remote_tunnel=(port, port)): 346 remote_tunnel=(port, port)):
322 self.Error('Client stateful update failed') 347 self.Error('Client stateful update failed')
323 return False 348 return False
324 349
325 self.Info('Rebooting client') 350 self.Info('Rebooting client')
326 if not self.ClientReboot(): 351 if not self.ClientReboot():
327 self.Error('Client may not have successfully rebooted...') 352 self.Error('Client may not have successfully rebooted...')
328 return False 353 return False
329 354
330 print 'Client update completed successfully!' 355 self.Info('Client update completed successfully!')
331 return True 356 return True
332 357
333 358
334 class UpdateResponse(object): 359 class UpdateResponse(object):
335 """Default response is the 404 error response.""" 360 """Default response is the 404 error response."""
336 361
337 def Reply(self, handler, send_content=True, post_data=None): 362 def Reply(self, handler, send_content=True, post_data=None):
338 handler.send_Error(404, 'File not found') 363 handler.send_error(404, 'File not found')
339 return None 364 return None
340 365
341 366
342 class FileUpdateResponse(UpdateResponse): 367 class FileUpdateResponse(UpdateResponse):
343 """Respond by sending the contents of a file.""" 368 """Respond by sending the contents of a file."""
344 369
345 def __init__(self, filename, content_type='application/octet-stream', 370 def __init__(self, filename, content_type='application/octet-stream',
346 verbose=False, blocksize=16*1024): 371 verbose=False, blocksize=16*1024, have_pv=False):
347 self.filename = filename 372 self.filename = filename
348 self.content_type = content_type 373 self.content_type = content_type
349 self.verbose = verbose 374 self.verbose = verbose
350 self.blocksize = blocksize 375 self.blocksize = blocksize
376 self.have_pv = have_pv
351 377
352 def Reply(self, handler, send_content=True, post_data=None): 378 def Reply(self, handler, send_content=True, post_data=None):
353 """Return file contents to the client. Optionally display progress.""" 379 """Return file contents to the client. Optionally display progress."""
354 380
355 try: 381 try:
356 f = open(self.filename, 'rb') 382 f = open(self.filename, 'rb')
357 except IOError: 383 except IOError:
358 return UpdateResponse.Reply(self, handler) 384 return UpdateResponse.Reply(self, handler)
359 385
360 handler.send_response(200) 386 handler.send_response(200)
361 handler.send_header('Content-type', self.content_type) 387 handler.send_header('Content-type', self.content_type)
362 filestat = os.fstat(f.fileno()) 388 filestat = os.fstat(f.fileno())
363 filesize = filestat[6] 389 filesize = filestat[6]
364 handler.send_header('Content-Length', str(filesize)) 390 handler.send_header('Content-Length', str(filesize))
365 handler.send_header('Last-Modified', 391 handler.send_header('Last-Modified',
366 handler.date_time_string(filestat.st_mtime)) 392 handler.date_time_string(filestat.st_mtime))
367 handler.end_headers() 393 handler.end_headers()
368 394
369 if not send_content: 395 if send_content:
370 return
371
372 if filesize <= self.blocksize:
373 handler.wfile.write(f.read())
374 else:
375 sent_size = 0 396 sent_size = 0
376 sent_percentage = None 397 sent_percentage = None
398
399 #TODO(sjg): this should use pv also
377 while True: 400 while True:
378 buf = f.read(self.blocksize) 401 buf = f.read(self.blocksize)
379 if not buf: 402 if not buf:
380 break 403 break
381 handler.wfile.write(buf) 404 handler.wfile.write(buf)
382 if self.verbose: 405 if self.verbose:
383 sent_size += len(buf) 406 sent_size += len(buf)
384 percentage = int(100 * sent_size / filesize) 407 percentage = int(100 * sent_size / filesize)
385 if sent_percentage != percentage: 408 if sent_percentage != percentage:
386 sent_percentage = percentage 409 sent_percentage = percentage
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 usage = 'usage: %prog [options]' 565 usage = 'usage: %prog [options]'
543 parser = optparse.OptionParser(usage=usage) 566 parser = optparse.OptionParser(usage=usage)
544 parser.add_option('--board', dest='board', default=None, 567 parser.add_option('--board', dest='board', default=None,
545 help='Board platform type') 568 help='Board platform type')
546 parser.add_option('--force-mismatch', dest='force_mismatch', default=False, 569 parser.add_option('--force-mismatch', dest='force_mismatch', default=False,
547 action='store_true', 570 action='store_true',
548 help='Upgrade even if client arch does not match') 571 help='Upgrade even if client arch does not match')
549 parser.add_option('--from', dest='src', default=None, 572 parser.add_option('--from', dest='src', default=None,
550 help='Source image to install') 573 help='Source image to install')
551 parser.add_option('--image-name', dest='image_name', 574 parser.add_option('--image-name', dest='image_name',
552 default=DEFAULT_IMAGE_NAME,
553 help='Filename within image directory to load') 575 help='Filename within image directory to load')
554 parser.add_option('--port', dest='port', default=8081, type='int', 576 parser.add_option('--port', dest='port', default=8081, type='int',
555 help='TCP port to serve from and tunnel through') 577 help='TCP port to serve from and tunnel through')
556 parser.add_option('--remote', dest='remote', default=None, 578 parser.add_option('--remote', dest='remote', default=None,
557 help='Remote device-under-test IP address') 579 help='Remote device-under-test IP address')
558 parser.add_option('--server-only', dest='server_only', default=False, 580 parser.add_option('--server-only', dest='server_only', default=False,
559 action='store_true', help='Do not start client') 581 action='store_true', help='Do not start client')
560 parser.add_option('--verbose', dest='verbose', default=False, 582 parser.add_option('--verbose', dest='verbose', default=False,
583 action='store_true', help='Display progress')
584 parser.add_option('--debug', dest='debug', default=False,
561 action='store_true', help='Display running commands') 585 action='store_true', help='Display running commands')
586 parser.add_option('--test', dest='test', default=False,
587 action='store_true', help='Select test image')
562 588
563 (options, args) = parser.parse_args(argv) 589 (options, args) = parser.parse_args(argv)
564 590
565 cros_env = CrosEnv(verbose=options.verbose) 591 # we can build the test image if it doesn't exist, so remember if we want to
592 build_test_image = False
593
594 verbosity = 0
595 if options.verbose:
596 verbosity = 1
597 if options.debug:
598 verbosity = 2
599 cros_env = CrosEnv(verbose=verbosity)
566 600
567 if not options.board: 601 if not options.board:
568 options.board = cros_env.GetDefaultBoard() 602 options.board = cros_env.GetDefaultBoard()
569 603
570 if not options.src: 604 if not options.src:
571 options.src = cros_env.GetLatestImage(options.board) 605 options.src = cros_env.GetLatestImage(options.board)
572 if options.src is None: 606 if options.src is None:
573 parser.error('No --from argument given and no default image found') 607 parser.error('No --from argument given and no default image found')
574 608
575 cros_env.Info('Performing update from %s' % options.src) 609 cros_env.Info('Performing update from %s' % options.src)
576 610
577 if not os.path.exists(options.src): 611 if not os.path.exists(options.src):
578 parser.error('Path %s does not exist' % options.src) 612 parser.error('Path %s does not exist' % options.src)
579 613
614 if not options.image_name:
615 # auto-select the correct image
616 if options.test:
617 options.image_name = DEFAULT_IMAGE_NAME_TEST
618
619 # we will build the test image if not found
620 build_test_image = True
621 else:
622 options.image_name = DEFAULT_IMAGE_NAME
623
580 if os.path.isdir(options.src): 624 if os.path.isdir(options.src):
581 image_directory = options.src 625 image_directory = options.src
582 image_file = os.path.join(options.src, options.image_name) 626 image_file = os.path.join(options.src, options.image_name)
583 627
584 if not os.path.exists(image_file): 628 if not os.path.exists(image_file):
629 if build_test_image:
630 # we want a test image but it doesn't exist
631 # try to build it if we can
632 cros_env.Info('Creating test image')
633 test_output = cros_env.cmd.Output(
634 cros_env.CrosUtilsPath('enter_chroot.sh'),
635 '--', './mod_image_for_test.sh',
636 '--board=%s' % options.board, '-y')
637 if not os.path.exists(image_file):
638 print test_output
639 cros_env.Fatal('Failed to create test image - please run '
640 './mod_image_for_test.sh manually inside the chroot')
585 parser.error('Image file %s does not exist' % image_file) 641 parser.error('Image file %s does not exist' % image_file)
586 else: 642 else:
587 image_file = options.src 643 image_file = options.src
588 image_directory = os.path.dirname(options.src) 644 image_directory = os.path.dirname(options.src)
589 645
646 update_file = os.path.join(image_directory, UPDATE_FILENAME)
647 stateful_file = os.path.join(image_directory, STATEFUL_FILENAME)
648
649 cros_env.Debug("Image file %s" % image_file)
650 cros_env.Debug("Update file %s" % update_file)
651 cros_env.Debug("Stateful file %s" % stateful_file)
652
590 if options.remote: 653 if options.remote:
654 cros_env.Info('Contacting client %s' % options.remote)
591 cros_env.SetRemote(options.remote) 655 cros_env.SetRemote(options.remote)
592 rel = cros_env.GetRemoteRelease() 656 rel = cros_env.GetRemoteRelease()
593 if not rel: 657 if not rel:
594 cros_env.Fatal('Could not retrieve remote lsb-release') 658 cros_env.Fatal('Could not retrieve remote lsb-release')
595 board = rel.get('CHROMEOS_RELEASE_BOARD', '(None)') 659 board = rel.get('CHROMEOS_RELEASE_BOARD', '(None)')
596 if board != options.board and not options.force_mismatch: 660 if board != options.board and not options.force_mismatch:
597 cros_env.Error('Board %s does not match expected %s' % 661 cros_env.Error('Board %s does not match expected %s' %
598 (board, options.board)) 662 (board, options.board))
599 cros_env.Error('(Use --force-mismatch option to override this)') 663 cros_env.Error('(Use --force-mismatch option to override this)')
600 cros_env.Fatal() 664 cros_env.Fatal()
601 665
602 elif not options.server_only: 666 elif not options.server_only:
603 parser.error('Either --server-only must be specified or ' 667 parser.error('Either --server-only must be specified or '
604 '--remote=<client> needs to be given') 668 '--remote=<client> needs to be given')
605 669
606 update_file = os.path.join(image_directory, UPDATE_FILENAME)
607 stateful_file = os.path.join(image_directory, STATEFUL_FILENAME)
608
609 if (not cros_env.GenerateUpdatePayload(image_file, update_file) or 670 if (not cros_env.GenerateUpdatePayload(image_file, update_file) or
610 not cros_env.BuildStateful(image_file, image_directory, stateful_file)): 671 not cros_env.BuildStateful(image_file, image_directory, stateful_file)):
611 cros_env.Fatal() 672 cros_env.Fatal()
612 673
613 cros_env.CreateServer(options.port, update_file, stateful_file) 674 cros_env.CreateServer(options.port, update_file, stateful_file)
614 675
615 exit_status = 1 676 exit_status = 1
616 if options.server_only: 677 if options.server_only:
617 child = None 678 child = None
618 else: 679 else:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 711
651 if child: 712 if child:
652 os.kill(child, 15) 713 os.kill(child, 15)
653 714
654 cros_env.Info('Server exiting with status %d' % exit_status) 715 cros_env.Info('Server exiting with status %d' % exit_status)
655 sys.exit(exit_status) 716 sys.exit(exit_status)
656 717
657 718
658 if __name__ == '__main__': 719 if __name__ == '__main__':
659 main(sys.argv) 720 main(sys.argv)
OLDNEW
« no previous file with comments | « no previous file | cros_generate_update_payload » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698