chef 10.14.2 → 10.14.4.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/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
|