Skip to content

Commit b35c64f

Browse files
committed
Using httplib instead of httplib2 to get GCE metadata.
Fixes #575.
1 parent bf93d46 commit b35c64f

File tree

2 files changed

+58
-39
lines changed

2 files changed

+58
-39
lines changed

gcloud/datastore/_implicit_environ.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
imply the current dataset ID and connection from the enviroment.
1919
"""
2020

21-
import httplib2
21+
import httplib
2222
import socket
2323

2424
try:
@@ -64,17 +64,20 @@ def compute_engine_id():
6464
:returns: Compute Engine project ID if the metadata service is available,
6565
else ``None``.
6666
"""
67-
http = httplib2.Http(timeout=0.1)
68-
uri = 'http://169.254.169.254/computeMetadata/v1/project/project-id'
67+
host = '169.254.169.254'
68+
uri_path = '/computeMetadata/v1/project/project-id'
6969
headers = {'Metadata-Flavor': 'Google'}
70+
connection = httplib.HTTPConnection(host, timeout=0.1)
7071

71-
response = content = None
72+
content = None
7273
try:
73-
response, content = http.request(uri, method='GET', headers=headers)
74-
except socket.timeout:
74+
connection.request('GET', uri_path, headers=headers)
75+
response = connection.getresponse()
76+
if response.status == 200:
77+
content = response.read()
78+
except socket.error: # socket.timeout or socket.error(64, 'Host is down')
7579
pass
76-
77-
if response is None or response['status'] != '200':
78-
return None
80+
finally:
81+
connection.close()
7982

8083
return content

gcloud/datastore/test___init__.py

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -109,37 +109,38 @@ def _implicit_compute_engine_helper(self, status):
109109
from gcloud.datastore import _implicit_environ
110110

111111
COMPUTE_ENGINE_ID = 'GCE'
112-
HTTPLIB2 = _Httplib2(COMPUTE_ENGINE_ID, status=status)
113-
if status == '200':
112+
HTTPLIB = _Httplib(COMPUTE_ENGINE_ID, status=status)
113+
if status == 200:
114114
EXPECTED_ID = COMPUTE_ENGINE_ID
115115
else:
116116
EXPECTED_ID = None
117117

118118
with self._monkey(None):
119-
with _Monkey(_implicit_environ, httplib2=HTTPLIB2):
119+
with _Monkey(_implicit_environ, httplib=HTTPLIB):
120120
self._callFUT()
121121

122122
self.assertEqual(_implicit_environ.DATASET_ID, EXPECTED_ID)
123-
self.assertEqual(len(HTTPLIB2._http_instances), 1)
123+
self.assertEqual(len(HTTPLIB._http_connections), 1)
124124

125-
(timeout, http_instance), = HTTPLIB2._http_instances
125+
(host, timeout, http_connection), = HTTPLIB._http_connections
126+
self.assertEqual(host, '169.254.169.254')
126127
self.assertEqual(timeout, 0.1)
127128
self.assertEqual(
128-
http_instance._called_uris,
129-
['http://169.254.169.254/computeMetadata/v1/project/project-id'])
129+
http_connection._called_args,
130+
[('GET', '/computeMetadata/v1/project/project-id')])
130131
expected_kwargs = {
131-
'method': 'GET',
132132
'headers': {
133133
'Metadata-Flavor': 'Google',
134134
},
135135
}
136-
self.assertEqual(http_instance._called_kwargs, [expected_kwargs])
136+
self.assertEqual(http_connection._called_kwargs, [expected_kwargs])
137+
self.assertEqual(http_connection._close_count, 1)
137138

138139
def test_set_implicit_from_compute_engine(self):
139-
self._implicit_compute_engine_helper('200')
140+
self._implicit_compute_engine_helper(200)
140141

141142
def test_set_implicit_from_compute_engine_bad_status(self):
142-
self._implicit_compute_engine_helper('404')
143+
self._implicit_compute_engine_helper(404)
143144

144145
def test_set_implicit_from_compute_engine_raise_timeout(self):
145146
self._implicit_compute_engine_helper('RAISE')
@@ -150,31 +151,31 @@ def test_set_implicit_both_appengine_and_compute(self):
150151

151152
APP_ENGINE_ID = 'GAE'
152153
APP_IDENTITY = _AppIdentity(APP_ENGINE_ID)
153-
HTTPLIB2 = _Httplib2('GCE')
154+
HTTPLIB = _Httplib('GCE')
154155

155156
with self._monkey(None):
156157
with _Monkey(_implicit_environ, app_identity=APP_IDENTITY,
157-
httplib2=HTTPLIB2):
158+
httplib=HTTPLIB):
158159
self._callFUT()
159160

160161
self.assertEqual(_implicit_environ.DATASET_ID, APP_ENGINE_ID)
161-
self.assertEqual(len(HTTPLIB2._http_instances), 0)
162+
self.assertEqual(len(HTTPLIB._http_connections), 0)
162163

163164
def test_set_implicit_three_env_appengine_and_compute(self):
164165
from gcloud._testing import _Monkey
165166
from gcloud.datastore import _implicit_environ
166167

167168
IMPLICIT_DATASET_ID = 'IMPLICIT'
168169
APP_IDENTITY = _AppIdentity('GAE')
169-
HTTPLIB2 = _Httplib2('GCE')
170+
HTTPLIB = _Httplib('GCE')
170171

171172
with self._monkey(IMPLICIT_DATASET_ID):
172173
with _Monkey(_implicit_environ, app_identity=APP_IDENTITY,
173-
httplib2=HTTPLIB2):
174+
httplib=HTTPLIB):
174175
self._callFUT()
175176

176177
self.assertEqual(_implicit_environ.DATASET_ID, IMPLICIT_DATASET_ID)
177-
self.assertEqual(len(HTTPLIB2._http_instances), 0)
178+
self.assertEqual(len(HTTPLIB._http_connections), 0)
178179

179180

180181
class Test_set_default_connection(unittest2.TestCase):
@@ -274,33 +275,48 @@ def get_application_id(self):
274275
return self.app_id
275276

276277

277-
class _Http(object):
278+
class _HTTPResponse(object):
279+
280+
def __init__(self, status, data):
281+
self.status = status
282+
self.data = data
283+
284+
def read(self):
285+
return self.data
286+
287+
288+
class _HTTPConnection(object):
278289

279290
def __init__(self, parent):
280291
self.parent = parent
281-
self._called_uris = []
292+
self._close_count = 0
293+
self._called_args = []
282294
self._called_kwargs = []
283295

284-
def request(self, uri, **kwargs):
285-
import socket
286-
287-
self._called_uris.append(uri)
296+
def request(self, method, uri, **kwargs):
297+
self._called_args.append((method, uri))
288298
self._called_kwargs.append(kwargs)
289299

300+
def getresponse(self):
301+
import socket
302+
290303
if self.parent.status == 'RAISE':
291304
raise socket.timeout('timed out')
292305
else:
293-
return {'status': self.parent.status}, self.parent.project_id
306+
return _HTTPResponse(self.parent.status, self.parent.project_id)
307+
308+
def close(self):
309+
self._close_count += 1
294310

295311

296-
class _Httplib2(object):
312+
class _Httplib(object):
297313

298-
def __init__(self, project_id, status='200'):
314+
def __init__(self, project_id, status=200):
299315
self.project_id = project_id
300316
self.status = status
301-
self._http_instances = []
317+
self._http_connections = []
302318

303-
def Http(self, timeout=None):
304-
result = _Http(self)
305-
self._http_instances.append((timeout, result))
319+
def HTTPConnection(self, host, timeout=None):
320+
result = _HTTPConnection(self)
321+
self._http_connections.append((host, timeout, result))
306322
return result

0 commit comments

Comments
 (0)