vagrant-unbundled 1.9.1.1 → 1.9.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +126 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/bin/vagrant +11 -0
- data/contrib/bash/completion.sh +9 -9
- data/lib/vagrant.rb +4 -2
- data/lib/vagrant/action/builtin/box_add.rb +13 -8
- data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +67 -14
- data/lib/vagrant/action/builtin/provision.rb +10 -5
- data/lib/vagrant/action/general/package_setup_files.rb +51 -0
- data/lib/vagrant/action/general/package_setup_folders.rb +37 -0
- data/lib/vagrant/batch_action.rb +4 -2
- data/lib/vagrant/box_collection.rb +17 -5
- data/lib/vagrant/bundler.rb +110 -12
- data/lib/vagrant/cli.rb +1 -1
- data/lib/vagrant/environment.rb +4 -4
- data/lib/vagrant/errors.rb +32 -0
- data/lib/vagrant/shared_helpers.rb +14 -0
- data/lib/vagrant/ui.rb +3 -3
- data/lib/vagrant/util.rb +7 -1
- data/lib/vagrant/util/command_deprecation.rb +56 -0
- data/lib/vagrant/util/credential_scrubber.rb +29 -0
- data/lib/vagrant/util/guest_inspection.rb +47 -0
- data/lib/vagrant/util/platform.rb +217 -27
- data/lib/vagrant/util/powershell.rb +25 -0
- data/lib/vagrant/util/safe_exec.rb +9 -1
- data/lib/vagrant/util/ssh.rb +1 -1
- data/lib/vagrant/util/subprocess.rb +21 -2
- data/lib/vagrant/util/which.rb +6 -4
- data/plugins/commands/box/command/list.rb +1 -1
- data/plugins/commands/package/command.rb +3 -2
- data/plugins/commands/plugin/action.rb +2 -1
- data/plugins/commands/plugin/action/expunge_plugins.rb +20 -5
- data/plugins/commands/plugin/action/install_gem.rb +0 -8
- data/plugins/commands/plugin/command/expunge.rb +18 -5
- data/plugins/commands/plugin/command/mixin_install_opts.rb +1 -4
- data/plugins/commands/plugin/gem_helper.rb +5 -1
- data/plugins/commands/up/command.rb +1 -1
- data/plugins/commands/validate/command.rb +31 -0
- data/plugins/commands/validate/plugin.rb +17 -0
- data/plugins/communicators/ssh/communicator.rb +50 -25
- data/plugins/communicators/winrm/communicator.rb +8 -54
- data/plugins/communicators/winrm/config.rb +3 -0
- data/plugins/communicators/winrm/helper.rb +1 -1
- data/plugins/communicators/winrm/shell.rb +38 -32
- data/plugins/communicators/winssh/communicator.rb +161 -0
- data/plugins/communicators/winssh/config.rb +30 -0
- data/plugins/communicators/winssh/plugin.rb +21 -0
- data/plugins/guests/arch/cap/change_host_name.rb +0 -3
- data/plugins/guests/arch/cap/configure_networks.rb +1 -1
- data/plugins/guests/atomic/cap/change_host_name.rb +0 -3
- data/plugins/guests/darwin/cap/change_host_name.rb +0 -4
- data/plugins/guests/debian/cap/change_host_name.rb +0 -3
- data/plugins/guests/debian/cap/configure_networks.rb +2 -1
- data/plugins/guests/elementary/guest.rb +10 -0
- data/plugins/guests/elementary/plugin.rb +15 -0
- data/plugins/guests/esxi/cap/public_key.rb +63 -0
- data/plugins/guests/esxi/plugin.rb +11 -0
- data/plugins/guests/freebsd/cap/change_host_name.rb +0 -4
- data/plugins/guests/gentoo/cap/change_host_name.rb +7 -5
- data/plugins/guests/gentoo/cap/configure_networks.rb +57 -21
- data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +20 -53
- data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -58
- data/plugins/guests/linux/cap/network_interfaces.rb +8 -1
- data/plugins/guests/linux/cap/nfs.rb +5 -14
- data/plugins/guests/linux/guest.rb +3 -3
- data/plugins/guests/omnios/cap/change_host_name.rb +0 -3
- data/plugins/guests/openbsd/cap/change_host_name.rb +0 -4
- data/plugins/guests/photon/cap/change_host_name.rb +0 -3
- data/plugins/guests/pld/cap/change_host_name.rb +0 -3
- data/plugins/guests/redhat/cap/change_host_name.rb +2 -9
- data/plugins/guests/redhat/cap/configure_networks.rb +43 -21
- data/plugins/guests/slackware/cap/change_host_name.rb +0 -3
- data/plugins/guests/suse/cap/change_host_name.rb +0 -3
- data/plugins/guests/tinycore/cap/mount_nfs.rb +3 -8
- data/plugins/guests/windows/cap/configure_networks.rb +0 -4
- data/plugins/guests/windows/cap/mount_shared_folder.rb +13 -1
- data/plugins/guests/windows/scripts/mount_volume.ps1.erb +1 -1
- data/plugins/hosts/windows/cap/ps.rb +6 -1
- data/plugins/kernel_v2/config/vm.rb +6 -4
- data/plugins/providers/docker/action.rb +4 -7
- data/plugins/providers/docker/action/build.rb +1 -1
- data/plugins/providers/docker/action/create.rb +3 -0
- data/plugins/providers/docker/config.rb +27 -1
- data/plugins/providers/docker/driver.rb +15 -2
- data/plugins/providers/docker/driver/compose.rb +287 -0
- data/plugins/providers/docker/errors.rb +16 -0
- data/plugins/providers/docker/provider.rb +25 -10
- data/plugins/providers/hyperv/action.rb +33 -8
- data/plugins/providers/hyperv/action/export.rb +39 -0
- data/plugins/providers/hyperv/action/import.rb +23 -4
- data/plugins/providers/hyperv/action/package.rb +16 -0
- data/plugins/providers/hyperv/action/package_metadata_json.rb +34 -0
- data/plugins/providers/hyperv/action/package_setup_files.rb +16 -0
- data/plugins/providers/hyperv/action/package_setup_folders.rb +18 -0
- data/plugins/providers/hyperv/action/package_vagrantfile.rb +34 -0
- data/plugins/providers/hyperv/config.rb +20 -4
- data/plugins/providers/hyperv/driver.rb +12 -0
- data/plugins/providers/hyperv/scripts/export_vm.ps1 +15 -0
- data/plugins/providers/hyperv/scripts/get_network_mac.ps1 +28 -0
- data/plugins/providers/hyperv/scripts/has_vmcx_support.ps1 +11 -0
- data/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +10 -4
- data/plugins/providers/hyperv/scripts/import_vm_xml.ps1 +9 -3
- data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +37 -0
- data/plugins/providers/virtualbox/action/package_setup_files.rb +7 -42
- data/plugins/providers/virtualbox/action/package_setup_folders.rb +6 -26
- data/plugins/providers/virtualbox/driver/base.rb +10 -0
- data/plugins/providers/virtualbox/driver/version_5_0.rb +11 -11
- data/plugins/providers/virtualbox/driver/version_5_1.rb +3 -721
- data/plugins/providers/virtualbox/provider.rb +9 -5
- data/plugins/providers/virtualbox/synced_folder.rb +1 -1
- data/plugins/providers/virtualbox/util/compile_forwarded_ports.rb +3 -1
- data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +2 -2
- data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +8 -8
- data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +9 -5
- data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
- data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +5 -3
- data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +7 -3
- data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +1 -1
- data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
- data/plugins/provisioners/ansible/config/guest.rb +7 -1
- data/plugins/provisioners/ansible/provisioner/guest.rb +1 -1
- data/plugins/provisioners/chef/cap/freebsd/chef_install.rb +18 -0
- data/plugins/provisioners/chef/cap/freebsd/chef_installed.rb +22 -0
- data/plugins/provisioners/chef/plugin.rb +10 -0
- data/plugins/provisioners/docker/cap/linux/docker_installed.rb +1 -0
- data/plugins/provisioners/salt/bootstrap-salt.ps1 +4 -4
- data/plugins/provisioners/shell/config.rb +2 -2
- data/plugins/provisioners/shell/provisioner.rb +66 -4
- data/plugins/pushes/atlas/push.rb +6 -0
- data/plugins/pushes/local-exec/config.rb +2 -2
- data/plugins/synced_folders/unix_mount_helpers.rb +105 -0
- data/templates/commands/init/Vagrantfile.erb +6 -0
- data/templates/commands/init/Vagrantfile.min.erb +3 -0
- data/templates/guests/debian/network_dhcp.erb +2 -2
- data/templates/guests/gentoo/network_systemd.erb +16 -0
- data/templates/guests/redhat/network_dhcp.erb +1 -0
- data/templates/guests/redhat/network_static.erb +1 -1
- data/templates/guests/redhat/network_static6.erb +1 -1
- data/templates/locales/en.yml +72 -3
- data/templates/locales/providers_docker.yml +15 -0
- data/test/acceptance/provider-virtualbox/linked_clone_spec.rb +1 -1
- data/test/unit/plugins/commands/init/command_test.rb +7 -0
- data/test/unit/plugins/commands/up/command_test.rb +65 -0
- data/test/unit/plugins/commands/validate/command_test.rb +52 -0
- data/test/unit/plugins/communicators/ssh/communicator_test.rb +58 -2
- data/test/unit/plugins/communicators/winrm/communicator_test.rb +14 -26
- data/test/unit/plugins/communicators/winrm/helper_test.rb +12 -0
- data/test/unit/plugins/communicators/winrm/shell_test.rb +54 -15
- data/test/unit/plugins/communicators/winssh/communicator_test.rb +525 -0
- data/test/unit/plugins/guests/arch/cap/configure_networks_test.rb +5 -0
- data/test/unit/plugins/guests/esxi/cap/public_key_test.rb +48 -0
- data/test/unit/plugins/guests/linux/cap/mount_nfs_test.rb +1 -1
- data/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder.rb +71 -0
- data/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb +43 -0
- data/test/unit/plugins/guests/linux/cap/network_interfaces_test.rb +10 -10
- data/test/unit/plugins/guests/redhat/cap/configure_networks_test.rb +132 -12
- data/test/unit/plugins/guests/windows/cap/mount_shared_folder_test.rb +23 -0
- data/test/unit/plugins/providers/docker/driver_compose_test.rb +268 -0
- data/test/unit/plugins/provisioners/ansible/config/guest_test.rb +9 -0
- data/test/unit/plugins/provisioners/ansible/provisioner_test.rb +2 -2
- data/test/unit/plugins/pushes/atlas/push_test.rb +151 -150
- data/test/unit/templates/guests/debian/network_dhcp_test.rb +1 -0
- data/test/unit/templates/guests/gentoo/systemd_network_test.rb +73 -0
- data/test/unit/templates/guests/redhat/network_dhcp_test.rb +18 -0
- data/test/unit/vagrant/action/builtin/box_add_test.rb +27 -0
- data/test/unit/vagrant/action/builtin/handle_forwarded_port_collisions_test.rb +170 -0
- data/test/unit/vagrant/action/builtin/provision_test.rb +208 -0
- data/test/unit/vagrant/box_collection_test.rb +98 -0
- data/test/unit/vagrant/environment_test.rb +17 -0
- data/test/unit/vagrant/shared_helpers_test.rb +12 -0
- data/test/unit/vagrant/util/command_deprecation_test.rb +106 -0
- data/test/unit/vagrant/util/env_test.rb +43 -0
- data/test/unit/vagrant/util/platform_test.rb +8 -0
- data/test/unit/vagrant/util/subprocess_test.rb +61 -0
- data/test/vagrant-spec/Vagrantfile.spec +78 -0
- data/test/vagrant-spec/boxes/.keep +0 -0
- data/test/vagrant-spec/configs/vagrant-spec.config.virtualbox.rb +10 -0
- data/test/vagrant-spec/scripts/centos-run.virtualbox.sh +8 -0
- data/test/vagrant-spec/scripts/centos-setup.virtualbox.sh +14 -0
- data/test/vagrant-spec/scripts/ubuntu-run.virtualbox.sh +8 -0
- data/test/vagrant-spec/scripts/ubuntu-setup.virtualbox.sh +12 -0
- data/vagrant.gemspec +6 -11
- data/version.txt +1 -1
- metadata +1694 -1835
- data/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb +0 -101
@@ -142,10 +142,10 @@ module VagrantPlugins
|
|
142
142
|
interactive: false,
|
143
143
|
}.merge(opts || {})
|
144
144
|
|
145
|
+
opts[:shell] = :elevated if opts[:elevated]
|
145
146
|
opts[:good_exit] = Array(opts[:good_exit])
|
146
|
-
command = wrap_in_scheduled_task(command, opts[:interactive]) if opts[:elevated]
|
147
147
|
@logger.debug("#{opts[:shell]} executing:\n#{command}")
|
148
|
-
output = shell.send(opts[:shell], command, &block)
|
148
|
+
output = shell.send(opts[:shell], command, opts, &block)
|
149
149
|
execution_output(output, opts)
|
150
150
|
end
|
151
151
|
alias_method :sudo, :execute
|
@@ -165,7 +165,7 @@ module VagrantPlugins
|
|
165
165
|
# If we're passed a *nix command which PS can't parse we get exit code
|
166
166
|
# 0, but output in stderr. We need to check both exit code and stderr.
|
167
167
|
output = shell.send(:powershell, command)
|
168
|
-
return output
|
168
|
+
return output.exitcode == 0 && output.stderr.length == 0
|
169
169
|
end
|
170
170
|
|
171
171
|
def upload(from, to)
|
@@ -180,7 +180,7 @@ module VagrantPlugins
|
|
180
180
|
|
181
181
|
protected
|
182
182
|
|
183
|
-
# This creates
|
183
|
+
# This creates a new WinRMShell based on the information we know
|
184
184
|
# about this machine.
|
185
185
|
def create_shell
|
186
186
|
winrm_info = Helper.winrm_info(@machine)
|
@@ -192,55 +192,23 @@ module VagrantPlugins
|
|
192
192
|
)
|
193
193
|
end
|
194
194
|
|
195
|
-
# Creates and uploads a PowerShell script which wraps a command in a
|
196
|
-
# scheduled task. The scheduled task allows commands to run on the guest
|
197
|
-
# as a true local admin without any of the restrictions that WinRM puts
|
198
|
-
# in place.
|
199
|
-
#
|
200
|
-
# @return The wrapper command to execute
|
201
|
-
def wrap_in_scheduled_task(command, interactive)
|
202
|
-
path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__)
|
203
|
-
script = Vagrant::Util::TemplateRenderer.render(path, options: {
|
204
|
-
interactive: interactive,
|
205
|
-
})
|
206
|
-
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
|
207
|
-
Tempfile.open(["vagrant-elevated-shell", "ps1"]) do |f|
|
208
|
-
f.binmode
|
209
|
-
f.write(script)
|
210
|
-
f.fsync
|
211
|
-
f.close
|
212
|
-
upload(f.path, guest_script_path)
|
213
|
-
end
|
214
|
-
|
215
|
-
# Convert to double byte unicode string then base64 encode
|
216
|
-
# just like PowerShell -EncodedCommand expects.
|
217
|
-
# Suppress the progress stream from leaking to stderr.
|
218
|
-
wrapped_encoded_command = Base64.strict_encode64(
|
219
|
-
"$ProgressPreference='SilentlyContinue'; #{command}; exit $LASTEXITCODE".encode('UTF-16LE', 'UTF-8'))
|
220
|
-
|
221
|
-
"powershell -executionpolicy bypass -file '#{guest_script_path}' " +
|
222
|
-
"-username '#{shell.username}' -password '#{shell.password}' " +
|
223
|
-
"-encoded_command '#{wrapped_encoded_command}' " +
|
224
|
-
"-execution_time_limit '#{shell.execution_time_limit}'"
|
225
|
-
end
|
226
|
-
|
227
195
|
# Handles the raw WinRM shell result and converts it to a
|
228
196
|
# standard Vagrant communicator result
|
229
197
|
def execution_output(output, opts)
|
230
198
|
if opts[:shell] == :wql
|
231
199
|
return output
|
232
200
|
elsif opts[:error_check] && \
|
233
|
-
!opts[:good_exit].include?(output
|
201
|
+
!opts[:good_exit].include?(output.exitcode)
|
234
202
|
raise_execution_error(output, opts)
|
235
203
|
end
|
236
|
-
output
|
204
|
+
output.exitcode
|
237
205
|
end
|
238
206
|
|
239
207
|
def raise_execution_error(output, opts)
|
240
208
|
# WinRM can return multiple stderr and stdout entries
|
241
209
|
error_opts = opts.merge(
|
242
|
-
stdout:
|
243
|
-
stderr:
|
210
|
+
stdout: output.stdout,
|
211
|
+
stderr: output.stderr
|
244
212
|
)
|
245
213
|
|
246
214
|
# Use a different error message key if the caller gave us one,
|
@@ -250,20 +218,6 @@ module VagrantPlugins
|
|
250
218
|
# Raise the error, use the type the caller gave us or the comm default
|
251
219
|
raise opts[:error_class], error_opts
|
252
220
|
end
|
253
|
-
|
254
|
-
|
255
|
-
# TODO: Replace with WinRM Output class when WinRM 1.3 is released
|
256
|
-
def flatten_stderr(output)
|
257
|
-
output[:data].map do | line |
|
258
|
-
line[:stderr]
|
259
|
-
end.compact.join
|
260
|
-
end
|
261
|
-
|
262
|
-
def flatten_stdout(output)
|
263
|
-
output[:data].map do | line |
|
264
|
-
line[:flatten_stdout]
|
265
|
-
end.compact.join
|
266
|
-
end
|
267
221
|
end #WinRM class
|
268
222
|
end
|
269
223
|
end
|
@@ -13,6 +13,7 @@ module VagrantPlugins
|
|
13
13
|
attr_accessor :ssl_peer_verification
|
14
14
|
attr_accessor :execution_time_limit
|
15
15
|
attr_accessor :basic_auth_only
|
16
|
+
attr_accessor :codepage
|
16
17
|
|
17
18
|
def initialize
|
18
19
|
@username = UNSET_VALUE
|
@@ -27,6 +28,7 @@ module VagrantPlugins
|
|
27
28
|
@ssl_peer_verification = UNSET_VALUE
|
28
29
|
@execution_time_limit = UNSET_VALUE
|
29
30
|
@basic_auth_only = UNSET_VALUE
|
31
|
+
@codepage = UNSET_VALUE
|
30
32
|
end
|
31
33
|
|
32
34
|
def finalize!
|
@@ -43,6 +45,7 @@ module VagrantPlugins
|
|
43
45
|
@ssl_peer_verification = true if @ssl_peer_verification == UNSET_VALUE
|
44
46
|
@execution_time_limit = "PT2H" if @execution_time_limit == UNSET_VALUE
|
45
47
|
@basic_auth_only = false if @basic_auth_only == UNSET_VALUE
|
48
|
+
@codepage = nil if @codepage == UNSET_VALUE
|
46
49
|
end
|
47
50
|
|
48
51
|
def validate(machine)
|
@@ -9,6 +9,7 @@ Vagrant::Util::SilenceWarnings.silence! do
|
|
9
9
|
require "winrm"
|
10
10
|
end
|
11
11
|
|
12
|
+
require "winrm-elevated"
|
12
13
|
require "winrm-fs"
|
13
14
|
|
14
15
|
module VagrantPlugins
|
@@ -53,48 +54,55 @@ module VagrantPlugins
|
|
53
54
|
@config = config
|
54
55
|
end
|
55
56
|
|
56
|
-
def powershell(command, &block)
|
57
|
-
|
58
|
-
|
59
|
-
session.create_executor do |executor|
|
60
|
-
execute_with_rescue(executor.method("run_powershell_script"), command, &block)
|
57
|
+
def powershell(command, opts = {}, &block)
|
58
|
+
connection.shell(:powershell) do |shell|
|
59
|
+
execute_with_rescue(shell, command, &block)
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
64
|
-
def cmd(command, &block)
|
65
|
-
|
66
|
-
|
63
|
+
def cmd(command, opts = {}, &block)
|
64
|
+
shell_opts = {}
|
65
|
+
shell_opts[:codepage] = @config.codepage if @config.codepage
|
66
|
+
connection.shell(:cmd, shell_opts) do |shell|
|
67
|
+
execute_with_rescue(shell, command, &block)
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
|
-
def
|
71
|
+
def elevated(command, opts = {}, &block)
|
72
|
+
connection.shell(:elevated) do |shell|
|
73
|
+
shell.interactive_logon = opts[:interactive] || false
|
74
|
+
execute_with_rescue(shell, command, &block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def wql(query, opts = {}, &block)
|
71
79
|
retryable(tries: @config.max_tries, on: @@exceptions_to_retry_on, sleep: @config.retry_delay) do
|
72
|
-
|
80
|
+
connection.run_wql(query)
|
73
81
|
end
|
74
82
|
rescue => e
|
75
83
|
raise_winrm_exception(e, "run_wql", query)
|
76
84
|
end
|
77
85
|
|
78
86
|
def upload(from, to)
|
79
|
-
file_manager = WinRM::FS::FileManager.new(
|
87
|
+
file_manager = WinRM::FS::FileManager.new(connection)
|
80
88
|
file_manager.upload(from, to)
|
81
89
|
end
|
82
90
|
|
83
91
|
def download(from, to)
|
84
|
-
file_manager = WinRM::FS::FileManager.new(
|
92
|
+
file_manager = WinRM::FS::FileManager.new(connection)
|
85
93
|
file_manager.download(from, to)
|
86
94
|
end
|
87
95
|
|
88
96
|
protected
|
89
97
|
|
90
|
-
def execute_with_rescue(
|
91
|
-
handle_output(
|
98
|
+
def execute_with_rescue(shell, command, &block)
|
99
|
+
handle_output(shell, command, &block)
|
92
100
|
rescue => e
|
93
|
-
raise_winrm_exception(e,
|
101
|
+
raise_winrm_exception(e, shell.class.name.split("::").last, command)
|
94
102
|
end
|
95
103
|
|
96
|
-
def handle_output(
|
97
|
-
output =
|
104
|
+
def handle_output(shell, command, &block)
|
105
|
+
output = shell.run(command) do |out, err|
|
98
106
|
block.call(:stdout, out) if block_given? && out
|
99
107
|
block.call(:stderr, err) if block_given? && err
|
100
108
|
end
|
@@ -104,14 +112,10 @@ module VagrantPlugins
|
|
104
112
|
# Verify that we didn't get a parser error, and if so we should
|
105
113
|
# set the exit code to 1. Parse errors return exit code 0 so we
|
106
114
|
# need to do this.
|
107
|
-
if output
|
108
|
-
(
|
109
|
-
|
110
|
-
|
111
|
-
@logger.warn("Detected ParserError, setting exit code to 1")
|
112
|
-
output[:exitcode] = 1
|
113
|
-
break
|
114
|
-
end
|
115
|
+
if output.exitcode == 0
|
116
|
+
if output.stderr.include?("ParserError")
|
117
|
+
@logger.warn("Detected ParserError, setting exit code to 1")
|
118
|
+
output.exitcode = 1
|
115
119
|
end
|
116
120
|
end
|
117
121
|
|
@@ -159,21 +163,20 @@ module VagrantPlugins
|
|
159
163
|
end
|
160
164
|
end
|
161
165
|
|
162
|
-
def
|
166
|
+
def new_connection
|
163
167
|
@logger.info("Attempting to connect to WinRM...")
|
164
168
|
@logger.info(" - Host: #{@host}")
|
165
169
|
@logger.info(" - Port: #{@port}")
|
166
170
|
@logger.info(" - Username: #{@config.username}")
|
167
171
|
@logger.info(" - Transport: #{@config.transport}")
|
168
172
|
|
169
|
-
client = ::WinRM::
|
170
|
-
client.set_timeout(@config.timeout)
|
173
|
+
client = ::WinRM::Connection.new(endpoint_options)
|
171
174
|
client.logger = @logger
|
172
175
|
client
|
173
176
|
end
|
174
177
|
|
175
|
-
def
|
176
|
-
@
|
178
|
+
def connection
|
179
|
+
@connection ||= new_connection
|
177
180
|
end
|
178
181
|
|
179
182
|
def endpoint
|
@@ -188,8 +191,11 @@ module VagrantPlugins
|
|
188
191
|
end
|
189
192
|
|
190
193
|
def endpoint_options
|
191
|
-
{
|
192
|
-
|
194
|
+
{ endpoint: endpoint,
|
195
|
+
transport: @config.transport,
|
196
|
+
operation_timeout: @config.timeout,
|
197
|
+
user: @username,
|
198
|
+
password: @password,
|
193
199
|
host: @host,
|
194
200
|
port: @port,
|
195
201
|
basic_auth_only: @config.basic_auth_only,
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require File.expand_path("../../ssh/communicator", __FILE__)
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module CommunicatorWinSSH
|
5
|
+
# This class provides communication with a Windows VM running
|
6
|
+
# the Windows native port of OpenSSH
|
7
|
+
class Communicator < VagrantPlugins::CommunicatorSSH::Communicator
|
8
|
+
|
9
|
+
def initialize(machine)
|
10
|
+
super
|
11
|
+
@logger = Log4r::Logger.new("vagrant::communication::winssh")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Executes the command on an SSH connection within a login shell.
|
15
|
+
def shell_execute(connection, command, **opts)
|
16
|
+
opts = {
|
17
|
+
sudo: false,
|
18
|
+
shell: nil
|
19
|
+
}.merge(opts)
|
20
|
+
|
21
|
+
sudo = opts[:sudo]
|
22
|
+
shell = (opts[:shell] || machine_config_ssh.shell).to_s
|
23
|
+
|
24
|
+
@logger.info("Execute: #{command} (sudo=#{sudo.inspect})")
|
25
|
+
exit_status = nil
|
26
|
+
|
27
|
+
# Open the channel so we can execute or command
|
28
|
+
channel = connection.open_channel do |ch|
|
29
|
+
marker_found = false
|
30
|
+
data_buffer = ''
|
31
|
+
stderr_marker_found = false
|
32
|
+
stderr_data_buffer = ''
|
33
|
+
|
34
|
+
tfile = Tempfile.new('vagrant-ssh')
|
35
|
+
remote_ext = shell == "powershell" ? "ps1" : "bat"
|
36
|
+
remote_name = "C:\\Windows\\Temp\\#{File.basename(tfile.path)}.#{remote_ext}"
|
37
|
+
|
38
|
+
if shell == "powershell"
|
39
|
+
base_cmd = "powershell -File #{remote_name}"
|
40
|
+
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
41
|
+
Remove-Item #{remote_name}
|
42
|
+
Write-Host #{CMD_GARBAGE_MARKER}
|
43
|
+
[Console]::Error.WriteLine("#{CMD_GARBAGE_MARKER}")
|
44
|
+
#{command}
|
45
|
+
SCRIPT
|
46
|
+
else
|
47
|
+
base_cmd = remote_name
|
48
|
+
tfile.puts <<-SCRIPT.force_encoding('ASCII-8BIT')
|
49
|
+
ECHO OFF
|
50
|
+
ECHO #{CMD_GARBAGE_MARKER}
|
51
|
+
ECHO #{CMD_GARBAGE_MARKER} 1>&2
|
52
|
+
#{command}
|
53
|
+
SCRIPT
|
54
|
+
end
|
55
|
+
|
56
|
+
tfile.close
|
57
|
+
upload(tfile.path, remote_name)
|
58
|
+
tfile.delete
|
59
|
+
|
60
|
+
base_cmd = shell_cmd(opts.merge(shell: base_cmd))
|
61
|
+
@logger.debug("Base SSH exec command: #{base_cmd}")
|
62
|
+
|
63
|
+
ch.exec(base_cmd) do |ch2, _|
|
64
|
+
# Setup the channel callbacks so we can get data and exit status
|
65
|
+
ch2.on_data do |ch3, data|
|
66
|
+
# Filter out the clear screen command
|
67
|
+
data = remove_ansi_escape_codes(data)
|
68
|
+
|
69
|
+
if !marker_found
|
70
|
+
data_buffer << data
|
71
|
+
marker_index = data_buffer.index(CMD_GARBAGE_MARKER)
|
72
|
+
if marker_index
|
73
|
+
marker_found = true
|
74
|
+
data_buffer.slice!(0, marker_index + CMD_GARBAGE_MARKER.size)
|
75
|
+
data.replace(data_buffer)
|
76
|
+
data_buffer = nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
if block_given? && marker_found
|
81
|
+
yield :stdout, data
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
ch2.on_extended_data do |ch3, type, data|
|
86
|
+
# Filter out the clear screen command
|
87
|
+
data = remove_ansi_escape_codes(data)
|
88
|
+
@logger.debug("stderr: #{data}")
|
89
|
+
if !stderr_marker_found
|
90
|
+
stderr_data_buffer << data
|
91
|
+
marker_index = stderr_data_buffer.index(CMD_GARBAGE_MARKER)
|
92
|
+
if marker_index
|
93
|
+
marker_found = true
|
94
|
+
stderr_data_buffer.slice!(0, marker_index + CMD_GARBAGE_MARKER.size)
|
95
|
+
data.replace(stderr_data_buffer.lstrip)
|
96
|
+
data_buffer = nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
if block_given? && marker_found
|
101
|
+
yield :stderr, data
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
ch2.on_request("exit-status") do |ch3, data|
|
106
|
+
exit_status = data.read_long
|
107
|
+
@logger.debug("Exit status: #{exit_status}")
|
108
|
+
|
109
|
+
# Close the channel, since after the exit status we're
|
110
|
+
# probably done. This fixes up issues with hanging.
|
111
|
+
ch.close
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
begin
|
118
|
+
keep_alive = nil
|
119
|
+
|
120
|
+
if @machine.config.ssh.keep_alive
|
121
|
+
# Begin sending keep-alive packets while we wait for the script
|
122
|
+
# to complete. This avoids connections closing on long-running
|
123
|
+
# scripts.
|
124
|
+
keep_alive = Thread.new do
|
125
|
+
loop do
|
126
|
+
sleep 5
|
127
|
+
@logger.debug("Sending SSH keep-alive...")
|
128
|
+
connection.send_global_request("keep-alive@openssh.com")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Wait for the channel to complete
|
134
|
+
begin
|
135
|
+
channel.wait
|
136
|
+
rescue Errno::ECONNRESET, IOError
|
137
|
+
@logger.info(
|
138
|
+
"SSH connection unexpected closed. Assuming reboot or something.")
|
139
|
+
exit_status = 0
|
140
|
+
pty = false
|
141
|
+
rescue Net::SSH::ChannelOpenFailed
|
142
|
+
raise Vagrant::Errors::SSHChannelOpenFail
|
143
|
+
rescue Net::SSH::Disconnect
|
144
|
+
raise Vagrant::Errors::SSHDisconnected
|
145
|
+
end
|
146
|
+
ensure
|
147
|
+
# Kill the keep-alive thread
|
148
|
+
keep_alive.kill if keep_alive
|
149
|
+
end
|
150
|
+
|
151
|
+
# Return the final exit status
|
152
|
+
return exit_status
|
153
|
+
end
|
154
|
+
|
155
|
+
def machine_config_ssh
|
156
|
+
@machine.config.winssh
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path("../../../kernel_v2/config/ssh", __FILE__)
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module CommunicatorWinSSH
|
5
|
+
class Config < VagrantPlugins::Kernel_V2::SSHConfig
|
6
|
+
|
7
|
+
def finalize!
|
8
|
+
@shell = "cmd" if @shell == UNSET_VALUE
|
9
|
+
@sudo_command = "%c" if @sudo_command == UNSET_VALUE
|
10
|
+
if @export_command_template == UNSET_VALUE
|
11
|
+
if @shell == "cmd"
|
12
|
+
@export_command_template = 'set %ENV_KEY%="%ENV_VALUE%"'
|
13
|
+
else
|
14
|
+
@export_command_template = '$env:%ENV_KEY%="%ENV_VALUE%"'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"WINSSH"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Remove configuration options from regular SSH that are
|
25
|
+
# not used within this communicator
|
26
|
+
undef :forward_x11
|
27
|
+
undef :pty
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|