| OLD | NEW |
| 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 by the Apache v2.0 license that can be | 3 # Use of this source code is governed by the Apache v2.0 license that can be |
| 4 # found in the LICENSE file. | 4 # 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.4.7' | 8 __version__ = '0.4.8' |
| 9 | 9 |
| 10 import base64 | 10 import base64 |
| 11 import functools | 11 import functools |
| 12 import logging | 12 import logging |
| 13 import optparse | 13 import optparse |
| 14 import os | 14 import os |
| 15 import re | 15 import re |
| 16 import signal | 16 import signal |
| 17 import sys | 17 import sys |
| 18 import tempfile | 18 import tempfile |
| (...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2075 is uploaded. Then this .isolated file can be included in another one to run | 2075 is uploaded. Then this .isolated file can be included in another one to run |
| 2076 commands. | 2076 commands. |
| 2077 | 2077 |
| 2078 The commands output each file that was processed with its content hash. For | 2078 The commands output each file that was processed with its content hash. For |
| 2079 directories, the .isolated generated for the directory is listed as the | 2079 directories, the .isolated generated for the directory is listed as the |
| 2080 directory entry itself. | 2080 directory entry itself. |
| 2081 """ | 2081 """ |
| 2082 add_isolate_server_options(parser) | 2082 add_isolate_server_options(parser) |
| 2083 add_archive_options(parser) | 2083 add_archive_options(parser) |
| 2084 options, files = parser.parse_args(args) | 2084 options, files = parser.parse_args(args) |
| 2085 process_isolate_server_options(parser, options, True) | 2085 process_isolate_server_options(parser, options, True, True) |
| 2086 try: | 2086 try: |
| 2087 archive(options.isolate_server, options.namespace, files, options.blacklist) | 2087 archive(options.isolate_server, options.namespace, files, options.blacklist) |
| 2088 except Error as e: | 2088 except Error as e: |
| 2089 parser.error(e.args[0]) | 2089 parser.error(e.args[0]) |
| 2090 return 0 | 2090 return 0 |
| 2091 | 2091 |
| 2092 | 2092 |
| 2093 def CMDdownload(parser, args): | 2093 def CMDdownload(parser, args): |
| 2094 """Download data from the server. | 2094 """Download data from the server. |
| 2095 | 2095 |
| 2096 It can either download individual files or a complete tree from a .isolated | 2096 It can either download individual files or a complete tree from a .isolated |
| 2097 file. | 2097 file. |
| 2098 """ | 2098 """ |
| 2099 add_isolate_server_options(parser) | 2099 add_isolate_server_options(parser) |
| 2100 parser.add_option( | 2100 parser.add_option( |
| 2101 '-s', '--isolated', metavar='HASH', | 2101 '-s', '--isolated', metavar='HASH', |
| 2102 help='hash of an isolated file, .isolated file content is discarded, use ' | 2102 help='hash of an isolated file, .isolated file content is discarded, use ' |
| 2103 '--file if you need it') | 2103 '--file if you need it') |
| 2104 parser.add_option( | 2104 parser.add_option( |
| 2105 '-f', '--file', metavar='HASH DEST', default=[], action='append', nargs=2, | 2105 '-f', '--file', metavar='HASH DEST', default=[], action='append', nargs=2, |
| 2106 help='hash and destination of a file, can be used multiple times') | 2106 help='hash and destination of a file, can be used multiple times') |
| 2107 parser.add_option( | 2107 parser.add_option( |
| 2108 '-t', '--target', metavar='DIR', default='download', | 2108 '-t', '--target', metavar='DIR', default='download', |
| 2109 help='destination directory') | 2109 help='destination directory') |
| 2110 add_cache_options(parser) | 2110 add_cache_options(parser) |
| 2111 options, args = parser.parse_args(args) | 2111 options, args = parser.parse_args(args) |
| 2112 if args: | 2112 if args: |
| 2113 parser.error('Unsupported arguments: %s' % args) | 2113 parser.error('Unsupported arguments: %s' % args) |
| 2114 | 2114 |
| 2115 process_isolate_server_options(parser, options, True) | 2115 process_isolate_server_options(parser, options, True, True) |
| 2116 if bool(options.isolated) == bool(options.file): | 2116 if bool(options.isolated) == bool(options.file): |
| 2117 parser.error('Use one of --isolated or --file, and only one.') | 2117 parser.error('Use one of --isolated or --file, and only one.') |
| 2118 | 2118 |
| 2119 cache = process_cache_options(options) | 2119 cache = process_cache_options(options) |
| 2120 options.target = unicode(os.path.abspath(options.target)) | 2120 options.target = unicode(os.path.abspath(options.target)) |
| 2121 if options.isolated: | 2121 if options.isolated: |
| 2122 if (fs.isfile(options.target) or | 2122 if (fs.isfile(options.target) or |
| 2123 (fs.isdir(options.target) and fs.listdir(options.target))): | 2123 (fs.isdir(options.target) and fs.listdir(options.target))): |
| 2124 parser.error( | 2124 parser.error( |
| 2125 '--target \'%s\' exists, please use another target' % options.target) | 2125 '--target \'%s\' exists, please use another target' % options.target) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2173 '-I', '--isolate-server', | 2173 '-I', '--isolate-server', |
| 2174 metavar='URL', default=os.environ.get('ISOLATE_SERVER', ''), | 2174 metavar='URL', default=os.environ.get('ISOLATE_SERVER', ''), |
| 2175 help='URL of the Isolate Server to use. Defaults to the environment ' | 2175 help='URL of the Isolate Server to use. Defaults to the environment ' |
| 2176 'variable ISOLATE_SERVER if set. No need to specify https://, this ' | 2176 'variable ISOLATE_SERVER if set. No need to specify https://, this ' |
| 2177 'is assumed.') | 2177 'is assumed.') |
| 2178 parser.add_option( | 2178 parser.add_option( |
| 2179 '--namespace', default='default-gzip', | 2179 '--namespace', default='default-gzip', |
| 2180 help='The namespace to use on the Isolate Server, default: %default') | 2180 help='The namespace to use on the Isolate Server, default: %default') |
| 2181 | 2181 |
| 2182 | 2182 |
| 2183 def process_isolate_server_options(parser, options, set_exception_handler): | 2183 def process_isolate_server_options( |
| 2184 """Processes the --isolate-server option and aborts if not specified. | 2184 parser, options, set_exception_handler, required): |
| 2185 """Processes the --isolate-server option. |
| 2185 | 2186 |
| 2186 Returns the identity as determined by the server. | 2187 Returns the identity as determined by the server. |
| 2187 """ | 2188 """ |
| 2188 if not options.isolate_server: | 2189 if not options.isolate_server: |
| 2189 parser.error('--isolate-server is required.') | 2190 if required: |
| 2191 parser.error('--isolate-server is required.') |
| 2192 return |
| 2193 |
| 2190 try: | 2194 try: |
| 2191 options.isolate_server = net.fix_url(options.isolate_server) | 2195 options.isolate_server = net.fix_url(options.isolate_server) |
| 2192 except ValueError as e: | 2196 except ValueError as e: |
| 2193 parser.error('--isolate-server %s' % e) | 2197 parser.error('--isolate-server %s' % e) |
| 2194 if set_exception_handler: | 2198 if set_exception_handler: |
| 2195 on_error.report_on_exception_exit(options.isolate_server) | 2199 on_error.report_on_exception_exit(options.isolate_server) |
| 2196 try: | 2200 try: |
| 2197 return auth.ensure_logged_in(options.isolate_server) | 2201 return auth.ensure_logged_in(options.isolate_server) |
| 2198 except ValueError as e: | 2202 except ValueError as e: |
| 2199 parser.error(str(e)) | 2203 parser.error(str(e)) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2261 def main(args): | 2265 def main(args): |
| 2262 dispatcher = subcommand.CommandDispatcher(__name__) | 2266 dispatcher = subcommand.CommandDispatcher(__name__) |
| 2263 return dispatcher.execute(OptionParserIsolateServer(), args) | 2267 return dispatcher.execute(OptionParserIsolateServer(), args) |
| 2264 | 2268 |
| 2265 | 2269 |
| 2266 if __name__ == '__main__': | 2270 if __name__ == '__main__': |
| 2267 fix_encoding.fix_encoding() | 2271 fix_encoding.fix_encoding() |
| 2268 tools.disable_buffering() | 2272 tools.disable_buffering() |
| 2269 colorama.init() | 2273 colorama.init() |
| 2270 sys.exit(main(sys.argv[1:])) | 2274 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |