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) class Config < Vagrant.plugin("2", :config)
attr_accessor :inline attr_accessor :inline
attr_accessor :path attr_accessor :path
attr_accessor :env
attr_accessor :upload_path attr_accessor :upload_path
attr_accessor :args attr_accessor :args
attr_accessor :privileged attr_accessor :privileged
@ -18,6 +19,7 @@ module VagrantPlugins
@args = UNSET_VALUE @args = UNSET_VALUE
@inline = UNSET_VALUE @inline = UNSET_VALUE
@path = UNSET_VALUE @path = UNSET_VALUE
@env = UNSET_VALUE
@upload_path = UNSET_VALUE @upload_path = UNSET_VALUE
@privileged = UNSET_VALUE @privileged = UNSET_VALUE
@binary = UNSET_VALUE @binary = UNSET_VALUE
@ -31,6 +33,7 @@ module VagrantPlugins
@args = nil if @args == UNSET_VALUE @args = nil if @args == UNSET_VALUE
@inline = nil if @inline == UNSET_VALUE @inline = nil if @inline == UNSET_VALUE
@path = nil if @path == UNSET_VALUE @path = nil if @path == UNSET_VALUE
@env = {} if @env == UNSET_VALUE
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE @upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
@privileged = true if @privileged == UNSET_VALUE @privileged = true if @privileged == UNSET_VALUE
@binary = false if @binary == UNSET_VALUE @binary = false if @binary == UNSET_VALUE
@ -72,6 +75,10 @@ module VagrantPlugins
end end
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 # There needs to be a path to upload the script to
if !upload_path if !upload_path
errors << I18n.t("vagrant.provisioners.shell.upload_path_not_set") 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 # This is the provision method called if SSH is what is running
# on the remote end, which assumes a POSIX-style host. # on the remote end, which assumes a POSIX-style host.
def provision_ssh(args) 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| with_script_file do |path|
# Upload the script to the machine # Upload the script to the machine
@ -107,6 +112,9 @@ module VagrantPlugins
# Upload it # Upload it
comm.upload(path.to_s, upload_path) 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 # Calculate the path that we'll be executing
exec_path = upload_path exec_path = upload_path
exec_path.gsub!('/', '\\') exec_path.gsub!('/', '\\')
@ -125,6 +133,11 @@ module VagrantPlugins
command = "powershell #{shell_args.to_s} -file #{command}" if command = "powershell #{shell_args.to_s} -file #{command}" if
File.extname(exec_path).downcase == '.ps1' File.extname(exec_path).downcase == '.ps1'
# Append the environment
if !env.empty?
command = "#{env}; #{command}"
end
if config.name if config.name
@machine.ui.detail(I18n.t("vagrant.provisioners.shell.running", @machine.ui.detail(I18n.t("vagrant.provisioners.shell.running",
script: "script: #{config.name}")) script: "script: #{config.name}"))

View File

@ -2054,6 +2054,8 @@ en:
invalid_encoding: |- invalid_encoding: |-
Invalid encoding '%{actual}' for script at '%{path}'. Invalid encoding '%{actual}' for script at '%{path}'.
Must be '%{default}' or UTF-8. 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." 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_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}" 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") I18n.t("vagrant.provisioners.shell.interactive_not_elevated")
]) ])
end 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 end
describe 'finalize!' do describe 'finalize!' do

View File

@ -16,6 +16,7 @@ describe "Vagrant::Shell::Provisioner" do
double( double(
:config, :config,
:args => "doesn't matter", :args => "doesn't matter",
:env => {},
:upload_path => "arbitrary", :upload_path => "arbitrary",
:remote? => false, :remote? => false,
:path => nil, :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 etc. as needed. You may also pass the arguments in using an array. In this
case, Vagrant will handle quoting for you. 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 * `binary` (boolean) - Vagrant automatically replaces Windows line endings with
Unix line endings. If this is true, then Vagrant will not do this. By default 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 this is "false". If the shell provisioner is communicating over WinRM, this