You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by jb...@apache.org on 2013/07/24 00:04:59 UTC
git commit: updated refs/heads/master to 529ac6f
Updated Branches:
refs/heads/master 9fb71c30a -> 529ac6f12
- CLOUDSTACK-2583: Backports the s3xen plugin to Python 2.4
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/529ac6f1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/529ac6f1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/529ac6f1
Branch: refs/heads/master
Commit: 529ac6f12991370f9a5324b3b40f72b2f0601746
Parents: 9fb71c3
Author: John Burwell <jb...@apache.org>
Authored: Tue Jul 23 18:02:49 2013 -0400
Committer: John Burwell <jb...@apache.org>
Committed: Tue Jul 23 18:02:49 2013 -0400
----------------------------------------------------------------------
scripts/vm/hypervisor/xenserver/s3xen | 147 +++++++++++++++++++----------
1 file changed, 98 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/529ac6f1/scripts/vm/hypervisor/xenserver/s3xen
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/s3xen b/scripts/vm/hypervisor/xenserver/s3xen
index 4d9c12d..9cbe238 100644
--- a/scripts/vm/hypervisor/xenserver/s3xen
+++ b/scripts/vm/hypervisor/xenserver/s3xen
@@ -18,18 +18,18 @@
# Version @VERSION@
#
-# A plugin for executing script needed by cloud stack
-from __future__ import with_statement
-
+# A plugin for executing script needed by CloudStack
from copy import copy
from datetime import datetime
from httplib import *
from string import join
+from string import split
import os
import sys
import time
-import hashlib
+import md5 as md5mod
+import sha
import base64
import hmac
import traceback
@@ -42,35 +42,56 @@ import util
NULL = 'null'
# Value conversion utility functions ...
-
-
def to_none(value):
- return value if value is not None and value.strip() != NULL else None
+ if value is None:
+ return None
+ if isinstance(value, basestring) and value.strip().lower() == NULL:
+ return None
+ return value
def to_bool(value):
- return True if to_none(value) in ['true', 'True', None] else False
+
+ if to_none(value) is None:
+ return False
+ if isinstance(value, basestring) and value.strip().lower() == 'true':
+ return True
+ if isinstance(value, int) and value == True:
+ return True
+ return False
def to_integer(value, default):
- return int(value) if to_none(value) is not None else default
+ if to_none(value) is None or not isinstance(value, int):
+ return default
+ return int(value)
def optional_str_value(value, default):
- return value if is_not_blank(value) else default
+ if is_not_blank(value):
+ return value
+ return default
def is_not_blank(value):
- return True if to_none(value) is not None and value.strip != '' else False
+
+ if to_none(value) is None or not isinstance(value, basestring):
+ return True
+ if value.strip == '':
+ return False
+ return True
def get_optional_key(map, key, default=''):
- return map[key] if key in map else default
+
+ if key in map:
+ return map[key]
+ return default
def log(message):
- util.SMlog('#### VMOPS %s ####' % message)
+ util.SMlog('#### VMOPS %s ####' % message)
def echo(fn):
def wrapped(*v, **k):
@@ -94,8 +115,7 @@ def retry(max_attempts, fn):
attempts = 1
while attempts <= max_attempts:
- log("Attempting execution {0}/{1} of {2}".
- format(attempts, max_attempts, fn.__name__))
+ log("Attempting execution " + str(attempts) + "/" + str(max_attempts) + " of " + fn.__name__)
try:
return fn()
except:
@@ -106,15 +126,21 @@ def retry(max_attempts, fn):
def compute_md5(filename, buffer_size=8192):
- hasher = hashlib.md5()
+ hasher = md5mod.md5()
+
+ file = open(filename, 'rb')
+ try:
- with open(filename, 'rb') as file:
- data = file.read(buffer_size)
- while data != "":
- hasher.update(data)
- data = file.read(buffer_size)
+ data = file.read(buffer_size)
+ while data != "":
+ hasher.update(data)
+ data = file.read(buffer_size)
- return base64.encodestring(hasher.digest())[:-1]
+ return base64.encodestring(hasher.digest())[:-1]
+
+ finally:
+
+ file.close()
class S3Client(object):
@@ -146,10 +172,9 @@ class S3Client(object):
max_error_retry, self.DEFAULT_MAX_ERROR_RETRY)
def build_canocialized_resource(self, bucket, key):
+ return "/" + join([bucket, key], '/')
- return '/{bucket}/{key}'.format(bucket=bucket, key=key)
-
- def noop_send_body():
+ def noop_send_body(connection):
pass
def noop_read(response):
@@ -164,28 +189,37 @@ class S3Client(object):
uri = self.build_canocialized_resource(bucket, key)
signature, request_date = self.sign_request(method, uri, headers)
- headers['Authorization'] = "AWS {0}:{1}".format(
- self.access_key, signature)
+ headers['Authorization'] = "AWS " + self.access_key + ":" + signature
headers['Date'] = request_date
- connection = HTTPSConnection(self.end_point) \
- if self.https_flag else HTTPConnection(self.end_point)
- connection.timeout = self.socket_timeout
-
def perform_request():
+ print "method=", method, ", uri=", uri, ", headers=", headers, " endpoint=", self.end_point
- connection.request(method, uri, fn_send_body(), headers)
- response = connection.getresponse()
- log("Sent {0} request to {1} {2} with headers {3}. \
- Got response status {4}: {5}".
- format(method, self.end_point, uri, headers,
- response.status, response.reason))
- return fn_read(response)
+ connection = None
+ if self.https_flag:
+ connection = HTTPSConnection(self.end_point)
+ else:
+ connection = HTTPConnection(self.end_point)
+
+ try:
+ connection.timeout = self.socket_timeout
+ connection.putrequest(method, uri)
+
+ for k,v in headers.items():
+ connection.putheader(k,v)
+ connection.endheaders()
+
+ fn_send_body(connection)
+
+ response = connection.getresponse()
+ log("Sent " + method + " request to " + self.end_point + "/" + uri + " with headers " + str(headers) + ". Received response status " + str(response.status) + ": " + response.reason)
+ return fn_read(response)
+
+ finally:
+ connection.close()
+
+ return retry(self.max_error_retry, perform_request)
- try:
- return retry(self.max_error_retry, perform_request)
- finally:
- connection.close()
'''
See http://bit.ly/MMC5de for more information regarding the creation of
@@ -205,7 +239,7 @@ class S3Client(object):
signature = base64.encodestring(
hmac.new(self.secret_key, string_to_sign.encode('utf8'),
- hashlib.sha1).digest())[:-1]
+ sha).digest())[:-1]
return signature, request_date
@@ -217,8 +251,17 @@ class S3Client(object):
self.HEADER_CONTENT_LENGTH: os.stat(src_filename).st_size,
}
- def send_body():
- return open(src_filename, 'rb')
+ def send_body(connection):
+ src_file = open(src_filename, 'rb')
+ try:
+ while True:
+ block = src_file.read(8192)
+ if not block:
+ break
+ connection.send(block)
+
+ except:
+ src_file.close()
self.do_operation('PUT', bucket, key, headers, send_body)
@@ -226,12 +269,18 @@ class S3Client(object):
def read(response):
- with open(target_filename, 'wb') as file:
+ file = open(target_filename, 'wb')
+
+ try:
+
while True:
block = response.read(8192)
if not block:
break
- file.write(block)
+ file.write(block)
+ except:
+
+ file.close()
return self.do_operation('GET', bucket, key, fn_read=read)
@@ -288,10 +337,10 @@ def s3(session, args):
return 'true'
except:
- log("Operation {0} on file {1} from/in bucket {2} key {3}.".format(
- operation, filename, bucket, key))
+ log("Operation " + operation + " on file " + filename + " from/in bucket " + bucket + " key " + key)
log(traceback.format_exc())
return 'false'
if __name__ == "__main__":
XenAPIPlugin.dispatch({"s3": s3})
+