lib/cucumber/chef/providers/aws.rb in cucumber-chef-2.1.0.rc.2 vs lib/cucumber/chef/providers/aws.rb in cucumber-chef-2.1.0.rc.3

- old
+ new

@@ -23,239 +23,208 @@ class Provider class AWSError < Error; end class AWS - attr_accessor :stdout, :stderr, :stdin, :logger + attr_accessor :connection, :server, :stdout, :stderr, :stdin, :logger - INVALID_STATES = %w( terminated pending ) - RUNNING_STATES = %w( running starting-up ) - SHUTDOWN_STATES = %w( shutdown stopping stopped shutting-down ) + INVALID_STATES = %w(terminated pending).map(&:to_sym) + RUNNING_STATES = %w(running starting-up).map(&:to_sym) + SHUTDOWN_STATES = %w(shutdown stopping stopped shutting-down).map(&:to_sym) VALID_STATES = RUNNING_STATES+SHUTDOWN_STATES ################################################################################ def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN, logger=$logger) @stdout, @stderr, @stdin, @logger = stdout, stderr, stdin, logger @stdout.sync = true if @stdout.respond_to?(:sync=) @connection = Fog::Compute.new( :provider => 'AWS', - :aws_access_key_id => Cucumber::Chef::Config[:aws][:aws_access_key_id], - :aws_secret_access_key => Cucumber::Chef::Config[:aws][:aws_secret_access_key], - :region => Cucumber::Chef::Config[:aws][:region] + :aws_access_key_id => Cucumber::Chef::Config.aws[:aws_access_key_id], + :aws_secret_access_key => Cucumber::Chef::Config.aws[:aws_secret_access_key], + :region => Cucumber::Chef::Config.aws[:region] ) ensure_security_group + + @server = filter_servers(@connection.servers, VALID_STATES) end ################################################################################ +# CREATE +################################################################################ def create - if (lab_exists? && (@server = labs_running.first)) - @stdout.puts("A test lab already exists using the AWS credentials you have supplied; attempting to reprovision it.") + if (exists? && alive?) + @stdout.puts("A test lab already exists using the #{Cucumber::Chef::Config.provider.upcase} credentials you have supplied; attempting to reprovision it.") else server_definition = { :image_id => Cucumber::Chef::Config.aws_image_id, - :groups => Cucumber::Chef::Config[:aws][:aws_security_group], - :flavor_id => Cucumber::Chef::Config[:aws][:aws_instance_type], - :key_name => Cucumber::Chef::Config[:aws][:aws_ssh_key_id], - :availability_zone => Cucumber::Chef::Config[:aws][:availability_zone], - :tags => { "purpose" => "cucumber-chef", "cucumber-chef-mode" => Cucumber::Chef::Config[:mode] }, - :identity_file => Cucumber::Chef::Config[:aws][:identity_file] + :groups => Cucumber::Chef::Config.aws[:aws_security_group], + :flavor_id => Cucumber::Chef::Config.aws[:aws_instance_type], + :key_name => Cucumber::Chef::Config.aws[:aws_ssh_key_id], + :availability_zone => Cucumber::Chef::Config.aws[:availability_zone], + :tags => { "purpose" => "cucumber-chef", "cucumber-chef-mode" => Cucumber::Chef::Config.mode }, + :identity_file => Cucumber::Chef::Config.aws[:identity_file] } - if (@server = @connection.servers.create(server_definition)) - @stdout.puts("Provisioning cucumber-chef test lab platform.") - @stdout.print("Waiting for instance...") - Cucumber::Chef.spinner do + if (@server = @connection.servers.create(server_definition)) + ZTK::Benchmark.bench(:message => "Creating #{Cucumber::Chef::Config.provider.upcase} instance", :mark => "completed in %0.4f seconds.", :stdout => @stdout) do @server.wait_for { ready? } + tag_server + ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait end - @stdout.puts("done.\n") - - tag_server - - @stdout.print("Waiting for 20 seconds...") - Cucumber::Chef.spinner do - sleep(20) - end - @stdout.print("done.\n") end end - if @server - @stdout.print("Waiting for SSHD...") - Cucumber::Chef.spinner do - ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait - end - @stdout.puts("done.\n") - end - self rescue Exception => e Cucumber::Chef.logger.fatal { e.message } Cucumber::Chef.logger.fatal { "Backtrace:\n#{e.backtrace.join("\n")}" } raise AWSError, e.message end ################################################################################ +# DESTROY +################################################################################ def destroy - if ((l = labs).count > 0) - @stdout.puts("Destroying Servers:") - l.each do |server| - @stdout.puts(" * #{server.public_ip_address}") - server.destroy - end + if exists? + @server.destroy else - @stdout.puts("There are no cucumber-chef test labs to destroy!") + raise AWSError, "We could not find a test lab!" end rescue Exception => e Cucumber::Chef.logger.fatal { e.message } Cucumber::Chef.logger.fatal { e.backtrace.join("\n") } raise AWSError, e.message end ################################################################################ +# UP +################################################################################ def up - if (lab_exists? && (@server = labs_shutdown.first)) + if (exists? && dead?) if @server.start + @server.wait_for { ready? } + ZTK::TCPSocketCheck.new(:host => self.ip, :port => self.port, :wait => 120).wait + else + raise AWSError, "Failed to boot the test lab!" + end + else + raise AWSError, "We could not find a powered off test lab." + end - @stdout.print("Waiting for instance...") - Cucumber::Chef.spinner do - @server.wait_for { ready? } - end - @stdout.puts("done.\n") + rescue Exception => e + Cucumber::Chef.logger.fatal { e.message } + Cucumber::Chef.logger.fatal { e.backtrace.join("\n") } + raise AWSError, e.message + end - @stdout.print("Waiting for SSHD...") - Cucumber::Chef.spinner do - ZTK::TCPSocketCheck.new(:host => @server.public_ip_address, :port => 22, :wait => 120).wait - end - @stdout.puts("done.\n") +################################################################################ +# HALT +################################################################################ - @stdout.puts("Successfully started up cucumber-chef test lab!") - - info - else - @stdout.puts("Failed to start up cucumber-chef test lab!") + def halt + if (exists? && alive?) + if !@server.stop + raise AWSError, "Failed to halt the test lab!" end else - @stdout.puts("There are no available cucumber-chef test labs to start up!") + raise AWSError, "We could not find a running test lab." end rescue Exception => e Cucumber::Chef.logger.fatal { e.message } Cucumber::Chef.logger.fatal { e.backtrace.join("\n") } raise AWSError, e.message end ################################################################################ +# RELOAD +################################################################################ - def down - if (lab_exists? && (@server = labs_running.first)) - if @server.stop - @stdout.puts("Successfully shutdown cucumber-chef test lab!") - else - @stdout.puts("Failed to shutdown cucumber-chef test lab!") + def reload + if (exists? && alive?) + if !@server.restart + raise AWSError, "Failed to reload the test lab!" end else - @stdout.puts("There are no available cucumber-chef test labs top shutdown!") + raise AWSError, "We could not find a running test lab." end rescue Exception => e Cucumber::Chef.logger.fatal { e.message } Cucumber::Chef.logger.fatal { e.backtrace.join("\n") } raise AWSError, e.message end ################################################################################ + def exists? + !!@server + end + + def alive? + (exists? && RUNNING_STATES.include?(self.state)) + end + + def dead? + (exists? && SHUTDOWN_STATES.include?(self.state)) + end + +################################################################################ + def id - labs_running.first.id + @server.id end def state - labs_running.first.state + @server.state.to_sym end def username - labs_running.first.username + @server.username end def ip - labs_running.first.public_ip_address + @server.public_ip_address end def port 22 end -################################################################################ - def lab_exists? - (labs.size > 0) - end - ################################################################################ - - def labs - @servers ||= @connection.servers - results = @servers.select do |server| - Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" } - ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s && - server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s && - VALID_STATES.any?{ |state| state == server.state } ) - end - results.each do |server| - Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" } - end - results - end - + private ################################################################################ - def labs_running - @servers ||= @connection.servers - results = @servers.select do |server| - Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" } - ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s && - server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s && - RUNNING_STATES.any?{ |state| state == server.state } ) - end - results.each do |server| - Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" } - end - results - end + def filter_servers(servers, states=VALID_STATES) + Cucumber::Chef.logger.debug("states") { states.collect{ |s| s.inspect }.join(", ") } + results = servers.select do |server| + Cucumber::Chef.logger.debug("candidate") { "id=#{server.id.inspect}, state=#{server.state.inspect}, tags=#{server.tags.inspect}" } -################################################################################ - - def labs_shutdown - @servers ||= @connection.servers - results = @servers.select do |server| - Cucumber::Chef.logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" } - ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s && - server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s && - SHUTDOWN_STATES.any?{ |state| state == server.state } ) + ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config.mode.to_s && + server.tags['cucumber-chef-user'] == Cucumber::Chef::Config.user.to_s && + states.any?{ |state| state.to_s == server.state } ) end results.each do |server| - Cucumber::Chef.logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" } + Cucumber::Chef.logger.debug("results") { "id=#{server.id.inspect}, state=#{server.state.inspect}" } end - results + results.first end - ################################################################################ - private -################################################################################ def tag_server { - "cucumber-chef-mode" => Cucumber::Chef::Config[:mode], - "cucumber-chef-user" => Cucumber::Chef::Config[:user], + "cucumber-chef-mode" => Cucumber::Chef::Config.mode, + "cucumber-chef-user" => Cucumber::Chef::Config.user, "purpose" => "cucumber-chef" }.each do |k, v| tag = @connection.tags.new tag.resource_id = @server.id tag.key, tag.value = k, v @@ -264,10 +233,10 @@ end ################################################################################ def ensure_security_group - security_group_name = Cucumber::Chef::Config[:aws][:aws_security_group] + security_group_name = Cucumber::Chef::Config.aws[:aws_security_group] if (security_group = @connection.security_groups.get(security_group_name)) port_ranges = security_group.ip_permissions.collect{ |entry| entry["fromPort"]..entry["toPort"] } security_group.authorize_port_range(22..22) if port_ranges.none?{ |port_range| port_range === 22 } security_group.authorize_port_range(4000..4000) if port_ranges.none?{ |port_range| port_range === 4000 } security_group.authorize_port_range(4040..4040) if port_ranges.none?{ |port_range| port_range === 4040 }