summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivek Singh <vivek.singh@msystechnologies.com>2020-09-18 16:09:12 +0530
committerTim Smith <tsmith84@gmail.com>2021-02-02 11:58:07 -0800
commit36dbbdc8494401e8859aec7e45b468d82454a013 (patch)
treeb11813dace86e368a8d17d0f051f956e0d5bf88c
parentb1470272c084fadf658f35d03e28a66f8e1052fd (diff)
downloadchef-36dbbdc8494401e8859aec7e45b468d82454a013.tar.gz
Rescue Train::UserError and re-try with su_password
Signed-off-by: Vivek Singh <vivek.singh@msystechnologies.com>
-rw-r--r--lib/chef/knife/bootstrap.rb33
-rw-r--r--spec/unit/knife/bootstrap_spec.rb7
2 files changed, 19 insertions, 21 deletions
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 13a62b4de0..340ffaecfd 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -606,25 +606,26 @@ class Chef
# Actual bootstrap command to be run on the node.
# Handles recursive calls if su USER failed to authenticate.
- def bootstrap_run_command(cmd, limit = 3)
- r = connection.run_command(cmd) do |data, ch|
+ def bootstrap_run_command(cmd)
+ r = connection.run_command(cmd) do |data, channel|
ui.msg("#{ui.color(" [#{connection.hostname}]", :cyan)} #{data}")
- ch.send_data("#{config[:su_password] || config[:connection_password]}\n") if data.match?("Password:")
+ channel.send_data("#{config[:su_password] || config[:connection_password]}\n") if data.match?("Password:")
end
+
if r.exit_status != 0
- stderr = (r.stderr + r.stdout).strip
-
- if stderr.match?("su: Authentication failure")
- limit -= 1
- ui.warn("Failed to authenticate su - #{config[:su_user]} to #{server_name}")
- password = ui.ask("Enter password for su - #{config[:su_user]}@#{server_name}:", echo: false)
- config[:su_password] = password
- bootstrap_run_command(cmd, limit) if limit > 0
- else
- ui.error("The following error occurred on #{server_name}:")
- ui.error(stderr)
- exit(r.exit_status)
- end
+ ui.error("The following error occurred on #{server_name}:")
+ ui.error("#{r.stdout} #{r.stderr}".strip)
+ exit(r.exit_status)
+ end
+ rescue Train::UserError => e
+ limit ||= 0
+ if e.reason == :bad_su_user_password && limit < 3
+ limit += 1
+ ui.warn("Failed to authenticate su - #{config[:su_user]} to #{server_name}")
+ config[:su_password] = ui.ask("Enter password for su - #{config[:su_user]}@#{server_name}:", echo: false)
+ retry
+ else
+ raise
end
end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index ede8d029c6..294942c229 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -1763,7 +1763,6 @@ describe Chef::Knife::Bootstrap do
let(:exit_status) { 1 }
let(:stdout) { "su: Authentication failure" }
let(:connection_obj) { double("connection", transport_options: {}) }
- let(:result_mock2) { double("result", exit_status: 1, stderr: "A message", stdout: "") }
it "shows an error and exits" do
allow(connection).to receive(:connection).and_return(connection_obj)
expect(knife.ui).to receive(:info).with(/Bootstrapping.*/)
@@ -1774,10 +1773,8 @@ describe Chef::Knife::Bootstrap do
.to receive(:run_command)
.with("su - USER -c 'sh /path.sh'")
.and_yield("output here", nil)
- .and_return result_mock
- expect(knife.ui).to receive(:ask).and_return("password").twice
- expect(connection).to receive(:run_command).with("su - USER -c 'sh /path.sh'").and_return(result_mock, result_mock2)
- expect { knife.perform_bootstrap("/path.sh") }.to raise_error(SystemExit)
+ .and_raise(Train::UserError)
+ expect { knife.perform_bootstrap("/path.sh") }.to raise_error(Train::UserError)
end
end
end