Skip to content

Commit f799b9a

Browse files
author
Jon Wayne Parrott
committed
Adding metadata sample
Change-Id: I9876e6badd5dfda2c142b153a9ec1c54ca5d4a79
1 parent fddf5e6 commit f799b9a

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

compute/metadata/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Compute Engine Metadata Samples
2+
3+
These samples demonstrate interacting with the Compute Engine metadata service. These samples must be run on Compute Engine.
4+
5+
<!-- auto-doc-link -->
6+
<!-- end-auto-doc-link -->

compute/metadata/main.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Example of using the Compute Engine API to watch for maintenance notices.
18+
19+
For more information, see the README.md under /compute.
20+
"""
21+
22+
# [START all]
23+
24+
import time
25+
26+
import requests
27+
28+
29+
METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/"
30+
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
31+
32+
33+
def wait_for_maintenance(callback):
34+
url = METADATA_URL + 'instance/maintenance-event'
35+
last_in_maintenance = False
36+
# [START hanging_get]
37+
last_etag = 0
38+
39+
while True:
40+
r = requests.get(
41+
url,
42+
params={'last_etag': last_etag},
43+
headers=METADATA_HEADERS)
44+
45+
# During maintenance the service can return a 503, so these should
46+
# be retried.
47+
if r.status_code == 503:
48+
time.sleep(1)
49+
continue
50+
# [END hanging_get]
51+
52+
last_etag = r.headers['etag']
53+
54+
if r.text == 'MIGRATE_ON_HOST_MAINTENANCE':
55+
in_maintenance = True
56+
else:
57+
in_maintenance = False
58+
59+
if in_maintenance != last_in_maintenance:
60+
last_in_maintenance = in_maintenance
61+
callback(in_maintenance)
62+
63+
64+
def maintenance_callback(status):
65+
if status:
66+
print('Undergoing host maintenance')
67+
else:
68+
print('Finished host maintenance')
69+
70+
71+
def main():
72+
wait_for_maintenance(maintenance_callback)
73+
74+
75+
if __name__ == '__main__':
76+
main()
77+
# [END all]

compute/metadata/main_test.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2016, Google, Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
import main
15+
import mock
16+
17+
18+
@mock.patch('main.requests')
19+
def test_wait_for_maintenance(requests_mock):
20+
# Response 1 is a host maintenance event.
21+
response1_mock = mock.Mock()
22+
response1_mock.status_code = 200
23+
response1_mock.text = 'MIGRATE_ON_HOST_MAINTENANCE'
24+
response1_mock.headers = {'etag': 1}
25+
# Response 2 is the end of the event.
26+
response2_mock = mock.Mock()
27+
response2_mock.status_code = 200
28+
response2_mock.text = 'NONE'
29+
response2_mock.headers = {'etag': 2}
30+
# Response 3 is a 503
31+
response3_mock = mock.Mock()
32+
response3_mock.status_code = 503
33+
34+
requests_mock.get.side_effect = [
35+
response1_mock, response2_mock, response3_mock, response2_mock,
36+
StopIteration()]
37+
38+
callback_mock = mock.Mock()
39+
40+
try:
41+
main.wait_for_maintenance(callback_mock)
42+
except StopIteration:
43+
pass
44+
45+
assert callback_mock.call_count == 2
46+
assert callback_mock.call_args_list[0][0] == (True,)
47+
assert callback_mock.call_args_list[1][0] == (False,)

compute/metadata/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests==2.9.1

0 commit comments

Comments
 (0)