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

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 die(msg, withOptions=True):
61 print msg
62 if withOptions:
63 GetOptionsParser().print_usage()
64 sys.exit(1)
65
66 def run(command):
67 """We use run() instead of builtin python methods, because not all
68 functionality can easily be done by python and we can support --dry-run"""
69
70 print "Running: ", command
71 if not DRY_RUN:
72 process = subprocess.Popen(command,
73 stdout=subprocess.PIPE,
74 stderr=subprocess.PIPE)
75 (stdout, stderr) = process.communicate()
76 if process.returncode != 0:
77 print "DEBUG: failed to run command '%s'" % command
78 print "DEBUG: stdout = ", stdout
79 print "DEBUG: stderr = ", stderr
80 print "DEBUG: returncode = ", process.returncode
81 raise OSError(process.returncode)
82
83 def clean_directory(directory):
84 if os.path.exists(directory):
85 run(['rm', '-r', directory])
86 run(['mkdir', '-p', directory])
87
88 def rm_tree(directory):
89 if os.path.exists(directory):
90 run(['rm', '-r', directory])
91
92 def copy_tree(from_dir, to_dir):
93 if os.path.exists(to_dir):
94 run(['rm', '-r', to_dir])
95 run(['cp', '-Rp', from_dir, to_dir])
96
97 def copy_file(from_file, to_file):
98 if os.path.exists(to_file):
99 run(['rm', to_file])
100 run(['cp', '-p', from_file, to_file])
101
102 def copy_and_zip(from_dir, to_dir):
103 rm_tree(to_dir)
104 copy_tree(from_dir, to_dir)
105
106 dirname = os.path.basename(to_dir)
107 with ChangedWorkingDirectory(os.path.dirname(to_dir)):
108 run(['zip', '-r9', dirname + '.zip', dirname])
109
110 def unzip_and_copy(extracted_zipfiledir, to_dir):
111 rm_tree(extracted_zipfiledir)
112 run(['unzip', extracted_zipfiledir + '.zip', '-d',
113 os.path.dirname(extracted_zipfiledir)])
114 rm_tree(to_dir)
115 copy_tree(extracted_zipfiledir, to_dir)
116
117 def download_from_old_location(config, destination):
118 bucket = BUCKET_PATTERN % config
119 run([GSUTIL, 'cp', bucket, destination])
120
121 def upload_to_old_location(config, source_zip):
122 if not DRY_RUN:
123 bot_utils.CreateChecksumFile(
124 source_zip, mangled_filename=os.path.basename(source_zip))
125 md5_zip_file = source_zip + '.md5sum'
126
127 bucket = BUCKET_PATTERN % config
128 run([GSUTIL, 'cp', source_zip, bucket])
129 run([GSUTIL, 'cp', md5_zip_file, bucket + '.md5sum'])
130 run([GSUTIL, 'setacl', 'public-read', bucket])
131 run([GSUTIL, 'setacl', 'public-read', bucket + '.md5sum'])
132
133 def download_from_new_location(channel, config, destination):
134 namer = bot_utils.GCSNamer(channel,
135 bot_utils.ReleaseType.RAW)
136 bucket = namer.editor_zipfilepath(config['revision'], config['system'],
137 config['bits'])
138 run([GSUTIL, 'cp', bucket, destination])
139
140 def upload_to_new_location(channel, config, source_zip):
141 namer = bot_utils.GCSNamer(channel,
142 bot_utils.ReleaseType.SIGNED)
143 zipfilename = namer.editor_zipfilename(config['system'], config['bits'])
144 bucket = namer.editor_zipfilepath(config['revision'], config['system'],
145 config['bits'])
146
147 if not DRY_RUN:
148 bot_utils.CreateChecksumFile(source_zip, mangled_filename=zipfilename)
149 md5_zip_file = source_zip + '.md5sum'
150
151 run([GSUTIL, 'cp', source_zip, bucket])
152 run([GSUTIL, 'cp', md5_zip_file, bucket + '.md5sum'])
153 run([GSUTIL, 'setacl', 'public-read', bucket])
154 run([GSUTIL, 'setacl', 'public-read', bucket + '.md5sum'])
155
156 def main():
157 if sys.platform != 'linux2':
158 print "This script was only tested on linux. Please run it on linux!"
159 sys.exit(1)
160
161 parser = GetOptionsParser()
162 (options, args) = parser.parse_args()
163
164 if not options.scratch_dir:
165 die("No scratch directory given.")
166 if not options.revision:
167 die("No revision given.")
168 if not options.prepare and not options.deploy:
169 die("No prepare/deploy parameter given.")
170 if options.prepare and options.deploy:
171 die("Can't have prepare and deploy parameters at the same time.")
172 if len(args) > 0:
173 die("Invalid additional arguments: %s." % args)
174
175 if options.channel:
176 assert options.channel in bot_utils.Channel.ALL_CHANNELS
177
178 global DRY_RUN
179 DRY_RUN = options.dry_run
180
181 downloads_dir = os.path.join(options.scratch_dir, 'downloads')
182 presign_dir = os.path.join(options.scratch_dir, 'presign')
183 postsign_dir = os.path.join(options.scratch_dir, 'postsign')
184 uploads_dir = os.path.join(options.scratch_dir, 'uploads')
185
186 if options.prepare:
187 # Clean all directories
188 clean_directory(downloads_dir)
189 clean_directory(presign_dir)
190 clean_directory(postsign_dir)
191 clean_directory(uploads_dir)
192 elif options.deploy:
193 clean_directory(uploads_dir)
194
195 # These are the locations where we can find the *.app folders and *.exe files
196 # and the names we use inside the scratch directory.
197 locations = {
198 'macos' : {
199 'editor' : os.path.join('dart', 'DartEditor.app'),
200 'chrome' : os.path.join('dart', 'chromium', 'Chromium.app'),
201 'content_shell' : os.path.join('dart', 'chromium',
202 'Content Shell.app'),
203
204 'editor_scratch' : 'DartEditor%(bits)s.app',
205 'chrome_scratch' : 'Chromium%(bits)s.app',
206 'content_shell_scratch' : 'ContentShell%(bits)s.app',
207
208 'zip' : True,
209 },
210 'win32' : {
211 'editor' : os.path.join('dart', 'DartEditor.exe'),
212 'chrome' : os.path.join('dart', 'chromium', 'chrome.exe'),
213 'content_shell' : os.path.join('dart', 'chromium',
214 'content_shell.exe'),
215
216 'editor_scratch' : 'DartEditor%(bits)s.exe',
217 'chrome_scratch' : 'chromium%(bits)s.exe',
218 'content_shell_scratch' : 'content_shell%(bits)s.exe',
219
220 'zip' : False,
221 },
222 }
223
224 # Desitination of zip files we download
225 for system in ('macos', 'win32'):
226 for bits in ('32', '64'):
227 config = {
228 'revision' : options.revision,
229 'system' : system,
230 'bits' : bits,
231 }
232
233 destination = os.path.join(downloads_dir, FILENAME_PATTERN % config)
234 destination_dir = os.path.join(downloads_dir, BASENAME_PATTERN % config)
235
236 deploy = os.path.join(uploads_dir, FILENAME_PATTERN % config)
237 deploy_dir = os.path.join(uploads_dir, BASENAME_PATTERN % config)
238
239 if options.prepare:
240 # Download *.zip files from GCS buckets
241 if options.channel:
242 download_from_new_location(options.channel, config, destination)
243 else:
244 download_from_old_location(config, destination)
245
246 run(['unzip', destination, '-d', destination_dir])
247
248 for name in ['editor', 'chrome', 'content_shell']:
249 from_path = os.path.join(destination_dir, locations[system][name])
250 to_path = os.path.join(
251 presign_dir, locations[system]['%s_scratch' % name] % config)
252
253 if locations[system]['zip']:
254 # We copy a .app directory directory and zip it
255 copy_and_zip(from_path, to_path)
256 else:
257 # We copy an .exe file
258 copy_file(from_path, to_path)
259 elif options.deploy:
260 copy_tree(destination_dir, deploy_dir)
261
262 for name in ['editor', 'chrome', 'content_shell']:
263 from_path = os.path.join(
264 postsign_dir, locations[system]['%s_scratch' % name] % config)
265 to_path = os.path.join(deploy_dir, locations[system][name])
266
267 if locations[system]['zip']:
268 # We unzip a zip file and copy the resulting signed .app directory
269 unzip_and_copy(from_path, to_path)
270 else:
271 # We copy the signed .exe file
272 copy_file(from_path, to_path)
273
274 deploy_zip_file = os.path.abspath(deploy)
275 with ChangedWorkingDirectory(deploy_dir):
276 run(['zip', '-r9', deploy_zip_file, 'dart'])
277
278 # Upload *.zip/*.zip.md5sum and set 'public-read' ACL
279 if options.channel:
280 upload_to_new_location(options.channel, config, deploy_zip_file)
281 else:
282 upload_to_old_location(config, deploy_zip_file)
283
284 if __name__ == '__main__':
285 main()
286
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