Strip netrc hack, rewrite file.

Strip the netrc hack; apparently it only works on some versions of
Python, and the bots have many different versions.

Instead, we will actually emit the modified netrc as a new file without
comments or newlines, then read that directly from the vanilla netrc
module.

BUG=chromium:664664
TEST=None

Change-Id: I245759e2eae4e6ddcdffa0aaef59866a62bd0240
Reviewed-on: https://chromium-review.googlesource.com/411416
Commit-Queue: Daniel Jacques <dnj@chromium.org>
Reviewed-by: Ryan Tseng <hinoka@chromium.org>
Reviewed-by: Michael Moss <mmoss@chromium.org>
changes/16/411416/9
Dan Jacques 9 years ago committed by Commit Bot
parent 1d949fd373
commit 8d11e482fe

@ -9,6 +9,7 @@ https://gerrit-review.googlesource.com/Documentation/rest-api.html
""" """
import base64 import base64
import contextlib
import cookielib import cookielib
import httplib import httplib
import json import json
@ -16,14 +17,17 @@ import logging
import netrc import netrc
import os import os
import re import re
import shutil
import socket import socket
import stat import stat
import sys import sys
import tempfile
import time import time
import urllib import urllib
import urlparse import urlparse
from cStringIO import StringIO from cStringIO import StringIO
import gclient_utils
LOGGER = logging.getLogger() LOGGER = logging.getLogger()
TRY_LIMIT = 5 TRY_LIMIT = 5
@ -34,21 +38,6 @@ TRY_LIMIT = 5
GERRIT_PROTOCOL = 'https' GERRIT_PROTOCOL = 'https'
# Processing comments in "netrc" can trigger a bug in Windows.
# See crbug.com/664664
class safeNetrc(netrc.netrc):
# pylint: disable=redefined-builtin
def __init__(self, file=None):
self._orig_parse, self._parse = self._parse, self._safe_parse
netrc.netrc.__init__(self, file=file)
# pylint: disable=redefined-builtin
def _safe_parse(self, file, fp, default_netrc):
# Buffer the file.
sio = StringIO(''.join(l for l in fp
if l.strip() and not l.strip().startswith('#')))
return self._orig_parse(file, sio, default_netrc)
class GerritError(Exception): class GerritError(Exception):
"""Exception class for errors commuicating with the gerrit-on-borg service.""" """Exception class for errors commuicating with the gerrit-on-borg service."""
@ -129,27 +118,41 @@ class CookiesAuthenticator(Authenticator):
@classmethod @classmethod
def _get_netrc(cls): def _get_netrc(cls):
# Buffer the '.netrc' path. Use an empty file if it doesn't exist.
path = cls.get_netrc_path() path = cls.get_netrc_path()
if not os.path.exists(path): content = ''
return safeNetrc(os.devnull) if os.path.exists(path):
try:
return safeNetrc(path)
except IOError:
print >> sys.stderr, 'WARNING: Could not read netrc file %s' % path
return safeNetrc(os.devnull)
except netrc.NetrcParseError:
st = os.stat(path) st = os.stat(path)
if st.st_mode & (stat.S_IRWXG | stat.S_IRWXO): if st.st_mode & (stat.S_IRWXG | stat.S_IRWXO):
print >> sys.stderr, ( print >> sys.stderr, (
'WARNING: netrc file %s cannot be used because its file ' 'WARNING: netrc file %s cannot be used because its file '
'permissions are insecure. netrc file permissions should be ' 'permissions are insecure. netrc file permissions should be '
'600.' % path) '600.' % path)
else: with open(path) as fd:
print >> sys.stderr, ('ERROR: Cannot use netrc file %s due to a ' content = fd.read()
'parsing error.' % path)
raise # Load the '.netrc' file. We strip comments from it because processing them
return safeNetrc(os.devnull) # can trigger a bug in Windows. See crbug.com/664664.
content = '\n'.join(l for l in content.splitlines()
if l.strip() and not l.strip().startswith('#'))
with tempdir() as tdir:
netrc_path = os.path.join(tdir, 'netrc')
with open(netrc_path, 'w') as fd:
fd.write(content)
os.chmod(netrc_path, (stat.S_IRUSR | stat.S_IWUSR))
return cls._get_netrc_from_path(netrc_path)
@classmethod
def _get_netrc_from_path(cls, path):
try:
return netrc.netrc(path)
except IOError:
print >> sys.stderr, 'WARNING: Could not read netrc file %s' % path
return netrc.netrc(os.devnull)
except netrc.NetrcParseError as e:
print >> sys.stderr, ('ERROR: Cannot use netrc file %s due to a '
'parsing error: %s' % (path, e))
return netrc.netrc(os.devnull)
@classmethod @classmethod
def get_gitcookies_path(cls): def get_gitcookies_path(cls):
@ -749,3 +752,14 @@ def ResetReviewLabels(host, change, label, value='0', message=None,
elif jmsg[0]['current_revision'] != revision: elif jmsg[0]['current_revision'] != revision:
raise GerritError(200, 'While resetting labels on change "%s", ' raise GerritError(200, 'While resetting labels on change "%s", '
'a new patchset was uploaded.' % change) 'a new patchset was uploaded.' % change)
@contextlib.contextmanager
def tempdir():
tdir = None
try:
tdir = tempfile.mkdtemp(suffix='gerrit_util')
yield tdir
finally:
if tdir:
gclient_utils.rmtree(tdir)

Loading…
Cancel
Save