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

Side by Side Diff: client/isolateserver.py

Issue 2484133002: luci-py/isolateserver.py: Add support for tar archives when downloading. (Closed) Base URL: https://github.com/luci/luci-py.git@master
Patch Set: Rebase onto master. Created 4 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
« no previous file with comments | « client/isolated_format.py ('k') | client/tests/archive.tar » ('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/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The LUCI Authors. All rights reserved. 2 # Copyright 2013 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 """Archives a set of files or directories to an Isolate Server.""" 6 """Archives a set of files or directories to an Isolate Server."""
7 7
8 __version__ = '0.6.0' 8 __version__ = '0.7.0'
9 9
10 import base64 10 import base64
11 import errno 11 import errno
12 import functools 12 import functools
13 import io 13 import io
14 import logging 14 import logging
15 import optparse 15 import optparse
16 import os 16 import os
17 import re 17 import re
18 import signal 18 import signal
19 import stat 19 import stat
20 import sys 20 import sys
21 import tarfile
21 import tempfile 22 import tempfile
22 import threading 23 import threading
23 import time 24 import time
24 import types 25 import types
25 import zlib 26 import zlib
26 27
27 from third_party import colorama 28 from third_party import colorama
28 from third_party.depot_tools import fix_encoding 29 from third_party.depot_tools import fix_encoding
29 from third_party.depot_tools import subcommand 30 from third_party.depot_tools import subcommand
30 31
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if name is None: 163 if name is None:
163 return 164 return
164 165
165 # If the file like object was created using something like open("test.txt") 166 # If the file like object was created using something like open("test.txt")
166 # name will end up being a str (such as a function outside our control, like 167 # name will end up being a str (such as a function outside our control, like
167 # the standard library). We want all our paths to be unicode objects, so we 168 # the standard library). We want all our paths to be unicode objects, so we
168 # decode it. 169 # decode it.
169 if not isinstance(name, unicode): 170 if not isinstance(name, unicode):
170 name = name.decode(sys.getfilesystemencoding()) 171 name = name.decode(sys.getfilesystemencoding())
171 172
173 # fs.exists requires an absolute path, otherwise it will fail with an
174 # assertion error.
175 if not os.path.isabs(name):
176 return
177
172 if fs.exists(name): 178 if fs.exists(name):
173 return name 179 return name
174 180
175 181
176 # TODO(tansell): Replace fileobj_copy with shutil.copyfileobj once proper file 182 # TODO(tansell): Replace fileobj_copy with shutil.copyfileobj once proper file
177 # wrappers have been created. 183 # wrappers have been created.
178 def fileobj_copy( 184 def fileobj_copy(
179 dstfileobj, srcfileobj, size=-1, 185 dstfileobj, srcfileobj, size=-1,
180 chunk_size=isolated_format.DISK_FILE_CHUNK): 186 chunk_size=isolated_format.DISK_FILE_CHUNK):
181 """Copy data from srcfileobj to dstfileobj. 187 """Copy data from srcfileobj to dstfileobj.
(...skipping 1918 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 2106
2101 if filetype == 'basic': 2107 if filetype == 'basic':
2102 file_mode = props.get('m') 2108 file_mode = props.get('m')
2103 if file_mode: 2109 if file_mode:
2104 # Ignore all bits apart from the user 2110 # Ignore all bits apart from the user
2105 file_mode &= 0700 2111 file_mode &= 0700
2106 putfile( 2112 putfile(
2107 srcfileobj, fullpath, file_mode, 2113 srcfileobj, fullpath, file_mode,
2108 use_symlink=use_symlinks) 2114 use_symlink=use_symlinks)
2109 2115
2116 elif filetype == 'tar':
2117 basedir = os.path.dirname(fullpath)
2118 with tarfile.TarFile(fileobj=srcfileobj) as extractor:
2119 for ti in extractor:
2120 if not ti.isfile():
2121 logging.warning(
2122 'Path(%r) is nonfile (%s), skipped',
2123 ti.name, ti.type)
2124 continue
2125 fp = os.path.normpath(os.path.join(basedir, ti.name))
2126 if not fp.startswith(basedir):
2127 logging.error(
2128 'Path(%r) is outside root directory',
2129 fp)
2130 ifd = extractor.extractfile(ti)
2131 file_path.ensure_tree(os.path.dirname(fp))
2132 putfile(ifd, fp, 0700, ti.size)
2133
2110 elif filetype == 'ar': 2134 elif filetype == 'ar':
2111 basedir = os.path.dirname(fullpath) 2135 basedir = os.path.dirname(fullpath)
2112 extractor = arfile.ArFileReader(srcfileobj, fullparse=False) 2136 extractor = arfile.ArFileReader(srcfileobj, fullparse=False)
2113 for ai, ifd in extractor: 2137 for ai, ifd in extractor:
2114 fp = os.path.normpath(os.path.join(basedir, ai.name)) 2138 fp = os.path.normpath(os.path.join(basedir, ai.name))
2139 if not fp.startswith(basedir):
2140 logging.error(
2141 'Path(%r) is outside root directory',
2142 fp)
2115 file_path.ensure_tree(os.path.dirname(fp)) 2143 file_path.ensure_tree(os.path.dirname(fp))
2116 putfile(ifd, fp, 0700, ai.size) 2144 putfile(ifd, fp, 0700, ai.size)
2117 2145
2118 else: 2146 else:
2119 raise isolated_format.IsolatedError( 2147 raise isolated_format.IsolatedError(
2120 'Unknown file type %r', filetype) 2148 'Unknown file type %r', filetype)
2121 2149
2122 # Report progress. 2150 # Report progress.
2123 duration = time.time() - last_update 2151 duration = time.time() - last_update
2124 if duration > DELAY_BETWEEN_UPDATES_IN_SECS: 2152 if duration > DELAY_BETWEEN_UPDATES_IN_SECS:
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 return dispatcher.execute(OptionParserIsolateServer(), args) 2484 return dispatcher.execute(OptionParserIsolateServer(), args)
2457 2485
2458 2486
2459 if __name__ == '__main__': 2487 if __name__ == '__main__':
2460 subprocess42.inhibit_os_error_reporting() 2488 subprocess42.inhibit_os_error_reporting()
2461 fix_encoding.fix_encoding() 2489 fix_encoding.fix_encoding()
2462 tools.disable_buffering() 2490 tools.disable_buffering()
2463 colorama.init() 2491 colorama.init()
2464 file_path.enable_symlink() 2492 file_path.enable_symlink()
2465 sys.exit(main(sys.argv[1:])) 2493 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « client/isolated_format.py ('k') | client/tests/archive.tar » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698