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

Side by Side Diff: tools/signing_script.py

Issue 23442023: Added tools/signing_script.py, used to automate steps before and after the signing step (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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 | « 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 #!/usr/bin/env python
2 #
3 # Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file.
6
7 import hashlib
8 import imp
9 import optparse
10 import os
11 import subprocess
12 import sys
13
14 DART_DIR = os.path.dirname(os.path.dirname(__file__))
15 GSUTIL = os.path.join(DART_DIR, 'third_party', 'gsutil', 'gsutil')
16 BOT_UTILS = os.path.join(DART_DIR, 'tools', 'bots', 'bot_utils.py')
17 BASENAME_PATTERN = 'darteditor-%(system)s-%(bits)s'
18 FILENAME_PATTERN = BASENAME_PATTERN + '.zip'
19 BUCKET_PATTERN = (
20 'gs://dart-editor-archive-trunk/%(revision)s/' + FILENAME_PATTERN)
21
22 DRY_RUN = False
23
24 bot_utils = imp.load_source('bot_utils', BOT_UTILS)
25
26 class ChangedWorkingDirectory(object):
27 def __init__(self, working_directory):
28 self._working_directory = working_directory
29
30 def __enter__(self):
31 self._old_cwd = os.getcwd()
32 print "Enter directory = ", self._working_directory
33 if not DRY_RUN:
34 os.chdir(self._working_directory)
35
36 def __exit__(self, *_):
37 print "Enter directory = ", self._old_cwd
38 os.chdir(self._old_cwd)
39
40 def GetOptionsParser():
41 parser = optparse.OptionParser("usage: %prog [options]")
42 parser.add_option("--scratch-dir",
43 help="Scratch directory to use.")
44 parser.add_option("--revision", type="int",
45 help="Revision we want to sign.")
46 parser.add_option("--channel", type="string",
47 default=None,
48 help="Channel we want to sign.")
49 parser.add_option("--dry-run", action="store_true", dest="dry_run",
50 default=False,
51 help="Do a dry run and do not execute any commands.")
52 parser.add_option("--prepare", action="store_true", dest="prepare",
53 default=False,
54 help="Prepare the .exe/.zip files to sign.")
55 parser.add_option("--deploy", action="store_true", dest="deploy",
56 default=False,
57 help="Pack the signed .exe/.zip files and deploy.")
58 return parser
59
60 def CalculateMd5Checksum(filename):
61 md5 = hashlib.md5()
62 with open(filename, 'rb') as f:
63 data = f.read(65536)
64 while len(data) > 0:
65 md5.update(data)
66 data = f.read(65536)
67 return md5.hexdigest()
68
69 def die(msg, withOptions=True):
70 print msg
71 if withOptions:
72 GetOptionsParser().print_usage()
73 sys.exit(1)
74
75 def run(command):
76 """We use run() instead of builtin python methods, because not all
77 functionality can easily be done by python and we can support --dry-run"""
78
79 print "Running: ", command
80 if not DRY_RUN:
81 process = subprocess.Popen(command,
82 stdout=subprocess.PIPE,
83 stderr=subprocess.PIPE)
84 (stdout, stderr) = process.communicate()
85 if process.returncode != 0:
86 print "DEBUG: failed to run command '%s'" % command
87 print "DEBUG: stdout = ", stdout
88 print "DEBUG: stderr = ", stderr
89 print "DEBUG: returncode = ", process.returncode
90 raise OSError(process.returncode)
91
92 def clean_directory(directory):
93 if os.path.exists(directory):
94 run(['rm', '-r', directory])
95 run(['mkdir', '-p', directory])
96
97 def rm_tree(directory):
98 if os.path.exists(directory):
99 run(['rm', '-r', directory])
100
101 def copy_tree(from_dir, to_dir):
102 if os.path.exists(to_dir):
103 run(['rm', '-r', to_dir])
104 run(['cp', '-Rp', from_dir, to_dir])
105
106 def copy_file(from_file, to_file):
107 if os.path.exists(to_file):
108 run(['rm', to_file])
109 run(['cp', '-p', from_file, to_file])
110
111 def copy_and_zip(from_dir, to_dir):
112 rm_tree(to_dir)
113 copy_tree(from_dir, to_dir)
114
115 dirname = os.path.basename(to_dir)
116 with ChangedWorkingDirectory(os.path.dirname(to_dir)):
117 run(['zip', '-r9', dirname + '.zip', dirname])
118
119 def unzip_and_copy(from_dir, to_dir, postsign_dir):
ricow1 2013/10/14 13:23:46 as discussed offline, the parameter names here cou
kustermann 2013/10/14 16:05:32 Done.
120 rm_tree(from_dir)
121 run(['unzip', from_dir + '.zip', '-d', postsign_dir])
122 clean_directory(to_dir)
123 copy_tree(from_dir, to_dir)
124
125 def download_from_old_location(config, destination):
126 bucket = BUCKET_PATTERN % config
127 run([GSUTIL, 'cp', bucket, destination])
128
129 def upload_to_old_location(config, source_zip):
ricow1 2013/10/14 13:23:46 this is a little late now - we should have filed a
kustermann 2013/10/14 16:05:32 It's not that many places we have, so I guess it's
130 bot_utils.CreateChecksumFile(
131 source_zip, mangled_filename=os.path.basename(source_zip))
132 md5_zip_file = source_zip + '.md5sum'
133
134 bucket = BUCKET_PATTERN % config
135 run([GSUTIL, 'cp', source_zip, bucket])
136 run([GSUTIL, 'cp', md5_zip_file, bucket + '.md5sum'])
137 run([GSUTIL, 'setacl', 'public-read', bucket])
138 run([GSUTIL, 'setacl', 'public-read', bucket + '.md5sum'])
139
140 def download_from_new_location(channel, config, destination):
141 namer = bot_utils.GCSNamer(channel,
142 bot_utils.ReleaseType.RAW)
143 bucket = namer.editor_zipfilepath(config['revision'], config['system'],
144 config['bits'])
145 run([GSUTIL, 'cp', bucket, destination])
146
147 def upload_to_new_location(channel, config, source_zip):
148 namer = bot_utils.GCSNamer(channel,
149 bot_utils.ReleaseType.SIGNED)
150 zipfilename = namer.editor_zipfilename(config['system'], config['bits'])
151 bucket = namer.editor_zipfilepath(config['revision'], config['system'],
152 config['bits'])
153
154 bot_utils.CreateChecksumFile(source_zip, mangled_filename=zipfilename)
155 md5_zip_file = source_zip + '.md5sum'
156
157 run([GSUTIL, 'cp', source_zip, bucket])
158 run([GSUTIL, 'cp', md5_zip_file, bucket + '.md5sum'])
159 run([GSUTIL, 'setacl', 'public-read', bucket])
160 run([GSUTIL, 'setacl', 'public-read', bucket + '.md5sum'])
161
162 def main():
163 if sys.platform != 'linux2':
164 print "This script was only tested on linux. Please run it on linux!"
165 sys.exit(1)
166
167 parser = GetOptionsParser()
168 (options, args) = parser.parse_args()
169
170 if not options.scratch_dir:
171 die("No scratch directory given.")
172 if not options.revision:
173 die("No revision given.")
174 if not options.prepare and not options.deploy:
175 die("No prepare/deploy parameter given.")
176 if options.prepare and options.deploy:
177 die("Can't have prepare and deploy parameters at the same time.")
178 if len(args) > 0:
179 die("Invalid additional arguments: %s." % args)
180
181 if options.channel:
182 assert options.channel in bot_utils.Channel.ALL_CHANNELS
183
184 global DRY_RUN
185 DRY_RUN = options.dry_run
186
187 downloads_dir = os.path.join(options.scratch_dir, 'downloads')
188 presign_dir = os.path.join(options.scratch_dir, 'presign')
189 postsign_dir = os.path.join(options.scratch_dir, 'postsign')
190 uploads_dir = os.path.join(options.scratch_dir, 'uploads')
191
192 if options.prepare:
193 # Clean all directories
194 clean_directory(downloads_dir)
195 clean_directory(presign_dir)
196 clean_directory(postsign_dir)
197 clean_directory(uploads_dir)
198 elif options.deploy:
199 clean_directory(uploads_dir)
200
201 # These are the locations where we can find the *.app folders and *.exe files
202 # and the names we use inside the scratch directory.
203 locations = {
204 'macos' : {
205 'editor' : os.path.join('dart', 'DartEditor.app'),
206 'chrome' : os.path.join('dart', 'chromium', 'Chromium.app'),
207 'content_shell' : os.path.join('dart', 'chromium',
208 'Content Shell.app'),
209
210 'editor_scratch' : 'DartEditor%(bits)s.app',
211 'chrome_scratch' : 'Chromium%(bits)s.app',
212 'content_shell_scratch' : 'ContentShell%(bits)s.app',
213
214 'zip' : True,
215 },
216 'win32' : {
217 'editor' : os.path.join('dart', 'DartEditor.exe'),
218 'chrome' : os.path.join('dart', 'chromium', 'chrome.exe'),
219 'content_shell' : os.path.join('dart', 'chromium',
220 'content_shell.exe'),
221
222 'editor_scratch' : 'DartEditor%(bits)s.exe',
223 'chrome_scratch' : 'chromium%(bits)s.exe',
224 'content_shell_scratch' : 'content_shell%(bits)s.exe',
225
226 'zip' : False,
227 },
228 }
229
230 # Desitination of zip files we download
231 for system in ('macos', 'win32'):
232 for bits in ('32', '64'):
233 config = {
234 'revision' : options.revision,
235 'system' : system,
236 'bits' : bits,
237 }
238
239 destination = os.path.join(downloads_dir, FILENAME_PATTERN % config)
240 destination_dir = os.path.join(downloads_dir, BASENAME_PATTERN % config)
241
242 deploy = os.path.join(uploads_dir, FILENAME_PATTERN % config)
243 deploy_dir = os.path.join(uploads_dir, BASENAME_PATTERN % config)
244
245 if options.prepare:
246 # Download *.zip files from GCS buckets
ricow1 2013/10/14 13:23:46 I think all of this would be more readable if you
247 if options.channel:
248 download_from_new_location(options.channel, config, destination)
249 else:
250 download_from_old_location(config, destination)
251
252 run(['unzip', destination, '-d', destination_dir])
253
254 for name in ['editor', 'chrome', 'content_shell']:
255 from_path = os.path.join(destination_dir, locations[system][name])
256 to_path = os.path.join(
257 presign_dir, locations[system]['%s_scratch' % name] % config)
258
259 if locations[system]['zip']:
260 # We copy a .app directory directory and zip it
261 copy_and_zip(from_path, to_path)
262 else:
263 # We copy an .exe file
264 copy_file(from_path, to_path)
265 elif options.deploy:
266 copy_tree(destination_dir, deploy_dir)
267
268 for name in ['editor', 'chrome', 'content_shell']:
269 from_path = os.path.join(
270 postsign_dir, locations[system]['%s_scratch' % name] % config)
271 to_path = os.path.join(deploy_dir, locations[system][name])
272
273 if locations[system]['zip']:
274 # We unzip a zip file and copy the resulting signed .app directory
275 unzip_and_copy(from_path, to_path, postsign_dir)
276 else:
277 # We copy the signed .exe file
278 copy_file(from_path, to_path)
279
280 deploy_zip_file = os.path.abspath(deploy)
281 with ChangedWorkingDirectory(deploy_dir):
282 run(['zip', '-r9', deploy_zip_file, 'dart'])
283
284 # Upload *.zip/*.zip.md5sum and set 'public-read' ACL
285 if options.channel:
286 upload_to_new_location(options.channel, config, deploy_zip_file)
287 else:
288 upload_to_old_location(config, deploy_zip_file)
289
290 if __name__ == '__main__':
291 main()
292
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