libcloud代碼研究(三)——bugs

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。勿迷信他人代碼,相信本身判斷。
相關文章
相關標籤/搜索