diff --git a/seafobj/backends/alioss.py b/seafobj/backends/alioss.py new file mode 100644 index 0000000..94d9283 --- /dev/null +++ b/seafobj/backends/alioss.py @@ -0,0 +1,39 @@ +from .base import AbstractObjStore + +from oss.oss_api import OssAPI +from seafobj.exceptions import GetObjectError +import httplib + +class OSSConf(object): + def __init__(self, key_id, key, bucket_name, host): + self.key_id = key_id + self.key = key + self.bucket_name = bucket_name + self.host = host + +class SeafOSSClient(object): + '''Wraps a oss connection and a bucket''' + def __init__(self, conf): + self.conf = conf + # Due to a bug in httplib we can't use https + self.oss = OssAPI(conf.host, conf.key_id, conf.key) + + def read_object_content(self, obj_id): + res = self.oss.get_object(self.conf.bucket_name, obj_id) + if res.status != httplib.OK: + raise GetObjectError("Failed to get object %s from bucket %s: %s %s", + obj_id, self.conf.bucket_name, res.status, res.reason) + return res.read() + +class SeafObjStoreOSS(AbstractObjStore): + '''OSS backend for seafile objecs''' + def __init__(self, compressed, oss_conf): + AbstractObjStore.__init__(self, compressed) + self.oss_client = SeafOSSClient(oss_conf) + + def read_obj_raw(self, repo_id, version, obj_id): + real_obj_id = '%s/%s' % (repo_id, obj_id) + return self.oss_client.read_object_content(real_obj_id) + + def get_name(self): + return 'OSS storage backend' diff --git a/seafobj/exceptions.py b/seafobj/exceptions.py index 4c618e4..3bd59fd 100644 --- a/seafobj/exceptions.py +++ b/seafobj/exceptions.py @@ -20,4 +20,9 @@ class ObjectFormatError(SeafObjException): format ''' - pass \ No newline at end of file + pass + +class GetObjectError(SeafObjException): + '''This exception is raised when we failed to read object from backend. + ''' + pass diff --git a/seafobj/objstore_factory.py b/seafobj/objstore_factory.py index 896bf02..6139046 100644 --- a/seafobj/objstore_factory.py +++ b/seafobj/objstore_factory.py @@ -53,6 +53,19 @@ def get_s3_conf(cfg, section): return conf +def get_oss_conf(cfg, section): + key_id = cfg.get(section, 'key_id') + key = cfg.get(section, 'key') + bucket = cfg.get(section, 'bucket') + region = cfg.get(section, 'region') + + host = 'oss-cn-%s-internal.aliyuncs.com' % region + + from seafobj.backends.alioss import OSSConf + conf = OSSConf(key_id, key, bucket, host) + + return conf + class SeafileConfig(object): def __init__(self): self.cfg = None @@ -112,6 +125,11 @@ def get_obj_store(self, obj_type): ceph_conf = get_ceph_conf(cfg, section) return SeafObjStoreCeph(compressed, ceph_conf) + elif backend_name == 'oss': + from seafobj.backends.alioss import SeafObjStoreOSS + oss_conf = get_oss_conf(cfg, section) + return SeafObjStoreOSS(compressed, oss_conf) + else: raise InvalidConfigError('unknown %s backend "%s"' % (obj_type, backend_name))