Set correct HTTP proxy when running gsutil
Gsutil disregards the environment variable http_proxy and only reads
proxy settings from the boto configuration file. This CL allows our GS
library to read http_proxy and then overrides the proxy settings when
running gsutil using '-o'.
BUG=chromium:318478
TEST=unittest, cros lint
Change-Id: I25dff79291fe46eb2852bdf16f25665896dec739
Reviewed-on: https://chromium-review.googlesource.com/179326
Reviewed-by: Yu-Ju Hong <yjhong@chromium.org>
Commit-Queue: Yu-Ju Hong <yjhong@chromium.org>
Tested-by: Yu-Ju Hong <yjhong@chromium.org>
diff --git a/lib/gs.py b/lib/gs.py
index 6d564fc..5e61495 100644
--- a/lib/gs.py
+++ b/lib/gs.py
@@ -177,7 +177,6 @@
GSUTIL_TAR = 'gsutil_3.37.tar.gz'
GSUTIL_URL = PUBLIC_BASE_HTTPS_URL + 'pub/%s' % GSUTIL_TAR
- GSUTIL_FLAGS = ['-o', 'GSUtil:parallel_composite_upload_threshold=0']
RESUMABLE_UPLOAD_ERROR = ('Too many resumable upload attempts failed without '
'progress')
@@ -239,6 +238,28 @@
self._CheckFile('gsutil not found', gsutil_bin)
self.gsutil_bin = gsutil_bin
+ # TODO (yjhong): disable parallel composite upload for now because
+ # it is not backward compatible (older gsutil versions cannot
+ # download files uploaded with this option enabled). Remove this
+ # after all users transition to newer versions (3.37 and above).
+ self.gsutil_flags = ['-o', 'GSUtil:parallel_composite_upload_threshold=0']
+
+ # Set HTTP proxy if environment variable http_proxy is set
+ # (crbug.com/325032).
+ if 'http_proxy' in os.environ:
+ url = urlparse.urlparse(os.environ['http_proxy'])
+ if not url.hostname or (not url.username and url.password):
+ logging.warning('GS_ERROR: Ignoring env variable http_proxy because it '
+ 'is not properly set: %s', os.environ['http_proxy'])
+ else:
+ self.gsutil_flags += ['-o', 'Boto:proxy=%s' % url.hostname]
+ if url.username:
+ self.gsutil_flags += ['-o', 'Boto:proxy_user=%s' % url.username]
+ if url.password:
+ self.gsutil_flags += ['-o', 'Boto:proxy_pass=%s' % url.password]
+ if url.port:
+ self.gsutil_flags += ['-o', 'Boto:proxy_port=%d' % url.port]
+
# Prefer boto_file if specified, else prefer the env then the default.
default_boto = False
if boto_file is None:
@@ -447,11 +468,7 @@
kwargs.setdefault('redirect_stderr', True)
cmd = [self.gsutil_bin]
- # TODO (yjhong): disable parallel composite upload for now because
- # it is not backward compatible (older gsutil versions cannot
- # download files uploaded with this option enbaled). Remove this
- # after all users transition to newer versions (3.37 above).
- cmd += self.GSUTIL_FLAGS
+ cmd += self.gsutil_flags
for header in headers:
cmd += ['-h', header]
cmd.extend(gsutil_cmd)
diff --git a/lib/gs_unittest.py b/lib/gs_unittest.py
index 3937f5f..7186087 100755
--- a/lib/gs_unittest.py
+++ b/lib/gs_unittest.py
@@ -215,6 +215,43 @@
self.assertEqual(gs.GSContext(acl=self.acl_file).acl,
self.acl_file)
+ def _testHTTPProxySettings(self, d):
+ flags = gs.GSContext().gsutil_flags
+ for key in d:
+ flag = 'Boto:%s=%s' % (key, d[key])
+ error_msg = '%s not in %s' % (flag, ' '.join(flags))
+ self.assertTrue(flag in flags, error_msg)
+
+ def testHTTPProxy(self):
+ """Test we set http proxy correctly."""
+ d = {'proxy': 'fooserver', 'proxy_user': 'foouser',
+ 'proxy_pass': 'foopasswd', 'proxy_port': '8080'}
+ os.environ['http_proxy'] = 'http://%s:%s@%s:%s/' % (
+ d['proxy_user'], d['proxy_pass'], d['proxy'], d['proxy_port'])
+ self._testHTTPProxySettings(d)
+
+ def testHTTPProxyNoPort(self):
+ """Test we accept http proxy without port number."""
+ d = {'proxy': 'fooserver', 'proxy_user': 'foouser',
+ 'proxy_pass': 'foopasswd'}
+ os.environ['http_proxy'] = 'http://%s:%s@%s/' % (
+ d['proxy_user'], d['proxy_pass'], d['proxy'])
+ self._testHTTPProxySettings(d)
+
+ def testHTTPProxyNoUserPasswd(self):
+ """Test we accept http proxy without user and password."""
+ d = {'proxy': 'fooserver', 'proxy_port': '8080'}
+ os.environ['http_proxy'] = 'http://%s:%s/' % (d['proxy'], d['proxy_port'])
+ self._testHTTPProxySettings(d)
+
+ def testHTTPProxyNoPasswd(self):
+ """Test we accept http proxy without password."""
+ d = {'proxy': 'fooserver', 'proxy_user': 'foouser',
+ 'proxy_port': '8080'}
+ os.environ['http_proxy'] = 'http://%s@%s:%s/' % (
+ d['proxy_user'], d['proxy'], d['proxy_port'])
+ self._testHTTPProxySettings(d)
+
class GSDoCommandTest(cros_test_lib.TestCase):
"""Tests of gs.DoCommand behavior.
@@ -233,7 +270,7 @@
def _testDoCommand(self, ctx, retries, sleep):
with mock.patch.object(cros_build_lib, 'GenericRetry', autospec=True):
ctx.Copy('/blah', 'gs://foon')
- cmd = [self.ctx.gsutil_bin] + self.ctx.GSUTIL_FLAGS
+ cmd = [self.ctx.gsutil_bin] + self.ctx.gsutil_flags
cmd += ['cp', '--', '/blah', 'gs://foon']
cros_build_lib.GenericRetry.assert_called_once_with(