python-swiftclient 是一個 OpenStack swift 的 client tool 簡而言之就是 command line interface(CLI).
之前有想過如何可以直接使用 swiftclient 裡面的 library 直接與 swift APIs 做溝通,省去寫 http client 與 APIs 的攥寫時間,這是一個很單純的問題。就 code 的邏輯是一定沒問題,只是怎麼做比較漂亮,那個地方是插入點,就值得花點時間研究。
作法一: 直接利用 shell.st_FUNCTION 來做,把所需參數倒入即可
- 缺點:需要處理 swiftclient output 的非同步問題,已經處理完 APIs ,但是回來的 buffer 內容就是少些東西。
- 優點:很直覺,直接把參數帶在function後面即可。
#!/usr/bin/env python
import socket
from os import environ
from optparse import OptionParser
from swiftclient import shell
from swiftclient import RequestException
from swiftclient.exceptions import ClientException
from swiftclient.multithreading import OutputManager
def options():
parser = OptionParser()
parser.add_option('-A', '--auth', dest='auth',
default=environ.get('ST_AUTH'))
parser.add_option('-V', '--auth-version',
default=environ.get('ST_AUTH_VERSION',
(environ.get('OS_AUTH_VERSION',
'1.0'))))
parser.add_option('-U', '--user', dest='user',
default=environ.get('ST_USER'))
parser.add_option('-K', '--key', dest='key',
default=environ.get('ST_KEY'))
parser.add_option('--os_user_id')
parser.add_option('--os_user_domain_id')
parser.add_option('--os_user_domain_name')
parser.add_option('--os_tenant_id')
parser.add_option('--os_tenant_name')
parser.add_option('--os_project_id')
parser.add_option('--os_project_domain_id')
parser.add_option('--os_project_name')
parser.add_option('--os_project_domain_name')
parser.add_option('--os_service_type')
parser.add_option('--os_endpoint_type')
parser.add_option('--os_auth_token')
parser.add_option('--os_storage_url')
parser.add_option('--os_region_name')
parser.add_option('--verbose')
parser.add_option('--insecure', default='True')
return parser
def stat(*args):
args = ('',) + args
with OutputManager() as output:
parser = options()
try:
shell.st_stat(parser, list(args), output)
except (ClientException, RequestException, socket.error) as err:
output.error(str(err))
print 'show swift cluster stat'
stat()
輸出
$ ./wrapper_swiftcleint.py
show swift cluster stat
Account: AUTH_demo
Containers: 4
Objects: 5679
Bytes: 468730045
Containers in policy "standard-replica": 4
Objects in policy "standard-replica": 5679
Bytes in policy "standard-replica": 468730045
Meta Temp-Url-Key: f270afa2-0552-43c6-ada0-0688d92c083d
Accept-Ranges: bytes
Connection: keep-alive
X-Timestamp: 1422242407.75372
X-Trans-Id: txb135b30b90384105bf100-0054d728c8
Content-Type: text/plain; charset=utf-8
做法二:利用 SwiftService class (Hight Level APIs 或稱為 Service APIs)
- 優點:該有的都有,output 是一個 dicitionary,處理起來挺方便的。
#!/usr/bin/env python
import json
from swiftclient.service import SwiftService
client_opts = {'insecure': True}
with SwiftService(options=client_opts) as swift:
stat_output = swift.stat()
print json.dumps(stat_output, indent=2)
輸出
$ ./highlevel-swiftclient.py
{
"headers": {
"content-length": "0",
"x-account-storage-policy-standard-replica-container-count": "4",
"accept-ranges": "bytes",
"connection": "keep-alive",
"x-account-object-count": "5679",
"x-timestamp": "1422242407.75372",
"x-account-meta-temp-url-key": "f270afa2-0552-43c6-ada0-0688d92c083d",
"x-trans-id": "tx56fe3088a81f4696ad79d-0054d72c57",
"date": "Sun, 08 Feb 2015 09:28:55 GMT",
"x-account-storage-policy-standard-replica-bytes-used": "468730045",
"x-account-container-count": "4",
"content-type": "text/plain; charset=utf-8",
"x-account-bytes-used": "468730045",
"x-account-storage-policy-standard-replica-object-count": "5679"
},
"container": null,
"success": true,
"action": "stat_account",
"items": [
[
"Account",
"AUTH_demo"
],
[
"Containers",
4
],
[
"Objects",
"5679"
],
[
"Bytes",
"468730045"
],
[
"Containers in policy \"standard-replica\"",
"4"
],
[
"Objects in policy \"standard-replica\"",
"5679"
],
[
"Bytes in policy \"standard-replica\"",
"468730045"
]
],
"object": null
}
其實方法一,是我原本處理的方式。一直到今天才發現這個 blueprint: Move high-level functionality from bin/swift into importable/testable library ,而且已經完成。而且解釋了為什麼需要做這 Service APIs (就是我所遇到的問題),下次做之前一定要『多看,多聽,多問』。
另外關於這個 Patch Review ,不免可以發現其實在 OpenStack 下的 project 已經算是有很完整的 Code review (Gerrit) 以及 continuous integration (Jenkins + Zuul + Gerrit) ,這個 patch 經歷的四個月,而且都是在線上討論完成,而且經過 Code review 與 CI 的洗禮,品質相對會比較穩定。
不過 python-swiftclient 的 performance 真的挺不好的,很慢啊!Head 5k 的 Objects 需要 10分鐘,不過也是因為它每次去取得資料都會去做一次 Auth,難怪會這麼慢。