Bug 1:對不可迭代類進行迭代(libcloud.storage.driver.cloudfile line. 141-142)
使用libcloud鏈接自搭建swift服務,本身在服務器上搭建swift服務,利用keystone進行認證(swift自帶認證服務swauth libcloud好像不支持),配置好keystone服務器(keystone服務器ip爲192.168.137.201),先利用curl命令確認swift和keystone服務是正常運行。
執行以下幾行代碼進行openstack StorageDriver類的初始化:
1 CloudDriver = get_driver(Provider.CLOUDFILES_SWIFT)
2 driver = CloudDriver(user_id, passwd, secure=False, region='RegionOne',
3 ex_tenant_name=tenant_name,
4 ex_force_auth_url='http://192.168.137.201:35357',
5 ex_force_auth_version='2.0_passwd',
6 ex_force_service_type='object-store',
7 ex_force_service_name='Swift')
注意,其中auth_url要與本身認證服務器url一致,且auth_version/service_type/service_name等信息均要與keystone服務器中相應信息一致,不然將沒法獲取endpoint!
即使如此,仍舊沒法得到endpoint,通過跟蹤調試,最終將錯誤定位於libcloud.storage.driver中cloudfiles.py文件中line. 141-142:
1 if PUBLIC_ENDPOINT_KEY in endpoint:
2 return endpoint[PUBLIC_ENDPOINT_KEY]
此處endpoint爲OpenStackServiceCatalogEntryEndpoint類對象,此類中並未定義迭代方法,沒法對一個不可迭代類進行迭代!將上面兩行代碼修改成:
1 if endpoint.url:
2 return endpoint.url
代碼便可正常運行。
Bug 2:死循環(libcloud.storage.driver.cloudfiles line. 728-751)
1 while True:
2 container_name_encoded = \
3 self._encode_container_name(container.name)
4 response = self.connection.request('/%s' %
5 (container_name_encoded),
6 params=params)
7
8 if response.status == httplib.NO_CONTENT:
9 # Empty or non-existent container
10 break
11 elif response.status == httplib.OK:
12 objects = self._to_object_list(json.loads(response.body),
13 container)
14
15 if len(objects) == 0:
16 break
17
18 for obj in objects:
19 yield obj
20 params['marker'] = obj.name
此循環,是爲了列出一個container中符合要求的全部object,但在依照此代碼對百度雲存儲進行封裝時輸出結果陷入死循環,在最後一行添加break語句後代碼正常運行。
在鏈接swift時還沒有運行此段代碼,不知其是否也會出現問題。
Bug 3:對上傳文件進行二次迭代錯誤(libcloud.storage.base line. 622-637 734-782)
line 734:
1 generator = libcloud.utils.files.read_in_chunks(iterator, chunk_size)
2
3 bytes_transferred = 0
4 try:
5 chunk = next(generator)
6 except StopIteration:
7 # Special case when StopIteration is thrown on the first iteration
8 # create a 0-byte long object
9 chunk = ''
對文件的流式上傳,每次均須要調用base.py中_upload_object()和_stream_data()函數。而我在對百度雲存儲封裝流式上傳函數時,每次上傳文件均不成功,上面_stream_data()中代碼每次都會進入StopIteration異常處理流程,上傳一個空文件。
後來我發現是由於百度雲不支持文件分塊編碼上傳,故supports_chunked_encoding =False。在_upload_object()中會執行一次read_in_chunks(),而上面代碼再次執行read_in_chunks()時,文件迭代器iterator已經指向文件末尾,故chunk = next(generator)老是異常。
仔細思考後,我在read_in_chunks()函數(libcloud.utils.file line. 36-94)開頭添加以下兩行代碼:
1 if isinstance(iterator, file) and iterator.tell():
2 iterator.seek(0,os.SEEK_SET)
即若是迭代器類型爲文件且文件當前位置不爲起始位置,將其位置置於起始位置。後代碼正常運行。
開源代碼也是人寫的,也許在之後使用libcloud過程當中,會發現更多bug。勿迷信他人代碼,相信本身判斷。