今回は、S3のバージョン管理機能について紹介します。
S3では、デフォルトの状態だとバージョン機能は無効になっていますが、バケットごとにバージョン管理を有効にすることができます。
そこで今回は、AWS SDK for Rubyを利用して、その動作を簡単に確認してみます。

事前に、認証情報設定用のファイルを用意しておきます。

$ vi config.rb
require 'rubygems'
require 'aws'

AWS.config({
:access_key_id => 'アクセスキー',
:secret_access_key => 'シークレットキー'
})

指定されたバケットのファイルとバージョンの全状態を確認するスクリプトを作ります。

$ vi check_version.rb
# 設定情報を読み込む
require File.expand_path(File.dirname(__FILE__) + '/config')

# 引数からバケット名を読み込む
bucket_name = ARGV[0]
unless bucket_name
 puts "Usage: check_version.rb "
 exit 1
end

# S3インスタンスの取得
s3 = AWS::S3.new
# バケットオブジェクトの取得
bucket = s3.buckets[bucket_name]
# バケットのバージョンが有効か出力
puts "state :" + bucket.versioning_state.to_s
# バケットの全バージョン情報を取得
versions = bucket.versions
# 全てのバージョン情報を出力
versions.each(){|obj_ver|
 puts "key=" + obj_ver.object.key + "; version_id=" + obj_ver.version_id + ";"
}

これを実行して全バージョンの情報を確認してみます。

$ ruby check_version.rb hoge-bucket

state :unversioned
key=_1308236999981.png; version_id=null;
key=welcome.txt; version_id=null;

ここで、stateがunversionedとなっているのはバケットがデフォルトでバージョニング無効になっているためです。
また、元々アップされていた _1308236999981.pngとwelcome.txtの2つのファイルのversion_idもnullになっています。

次に、このバケットをバージョニング有効にするためのスクリプトを書きます。

$ vi enable_version.rb
# 設定情報を読み込む
require File.expand_path(File.dirname(__FILE__) + '/config')

# 引数からバケット名を読み込む
bucket_name = ARGV[0]
unless bucket_name
 puts "Usage: check_version.rb "
 exit 1
end

# S3インスタンスの取得
s3 = AWS::S3.new
# バージョニングの有効化
s3.buckets[bucket_name].enable_versioning

これを実行して、再度バージョニング状態を確認します。

$ ruby enable_version.rb hoge-bucket
$ ruby check_version.rb hoge-bucket

state :enabled
key=_1308236999981.png; version_id=null;
key=welcome.txt; version_id=null;

state: enabledとなっており、バージョニングが有効になっていることが確認できます。

次に、ファイルをアップロードするスクリプトを作ります。

$ vi upload.rb
# 設定情報を読み込む
require File.expand_path(File.dirname(__FILE__) + '/config')

# 引数からバケット名、ファイル名を読み込む
(bucket_name, file_name) = ARGV
unless bucket_name && file_name
 puts "Usage: upload.rb  "
 exit 1
end

# S3インスタンスの取得
s3 = AWS::S3.new

# バケットが存在しなければ作成する
b = s3.buckets[bucket_name]
unless b.exists?
 b = s3.buckets.create(bucket_name)
end

# アップロード
basename = File.basename(file_name)
o = b.objects[basename]
o.write(:file => file_name)

このアップロードスクリプトを使用して、バージョニングが有効になった状態のバケットに、連続して違う内容のwelcome.txtをアップロードしてみます。

$ echo "hoge" > welcome.txt
$ ruby upload.rb hoge-bucket welcome.txt
$ echo "moge" > welcome.txt
$ ruby upload.rb hoge-bucket welcome.txt

ここで、再度バージョン情報を確認します。

$ ruby check_version.rb hoge-bucket

state : enabled
key=_1308236999981.png; version_id=null;
key=welcome.txt; version_id=1ut2HAksA7WCEkbdlDD3rnBC_OxP8Lvf;
key=welcome.txt; version_id=VpCOAn8Et9ZbOQyk_bKVJGeYaYp2x2W_;
key=welcome.txt; version_id=null;

このように、version_idがついたwelcome.txtが2つ増えていることが確認できます。
ここで、バージョンを指定してファイルを読み込むスクリプトを作成します。

$ vi read_by_version.rb
# 設定情報を読み込む
require File.expand_path(File.dirname(__FILE__) + '/config')

# 引数からバケット名、ファイル名、バージョンIDを読み込む
(bucket_name, file_name, version_id) = ARGV
unless bucket_name && file_name && version_id
 puts "Usage: version_check.rb "
 exit 1
end

# S3インスタンスの作成
s3 = AWS::S3.new

# バージョンを指定して読み込んだものを出力
bucket = s3.buckets[bucket_name]
puts bucket.objects[file_name].read({:version_id=>version_id}).to_s

これを先程の出力で確認したバージョンIDを指定して、個別に実行すると、以下のように各バージョンのファイル内容を確認することができます。

$ ruby read_by_version.rb hoge-bucket welcome.txt 1ut2HAksA7WCEkbdlDD3rnBC_OxP8Lvf
> moge
$ ruby read_by_version.rb hoge-bucket welcome.txt VpCOAn8Et9ZbOQyk_bKVJGeYaYp2x2W_
> hoge  

このように、S3を使用してバージョン管理ができることを確認しました。
ちなみに、このバージョン機能は、ファイル単位での適応となるようです。

こちらの記事はなかの人(memorycraft)監修のもと掲載しています。
元記事は、こちら