2015年2月8日 星期日

Service APIs of python-swiftclient

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,難怪會這麼慢。

2014年12月4日 星期四

用Markdown寫Blog

這幾天花了點時間,想說應該花點時間更新自己的blog,另外也該分出一些時間寫些技術性的文章。

由於工作上會用到很多Markdown的格式,所以想說找個可以發布的軟體,讓我寫blog可以比較輕鬆些。

希望可以支援的功能:

  • Mac平臺
  • Markdown support
      • Code block
      • Table
  • 原始文字格式儲存(.md)
  • 圖片拖拉
  • 支援 blogger 或其他 blog

大概就是上面這樣的內容,看了一下似乎有幾套可以滿足我的需求,所以就先下手嘗試看看。


使用了一會,大致上瞭解了支援的程度。

Desk 

對於一般使用者Desk是不錯的選擇,前提是你不知道所謂的Markdown也沒關係,因為他會有簡單的提示告訴你如何調整格式。如果你是Markdown的使用者,Desk對你來說應該不太夠用,因為目前似乎還未支援:

  • Table
  • Code block
  • 其他進階功能

Byword

如果你是進階的使用者,可以推薦你這款軟體,Table and code block都有支援,其他的進階功能還沒嘗試過,所以也還不知道支援程度。

缺點如下:

  • Publish to blog 需而外付費(NT 150)
  • 不支援圖片拖拉,須自行上傳網站然自行加入圖片(這有點討厭)

所以目前我應該是選擇Desk來當我主力寫文章的工具,Byword拿來寫文件好了。


其實Byword + scriptogr.am + dropbox也是可以當作另外一種Markdown blog,只可惜第一次嘗試的時候 scriptogr.am 對markdown的支援沒有想像中好啊(code block整個爛掉)!


2014年12月3日 星期三

Startup

前陣子換了一家Startup公司,規模更小,雖然公司的人不多,但是算算也有30來個。工作上的性質也變得不太一樣,不是單純的Porgrammer,做起來的感覺像是 QA+DevOP+Customer service+Develop,真是有趣啊!

大家真的很認真在上班,打混摸魚的人幾乎沒有,大家都很認真的在做自己的事情,雖然不在同一個時區工作,但是整個工作的狀況真的很國際化,加上使用的軟體以及工具,真的是很少在台灣看到,有機會再來分享一下心得。

雖然還是有些地方不太適應,但是應該會越來越好。

2014年5月2日 星期五

世代交替

漸漸感受到世代交替的重要性,公司(政府)能不能轉型,往往在於是否改革方能用新的方式 ,作法或技術來處理同樣的問題。

如果還是想拿舊的方式,態度面對新的產業,有時直接會被產業淘汰掉,淘汰的速度比較像是溫水煮青蛙,慢慢的但你發現時已經無力回天。

工程技術人員也一樣,如果只是在公司把事情完成,沒有嘗試與其他技術人員交流,尤其是新創公司的開發者,他們往往會用新的技術與工具來加速開發,等到你想換另一份工作時,就會發現怎麼產業完全不同,自己會的東西已經沒有需求!


看到50多歲還能在矽谷打拼的工程師,真的是不簡單!希望自己到那年紀還能有這樣的熱誠,但口袋可以麥可麥克!

2014年5月1日 星期四

Git and git-p4

Perforce is great source version tool for owner of company, because it's centralize control and can track each client behavior. But I don't like it anymore.
So I used Git to manage my local repo that is sync from perforce server. Use git to track my local commits and use p4/p4v to submit changes to Perforce server. But the work flow will complex and waste time(file always locks to read only with p4).

Few couple months passed, I found the tool git-p4 that can manage p4 repo like remote git branch. That similar like git-svn tool (git 與 git-svn 簡單教學)

The git-p4 is wrote by python and it integrates to git source tree. you need turn off the compile flag(ON_PYTHON) when you compiling git. In official build on git website, the NO_PYTHON is enable, so you can't use it with git-p4.

$ git p4
fatal: git was built without support for git-p4 (NO_PYTHON=1).

Please clone the git and switch to tag v1.9.2
$ git clone https://github.com/git/git
$ git checkout v1.9.2 -b v1.9.2

Follow INSTALL document to compile and install git, Please make sure the python already install in your environment (NO_PYTHON will turn OFF when you compile)
$ make prefix=/usr all 
$ sudo make prefix=/usr install

Check your git and git-p4 are ready to use

$ git --version
git version 1.9.2

$ git-p4
usage: /usr/bin/git-p4  [options]

valid commands: clone, rollback, debug, commit, rebase, branches, sync, submit

Try /usr/bin/git-p4  --help for command specific help.

Add p4 alias to your ~/.gitconfig

[alias]
    p4 = !/usr/bin/git-p4

Don't forget your p4 command and environemnt

$ export P4CLIENT=[your_client_name]
$ export P4HOST=[perforce_server_ip]:1666
$ export P4USER=[login_user_name]
$ export P4EDITOR=vim


Now, you can clone a proj from perforce.

# Clone a repository and covert all change list to git log
$ git p4 clone //depot/path/project@all myproject

# Clone a repository without log
$ git p4 clone //depot/path/project myproject
  
# Do some work and commit to your local git repo
$ git add foo.py
$ git commit foo.py
# Submit your local commit to remote repo (Perforce server)
# git p4 will create a change list for commit
$ git p4 submit

# Synchronize with Perforce (almost like 'git fetch' and 'get pull')
$ git p4 rebase
All done, enjoy it! :)

2014年4月23日 星期三

安裝 Xcode 5.1 Command line tools 所引起的問題

在 MacOS 10.9.2 上面如果有安裝 xcode command line tools,當你在裝第三方packages (python pip or ruby gem)而且有compile native library (大部份應該都是 c library),請記得加入這樣的 flag 在你環境上:


Ruby

sudo  gem update --verbose

export ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
sudo gem update --verbose


Python

pip install xxx

export ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
pip install xxx


不然就會感受到 compiler 很熱情地抱怨...

./ruby_xml_encoding.h:11:51: note: passing argument to parameter 'xencoding' here
VALUE rxml_new_cstr(const char* xstr, const char* xencoding);
                                                  ^
1 warning generated.
compiling ruby_xml_xpointer.c
linking shared-object libxml_ruby.bundle
clang: error: unknown argument: '-multiply_definedsuppress' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
make: *** [libxml_ruby.bundle] Error 1


Gem files will remain installed in /Library/Ruby/Gems/2.0.0/gems/libxml-ruby-2.7.0 for inspection.
Results logged to /Library/Ruby/Gems/2.0.0/gems/libxml-ruby-2.7.0/ext/libxml/gem_make.out
Updating mini_portile
Fetching: mini_portile-0.6.0.gem (100%)
Successfully installed mini_portile-0.6.0
Parsing documentation for mini_portile-0.6.0
Installing ri documentation for mini_portile-0.6.0
Installing darkfish documentation for mini_portile-0.6.0
Updating nokogiri
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
 ERROR: Failed to build gem native extension.

這應該是 Apple 為了避免出現類似 iOS 7.0.4 裡面的 gotofail bug,所設下的 flag。
有一好沒兩好...

2014年3月25日 星期二

讓 vim 支援 multiple cscope DB

之前發現blog,有幾篇文章是比較熱門的,尤其是這篇(用 vim 有效閱讀 Android framework 程式碼),被點閱的次數還不少。不過看了之前寫的plugin,還是覺得寫得很差,都是可以動就好。

所以前幾天有點時間,就把部分拿來重寫,大致上已經修改完畢。大家可以到multi-cscope-db(github去看看。

安裝的方式跟以往相同,不過建議用 vundle 來管理你的 vim plugin。
我把 goproj.sh 的部分,移動到 vim script 裡面。所以不需這隻 shell。以後只需要在 vim 的 command line 打入

:CSBuild

就可以建立新的 DB 或是更新 DB 內容,相信這樣應該會比較好用些。

目前預設支援:

*.aidl
*.cc
*.h
*.c
*.cpp
*.java
*.py

當加上越多副檔名支援,更新或是新建  DB 的時間就會花比較多。

Fork and enjoy it! :)
歡迎討論!