chef 10.14.2 → 10.14.4.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- data/distro/common/html/chef-client.8.html +3 -3
- data/distro/common/html/chef-expander.8.html +3 -3
- data/distro/common/html/chef-expanderctl.8.html +3 -3
- data/distro/common/html/chef-server-webui.8.html +3 -3
- data/distro/common/html/chef-server.8.html +3 -3
- data/distro/common/html/chef-solo.8.html +3 -3
- data/distro/common/html/chef-solr.8.html +3 -3
- data/distro/common/html/knife-bootstrap.1.html +3 -3
- data/distro/common/html/knife-client.1.html +4 -4
- data/distro/common/html/knife-configure.1.html +3 -3
- data/distro/common/html/knife-cookbook-site.1.html +3 -3
- data/distro/common/html/knife-cookbook.1.html +3 -3
- data/distro/common/html/knife-data-bag.1.html +3 -3
- data/distro/common/html/knife-environment.1.html +6 -6
- data/distro/common/html/knife-exec.1.html +4 -4
- data/distro/common/html/knife-index.1.html +4 -4
- data/distro/common/html/knife-node.1.html +4 -4
- data/distro/common/html/knife-role.1.html +6 -6
- data/distro/common/html/knife-search.1.html +3 -3
- data/distro/common/html/knife-ssh.1.html +3 -3
- data/distro/common/html/knife-status.1.html +3 -3
- data/distro/common/html/knife-tag.1.html +4 -4
- data/distro/common/html/knife.1.html +3 -3
- data/distro/common/html/shef.1.html +7 -7
- data/distro/common/man/man1/knife-bootstrap.1 +1 -1
- data/distro/common/man/man1/knife-client.1 +1 -1
- data/distro/common/man/man1/knife-configure.1 +1 -1
- data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
- data/distro/common/man/man1/knife-cookbook.1 +1 -1
- data/distro/common/man/man1/knife-data-bag.1 +1 -1
- data/distro/common/man/man1/knife-environment.1 +1 -1
- data/distro/common/man/man1/knife-exec.1 +1 -1
- data/distro/common/man/man1/knife-index.1 +1 -1
- data/distro/common/man/man1/knife-node.1 +1 -1
- data/distro/common/man/man1/knife-role.1 +1 -1
- data/distro/common/man/man1/knife-search.1 +1 -1
- data/distro/common/man/man1/knife-ssh.1 +1 -1
- data/distro/common/man/man1/knife-status.1 +1 -1
- data/distro/common/man/man1/knife-tag.1 +1 -1
- data/distro/common/man/man1/knife.1 +1 -1
- data/distro/common/man/man1/shef.1 +1 -1
- data/distro/common/man/man8/chef-client.8 +1 -1
- data/distro/common/man/man8/chef-expander.8 +1 -1
- data/distro/common/man/man8/chef-expanderctl.8 +1 -1
- data/distro/common/man/man8/chef-server-webui.8 +1 -1
- data/distro/common/man/man8/chef-server.8 +1 -1
- data/distro/common/man/man8/chef-solo.8 +1 -1
- data/distro/common/man/man8/chef-solr.8 +1 -1
- data/lib/chef/config.rb +1 -0
- data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +12 -3
- data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +0 -1
- data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +1 -1
- data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +5 -5
- data/lib/chef/knife/data_bag_edit.rb +1 -1
- data/lib/chef/knife/ssh.rb +15 -4
- data/lib/chef/platform.rb +1 -1
- data/lib/chef/provider/deploy.rb +9 -5
- data/lib/chef/provider/http_request.rb +15 -12
- data/lib/chef/version.rb +1 -1
- data/spec/data/cookbooks/angrybash/recipes/default.rb +8 -0
- data/spec/support/shared/unit/api_error_inspector.rb +14 -2
- data/spec/unit/config_spec.rb +17 -5
- data/spec/unit/cookbook_loader_spec.rb +5 -4
- data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +58 -0
- data/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb +18 -0
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +30 -0
- data/spec/unit/knife/ssh_spec.rb +63 -24
- data/spec/unit/platform_spec.rb +15 -3
- data/spec/unit/provider/deploy_spec.rb +45 -10
- data/spec/unit/provider/http_request_spec.rb +6 -0
- metadata +14 -9
@@ -55,13 +55,11 @@ class Chef
|
|
55
55
|
relevant_lines = ["# In #{file}\n\n"]
|
56
56
|
|
57
57
|
|
58
|
-
current_line = line -
|
58
|
+
current_line = line - 1
|
59
|
+
current_line = 0 if current_line < 0
|
59
60
|
nesting = 0
|
60
61
|
|
61
|
-
relevant_lines << format_line(current_line, lines[current_line])
|
62
|
-
|
63
62
|
loop do
|
64
|
-
current_line += 1
|
65
63
|
|
66
64
|
# low rent parser. try to gracefully handle nested blocks in resources
|
67
65
|
nesting += 1 if lines[current_line] =~ /[\s]+do[\s]*/
|
@@ -69,9 +67,11 @@ class Chef
|
|
69
67
|
|
70
68
|
relevant_lines << format_line(current_line, lines[current_line])
|
71
69
|
|
72
|
-
break if lines[current_line].nil?
|
70
|
+
break if lines[current_line + 1].nil?
|
73
71
|
break if current_line >= (line + 50)
|
74
72
|
break if nesting <= 0
|
73
|
+
|
74
|
+
current_line += 1
|
75
75
|
end
|
76
76
|
relevant_lines << format_line(current_line + 1, lines[current_line + 1]) if lines[current_line + 1]
|
77
77
|
relevant_lines.join("")
|
@@ -84,7 +84,7 @@ class Chef
|
|
84
84
|
output = edit_item(item)
|
85
85
|
rest.put_rest("data/#{@name_args[0]}/#{@name_args[1]}", output)
|
86
86
|
stdout.puts("Saved data_bag_item[#{@name_args[1]}]")
|
87
|
-
output(
|
87
|
+
ui.output(output) if config[:print_after]
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
data/lib/chef/knife/ssh.rb
CHANGED
@@ -48,8 +48,8 @@ class Chef
|
|
48
48
|
option :attribute,
|
49
49
|
:short => "-a ATTR",
|
50
50
|
:long => "--attribute ATTR",
|
51
|
-
:description => "The attribute to use for opening the connection - default
|
52
|
-
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_attribute] = key }
|
51
|
+
:description => "The attribute to use for opening the connection - default depends on the context",
|
52
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:ssh_attribute] = key.strip }
|
53
53
|
|
54
54
|
option :manual,
|
55
55
|
:short => "-m",
|
@@ -128,6 +128,8 @@ class Chef
|
|
128
128
|
# see #configure_attribute for the source of config[:attribute] and config[:override_attribute]
|
129
129
|
if !config[:override_attribute] && item[:cloud] and item[:cloud][:public_hostname]
|
130
130
|
i = item[:cloud][:public_hostname]
|
131
|
+
elsif config[:override_attribute]
|
132
|
+
i = format_for_display(item)[config[:override_attribute]]
|
131
133
|
else
|
132
134
|
i = format_for_display(item)[config[:attribute]]
|
133
135
|
end
|
@@ -135,7 +137,16 @@ class Chef
|
|
135
137
|
end
|
136
138
|
r
|
137
139
|
end
|
138
|
-
|
140
|
+
if list.length == 0
|
141
|
+
if @action_nodes.length == 0
|
142
|
+
ui.fatal("No nodes returned from search!")
|
143
|
+
else
|
144
|
+
ui.fatal("#{@action_nodes.length} #{@action_nodes.length > 1 ? "nodes":"node"} found, " +
|
145
|
+
"but do not have the required attribute to stablish the connection. " +
|
146
|
+
"Try setting another attribute to open the connection using --attribute.")
|
147
|
+
end
|
148
|
+
exit 10
|
149
|
+
end
|
139
150
|
session_from_list(list)
|
140
151
|
end
|
141
152
|
|
@@ -346,7 +357,7 @@ class Chef
|
|
346
357
|
# Thus we can differentiate between a config file value and a command line override at this point by checking config[:attribute]
|
347
358
|
# We can tell here if fqdn was passed from the command line, rather than being the default, by checking config[:attribute]
|
348
359
|
# However, after here, we cannot tell these things, so we must preserve config[:attribute]
|
349
|
-
config[:override_attribute] = config[:attribute]
|
360
|
+
config[:override_attribute] = config[:attribute] || Chef::Config[:knife][:ssh_attribute]
|
350
361
|
config[:attribute] = (Chef::Config[:knife][:ssh_attribute] ||
|
351
362
|
config[:attribute] ||
|
352
363
|
"fqdn").strip
|
data/lib/chef/platform.rb
CHANGED
@@ -369,7 +369,7 @@ class Chef
|
|
369
369
|
return platform, version
|
370
370
|
end
|
371
371
|
|
372
|
-
def provider_for_resource(resource, action)
|
372
|
+
def provider_for_resource(resource, action=:nothing)
|
373
373
|
node = resource.run_context && resource.run_context.node
|
374
374
|
raise ArgumentError, "Cannot find the provider for a resource with no run context set" unless node
|
375
375
|
provider = find_provider_for_node(node, resource).new(resource, resource.run_context)
|
data/lib/chef/provider/deploy.rb
CHANGED
@@ -149,6 +149,12 @@ class Chef
|
|
149
149
|
|
150
150
|
def deploy
|
151
151
|
verify_directories_exist
|
152
|
+
# CHEF-3435: We need to create the directories if they don't exist before calling the
|
153
|
+
# scm_provider because it expects them to be there in its own assertations
|
154
|
+
unless self.converge_actions.empty?
|
155
|
+
Chef::Log.info "#{@new_resource} running collected converge_actions before calling scm_provider"
|
156
|
+
self.converge_actions.converge!
|
157
|
+
end
|
152
158
|
update_cached_repo # no converge-by - scm provider will dothis
|
153
159
|
enforce_ownership
|
154
160
|
copy_cached_repo
|
@@ -402,11 +408,9 @@ class Chef
|
|
402
408
|
end
|
403
409
|
|
404
410
|
def run_callback_from_file(callback_file)
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
recipe_eval { from_file(callback_file) }
|
409
|
-
end
|
411
|
+
Dir.chdir(release_path) do
|
412
|
+
Chef::Log.info "#{@new_resource} queueing checkdeploy hook #{callback_file}"
|
413
|
+
recipe_eval { from_file(callback_file) if ::File.exist?(callback_file) }
|
410
414
|
end
|
411
415
|
end
|
412
416
|
|
@@ -34,18 +34,21 @@ class Chef
|
|
34
34
|
|
35
35
|
# Send a HEAD request to @new_resource.url, with ?message=@new_resource.message
|
36
36
|
def action_head
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
message = check_message(@new_resource.message)
|
38
|
+
# returns true from Chef::REST if returns 2XX (Net::HTTPSuccess)
|
39
|
+
modified = @rest.run_request(
|
40
|
+
:HEAD,
|
41
|
+
@rest.create_url("#{@new_resource.url}?message=#{message}"),
|
42
|
+
@new_resource.headers,
|
43
|
+
false,
|
44
|
+
10,
|
45
|
+
false
|
46
|
+
)
|
47
|
+
Chef::Log.info("#{@new_resource} HEAD to #{@new_resource.url} successful")
|
48
|
+
Chef::Log.debug("#{@new_resource} HEAD request response: #{modified}")
|
49
|
+
# :head is usually used to trigger notifications, which converge_by now does
|
50
|
+
if modified
|
51
|
+
converge_by("#{@new_resource} HEAD to #{@new_resource.url} returned modified, trigger notifications") {}
|
49
52
|
end
|
50
53
|
end
|
51
54
|
|
data/lib/chef/version.rb
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -177,4 +177,16 @@ shared_examples_for "an api error inspector" do
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
+
describe "when explaining an unknown error" do
|
181
|
+
before do
|
182
|
+
@exception = RuntimeError.new("(exception) something went wrong")
|
183
|
+
@inspector = described_class.new(@node_name, @exception, @config)
|
184
|
+
@inspector.add_explanation(@description)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "prints a nice message" do
|
188
|
+
@description.display(@outputter)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
180
192
|
end
|
data/spec/unit/config_spec.rb
CHANGED
@@ -24,11 +24,7 @@ describe Chef::Config do
|
|
24
24
|
@original_env = { 'HOME' => ENV['HOME'], 'SYSTEMDRIVE' => ENV['SYSTEMDRIVE'], 'HOMEPATH' => ENV['HOMEPATH'], 'USERPROFILE' => ENV['USERPROFILE'] }
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
before do
|
29
|
-
Chef::Config.chef_server_url = "https://junglist.gen.nz"
|
30
|
-
end
|
31
|
-
|
27
|
+
shared_examples_for "server URL" do
|
32
28
|
it "should set the registration url" do
|
33
29
|
Chef::Config.registration_url.should == "https://junglist.gen.nz"
|
34
30
|
end
|
@@ -50,6 +46,22 @@ describe Chef::Config do
|
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
49
|
+
describe "config attribute writer: chef_server_url" do
|
50
|
+
before do
|
51
|
+
Chef::Config.chef_server_url = "https://junglist.gen.nz"
|
52
|
+
end
|
53
|
+
|
54
|
+
it_behaves_like "server URL"
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when the url has a leading space" do
|
58
|
+
before do
|
59
|
+
Chef::Config.chef_server_url = " https://junglist.gen.nz"
|
60
|
+
end
|
61
|
+
|
62
|
+
it_behaves_like "server URL"
|
63
|
+
end
|
64
|
+
|
53
65
|
describe "class method: manage_secret_key" do
|
54
66
|
before do
|
55
67
|
Chef::FileCache.stub!(:load).and_return(true)
|
@@ -59,10 +59,11 @@ describe Chef::CookbookLoader do
|
|
59
59
|
@cookbook_loader.each do |cookbook_name, cookbook|
|
60
60
|
seen << cookbook_name
|
61
61
|
end
|
62
|
-
seen[0].should == "
|
63
|
-
seen[1].should == "
|
64
|
-
seen[2].should == "
|
65
|
-
seen[3].should == "
|
62
|
+
seen[0].should == "angrybash"
|
63
|
+
seen[1].should == "apache2"
|
64
|
+
seen[2].should == "borken"
|
65
|
+
seen[3].should == "java"
|
66
|
+
seen[4].should == "openldap"
|
66
67
|
end
|
67
68
|
end
|
68
69
|
|
@@ -85,6 +85,10 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
|
|
85
85
|
@inspector.add_explanation(@description)
|
86
86
|
end
|
87
87
|
|
88
|
+
it "finds the line number of the error from the stacktrace" do
|
89
|
+
@inspector.culprit_line.should == 14
|
90
|
+
end
|
91
|
+
|
88
92
|
it "prints a pretty message" do
|
89
93
|
@description.display(@outputter)
|
90
94
|
end
|
@@ -124,10 +128,64 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
|
|
124
128
|
@inspector.add_explanation(@description)
|
125
129
|
end
|
126
130
|
|
131
|
+
it "finds the culprit recipe name from the stacktrace" do
|
132
|
+
@inspector.culprit_file.should == "C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "finds the line number of the error from the stack trace" do
|
136
|
+
@inspector.culprit_line.should == 14
|
137
|
+
end
|
138
|
+
|
127
139
|
it "prints a pretty message" do
|
128
140
|
@description.display(@outputter)
|
129
141
|
end
|
130
142
|
end
|
131
143
|
|
144
|
+
describe "when explaining an error on windows, and the backtrace lowercases the drive letter" do
|
145
|
+
before do
|
146
|
+
Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
|
147
|
+
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
|
148
|
+
IO.should_receive(:readlines).with("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb").and_return(recipe_lines)
|
149
|
+
@trace = [
|
150
|
+
"c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'",
|
151
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'",
|
152
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:138:in `block in load_libraries'",
|
153
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:230:in `call'",
|
154
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:230:in `block (2 levels) in foreach_cookbook_load_segment'",
|
155
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:229:in `each'",
|
156
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:229:in `block in foreach_cookbook_load_segment'",
|
157
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:227:in `each'",
|
158
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:227:in `foreach_cookbook_load_segment'",
|
159
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:137:in `load_libraries'",
|
160
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:62:in `load'",
|
161
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:198:in `setup_run_context'",
|
162
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:418:in `do_run'",
|
163
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:176:in `run'",
|
164
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:283:in `block in run_application'",
|
165
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:270:in `loop'",
|
166
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:270:in `run_application'",
|
167
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application.rb:70:in `run'",
|
168
|
+
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/bin/chef-client:26:in `<top (required)>'",
|
169
|
+
"c:/opscode/chef/bin/chef-client:19:in `load'",
|
170
|
+
"c:/opscode/chef/bin/chef-client:19:in `<main>'"
|
171
|
+
]
|
172
|
+
@exception.set_backtrace(@trace)
|
173
|
+
@path = "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb"
|
174
|
+
@inspector = described_class.new(@path, @exception)
|
175
|
+
@inspector.add_explanation(@description)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "finds the culprit recipe name from the stacktrace" do
|
179
|
+
@inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
|
180
|
+
end
|
181
|
+
|
182
|
+
it "finds the line number of the error from the stack trace" do
|
183
|
+
@inspector.culprit_line.should == 14
|
184
|
+
end
|
185
|
+
|
186
|
+
it "prints a pretty message" do
|
187
|
+
@description.display(@outputter)
|
188
|
+
end
|
189
|
+
end
|
132
190
|
|
133
191
|
end
|
@@ -28,6 +28,24 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
|
|
28
28
|
#@outputter = Chef::Formatters::Outputter.new(STDOUT, STDERR)
|
29
29
|
end
|
30
30
|
|
31
|
+
describe "when explaining a 403 error" do
|
32
|
+
before do
|
33
|
+
|
34
|
+
@response_body = %Q({"error": [{"message": "gtfo"}])
|
35
|
+
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
|
36
|
+
@response.stub!(:body).and_return(@response_body)
|
37
|
+
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
|
38
|
+
|
39
|
+
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
|
40
|
+
@inspector.add_explanation(@description)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "prints a nice message" do
|
44
|
+
lambda { @description.display(@outputter) }.should_not raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
31
49
|
describe "when explaining a PreconditionFailed (412) error with current error message style" do
|
32
50
|
# Chef currently returns error messages with some fields as JSON strings,
|
33
51
|
# which must be re-parsed to get the actual data.
|
@@ -98,5 +98,35 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
|
|
98
98
|
@inspector.recipe_snippet.should match(/^# In \/home\/btm/)
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
describe "when examining a resource that confuses the parser" do
|
103
|
+
before do
|
104
|
+
angry_bash_recipe = File.expand_path("cookbooks/angrybash/recipes/default.rb", CHEF_SPEC_DATA)
|
105
|
+
source_line = "#{angry_bash_recipe}:1:in `<main>'"
|
106
|
+
|
107
|
+
# source_line = caller(0)[0]; @resource = bash "go off the rails" do
|
108
|
+
# code <<-END
|
109
|
+
# for i in localhost 127.0.0.1 #{Socket.gethostname()}
|
110
|
+
# do
|
111
|
+
# echo "grant all on *.* to root@'$i' identified by 'a_password'; flush privileges;" | mysql -u root -h 127.0.0.1
|
112
|
+
# done
|
113
|
+
# END
|
114
|
+
# end
|
115
|
+
@resource = eval(IO.read(angry_bash_recipe))
|
116
|
+
@resource.source_line = source_line
|
117
|
+
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
|
118
|
+
|
119
|
+
@exception.set_backtrace(@trace)
|
120
|
+
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "does not generate an error" do
|
124
|
+
lambda { @inspector.add_explanation(@description) }.should_not raise_error(TypeError)
|
125
|
+
@description.display(@outputter)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
101
129
|
end
|
130
|
+
|
131
|
+
|
102
132
|
end
|
data/spec/unit/knife/ssh_spec.rb
CHANGED
@@ -23,11 +23,13 @@ require 'net/ssh/multi'
|
|
23
23
|
describe Chef::Knife::Ssh do
|
24
24
|
before(:all) do
|
25
25
|
@original_config = Chef::Config.hash_dup
|
26
|
+
@original_knife_config = Chef::Config[:knife].dup
|
26
27
|
Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem"
|
27
28
|
end
|
28
29
|
|
29
30
|
after(:all) do
|
30
31
|
Chef::Config.configuration = @original_config
|
32
|
+
Chef::Config[:knife] = @original_knife_config
|
31
33
|
end
|
32
34
|
|
33
35
|
before do
|
@@ -36,8 +38,10 @@ describe Chef::Knife::Ssh do
|
|
36
38
|
@knife.config[:attribute] = "fqdn"
|
37
39
|
@node_foo = Chef::Node.new('foo')
|
38
40
|
@node_foo[:fqdn] = "foo.example.org"
|
39
|
-
@
|
41
|
+
@node_foo[:ipaddress] = "10.0.0.1"
|
42
|
+
@node_bar = Chef::Node.new('bar')
|
40
43
|
@node_bar[:fqdn] = "bar.example.org"
|
44
|
+
@node_bar[:ipaddress] = "10.0.0.2"
|
41
45
|
end
|
42
46
|
|
43
47
|
describe "#configure_session" do
|
@@ -47,27 +51,36 @@ describe Chef::Knife::Ssh do
|
|
47
51
|
@query = Chef::Search::Query.new
|
48
52
|
end
|
49
53
|
|
50
|
-
def
|
51
|
-
|
54
|
+
def configure_query(node_array)
|
55
|
+
@query.stub!(:search).and_return([node_array])
|
56
|
+
Chef::Search::Query.stub!(:new).and_return(@query)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.should_return_specified_attributes
|
60
|
+
it "returns an array of the attributes specified on the command line OR config file, if only one is set" do
|
52
61
|
@knife.config[:attribute] = "ipaddress"
|
53
62
|
@knife.config[:override_attribute] = "ipaddress"
|
54
|
-
@node_foo
|
55
|
-
@
|
56
|
-
@
|
57
|
-
|
63
|
+
configure_query([@node_foo, @node_bar])
|
64
|
+
@knife.should_receive(:session_from_list).with(['10.0.0.1', '10.0.0.2'])
|
65
|
+
@knife.configure_session
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns an array of the attributes specified on the command line even when a config value is set" do
|
69
|
+
@knife.config[:attribute] = "config_file" # this value will be the config file
|
70
|
+
@knife.config[:override_attribute] = "ipaddress" # this is the value of the command line via #configure_attribute
|
71
|
+
configure_query([@node_foo, @node_bar])
|
58
72
|
@knife.should_receive(:session_from_list).with(['10.0.0.1', '10.0.0.2'])
|
59
73
|
@knife.configure_session
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
63
77
|
it "searchs for and returns an array of fqdns" do
|
64
|
-
|
65
|
-
Chef::Search::Query.stub!(:new).and_return(@query)
|
78
|
+
configure_query([@node_foo, @node_bar])
|
66
79
|
@knife.should_receive(:session_from_list).with(['foo.example.org', 'bar.example.org'])
|
67
80
|
@knife.configure_session
|
68
81
|
end
|
69
82
|
|
70
|
-
|
83
|
+
should_return_specified_attributes
|
71
84
|
|
72
85
|
context "when cloud hostnames are available" do
|
73
86
|
before do
|
@@ -78,22 +91,35 @@ describe Chef::Knife::Ssh do
|
|
78
91
|
end
|
79
92
|
|
80
93
|
it "returns an array of cloud public hostnames" do
|
81
|
-
|
82
|
-
Chef::Search::Query.stub!(:new).and_return(@query)
|
94
|
+
configure_query([@node_foo, @node_bar])
|
83
95
|
@knife.should_receive(:session_from_list).with(['ec2-10-0-0-1.compute-1.amazonaws.com', 'ec2-10-0-0-2.compute-1.amazonaws.com'])
|
84
96
|
@knife.configure_session
|
85
97
|
end
|
86
|
-
|
87
|
-
|
98
|
+
|
99
|
+
should_return_specified_attributes
|
88
100
|
end
|
89
101
|
|
90
102
|
it "should raise an error if no host are found" do
|
91
|
-
|
92
|
-
Chef::Search::Query.stub!(:new).and_return(@query)
|
103
|
+
configure_query([ ])
|
93
104
|
@knife.ui.should_receive(:fatal)
|
94
105
|
@knife.should_receive(:exit).with(10)
|
95
106
|
@knife.configure_session
|
96
107
|
end
|
108
|
+
|
109
|
+
context "when there are some hosts found but they do not have an attribute to connect with" do
|
110
|
+
before do
|
111
|
+
@query.stub!(:search).and_return([[@node_foo, @node_bar]])
|
112
|
+
@node_foo[:fqdn] = nil
|
113
|
+
@node_bar[:fqdn] = nil
|
114
|
+
Chef::Search::Query.stub!(:new).and_return(@query)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should raise a specific error (CHEF-3402)" do
|
118
|
+
@knife.ui.should_receive(:fatal).with(/^2 nodes found/)
|
119
|
+
@knife.should_receive(:exit).with(10)
|
120
|
+
@knife.configure_session
|
121
|
+
end
|
122
|
+
end
|
97
123
|
end
|
98
124
|
|
99
125
|
context "manual is set to true" do
|
@@ -121,24 +147,37 @@ describe Chef::Knife::Ssh do
|
|
121
147
|
end
|
122
148
|
|
123
149
|
it "should return the value set in the configuration file" do
|
124
|
-
Chef::Config[:knife][:ssh_attribute] = "
|
150
|
+
Chef::Config[:knife][:ssh_attribute] = "config_file"
|
125
151
|
@knife.configure_attribute
|
126
|
-
@knife.config[:attribute].should == "
|
152
|
+
@knife.config[:attribute].should == "config_file"
|
127
153
|
end
|
128
154
|
|
129
155
|
it "should return the value set on the command line" do
|
130
|
-
@knife.config[:attribute] = "
|
156
|
+
@knife.config[:attribute] = "command_line"
|
131
157
|
@knife.configure_attribute
|
132
|
-
@knife.config[:attribute].should == "
|
158
|
+
@knife.config[:attribute].should == "command_line"
|
133
159
|
end
|
134
160
|
|
135
|
-
it "should set override_attribute to the value of attribute" do
|
136
|
-
@knife.config[:attribute] = "
|
161
|
+
it "should set override_attribute to the value of attribute from the command line" do
|
162
|
+
@knife.config[:attribute] = "command_line"
|
137
163
|
@knife.configure_attribute
|
138
|
-
@knife.config[:attribute].should == "
|
139
|
-
@knife.config[:override_attribute].should == "
|
164
|
+
@knife.config[:attribute].should == "command_line"
|
165
|
+
@knife.config[:override_attribute].should == "command_line"
|
140
166
|
end
|
141
167
|
|
168
|
+
it "should set override_attribute to the value of attribute from the config file" do
|
169
|
+
Chef::Config[:knife][:ssh_attribute] = "config_file"
|
170
|
+
@knife.configure_attribute
|
171
|
+
@knife.config[:attribute].should == "config_file"
|
172
|
+
@knife.config[:override_attribute].should == "config_file"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should prefer the command line over the config file for the value of override_attribute" do
|
176
|
+
Chef::Config[:knife][:ssh_attribute] = "config_file"
|
177
|
+
@knife.config[:attribute] = "command_line"
|
178
|
+
@knife.configure_attribute
|
179
|
+
@knife.config[:override_attribute].should == "command_line"
|
180
|
+
end
|
142
181
|
end
|
143
182
|
|
144
183
|
end
|