class Chef::Knife::LinodeServerCreate

Attributes

initial_sleep_delay[RW]

Public Instance Methods

bootstrap_for_node(server, fqdn) click to toggle source
# File lib/chef/knife/linode_server_create.rb, line 266
def bootstrap_for_node(server, fqdn)
  bootstrap = Chef::Knife::Bootstrap.new
  bootstrap.name_args = [fqdn]
  bootstrap.config[:run_list] = config[:run_list]
  bootstrap.config[:ssh_user] = config[:ssh_user]
  bootstrap.config[:identity_file] = config[:identity_file]
  bootstrap.config[:ssh_password] = locate_config_value(:ssh_password)
  bootstrap.config[:chef_node_name] = config[: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)
  bootstrap.config[:use_sudo] = true unless config[: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.config[:secret] = locate_config_value(:secret)
  bootstrap.config[:secret_file] = locate_config_value(:secret_file)
  bootstrap.config[:private_ip] = server.ips.reject { |ip| ip.public }.first.ip
  bootstrap.config[:public_ip] = server.public_ip_address
  bootstrap
end
run() click to toggle source
# File lib/chef/knife/linode_server_create.rb, line 199
def run
  $stdout.sync = true

  validate!

  raise "You must provide linode_node_name via the CLI or knife.rb config. See help for details" if locate_config_value(:linode_node_name).nil?

  datacenter_id = locate_config_value(:linode_datacenter).to_i
  datacenter = connection.data_centers.select { |dc| dc.id == datacenter_id }.first

  flavor = connection.flavors.get(locate_config_value(:linode_flavor).to_i)

  image = connection.images.get(locate_config_value(:linode_image).to_i)

  kernel = connection.kernels.get(locate_config_value(:linode_kernel).to_i)

  # FIXME: tweakable stack_script
  # FIXME: tweakable payment terms
  # FIXME: tweakable disk type

  server = connection.servers.create(
              :data_center => datacenter,
              :flavor => flavor,
              :image => image,
              :kernel => kernel,
              :type => "ext3",
              :payment_terms => 1,
              :stack_script => nil,
              :name => locate_config_value(:linode_node_name),
              :password => locate_config_value(:ssh_password)
           )

  connection.linode_update(server.id, { :lpm_displaygroup => config[:display_group] }) if config[:display_group]

  fqdn = server.ips.select { |lip| !( lip.ip =~ /^192\.168\./ || lip.ip =~ /^10\./ || lip.ip =~ /^172\.(1[6-9]|2[0-9]|3[0-1])\./ ) }.first.ip

  msg_pair("Linode ID", server.id.to_s)
  msg_pair("Name", server.name)
  msg_pair("IPs", server.ips.map { |x| x.ip }.join(",") )
  msg_pair("Status", status_to_ui(server.status) )
  msg_pair("Public IP", fqdn)
  msg_pair("User", config[:ssh_user])
  password = locate_config_value(:ssh_password)
  if password == @@defpass
    msg_pair("Password", password)
  end

  print "\n#{ui.color("Waiting for sshd", :magenta)}"

  print(".") until tcp_test_ssh(fqdn) do
    sleep @initial_sleep_delay ||= 10
    puts("done")
  end

  Chef::Config[:knife][:hints]["linode"] ||= Hash.new
  Chef::Config[:knife][:hints]["linode"].merge!({
      "server_id" => server.id.to_s,
      "datacenter_id" => locate_config_value(:linode_datacenter),
      "flavor_id" => locate_config_value(:linode_flavor),
      "image_id" => locate_config_value(:linode_image),
      "kernel_id" => locate_config_value(:linode_kernel),
      "ip_addresses" => server.ips.map(&:ip) })

  msg_pair("JSON Attributes", config[:json_attributes]) unless !config[:json_attributes] || config[:json_attributes].empty?
  bootstrap_for_node(server, fqdn).run
end
tcp_test_ssh(hostname) { || ... } click to toggle source
# File lib/chef/knife/linode_server_create.rb, line 166
def tcp_test_ssh(hostname)
  Chef::Log.debug("testing ssh connection to #{hostname}")
  tcp_socket = TCPSocket.new(hostname, 22)
  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
  Chef::Log.debug("SocketError, retrying")
  sleep 2
  false
rescue Errno::ETIMEDOUT
  Chef::Log.debug("ETIMEDOUT, retrying")
  false
rescue Errno::EPERM
  Chef::Log.debug("EPERM, retrying")
  false
rescue Errno::ECONNREFUSED
  Chef::Log.debug("ECONNREFUSED, retrying")
  sleep 2
  false
rescue Errno::EHOSTUNREACH
  Chef::Log.debug("EHOSTUNREACH, retrying")
  sleep 2
  false
ensure
  tcp_socket && tcp_socket.close
end