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

Side by Side Diff: devserver.py

Issue 3296022: Re-write of autoupdate.py to merge changes to be more cohesive and allow a forced_image option. (Closed) Base URL: http://git.chromium.org/git/dev-util.git
Patch Set: Cleanup before push. 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 | « autoupdate_unittest.py ('k') | 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 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import autoupdate
6 import buildutil
7 import optparse 5 import optparse
8 import os 6 import os
9 import sys 7 import sys
10 import web 8 import web
11 9
10 import autoupdate
11 import buildutil
12
13 # Sets up global to share between classes.
12 global updater 14 global updater
13 updater = None 15 updater = None
14 16
15 17
16 class index: 18 class index:
17 def GET(self): 19 def GET(self):
18 return render.index(None) 20 return render.index(None)
19 21
22
20 class update: 23 class update:
21 """ 24 """
22 Processes updates from the client machine. If an update is found, the url 25 Processes updates from the client machine. If an update is found, the url
23 references a static link that can be served automagically from web.py. 26 references a static link that can be served automagically from web.py.
24 """ 27 """
25 def POST(self, args=None): 28 def POST(self, args=None):
26 return updater.HandleUpdatePing(web.data(), args) 29 return updater.HandleUpdatePing(web.data(), args)
27 30
31
28 class build: 32 class build:
29 """ 33 """
30 builds the package specified by the pkg parameter and returns the name 34 builds the package specified by the pkg parameter and returns the name
31 of the output file. 35 of the output file.
32 """ 36 """
33 def POST(self): 37 def POST(self):
34 input = web.input() 38 input = web.input()
35 web.debug('emerging %s ' % input.pkg) 39 web.debug('emerging %s ' % input.pkg)
36 emerge_command = 'emerge-%s %s' % (input.board, input.pkg) 40 emerge_command = 'emerge-%s %s' % (input.board, input.pkg)
37 err = os.system(emerge_command) 41 err = os.system(emerge_command)
38 if err != 0: 42 if err != 0:
39 raise Exception('failed to execute %s' % emerge_command) 43 raise Exception('failed to execute %s' % emerge_command)
40 eclean_command = 'eclean-%s -d packages' % input.board 44 eclean_command = 'eclean-%s -d packages' % input.board
41 err = os.system(eclean_command) 45 err = os.system(eclean_command)
42 if err != 0: 46 if err != 0:
43 raise Exception('failed to execute %s' % emerge_command) 47 raise Exception('failed to execute %s' % emerge_command)
44 48
49
45 def OverrideWSGIServer(server_address, wsgi_app): 50 def OverrideWSGIServer(server_address, wsgi_app):
46 """Creates a CherryPyWSGIServer instance. 51 """Creates a CherryPyWSGIServer instance.
47 52
48 Overrides web.py's WSGIServer routine (web.httpserver.WSGIServer) to 53 Overrides web.py's WSGIServer routine (web.httpserver.WSGIServer) to
49 increase the accepted connection socket timeout from the default 10 54 increase the accepted connection socket timeout from the default 10
50 seconds to 10 minutes. The extra time is necessary to serve delta 55 seconds to 10 minutes. The extra time is necessary to serve delta
51 updates as well as update requests from a low priority update_engine 56 updates as well as update requests from a low priority update_engine
52 process running on a heavily loaded Chrome OS device. 57 process running on a heavily loaded Chrome OS device.
53 """ 58 """
54 web.debug('using local OverrideWSGIServer routine') 59 web.debug('using local OverrideWSGIServer routine')
55 from web.wsgiserver import CherryPyWSGIServer 60 from web.wsgiserver import CherryPyWSGIServer
56 return CherryPyWSGIServer(server_address, wsgi_app, server_name="localhost", 61 return CherryPyWSGIServer(server_address, wsgi_app, server_name="localhost",
57 timeout=600) 62 timeout=600)
58 63
64 def _PrepareToServeUpdatesOnly(image_dir):
65 """Sets up symlink to image_dir for serving purposes."""
66 assert os.path.exists(image_dir), '%s must exist.' % image_dir
67 # If we're serving out of an archived build dir (e.g. a
68 # buildbot), prepare this webserver's magic 'static/' dir with a
69 # link to the build archive.
70 web.debug('Preparing autoupdate for "serve updates only" mode.')
71 if os.path.exists('static/archive'):
72 if image_dir != os.readlink('static/archive'):
73 web.debug('removing stale symlink to %s' % image_dir)
74 os.unlink('static/archive')
75 os.symlink(image_dir, 'static/archive')
76 else:
77 os.symlink(image_dir, 'static/archive')
78 web.debug('archive dir: %s ready to be used to serve images.' % image_dir)
79
80
59 if __name__ == '__main__': 81 if __name__ == '__main__':
60 usage = 'usage: %prog [options]' 82 usage = 'usage: %prog [options]'
61 parser = optparse.OptionParser(usage) 83 parser = optparse.OptionParser(usage)
62 parser.add_option('--archive_dir', dest='archive_dir', 84 parser.add_option('--archive_dir', dest='archive_dir',
63 help='serve archived builds only.') 85 help='serve archived builds only.')
64 parser.add_option('--client_prefix', dest='client_prefix', 86 parser.add_option('--client_prefix', dest='client_prefix',
65 help='Required prefix for client software version.', 87 help='Required prefix for client software version.',
66 default='MementoSoftwareUpdate') 88 default='MementoSoftwareUpdate')
67 parser.add_option('--factory_config', dest='factory_config', 89 parser.add_option('--factory_config', dest='factory_config',
68 help='Config file for serving images from factory floor.') 90 help='Config file for serving images from factory floor.')
91 parser.add_option('--image', dest='image',
92 help='Force update using this image.')
69 parser.add_option('-t', action='store_true', dest='test_image') 93 parser.add_option('-t', action='store_true', dest='test_image')
70 parser.add_option('-u', '--urlbase', dest='urlbase', 94 parser.add_option('-u', '--urlbase', dest='urlbase',
71 help='base URL, other than devserver, for update images.') 95 help='base URL, other than devserver, for update images.')
72 parser.add_option('--validate_factory_config', action="store_true", 96 parser.add_option('--validate_factory_config', action="store_true",
73 dest='validate_factory_config', 97 dest='validate_factory_config',
74 help='Validate factory config file, then exit.') 98 help='Validate factory config file, then exit.')
75 options, args = parser.parse_args() 99 # Clean up the args, due to httpserver's hardcoded use of sys.argv.
76 # clean up the args, due to httpserver's hardcoded use of sys.argv 100 options, sys.argv = parser.parse_args(sys.argv)
77 if options.archive_dir:
78 sys.argv.remove('--archive_dir')
79 sys.argv.remove(options.archive_dir)
80 if '--client_prefix' in sys.argv:
81 sys.argv.remove('--client_prefix')
82 sys.argv.remove(options.client_prefix)
83 if options.factory_config:
84 sys.argv.remove('--factory_config')
85 sys.argv.remove(options.factory_config)
86 if options.test_image:
87 sys.argv.remove('-t')
88 if options.urlbase:
89 sys.argv.remove('-u')
90 sys.argv.remove(options.urlbase)
91 if options.validate_factory_config:
92 sys.argv.remove('--validate_factory_config')
93 101
94 root_dir = os.path.realpath('%s/../..' % 102 root_dir = os.path.realpath('%s/../..' %
95 os.path.dirname(os.path.abspath(sys.argv[0]))) 103 os.path.dirname(os.path.abspath(sys.argv[0])))
104
105 serve_only = False
106
96 if options.archive_dir: 107 if options.archive_dir:
97 static_dir = os.path.realpath(options.archive_dir) 108 static_dir = os.path.realpath(options.archive_dir)
98 assert os.path.exists(static_dir), '%s must exist.' % options.archive_dir 109 _PrepareToServeUpdatesOnly(static_dir)
99 web.debug('using archive dir: %s' % static_dir) 110 serve_only = True
100 else: 111 else:
101 static_dir = os.path.realpath('%s/static' % 112 static_dir = os.path.realpath('%s/static' %
102 os.path.dirname(os.path.abspath(sys.argv[0]))) 113 os.path.dirname(os.path.abspath(sys.argv[0])))
103 web.debug('dev root is %s' % root_dir) 114 web.debug('dev root is %s' % root_dir)
104 os.system('mkdir -p %s' % static_dir) 115 os.system('mkdir -p %s' % static_dir)
105 web.debug('Serving images from %s' % static_dir) 116
117 web.debug('Serving from %s' % static_dir)
106 118
107 updater = autoupdate.Autoupdate( 119 updater = autoupdate.Autoupdate(
108 root_dir=root_dir, 120 root_dir=root_dir,
109 static_dir=static_dir, 121 static_dir=static_dir,
110 serve_only=options.archive_dir, 122 serve_only=serve_only,
111 urlbase=options.urlbase, 123 urlbase=options.urlbase,
112 test_image=options.test_image, 124 test_image=options.test_image,
113 factory_config_path=options.factory_config, 125 factory_config_path=options.factory_config,
114 validate_factory_config=options.validate_factory_config, 126 client_prefix=options.client_prefix,
115 client_prefix=options.client_prefix) 127 forced_image=options.image)
116 if options.validate_factory_config:
117 sys.exit(0)
118 urls = ('/', 'index',
119 '/update', 'update',
120 '/update/(.+)', 'update',
121 '/build', 'build')
122 128
123 # Overrides the default WSGIServer routine -- see OverrideWSGIServer. 129 if options.factory_config:
124 web.httpserver.WSGIServer = OverrideWSGIServer 130 updater.ImportFactoryConfigFile(factory_config_path,
125 app = web.application(urls, globals(), autoreload=True) 131 validate_factory_config)
126 render = web.template.render('templates/') 132
127 app.run() 133 if not options.validate_factory_config:
134 # We do not need to run the dev server for validating the factory config.
135 # TODO(nsanders): Write unit test to validate.
136 urls = ('/', 'index',
137 '/update', 'update',
138 '/update/(.+)', 'update',
139 '/build', 'build')
140
141 # Overrides the default WSGIServer routine -- see OverrideWSGIServer.
142 web.httpserver.WSGIServer = OverrideWSGIServer
143 app = web.application(urls, globals(), autoreload=True)
144 render = web.template.render('templates/')
145 app.run()
OLDNEW
« no previous file with comments | « autoupdate_unittest.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698