class Chef::Knife::SceServerCreate
Attributes
initial_sleep_delay[RW]
server[R]
Public Instance Methods
bootstrap_for_node(server,ssh_host)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 284 def bootstrap_for_node(server,ssh_host) # Chef::Knife:Ssh is going to use ssh_user setting from knife.rb # over the one that we hand to it. # To overrule this setting we have to override to Chef knife.rb setting. Chef::Config[:knife][:ssh_user] = config[:sce_ssh_user] bootstrap = Chef::Knife::Bootstrap.new bootstrap.name_args = [ssh_host] bootstrap.config[:run_list] = locate_config_value(:run_list) || [] bootstrap.config[:ssh_user] = config[:sce_ssh_user] bootstrap.config[:ssh_port] = config[:ssh_port] bootstrap.config[:ssh_gateway] = config[:ssh_gateway] bootstrap.config[:identity_file] = config[:identity_file] bootstrap.config[:chef_node_name] = locate_config_value(:chef_node_name) || server.id bootstrap.config[:prerelease] = config[:prerelease] bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version) bootstrap.config[:first_boot_attributes] = locate_config_value(:json_attributes) || {} bootstrap.config[:distro] = locate_config_value(:distro) || "chef-full" bootstrap.config[:use_sudo] = true unless config[:sce_ssh_user] == 'root' bootstrap.config[:template_file] = locate_config_value(:template_file) bootstrap.config[:environment] = config[:environment] bootstrap.config[:host_key_verify] = config[:host_key_verify] bootstrap end
create_server_def()
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 349 def create_server_def server_def = { :name => locate_config_value(:chef_node_name), :image_id => locate_config_value(:sce_image), :instance_type => locate_config_value(:sce_flavor), :location => datacenter_id, :key_name => locate_config_value(:sce_key_name) } if locate_config_value(:sce_vlan_id) server_def[:vlan_id] = locate_config_value(:sce_vlan_id) end if locate_config_value(:secondary_ip) server_def[:secondary_ip] = locate_config_value(:secondary_ip) end %w{ip is_mini_ephemeral configuration_data anti_collocation_instance volume_id}.each do |parm| server_def[parm.to_sym] = locate_config_value(parm.to_sym) if locate_config_value(parm.to_sym) end server_def end
eip_scope()
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 341 def eip_scope if vlan_mode? "vpc" else "standard" end end
run()
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 209 def run $stdout.sync = true Fog.timeout = Chef::Config[:knife][:sce_max_timeout] || 6000 validate! requested_ip = config[:associate_ip] if config[:associate_ip] # For VPC EIP assignment we need the allocation ID so fetch full EIP details # elastic_ip = connection.addresses.detect{|addr| addr if addr.public_ip == requested_elastic_ip} begin definition = create_server_def # SCE library gives me an excon response object, we have to fetch the server object ourselves: excon_response = connection.create_instance(definition[:name], definition[:image_id], definition[:instance_type], definition[:location], definition) @server = connection.servers.get(excon_response.data[:body]["instances"][0]["id"]) raise "Creating a server failed." if @server.nil? msg_pair("Instance ID", @server.id.to_s) msg_pair("Name", @server.name.to_s) msg_pair("Flavor", @server.instance_type.to_s) msg_pair("Image", @server.image.name.to_s) msg_pair("Region", @server.location.location) msg_pair("SSH Key", @server.key_name.to_s) msg_pair("Owner", @server.owner.to_s) msg_pair("Environment", config[:environment] || '_default') msg_pair("Run List", (config[:run_list] || []).join(', ')) msg_pair("JSON Attributes",config[:json_attributes]) unless !config[:json_attributes] || config[:json_attributes].empty? msg_pair("VLAN ID", @server.primary_ip["vlan"]["name"].to_s) if @server.primary_ip["vlan"] msg_pair("Volume IDs", @server.volume_ids.join(",").to_s) if @server.volume_ids print "\n#{ui.color("Waiting for server", :magenta)}" @server.wait_for { print "."; ready? } msg_pair("\nPublic DNS Name", @server.primary_ip["hostname"].to_s) msg_pair("Public IP Address", @server.primary_ip["ip"].to_s) if @server.secondary_ip ips = [] @server.secondary_ip.each {|item| ips << item['ip']} msg_pair("Secondary IP Addresses", ips.join(",")) end wait_for_sshd(ssh_connect_host) Chef::Config[:knife][:hints] ||= {} Chef::Config[:knife][:hints]["sce"] ||= {} Chef::Config[:knife][:hints]["sce"].merge!({ 'server_id' => @server.id.to_s, 'region' => @server.location.location, 'flavor' => @server.instance_type.to_s, 'image' => @server.image.name.to_s }) if @server.primary_ip["vlan"] Chef::Config[:knife][:hints]["sce"].merge!({ 'vlan' => @server.primary_ip["vlan"]["name"].to_s }) end if @server.volume_ids Chef::Config[:knife][:hints]["sce"].merge!({ 'volumes' => @server.volume_ids }) end bootstrap_for_node(@server, ssh_connect_host).run unless locate_config_value(:no_bootstrap) rescue Excon::Errors::PreconditionFailed => e ui.error e.response.data[:body] exit 1 end end
ssh_connect_host()
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 405 def ssh_connect_host @ssh_connect_host ||= if config[:server_connect_attribute] server.send(config[:server_connect_attribute]) else server.ip.to_s end end
tcp_test_ssh(hostname, ssh_port) { || ... }
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 186 def tcp_test_ssh(hostname, ssh_port) tcp_socket = TCPSocket.new(hostname, ssh_port) readable = IO.select([tcp_socket], nil, nil, 5) if readable Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}") yield true else false end rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError sleep 2 false rescue Errno::EPERM, Errno::ETIMEDOUT false ensure tcp_socket && tcp_socket.close end
tunnel_test_ssh(hostname, &block)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 382 def tunnel_test_ssh(hostname, &block) gw_host, gw_user = config[:ssh_gateway].split('@').reverse gw_host, gw_port = gw_host.split(':') gateway = Net::SSH::Gateway.new(gw_host, gw_user, :port => gw_port || 22) status = false gateway.open(hostname, config[:ssh_port]) do |local_tunnel_port| status = tcp_test_ssh('localhost', local_tunnel_port, &block) end status rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError sleep 2 false rescue Errno::EPERM, Errno::ETIMEDOUT false end
validate!()
click to toggle source
Calls superclass method
# File lib/chef/knife/sce_server_create.rb, line 316 def validate! super([:ibm_username, :ibm_password]) if locate_config_value(:sce_flavor).nil? ui.error("No flavor provided. Use knife sce image describe to list supported flavors for used image.") exit 1 else flavor_found = false requested_image = connection.images.get(locate_config_value(:sce_image)) requested_image.supported_instance_types.each do |sit| if sit.id.to_s.eql?( locate_config_value(:sce_flavor) ) flavor_found = true end end if !flavor_found ui.error("Flavor #{config[:sce_flavor]} is not supported for image #{locate_config_value(:sce_image)}. Use knife sce image describe to list supported flavors for used image.") exit 1 end end end
vlan_mode?()
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 310 def vlan_mode? # Amazon Virtual Private Cloud requires a subnet_id. If # present, do a few things differently !!locate_config_value(:vlan_id) end
wait_for_direct_sshd(hostname, ssh_port)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 398 def wait_for_direct_sshd(hostname, ssh_port) print(".") until tcp_test_ssh(ssh_connect_host, ssh_port) { sleep @initial_sleep_delay ||= (vlan_mode? ? 40 : 10) puts("done") } end
wait_for_server_active(server)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 205 def wait_for_server_active(server) server.wait_for { print "."; ready? } end
wait_for_sshd(hostname)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 370 def wait_for_sshd(hostname) config[:ssh_gateway] ? wait_for_tunnelled_sshd(hostname) : wait_for_direct_sshd(hostname, config[:ssh_port]) end
wait_for_tunnelled_sshd(hostname)
click to toggle source
# File lib/chef/knife/sce_server_create.rb, line 374 def wait_for_tunnelled_sshd(hostname) print(".") print(".") until tunnel_test_ssh(ssh_connect_host) { sleep @initial_sleep_delay ||= (vlan_mode? ? 40 : 10) puts("done") } end