stack-kicker 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/stack-kicker/version.rb +1 -1
- data/lib/stack.rb +53 -19
- metadata +1 -1
data/lib/stack-kicker/version.rb
CHANGED
data/lib/stack.rb
CHANGED
@@ -30,6 +30,7 @@ require 'tempfile'
|
|
30
30
|
# This really needs to be converted into a class....
|
31
31
|
#
|
32
32
|
module Stack
|
33
|
+
include Methadone::SH
|
33
34
|
|
34
35
|
# Shadow the global constant Logger with Stack::Logger
|
35
36
|
# (if you want access to the global constant, use ::Logger from inside the Stack module)
|
@@ -39,6 +40,7 @@ module Stack
|
|
39
40
|
Logger.formatter = proc do |severity, datetime, progname, msg|
|
40
41
|
"#{datetime} #{severity}: #{msg}\n"
|
41
42
|
end
|
43
|
+
set_sh_logger(Logger)
|
42
44
|
|
43
45
|
# location of gem, where config[:gemhome]/lib contains our default cloud-init templates
|
44
46
|
@@gemhome = File.absolute_path(File.realpath(File.dirname(File.expand_path(__FILE__)) + '/..'))
|
@@ -142,7 +144,7 @@ module Stack
|
|
142
144
|
# check that we have semi-sensible Chef setup
|
143
145
|
# at a bare minimum, we need the directory where we're going to download
|
144
146
|
# validation.pem to to exist
|
145
|
-
dot_chef_abs = File.absolute_path(config[:stackhome]
|
147
|
+
dot_chef_abs = File.absolute_path(File.join(config[:stackhome], config[:dot_chef]))
|
146
148
|
if !File.directory?(dot_chef_abs)
|
147
149
|
Logger.warn "#{dot_chef_abs} doesn't exist"
|
148
150
|
end
|
@@ -166,7 +168,7 @@ module Stack
|
|
166
168
|
# this lazily assumes that the :key_pair name matches the file the keys were loaded
|
167
169
|
# from
|
168
170
|
if (0 == 1)
|
169
|
-
ssh_keys_loaded =
|
171
|
+
ssh_keys_loaded = Stack.shellout(config, "ssh-add -L")
|
170
172
|
Logger.debug "ssh_keys_loaded: #{ssh_keys_loaded}"
|
171
173
|
Logger.debug "Looking for #{config[:key_pair]}"
|
172
174
|
if ssh_keys_loaded.include?(config[:key_pair])
|
@@ -242,15 +244,15 @@ module Stack
|
|
242
244
|
end
|
243
245
|
|
244
246
|
# CWD shoud be chef-repo/bootstrap, so the project .chef directory should be
|
245
|
-
dot_chef_abs = File.absolute_path(config[:stackhome]
|
247
|
+
dot_chef_abs = File.absolute_path(File.join(config[:stackhome],config[:dot_chef]))
|
246
248
|
|
247
249
|
if !File.directory?(dot_chef_abs)
|
248
250
|
Logger.warn "#{dot_chef_abs} doesn't exist, creating it..."
|
249
251
|
Dir.mkdir(dot_chef_abs)
|
250
252
|
end
|
251
253
|
|
252
|
-
client_key = dot_chef_abs
|
253
|
-
validation_key = dot_chef_abs
|
254
|
+
client_key = File.join(dot_chef_abs, config[:name] + '-' + ENV['USER'] + '.pem')
|
255
|
+
validation_key = File.join(dot_chef_abs, config[:name] + '-' + 'validation.pem')
|
254
256
|
|
255
257
|
Logger.debug "stackhome: #{config[:stackhome]}"
|
256
258
|
Logger.debug "Current user client key: #{client_key}"
|
@@ -260,9 +262,9 @@ module Stack
|
|
260
262
|
log_level :info
|
261
263
|
log_location STDOUT
|
262
264
|
node_name '<%=ENV['USER']%>'
|
263
|
-
client_key '<%=
|
265
|
+
client_key '<%=client_key%>'
|
264
266
|
validation_client_name 'chef-validator'
|
265
|
-
validation_key '<%=
|
267
|
+
validation_key '<%=validation_key%>'
|
266
268
|
chef_server_url '<%=config[:chef_server_public]%>'
|
267
269
|
cache_type 'BasicFile'
|
268
270
|
cache_options( :path => '<%=dot_chef_abs%>/checksums' )
|
@@ -306,6 +308,10 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
306
308
|
# config[:role_details] contains built out role details with defaults filled in from stack defaults
|
307
309
|
# config[:node_details] contains node details built out from role_details
|
308
310
|
|
311
|
+
if config[:find_file_paths].nil?
|
312
|
+
config[:find_file_paths] = Array.new
|
313
|
+
end
|
314
|
+
|
309
315
|
# set some sensible defaults to the stack-wide defaults if they haven't been set in the Stackfile.
|
310
316
|
if config[:provisioner].nil?
|
311
317
|
Logger.warn { "Defaulting to chef for config[:provisioner] "}
|
@@ -326,6 +332,7 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
326
332
|
Logger.warn { "Defaulting to .chef/validation.pem for config[:chef_validation_pem]" }
|
327
333
|
config[:chef_validation_pem] = '.chef/validation.pem'
|
328
334
|
end
|
335
|
+
config[:chef_validation_pem] = Stack.find_file(config, config[:chef_validation_pem])
|
329
336
|
|
330
337
|
if config[:name_template].nil?
|
331
338
|
Logger.warn { "Defaulting to '%s-%s-%s%04d' for config[:name_template]" }
|
@@ -346,10 +353,6 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
346
353
|
config[:metadata] = Hash.new
|
347
354
|
end
|
348
355
|
|
349
|
-
if config[:find_file_paths].nil?
|
350
|
-
config[:find_file_paths] = Array.new
|
351
|
-
end
|
352
|
-
|
353
356
|
if config[:node_details].nil?
|
354
357
|
Logger.debug { "Initializing config[:node_details] and config[:azs]" }
|
355
358
|
config[:node_details] = Hash.new
|
@@ -531,7 +534,7 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
531
534
|
servers.each do |host, details|
|
532
535
|
public_ip = Stack.get_public_ip(config, host)
|
533
536
|
Logger.info { "#{host} #{public_ip}" }
|
534
|
-
cmd_output =
|
537
|
+
cmd_output = Stack.shellout(config, %Q[ssh -oStrictHostKeyChecking=no -l #{user} #{public_ip} "#{command}"])
|
535
538
|
Logger.info { "#{host} #{public_ip} #{cmd_output}" }
|
536
539
|
end
|
537
540
|
else
|
@@ -708,11 +711,11 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
708
711
|
else
|
709
712
|
# Prepare Chef
|
710
713
|
# 1) delete the client if it exists
|
711
|
-
knife_client_list =
|
714
|
+
knife_client_list = Stack.shellout(config, "knife client list | grep #{hostname}")
|
712
715
|
knife_client_list.sub!(/\s/,'')
|
713
716
|
if knife_client_list.length() > 0
|
714
717
|
# we should delete the client to make way for this new machine
|
715
|
-
|
718
|
+
Stack.shellout(config, "knife client delete --yes #{hostname}")
|
716
719
|
end
|
717
720
|
|
718
721
|
# knife node create -d --environment $CHEF_ENVIRONMENT $SERVER_NAME
|
@@ -720,12 +723,12 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
720
723
|
# this relies on .chef matching the stacks config (TODO: poke the Chef API directly?)
|
721
724
|
cmd = "EDITOR=\"perl -p -i -e 's/_default/#{config[:chef_environment]}/'\" knife node create --server-url #{config[:chef_server_public]} #{hostname}"
|
722
725
|
Logger.debug cmd
|
723
|
-
knife_node_create =
|
726
|
+
knife_node_create = Stack.shellout(config, cmd)
|
724
727
|
Logger.info "Priming Chef Server: #{knife_node_create}"
|
725
728
|
|
726
729
|
cmd = "knife node run_list add -d --environment #{config[:chef_environment]} #{hostname} \"role[#{role}]\""
|
727
730
|
Logger.info cmd
|
728
|
-
knife_node_run_list =
|
731
|
+
knife_node_run_list = Stack.shellout(config, cmd)
|
729
732
|
Logger.info "Priming Chef Server: #{knife_node_run_list}"
|
730
733
|
end
|
731
734
|
|
@@ -746,9 +749,14 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
746
749
|
|
747
750
|
if config[:chef_server_hostname].nil?
|
748
751
|
Logger.info "config[:chef_server_hostname] is nil, skipping chef server substitution"
|
752
|
+
elsif (role_details[:chef_server])
|
753
|
+
Logger.info "This is the Chef Server - setting up to talk to ourselves"
|
754
|
+
multipart.gsub!(%q!%CHEF_SERVER%!, 'http://127.0.0.1:4000/')
|
755
|
+
multipart.gsub!(%q!%CHEF_ENVIRONMENT%!, config[:chef_environment])
|
749
756
|
else
|
750
757
|
Logger.info "Chef server is #{config[:chef_server_hostname]}, which is in #{config[:node_details][config[:chef_server_hostname]][:region]}"
|
751
758
|
Logger.info "#{hostname}'s region is #{config[:node_details][hostname][:region]}"
|
759
|
+
|
752
760
|
# if this host is in the same region/az, use the private URL, if not, use the public url
|
753
761
|
if (config[:node_details][hostname][:region] == config[:node_details][config[:chef_server_hostname]][:region]) && !config[:chef_server_private].nil?
|
754
762
|
multipart.gsub!(%q!%CHEF_SERVER%!, config[:chef_server_private])
|
@@ -757,7 +765,9 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
757
765
|
else
|
758
766
|
Logger.warn { "Not setting the chef url for #{hostname} as neither chef_server_private or chef_server_public are valid yet" }
|
759
767
|
end
|
768
|
+
|
760
769
|
multipart.gsub!(%q!%CHEF_ENVIRONMENT%!, config[:chef_environment])
|
770
|
+
|
761
771
|
if File.exists?(config[:chef_validation_pem])
|
762
772
|
multipart.gsub!(%q!%CHEF_VALIDATION_PEM%!, File.read(config[:chef_validation_pem]))
|
763
773
|
else
|
@@ -783,6 +793,7 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
783
793
|
Logger.debug { "multipart_complete after erb => #{multipart_complete} " }
|
784
794
|
multipart = multipart_complete
|
785
795
|
end
|
796
|
+
Logger.debug { "multipart = #{multipart}" }
|
786
797
|
|
787
798
|
Logger.info "Creating #{hostname} in #{node_details[hostname][:az]} with role #{role}"
|
788
799
|
|
@@ -847,7 +858,7 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
847
858
|
if role_details[:post_install_script]
|
848
859
|
Logger.debug { "This role has a post-install script (#{role_details[:post_install_script]}), preparing to run" }
|
849
860
|
# convert when we got passed to an absolute path
|
850
|
-
post_install_script_abs =
|
861
|
+
post_install_script_abs = Stack.find_file(config, role_details[:post_install_script])
|
851
862
|
post_install_cwd_abs = File.realpath(config[:stackhome] + '/' + role_details[:post_install_cwd])
|
852
863
|
|
853
864
|
# replace any tokens in the argument
|
@@ -871,16 +882,22 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
871
882
|
# 2) stackhome
|
872
883
|
# 2) stackhome + find_file_paths
|
873
884
|
# 3) gemhome/lib
|
874
|
-
|
885
|
+
|
886
|
+
if filename.nil? || filename.empty?
|
887
|
+
raise ArgumentError
|
888
|
+
end
|
889
|
+
|
890
|
+
dirs = [ '.' ] # current directory
|
875
891
|
dirs.push(config[:stackhome])
|
876
892
|
config[:find_file_paths].each { |fp| dirs.push(File.join(config[:stackhome], fp)) }
|
877
893
|
dirs.push(File.join(@@gemhome, 'lib'))
|
894
|
+
dirs.push('') # find absolute paths
|
878
895
|
dirs.flatten!
|
879
896
|
|
880
897
|
Logger.debug "find_file, looking for #{filename} in #{dirs}"
|
881
898
|
filename_fqp = ''
|
882
899
|
dirs.each do |dir|
|
883
|
-
fqp = dir
|
900
|
+
fqp = File.join(dir, filename)
|
884
901
|
Logger.debug "find_file: checking #{fqp}"
|
885
902
|
if File.file?(fqp)
|
886
903
|
Logger.debug "find_file: found #{fqp}!"
|
@@ -894,5 +911,22 @@ cookbook_path [ '<%=config[:stackhome]%>/cookbooks' ]
|
|
894
911
|
filename_fqp
|
895
912
|
end
|
896
913
|
|
914
|
+
def Stack.shellout(config, command, cwd=nil)
|
915
|
+
# wrapper to exec things in a knife friendly way
|
916
|
+
|
917
|
+
if cwd.nil?
|
918
|
+
cwd = config[:stackhome]
|
919
|
+
end
|
920
|
+
|
921
|
+
saved_wd = Dir.getwd()
|
922
|
+
output = ""
|
923
|
+
Dir.chdir(cwd)
|
924
|
+
sh command do |stdout, stderr, exitstatus|
|
925
|
+
output = stdout
|
926
|
+
end
|
927
|
+
Dir.chdir(saved_wd)
|
928
|
+
|
929
|
+
return output
|
930
|
+
end
|
897
931
|
end
|
898
932
|
|