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

View File

@ -12,8 +12,8 @@ $task_xml = @'
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Principals> <Principals>
<Principal id="Author"> <Principal id="Author">
<UserId>{username}</UserId> <UserId>{user}</UserId>
<LogonType>Password</LogonType> <LogonType><%= options[:interactive] ? 'InteractiveTokenOrPassword' : 'Password' %></LogonType>
<RunLevel>HighestAvailable</RunLevel> <RunLevel>HighestAvailable</RunLevel>
</Principal> </Principal>
</Principals> </Principals>
@ -55,7 +55,7 @@ $schedule.Connect()
$task = $schedule.NewTask($null) $task = $schedule.NewTask($null)
$task.XmlText = $task_xml $task.XmlText = $task_xml
$folder = $schedule.GetFolder("\") $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 = $folder.GetTask("\$task_name")
$registered_task.Run($null) | Out-Null $registered_task.Run($null) | Out-Null

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

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

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

@ -12,6 +12,7 @@ module VagrantPlugins
attr_accessor :keep_color attr_accessor :keep_color
attr_accessor :name attr_accessor :name
attr_accessor :powershell_args attr_accessor :powershell_args
attr_accessor :elevated_interactive
def initialize def initialize
@args = UNSET_VALUE @args = UNSET_VALUE
@ -23,6 +24,7 @@ module VagrantPlugins
@keep_color = UNSET_VALUE @keep_color = UNSET_VALUE
@name = UNSET_VALUE @name = UNSET_VALUE
@powershell_args = UNSET_VALUE @powershell_args = UNSET_VALUE
@elevated_interactive = UNSET_VALUE
end end
def finalize! def finalize!
@ -35,6 +37,7 @@ module VagrantPlugins
@keep_color = false if @keep_color == UNSET_VALUE @keep_color = false if @keep_color == UNSET_VALUE
@name = nil if @name == UNSET_VALUE @name = nil if @name == UNSET_VALUE
@powershell_args = "-ExecutionPolicy Bypass" if @powershell_args == UNSET_VALUE @powershell_args = "-ExecutionPolicy Bypass" if @powershell_args == UNSET_VALUE
@elevated_interactive = false if @elevated_interactive == UNSET_VALUE
if @args && args_valid? if @args && args_valid?
@args = @args.is_a?(Array) ? @args.map { |a| a.to_s } : @args.to_s @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") errors << I18n.t("vagrant.provisioners.shell.args_bad_type")
end end
if @elevated_interactive == true && @privileged == false
errors << I18n.t("vagrant.provisioners.shell.interactive_not_elevated")
end
{ "shell provisioner" => errors } { "shell provisioner" => errors }
end end

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

@ -137,7 +137,7 @@ module VagrantPlugins
end end
# Execute it with sudo # 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) handle_comm(type, data)
end end
end end

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

@ -1996,6 +1996,7 @@ en:
running: "Running: %{script}" running: "Running: %{script}"
runningas: "Running: %{local} as %{remote}" runningas: "Running: %{local} as %{remote}"
upload_path_not_set: "`upload_path` must be set for the shell provisioner." 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: ansible:
no_playbook: "`playbook` must be set for the Ansible provisioner." 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". defaults to "true".
* `privileged` (boolean) - Specifies whether to execute the shell script * `privileged` (boolean) - Specifies whether to execute the shell script
as a privileged user or not (`sudo`). By default this is "true". This has as a privileged user or not (`sudo`). By default this is "true". Windows
no effect for Windows guests. 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 * `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 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` * `powershell_args` (string) - Extra arguments to pass to `PowerShell`
if you're provisioning with PowerShell on Windows. 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> <a name="inline-scripts"></a>
## Inline Scripts ## Inline Scripts