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

Side by Side Diff: native_client_sdk/src/build_tools/sdk_tools/command/update.py

Issue 11228013: [NaCl SDK] Refactor sdk_update*. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix build_updater Created 8 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
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import download
6 import logging
7 import os
8 from sdk_update_common import Error
9 import sdk_update_common
10 import sys
11 import urlparse
12 import urllib2
13
14 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
15 PARENT_DIR = os.path.dirname(SCRIPT_DIR)
16 sys.path.append(PARENT_DIR)
17 try:
18 import cygtar
19 except ImportError:
20 # Try to find this in the Chromium repo.
21 CHROME_SRC_DIR = os.path.abspath(
22 os.path.join(PARENT_DIR, '..', '..', '..', '..'))
23 sys.path.append(os.path.join(CHROME_SRC_DIR, 'native_client', 'build'))
24 import cygtar
25
26
27 RECOMMENDED = 'recommended'
28 SDK_TOOLS = 'sdk_tools'
29 HTTP_CONTENT_LENGTH = 'Content-Length' # HTTP Header field for content length
30
31
32 class UpdateDelegate(object):
33 def BundleDirectoryExists(self, bundle_name):
34 raise NotImplementedError()
35
36 def DownloadToFile(self, url, dest_filename):
37 raise NotImplementedError()
38
39 def ExtractArchive(self, archive, extract_dir, rename_from_dir,
40 rename_to_dir):
41 raise NotImplementedError()
42
43
44 class RealUpdateDelegate(UpdateDelegate):
45 def __init__(self, user_data_dir, install_dir):
46 UpdateDelegate.__init__(self)
47 self.user_data_dir = user_data_dir
48 self.install_dir = install_dir
49
50 def BundleDirectoryExists(self, bundle_name):
51 bundle_path = os.path.join(self.install_dir, bundle_name)
52 return os.path.isdir(bundle_path)
53
54 def DownloadToFile(self, url, dest_filename):
55 sdk_update_common.MakeDirs(self.user_data_dir)
56 dest_path = os.path.join(self.user_data_dir, dest_filename)
57 out_stream = None
58 url_stream = None
59 try:
60 out_stream = open(dest_path, 'wb')
61 url_stream = download.UrlOpen(url)
62 content_length = int(url_stream.info()[HTTP_CONTENT_LENGTH])
63 progress = download.MakeProgressFunction(content_length)
64 sha1, size = download.DownloadAndComputeHash(url_stream, out_stream,
65 progress)
66 return sha1, size
67 except urllib2.URLError as e:
68 raise Error('Unable to read from URL "%s".\n %s' % (url, e))
69 except IOError as e:
70 raise Error('Unable to write to file "%s".\n %s' % (dest_filename, e))
71 finally:
72 if url_stream:
73 url_stream.close()
74 if out_stream:
75 out_stream.close()
76
77 def ExtractArchive(self, archive, extract_dir, rename_from_dir,
78 rename_to_dir):
79 tar_file = None
80
81 archive_path = os.path.join(self.user_data_dir, archive)
82 extract_path = os.path.join(self.install_dir, extract_dir)
83 rename_from_path = os.path.join(self.install_dir, rename_from_dir)
84 rename_to_path = os.path.join(self.install_dir, rename_to_dir)
85
86 # Extract to extract_dir, usually "<bundle name>_update".
87 # This way if the extraction fails, we haven't blown away the old bundle
88 # (if it exists).
89 sdk_update_common.RemoveDir(extract_path)
90 sdk_update_common.MakeDirs(extract_path)
91 curpath = os.getcwd()
92 tar_file = None
93
94 try:
95 try:
96 tar_file = cygtar.CygTar(archive_path, 'r', verbose=True)
97 except Exception as e:
98 raise Error('Can\'t open archive "%s".\n %s' % (archive_path, e))
99
100 try:
101 logging.info('Changing the directory to %s' % (extract_path,))
102 os.chdir(extract_path)
103 except Exception as e:
104 raise Error('Unable to chdir into "%s".\n %s' % (extract_path, e))
105
106 logging.info('Extracting to %s' % (extract_path,))
107 tar_file.Extract()
108
109 logging.info('Changing the directory to %s' % (curpath,))
110 os.chdir(curpath)
111
112 logging.info('Renaming %s->%s' % (rename_from_path, rename_to_path))
113 sdk_update_common.RenameDir(rename_from_path, rename_to_path)
114 finally:
115 # Change the directory back so we can remove the update directory.
116 os.chdir(curpath)
117
118 # Clean up the ..._update directory.
119 try:
120 sdk_update_common.RemoveDir(extract_path)
121 except Exception as e:
122 logging.error('Failed to remove directory \"%s\". %s' % (
123 extract_path, e))
124
125 if tar_file:
126 tar_file.Close()
127
128 # Remove the archive.
129 os.remove(archive_path)
130
131
132 def Update(delegate, remote_manifest, local_manifest, bundle_names, force):
133 valid_bundles = set([bundle.name for bundle in remote_manifest.GetBundles()])
134 requested_bundles = _GetRequestedBundlesFromArgs(remote_manifest,
135 bundle_names)
136 invalid_bundles = requested_bundles - valid_bundles
137 if invalid_bundles:
138 logging.warn('Ignoring unknown bundle(s): %s' % (
139 ', '.join(invalid_bundles)))
140 requested_bundles -= invalid_bundles
141
142 if SDK_TOOLS in requested_bundles:
143 logging.warn('Updating sdk_tools happens automatically. '
144 'Ignoring manual update request.')
145 requested_bundles.discard(SDK_TOOLS)
146
147 if requested_bundles:
148 for bundle_name in requested_bundles:
149 logging.info('Trying to update %s' % (bundle_name,))
150 UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
151 bundle_name, force)
152 else:
153 logging.warn('No bundles to update.')
154
155
156 def UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
157 bundle_name, force):
158 bundle = remote_manifest.GetBundle(bundle_name)
159 if bundle:
160 if _BundleNeedsUpdate(delegate, local_manifest, bundle):
161 _UpdateBundle(delegate, bundle, local_manifest, force)
162 else:
163 print '%s is already up-to-date.' % (bundle.name,)
164 else:
165 logging.error('Bundle %s does not exist.' % (bundle_name,))
166
167
168 def _GetRequestedBundlesFromArgs(remote_manifest, requested_bundles):
169 requested_bundles = set(requested_bundles)
170 if RECOMMENDED in requested_bundles:
171 requested_bundles.discard(RECOMMENDED)
172 requested_bundles |= set(_GetRecommendedBundles(remote_manifest))
173
174 return requested_bundles
175
176
177 def _GetRecommendedBundles(remote_manifest):
178 return [bundle for bundle in remote_manifest.GetBundles() if
179 bundle.recommended]
180
181
182 def _BundleNeedsUpdate(delegate, local_manifest, bundle):
183 # Always update the bundle if the directory doesn't exist;
184 # the user may have deleted it.
185 if not delegate.BundleDirectoryExists(bundle.name):
186 return True
187
188 return local_manifest.BundleNeedsUpdate(bundle)
189
190
191 def _UpdateBundle(delegate, bundle, local_manifest, force):
192 archive = bundle.GetHostOSArchive()
193 if not archive:
194 logging.warn('Bundle %s does not exist for this platform.' % (bundle.name,))
195 return
196
197 print 'Downloading bundle %s' % (bundle.name,)
198 dest_filename = _GetFilenameFromURL(archive.url)
199 sha1, size = delegate.DownloadToFile(archive.url, dest_filename)
200 _ValidateArchive(archive, sha1, size)
201
202 print 'Updating bundle %s to version %s, revision %s' % (
203 bundle.name, bundle.version, bundle.revision)
204 extract_dir = bundle.name + '_update'
205
206 repath_dir = bundle.get('repath', None)
207 if repath_dir:
208 # If repath is specified:
209 # The files are extracted to nacl_sdk/<bundle.name>_update/<repath>/...
210 # The destination directory is nacl_sdk/<repath>/...
211 rename_from_dir = os.path.join(extract_dir, repath_dir)
212 rename_to_dir = repath_dir
213 else:
214 # If no repath is specified:
215 # The files are extracted to nacl_sdk/<bundle.name>_update/...
216 # The destination directory is nacl_sdk/<bundle.name>/...
217 rename_from_dir = extract_dir
218 rename_to_dir = bundle.name
219
220 delegate.ExtractArchive(dest_filename, extract_dir, rename_from_dir,
221 rename_to_dir)
222
223 logging.info('Updating local manifest to include bundle %s' % (bundle.name))
224 local_manifest.MergeBundle(bundle)
225
226
227 def _GetFilenameFromURL(url):
228 _, _, path, _, _, _ = urlparse.urlparse(url)
229 return path.split('/')[-1]
230
231
232 def _ValidateArchive(archive, actual_sha1, actual_size):
233 if actual_sha1 != archive.GetChecksum():
234 raise Error('SHA1 checksum mismatch on "%s". Expected %s but got %s' % (
235 archive.name, archive.GetChecksum(), actual_sha1))
236 if actual_size != archive.size:
237 raise Error('Size mismatch on "%s". Expected %s but got %s bytes' % (
238 archive.name, archive.size, actual_size))
OLDNEW
« no previous file with comments | « native_client_sdk/src/build_tools/sdk_tools/command/sources.py ('k') | native_client_sdk/src/build_tools/sdk_tools/config.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698