add the option to make elevated interactive scripts

This commit is contained in:
Marc Siegfriedt 2015-08-21 13:37:10 -07:00 committed by Dan Dunckel
parent c88d52082a
commit 8e87990599
7 changed files with 45 additions and 27 deletions

7
plugins/communicators/winrm/communicator.rb Normal file → Executable file
View File

@ -136,10 +136,11 @@ module VagrantPlugins
error_key: nil, # use the error_class message key
good_exit: 0,
shell: :powershell,
interactive: false,
}.merge(opts || {})
opts[:good_exit] = Array(opts[:good_exit])
command = wrap_in_scheduled_task(command) if opts[:elevated]
command = wrap_in_scheduled_task(command, opts[:interactive]) if opts[:elevated]
output = shell.send(opts[:shell], command, &block)
execution_output(output, opts)
end
@ -195,7 +196,9 @@ module VagrantPlugins
# @return The wrapper command to execute
def wrap_in_scheduled_task(command)
path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__)
script = Vagrant::Util::TemplateRenderer.render(path)
script = Vagrant::Util::TemplateRenderer.render(path, options: {
interactive: interactive,
})
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
file = Tempfile.new(["vagrant-elevated-shell", "ps1"])
begin

View File

@ -12,8 +12,8 @@ $task_xml = @'
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Principals>
<Principal id="Author">
<UserId>{username}</UserId>
<LogonType>Password</LogonType>
<UserId>{user}</UserId>
<LogonType><%= options[:interactive] ? 'InteractiveTokenOrPassword' : 'Password' %></LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
@ -55,7 +55,7 @@ $schedule.Connect()
$task = $schedule.NewTask($null)
$task.XmlText = $task_xml
$folder = $schedule.GetFolder("\")
$folder.RegisterTaskDefinition($task_name, $task, 6, $username, $password, 1, $null) | Out-Null
$folder.RegisterTaskDefinition($task_name, $task, 6, $user, $password, <%= options[:interactive] ? 3 : 1 %>, $null) | Out-Null
$registered_task = $folder.GetTask("\$task_name")
$registered_task.Run($null) | Out-Null
@ -71,7 +71,7 @@ function SlurpOutput($out_file, $cur_line) {
if (Test-Path $out_file) {
get-content $out_file | select -skip $cur_line | ForEach {
$cur_line += 1
Write-Host "$_"
Write-Host "$_"
}
}
return $cur_line

1
plugins/communicators/winrm/shell.rb Normal file → Executable file
View File

@ -23,6 +23,7 @@ module VagrantPlugins
HTTPClient::KeepAliveDisconnected,
WinRM::WinRMHTTPTransportError,
WinRM::WinRMAuthorizationError,
WinRM::WinRMWSManFault,
Errno::EACCES,
Errno::EADDRINUSE,
Errno::ECONNREFUSED,

43
plugins/provisioners/shell/config.rb Normal file → Executable file
View File

@ -12,29 +12,32 @@ module VagrantPlugins
attr_accessor :keep_color
attr_accessor :name
attr_accessor :powershell_args
attr_accessor :elevated_interactive
def initialize
@args = UNSET_VALUE
@inline = UNSET_VALUE
@path = UNSET_VALUE
@upload_path = UNSET_VALUE
@privileged = UNSET_VALUE
@binary = UNSET_VALUE
@keep_color = UNSET_VALUE
@name = UNSET_VALUE
@powershell_args = UNSET_VALUE
@args = UNSET_VALUE
@inline = UNSET_VALUE
@path = UNSET_VALUE
@upload_path = UNSET_VALUE
@privileged = UNSET_VALUE
@binary = UNSET_VALUE
@keep_color = UNSET_VALUE
@name = UNSET_VALUE
@powershell_args = UNSET_VALUE
@elevated_interactive = UNSET_VALUE
end
def finalize!
@args = nil if @args == UNSET_VALUE
@inline = nil if @inline == UNSET_VALUE
@path = nil if @path == UNSET_VALUE
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
@privileged = true if @privileged == UNSET_VALUE
@binary = false if @binary == UNSET_VALUE
@keep_color = false if @keep_color == UNSET_VALUE
@name = nil if @name == UNSET_VALUE
@powershell_args = "-ExecutionPolicy Bypass" if @powershell_args == UNSET_VALUE
@args = nil if @args == UNSET_VALUE
@inline = nil if @inline == UNSET_VALUE
@path = nil if @path == UNSET_VALUE
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
@privileged = true if @privileged == UNSET_VALUE
@binary = false if @binary == UNSET_VALUE
@keep_color = false if @keep_color == UNSET_VALUE
@name = nil if @name == UNSET_VALUE
@powershell_args = "-ExecutionPolicy Bypass" if @powershell_args == UNSET_VALUE
@elevated_interactive = false if @elevated_interactive == UNSET_VALUE
if @args && args_valid?
@args = @args.is_a?(Array) ? @args.map { |a| a.to_s } : @args.to_s
@ -78,6 +81,10 @@ module VagrantPlugins
errors << I18n.t("vagrant.provisioners.shell.args_bad_type")
end
if @elevated_interactive == true && @privileged == false
errors << I18n.t("vagrant.provisioners.shell.interactive_not_elevated")
end
{ "shell provisioner" => errors }
end

2
plugins/provisioners/shell/provisioner.rb Normal file → Executable file
View File

@ -137,7 +137,7 @@ module VagrantPlugins
end
# Execute it with sudo
comm.sudo(command, elevated: config.privileged) do |type, data|
comm.sudo(command, { elevated: config.privileged, interactive: config.elevated_interactive }) do |type, data|
handle_comm(type, data)
end
end

1
templates/locales/en.yml Normal file → Executable file
View File

@ -1996,6 +1996,7 @@ en:
running: "Running: %{script}"
runningas: "Running: %{local} as %{remote}"
upload_path_not_set: "`upload_path` must be set for the shell provisioner."
interactive_not_elevated: "To be interactive, it must also be privileged."
ansible:
no_playbook: "`playbook` must be set for the Ansible provisioner."

10
website/docs/source/v2/provisioning/shell.html.md Normal file → Executable file
View File

@ -45,8 +45,9 @@ The remainder of the available options are optional:
defaults to "true".
* `privileged` (boolean) - Specifies whether to execute the shell script
as a privileged user or not (`sudo`). By default this is "true". This has
no effect for Windows guests.
as a privileged user or not (`sudo`). By default this is "true". Windows
guests use a scheduled task to run as a true administrator without the
WinRM limitations.
* `upload_path` (string) - Is the remote path where the shell script will
be uploaded to. The script is uploaded as the SSH user over SCP, so this
@ -65,6 +66,11 @@ The remainder of the available options are optional:
* `powershell_args` (string) - Extra arguments to pass to `PowerShell`
if you're provisioning with PowerShell on Windows.
* `elevated_interactive` (boolean) - Run an elevated script in interactive mode
on Windows. By default this is "false". Must also be `privileged`. Be sure to
enable auto-login for Windows as the user must be logged in for interactive
mode to work.
<a name="inline-scripts"></a>
## Inline Scripts