第11回:イメージを操作するEucalyptusのAPI


 前回はEBSに関するAPIとして、ボリュームとスナップショットを操作できるAPIについて取り上げましたが、今回はマシンイメージを操作するAPIについて説明します。なお、基本的な使い方は第8回を参照してください。

セキュリティアップデート

 本題に入る前に、Eucalyptusのセキュリティアップデートについてアナウンスします。昨年の12月16日(米国時間)にバージョン2.0.2がリリースされましたが、このリリースはバージョン2.0.0と2.0.1に存在する脆弱性に対するセキュリティアップデートとなっています。詳細は下記のURLを参照してください。

ESA-01: password reset vulnerability(パスワードリセットに関する脆弱性)
http://open.eucalyptus.com/wiki/esa-01

 なお、昨年12月14日のプレスリリースにもあるように、Eucalyptus社はセキュリティアドバイザリーチームを発足させました。今後Eucalyptusのセキュリティに関する問題や課題が発生した場合は、同チームがそうした問題に取り組み、そしてアナウンスをするようです。

Security Information
http://open.eucalyptus.com/wiki/security

イメージの操作

 仮想マシンイメージの登録や一覧の取得も重要なAPIです。仮想マシンイメージには、他のユーザーも利用可能なパブリックなイメージにするかなどの属性も設定することができます。イメージを操作するAPIには、下記のAPIがあります。

【仮想マシンイメージを操作するAPI】
API説明
DescribeImages仮想マシンイメージの情報を取得する。
RegisterImage仮想マシンイメージを登録する。
DeregisterImage仮想マシンイメージの登録を解除する。
DescribeImageAttribute仮想マシンイメージの属性を取得する。
ModifyImageAttribute仮想マシンイメージの属性を変更する。
ResetImageAttribute仮想マシンイメージの属性をリセットする。

 

イメージの一覧を取得する

 仮想マシンイメージの一覧を取得するには、DescribeImages APIを使用します。DescribeImages APIを呼び出す際のパラメータには以下のものがあります。

【DescribeImagesのパラメータ】
パラメータ説明必須/任意
ImageIdイメージのIDを指定します。複数個指定することができます。emi-12345678任意
Ownerイメージの所有者を指定します。複数個指定することができます。user001任意
ExecutableByイメージを起動可能なユーザーを指定します。複数個指定することができます。user001任意

 

 DescribeImages APIのレスポンスとして下記のようなXMLが返却されます。

<?xml version="1.0"?>  <DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">    <requestId>eccab7db-e3da-4233-9aa3-2cd710725638</requestId>    <imagesSet>      <item>        <imageId>eki-68C21677</imageId>        <imageLocation>pubkernel/vmlinuz-2.6.28-11-generic.manifest.xml</imageLocation>        <imageState>available</imageState>        <imageOwnerId>admin</imageOwnerId>        <isPublic>true</isPublic>        <productCodes/>        <architecture>x86_64</architecture>        <imageType>kernel</imageType>      </item>      <item>        <imageId>eri-ADBD175A</imageId>        <imageLocation>pubramdisk/initrd.img-2.6.28-11-generic.manifest.xml</imageLocation>        <imageState>available</imageState>        <imageOwnerId>admin</imageOwnerId>        <isPublic>true</isPublic>        <productCodes/>        <architecture>x86_64</architecture>        <imageType>ramdisk</imageType>      </item>      <item>        <imageId>emi-02DD14D3</imageId>        <imageLocation>pubmachine/centos.5-3.x86-64.img.manifest.xml</imageLocation>        <imageState>available</imageState>        <imageOwnerId>admin</imageOwnerId>        <isPublic>true</isPublic>        <productCodes/>        <architecture>x86_64</architecture>        <imageType>machine</imageType>        <kernelId>eki-68C21677</kernelId>        <ramdiskId>eri-ADBD175A</ramdiskId>      </item>        </imagesSet>  </DescribeImagesResponse

 

 上記のレスポンスXMLでは、3つのイメージが返却され、それぞれカーネルイメージ、ラムディスクイメージ、マシンイメージの場合のレスポンスです。レスポンスXMLの内、重要な情報は下記の通りです。

【DescribeImageの戻り値】
情報説明
imageId仮想マシンイメージのIDです。
imageLocation仮想マシンイメージのマニフェストファイルのロケーションです。バケット名から始まります。
imageState仮想マシンイメージの状態です。基本的には「available」が入ります。
imageOwnerId仮想マシンイメージの所有者です。
isPublic仮想マシンイメージがすべてのユーザーで利用可能なpublicであるかを示します。
architecture仮想マシンイメージのアーキテクチャです。「x86_64」や「i386」が入ります。
imageType仮想マシンイメージの種類です。「machine」、「kernel」、「ramdisk」が入ります。
kernelId仮想マシンイメージを起動時に使用するカーネルイメージのIDです。
ramdiskId仮想マシンイメージを起動時に使用するラムディスクイメージのIDです。

 

 下記にbotoとRightAwsによるサンプルコードを示します。セットアップ方法と基本的な内容は第8回を参照してください。

【botoでのDescribeImages】
images = connection.get_all_images()
# 結果の表示
for image in images:
print image.id, image.location, image.ownerId, image.is_public
if image.kernel_id:
print image.kernel_id
if image.ramdisk_id:
print image.ramdisk_id

# イメージIDを指定する場合
connection.get_all_images(image_ids=['emi-12345678', 'eki-12345678'])

# イメージの所有者を指定する場合
# 所有者が user001 のイメージ
connection.get_all_images(owners=['user001'])

# イメージの起動権限を指定する場合
# user001 が起動可能なイメージ
connection.get_all_images(executable_by=['user001'])

 

【RightAwsでのDescribeImages】
# 引数を省略した場合は、当該ユーザーが利用可能なイメージが返る
# 引数は、イメージID。複数指定する場合は Array で渡す。
result = @ec2.describe_images('emi-12345678')
pp result
#=> [{:aws_ramdisk_id=>"eri-12345678",
# :aws_is_public=>true,
# :aws_id=>"emi-12345678",
# :aws_architecture=>"x86_64",
# :root_device_name=>"/dev/sda1",
# :root_device_type=>"instance-store",
# :aws_location=>"centos.emi.006/centos55.img.manifest.xml",
# :aws_image_type=>"machine",
# :aws_state=>"available",
# :aws_kernel_id=>"eki-12345678",
# :aws_owner=>"admin"}]

# 引数に与えられたユーザー名などが起動できるイメージの一覧を取得
# 以下は自身が起動できるイメージの一覧を取得する例
result = @ec2.describe_images_by_executable_by('self')

# 引数に与えられたユーザーが所有するイメージの一覧を取得
# 以下は自身が所有するイメージの一覧を取得する例
result = @ec2.describe_images_by_owner('self')

 

イメージを登録する

 仮想マシンイメージを登録するには、RegisterImage APIを使用します。RegisterImageを呼び出す際には、パラメータとしてWalrus上にアップロードしたイメージの情報を書いたマニフェストファイルを指定する必要があります。また、マニフェストファイルとバンドル済みのイメージはWalrus上にアップロードしておく必要があります。これらの必要なファイルの作成とアップロードはeuca2oolsで提供されている「euca-bundle-image」コマンドと「euca-upload-bundle」コマンドを使用して行うことができます。

 botoには、RegisterImage APIに対応した register_imageメソッドがありますが、このメソッドの仕様はEucalyptusが対応しているAPIよりも最新のバージョンが使われており、若干仕様が異なるためそのまま使用することができません。そのため、少し面倒ですが下記のようにする必要があります。

【botoでのRegisterImage】
# 指定するマニフェストファイルのロケーション
image_location='bucket_name/good_image.img.manifest.xml'
params = {'ImageLocation': image_location}

# レスポンスをパース・マッピングするクラスをインポートします
from boto.resultset import ResultSet
# ここでサーバ側へリクエストを送付します
rs = connection.get_object('RegisterImage', params, ResultSet)
# レスポンスXMLのマッピングしたインスタンスからイメージIDを取得します
image_id = getattr(rs, 'imageId', None)
return image_id

 

 euca2oolsでは、boto.ec2.connection.EC2Connectionクラスのregister_imageメソッドを実行時に上書きして自前のregister_imageを使用しています。

【RightAwsでのRegisterImage】
# 引数は、イメージロケーション(バケット名/マニフェスト)
result = @ec2.register_image('vtaro.emi.001/centos.5-3.x86-64.img.manifest.xml')

# 戻り値はイメージID
pp result #=> emi-12345678

 

イメージの登録を解除する

 仮想マシンイメージの登録を解除するには、DeregisterImage APIを使用します。DeregisterImage APIを呼び出す際には、パラメータとして登録を解除したいイメージのIDを指定します。

【botoでのDeregisterImage】
# 戻り値はTrue/Falseが入る
result = connection.deregister_image('emi-12345678')

 

【RightAwsでのDeregisterImage】
# 引数は、イメージID
result = @ec2.deregister_image('emi-12345678')

# 戻り値は true/false が返る
pp result #=> true

 

イメージの属性を取得する

 仮想マシンイメージにはパブリックなイメージかどうかや誰が起動可能かなどの属性を持っています。これらの仮想マシンイメージの属性を取得するには、DescribeImageAttribute APIを使用します。DescribeImageAttribute APIを呼び出す際のパラメータは以下のものがあります。

【DescribeImageAttributeのパラメータ】
パラメータ説明必須/任意
ImageId属性を取得する仮想マシンイメージのIDを指定します。emi-12345678必須
Attribute取得する属性を指定します。launchPermission必須

 

 Eucalyptusで指定可能な属性は下記の通りです。

【指定可能な属性】
属性説明
launchPermission起動可能なユーザーの設定です。グループ「all」が設定されている場合は、すべてのユーザーが利用できます。プライベートなイメージにしたい場合は、このパーミッションを削除します。また、ユーザー単位で指定することができます。デフォルトでは自ユーザーのみ設定されます。
kernel仮想マシンイメージを起動する際に使用するカーネルイメージのIDです。
ramdisk仮想マシンイメージを起動する際に使用するラムディスクイメージのIDです。

 

【botoでのDescribeImageAttribute】
# launchPermissionを取得する場合
attribute = connection.get_image_attribute('emi-12345678', 'launchPermission')
# boto.ec2.image.ImageAttribute instance
print attribute.attrs
# 実行結果は {'user_ids': [u'admin'], 'groups': [u'all']}

# カーネルイメージのIDを取得する場合
kernel = connection.get_image_attribute('emi-12345678', 'kernel')
print kernel.value
# 実行結果は eki-12345678

# ラムディスクイメージのIDを取得する場合
ramdisk = connection.get_image_attribute('emi-12345678', 'ramdisk')
print ramdisk.value
# 実行結果は eri-12345678

 

【RightAwsでのDescribeImageAttribute】
# 引数は、イメージID, アトリビュート
result = @ec2.describe_image_attribute('emi-12345678', 'launchPermission')

# 戻り値は以下の情報が返る
pp result
#=> {:users=>["vtaro"], :aws_id=>"emi-12345678", :groups=>["all"]}

 

イメージの属性を変更する

 仮想マシンイメージの属性を変更するには、ModifyImageAttribute APIを使用します。ただし、ModifyImageAttribute APIを使用して変更可能な属性は「launchPermission」のみとなります。ModifyImageAttribute APIを呼び出す際のパラメータ以下のものがあります。

【ModifyImageAttribute APIのパラメータ】
パラメータ説明必須/任意
ImageId属性を変更するイメージIDを指定します。emi-12345678必須
Attribute変更する属性を指定します。現在のところ、「launchPermission」のみしか指定できません。launchPermission必須
OperationType属性を追加するか削除するかを指定します。属性の追加を場合は「add」、削除する場合は「remove」を指定します。add必須
UserIdlaunchPermissionに追加もしくは削除するユーザーのIDを指定します。複数個指定することができます。本項目かGroupのいずれかを指定する必要があります。user001場合により必須
GrouplaunchPermissionに追加もしくは削除するグループのIDを指定します。現在のところ、「all」以外は指定できません。本項目かUserIdのいずれかを指定する必要があります。all場合により必須

 

【botoでのModifyImageAttribute】
# ユーザーIDを指定して属性を追加する場合
# 戻り値はTrue/Falseが入る
result = connection.modify_image_attribute(
image_id='emi-12345678',
attribute='launchPermission',
operation='add',
user_ids=['user001'])
# 属性とオペレーションはデフォルト値がlaunchPermissionをaddになっているため省略可能
result = connection.modify_image_attribute('emi-12345678', user_ids=['user001'])

# グループを指定する場合
result = connection.modify_image_attribute('emi-12345678', groups=['all'])

# 削除の場合
result = connection.modify_image_attribute('emi-12345678', 'remove', user_ids=['user001'])
result = connection.modify_image_attribute('emi-12345678', 'remove', groups=['all'])

 

【RightAwsでのModifyImageAttribute】
# 引数は、イメージID, アトリビュート, オペレーション, アトリビュートの値
# サポートしているアトリビュートは 'launchPermission' のみ
# サポートしているオペレーションは 'add' と 'remove' のみ
# サポートしているアトリビュートの値は、以下。
# :user_group => 'all' のみ
# :user_id => ユーザー名
# :product_code => プロダクトコード
result = @ec2.modify_image_attribute('emi-12345678', 'launchPermission', 'add', :user_id => 'vjiro')

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

# RightAws では modify_image_attribute() より以下のメソッドの使用を推奨している
# それぞれのメソッドの戻り値は true か例外が返る

# 指定したイメージの起動権限にグループを追加 (ただしグループ all のみサポート)
@ec2.modify_image_launch_perm_add_groups('emi-12345678', ['all'])

# 指定したイメージの起動権限にユーザーを追加
@ec2.modify_image_launch_perm_add_users('emi-12345678', ['vtaro', 'vjiro'])

# 指定したイメージの起動権限からグループを削除 (ただしグループ all のみサポート)
@ec2.modify_image_launch_perm_remove_groups('emi-12345678', ['all'])

# 指定したイメージの起動権限からユーザーを削除
@ec2.modify_image_launch_perm_remove_users('emi-12345678', ['vtaro', 'vjiro'])

 

イメージの属性をリセットする

 ModifyImageAttribute APIを使用して変更した仮想マシンイメージの属性値をデフォルト値に戻したい場合には、ResetImageAttribute APIを使用します。ResetImageAttribute APIを呼び出す際には、パラメータとして仮想マシンイメージのIDとデフォルト値に戻したい属性を指定します。ただし、こちらもModifyImageAttribute APIと同様に指定可能な属性は「launchPermission」のみとなります。

【botoでのResetImageAttribute】
# 戻り値はTrue/Falseが入る
result = connection.reset_image_attribute('emi-123455678', 'launchPermission')
# 属性の指定は省略可能(デフォルトでlaunchPermission)
result = connection.reset_image_attribute('emi-123455678')

 

【RightAwsでのResetImageAttribute】
# 引数は、イメージID, アトリビュート
result = @ec2.reset_image_attribute('emi-12345678', 'launchPermission')

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

 

次回は、Amazon S3互換APIについて

 第8回から第11回までの連載で主なAmazon EC2 APIについて紹介しました。次回はAmazon S3 APIについて簡単に説明します。

 


羽深 修
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/4 06:00