ConoHaオブジェクトストレージ概要
VPSサービスであるConoHaにオブジェクトストレージのサービスがリリースされました。
ConoHa VPSはAWS互換のOpenStackで作られておりそのOpenStackのSwiftサーバー(AWS S3相当の機能)部分が一般ユーザーに公開されたことになります。
ConoHa VPSとは独立して立っているため、自宅PCからConoHaオブジェクトストレージにアップロードしたり、ConoHaVPSからConoHaオブジェクトストレージにアップロードしたりできます。
AWSに対するアドバンテージは450円 / 100GBでリクエスト数、転送量無料な所でしょうか。
OpenStack Swift概要
OpenStackはオープンソースなのですでに資料が相当出回っています。
http://www.valinux.co.jp/technologylibrary/document/cloud/openstack0001/
Swiftの機能はREST APIで公開されており丁寧なマニュアル(curlコマンド付!)も公開されています。
http://docs.openstack.org/api/openstack-object-storage/1.0/content/large-object-creation.html
RubyでOpenStack用のSwiftモジュールを作ってみる
すでにOpenStack用のライブラリやらgemサイトに接続モジュールはありますがREST API程度の接続ライブラリであれば書いたほうが早いので書いてみました。
まずConoHaオブジェクトストレージの接続情報を用意する
ConoHaオブジェクトストレージ(というかOpenStack Swift)には以下の情報が必要になります。
- テナントID
- テナント名
- ユーザー名
- API Auth URL
- オブジェクトストレージエンドポイント
- パスワード
認証サーバー(API Auth URL)に接続しトークンを取得する
def initialize(opt)
@auth_url = opt['auth_url']
@tenantName = opt['tenantName']
@username = opt['username']
@password = opt['password']
end
def get_token
body = build_auth_json
http_client = HTTPClient.new
response = http_client.post_content(@auth_url, body, 'Content-Type' => 'application/json')
response_json_body = JSON.load(response)
response_json_body['access']['token']['id']
end
def build_auth_json
auth_json = {
auth: {
tenantName: @tenantName,
passwordCredentials: {
username: @username,
password: @password
}
}
}
JSON.dump(auth_json)
end
解説すると
initializeの引数に認証情報を渡す。
build_auth_json関数でリクエストに必要なJSONに整形する。
認証URLから返却されたJSONをハッシュ化し**['access']['token']['id']**を取得する。(これがトークンID)
認証サーバーから返却されるJSONにはトークンの有効期限などトークンをリフレッシュする時のための情報も入っているため、ソフトウェアにリフレッシュトークンの機能を実装する時はそれを利用する。
トークンを利用してサーバーにファイルをアップロードする
ファイルをOpenStack Swiftサーバーにアップロードする時
file = "アップロードするファイルのフルパス"
target_url = "オブジェクトストレージエンドポイント/コンテナ名" + "ファイル名"
auth_header = {
'X-Auth-Token' => token #取得したトークン
}
http_client = HTTPClient.new
File.open(file_path) do |file|
@res = http_client.put(URI.parse(URI.encode(target_url)), file, auth_header)
end
ファイルをアップロードする時のポイントは
- HTTPヘッダーに ** X-Auth-Token ** 情報を付与する
- 送信先のオブジェクトストレージエンドポイントにはアップロード先のファイル名も付与する必要がある
特にオブジェクトストレージのエンドポイントにファイル名を付与しないとアップロードは成功するがHTTP Status 202が返却され、ConoHaオブジェクトストレージのコントロールパネルから見てもファイルが生成されてない珍現象になる。
フォルダをOpenStack Swiftサーバにアップロードする時
target_url = "オブジェクトストレージエンドポイント" + "作成したいフォルダ名"
if File::ftype(file_path) == 'directory'
auth_header = {
'X-Auth-Token' => token,
'Content-Type' => 'application/directory', #必要!
'Content-Length' => 0 #必要!
}
@res = http_client.put(URI.parse(URI.encode(target_url)), file_path, auth_header)
}
フォルダをアップロードする際のポイントは
- HTTP ヘッダーのContent-Type'を**'application/directory'**にする
- HTTP ヘッダーのContent-Length'を0にする
これを実行するとフォルダだけサーバーに作成される。
フォルダの中身までアップロードしたい場合はまずフォルダをSwiftサーバーに作成しその後、中のファイルリストを再帰でぐるぐるアップロードする形になる。
作ったモジュールを利用してファイルをアップロードしてみる。
Gemfileにrabbit_swiftを記述してbundle install。
コマンドラインソフトを想定して以下のように記述
src_file_path = ARGV[0]
dest_url = ARGV[1]
swift_conf = {
auth_url: "https://ident-r1nd9999.cnode.jp/v2.0/tokens",
tenantName: "1234567",
username: "chino",
password: "password"
}
#Swiftクライアントを作成
rabbit_swift_client = RabbitSwift::Client.new(swift_conf);
#トークンを取得
token = rabbit_swift_client.get_token
#ファイルをアップロード
status = rabbit_swift_client.upload(token, dest_url, src_file_path)
#ステータスをチェック
if (status == RabbitSwift::Client::UPLOAD_SUCCESS_HTTP_STATUS_CODE)
puts "upload success!"
end
設定ファイルがベタ書きなのがいけてないですが、上記のコードで
swift_client.rb kawaii.mp4 https://objectstore-r9nd9999.cnode.jp/v1/1231314i12313123/my_folder_name
などのようにすればkawaii.mp4がmy_folder_nameにアップロードされます(my_folder_nameコンテナは予めConoHaのコントロールパネルで作成する必要があります)。
ファイルがアップロードされたか確認する。
ConoHaのコントロールパネルかGUIソフトウェアのCyberduckを使用します。
https://cyberduck.io/
ConoHaのコントロールパネルではファイル数がある一定数を超えると表示されなくなる仕様っぽいのでConoHaのオブジェクトストレージを利用する方はしばらくはCyberduckが必須だと思われます。
こういう感じでFTPソフトウェアのようなインターフェースでSwiftサーバーのファイルのアップロードダウンロードができるソフトです。
バッチでいっきにファイルをアップロード/ダウンロードする時はプログラムを書いて、ちまちまファイルを上げたり落としたりする時はCyberduckを使用するのがいいでしょう。
作成したコンソールソフトでいっきにファイルをアップロードする
前述したフォルダ内のファイルを再帰でアップロードする機能を加えたものを作りました。
以下のような感じで打てばファイルをいっきにアップロードできます。
bundle exec ruby chino.rb -s /Users/Image/Nico/Directory/ -d https://objectstore-r1nd1111.cnode.jp/v1/99a2200c0a1e4c68b766f5e46527199c/test


