summaryrefslogtreecommitdiff
path: root/boto/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'boto/utils.py')
-rw-r--r--boto/utils.py49
1 files changed, 34 insertions, 15 deletions
diff --git a/boto/utils.py b/boto/utils.py
index d1f88b6c..e5c083f3 100644
--- a/boto/utils.py
+++ b/boto/utils.py
@@ -90,7 +90,9 @@ qsa_of_interest = ['acl', 'cors', 'defaultObjectAcl', 'location', 'logging',
# GET bucket?storageClass is not part of the S3 API.)
'storageClass',
# websiteConfig is a QSA for buckets in Google Cloud Storage.
- 'websiteConfig']
+ 'websiteConfig',
+ # compose is a QSA for objects in Google Cloud Storage.
+ 'compose']
_first_cap_regex = re.compile('(.)([A-Z][a-z]+)')
@@ -208,8 +210,7 @@ def retry_url(url, retry_on_404=True, num_retries=10):
req = urllib2.Request(url)
r = opener.open(req)
result = r.read()
- resp = urllib2.urlopen(req)
- return resp.read()
+ return result
except urllib2.HTTPError, e:
# in 2.6 you use getcode(), in 2.5 and earlier you use code
if hasattr(e, 'getcode'):
@@ -218,12 +219,12 @@ def retry_url(url, retry_on_404=True, num_retries=10):
code = e.code
if code == 404 and not retry_on_404:
return ''
- except urllib2.URLError, e:
- raise e
except Exception, e:
pass
boto.log.exception('Caught exception reading instance data')
- time.sleep(2 ** i)
+ # If not on the last iteration of the loop then sleep.
+ if i + 1 != num_retries:
+ time.sleep(2 ** i)
boto.log.error('Unable to read instance data, giving up')
return ''
@@ -310,8 +311,23 @@ class LazyLoadMetadata(dict):
return super(LazyLoadMetadata, self).__repr__()
+def _build_instance_metadata_url(url, version, path):
+ """
+ Builds an EC2 metadata URL for fetching information about an instance.
+
+ Requires the following arguments: a URL, a version and a path.
+
+ Example:
+
+ >>> _build_instance_metadata_url('http://169.254.169.254', 'latest', 'meta-data')
+ http://169.254.169.254/latest/meta-data/
+
+ """
+ return '%s/%s/%s/' % (url, version, path)
+
+
def get_instance_metadata(version='latest', url='http://169.254.169.254',
- timeout=None, num_retries=5):
+ data='meta-data', timeout=None, num_retries=5):
"""
Returns the instance metadata as a nested Python dictionary.
Simple values (e.g. local_hostname, hostname, etc.) will be
@@ -327,8 +343,8 @@ def get_instance_metadata(version='latest', url='http://169.254.169.254',
original = socket.getdefaulttimeout()
socket.setdefaulttimeout(timeout)
try:
- return _get_instance_metadata('%s/%s/meta-data/' % (url, version),
- num_retries=num_retries)
+ metadata_url = _build_instance_metadata_url(url, version, data)
+ return _get_instance_metadata(metadata_url, num_retries=num_retries)
except urllib2.URLError, e:
return None
finally:
@@ -342,7 +358,7 @@ def get_instance_identity(version='latest', url='http://169.254.169.254',
Returns the instance identity as a nested Python dictionary.
"""
iid = {}
- base_url = 'http://169.254.169.254/latest/dynamic/instance-identity'
+ base_url = _build_instance_metadata_url(url, version, 'dynamic/instance-identity')
if timeout is not None:
original = socket.getdefaulttimeout()
socket.setdefaulttimeout(timeout)
@@ -365,7 +381,7 @@ def get_instance_identity(version='latest', url='http://169.254.169.254',
def get_instance_userdata(version='latest', sep=None,
url='http://169.254.169.254'):
- ud_url = '%s/%s/user-data' % (url, version)
+ ud_url = _build_instance_metadata_url(url, version, 'user-data')
user_data = retry_url(ud_url, retry_on_404=False)
if user_data:
if sep:
@@ -378,7 +394,7 @@ def get_instance_userdata(version='latest', sep=None,
ISO8601 = '%Y-%m-%dT%H:%M:%SZ'
ISO8601_MS = '%Y-%m-%dT%H:%M:%S.%fZ'
-
+RFC1123 = '%a, %d %b %Y %H:%M:%S %Z'
def get_ts(ts=None):
if not ts:
@@ -392,9 +408,12 @@ def parse_ts(ts):
dt = datetime.datetime.strptime(ts, ISO8601)
return dt
except ValueError:
- dt = datetime.datetime.strptime(ts, ISO8601_MS)
- return dt
-
+ try:
+ dt = datetime.datetime.strptime(ts, ISO8601_MS)
+ return dt
+ except ValueError:
+ dt = datetime.datetime.strptime(ts, RFC1123)
+ return dt
def find_class(module_name, class_name=None):
if class_name: