diff --git a/lib/fog/rackspace/models/compute_v2/attachment.rb b/lib/fog/rackspace/models/compute_v2/attachment.rb index d5d72d941..8e02571da 100644 --- a/lib/fog/rackspace/models/compute_v2/attachment.rb +++ b/lib/fog/rackspace/models/compute_v2/attachment.rb @@ -4,27 +4,31 @@ module Fog module Compute class RackspaceV2 class Attachment < Fog::Model - identity :id - attribute :server_id, :aliases => 'serverId' attribute :volume_id, :aliases => 'volumeId' attribute :device + def initialize(new_attributes = {}) + super(new_attributes) + server_id = server.id if server #server id should come from collection + self + end + def save - requires :server, :identity, :device - data = service.attach_volume(server.identity, identity, device) + requires :server_id, :volume_id, :device + data = service.attach_volume(server_id, volume_id, device) merge_attributes(data.body['volumeAttachment']) true end def destroy - requires :server, :identity - service.delete_attachment(server.identity, identity) + requires :server_id, :volume_id + service.delete_attachment(server_id, volume_id) true end - - private - + alias :detach :destroy + + private def server collection.server end diff --git a/lib/fog/rackspace/models/compute_v2/server.rb b/lib/fog/rackspace/models/compute_v2/server.rb index 9197ae314..3206f6baa 100644 --- a/lib/fog/rackspace/models/compute_v2/server.rb +++ b/lib/fog/rackspace/models/compute_v2/server.rb @@ -103,6 +103,12 @@ module Fog }) end end + + def attach_volume(volume, device) + requires :identity + volume_id = volume.is_a?(String) ? volume : volume.id + attachments.create(:server_id => identity, :volume_id => volume_id, :device => device) + end def private_ip_address addresses['private'].select{|a| a["version"] == 4}[0]["addr"] diff --git a/tests/rackspace/models/compute_v2/server_tests.rb b/tests/rackspace/models/compute_v2/server_tests.rb index 22de7cffd..01375179c 100644 --- a/tests/rackspace/models/compute_v2/server_tests.rb +++ b/tests/rackspace/models/compute_v2/server_tests.rb @@ -3,75 +3,97 @@ Shindo.tests('Fog::Compute::RackspaceV2 | server', ['rackspace']) do pending if Fog.mocking? service = Fog::Compute::RackspaceV2.new + cbs_service = Fog::Rackspace::BlockStorage.new + timestamp = Time.now.to_i.to_s + options = { - :name => "fog_server_#{Time.now.to_i.to_s}", + :name => "fog_server_#{timestamp}", :flavor_id => 2, :image_id => '3afe97b2-26dc-49c5-a2cc-a2fc8d80c001' } - model_tests(service.servers, options, false) do - @instance.wait_for { ready? } + model_tests(service.servers, options, false) do + @instance.wait_for(timeout=1500) { ready? } tests('#reboot("SOFT")').succeeds do @instance.reboot('SOFT') returns('REBOOT') { @instance.state } end - - @instance.wait_for { ready? } + + @instance.wait_for(timeout=1500) { ready? } tests('#reboot("HARD")').succeeds do @instance.reboot('HARD') returns('HARD_REBOOT') { @instance.state } end - - @instance.wait_for { ready? } + + @instance.wait_for(timeout=1500) { ready? } tests('#rebuild').succeeds do @instance.rebuild('5cebb13a-f783-4f8c-8058-c4182c724ccd') returns('REBUILD') { @instance.state } end - - @instance.wait_for { ready? } + + @instance.wait_for(timeout=1500) { ready? } tests('#resize').succeeds do @instance.resize(3) returns('RESIZE') { @instance.state } end - - @instance.wait_for { state == 'VERIFY_RESIZE' } + + @instance.wait_for(timeout=1500) { state == 'VERIFY_RESIZE' } tests('#confirm_resize').succeeds do @instance.confirm_resize end - - @instance.wait_for { ready? } + + @instance.wait_for(timeout=1500) { ready? } tests('#resize').succeeds do @instance.resize(2) returns('RESIZE') { @instance.state } end - - @instance.wait_for { state == 'VERIFY_RESIZE' } + + @instance.wait_for(timeout=1500) { state == 'VERIFY_RESIZE' } tests('#revert_resize').succeeds do @instance.revert_resize end - - @instance.wait_for { ready? } + + @instance.wait_for(timeout=1500) { ready? } tests('#change_admin_password').succeeds do @instance.change_admin_password('somerandompassword') returns('PASSWORD') { @instance.state } returns('somerandompassword') { @instance.password } end - @instance.wait_for { ready? } - end + tests('attachments') do + begin + @volume = cbs_service.volumes.create(:size => 100, :display_name => "fog-#{timestamp}") + @volume.wait_for(timeout=1500) { ready? } + tests('#attach_volume') do + @instance.attach_volume(@volume, "/dev/xvdb") + @instance.wait_for(timeout=1500) do + !attachments.empty? + end + returns(true) { @instance.attachments.any? {|a| a.volume_id == @volume.id } } + end + ensure + @volume.wait_for(timeout=1500) { !attachments.empty? } + @instance.attachments.each {|a| a.detach } + @volume.wait_for(timeout=1500) { ready? && attachments.empty? } + @volume.destroy if @volume + end + end + + @instance.wait_for(timeout=1500) { ready? } + end - # When after testing resize/resize_confirm we get a 409 when we try to resize_revert so I am going to split it into two blocks + #When after testing resize/resize_confirm we get a 409 when we try to resize_revert so I am going to split it into two blocks model_tests(service.servers, options, false) do - @instance.wait_for { ready? } + @instance.wait_for(timeout=1500) { ready? } tests('#resize').succeeds do @instance.resize(4) returns('RESIZE') { @instance.state } end - @instance.wait_for { state == 'VERIFY_RESIZE' } + @instance.wait_for(timeout=1500) { state == 'VERIFY_RESIZE' } tests('#revert_resize').succeeds do @instance.revert_resize end - @instance.wait_for { ready? } + @instance.wait_for(timeout=1500) { ready? } end end