diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index c1d0e8d7a..e7d547a39 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -442,6 +442,7 @@ module Vagrant # We also set some fields that are purely controlled by Varant info[:forward_agent] = @config.ssh.forward_agent info[:forward_x11] = @config.ssh.forward_x11 + info[:forward_env] = @config.ssh.forward_env info[:ssh_command] = @config.ssh.ssh_command if @config.ssh.ssh_command diff --git a/lib/vagrant/util/ssh.rb b/lib/vagrant/util/ssh.rb index 20afcdb04..5f3876ce9 100644 --- a/lib/vagrant/util/ssh.rb +++ b/lib/vagrant/util/ssh.rb @@ -138,6 +138,10 @@ module Vagrant command_options += ["-o", "ProxyCommand=#{ssh_info[:proxy_command]}"] end + if ssh_info[:forward_env] + command_options += ["-o", "SendEnv=" + ssh_info[:forward_env].keys().join(" ")] + end + # Configurables -- extra_args should always be last due to the way the # ssh args parser works. e.g. if the user wants to use the -t option, # any shell command(s) she'd like to run on the remote server would @@ -172,6 +176,14 @@ module Vagrant LOGGER.info("Executing SSH in subprocess: #{ssh} #{command_options.inspect}") process = ChildProcess.build(ssh, *command_options) process.io.inherit! + + # Forward configured environment variables. + if ssh_info[:forward_env] + ssh_info[:forward_env].each do |host_var, guest_var| + process.environment[guest_var] = ENV[guest_var] + end + end + process.start process.wait return process.exit_code diff --git a/plugins/commands/ssh_config/command.rb b/plugins/commands/ssh_config/command.rb index 6013a90b7..94e89c141 100644 --- a/plugins/commands/ssh_config/command.rb +++ b/plugins/commands/ssh_config/command.rb @@ -41,7 +41,8 @@ module VagrantPlugins forward_agent: ssh_info[:forward_agent], forward_x11: ssh_info[:forward_x11], proxy_command: ssh_info[:proxy_command], - ssh_command: ssh_info[:ssh_command] + ssh_command: ssh_info[:ssh_command], + forward_env: ssh_info[:forward_env], } # Render the template and output directly to STDOUT diff --git a/plugins/communicators/ssh/communicator.rb b/plugins/communicators/ssh/communicator.rb index 40f49e82c..86999502b 100644 --- a/plugins/communicators/ssh/communicator.rb +++ b/plugins/communicators/ssh/communicator.rb @@ -328,6 +328,17 @@ module VagrantPlugins auth_methods << "publickey" if ssh_info[:private_key_path] auth_methods << "password" if ssh_info[:password] + # Build the environment + env_revert = {} + send_env_array = nil + if ssh_info[:forward_agent] + send_env_array = ssh_info[:forward_env].values() + ssh_info[:forward_env].each do |host_var, guest_var| + env_revert[guest_var] = ENV[guest_var] + ENV[guest_var] = ENV[host_var] + end + end + # Build the options we'll use to initiate the connection via Net::SSH common_connect_opts = { auth_methods: auth_methods, @@ -338,6 +349,7 @@ module VagrantPlugins paranoid: false, password: ssh_info[:password], port: ssh_info[:port], + send_env: send_env_array, timeout: 15, user_known_hosts_file: [], verbose: :debug, @@ -430,6 +442,11 @@ module VagrantPlugins # This is raised if a private key type that Net-SSH doesn't support # is used. Show a nicer error. raise Vagrant::Errors::SSHKeyTypeNotSupported + ensure + # TODO: will this leak? + env_revert.each do |guest_var, guest_value| + ENV[guest_var] = guest_value + end end @connection = connection diff --git a/plugins/kernel_v1/config/ssh.rb b/plugins/kernel_v1/config/ssh.rb index 7226917ca..7d9b944b5 100644 --- a/plugins/kernel_v1/config/ssh.rb +++ b/plugins/kernel_v1/config/ssh.rb @@ -13,6 +13,7 @@ module VagrantPlugins attr_accessor :private_key_path attr_accessor :forward_agent attr_accessor :forward_x11 + attr_accessor :forward_env attr_accessor :shell def initialize @@ -26,6 +27,7 @@ module VagrantPlugins @private_key_path = UNSET_VALUE @forward_agent = UNSET_VALUE @forward_x11 = UNSET_VALUE + @forward_env = UNSET_VALUE @shell = UNSET_VALUE end @@ -37,6 +39,7 @@ module VagrantPlugins new.ssh.private_key_path = @private_key_path if @private_key_path != UNSET_VALUE new.ssh.forward_agent = @forward_agent if @forward_agent != UNSET_VALUE new.ssh.forward_x11 = @forward_x11 if @forward_x11 != UNSET_VALUE + new.ssh.forward_env = @forward_env if @forward_env != UNSET_VALUE new.ssh.shell = @shell if @shell != UNSET_VALUE end end diff --git a/plugins/kernel_v2/config/ssh.rb b/plugins/kernel_v2/config/ssh.rb index 95603142c..c9e0a6695 100644 --- a/plugins/kernel_v2/config/ssh.rb +++ b/plugins/kernel_v2/config/ssh.rb @@ -7,6 +7,7 @@ module VagrantPlugins class SSHConfig < SSHConnectConfig attr_accessor :forward_agent attr_accessor :forward_x11 + attr_accessor :forward_env attr_accessor :guest_port attr_accessor :keep_alive attr_accessor :shell @@ -22,6 +23,7 @@ module VagrantPlugins @forward_agent = UNSET_VALUE @forward_x11 = UNSET_VALUE + @forward_env = UNSET_VALUE @guest_port = UNSET_VALUE @keep_alive = UNSET_VALUE @proxy_command = UNSET_VALUE @@ -45,6 +47,7 @@ module VagrantPlugins @forward_agent = false if @forward_agent == UNSET_VALUE @forward_x11 = false if @forward_x11 == UNSET_VALUE + @forward_env = false if @forward_env == UNSET_VALUE @guest_port = 22 if @guest_port == UNSET_VALUE @keep_alive = true if @keep_alive == UNSET_VALUE @proxy_command = nil if @proxy_command == UNSET_VALUE diff --git a/website/docs/source/v2/vagrantfile/ssh_settings.html.md b/website/docs/source/v2/vagrantfile/ssh_settings.html.md index cadeca060..67bfb7936 100644 --- a/website/docs/source/v2/vagrantfile/ssh_settings.html.md +++ b/website/docs/source/v2/vagrantfile/ssh_settings.html.md @@ -67,6 +67,11 @@ is enabled. Defaults to false.