cucumber-chef 2.0.7 → 2.1.0.rc.0
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/README.md +1 -1
- data/Rakefile +1 -1
- data/bin/cc-knife +2 -5
- data/bin/cc-push +50 -26
- data/bin/cc-server +9 -10
- data/bin/cucumber-chef +65 -71
- data/chef_repo/cookbooks/cucumber-chef/attributes/default.rb +1 -1
- data/chef_repo/cookbooks/cucumber-chef/recipes/default.rb +1 -1
- data/chef_repo/cookbooks/cucumber-chef/recipes/lxc.rb +34 -36
- data/chef_repo/cookbooks/cucumber-chef/recipes/test_lab.rb +64 -47
- data/chef_repo/cookbooks/cucumber-chef/templates/default/solrconfig.erb +650 -0
- data/cucumber-chef.gemspec +5 -5
- data/lib/cucumber/chef/bootstrap.rb +10 -10
- data/lib/cucumber/chef/config.rb +15 -15
- data/lib/cucumber/chef/helpers/chef_client.rb +88 -14
- data/lib/cucumber/chef/helpers/chef_server.rb +39 -16
- data/lib/cucumber/chef/helpers/command.rb +28 -12
- data/lib/cucumber/chef/helpers/container.rb +29 -26
- data/lib/cucumber/chef/helpers/minitest.rb +1 -1
- data/lib/cucumber/chef/helpers/server.rb +37 -18
- data/lib/cucumber/chef/helpers/test_lab.rb +1 -1
- data/lib/cucumber/chef/helpers/utility.rb +23 -3
- data/lib/cucumber/chef/helpers.rb +10 -8
- data/lib/cucumber/chef/provisioner.rb +22 -21
- data/lib/cucumber/chef/steps/chef_steps.rb +1 -1
- data/lib/cucumber/chef/steps/minitest_steps.rb +3 -3
- data/lib/cucumber/chef/steps/provision_steps.rb +7 -6
- data/lib/cucumber/chef/steps/ssh_steps.rb +31 -2
- data/lib/cucumber/chef/steps.rb +1 -1
- data/lib/cucumber/chef/templates/cucumber/cc-hooks.rb +111 -0
- data/lib/cucumber/chef/templates/cucumber/env.rb +0 -87
- data/lib/cucumber/chef/templates/cucumber/readme-environments.erb +1 -0
- data/lib/cucumber/chef/templates/cucumber/readme-roles.erb +1 -1
- data/lib/cucumber/chef/templates/cucumber-chef/config-rb.erb +5 -0
- data/lib/cucumber/chef/test_lab.rb +70 -23
- data/lib/cucumber/chef/utility.rb +121 -31
- data/lib/cucumber/chef/version.rb +2 -2
- data/lib/cucumber/chef.rb +1 -1
- data/lib/cucumber-chef.rb +1 -1
- data/spec/cucumber/chef/config_spec.rb +1 -1
- data/spec/cucumber/chef/provisioner_spec.rb +1 -1
- data/spec/cucumber/chef/test_lab_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +8 -5
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -41,33 +41,33 @@ module Cucumber
|
|
41
41
|
################################################################################
|
42
42
|
|
43
43
|
def run
|
44
|
-
|
44
|
+
Cucumber::Chef.logger.debug { "config(#{@config.inspect})" }
|
45
45
|
|
46
46
|
if !@config[:template_file]
|
47
47
|
message = "You must supply a 'template_file' option."
|
48
|
-
|
48
|
+
Cucumber::Chef.logger.fatal { message }
|
49
49
|
raise BootstrapError, message
|
50
50
|
end
|
51
51
|
|
52
52
|
if !@config[:host]
|
53
53
|
message = "You must supply a 'host' option."
|
54
|
-
|
54
|
+
Cucumber::Chef.logger.fatal { message }
|
55
55
|
raise BootstrapError, message
|
56
56
|
end
|
57
57
|
|
58
58
|
if !@config[:ssh_user]
|
59
59
|
message = "You must supply a 'ssh_user' option."
|
60
|
-
|
60
|
+
Cucumber::Chef.logger.fatal { message }
|
61
61
|
raise BootstrapError, message
|
62
62
|
end
|
63
63
|
|
64
64
|
if (!@config[:ssh_password] && !@config[:identity_file])
|
65
65
|
message = "You must supply a 'ssh_password' or 'identity_file' option."
|
66
|
-
|
66
|
+
Cucumber::Chef.logger.fatal { message }
|
67
67
|
raise BootstrapError, message
|
68
68
|
end
|
69
69
|
|
70
|
-
|
70
|
+
Cucumber::Chef.logger.debug { "prepare(#{@config[:host]})" }
|
71
71
|
|
72
72
|
@ssh.config.host_name = @config[:host]
|
73
73
|
@ssh.config.user = @config[:ssh_user]
|
@@ -75,13 +75,13 @@ module Cucumber
|
|
75
75
|
@ssh.config.keys = @config[:identity_file]
|
76
76
|
@ssh.config.timeout = 5
|
77
77
|
|
78
|
-
|
78
|
+
Cucumber::Chef.logger.debug { "template_file(#{@config[:template_file]})" }
|
79
79
|
command = ZTK::Template.render(@config[:template_file], @config[:context])
|
80
80
|
command = "sudo #{command}" if @config[:use_sudo]
|
81
81
|
|
82
|
-
|
82
|
+
Cucumber::Chef.logger.debug { "begin(#{@config[:host]})" }
|
83
83
|
@ssh.exec(command, :silence => true)
|
84
|
-
|
84
|
+
Cucumber::Chef.logger.debug { "end(#{@config[:host]})" }
|
85
85
|
end
|
86
86
|
|
87
87
|
################################################################################
|
data/lib/cucumber/chef/config.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -51,14 +51,14 @@ module Cucumber
|
|
51
51
|
|
52
52
|
def self.load
|
53
53
|
config_rb = Cucumber::Chef.locate(:file, ".cucumber-chef", "config.rb")
|
54
|
-
|
54
|
+
Cucumber::Chef.logger.debug { "Attempting to load cucumber-chef configuration from '%s'." % config_rb }
|
55
55
|
self.from_file(config_rb)
|
56
56
|
self.verify
|
57
|
-
|
57
|
+
Cucumber::Chef.logger.debug { "Successfully loaded cucumber-chef configuration from '%s'." % config_rb }
|
58
58
|
|
59
59
|
log_dump = self.duplicate(self.configuration)
|
60
60
|
log_dump[:aws].merge!(:aws_access_key_id => "[REDACTED]", :aws_secret_access_key => "[REDACTED]")
|
61
|
-
|
61
|
+
Cucumber::Chef.logger.debug { log_dump.inspect }
|
62
62
|
|
63
63
|
self
|
64
64
|
rescue Errno::ENOENT, UtilityError
|
@@ -77,25 +77,25 @@ module Cucumber
|
|
77
77
|
self.verify_keys
|
78
78
|
self.verify_provider_keys
|
79
79
|
eval("self.verify_provider_#{self[:provider].to_s.downcase}")
|
80
|
-
|
80
|
+
Cucumber::Chef.logger.debug { "Configuration verified successfully" }
|
81
81
|
end
|
82
82
|
|
83
83
|
################################################################################
|
84
84
|
|
85
85
|
def self.verify_keys
|
86
|
-
|
86
|
+
Cucumber::Chef.logger.debug { "Checking for missing configuration keys" }
|
87
87
|
missing_keys = KEYS.select{ |key| !self[key.to_sym] }
|
88
88
|
if missing_keys.count > 0
|
89
89
|
message = "Configuration incomplete, missing configuration keys: #{missing_keys.join(", ")}"
|
90
|
-
|
90
|
+
Cucumber::Chef.logger.fatal { message }
|
91
91
|
raise ConfigError, message
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
Cucumber::Chef.logger.debug { "Checking for invalid configuration keys" }
|
95
95
|
invalid_keys = KEYS.select{ |key| !eval("#{key.to_s.upcase}S").include?(self[key]) }
|
96
96
|
if invalid_keys.count > 0
|
97
97
|
message = "Configuration incomplete, invalid configuration keys: #{invalid_keys.join(", ")}"
|
98
|
-
|
98
|
+
Cucumber::Chef.logger.fatal { message }
|
99
99
|
raise ConfigError, message
|
100
100
|
end
|
101
101
|
end
|
@@ -103,11 +103,11 @@ module Cucumber
|
|
103
103
|
################################################################################
|
104
104
|
|
105
105
|
def self.verify_provider_keys
|
106
|
-
|
106
|
+
Cucumber::Chef.logger.debug { "Checking for missing provider keys" }
|
107
107
|
missing_keys = eval("PROVIDER_#{self[:provider].to_s.upcase}_KEYS").select{ |key| !self[self[:provider]].key?(key) }
|
108
108
|
if missing_keys.count > 0
|
109
109
|
message = "Configuration incomplete, missing provider configuration keys: #{missing_keys.join(", ")}"
|
110
|
-
|
110
|
+
Cucumber::Chef.logger.fatal { message }
|
111
111
|
raise ConfigError, message
|
112
112
|
end
|
113
113
|
end
|
@@ -122,14 +122,14 @@ module Cucumber
|
|
122
122
|
compute.describe_availability_zones
|
123
123
|
end
|
124
124
|
rescue Fog::Service::Error => err
|
125
|
-
message = "Invalid AWS credentials. Please check your configuration."
|
126
|
-
|
125
|
+
message = "Invalid AWS credentials. Please check your configuration. #{err.inspect}"
|
126
|
+
Cucumber::Chef.logger.fatal { message }
|
127
127
|
raise ConfigError, message
|
128
128
|
end
|
129
129
|
|
130
130
|
def self.verify_provider_vagrant
|
131
131
|
message = "Not yet implemented."
|
132
|
-
|
132
|
+
Cucumber::Chef.logger.fatal { message }
|
133
133
|
raise ConfigError, message
|
134
134
|
end
|
135
135
|
|
@@ -147,7 +147,7 @@ module Cucumber
|
|
147
147
|
return ami.name if ami
|
148
148
|
end
|
149
149
|
message = "Could not find a valid AMI image ID. Please check your configuration."
|
150
|
-
|
150
|
+
Cucumber::Chef.logger.fatal { message }
|
151
151
|
raise ConfigError, message
|
152
152
|
end
|
153
153
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -26,26 +26,45 @@ module Cucumber::Chef::Helpers::ChefClient
|
|
26
26
|
# call this in a Before hook
|
27
27
|
def chef_set_client_config(config={})
|
28
28
|
@chef_client_config = (@chef_client_config || {
|
29
|
-
:log_level => :
|
29
|
+
:log_level => :info,
|
30
30
|
:log_location => "/var/log/chef/client.log",
|
31
31
|
:chef_server_url => "https://api.opscode.com/organizations/#{config[:orgname]}",
|
32
|
-
:validation_client_name => "#{config[:orgname]}-validator"
|
32
|
+
:validation_client_name => "#{config[:orgname]}-validator",
|
33
|
+
:ssl_verify_mode => :verify_none,
|
34
|
+
:environment => nil # use default; i.e. set no value
|
33
35
|
}).merge(config)
|
36
|
+
log("setting chef client config $#{@chef_client_config.inspect}$")
|
37
|
+
|
38
|
+
true
|
34
39
|
end
|
35
40
|
|
36
41
|
################################################################################
|
37
42
|
|
38
43
|
# call this before chef_run_client
|
39
44
|
def chef_set_client_attributes(name, attributes={})
|
40
|
-
@
|
45
|
+
@servers[name] ||= Hash.new
|
46
|
+
@servers[name][:chef_client] = (@servers[name][:chef_client] || {}).merge(attributes) { |k,o,n| (k = (o + n).uniq) }
|
47
|
+
log("setting chef client attributes to $#{@servers[name][:chef_client].inspect}$ for container $#{name}$")
|
48
|
+
|
49
|
+
true
|
41
50
|
end
|
42
51
|
|
43
52
|
################################################################################
|
44
53
|
|
45
54
|
def chef_run_client(name,*args)
|
46
55
|
chef_config_client(name)
|
47
|
-
|
48
|
-
log("
|
56
|
+
artifacts =
|
57
|
+
log("removing artifacts #{Cucumber::Chef::Config[:artifacts].values.collect{|z| "$#{z}$" }.join(' ')}")
|
58
|
+
(command_run_remote(name, "/bin/rm -fv #{Cucumber::Chef::Config[:artifacts].values.join(' ')}") rescue nil)
|
59
|
+
|
60
|
+
log("running chef client on container $#{name}$")
|
61
|
+
|
62
|
+
output = nil
|
63
|
+
bm = ::Benchmark.realtime do
|
64
|
+
output = command_run_remote(name, ["/usr/bin/chef-client --json-attributes /etc/chef/attributes.json --node-name #{name}", args].flatten.join(" "))
|
65
|
+
end
|
66
|
+
log("chef client run on container $#{name}$ took %0.4f seconds" % bm)
|
67
|
+
|
49
68
|
output
|
50
69
|
end
|
51
70
|
|
@@ -56,16 +75,15 @@ module Cucumber::Chef::Helpers::ChefClient
|
|
56
75
|
client_rb = File.join("/", container_root(name), "etc/chef/client.rb")
|
57
76
|
FileUtils.mkdir_p(File.dirname(client_rb))
|
58
77
|
|
78
|
+
max_key_size = @chef_client_config.keys.collect{ |z| z.to_s.size }.max
|
79
|
+
|
59
80
|
File.open(client_rb, 'w') do |f|
|
60
81
|
f.puts(Cucumber::Chef.generate_do_not_edit_warning("Chef Client Configuration"))
|
61
82
|
f.puts
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
f.puts("validation_client_name \"#{@chef_client_config[:validation_client_name]}\"")
|
67
|
-
f.puts("node_name \"#{name}\"")
|
68
|
-
f.puts("environment \"#{@chef_client_config[:environment]}\"") if @chef_client_config[:environment]
|
83
|
+
@chef_client_config.merge(:node_name => name).each do |(key,value)|
|
84
|
+
next if value.nil?
|
85
|
+
f.puts("%-#{max_key_size}s %s" % [key, value.inspect])
|
86
|
+
end
|
69
87
|
f.puts
|
70
88
|
f.puts("Mixlib::Log::Formatter.show_time = true")
|
71
89
|
end
|
@@ -73,7 +91,7 @@ module Cucumber::Chef::Helpers::ChefClient
|
|
73
91
|
attributes_json = File.join("/", container_root(name), "etc", "chef", "attributes.json")
|
74
92
|
FileUtils.mkdir_p(File.dirname(attributes_json))
|
75
93
|
File.open(attributes_json, 'w') do |f|
|
76
|
-
f.puts((@
|
94
|
+
f.puts((@servers[name][:chef_client] || {}).to_json)
|
77
95
|
end
|
78
96
|
|
79
97
|
# make sure our log location is there
|
@@ -81,6 +99,62 @@ module Cucumber::Chef::Helpers::ChefClient
|
|
81
99
|
FileUtils.mkdir_p(File.dirname(log_location))
|
82
100
|
|
83
101
|
command_run_local("cp /etc/chef/validation.pem #{container_root(name)}/etc/chef/ 2>&1")
|
102
|
+
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
################################################################################
|
107
|
+
|
108
|
+
def chef_client_artifacts(name)
|
109
|
+
# this is messy and needs to be refactored into a more configurable
|
110
|
+
# solution; but for now this should do the trick
|
111
|
+
|
112
|
+
ssh_private_key_file = Cucumber::Chef.locate(:file, ".cucumber-chef", "id_rsa-#{Cucumber::Chef::Config[:lab_user]}")
|
113
|
+
File.chmod(0400, ssh_private_key_file)
|
114
|
+
|
115
|
+
ssh = ZTK::SSH.new
|
116
|
+
|
117
|
+
ssh.config.proxy_host_name = $test_lab.labs_running.first.public_ip_address
|
118
|
+
ssh.config.proxy_user = Cucumber::Chef::Config[:lab_user]
|
119
|
+
ssh.config.proxy_keys = ssh_private_key_file
|
120
|
+
|
121
|
+
ssh.config.host_name = name
|
122
|
+
ssh.config.user = Cucumber::Chef::Config[:lxc_user]
|
123
|
+
ssh.config.keys = ssh_private_key_file
|
124
|
+
|
125
|
+
feature_file = $scenario.file_colon_line.split(":").first
|
126
|
+
feature_line = $scenario.file_colon_line.split(":").last
|
127
|
+
scenario_tag = $scenario.name.gsub(" ", "_")
|
128
|
+
|
129
|
+
feature_name = File.basename(feature_file, ".feature")
|
130
|
+
feature_dir = feature_file.split("/")[-2]
|
131
|
+
|
132
|
+
Cucumber::Chef::Config[:artifacts].each do |label, remote_path|
|
133
|
+
result = ssh.exec("/bin/bash -c '[[ -f #{remote_path} ]] ; echo $?'", :silence => true)
|
134
|
+
if (result.output =~ /0/)
|
135
|
+
log("retrieving artifact $#{remote_path}$ from container $#{name}$")
|
136
|
+
|
137
|
+
local_path = File.join(Cucumber::Chef.locate(:directory, ".cucumber-chef"), "artifacts", feature_dir, "#{feature_name}.txt")
|
138
|
+
tmp_path = File.join("/tmp", label)
|
139
|
+
|
140
|
+
FileUtils.mkdir_p(File.dirname(local_path))
|
141
|
+
ssh.download(remote_path, tmp_path)
|
142
|
+
data = IO.read(tmp_path).chomp
|
143
|
+
|
144
|
+
message = "#{$scenario.name} (#{File.basename(feature_file)}:#{feature_line}:#{label})"
|
145
|
+
header = ("-" * message.length)
|
146
|
+
|
147
|
+
f = File.open(local_path, "a")
|
148
|
+
f.write("#{header}\n")
|
149
|
+
f.write("#{message}\n")
|
150
|
+
f.write("#{header}\n")
|
151
|
+
f.write("#{data}\n")
|
152
|
+
|
153
|
+
File.chmod(0644, local_path)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
true
|
84
158
|
end
|
85
159
|
|
86
160
|
################################################################################
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -25,14 +25,14 @@ module Cucumber::Chef::Helpers::ChefServer
|
|
25
25
|
|
26
26
|
def chef_server_node_destroy(name)
|
27
27
|
(::Chef::Node.load(name).destroy rescue nil)
|
28
|
-
log("chef
|
28
|
+
log("destroyed chef node $#{name}$")
|
29
29
|
end
|
30
30
|
|
31
31
|
################################################################################
|
32
32
|
|
33
33
|
def chef_server_client_destroy(name)
|
34
34
|
(::Chef::ApiClient.load(name).destroy rescue nil)
|
35
|
-
log("chef
|
35
|
+
log("destroyed chef client $#{name}$")
|
36
36
|
end
|
37
37
|
|
38
38
|
################################################################################
|
@@ -45,20 +45,37 @@ module Cucumber::Chef::Helpers::ChefServer
|
|
45
45
|
cookbook_repo.each do |name, cbook|
|
46
46
|
next if name != cookbook
|
47
47
|
::Chef::CookbookUploader.new(cbook, cookbook_path, :force => true).upload_cookbooks
|
48
|
-
log("chef
|
48
|
+
log("uploaded chef cookbook $#{cookbook}$ from $#{cookbook_path}$")
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
################################################################################
|
53
53
|
|
54
54
|
def load_role(role, role_path)
|
55
|
-
|
56
|
-
|
55
|
+
expanded_role_path = File.expand_path(role_path)
|
56
|
+
if !File.exists?(expanded_role_path)
|
57
|
+
raise "Role path, '#{expanded_role_path}', does not exist!"
|
57
58
|
end
|
58
|
-
::Chef::Config[:role_path] =
|
59
|
+
::Chef::Config[:role_path] = expanded_role_path
|
59
60
|
role = ::Chef::Role.from_disk(role)
|
60
61
|
role.save
|
61
|
-
log("chef
|
62
|
+
log("updated chef role $#{role}$ from $#{role_path}$")
|
63
|
+
end
|
64
|
+
|
65
|
+
################################################################################
|
66
|
+
|
67
|
+
def get_databag(databag)
|
68
|
+
@rest ||= ::Chef::REST.new(Chef::Config[:chef_server_url])
|
69
|
+
@rest.get_rest("data/#{databag}")
|
70
|
+
rescue Net::HTTPServerException => e
|
71
|
+
raise unless e.to_s =~ /^404/
|
72
|
+
end
|
73
|
+
|
74
|
+
def destroy_databag(databag)
|
75
|
+
@rest ||= ::Chef::REST.new(Chef::Config[:chef_server_url])
|
76
|
+
@rest.delete_rest("data/#{databag}")
|
77
|
+
rescue Net::HTTPServerException => e
|
78
|
+
raise unless e.to_s =~ /^404/
|
62
79
|
end
|
63
80
|
|
64
81
|
################################################################################
|
@@ -77,24 +94,30 @@ module Cucumber::Chef::Helpers::ChefServer
|
|
77
94
|
def load_databag(databag, databag_path)
|
78
95
|
create_databag(databag)
|
79
96
|
items = Dir.glob(File.expand_path(File.join(databag_path, "*.{json,rb}")))
|
97
|
+
if (items.size == 0)
|
98
|
+
raise "Could not find any of the data bags you defined!"
|
99
|
+
end
|
80
100
|
items.each do |item|
|
81
101
|
next if File.directory?(item)
|
82
102
|
|
103
|
+
item_name = %w( json rb ).collect{ |ext| (item =~ /#{ext}/ ? File.basename(item, ".#{ext}") : nil) }.compact.first
|
83
104
|
item_path = File.basename(item)
|
84
105
|
databag_item_path = File.expand_path(File.join(databag_path, item_path))
|
85
106
|
|
86
107
|
data_bag_item = ::Chef::DataBagItem.new
|
87
108
|
data_bag_item.data_bag(databag)
|
88
|
-
|
109
|
+
raw_data = load_databag_item(databag_item_path)
|
110
|
+
data_bag_item.raw_data = raw_data.dup
|
89
111
|
data_bag_item.save
|
90
|
-
log("chef-server", "updated data bag item '#{databag}/#{item_path}' from file '#{databag_path}'")
|
91
|
-
end
|
92
112
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
113
|
+
loop do
|
114
|
+
chef_data = ::Chef::DataBagItem.load(databag, item_name).raw_data
|
115
|
+
break if chef_data == raw_data
|
116
|
+
log("waiting on chef data bag to update")
|
117
|
+
sleep(1)
|
118
|
+
end
|
119
|
+
log("updated chef data bag item $#{databag}/#{item_path}$ from $#{databag_path}$")
|
120
|
+
end
|
98
121
|
end
|
99
122
|
|
100
123
|
################################################################################
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -24,29 +24,45 @@ module Cucumber::Chef::Helpers::Command
|
|
24
24
|
################################################################################
|
25
25
|
|
26
26
|
def command_run_remote(name, command, expected_exit_code=0)
|
27
|
-
|
28
|
-
|
27
|
+
command = %Q(ssh #{name} #{command} 2>&1)
|
28
|
+
logger.info { "command_run_remote(#{command})" }
|
29
|
+
output = %x(#{command})
|
30
|
+
if !expected_exit_code.nil? && ($? != expected_exit_code)
|
31
|
+
message = "command_run_remote(#{command}) failed (code=#{$?},output='#{output.chomp}')"
|
32
|
+
logger.fatal { message }
|
33
|
+
logger.fatal { "output(#{output.chomp})" }
|
34
|
+
raise message
|
35
|
+
end
|
29
36
|
output
|
30
|
-
# rescue RuntimeError => e
|
31
|
-
# if $? == 65280
|
32
|
-
# puts "Exit Code #{$?}: Retrying..."
|
33
|
-
# retry
|
34
|
-
# end
|
35
37
|
end
|
36
38
|
|
37
39
|
################################################################################
|
38
40
|
|
39
41
|
def command_run_chroot(name, command, expected_exit_code=0)
|
40
|
-
|
41
|
-
|
42
|
+
command = %Q(chroot #{container_root(name)} /bin/bash -c '#{command.gsub("'", '"')}' 2>&1)
|
43
|
+
logger.info { "command_run_chroot(#{command})" }
|
44
|
+
output = %x(#{command})
|
45
|
+
if !expected_exit_code.nil? && ($? != expected_exit_code)
|
46
|
+
message = "command_run_chroot(#{command}) failed (#{$?})"
|
47
|
+
logger.fatal { message }
|
48
|
+
logger.fatal { "output(#{output.chomp})" }
|
49
|
+
raise message
|
50
|
+
end
|
42
51
|
output
|
43
52
|
end
|
44
53
|
|
45
54
|
################################################################################
|
46
55
|
|
47
56
|
def command_run_local(command, expected_exit_code=0)
|
48
|
-
|
49
|
-
|
57
|
+
command = %Q(/bin/bash -c '#{command.gsub("'", '"')}' 2>&1)
|
58
|
+
logger.info { "command_run_local(#{command})" }
|
59
|
+
output = %x(#{command})
|
60
|
+
if !expected_exit_code.nil? && ($? != expected_exit_code)
|
61
|
+
message = "command_run_local(#{command}) failed (#{$?})"
|
62
|
+
logger.fatal { message }
|
63
|
+
logger.fatal { "output(#{output.chomp})" }
|
64
|
+
raise message
|
65
|
+
end
|
50
66
|
output
|
51
67
|
end
|
52
68
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -25,71 +25,74 @@ module Cucumber::Chef::Helpers::Container
|
|
25
25
|
|
26
26
|
def container_create(name, distro, release, arch)
|
27
27
|
unless container_exists?(name)
|
28
|
-
chef_server_node_destroy(name)
|
29
|
-
chef_server_client_destroy(name)
|
30
|
-
|
31
28
|
cache_rootfs = container_cache_root(name, distro, release, arch)
|
32
|
-
|
29
|
+
if !File.exists?(cache_rootfs)
|
30
|
+
log("$#{name}$ has triggered building the lxc file cache for $#{distro}$")
|
31
|
+
log("this one time process per distro can take up to 10 minutes or longer depending on the test lab hardware")
|
32
|
+
end
|
33
33
|
|
34
34
|
command_run_local(container_create_command(name, distro, release, arch))
|
35
35
|
|
36
36
|
# install omnibus into the distro/release file cache if it's not already there
|
37
|
-
omnibus_chef_client = File.join("/", "opt", "
|
38
|
-
|
37
|
+
omnibus_chef_client = File.join("/", "opt", "chef", "bin", "chef-client")
|
38
|
+
omnibus_cache = File.join(cache_rootfs, omnibus_chef_client)
|
39
|
+
logger.info { "looking for omnibus cache in #{omnibus_cache}" }
|
40
|
+
if !File.exists?(omnibus_cache)
|
39
41
|
case distro.downcase
|
40
42
|
when "ubuntu" then
|
41
|
-
|
43
|
+
command_run_local("chroot #{cache_rootfs} /bin/bash -c 'apt-get -y --force-yes install wget'")
|
42
44
|
when "fedora" then
|
43
|
-
|
45
|
+
command_run_local("yum --nogpgcheck --installroot=#{cache_rootfs} -y install wget openssh-server")
|
44
46
|
end
|
45
|
-
|
47
|
+
command_run_local("chroot #{cache_rootfs} /bin/bash -c 'wget http://www.opscode.com/chef/install.sh -O - | bash'")
|
46
48
|
if distro.downcase == "fedora"
|
47
|
-
|
49
|
+
command_run_local("chroot #{cache_rootfs} /bin/bash -c 'rpm -Uvh --nodeps /tmp/*rpm'")
|
48
50
|
end
|
49
|
-
command_run_local("lxc-destroy -n #{name}
|
51
|
+
command_run_local("lxc-destroy -n #{name}")
|
50
52
|
command_run_local(container_create_command(name, distro, release, arch))
|
51
53
|
end
|
52
54
|
|
53
55
|
command_run_local("mkdir -p #{container_root(name)}/root/.ssh")
|
54
56
|
command_run_local("chmod 0755 #{container_root(name)}/root/.ssh")
|
55
57
|
command_run_local("cat /root/.ssh/id_rsa.pub | tee -a #{container_root(name)}/root/.ssh/authorized_keys")
|
56
|
-
command_run_local("cat /home
|
58
|
+
command_run_local("cat /home/#{Cucumber::Chef::Config[:lab_user]}/.ssh/id_rsa.pub | tee -a #{container_root(name)}/root/.ssh/authorized_keys")
|
57
59
|
|
58
|
-
command_run_local("mkdir -p #{container_root(name)}/home
|
59
|
-
command_run_local("chmod 0755 #{container_root(name)}/home
|
60
|
-
command_run_local("cat /root/.ssh/id_rsa.pub | tee -a #{container_root(name)}/home
|
61
|
-
command_run_local("cat /home
|
62
|
-
command_run_local("chown -R
|
60
|
+
command_run_local("mkdir -p #{container_root(name)}/home/#{Cucumber::Chef::Config[:lab_user]}/.ssh")
|
61
|
+
command_run_local("chmod 0755 #{container_root(name)}/home/#{Cucumber::Chef::Config[:lab_user]}/.ssh")
|
62
|
+
command_run_local("cat /root/.ssh/id_rsa.pub | tee -a #{container_root(name)}/home/#{Cucumber::Chef::Config[:lab_user]}/.ssh/authorized_keys")
|
63
|
+
command_run_local("cat /home/#{Cucumber::Chef::Config[:lab_user]}/.ssh/id_rsa.pub | tee -a #{container_root(name)}/home/#{Cucumber::Chef::Config[:lab_user]}/.ssh/authorized_keys")
|
64
|
+
command_run_local("chown -R #{Cucumber::Chef::Config[:lab_user]}:#{Cucumber::Chef::Config[:lab_user]} #{container_root(name)}/home/#{Cucumber::Chef::Config[:lab_user]}/.ssh")
|
63
65
|
|
64
66
|
command_run_local("rm #{container_root(name)}/etc/motd")
|
65
67
|
command_run_local("cp /etc/motd #{container_root(name)}/etc/motd")
|
66
|
-
command_run_local("echo
|
67
|
-
command_run_local("sed -i
|
68
|
-
command_run_local("echo
|
68
|
+
command_run_local("echo ' You are now logged in to the #{name} container!\n' >> #{container_root(name)}/etc/motd")
|
69
|
+
command_run_local("sed -i 's/localhost #{name}/#{name}.test-lab #{name} localhost/' #{container_root(name)}/etc/hosts")
|
70
|
+
command_run_local("echo '#{name}.test-lab' | tee #{container_root(name)}/etc/hostname")
|
69
71
|
end
|
70
72
|
container_start(name)
|
71
73
|
end
|
72
74
|
|
73
75
|
def container_destroy(name)
|
74
76
|
if container_exists?(name)
|
75
|
-
container_stop(name)
|
76
|
-
command_run_local("lxc-destroy -n #{name} 2>&1")
|
77
77
|
chef_server_node_destroy(name)
|
78
78
|
chef_server_client_destroy(name)
|
79
|
+
container_stop(name)
|
80
|
+
command_run_local("lxc-destroy -n #{name}")
|
81
|
+
log("destroyed container $#{name}$")
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
82
85
|
################################################################################
|
83
86
|
|
84
87
|
def container_start(name)
|
85
|
-
status = command_run_local("lxc-info -n #{name}
|
88
|
+
status = command_run_local("lxc-info -n #{name}")
|
86
89
|
if status.include?("STOPPED")
|
87
90
|
command_run_local("lxc-start -d -n #{name}")
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
91
94
|
def container_stop(name)
|
92
|
-
status = command_run_local("lxc-info -n #{name}
|
95
|
+
status = command_run_local("lxc-info -n #{name}")
|
93
96
|
if status.include?("RUNNING")
|
94
97
|
command_run_local("lxc-stop -n #{name}")
|
95
98
|
end
|
@@ -98,7 +101,7 @@ module Cucumber::Chef::Helpers::Container
|
|
98
101
|
################################################################################
|
99
102
|
|
100
103
|
def container_running?(name)
|
101
|
-
status = command_run_local("lxc-info -n #{name}
|
104
|
+
status = command_run_local("lxc-info -n #{name}")
|
102
105
|
status.include?("RUNNING")
|
103
106
|
end
|
104
107
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author: Stephen Nelson-Smith <stephen@atalanta-systems.com>
|
4
4
|
# Author: Zachary Patten <zachary@jovelabs.com>
|
5
|
-
# Copyright: Copyright (c) 2011-
|
5
|
+
# Copyright: Copyright (c) 2011-2013 Atalanta Systems Ltd
|
6
6
|
# License: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|