在Swift中,Swift3中間件在Object Storage上提供了S3 REST 風格的API。
目前支持的操作有以下幾種:
· GET Service
· DELETE Bucket
· GET Bucket (List Objects)
· PUT Bucket
· DELETE Object
· GET Object
· HEAD Object
· PUT Object
· PUT Object (Copy)
配置注意:
在proxy-server.conf配置swift3,並確保swift3在auth和其他查找swift請求的中間件之前。具體配置示例如下:
[pipeline:main]
pipeline = healthcheck cache swift3 swauth proxy-server
[filter:swift3]
use = egg:swift#swift3
以SAIO的配置為例,使用AWS的boto python包來分析S3 API的使用,基本信息:
account: test
user:tester
password: testing
0. 連接
文檔中僅給出了一個連接例子,代碼如下:
connection = boto.s3.Connection(
aws_access_key_id='test:tester',
aws_secret_access_key='testing',
port=8080,
host='127.0.0.1',
is_secure=False,
calling_format=boto.s3.connection.OrdinaryCallingFormat())
但是我在測試時,發現存在問題,traceback如下:
Traceback (most recent call last):
File "/home/swift/tmp2.py", line 8, in <module>
connection = boto.s3.Connection(
AttributeError: 'module' object has no attribute 'Connection'
我估計是寫錯了,boto.s3.connection是一個module,我去閱讀了boto的文檔,正確寫法應該是:
connection = boto.s3.connection.S3Connection(
aws_access_key_id='test:tester',
aws_secret_access_key='testing',
port=8080,
host='127.0.0.1',
is_secure=False,
calling_format=boto.s3.connection.OrdinaryCallingFormat())
創建成功,無任何輸出消息。
其中access_key和aws_access_key_id相同。
>>> connection.access_key
'test:tester'
>>> connection.aws_access_key_id
'test:tester'
>>> connection.aws_secret_access_key
'testing'
1. Container管理
Swift中Container的概念與S3中的Bucket相等。
使用以下語句創建一個bucket:
>>> connection.create_bucket('1st')
<Bucket: 1st>
如果再次創建相同名稱的bucket,會出現409沖突錯誤:
boto.exception.S3CreateError: S3CreateError: 409 Conflict
如果使用了大寫字母也會出錯,而使用rackspace的API則無此限制:
>>> connection.create_bucket('1sT')
boto.exception.BotoClientError: BotoClientError: Bucket names cannot contain upper-case characters when using either the sub-domain or virtual hosting calling format.
使用中文字符創建bucket,出現403 Forbidden錯誤:
>>> connection.create_bucket('結果')
boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden
此外,可以單獨使用純數字或下划線_創建bucket,不可以使用!@#$%&等符號。
也可以使用connecttion.create_bucket('media.userdomain.com')的風格來創建bucket。
檢索bucket
使用get_all_buckets()來獲得所有的buckets信息:
>>> connection.get_all_buckets()
[<Bucket: 1>, <Bucket: 1st>, <Bucket: SINA>, <Bucket: ___>, <Bucket: a>, <Bucket: aa>, <Bucket: media.user.com>,<Bucket: photos>, <Bucket: sss>, <Bucket: 圖片>, <Bucket: 文件>, <Bucket: 視頻>]
此外,使用get_bucket()來獲得指定bucket,這里分別測試了小寫字母、大寫字母、不存在的、中文的bucket,其中大寫字母的bucket可以獲得,get不存在的bucket返回400 Bad Request,而get中文字符的bucket仍然返回403 Forbidden:
>>> connection.get_bucket('sss')
<Bucket: sss>
>>> connection.get_bucket('SINA')
<Bucket: SINA>
>>> connection.get_bucket('SINa')
Traceback (most recent call last):
boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidBucketName</Code>
<Message>The specified bucket is not valid</Message>
</Error>
>>> connection.get_bucket('圖片')
Traceback (most recent call last):
boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AccessDenied</Code>
<Message>Access denied</Message>
</Error>
刪除bucket
使用delete_bucket()來刪除指定的bucket,如果目標bucket不存在,返回400 Bad Request,中文的bucket仍然有問題。
>>> connection.delete_bucket('sss')
>>>
>>> connection.delete_bucket('sss')
boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidBucketName</Code>
<Message>The specified bucket is not valid</Message>
</Error>
>>> connection.delete_bucket('視頻')
boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AccessDenied</Code>
<Message>Access denied</Message>
</Error>
2. key管理
獲得key列表
在swift中使用object的概念與S3中的key對應。
>>> con=connection.get_bucket('photos') #獲得名為photos的bucket
>>> con.get_all_keys() #獲得key列表
[<Key: photos,List>, <Key: photos,lzl.jpg>, <Key: photos,sample>]
創建key
使用以下流程創建了一個key,從本地磁盤上傳了一張照片並設置了元數據。
>>> from boto.s3.key import Key
>>> k=Key(con,'sample') #在photos內新建一個名為sample的key
>>> k
<Key: photos,sample>
>>> k.name
'sample'
>>> k.set_contents_from_filename('/home/swift/lzl.jpg') 選擇從本地上傳文件
>>> k.size #查看key的大小
46486L
>>> k.set_metadata('date',2011) 設置元數據
>>> k.metadata
{'data': '2011'}
提取key
使用 k.get_contents_to_filename('/home/swift/td.jpg')下載到本地磁盤上。
從字符串獲得content
>>> new_text=Key(con,'List')
>>> new_text.set_contents_from_string('This is a list of samples')
>>> new_text.get_contents_as_string()
'This is a list of samples'
key的重寫操作
由於swift不是文件系統,不支持類似於POSIX文件系統的讀寫操作,上傳一個文件的唯一方式本質上就是重寫這個文件。比如,為之前的new_text追加一行字符串,結果發現這個文件的內容被重寫了。通過etag可以判斷文件的版本信息。
>>> new_text.etag
'33e6bddcde5e0615dcd301f8f2e1e683'
>>> new_text.set_contents_from_string('New photo added')
>>> new_text.get_contents_as_string()
'New photo added'
>>> new_text.etag
'"6e0c13f0143a54cfa250dbace6da3a5d"'
使用copy復制key
把pohotos中的sample復制到SINA中並重命名為new_sample
>>> k=connection.get_bucket('photos').get_key('sample')
>>> k
<Key: photos,sample>
>>> new_k=k.copy('SINA','new_sample')
>>> new_k.bucket
<Bucket: SINA>
>>> new_k
<Key: SINA,new_sample>
key刪除
使用key的delete()方法就可以刪除key本身
>>> k.delete()
>>> k.exists()
False
參考文檔
http://aws.amazon.com/articles/3998?_encoding=UTF8&jiveRedirect=1
