diff options
Diffstat (limited to 'boto/utils.py')
-rw-r--r-- | boto/utils.py | 49 |
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: |