Class: Chef::Knife::NcServerCreate

Inherits:
Chef::Knife show all
Includes:
NcBase
Defined in:
lib/chef/knife/nc_server_create.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from NcBase

#connection, included, #locate_config_value, #msg_pair

Instance Attribute Details

#initial_sleep_delayObject

Returns the value of attribute initial_sleep_delay.



37
38
39
# File 'lib/chef/knife/nc_server_create.rb', line 37

def initial_sleep_delay
  @initial_sleep_delay
end

Instance Method Details

#bootstrap_for_node(server, fqdn) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/chef/knife/nc_server_create.rb', line 221

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[:ssh_password] = config[:ssh_password]
  bootstrap.config[:ssh_passphrase] = config[:ssh_passphrase]
  bootstrap.config[:identity_file] = config[:identity_file]
  bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.instanceId
  bootstrap.config[:prerelease] = config[:prerelease]
  bootstrap.config[:bootstrap_version] = locate_config_value(:nc_bootstrap_version)

  image_id = locate_config_value(:nc_image_id)
	if locate_config_value(:nc_distro)
    bootstrap.config[:distro] = locate_config_value(:nc_distro)
  elsif %w(1 2 6 7 13 14).include?(image_id)
    bootstrap.config[:distro] = 'nc-centos5-gems'
  elsif image_id == '17'
    bootstrap.config[:distro] = 'ubuntu10.04-gems'
  elsif image_id == '21'
    bootstrap.config[:distro] = 'nc-centos6-gems'
	else
    bootstrap.config[:distro] = 'nc-centos5-gems'
  end

  bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
  bootstrap.config[:template_file] = locate_config_value(:nc_template_file)
  bootstrap.config[:environment] = config[:environment]
  bootstrap
end

#create_server_defObject



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/chef/knife/nc_server_create.rb', line 280

def create_server_def
  server_def = {
    :instance_id => @name_args.first,
    :image_id => locate_config_value(:nc_image_id),
    :instance_type => locate_config_value(:nc_instance_type),
    :security_group => config[:security_group],
    :key_name => Chef::Config[:knife][:nc_ssh_key_id],
    :disable_api_termination => false # for 'knife nc server delete' command
  }

  if Chef::Config[:knife][:nc_user_data]
    begin
      server_def.merge!(:user_data => File.read(locate_config_value(:nc_user_data)))
    rescue
      ui.warn("Cannot read #{Chef::Config[:knife][:nc_user_data]}: #{$!.inspect}. Ignoring option.")
    end
  end

  server_def
end

#imageObject



252
253
254
# File 'lib/chef/knife/nc_server_create.rb', line 252

def image
  @image ||= connection.describe_images(:image_id => locate_config_value(:nc_image_id)).imagesSet.item.first
end

#runObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/chef/knife/nc_server_create.rb', line 163

def run
  $stdout.sync = true
  NIFTY::LOG.level = Logger::DEBUG

  validate!

  msg_pair("Instance ID", @name_args.first)
  msg_pair("Instance Type", locate_config_value(:nc_instance_type))
  msg_pair("Image", locate_config_value(:nc_image_id))
  msg_pair("SSH Key", locate_config_value(:nc_ssh_key_id))
  msg_pair("Security Group", config[:security_group])

  puts "\n"
  confirm("Do you really want to create this server")

  server = connection.run_instances(create_server_def).instancesSet.item.first

  msg_pair("Instance ID", server.instanceId)
  msg_pair("Instance Type", server.instanceType)
  msg_pair("Image", server.imageId)
  msg_pair("SSH Key", server.keyName)

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

  # wait for it to be ready to do stuff
  while server.instanceState.name != 'running'
    print "."
    server = connection.describe_instances(:instance_id => server.instanceId).reservationSet.item.first.instancesSet.item.first
    sleep 5
  end

  puts("done\n")
  
  msg_pair("Public IP Address", server.ipAddress)
  msg_pair("Private IP Address", server.privateIpAddress)

  ssh_ip_address = config[:ssh_locally] ? server.privateIpAddress : server.ipAddress
  print "\n#{ui.color("Waiting for sshd", :magenta)} (using #{ssh_ip_address})"
  
  print(".") until tcp_test_ssh(ssh_ip_address) {
    sleep @initial_sleep_delay ||= 10
    puts("done")
  }

  bootstrap_for_node(server, ssh_ip_address).run

  puts "\n"
  msg_pair("Instance ID", server.instanceId)
  msg_pair("Instance Type", server.instanceType)
  msg_pair("Image ID", server.imageId)
  msg_pair("Security Group", config[:security_group])
  msg_pair("SSH Key", server.keyName)
  msg_pair("Public IP Address", server.ipAddress)
  msg_pair("Private IP Address", server.privateIpAddress)
  msg_pair("Environment", config[:environment] || '_default')
  msg_pair("Run List", config[:run_list].join(', '))
end

#tcp_test_ssh(hostname) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/chef/knife/nc_server_create.rb', line 136

def tcp_test_ssh(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
  sleep 2
  false
rescue Errno::ETIMEDOUT
  false
rescue Errno::EPERM
  false
rescue Errno::ECONNREFUSED
  sleep 2
  false
rescue Errno::EHOSTUNREACH
  sleep 2
  false
ensure
  tcp_socket && tcp_socket.close
end

#validate!Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/chef/knife/nc_server_create.rb', line 256

def validate!
  super([:nc_image_id, :nc_ssh_key_id, :nc_access_key, :nc_secret_key])

  errors = []

  if @name_args.empty?
    errors << "You have not provided a valid instance ID."
  end

  if config[:security_group].nil?
    errors << "You have not provided a valid Security Group."
  end

  [:identity_file, :nc_template_file, :nc_user_data].each do |x|
    if (path = locate_config_value(x)) && !File.exists?(path)
      errors << "File does not exist: #{path}"
    end
  end

  if errors.each{|e| ui.error(e)}.any?
    exit 1
  end
end