1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Use sudo -p switch to set sudo password prompt to something predictable

git-svn-id: http://svn.rubyonrails.org/rails/tools/capistrano@7390 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jamis Buck 2007-09-01 14:56:00 +00:00
parent 8bfb81eac9
commit 250530b225
3 changed files with 32 additions and 16 deletions

View file

@ -1,5 +1,7 @@
*SVN*
* Use sudo -p switch to set sudo password prompt to something predictable [Mike Bailey]
* Allow independent configurations to require the same recipe file [Jamis Buck]
* Set :shell to false to run a command without wrapping it in "sh -c" [Jamis Buck]
@ -16,7 +18,7 @@
* Add version_dir, current_dir, and shared_dir variables for naming the directories used in deployment [drinkingbird]
* Use Windows-safe binary reads for reading file contents [fukas78]
* Use Windows-safe binary reads for reading file contents [Ladislav Martincik]
* Add Accurev SCM support [Doug Barth]

View file

@ -68,9 +68,9 @@ module Capistrano
options = options.dup
as = options.delete(:as)
user = as && "-u #{as}"
command = [fetch(:sudo, "sudo"), user, command].compact.join(" ")
command = [fetch(:sudo, "sudo"), "-p '#{sudo_prompt}'", user, command].compact.join(" ")
run(command, options, &sudo_behavior_callback(block))
end
@ -84,9 +84,9 @@ module Capistrano
# was wrong, let's track which host prompted first and only allow
# subsequent prompts from that host.
prompt_host = nil
Proc.new do |ch, stream, out|
if out =~ /password:/i
if out =~ /^#{Regexp.escape(sudo_prompt)}/
ch.send_data "#{self[:password]}\n"
elsif out =~ /try again/
if prompt_host.nil? || prompt_host == ch[:server]
@ -123,6 +123,13 @@ module Capistrano
options
end
private
# Returns the prompt text to use with sudo
def sudo_prompt
fetch(:sudo_prompt, "sudo password: ")
end
end
end
end

View file

@ -97,38 +97,45 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
end
def test_sudo_should_default_to_sudo
@config.expects(:run).with("sudo ls", {})
@config.expects(:run).with("sudo -p 'sudo password: ' ls", {})
@config.sudo "ls"
end
def test_sudo_should_use_sudo_variable_definition
@config.expects(:run).with("/opt/local/bin/sudo ls", {})
@config.expects(:run).with("/opt/local/bin/sudo -p 'sudo password: ' ls", {})
@config.options[:sudo] = "/opt/local/bin/sudo"
@config.sudo "ls"
end
def test_sudo_should_interpret_as_option_as_user
@config.expects(:run).with("sudo -u app ls", {})
@config.expects(:run).with("sudo -p 'sudo password: ' -u app ls", {})
@config.sudo "ls", :as => "app"
end
def test_sudo_should_pass_options_through_to_run
@config.expects(:run).with("sudo ls", :foo => "bar")
@config.expects(:run).with("sudo -p 'sudo password: ' ls", :foo => "bar")
@config.sudo "ls", :foo => "bar"
end
def test_sudo_behavior_callback_should_send_password_when_prompted
ch = mock("channel")
ch.expects(:send_data).with("g00b3r\n")
@config.options[:password] = "g00b3r"
@config.sudo_behavior_callback(nil)[ch, nil, "Password: "]
def test_sudo_should_interpret_sudo_prompt_variable_as_custom_prompt
@config.set :sudo_prompt, "give it to me: "
@config.expects(:run).with("sudo -p 'give it to me: ' ls", {})
@config.sudo "ls"
end
def test_sudo_behavior_callback_should_send_password_when_prompted_with_SuSE_dialect
def test_sudo_behavior_callback_should_send_password_when_prompted_with_default_sudo_prompt
ch = mock("channel")
ch.expects(:send_data).with("g00b3r\n")
@config.options[:password] = "g00b3r"
@config.sudo_behavior_callback(nil)[ch, nil, "user's password: "]
@config.sudo_behavior_callback(nil)[ch, nil, "sudo password: "]
end
def test_sudo_behavior_callback_should_send_password_when_prompted_with_custom_sudo_prompt
ch = mock("channel")
ch.expects(:send_data).with("g00b3r\n")
@config.set :sudo_prompt, "give it to me: "
@config.options[:password] = "g00b3r"
@config.sudo_behavior_callback(nil)[ch, nil, "give it to me: "]
end
def test_sudo_behavior_callback_with_incorrect_password_on_first_prompt