From 9295f3321d2bcc194c39cec7984fbb0939ca0ac4 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Sun, 2 Sep 2012 00:47:02 +0100 Subject: [PATCH] [AWS|Glacier] models for archives --- lib/fog/aws/models/glacier/archive.rb | 70 +++++++++++++++++++++++++ lib/fog/aws/models/glacier/archives.rb | 30 +++++++++++ lib/fog/aws/models/glacier/vault.rb | 6 +++ tests/aws/models/glacier/model_tests.rb | 17 ++++++ 4 files changed, 123 insertions(+) create mode 100644 lib/fog/aws/models/glacier/archive.rb create mode 100644 lib/fog/aws/models/glacier/archives.rb diff --git a/lib/fog/aws/models/glacier/archive.rb b/lib/fog/aws/models/glacier/archive.rb new file mode 100644 index 000000000..fc2396790 --- /dev/null +++ b/lib/fog/aws/models/glacier/archive.rb @@ -0,0 +1,70 @@ +require 'fog/core/model' + +module Fog + module AWS + class Glacier + + class Archive < Fog::Model + + identity :id + attribute :description + attribute :body + + attr_accessor :multipart_chunk_size #must be a power of 2 multiple of 1MB + + def vault + @vault + end + + def save + requires :body, :vault + + if multipart_chunk_size && body.respond_to?(:read) + self.id = multipart_save + else + data = connection.create_archive(vault.id, body, 'description' => description) + self.id = data.headers['x-amz-archive-id'] + end + true + end + + def destroy + requires :id + connection.delete_archive(vault.id,id) + end + + private + + def vault=(new_vault) + @vault = new_vault + end + + def multipart_save + # Initiate the upload + res = connection.initiate_multipart_upload vault.id, multipart_chunk_size + upload_id = res.headers["x-amz-multipart-upload-id"] + + hash = Fog::AWS::Glacier::TreeHash.new + + body.rewind if body.respond_to?(:rewind) + offset = 0 + while (chunk = body.read(multipart_chunk_size)) do + part_hash = hash.add_part(chunk) + part_upload = connection.upload_part(vault.id, upload_id, chunk, offset, part_hash ) + offset += chunk.bytesize + end + + rescue + # Abort the upload & reraise + connection.abort_multipart_upload(vault.id, upload_id) if upload_id + raise + else + # Complete the upload + connection.complete_multipart_upload(vault.id, upload_id, offset, hash.hexdigest).headers['x-amz-archive-id'] + end + + end + + end + end +end diff --git a/lib/fog/aws/models/glacier/archives.rb b/lib/fog/aws/models/glacier/archives.rb new file mode 100644 index 000000000..5ac9105c4 --- /dev/null +++ b/lib/fog/aws/models/glacier/archives.rb @@ -0,0 +1,30 @@ +require 'fog/core/collection' +require 'fog/aws/models/glacier/archive' + +module Fog + module AWS + class Glacier + + class Archives < Fog::Collection + + model Fog::AWS::Glacier::Archive + attribute :vault + #you can't list a vault's archives + def all + nil + end + + def get(key) + new(:id => key) + end + + def new(attributes = {}) + requires :vault + super({ :vault => vault }.merge!(attributes)) + end + + end + + end + end +end diff --git a/lib/fog/aws/models/glacier/vault.rb b/lib/fog/aws/models/glacier/vault.rb index c527a9ac2..47c5b4fc3 100644 --- a/lib/fog/aws/models/glacier/vault.rb +++ b/lib/fog/aws/models/glacier/vault.rb @@ -1,4 +1,6 @@ require 'fog/core/model' +require 'fog/aws/models/glacier/archives' + module Fog module AWS class Glacier @@ -17,6 +19,10 @@ module Fog true end + def archives + @archives ||= Fog::AWS::Glacier::Archives.new(:vault => self, :connection => connection) + end + def save requires :id data = connection.create_vault(id) diff --git a/tests/aws/models/glacier/model_tests.rb b/tests/aws/models/glacier/model_tests.rb index c6f681df5..01ef11ab2 100644 --- a/tests/aws/models/glacier/model_tests.rb +++ b/tests/aws/models/glacier/model_tests.rb @@ -21,5 +21,22 @@ Shindo.tests('AWS::Glacier | models', ['aws', 'glacier']) do tests('removes vault').returns(nil) {Fog::AWS[:glacier].vaults.get(vault.id)} end end + + tests("archives") do + vault = Fog::AWS[:glacier].vaults.create :id => 'Fog-Test-Vault-upload' + tests('create') do + archive = vault.archives.create(:body => 'data') + tests('sets id').returns(true) {!archive.id.nil?} + archive.destroy + end + tests('create multipart') do + body = StringIO.new('x'*1024*1024*2) + body.rewind + archive = vault.archives.create(:body => body, :multipart_chunk_size => 1024*1024) + tests('sets id').returns(true) {!archive.id.nil?} + archive.destroy + end + + end end end \ No newline at end of file