class Chef::Provider::AwsEbsVolume
Public Instance Methods
action_create()
click to toggle source
Calls superclass method
# File lib/chef/provider/aws_ebs_volume.rb, line 29 def action_create volume = super update_attachment(volume) unless new_resource.machine.nil? end
Protected Instance Methods
create_aws_object()
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 37 def create_aws_object volume = nil converge_by "create #{new_resource} in #{region}" do volume = new_resource.driver.ec2_resource.create_volume(initial_options) retry_with_backoff(::Aws::EC2::Errors::InvalidVolumeNotFound) do new_resource.driver.ec2_resource.create_tags(resources: [volume.volume_id], tags: [{ key: "Name", value: new_resource.name }]) end volume end converge_by "wait for new #{new_resource} in #{region} to become available" do wait_for_volume_status(volume, :available) volume end end
destroy_aws_object(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 86 def destroy_aws_object(volume) detach(volume) if volume.state == "in-use" delete(volume) end
update_aws_object(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 53 def update_aws_object(volume) if initial_options.key?(:availability_zone) if availability_zone != volume.availability_zone raise "#{new_resource}.availability_zone is #{availability_zone}, but actual volume has availability_zone_name set to #{volume.availability_zone}. Cannot be modified!" end end if initial_options.key?(:size) if initial_options[:size] != volume.size raise "#{new_resource}.size is #{new_resource.size}, but actual volume has size set to #{volume.size}. Cannot be modified!" end end if initial_options.key?(:snapshot_id) if initial_options[:snapshot_id] != volume.snapshot_id raise "#{new_resource}.snapshot is #{new_resource.snapshot}, but actual volume has snapshot set to #{volume.snapshot_id}. Cannot be modified!" end end if initial_options.key?(:iops) if initial_options[:iops] != volume.iops raise "#{new_resource}.iops is #{new_resource.iops}, but actual volume has iops set to #{volume.iops}. Cannot be modified!" end end if initial_options.key?(:volume_type) if initial_options[:volume_type] != volume.volume_type raise "#{new_resource}.volume_type is #{new_resource.volume_type}, but actual volume has type set to #{volume.type}. Cannot be modified!" end end if initial_options.key?(:encrypted) if initial_options[:encrypted] != !!volume.encrypted raise "#{new_resource}.encrypted is #{new_resource.encrypted}, but actual volume has encrypted set to #{volume.encrypted}. Cannot be modified!" end end end
Private Instance Methods
attach(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 182 def attach(volume) converge_by "attach #{new_resource} to #{new_resource.machine} (#{expected_instance.instance_id}) to device #{new_resource.device}" do volume.attach_to_instance(instance_id: expected_instance.id, device: new_resource.device) end converge_by "wait for #{new_resource} to attach" do wait_for_volume_status(volume, :in_use) volume end end
availability_zone()
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 215 def availability_zone az = new_resource.availability_zone if /^#{region}/ =~ az Chef::Log.warn("availability_zone attribute should only be set to the letter designation. Attempting to use '#{az[-1]}' to correct the issue.") elsif az.length == 1 az = "#{region}#{az[-1]}" end az end
current_attachment(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 193 def current_attachment(volume) volume.attachments.first end
delete(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 197 def delete(volume) converge_by "delete #{new_resource} in #{region}" do volume.delete end converge_by "wait for #{new_resource} in #{region} to delete" do log_callback = proc { Chef::Log.info("waiting for volume to delete...") } Retryable.retryable(tries: 30, sleep: 2, on: VolumeStatusTimeoutError, ensure: log_callback) do result = new_resource.driver.ec2_resource.volume(volume.id) if volume.id raise VolumeStatusTimeoutError.new(new_resource, "exists", "deleted") if new_resource.exists?(result) end volume end end
detach(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 167 def detach(volume) attachment = current_attachment(volume) instance = attachment.instance_id device = attachment.device converge_by "detach #{new_resource} from #{new_resource.machine} (#{instance})" do volume.detach_from_instance(instance_id: instance, device: device) end converge_by "wait for #{new_resource} to detach" do wait_for_volume_status(volume, :available) volume end end
expected_instance()
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 93 def expected_instance unless defined?(@expected_instance) if new_resource.machine == false @expected_instance = nil else @expected_instance = Chef::Resource::AwsInstance.get_aws_object(new_resource.machine, resource: new_resource) end end @expected_instance end
initial_options()
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 104 def initial_options @initial_options ||= begin options = {} options[:availability_zone] = availability_zone unless new_resource.availability_zone.nil? options[:size] = new_resource.size unless new_resource.size.nil? options[:snapshot_id] = new_resource.snapshot unless new_resource.snapshot.nil? options[:iops] = new_resource.iops unless new_resource.iops.nil? options[:volume_type] = new_resource.volume_type unless new_resource.volume_type.nil? options[:encrypted] = new_resource.encrypted unless new_resource.encrypted.nil? options[:encrypted] = !!options[:encrypted] unless options[:encrypted].nil? AWSResource.lookup_options(options, resource: new_resource) end end
update_attachment(volume)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 119 def update_attachment(volume) status = new_resource.driver.ec2_resource.volume(volume.id).state # # If we were told to attach the volume to a machine, do so # if expected_instance.is_a?(::Aws::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance) case status when "in-use" # We don't want to attempt to reattach to the same instance and device attachment = current_attachment(volume) if attachment.instance_id != expected_instance.id || attachment.device != new_resource.device detach(volume) attach(volume) end when "available" attach(volume) when nil raise VolumeNotFoundError, new_resource else raise VolumeInvalidStatusError.new(new_resource, status) end # # If we were told to set the machine to false, detach it. # else case status when nil Chef::Log.warn VolumeNotFoundError.new(new_resource) when "in-use" detach(volume) end end volume end
wait_for_volume_status(volume, expected_status)
click to toggle source
# File lib/chef/provider/aws_ebs_volume.rb, line 155 def wait_for_volume_status(volume, expected_status) log_callback = proc { Chef::Log.info("waiting for #{new_resource} status to change to #{expected_status}...") } Retryable.retryable(tries: 120, sleep: 2, on: VolumeStatusTimeoutError, ensure: log_callback) do status = new_resource.driver.ec2_resource.volume(volume.id).state expected_status = "in-use" if expected_status.to_s.eql?("in_use") raise VolumeStatusTimeoutError.new(new_resource, status, expected_status) if status != expected_status.to_s end end