@ -9,6 +9,7 @@ https://gerrit-review.googlesource.com/Documentation/rest-api.html
"""
import base64
import contextlib
import cookielib
import httplib
import json
@ -16,14 +17,17 @@ import logging
import netrc
import os
import re
import shutil
import socket
import stat
import sys
import tempfile
import time
import urllib
import urlparse
from cStringIO import StringIO
import gclient_utils
LOGGER = logging . getLogger ( )
TRY_LIMIT = 5
@ -34,21 +38,6 @@ TRY_LIMIT = 5
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 ) :
""" Exception class for errors commuicating with the gerrit-on-borg service. """
@ -129,27 +118,41 @@ class CookiesAuthenticator(Authenticator):
@classmethod
def _get_netrc ( cls ) :
# Buffer the '.netrc' path. Use an empty file if it doesn't exist.
path = cls . get_netrc_path ( )
if not os . path . exists ( path ) :
return safeNetrc ( os . devnull )
try :
return safeNetrc ( path )
except IOError :
print >> sys . stderr , ' WARNING: Could not read netrc file %s ' % path
return safeNetrc ( os . devnull )
except netrc . NetrcParseError :
content = ' '
if os . path . exists ( path ) :
st = os . stat ( path )
if st . st_mode & ( stat . S_IRWXG | stat . S_IRWXO ) :
print >> sys . stderr , (
' WARNING: netrc file %s cannot be used because its file '
' permissions are insecure. netrc file permissions should be '
' 600. ' % path )
else :
print >> sys . stderr , ( ' ERROR: Cannot use netrc file %s due to a '
' parsing error. ' % path )
raise
return safeNetrc ( os . devnull )
with open ( path ) as fd :
content = fd . read ( )
# Load the '.netrc' file. We strip comments from it because processing them
# 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
def get_gitcookies_path ( cls ) :
@ -749,3 +752,14 @@ def ResetReviewLabels(host, change, label, value='0', message=None,
elif jmsg [ 0 ] [ ' current_revision ' ] != revision :
raise GerritError ( 200 , ' While resetting labels on change " %s " , '
' 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 )