Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export environment variables and execute command in a subshell #273

Merged
merged 1 commit into from
Aug 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ appear at the top.

* Add your entries below here, remember to credit yourself however you want
to be credited!
* Export environment variables and execute command in a subshell.
[PR #273](https://github.com/capistrano/sshkit/pull/273)
@kuon
* Introduce `log_command_start`, `log_command_data`, `log_command_exit` methods on `Formatter`
[PR #257](https://github.com/capistrano/sshkit/pull/257)
@robd
Expand Down
2 changes: 1 addition & 1 deletion lib/sshkit/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def environment_string

def with(&block)
return yield unless environment_hash.any?
"( #{environment_string} %s )" % yield
"( export #{environment_string} ; %s )" % yield
end

def user(&block)
Expand Down
12 changes: 11 additions & 1 deletion test/functional/backends/test_netssh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_simple_netssh
Command: /usr/bin/env ls -l
Command: if test ! -d /tmp; then echo \"Directory does not exist '/tmp'\" 1>&2; false; fi
Command: if ! sudo -u root whoami > /dev/null; then echo \"You cannot switch to user 'root' using sudo, please check the sudoers file\" 1>&2; false; fi
Command: cd /tmp && ( RAILS_ENV="production" sudo -u root RAILS_ENV="production" -- sh -c '/usr/bin/env touch restart.txt' )
Command: cd /tmp && ( export RAILS_ENV="production" ; sudo -u root RAILS_ENV="production" -- sh -c '/usr/bin/env touch restart.txt' )
EOEXPECTED
end

Expand All @@ -62,6 +62,16 @@ def test_ssh_option_merge
assert_equal({ forward_agent: false, paranoid: true }, host_ssh_options)
end

def test_env_vars_substituion_in_subshell
captured_command_result = nil
Netssh.new(a_host) do |host|
with some_env_var: :some_value do
captured_command_result = capture(:echo, '$SOME_ENV_VAR')
end
end.run
assert_equal "some_value", captured_command_result
end

def test_execute_raises_on_non_zero_exit_status_and_captures_stdout_and_stderr
err = assert_raises SSHKit::Command::Failed do
Netssh.new(a_host) do |host|
Expand Down
18 changes: 9 additions & 9 deletions test/unit/test_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,44 +28,44 @@ def test_using_a_heredoc
def test_including_the_env
SSHKit.config = nil
c = Command.new(:rails, 'server', env: {rails_env: :production})
assert_equal %{( RAILS_ENV="production" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export RAILS_ENV="production" ; /usr/bin/env rails server )}, c.to_command
end

def test_including_the_env_with_multiple_keys
SSHKit.config = nil
c = Command.new(:rails, 'server', env: {rails_env: :production, foo: 'bar'})
assert_equal %{( RAILS_ENV="production" FOO="bar" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export RAILS_ENV="production" FOO="bar" ; /usr/bin/env rails server )}, c.to_command
end

def test_including_the_env_with_string_keys
SSHKit.config = nil
c = Command.new(:rails, 'server', env: {'FACTER_env' => :production, foo: 'bar'})
assert_equal %{( FACTER_env="production" FOO="bar" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export FACTER_env="production" FOO="bar" ; /usr/bin/env rails server )}, c.to_command
end

def test_double_quotes_are_escaped_in_env
SSHKit.config = nil
c = Command.new(:rails, 'server', env: {foo: 'asdf"hjkl'})
assert_equal %{( FOO="asdf\\\"hjkl" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export FOO="asdf\\\"hjkl" ; /usr/bin/env rails server )}, c.to_command
end

def test_including_the_env_doesnt_addressively_escape
SSHKit.config = nil
c = Command.new(:rails, 'server', env: {path: '/example:$PATH'})
assert_equal %{( PATH="/example:$PATH" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export PATH="/example:$PATH" ; /usr/bin/env rails server )}, c.to_command
end

def test_global_env
SSHKit.config = nil
SSHKit.config.default_env = { default: 'env' }
c = Command.new(:rails, 'server', env: {})
assert_equal %{( DEFAULT="env" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export DEFAULT="env" ; /usr/bin/env rails server )}, c.to_command
end

def test_default_env_is_overwritten_with_locally_defined
SSHKit.config.default_env = { foo: 'bar', over: 'under' }
c = Command.new(:rails, 'server', env: { over: 'write'})
assert_equal %{( FOO="bar" OVER="write" /usr/bin/env rails server )}, c.to_command
assert_equal %{( export FOO="bar" OVER="write" ; /usr/bin/env rails server )}, c.to_command
end

def test_working_in_a_given_directory
Expand All @@ -75,7 +75,7 @@ def test_working_in_a_given_directory

def test_working_in_a_given_directory_with_env
c = Command.new(:ls, '-l', in: "/opt/sites", env: {a: :b})
assert_equal %{cd /opt/sites && ( A="b" /usr/bin/env ls -l )}, c.to_command
assert_equal %{cd /opt/sites && ( export A="b" ; /usr/bin/env ls -l )}, c.to_command
end

def test_having_a_host_passed
Expand Down Expand Up @@ -120,7 +120,7 @@ def test_umask_with_working_directory_and_user
def test_umask_with_env_and_working_directory_and_user
SSHKit.config.umask = '007'
c = Command.new(:touch, 'somefile', user: 'bob', env: {a: 'b'}, in: '/var')
assert_equal %{cd /var && umask 007 && ( A="b" sudo -u bob A="b" -- sh -c '/usr/bin/env touch somefile' )}, c.to_command
assert_equal %{cd /var && umask 007 && ( export A="b" ; sudo -u bob A="b" -- sh -c '/usr/bin/env touch somefile' )}, c.to_command
end

def test_verbosity_defaults_to_logger_info
Expand Down