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。勿迷信他人代码,相信自己判断。
原文地址:https://www.cnblogs.com/qiyukun/p/4754193.html