File: //volume1/@appstore/HyperBackup/addon/openstack_swift/python/swift_agent.py
#!/usr/bin/env python
#-*-coding: utf-8 -*-
import os, sys, json
from struct import pack, unpack
from time import strptime, mktime
from syslog import syslog, LOG_ERR
debug = False
def log_debug(*args):
if debug:
print >> sys.stderr, ' '.join(args)
def _is_scoket_exception(e):
import socket
if type(e) == socket.gaierror or type(e) == socket.error or type(e) == socket.herror or type(e) == socket.timeout:
return True
return False
def _convert_socket_error_code(message):
error_code = -1
if -1 != message.find("[Errno -2] Name or service not known"):
error_code = -2
elif -1 != message.find("[Errno -3] Temporary failure in name resolution"):
error_code = -2
elif -1 != message.find("[Errno -5] No address associated with hostname"):
error_code = -2
elif -1 != message.find("[Errno 110] Connection timed out"):
error_code = 408
elif -1 != message.find("[Errno 101] Network is unreachable"):
error_code = -4
elif -1 != message.find("[Errno 111] Connection refused"):
error_code = -4
elif -1 != message.find("[Errno 113] No route to host"):
error_code = -4
elif -1 != message.find("[Errno 104] Connection reset by peer"):
error_code = -4
elif -1 != message.find("[Errno 32] Broken pipe"):
error_code = 408
return error_code
def _is_ssl_timeout(message):
#ssl.SSLErr_timeouteption log
if -1 != message.find("timed out"):
# The read operation timed out
# The write operation timed out
# The handshake operation timed out
return True
return False
def _convert_socket_exception(e):
import socket
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
if type(e) == socket.gaierror:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
if e.errno == -2:
# socket.gaierror: [Errno -2] Name or service not known
# 1. dns not set
# 2. set to a wrong dns
error_code = -2
elif e.errno == -3:
# socket.gaierror: [Errno -3] Temporary failure in name resolution
# man gai_strerror, and find EAI_AGAIN:
# The name server returned a temporary failure indication. Try again later.
error_code = -2
elif e.errno == -5:
# socket.gaierror: [Errno -5] No address associated with hostname
# man gai_strerror, and find EAI_NODATA:
# The specified network host exists, but does not have any network addresses defined.
error_code = -2
elif e.errno < 100 and e.errno > 0:
error_code = e.errno
elif type(e) == socket.error or type(e) == socket.herror:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
elif hasattr(e, 'args'):
error_msg = str(e.args)
if -1 != error_msg.find('Tunnel connection failed'):
error_code = -4
if e.errno == socket.errno.ETIMEDOUT:
# socket.error: [Errno 110] Connection timed out
error_code = 408
elif e.errno == socket.errno.ENETUNREACH:
# socket.error: [Errno 101] Network is unreachable
error_code = -4
elif e.errno == socket.errno.ECONNREFUSED:
# socket.error: [Errno 111] Connection refused
error_code = -4
elif e.errno == socket.errno.EHOSTUNREACH:
# socket.error: [Errno 113] No route to host
error_code = -4
elif e.errno == socket.errno.ECONNRESET:
# socket.error: [Errno 104] Connection reset by peer
error_code = -4
elif e.errno == socket.errno.EPIPE:
# socket.error: [Errno 32] Broken pipe
error_code = 408
elif e.errno < 100 and e.errno > 0:
error_code = e.errno
#syslog(LOG_ERR, "get network error %d:%s" % (e.errno, error_msg))
elif type(e) == socket.timeout:
error_msg = 'timed out'
error_code = 408
else:
syslog(LOG_ERR, "BUG: exception [%s], type [%s]" % (str(e), type(e)))
#syslog(LOG_ERR, "error %s:%d:%s" % (error_cls, error_code, str(error_msg)))
if -1 == error_code:
if hasattr(e, "args"):
syslog(LOG_ERR, "error args: [%s]" % (str(e.args)))
if hasattr(e, "errno"):
syslog(LOG_ERR, "error errno: [%s]" % (str(e.errno)))
if hasattr(e, "strerror"):
syslog(LOG_ERR, "error strerror: [%s]" % (str(e.strerror)))
except Exception as ee:
syslog(LOG_ERR, "parse socket exception failed: [%s]" % (str(ee)))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_exception(e):
import swiftclient
import keystoneclient
import requests
import socket
import httplib
import ssl
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
try:
if type(e.message) is unicode:
error_msg = repr(e.message).split('\\n')[0]
else:
error_msg = str(e.message).split('\n')[0]
log_debug("\033[31mexception: \033[0m", error_msg)
except:
log_debug("\033[31mexception: \033[0m", "could not parse error msg")
if type(e) == swiftclient.ClientException:
if hasattr(e, "http_status"):
if e.http_status == 400 and e.message == "Refresh access token failed":
error_code = 401
elif e.http_status >= 100 and e.http_status < 700:
error_code = e.http_status
elif type(e) == keystoneclient.exceptions.SSLError:
error_code = -4
elif type(e) == keystoneclient.exceptions.RequestTimeout:
error_code = 408
elif type(e) == keystoneclient.exceptions.ConnectionRefused:
error_code = _convert_socket_error_code(str(e))
elif type(e) == keystoneclient.exceptions.BadRequest:
if hasattr(e, "http_status"):
error_code = e.http_status
if hasattr(e, "message"):
error_msg = e.message
if error_code == 400 and (error_msg == "Username should not contain white spaces" \
or error_msg == 'Expecting username' or error_msg == 'Expecting apiKey'):
error_code = 401
elif type(e) == TypeError:
# this exception will raise when base64 decode for auth failed
if error_msg == "Incorrect padding":
error_code = 401
elif type(e) == UnicodeDecodeError:
error_code = -5
elif type(e) == requests.exceptions.ConnectionError:
error_code = -4
if type(e.args[0]) == requests.packages.urllib3.exceptions.ProtocolError:
if "BadStatusLine" in str(e.args[0]):
error_code = -4
elif _is_scoket_exception(e.args[0].args[1]):
return _convert_socket_exception(e.args[0].args[1])
else:
syslog(LOG_ERR, "ProtocolError: exception [%s], type [%s]" % (str(e.args[0].args[1]), type(e.args[0].args[1])))
elif type(e.args[0]) == requests.packages.urllib3.exceptions.MaxRetryError:
if hasattr(e.args[0], 'reason') and e.args[0].reason:
if type(e.args[0].reason) == requests.packages.urllib3.exceptions.NewConnectionError:
error_code = _convert_socket_error_code(str(e.args[0].reason))
else:
syslog(LOG_ERR, "MaxRetryError: exception [%s], type [%s]" % (str(e.args[0].reason), type(e.args[0].reason)))
elif _is_scoket_exception(e.args[0]):
return _convert_socket_exception(e.args[0])
elif type(e.args[0]) == ssl.SSLError or type(e.args[0]) == requests.packages.urllib3.exceptions.SSLError:
if hasattr(e.args[0], 'message') and e.args[0].message:
error_msg = e.args[0].message
if _is_ssl_timeout(str(error_msg)):
error_code = 408
else:
syslog(LOG_ERR, "SSLError: exception [%s], type [%s]" % (str(error_msg), type(error_msg)))
elif type(e) == requests.exceptions.SSLError:
error_code = -4
# EOF occurred in violation of protocol
# SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_ILLEGAL_PARAMETER
# SSL: TLSV1_ALERT_DECRYPT_ERROR
# SSL: TLSV1_ALERT_DECODE_ERROR
# SSL: CERTIFICATE_VERIFY_FAILED
if _is_ssl_timeout(str(e)):
error_code = 408
elif type(e) == requests.packages.urllib3.exceptions.NewConnectionError:
error_code = _convert_socket_error_code(str(e))
elif type(e) == requests.packages.urllib3.exceptions.ConnectTimeoutError:
error_code = 408
elif type(e) == requests.packages.urllib3.exceptions.ReadTimeoutError:
error_code = 408
elif type(e) == requests.exceptions.ConnectTimeout:
error_code = 408
elif type(e) == requests.exceptions.ReadTimeout:
error_code = 408
elif type(e) == httplib.ResponseNotReady:
error_code = -4
elif type(e) == httplib.BadStatusLine:
error_code = -4
elif type(e) == httplib.IncompleteRead:
error_code = -4
elif type(e) == ssl.SSLError:
error_code = -4
if hasattr(e, "strerror") and e.strerror:
# SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_BAD_RECORD_MAC
# SSL: CERTIFICATE_VERIFY_FAILED
error_msg = e.strerror
if _is_ssl_timeout(str(error_msg)):
error_code = 408
elif type(e) == ssl.SSLEOFError:
# ssl.SSLEOFError: [Errno 8] EOF occurred in violation of protocol
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
error_code = -4
elif type(e) == IOError:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
error_code = _convert_socket_error_code(str(e))
elif _is_scoket_exception(e):
return _convert_socket_exception(e)
else:
syslog(LOG_ERR, "exception [%s]" % str(e))
syslog(LOG_ERR, "type [%s]" % type(e))
#syslog(LOG_ERR, "error %s:%d:%s" % (error_cls, error_code, str(error_msg)))
if -1 == error_code:
if hasattr(e, "args"):
syslog(LOG_ERR, "error args: [%s]" % (str(e.args)))
if hasattr(e, "errno"):
syslog(LOG_ERR, "error errno: [%s]" % (str(e.errno)))
if hasattr(e, "strerror"):
syslog(LOG_ERR, "error strerror: [%s]" % (str(e.strerror)))
except Exception as ee:
syslog(LOG_ERR, "parse exception failed: [%s]" % (str(ee)))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_GMT_time_str(val):
origin_tz = None
if os.environ.get('TZ'):
origin_tz = os.environ.get('TZ')
os.environ['TZ'] = 'GMT'
timestamp = int(mktime(strptime(val, '%a, %d %b %Y %H:%M:%S %Z')))
if origin_tz:
os.environ['TZ'] = origin_tz
return timestamp
def _convert_UTC_time_str(val):
origin_tz = None
if os.environ.get('TZ'):
origin_tz = os.environ.get('TZ')
os.environ['TZ'] = 'UTC'
time_val, sec_xtime = str(val).split('.')
timestamp = int(mktime(strptime(time_val, '%Y-%m-%dT%H:%M:%S')))
sec_xtime = sec_xtime.rstrip('Z')
if int(sec_xtime) > 0:
timestamp += 1
if origin_tz:
os.environ['TZ'] = origin_tz
return timestamp
def _convert_properties(properties):
out_json = {
# 2015-10-01T02:52:24.169600 / 1443667944.169600 -> 1443667945
'LastModified': _convert_UTC_time_str(properties.get('last_modified')),
'ETag': properties.get('hash'),
'ContentType': properties.get('content_type'),
'ContentLength': properties.get('bytes')
}
return out_json
def _convert_properties_by_dict(properties):
out_json = {
'LastModified': _convert_GMT_time_str(properties.get('last-modified')),
'ETag': properties.get('etag'),
'ContentType': properties.get('content-type'),
'ContentLength': properties.get('content-length')
}
return out_json
class SimpleIO(object):
def read_int(self):
data = ''
n = 4
while n > 0:
read_data = sys.stdin.read(n)
if 0 == len(read_data):
raise StopIteration
data += read_data
n -= len(read_data)
if data:
return unpack('i', data)[0]
else:
# check eof?
raise StopIteration
def read_string(self):
n = self.read_int()
if 0 == n:
return ''
data = ''
while n > 0:
read_data = sys.stdin.read(n)
data += read_data
n -= len(read_data)
if data:
return data
else:
raise SystemError
def read_json(self):
json_str = self.read_string()
if json_str:
return json.loads(json_str)
else:
return None
def write_int(self, val):
data = pack('i', val)
sys.stdout.write(data)
sys.stdout.flush()
def write_string(self, val):
self.write_int(len(val))
sys.stdout.write(val)
sys.stdout.flush()
# log
def write_json(self, val):
s = json.dumps(val)
self.write_string(s)
def write_exception(self, e):
self.write_json(_convert_exception(e))
class FileObjectWithProgress(object):
"""
Readable file object with progress wrapper.
"""
def __init__(self, io):
"""
Wrap the underlying file object
:param file_obj: the file object to wrap
"""
self._io = io
self._file_obj = None
self._prev_process_size = 0
def set_file_obj(self, file_obj):
self._file_obj = file_obj
self._prev_process_size = 0
def read(self, length=None):
read_data = self._file_obj.read(length)
self._prev_process_size += len(read_data)
res = {
'success': True,
'complete': False,
'uploaded': self._prev_process_size
}
if self._io:
self._io.write_json(res)
else:
print res
return read_data
def write(self, write_data):
self._file_obj.write(write_data)
self._prev_process_size += len(write_data)
res = {
'success': True,
'complete': False,
'downloaded': self._prev_process_size
}
if self._io:
self._io.write_json(res)
else:
print res
return None
def tell(self):
return self._file_obj.tell();
def seek(self, offset, whence=os.SEEK_SET):
self._file_obj.seek(offset, whence)
class OpenStackSwiftApi(object):
def __init__(self, io=None):
import swiftclient
self._file_obj_progress = FileObjectWithProgress(io)
self._io = io
SYNO_SOCKET_TIMEOUT = 600
#os.environ['SWIFT_DEBUG'] = 1
self._swift = swiftclient.Connection(
authurl=os.environ.get('OPENSTACK_SWIFT_URL'),
user=os.environ.get('OPENSTACK_SWIFT_USER'),
key=os.environ.get('OPENSTACK_SWIFT_KEY'),
retries=int(os.environ.get('OPENSTACK_SWIFT_RETRIES')),
preauthurl=os.environ.get('OPENSTACK_SWIFT_PREAUTHURL'),
preauthtoken=os.environ.get('OPENSTACK_SWIFT_PREAUTHTOKEN'),
auth_version=os.environ.get('OPENSTACK_SWIFT_VERSION'),
os_options={
'tenant_id': os.environ.get('OPENSTACK_SWIFT_TENANT_ID'),
'tenant_name': os.environ.get('OPENSTACK_SWIFT_TENANT_NAME'),
'user_domain_id': os.environ.get('OPENSTACK_SWIFT_DOMAIN_ID'),
'user_domain_name': os.environ.get('OPENSTACK_SWIFT_DOMAIN_NAME'),
'region_name': os.environ.get('OPENSTACK_SWIFT_REGION')
},
timeout=SYNO_SOCKET_TIMEOUT)
self._service_options={
'auth': os.environ.get('OPENSTACK_SWIFT_URL'),
'user': os.environ.get('OPENSTACK_SWIFT_USER'),
'key': os.environ.get('OPENSTACK_SWIFT_KEY'),
'retries': int(os.environ.get('OPENSTACK_SWIFT_RETRIES')),
'auth_version': os.environ.get('OPENSTACK_SWIFT_VERSION'),
'os_tenant_id': os.environ.get('OPENSTACK_SWIFT_TENANT_ID'),
'os_tenant_name': os.environ.get('OPENSTACK_SWIFT_TENANT_NAME'),
'os_user_domain_id': os.environ.get('OPENSTACK_SWIFT_DOMAIN_ID'),
'os_user_domain_name': os.environ.get('OPENSTACK_SWIFT_DOMAIN_NAME'),
'os_auth_token': os.environ.get('OPENSTACK_SWIFT_PREAUTHTOKEN'),
'os_storage_url': os.environ.get('OPENSTACK_SWIFT_PREAUTHURL'),
'os_region_name': os.environ.get('OPENSTACK_SWIFT_REGION')}
self._swift_service = None
del os.environ['OPENSTACK_SWIFT_VERSION']
del os.environ['OPENSTACK_SWIFT_URL']
del os.environ['OPENSTACK_SWIFT_USER']
del os.environ['OPENSTACK_SWIFT_KEY']
del os.environ['OPENSTACK_SWIFT_RETRIES']
del os.environ['OPENSTACK_SWIFT_TENANT_ID']
del os.environ['OPENSTACK_SWIFT_TENANT_NAME']
del os.environ['OPENSTACK_SWIFT_DOMAIN_ID']
del os.environ['OPENSTACK_SWIFT_DOMAIN_NAME']
del os.environ['OPENSTACK_SWIFT_REGION']
del os.environ['OPENSTACK_SWIFT_PREAUTHURL']
del os.environ['OPENSTACK_SWIFT_PREAUTHTOKEN']
log_debug('agent created')
def getAuth(self, in_json):
storage_url, token = self._swift.get_auth()
return {
'success': True,
'token': token,
'endpoint': storage_url
}
def getAuthInfo(self, in_json):
storage_url, token = self._swift.get_auth_info()
if not storage_url or not token:
return {
'success': False
}
return {
'success': True,
'token': token,
'endpoint': storage_url
}
def getCapabilities(self, in_json):
res = self._swift.get_capabilities()
return {
'success': True,
'capabilities': res
}
def headAccount(self, in_json):
headers = self._swift.head_account()
# 404 not found
return {
'success': True,
'account': headers
}
def listRegions(self, in_json):
regions = self._swift.get_region()
out_json = {
'success': True,
'region': []
}
for r in regions:
out_json['region'].append({
'Name': r
})
return out_json
def putContainer(self, in_json):
res = {}
self._swift.put_container(
container=in_json['container'],
response_dict=res)
code = res.get('status')
# 201 Created
# 202 Accepted (exist)
# 204 Normal response
# 400 name len > 256
if code == 201 or code == 204:
return {'success': True, 'error_code': code, 'error_message': res.get('reason')}
else:
return {'success': False, 'error_code': code, 'error_message': res.get('reason')}
def headContainer(self, in_json):
headers = self._swift.head_container(in_json['container'])
# 404 not found
return {
'success': True,
'LastModified': _convert_GMT_time_str(headers.get('date'))
}
def listContainers(self, in_json):
headers, containers = self._swift.get_account(
full_listing=True)
out_json = {
'success': True,
'container': []
}
for c in containers:
out_json['container'].append({
'Name': c.get('name')
})
return out_json
def deleteContainer(self, in_json):
res = {}
self._swift.delete_container(
container=in_json['container'],
response_dict=res)
code = res.get('status')
# 204 Normal response
# 404 not found
# 409 conflict
if code == 204:
return {'success': True, 'error_code': code, 'error_message': res.get('reason')}
else:
return {'success': False, 'error_code': code, 'error_message': res.get('reason')}
def putObject(self, in_json):
res = {}
with open(in_json['fileInput'], "rb") as stream:
self._file_obj_progress.set_file_obj(stream)
self._swift.put_object(
container=in_json['container'],
obj=in_json['name'],
contents=self._file_obj_progress,
response_dict=res)
code = res.get('status')
# 201 Normal response
# 408 timeout
# 400 name len > 1024
# 411 length required
# 413 large file
# 422 unprocessable entity
if code == 201:
return {'success': True, 'error_code': code, 'error_message': res.get('reason'),
'Properties': _convert_properties_by_dict(res.get('headers'))}
else:
return {'success': False, 'error_code': code, 'error_message': res.get('reason')}
def putDirectory(self, in_json):
res = {}
self._swift.put_object(
container=in_json['container'],
obj=in_json['name'],
contents='',
content_type='application/directory',
response_dict=res)
code = res.get('status')
# 201 Normal response
# 408 timeout
# 400 name len > 1024
# 411 length required
# 413 large file
# 422 unprocessable entity
if code == 201:
return {'success': True, 'error_code': code, 'error_message': res.get('reason')}
else:
return {'success': False, 'error_code': code, 'error_message': res.get('reason')}
def listObjects(self, in_json):
limit_count = 10000
marker_obj = in_json.get('Marker', None)
prefix_obj = in_json.get('Prefix', None)
delimiter_obj = in_json.get('Delimiter', None)
headers, objects = self._swift.get_container(
container=in_json['container'],
marker=marker_obj,
limit=limit_count,
prefix=prefix_obj,
delimiter=delimiter_obj)
targetType = in_json.get('TargetType', 'all')
count = 0
out_json = {
'success': True,
'folder': [],
'file': []
}
for o in objects:
if targetType == 'folder' or targetType == 'all':
if o.get('subdir'):
out_json['folder'].append({'Name': o.get('subdir')})
count += 1
if targetType == 'file' or targetType == 'all':
if o.get('name'):
out_json['file'].append({
'Name': o.get('name'),
'Properties': _convert_properties(o)
})
count += 1
if len(objects) == limit_count:
if o.get('name'):
out_json['NextMarker'] = objects[limit_count - 1].get('name')
else:
out_json['NextMarker'] = objects[limit_count - 1].get('subdir')
out_json['count'] = count
return out_json
def headObject(self, in_json):
headers = self._swift.head_object(
container=in_json['container'],
obj=in_json['name'])
properties = _convert_properties_by_dict(headers)
if "\"" == properties['ETag'][0] and "\"" == properties['ETag'][-1]:
properties['ETag'] = properties['ETag'][1:-1]
return {
'success': True,
'Properties': properties
}
def deleteObject(self, in_json):
res = {}
self._swift.delete_object(
container=in_json['container'],
obj=in_json['name'],
response_dict=res)
code = res.get('status')
# 204 Normal response
# 400
# 404 not found
# 500
if code == 204:
return {'success': True, 'error_code': code, 'error_message': res.get('reason')}
else:
return {'success': False, 'error_code': code, 'error_message': res.get('reason')}
def getObject(self, in_json):
headers_obj = None
read_len = 65536
if in_json.get('RangeStart') and in_json.get('RangeEnd'):
headers_obj = {'Range': 'bytes=' + in_json.get('RangeStart') + '-' + in_json.get('RangeEnd')}
hdrs, body = self._swift.get_object(
container=in_json['container'],
obj=in_json['name'],
resp_chunk_size=read_len,
headers=headers_obj)
with open(in_json['fileOutput'], "wb") as stream:
self._file_obj_progress.set_file_obj(stream)
while True:
try:
self._file_obj_progress.write(body.next())
except StopIteration:
break
# 404 not found
return {'success': True}
def writeJson(self, res):
if self._io:
self._io.write_json(res)
else:
print res
def putLargeObject(self, in_json):
from swiftclient.service import SwiftService
from swiftclient.service import SwiftUploadObject
if self._swift_service is None:
storage_url, token = self._swift.get_auth_info()
if storage_url and token:
self._service_options['os_auth_token'] = token
self._service_options['os_storage_url'] = storage_url
self._swift_service = SwiftService(self._service_options)
generator = self._swift_service.upload(
container=in_json['container'],
objects=[SwiftUploadObject(
source=in_json['fileInput'],
object_name=in_json['name'])],
options={
'segment_size': in_json['segmentSize'],
'segment_container': in_json['container']})
for r in generator:
if r['success']:
if 'object' in r and 'upload_object' == r['action']:
if 'manifest_response_dict' in r:
return {
'success': True,
'error_code': r['manifest_response_dict'].get('status'),
'error_message': r['manifest_response_dict'].get('reason'),
'Properties': _convert_properties_by_dict(r['manifest_response_dict'].get('headers'))}
elif 'response_dict' in r:
return {
'success': True,
'error_code': r['response_dict'].get('status'),
'error_message': r['response_dict'].get('reason'),
'Properties': _convert_properties_by_dict(r['manifest_response_dict'].get('headers'))}
elif 'for_object' in r:
self.writeJson({
'success': True,
'complete': False,
'segment_location': r['segment_location'],
'segment_size': r['segment_size']})
else:
return _convert_exception(r['error'])
def deleteLargeObject(self, in_json):
from swiftclient.service import SwiftService
if self._swift_service is None:
storage_url, token = self._swift.get_auth_info()
if storage_url and token:
self._service_options['os_auth_token'] = token
self._service_options['os_storage_url'] = storage_url
self._swift_service = SwiftService(self._service_options)
res = {}
generator = self._swift_service.delete(
container=in_json['container'],
objects=[in_json['name']])
for r in generator:
if r['success']:
if r['action'] == 'delete_object':
return {
'success': True,
'error_code': r['response_dict'].get('status'),
'error_message': r['response_dict'].get('reason')}
#elif r['action'] == 'delete_segment':
#elif r['action'] == 'delete_container':
else:
return _convert_exception(r['error'])
def start_server():
io = SimpleIO()
try:
api = OpenStackSwiftApi(io)
except Exception as e:
io.write_exception(e)
return False
io.write_string('start')
while True:
try:
in_json = io.read_json()
fn_name = in_json['fn']
fn = getattr(api, fn_name)
del in_json['fn']
if fn is None:
raise SystemError('no such fn: ' + fn_name)
#log_debug('\033[34mexecute: ' + fn_name + ' ' + json.dumps(in_json) + '\033[0m');
res = fn(in_json)
io.write_json(res)
except StopIteration:
break
except Exception as e:
io.write_exception(e)
continue
if __name__ == '__main__':
# Under window, there are text mode and binary mode for files,
# Set binary mode before sending binary data(to stdout)
# to prevent some unexpected behavior!
if sys.platform == "win32":
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
# add include path
script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
sys.path.insert(0, script_dir + '/swiftclient')
sys.path.insert(1, script_dir + '/keystoneclient')
sys.path.insert(2, script_dir + '/module')
res = start_server()
sys.exit(0 if res else 1)