Merge pull request #6588 from mitchellh/sethvargo/env_shell

Add :env option to shell provisioner
This commit is contained in:
Seth Vargo 2015-11-23 19:38:19 -05:00
commit 262e3f254e
6 changed files with 39 additions and 1 deletions

View File

@ -5,6 +5,7 @@ module VagrantPlugins
class Config < Vagrant.plugin("2", :config)
attr_accessor :inline
attr_accessor :path
attr_accessor :env
attr_accessor :upload_path
attr_accessor :args
attr_accessor :privileged
@ -18,6 +19,7 @@ module VagrantPlugins
@args = UNSET_VALUE
@inline = UNSET_VALUE
@path = UNSET_VALUE
@env = UNSET_VALUE
@upload_path = UNSET_VALUE
@privileged = UNSET_VALUE
@binary = UNSET_VALUE
@ -31,6 +33,7 @@ module VagrantPlugins
@args = nil if @args == UNSET_VALUE
@inline = nil if @inline == UNSET_VALUE
@path = nil if @path == UNSET_VALUE
@env = {} if @env == UNSET_VALUE
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
@privileged = true if @privileged == UNSET_VALUE
@binary = false if @binary == UNSET_VALUE
@ -72,6 +75,10 @@ module VagrantPlugins
end
end
if !env.is_a?(Hash)
errors << I18n.t("vagrant.provisioners.shell.env_must_be_a_hash")
end
# There needs to be a path to upload the script to
if !upload_path
errors << I18n.t("vagrant.provisioners.shell.upload_path_not_set")

View File

@ -47,7 +47,12 @@ module VagrantPlugins
# This is the provision method called if SSH is what is running
# on the remote end, which assumes a POSIX-style host.
def provision_ssh(args)
command = "chmod +x #{config.upload_path} && #{config.upload_path}#{args}"
env = config.env.map { |k,v| "#{k}=#{quote_and_escape(v)}" }.join(" ")
command = "chmod +x '#{config.upload_path}'"
command << " &&"
command << " #{env}" if !env.empty?
command << " #{config.upload_path}#{args}"
with_script_file do |path|
# Upload the script to the machine
@ -107,6 +112,9 @@ module VagrantPlugins
# Upload it
comm.upload(path.to_s, upload_path)
# Build the environment
env = config.env.map { |k,v| "$env:#{k} = #{quote_and_escape(v)}" }.join("; ")
# Calculate the path that we'll be executing
exec_path = upload_path
exec_path.gsub!('/', '\\')
@ -125,6 +133,11 @@ module VagrantPlugins
command = "powershell #{shell_args.to_s} -file #{command}" if
File.extname(exec_path).downcase == '.ps1'
# Append the environment
if !env.empty?
command = "#{env}; #{command}"
end
if config.name
@machine.ui.detail(I18n.t("vagrant.provisioners.shell.running",
script: "script: #{config.name}"))

View File

@ -2054,6 +2054,8 @@ en:
invalid_encoding: |-
Invalid encoding '%{actual}' for script at '%{path}'.
Must be '%{default}' or UTF-8.
env_must_be_a_hash: |-
The shell provisioner's `env' option must be a hash.
no_path_or_inline: "One of `path` or `inline` must be set."
path_and_inline_set: "Only one of `path` or `inline` may be set."
path_invalid: "`path` for shell provisioner does not exist on the host system: %{path}"

View File

@ -98,6 +98,17 @@ describe "VagrantPlugins::Shell::Config" do
I18n.t("vagrant.provisioners.shell.interactive_not_elevated")
])
end
it "returns an error if the environment is not a hash" do
subject.env = "foo"
subject.finalize!
result = subject.validate(machine)
expect(result["shell provisioner"]).to include(
I18n.t("vagrant.provisioners.shell.env_must_be_a_hash")
)
end
end
describe 'finalize!' do

View File

@ -16,6 +16,7 @@ describe "Vagrant::Shell::Provisioner" do
double(
:config,
:args => "doesn't matter",
:env => {},
:upload_path => "arbitrary",
:remote? => false,
:path => nil,

View File

@ -39,6 +39,10 @@ The remainder of the available options are optional:
etc. as needed. You may also pass the arguments in using an array. In this
case, Vagrant will handle quoting for you.
* `env` (hash) - List of key-value pairs to pass in as environment variables to
the script. Vagrant will handle quoting for environment variable values, but
the keys remain untouched.
* `binary` (boolean) - Vagrant automatically replaces Windows line endings with
Unix line endings. If this is true, then Vagrant will not do this. By default
this is "false". If the shell provisioner is communicating over WinRM, this