第12回:Amazon S3 API互換なEucalyptusのAPI


 前回はイメージ操作のAPIとして、イメージの登録に関するAPIとイメージの属性に関するAPIについて取り上げました。今回はAmazon S3 API互換のEucalyptusのAPI(以下、Walrus APIと記す)について説明します。

ライブラリのセットアップ

 Walrus APIを使用するためのライブラリは前回までの連載で使用したbotoとRightAWSが使用できるため、今回もbotoとRightAWSを例に説明します(ライブラリの詳細については第8回を参照してください)。

 botoでWalrus APIを使用するためには下記のように作成したコネクションを介して操作を行います。EC2 APIライブラリの場合と同様にeucarcをsourceした環境で利用可能なコードは以下になります。

#!/usr/bin/env python2.5
# -*- coding:utf-8 -*-
import boto.s3
import os
import urlparse

EC2_ACCESS_KEY = os.environ.get("EC2_ACCESS_KEY")
EC2_SECRET_KEY = os.environ.get("EC2_SECRET_KEY")
S3_URL = os.environ.get("S3_URL")

url = urlparse.urlparse(S3_URL)
# Walrusに接続するための設定
calling_format=boto.s3.connection.OrdinaryCallingFormat()

connection = boto.s3.Connection(
    aws_access_key_id=EC2_ACCESS_KEY,
    aws_secret_access_key=EC2_SECRET_KEY,
    is_secure=url.scheme=='https',
    host=url.hostname,
    port=url.port,
    calling_format=calling_format,
    path=url.path
    )

 

 RightAWSを使用してWalrusに接続する場合は以下のように記述します。

【RightAwsでのDescribeImages】
#!/usr/bin/ruby -s

# RightAwsのライブラリをロード
require 'right_aws'

# このスクリプトの実行時に -ec2_access_key, -ec2_secret_key,
# -ec2_url, -s3_url のオプションが設定されていない場合は、
# 環境変数から情報を取得する
$ec2_access_key ||= ENV['EC2_ACCESS_KEY'] if ENV.has_key?('EC2_ACCESS_KEY')
$ec2_secret_key ||= ENV['EC2_SECRET_KEY'] if ENV.has_key?('EC2_SECRET_KEY')
$ec2_url ||= ENV['EC2_URL'] if ENV.has_key?('EC2_URL')
$s3_url ||= ENV['S3_URL'] if ENV.has_key?('S3_URL')

# 上記の値を使用して、Walrus に接続
@s3 = RightAws::S3Interface.new(
   $ec2_access_key, $ec2_secret_key, {
      :endpoint_url => s3_url,
   }
)

 

バケットの作成

 バケットの作成は単純にバケット名を指定するだけです。ただし、バケット名はシステム全体で一意となります。ユーザ毎ではないため、他のユーザが作ったバケットと同名のバケットを作成することはできません。また、バケットの中にバケットを作成することはできません。

【botoでのバケットの作成】
# バケットを作成する
new_bucket = connection.create_bucket('Test001')

# 結果の表示
print new_bucket.name, new_bucket.creation_date

 

 RightAWSではバケット名の頭文字が小文字の場合はVirtualHostingOfBucketsの仕様に従ったバケット名として扱おうとするため、Walrusではエラーになります。もしRightAWSで頭文字が小文字のバケット名を利用する場合は、eucalyptus.confにあるDISABLE_DNSを"N"とするか、もしくはright_s3_interface.rbを修正する必要があります。

【RightAwsでのバケットの作成】
result = @s3.create_bucket('Test001')

# 戻り値は true か例外が返る
pp result #=> true

 

バケットの削除

 続いてバケットの削除方法を説明します。バケットの削除には注意すべき点が1つあります。それはバケットの中にオブジェクトが存在する場合はバケットの削除がエラーになることです。後述の方法でオブジェクトを削除してからバケットを削除する必要があります。

【botoでのバケットの削除】
# バケットを削除する
result = connection.delete_bucket('Test001')

 

【RightAwsでのバケットの削除】
# バケットを削除する
result = @s3.delete_bucket('Test001')

# 戻り値は true か例外が返る
pp result #=> true

 

バケットの一覧取得

 バケットの一覧を取得する方法を説明します。バケットの一覧取得には特に指定すべきパラメータはありません。

【botoでのバケットの一覧取得】
# バケットの一覧を取得する
buckets = connection.get_all_buckets()

# 結果の表示
for bucket in buckets:
    print bucket.name, bucket.creation_date

 

【RightAwsでのバケットの一覧取得】
# バケットの一覧を取得する
result = @s3.list_all_my_buckets

# 戻り値は以下の情報が返る
pp result
#=> [{:creation_date=>"2011-01-08T15:16:13.000Z",
#     :owner_id=>"g8cNahGO2S16Q8h0idb46oWXkWV9dd8qnKNDA",
#     :name=>"vtaro.emi.001",
#     :owner_display_name=>"vtaro"}]

 

オブジェクトのアップロード

 オブジェクトのアップロードについて説明します。オブジェクトの名前をキー(key)と呼びます。同一バケットの中ではキーは一意にする必要があります。また、オブジェクトのキーとバケット名でオブジェクトを一意に特定することができます。

 botoでは、コネクションを介して取得したバケットを起点にオブジェクトのアップロードを行います。

【botoでのオブジェクトのアップロード】
# オブジェクトをアップロードするバケットを取得する
bucket = connection.get_bucket('Test001')

# オブジェクトのキーを作成する
from boto.s3.key import Key
key = Key(bucket)
# キー名を設定する
k.key = 'upload.dat'
# ファイル名を指定してアップロード
k.set_contents_from_filename('sample001.dat')

 

【RightAwsでのオブジェクトのアップロード】
# オブジェクトをアップロードする
# 引数は、バケット名, キー名, データ
result = @s3.put('Test001', 'upload.dat', File.open('sample001.dat'))

# 戻り値は true か例外が返る
pp result #=> true

 

オブジェクトのダウンロード

 アップロードしたオブジェクトをダウンロードする方法について説明します。オブジェクトのダウンロードは、バケット名とオブジェクトのキーを指定します。

 botoでは、オブジェクトのアップロードと同様にコネクションを介して取得したバケットを起点にオブジェクトのダウンロードを行います。

【botoでのオブジェクトのダウンロード】
# オブジェクトをダウンロードするバケットを取得する
bucket = connection.get_bucket('Test001')
# オブジェクトのキーを指定する
key = bucket.get_key('upload.dat')

# オブジェクトをダウンロードする
# 引数にはダウンロード時のローカルファイル名を指定する
key.get_contents_to_filename('sample002.dat')

 

【RightAwsでのオブジェクトのダウンロード】
# オブジェクトをダウンロードする  file = File.new('sample002.dat', File::CREAT|File::RDWR)  # 引数は、バケット名, キー名  result = @s3.get('Test001', 'upload.dat') do |chunk|      file.write(chunk)  end  file.close    # 戻り値は以下の情報が返る  pp result  #=> {:headers=>  #     {"etag"=>"d6ab82f23a8861c3c5439d64e496f5e7",  #     "last-modified"=>"2011-01-08T18:41:29.000Z",  #      "content-type"=>"",  #      "content-length"=>"750"},  #    :object=>#<Net::ReadAdapter>}

 

オブジェクトを削除する

 オブジェクトの削除方法について説明します。オブジェクトの削除をするには、削除したいオブジェクトのキーとバケット名を指定します。

 botoでは、これまでと同様にコネクションを介して取得したバケットを起点にオブジェクトの削除を行います。

【botoでのオブジェクトの削除】
# 削除するオブジェクトのあるバケットを取得する
bucket = connection.get_bucket('Test001')

# 削除するオブジェクトのキーを指定する
key = bucket.get_key('upload.dat')

# オブジェクトを削除する
k.delete()

 

【RightAwsでのオブジェクトの削除】
# オブジェクトを削除する
# 引数は、バケット名, オブジェクト名
result = @s3.delete('Test001', 'upload.dat')

# 戻り値は true か例外が返る
pp result #=> true

 

オブジェクトの一覧取得

 オブジェクトの一覧を取得する方法について説明します。オブジェクトの一覧を取得するには、バケット名を指定します。

 botoでは、これまでと同様にコネクションを介して取得したバケットを起点にオブジェクトの一覧取得を行います。

【botoでのオブジェクトの一覧取得】
# オブジェクトをダウンロードするバケットを取得する
bucket = connection.get_bucket('Test001')
# オブジェクトの一覧を取得する
objects = bucket.list()
for obj in objects:
    print obj.name, obj.last_modified, obj.size
    print obj.owner.id, obj.owner.display_name

 

【RightAwsでのオブジェクトの一覧取得】
# オブジェクトの一覧を取得する  # 引数は、バケット名  result = @s3.list_bucket('Test001')    # 戻り値は以下の情報が返る  pp result  #=> [{:key=>"upload.dat",  #     :owner_id=>"g8cNahGO2S16Q8h0idb46oWXkWV9dd8qnKNDA",  #     :service=>  #      {"name"=>"Test001",  #       "prefix"=>"",  #       "is_truncated"=>false,  #       "max-keys"=>"1000"},  #     :last_modified=>"2011-01-08T18:41:29.000Z",  #     :e_tag=>"d6ab82f23a8861c3c5439d64e496f5e7",  #     :size=>750,  #     :storage_class=>"STANDARD",  #     :owner_display_name=>"vtaro"}]

 

次回からはEucalyptusの利用方法などについて

 今回でAPIに関する説明はいったん終わりにして、次回からは実際にEucalyptusを利用してどのようなインスタンスを起動させてどのようなケースで使用されるかなどを、例をまじえて紹介致します。

イベントの報告とOpenCarfのご紹介

 去る2011年2月7日に国立情報学研究所にて「第47回先端ソフトウェア科学・工学に関するGRACEセミナー」が開催されました。

 筆者も2つ発表させて頂き、1つは「世界で一番使われている Eucalyptus」と題してEucalyptusの概要などやこれまでに得られた知見について発表し、もう1つは「15分で作れるプライベートクラウド」と題してインストール済みのCentOS上にEucalyptusのインストールを実施しインスタンスの起動までを15分間で行なうというデモムービーを発表しました。

 そのときに使用した資料は下記のOpenCarfのサイトで公開されておりますので、是非ご参照頂ければと思います。

・Open Cloud Architecture for Academia Forum(OpenCarf)
  http://www.opencarf.org/documents#grace47.html

 デモムービーは上記OpenCarfサイト以外に、YouTubeでも公開していますので、以下に上げておきます。ただし、YouTubeで公開している動画はOpenCarfサイトで公開している動画に比べて、画質はかなり劣るため画面の文字などは見づらくなっています。できれば、上記OpenCarfサイトで公開しているムービーをご利用ください。



 なお、OpenCarfはクラウドのあり方や教育に使えるクラウドのリファレンスアーキテクチャを議論するためのコミュニティとのことなので、もし興味のある方は参加してみて下さい。

 


羽深 修
Eucalyptus歴はまだ1年ですが、周囲からはEucalyptus中毒と勘違いされているようです。Japan Eucalyptus User Groupの活動に参加し、オープンソースカンファレンスでネタなどを披露しています。度々Eucalyptusへのパッチも書いてます。ちなみに仕事ではCentOS + Xenという環境でEucalyptusを利用していますが、自宅のEucalyptus環境はGentoo Linux + KVMで動かしています。

志田 隆弘
主にEucalyptusやクラウドとはあまり関係のない分野でちょこちょこと活動していました。Eucalyptusはバージョン 1.3の頃からいじり始め、かれこれ2年近くEucalyptusに浸かった生活をしています。Eucalyptus 1.4が出たタイミングで、Tanacasinoという名前のGUIクライアントを作ったりしていました。最新のEucalyptusで動作するので、ぜひ使ってみてください。

田中 智文
志田さんとともに初期の頃からEucalyptusの調査・検証・使用してきました。志田さんの作成したTanacasinoのメンテナンスと機能拡張を行っています。新婚ほやほやなので家でのハック活動時間が少ないですが、Walrus Clientを作ってみたりbotoを使ってEucalyptusを操作して遊んでいます。

 

関連情報
(羽深 修/志田 隆弘/田中 智文)
2011/2/18 06:00