vagrant-unbundled 2.2.7.0 → 2.2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.hashibot.hcl +2 -0
- data/CHANGELOG.md +228 -0
- data/Gemfile +1 -1
- data/README.md +9 -51
- data/RELEASE.md +1 -1
- data/bin/vagrant +50 -1
- data/contrib/README.md +1 -0
- data/contrib/sudoers/linux-suse +2 -2
- data/contrib/zsh/_vagrant +738 -0
- data/contrib/zsh/generate_zsh_completion.rb +165 -0
- data/lib/vagrant.rb +28 -5
- data/lib/vagrant/action.rb +7 -0
- data/lib/vagrant/action/builder.rb +184 -38
- data/lib/vagrant/action/builtin/box_add.rb +24 -8
- data/lib/vagrant/action/builtin/box_check_outdated.rb +2 -1
- data/lib/vagrant/action/builtin/cleanup_disks.rb +56 -0
- data/lib/vagrant/action/builtin/cloud_init_setup.rb +122 -0
- data/lib/vagrant/action/builtin/cloud_init_wait.rb +30 -0
- data/lib/vagrant/action/builtin/delayed.rb +26 -0
- data/lib/vagrant/action/builtin/disk.rb +14 -1
- data/lib/vagrant/action/builtin/handle_box.rb +3 -1
- data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +28 -9
- data/lib/vagrant/action/builtin/has_provisioner.rb +36 -0
- data/lib/vagrant/action/builtin/mixin_provisioners.rb +1 -0
- data/lib/vagrant/action/builtin/mixin_synced_folders.rb +20 -21
- data/lib/vagrant/action/builtin/set_hostname.rb +5 -1
- data/lib/vagrant/action/builtin/synced_folders.rb +16 -0
- data/lib/vagrant/action/builtin/trigger.rb +37 -0
- data/lib/vagrant/action/hook.rb +76 -23
- data/lib/vagrant/action/runner.rb +12 -27
- data/lib/vagrant/action/warden.rb +28 -31
- data/lib/vagrant/box.rb +11 -4
- data/lib/vagrant/box_collection.rb +1 -1
- data/lib/vagrant/bundler.rb +310 -61
- data/lib/vagrant/cli.rb +4 -2
- data/lib/vagrant/environment.rb +1 -0
- data/lib/vagrant/errors.rb +69 -1
- data/lib/vagrant/machine.rb +64 -11
- data/lib/vagrant/machine_index.rb +28 -1
- data/lib/vagrant/patches/net-ssh.rb +186 -0
- data/lib/vagrant/plugin/manager.rb +45 -16
- data/lib/vagrant/plugin/v2/command.rb +7 -2
- data/lib/vagrant/plugin/v2/components.rb +6 -0
- data/lib/vagrant/plugin/v2/manager.rb +67 -0
- data/lib/vagrant/plugin/v2/plugin.rb +13 -0
- data/lib/vagrant/plugin/v2/synced_folder.rb +50 -0
- data/lib/vagrant/plugin/v2/trigger.rb +64 -25
- data/lib/vagrant/shared_helpers.rb +36 -0
- data/lib/vagrant/ui.rb +43 -2
- data/lib/vagrant/util.rb +2 -0
- data/lib/vagrant/util/ansi_escape_code_remover.rb +1 -1
- data/lib/vagrant/util/caps.rb +48 -0
- data/lib/vagrant/util/credential_scrubber.rb +1 -1
- data/lib/vagrant/util/curl_helper.rb +12 -8
- data/lib/vagrant/util/directory.rb +19 -0
- data/lib/vagrant/util/downloader.rb +10 -5
- data/lib/vagrant/util/guest_hosts.rb +68 -0
- data/lib/vagrant/util/guest_inspection.rb +9 -1
- data/lib/vagrant/util/install_cli_autocomplete.rb +118 -0
- data/lib/vagrant/util/io.rb +7 -27
- data/lib/vagrant/util/ipv4_interfaces.rb +15 -0
- data/lib/vagrant/util/is_port_open.rb +8 -19
- data/lib/vagrant/util/map_command_options.rb +33 -0
- data/lib/vagrant/util/mime.rb +92 -0
- data/lib/vagrant/util/network_ip.rb +11 -1
- data/lib/vagrant/util/numeric.rb +28 -0
- data/lib/vagrant/util/platform.rb +10 -2
- data/lib/vagrant/util/powershell.rb +31 -15
- data/lib/vagrant/util/subprocess.rb +9 -1
- data/lib/vagrant/util/template_renderer.rb +2 -2
- data/lib/vagrant/util/uploader.rb +7 -4
- data/lib/vagrant/vagrantfile.rb +2 -2
- data/plugins/commands/autocomplete/command/install.rb +49 -0
- data/plugins/commands/autocomplete/command/root.rb +64 -0
- data/plugins/commands/autocomplete/plugin.rb +18 -0
- data/plugins/commands/cap/command.rb +5 -1
- data/plugins/commands/cloud/auth/login.rb +20 -23
- data/plugins/commands/cloud/auth/logout.rb +2 -10
- data/plugins/commands/cloud/auth/middleware/add_authentication.rb +60 -31
- data/plugins/commands/cloud/auth/middleware/add_downloader_authentication.rb +64 -0
- data/plugins/commands/cloud/auth/whoami.rb +18 -20
- data/plugins/commands/cloud/box/create.rb +33 -29
- data/plugins/commands/cloud/box/delete.rb +30 -24
- data/plugins/commands/cloud/box/show.rb +41 -31
- data/plugins/commands/cloud/box/update.rb +34 -26
- data/plugins/commands/cloud/client/client.rb +55 -79
- data/plugins/commands/cloud/list.rb +3 -4
- data/plugins/commands/cloud/locales/en.yml +15 -11
- data/plugins/commands/cloud/plugin.rb +10 -0
- data/plugins/commands/cloud/provider/create.rb +38 -28
- data/plugins/commands/cloud/provider/delete.rb +39 -29
- data/plugins/commands/cloud/provider/update.rb +37 -28
- data/plugins/commands/cloud/provider/upload.rb +53 -33
- data/plugins/commands/cloud/publish.rb +193 -106
- data/plugins/commands/cloud/search.rb +34 -21
- data/plugins/commands/cloud/util.rb +273 -161
- data/plugins/commands/cloud/version/create.rb +33 -28
- data/plugins/commands/cloud/version/delete.rb +35 -28
- data/plugins/commands/cloud/version/release.rb +35 -29
- data/plugins/commands/cloud/version/revoke.rb +36 -29
- data/plugins/commands/cloud/version/update.rb +29 -25
- data/plugins/commands/destroy/command.rb +7 -7
- data/plugins/commands/login/plugin.rb +0 -13
- data/plugins/commands/ssh_config/command.rb +1 -1
- data/plugins/communicators/ssh/communicator.rb +25 -24
- data/plugins/communicators/winrm/config.rb +1 -1
- data/plugins/communicators/winrm/helper.rb +1 -1
- data/plugins/communicators/winrm/shell.rb +1 -1
- data/plugins/communicators/winssh/communicator.rb +126 -38
- data/plugins/communicators/winssh/config.rb +3 -7
- data/plugins/guests/alpine/cap/change_host_name.rb +10 -11
- data/plugins/guests/alpine/cap/configure_networks.rb +1 -1
- data/plugins/guests/alt/cap/change_host_name.rb +40 -53
- data/plugins/guests/arch/cap/change_host_name.rb +5 -14
- data/plugins/guests/arch/cap/configure_networks.rb +27 -10
- data/plugins/guests/arch/cap/smb.rb +1 -1
- data/plugins/guests/atomic/cap/change_host_name.rb +5 -14
- data/plugins/guests/centos/cap/flavor.rb +24 -0
- data/plugins/guests/centos/guest.rb +9 -0
- data/plugins/guests/centos/plugin.rb +20 -0
- data/plugins/guests/darwin/cap/change_host_name.rb +10 -6
- data/plugins/guests/darwin/cap/darwin_version.rb +40 -0
- data/plugins/guests/darwin/cap/mount_smb_shared_folder.rb +1 -1
- data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +33 -10
- data/plugins/guests/darwin/plugin.rb +15 -0
- data/plugins/guests/debian/cap/change_host_name.rb +12 -11
- data/plugins/guests/debian/cap/configure_networks.rb +14 -6
- data/plugins/guests/esxi/cap/public_key.rb +3 -1
- data/plugins/guests/fedora/guest.rb +4 -4
- data/plugins/guests/freebsd/cap/change_host_name.rb +10 -6
- data/plugins/guests/gentoo/cap/change_host_name.rb +14 -22
- data/plugins/guests/haiku/cap/rsync.rb +19 -0
- data/plugins/guests/haiku/plugin.rb +15 -0
- data/plugins/guests/linux/cap/change_host_name.rb +46 -0
- data/plugins/guests/linux/cap/halt.rb +9 -1
- data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +25 -34
- data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +10 -11
- data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +74 -0
- data/plugins/guests/linux/cap/reboot.rb +36 -7
- data/plugins/guests/linux/plugin.rb +10 -0
- data/plugins/guests/omnios/cap/change_host_name.rb +10 -16
- data/plugins/guests/openbsd/cap/change_host_name.rb +10 -6
- data/plugins/guests/openwrt/cap/change_host_name.rb +19 -0
- data/plugins/guests/openwrt/cap/halt.rb +16 -0
- data/plugins/guests/openwrt/cap/insert_public_key.rb +20 -0
- data/plugins/guests/openwrt/cap/remove_public_key.rb +22 -0
- data/plugins/guests/openwrt/cap/rsync.rb +35 -0
- data/plugins/guests/openwrt/guest.rb +23 -0
- data/plugins/guests/openwrt/plugin.rb +61 -0
- data/plugins/guests/photon/cap/change_host_name.rb +9 -15
- data/plugins/guests/pld/cap/change_host_name.rb +11 -17
- data/plugins/guests/redhat/cap/change_host_name.rb +14 -5
- data/plugins/guests/redhat/cap/flavor.rb +3 -1
- data/plugins/guests/redhat/cap/smb.rb +20 -0
- data/plugins/guests/redhat/plugin.rb +5 -0
- data/plugins/guests/slackware/cap/change_host_name.rb +11 -17
- data/plugins/guests/solaris11/plugin.rb +5 -0
- data/plugins/guests/suse/cap/change_host_name.rb +31 -9
- data/plugins/guests/windows/cap/public_key.rb +3 -3
- data/plugins/guests/windows/cap/reboot.rb +10 -5
- data/plugins/hosts/darwin/cap/fs_iso.rb +49 -0
- data/plugins/hosts/darwin/plugin.rb +10 -0
- data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
- data/plugins/hosts/linux/cap/nfs.rb +1 -0
- data/plugins/hosts/linux/cap/rdp.rb +1 -1
- data/plugins/hosts/linux/plugin.rb +10 -0
- data/plugins/hosts/windows/cap/fs_iso.rb +48 -0
- data/plugins/hosts/windows/cap/rdp.rb +1 -1
- data/plugins/hosts/windows/plugin.rb +15 -0
- data/plugins/kernel_v2/config/cloud_init.rb +133 -0
- data/plugins/kernel_v2/config/disk.rb +67 -14
- data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
- data/plugins/kernel_v2/config/vm.rb +155 -21
- data/plugins/kernel_v2/config/vm_provisioner.rb +13 -2
- data/plugins/kernel_v2/config/vm_trigger.rb +6 -5
- data/plugins/providers/docker/action.rb +8 -17
- data/plugins/providers/docker/action/forwarded_ports.rb +2 -0
- data/plugins/providers/docker/action/prepare_forwarded_port_collision_params.rb +61 -0
- data/plugins/providers/docker/cap/has_communicator.rb +11 -0
- data/plugins/providers/docker/communicator.rb +1 -1
- data/plugins/providers/docker/driver.rb +58 -7
- data/plugins/providers/docker/plugin.rb +5 -0
- data/plugins/providers/hyperv/action.rb +3 -1
- data/plugins/providers/hyperv/action/configure.rb +8 -0
- data/plugins/providers/hyperv/action/export.rb +4 -2
- data/plugins/providers/hyperv/cap/cleanup_disks.rb +54 -0
- data/plugins/providers/hyperv/cap/configure_disks.rb +200 -0
- data/plugins/providers/hyperv/cap/validate_disk_ext.rb +34 -0
- data/plugins/providers/hyperv/config.rb +5 -0
- data/plugins/providers/hyperv/driver.rb +90 -9
- data/plugins/providers/hyperv/plugin.rb +25 -0
- data/plugins/providers/hyperv/scripts/attach_disk_drive.ps1 +28 -0
- data/plugins/providers/hyperv/scripts/dismount_vhd.ps1 +13 -0
- data/plugins/providers/hyperv/scripts/get_vhd.ps1 +16 -0
- data/plugins/providers/hyperv/scripts/get_vm_status.ps1 +1 -1
- data/plugins/providers/hyperv/scripts/list_hdds.ps1 +17 -0
- data/plugins/providers/hyperv/scripts/new_vhd.ps1 +31 -0
- data/plugins/providers/hyperv/scripts/remove_disk_drive.ps1 +25 -0
- data/plugins/providers/hyperv/scripts/resize_disk_drive.ps1 +18 -0
- data/plugins/providers/hyperv/scripts/set_enhanced_session_transport_type.ps1 +24 -0
- data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +3 -3
- data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +14 -6
- data/plugins/providers/virtualbox/action.rb +13 -1
- data/plugins/providers/virtualbox/action/export.rb +4 -2
- data/plugins/providers/virtualbox/action/forward_ports.rb +2 -2
- data/plugins/providers/virtualbox/action/import.rb +8 -4
- data/plugins/providers/virtualbox/action/network.rb +12 -5
- data/plugins/providers/virtualbox/action/prepare_clone_snapshot.rb +4 -2
- data/plugins/providers/virtualbox/action/snapshot_delete.rb +4 -2
- data/plugins/providers/virtualbox/action/snapshot_restore.rb +4 -2
- data/plugins/providers/virtualbox/cap/cleanup_disks.rb +85 -0
- data/plugins/providers/virtualbox/cap/configure_disks.rb +440 -0
- data/plugins/providers/virtualbox/cap/mount_options.rb +40 -0
- data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +34 -0
- data/plugins/providers/virtualbox/driver/base.rb +15 -0
- data/plugins/providers/virtualbox/driver/meta.rb +16 -2
- data/plugins/providers/virtualbox/driver/version_5_0.rb +217 -2
- data/plugins/providers/virtualbox/driver/version_6_1.rb +23 -0
- data/plugins/providers/virtualbox/model/storage_controller.rb +135 -0
- data/plugins/providers/virtualbox/model/storage_controller_array.rb +98 -0
- data/plugins/providers/virtualbox/plugin.rb +42 -0
- data/plugins/providers/virtualbox/provider.rb +2 -1
- data/plugins/providers/virtualbox/synced_folder.rb +1 -0
- data/plugins/provisioners/ansible/cap/guest/alpine/ansible_install.rb +44 -0
- data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
- data/plugins/provisioners/ansible/plugin.rb +5 -0
- data/plugins/provisioners/ansible/provisioner/base.rb +1 -1
- data/plugins/provisioners/container/client.rb +203 -0
- data/plugins/provisioners/container/config.rb +83 -0
- data/plugins/provisioners/container/installer.rb +13 -0
- data/plugins/provisioners/container/plugin.rb +23 -0
- data/plugins/provisioners/container/provisioner.rb +28 -0
- data/plugins/provisioners/docker/cap/{redhat → centos}/docker_install.rb +10 -7
- data/plugins/provisioners/docker/cap/centos/docker_start_service.rb +24 -0
- data/plugins/provisioners/docker/client.rb +4 -175
- data/plugins/provisioners/docker/config.rb +2 -72
- data/plugins/provisioners/docker/installer.rb +3 -5
- data/plugins/provisioners/docker/plugin.rb +6 -6
- data/plugins/provisioners/docker/provisioner.rb +4 -10
- data/plugins/provisioners/podman/cap/centos/podman_install.rb +35 -0
- data/plugins/provisioners/podman/cap/linux/podman_installed.rb +13 -0
- data/plugins/provisioners/podman/cap/redhat/podman_install.rb +26 -0
- data/plugins/provisioners/podman/client.rb +12 -0
- data/plugins/provisioners/podman/config.rb +28 -0
- data/plugins/provisioners/podman/installer.rb +33 -0
- data/plugins/provisioners/podman/plugin.rb +38 -0
- data/plugins/provisioners/podman/provisioner.rb +52 -0
- data/plugins/provisioners/salt/bootstrap-salt.sh +7 -4
- data/plugins/provisioners/salt/provisioner.rb +4 -0
- data/plugins/provisioners/shell/config.rb +1 -6
- data/plugins/provisioners/shell/provisioner.rb +61 -26
- data/plugins/synced_folders/nfs/synced_folder.rb +3 -1
- data/plugins/synced_folders/smb/cap/default_fstab_modification.rb +11 -0
- data/plugins/synced_folders/smb/cap/mount_options.rb +56 -0
- data/plugins/synced_folders/smb/plugin.rb +20 -0
- data/plugins/synced_folders/smb/synced_folder.rb +2 -2
- data/plugins/synced_folders/unix_mount_helpers.rb +14 -0
- data/scripts/website_push_www.sh +1 -1
- data/templates/commands/init/Vagrantfile.min.erb +3 -0
- data/templates/guests/arch/{network_dhcp.erb → default_network/network_dhcp.erb} +0 -0
- data/templates/guests/arch/{network_static.erb → default_network/network_static.erb} +0 -0
- data/templates/guests/arch/{network_static6.erb → default_network/network_static6.erb} +0 -0
- data/templates/guests/arch/systemd_networkd/network_dhcp.erb +6 -0
- data/templates/guests/arch/systemd_networkd/network_static.erb +9 -0
- data/templates/guests/arch/systemd_networkd/network_static6.erb +9 -0
- data/templates/guests/linux/etc_fstab.erb +6 -0
- data/templates/guests/nixos/network.erb +5 -6
- data/templates/locales/en.yml +221 -5
- data/templates/locales/providers_docker.yml +4 -0
- data/templates/nfs/exports_darwin.erb +1 -1
- data/vagrant.gemspec +14 -20
- data/version.txt +1 -1
- metadata +5092 -8978
- data/lib/vagrant/action/builtin/after_trigger.rb +0 -31
- data/lib/vagrant/action/builtin/before_trigger.rb +0 -28
- data/plugins/commands/login/client.rb +0 -253
- data/plugins/commands/login/command.rb +0 -137
- data/plugins/commands/login/errors.rb +0 -24
- data/plugins/commands/login/locales/en.yml +0 -49
- data/plugins/provisioners/docker/cap/redhat/docker_start_service.rb +0 -16
- data/scripts/website_push_docs.sh +0 -40
@@ -8,6 +8,7 @@ module VagrantPlugins
|
|
8
8
|
def execute
|
9
9
|
options = {}
|
10
10
|
options[:force] = false
|
11
|
+
options[:force_halt] = true
|
11
12
|
|
12
13
|
opts = OptionParser.new do |o|
|
13
14
|
o.banner = "Usage: vagrant destroy [options] [name|id]"
|
@@ -23,6 +24,10 @@ module VagrantPlugins
|
|
23
24
|
"Enable or disable parallelism if provider supports it (automatically enables force)") do |p|
|
24
25
|
options[:parallel] = p
|
25
26
|
end
|
27
|
+
|
28
|
+
o.on("-g", "--graceful", "Gracefully poweroff of VM") do |f|
|
29
|
+
options[:force_halt] = false
|
30
|
+
end
|
26
31
|
end
|
27
32
|
|
28
33
|
# Parse the options
|
@@ -46,13 +51,12 @@ module VagrantPlugins
|
|
46
51
|
# gather states to be checked after destroy
|
47
52
|
init_states[vm.name] = vm.state.id
|
48
53
|
machines << vm
|
49
|
-
|
50
|
-
batch.action(vm, :destroy, force_confirm_destroy: options[:force])
|
54
|
+
batch.action(vm, :destroy, force_confirm_destroy: options[:force], force_halt: options[:force_halt])
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
58
|
machines.each do |m|
|
55
|
-
if m.state.id == init_states[m.name]
|
59
|
+
if init_states[m.name] != :not_created && m.state.id == init_states[m.name]
|
56
60
|
declined += 1
|
57
61
|
end
|
58
62
|
end
|
@@ -60,10 +64,6 @@ module VagrantPlugins
|
|
60
64
|
# Nothing was declined
|
61
65
|
return 0 if declined == 0
|
62
66
|
|
63
|
-
# Everything was declined, and all states are `not_created`
|
64
|
-
return 0 if declined == machines.length &&
|
65
|
-
declined == init_states.values.count(:not_created)
|
66
|
-
|
67
67
|
# Everything was declined, state was not changed
|
68
68
|
return 1 if declined == machines.length
|
69
69
|
|
@@ -2,9 +2,6 @@ require "vagrant"
|
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module LoginCommand
|
5
|
-
autoload :Client, File.expand_path("../client", __FILE__)
|
6
|
-
autoload :Errors, File.expand_path("../errors", __FILE__)
|
7
|
-
|
8
5
|
class Plugin < Vagrant.plugin("2")
|
9
6
|
name "vagrant-login"
|
10
7
|
description <<-DESC
|
@@ -13,18 +10,8 @@ module VagrantPlugins
|
|
13
10
|
|
14
11
|
command(:login) do
|
15
12
|
require File.expand_path("../../cloud/auth/login", __FILE__)
|
16
|
-
init!
|
17
13
|
VagrantPlugins::CloudCommand::AuthCommand::Command::Login
|
18
14
|
end
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
22
|
-
def self.init!
|
23
|
-
return if defined?(@_init)
|
24
|
-
I18n.load_path << File.expand_path("../../cloud/locales/en.yml", __FILE__)
|
25
|
-
I18n.reload!
|
26
|
-
@_init = true
|
27
|
-
end
|
28
15
|
end
|
29
16
|
end
|
30
17
|
end
|
@@ -55,7 +55,7 @@ module VagrantPlugins
|
|
55
55
|
proxy_command: ssh_info[:proxy_command],
|
56
56
|
ssh_command: ssh_info[:ssh_command],
|
57
57
|
forward_env: ssh_info[:forward_env],
|
58
|
-
config: ssh_info[:config]
|
58
|
+
config: ssh_info[:config]
|
59
59
|
}
|
60
60
|
|
61
61
|
# Render the template and output directly to STDOUT
|
@@ -20,6 +20,7 @@ module VagrantPlugins
|
|
20
20
|
module CommunicatorSSH
|
21
21
|
# This class provides communication with the VM via SSH.
|
22
22
|
class Communicator < Vagrant.plugin("2", :communicator)
|
23
|
+
READY_COMMAND=""
|
23
24
|
# Marker for start of PTY enabled command output
|
24
25
|
PTY_DELIM_START = "bccbb768c119429488cfd109aacea6b5-pty"
|
25
26
|
# Marker for end of PTY enabled command output
|
@@ -65,7 +66,7 @@ module VagrantPlugins
|
|
65
66
|
while true
|
66
67
|
ssh_info = @machine.ssh_info
|
67
68
|
break if ssh_info
|
68
|
-
sleep
|
69
|
+
sleep(0.5)
|
69
70
|
end
|
70
71
|
|
71
72
|
# Got it! Let the user know what we're connecting to.
|
@@ -155,7 +156,7 @@ module VagrantPlugins
|
|
155
156
|
end
|
156
157
|
|
157
158
|
# Verify the shell is valid
|
158
|
-
if execute(
|
159
|
+
if execute(self.class.const_get(:READY_COMMAND), error_check: false) != 0
|
159
160
|
raise Vagrant::Errors::SSHInvalidShell
|
160
161
|
end
|
161
162
|
|
@@ -168,6 +169,7 @@ module VagrantPlugins
|
|
168
169
|
|
169
170
|
# If we used a password, then insert the insecure key
|
170
171
|
ssh_info = @machine.ssh_info
|
172
|
+
return if ssh_info.nil?
|
171
173
|
insert = ssh_info[:password] && ssh_info[:private_key_path].empty?
|
172
174
|
ssh_info[:private_key_path].each do |pk|
|
173
175
|
if insecure_key?(pk)
|
@@ -227,6 +229,7 @@ module VagrantPlugins
|
|
227
229
|
command: command,
|
228
230
|
shell: nil,
|
229
231
|
sudo: false,
|
232
|
+
force_raw: false
|
230
233
|
}.merge(opts || {})
|
231
234
|
|
232
235
|
opts[:good_exit] = Array(opts[:good_exit])
|
@@ -238,6 +241,7 @@ module VagrantPlugins
|
|
238
241
|
shell_opts = {
|
239
242
|
sudo: opts[:sudo],
|
240
243
|
shell: opts[:shell],
|
244
|
+
force_raw: opts[:force_raw]
|
241
245
|
}
|
242
246
|
|
243
247
|
shell_execute(connection, command, **shell_opts) do |type, data|
|
@@ -303,10 +307,11 @@ module VagrantPlugins
|
|
303
307
|
scp_connect do |scp|
|
304
308
|
uploader = lambda do |path, remote_dest=nil|
|
305
309
|
if File.directory?(path)
|
310
|
+
dest = File.join(to, path.sub(/^#{Regexp.escape(from)}/, ""))
|
311
|
+
create_remote_directory(dest)
|
306
312
|
Dir.new(path).each do |entry|
|
307
313
|
next if entry == "." || entry == ".."
|
308
314
|
full_path = File.join(path, entry)
|
309
|
-
dest = File.join(to, path.sub(/^#{Regexp.escape(from)}/, ""))
|
310
315
|
create_remote_directory(dest)
|
311
316
|
uploader.call(full_path, dest)
|
312
317
|
end
|
@@ -354,6 +359,11 @@ module VagrantPlugins
|
|
354
359
|
wait_for_ready(5)
|
355
360
|
end
|
356
361
|
|
362
|
+
def generate_environment_export(env_key, env_value)
|
363
|
+
template = machine_config_ssh.export_command_template
|
364
|
+
template.sub("%ENV_KEY%", env_key).sub("%ENV_VALUE%", env_value) + "\n"
|
365
|
+
end
|
366
|
+
|
357
367
|
protected
|
358
368
|
|
359
369
|
# Opens an SSH connection and yields it to a block.
|
@@ -398,14 +408,6 @@ module VagrantPlugins
|
|
398
408
|
auth_methods << "publickey" if ssh_info[:private_key_path]
|
399
409
|
auth_methods << "password" if ssh_info[:password]
|
400
410
|
|
401
|
-
# yanked directly from ruby's Net::SSH, but with `none` last
|
402
|
-
# TODO: Remove this once Vagrant has updated its dependency on Net:SSH
|
403
|
-
# to be > 4.1.0, which should include this fix.
|
404
|
-
cipher_array = Net::SSH::Transport::Algorithms::ALGORITHMS[:encryption].dup
|
405
|
-
if cipher_array.delete("none")
|
406
|
-
cipher_array.push("none")
|
407
|
-
end
|
408
|
-
|
409
411
|
# Build the options we'll use to initiate the connection via Net::SSH
|
410
412
|
common_connect_opts = {
|
411
413
|
auth_methods: auth_methods,
|
@@ -416,10 +418,9 @@ module VagrantPlugins
|
|
416
418
|
verify_host_key: ssh_info[:verify_host_key],
|
417
419
|
password: ssh_info[:password],
|
418
420
|
port: ssh_info[:port],
|
419
|
-
timeout:
|
421
|
+
timeout: ssh_info[:connect_timeout],
|
420
422
|
user_known_hosts_file: [],
|
421
|
-
verbose: :debug
|
422
|
-
encryption: cipher_array,
|
423
|
+
verbose: :debug
|
423
424
|
}
|
424
425
|
|
425
426
|
# Connect to SSH, giving it a few tries
|
@@ -628,7 +629,7 @@ module VagrantPlugins
|
|
628
629
|
end
|
629
630
|
|
630
631
|
# Set the terminal
|
631
|
-
ch2.send_data
|
632
|
+
ch2.send_data(generate_environment_export("TERM", "vt100"))
|
632
633
|
|
633
634
|
# Set SSH_AUTH_SOCK if we are in sudo and forwarding agent.
|
634
635
|
# This is to work around often misconfigured boxes where
|
@@ -651,7 +652,7 @@ module VagrantPlugins
|
|
651
652
|
@logger.warn("No SSH_AUTH_SOCK found despite forward_agent being set.")
|
652
653
|
else
|
653
654
|
@logger.info("Setting SSH_AUTH_SOCK remotely: #{auth_socket}")
|
654
|
-
ch2.send_data
|
655
|
+
ch2.send_data(generate_environment_export("SSH_AUTH_SOCK", auth_socket))
|
655
656
|
end
|
656
657
|
end
|
657
658
|
|
@@ -669,11 +670,11 @@ module VagrantPlugins
|
|
669
670
|
data += "printf #{PTY_DELIM_END}\n"
|
670
671
|
data += "exit $exitcode\n"
|
671
672
|
data = data.force_encoding('ASCII-8BIT')
|
672
|
-
ch2.send_data
|
673
|
+
ch2.send_data(data)
|
673
674
|
else
|
674
|
-
ch2.send_data
|
675
|
+
ch2.send_data("printf '#{CMD_GARBAGE_MARKER}'\n(>&2 printf '#{CMD_GARBAGE_MARKER}')\n#{command}\n".force_encoding('ASCII-8BIT'))
|
675
676
|
# Remember to exit or this channel will hang open
|
676
|
-
ch2.send_data
|
677
|
+
ch2.send_data("exit\n")
|
677
678
|
end
|
678
679
|
|
679
680
|
# Send eof to let server know we're done
|
@@ -729,6 +730,11 @@ module VagrantPlugins
|
|
729
730
|
yield :stdout, data if block_given?
|
730
731
|
end
|
731
732
|
|
733
|
+
if !exit_status
|
734
|
+
@logger.debug("Exit status: #{exit_status.inspect}")
|
735
|
+
raise Vagrant::Errors::SSHNoExitStatus
|
736
|
+
end
|
737
|
+
|
732
738
|
# Return the final exit status
|
733
739
|
return exit_status
|
734
740
|
end
|
@@ -759,11 +765,6 @@ module VagrantPlugins
|
|
759
765
|
return File.read(path).chomp == source_path.read.chomp
|
760
766
|
end
|
761
767
|
|
762
|
-
def generate_environment_export(env_key, env_value)
|
763
|
-
template = machine_config_ssh.export_command_template
|
764
|
-
template.sub("%ENV_KEY%", env_key).sub("%ENV_VALUE%", env_value) + "\n"
|
765
|
-
end
|
766
|
-
|
767
768
|
def create_remote_directory(dir)
|
768
769
|
execute("mkdir -p \"#{dir}\"")
|
769
770
|
end
|
@@ -56,7 +56,7 @@ module VagrantPlugins
|
|
56
56
|
errors << "winrm.port cannot be nil." if @port.nil?
|
57
57
|
errors << "winrm.guest_port cannot be nil." if @guest_port.nil?
|
58
58
|
errors << "winrm.max_tries cannot be nil." if @max_tries.nil?
|
59
|
-
errors << "winrm.retry_delay cannot be nil." if @
|
59
|
+
errors << "winrm.retry_delay cannot be nil." if @retry_delay.nil?
|
60
60
|
errors << "winrm.timeout cannot be nil." if @timeout.nil?
|
61
61
|
errors << "winrm.execution_time_limit cannot be nil." if @execution_time_limit.nil?
|
62
62
|
unless @ssl_peer_verification == true || @ssl_peer_verification == false
|
@@ -58,7 +58,7 @@ module VagrantPlugins
|
|
58
58
|
# ports.
|
59
59
|
port = nil
|
60
60
|
if machine.provider.capability?(:forwarded_ports)
|
61
|
-
machine.provider.capability(:forwarded_ports).each do |host, guest|
|
61
|
+
Array(machine.provider.capability(:forwarded_ports)).each do |host, guest|
|
62
62
|
if guest == machine.config.winrm.guest_port
|
63
63
|
port = host
|
64
64
|
break
|
@@ -19,7 +19,7 @@ module VagrantPlugins
|
|
19
19
|
|
20
20
|
# Exit code generated when user is invalid. Can occur
|
21
21
|
# after a hostname update
|
22
|
-
INVALID_USERID_EXITCODE = -
|
22
|
+
INVALID_USERID_EXITCODE = -2147024809
|
23
23
|
|
24
24
|
# These are the exceptions that we retry because they represent
|
25
25
|
# errors that are generally fixed from a retry and don't
|
@@ -1,27 +1,39 @@
|
|
1
1
|
require File.expand_path("../../ssh/communicator", __FILE__)
|
2
2
|
|
3
|
+
require 'net/sftp'
|
4
|
+
|
3
5
|
module VagrantPlugins
|
4
6
|
module CommunicatorWinSSH
|
5
7
|
# This class provides communication with a Windows VM running
|
6
8
|
# the Windows native port of OpenSSH
|
7
9
|
class Communicator < VagrantPlugins::CommunicatorSSH::Communicator
|
10
|
+
# Command to run when checking if connection is ready and working
|
11
|
+
READY_COMMAND="dir"
|
8
12
|
|
9
13
|
def initialize(machine)
|
10
14
|
super
|
11
15
|
@logger = Log4r::Logger.new("vagrant::communication::winssh")
|
12
16
|
end
|
13
17
|
|
18
|
+
# Wrap the shell if required. By default we are using powershell
|
19
|
+
# which requires no modification. If cmd is defined as shell, add
|
20
|
+
# prefix to start within cmd.exe
|
21
|
+
def shell_cmd(opts)
|
22
|
+
case opts[:shell].to_s
|
23
|
+
when "cmd"
|
24
|
+
"cmd.exe /c '#{opts[:command]}'"
|
25
|
+
else
|
26
|
+
opts[:command]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
14
30
|
# Executes the command on an SSH connection within a login shell.
|
15
31
|
def shell_execute(connection, command, **opts)
|
16
|
-
opts
|
17
|
-
sudo: false,
|
18
|
-
shell: nil
|
19
|
-
}.merge(opts)
|
32
|
+
opts[:shell] ||= machine_config_ssh.shell
|
20
33
|
|
21
|
-
|
22
|
-
shell = (opts[:shell] || machine_config_ssh.shell).to_s
|
34
|
+
command = shell_cmd(opts.merge(command: command))
|
23
35
|
|
24
|
-
@logger.info("Execute: #{command}
|
36
|
+
@logger.info("Execute: #{command} - opts: #{opts}")
|
25
37
|
exit_status = nil
|
26
38
|
|
27
39
|
# Open the channel so we can execute or command
|
@@ -31,36 +43,10 @@ module VagrantPlugins
|
|
31
43
|
stderr_marker_found = false
|
32
44
|
stderr_data_buffer = ''
|
33
45
|
|
34
|
-
|
35
|
-
|
36
|
-
remote_name = "#{machine_config_ssh.upload_directory}\\#{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}")
|
46
|
+
@logger.debug("Base SSH exec command: #{command}")
|
47
|
+
command = "$ProgressPreference = 'SilentlyContinue';Write-Output #{CMD_GARBAGE_MARKER};[Console]::Error.WriteLine('#{CMD_GARBAGE_MARKER}');#{command}"
|
62
48
|
|
63
|
-
ch.exec(
|
49
|
+
ch.exec(command) do |ch2, _|
|
64
50
|
# Setup the channel callbacks so we can get data and exit status
|
65
51
|
ch2.on_data do |ch3, data|
|
66
52
|
# Filter out the clear screen command
|
@@ -90,14 +76,14 @@ SCRIPT
|
|
90
76
|
stderr_data_buffer << data
|
91
77
|
marker_index = stderr_data_buffer.index(CMD_GARBAGE_MARKER)
|
92
78
|
if marker_index
|
93
|
-
|
79
|
+
stderr_marker_found = true
|
94
80
|
stderr_data_buffer.slice!(0, marker_index + CMD_GARBAGE_MARKER.size)
|
95
81
|
data.replace(stderr_data_buffer.lstrip)
|
96
82
|
data_buffer = nil
|
97
83
|
end
|
98
84
|
end
|
99
85
|
|
100
|
-
if block_given? &&
|
86
|
+
if block_given? && stderr_marker_found && !data.empty?
|
101
87
|
yield :stderr, data
|
102
88
|
end
|
103
89
|
end
|
@@ -156,6 +142,108 @@ SCRIPT
|
|
156
142
|
@machine.config.winssh
|
157
143
|
end
|
158
144
|
|
145
|
+
def download(from, to=nil)
|
146
|
+
@logger.debug("Downloading: #{from} to #{to}")
|
147
|
+
|
148
|
+
sftp_connect do |sftp|
|
149
|
+
sftp.download!(from, to)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Note: I could not get Net::SFTP to throw a permissions denied error,
|
154
|
+
# even when uploading to a directory where I did not have write
|
155
|
+
# privileges. I believe this is because Windows SSH sessions are started
|
156
|
+
# in an elevated process.
|
157
|
+
def upload(from, to)
|
158
|
+
to = Vagrant::Util::Platform.unix_windows_path(to)
|
159
|
+
@logger.debug("Uploading: #{from} to #{to}")
|
160
|
+
|
161
|
+
if File.directory?(from)
|
162
|
+
if from.end_with?(".")
|
163
|
+
@logger.debug("Uploading directory contents of: #{from}")
|
164
|
+
from = from.sub(/\.$/, "")
|
165
|
+
else
|
166
|
+
@logger.debug("Uploading full directory container of: #{from}")
|
167
|
+
to = File.join(to, File.basename(File.expand_path(from)))
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
sftp_connect do |sftp|
|
172
|
+
uploader = lambda do |path, remote_dest=nil|
|
173
|
+
if File.directory?(path)
|
174
|
+
Dir.new(path).each do |entry|
|
175
|
+
next if entry == "." || entry == ".."
|
176
|
+
full_path = File.join(path, entry)
|
177
|
+
dest = File.join(to, path.sub(/^#{Regexp.escape(from)}/, ""))
|
178
|
+
sftp.mkdir(dest)
|
179
|
+
uploader.call(full_path, dest)
|
180
|
+
end
|
181
|
+
else
|
182
|
+
if remote_dest
|
183
|
+
dest = File.join(remote_dest, File.basename(path))
|
184
|
+
else
|
185
|
+
dest = to
|
186
|
+
if to.end_with?(File::SEPARATOR)
|
187
|
+
dest = File.join(to, File.basename(path))
|
188
|
+
end
|
189
|
+
end
|
190
|
+
@logger.debug("Ensuring remote directory exists for destination upload")
|
191
|
+
sftp.mkdir(File.dirname(dest))
|
192
|
+
@logger.debug("Uploading file #{path} to remote #{dest}")
|
193
|
+
upload_file = File.open(path, "rb")
|
194
|
+
begin
|
195
|
+
sftp.upload!(upload_file, dest)
|
196
|
+
ensure
|
197
|
+
upload_file.close
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
uploader.call(from)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Opens an SFTP connection and yields it so that you can download and
|
206
|
+
# upload files. SFTP works more reliably than SCP on Windows due to
|
207
|
+
# issues with shell quoting and escaping.
|
208
|
+
def sftp_connect
|
209
|
+
# Connect to SFTP and yield the SFTP object
|
210
|
+
connect do |connection|
|
211
|
+
return yield connection.sftp
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
protected
|
216
|
+
|
217
|
+
# The WinSSH communicator connection provides isolated modification
|
218
|
+
# to the generated connection instances. This modification forces
|
219
|
+
# all provided commands to run within powershell
|
220
|
+
def connect(**opts)
|
221
|
+
connection = nil
|
222
|
+
super { |c| connection = c }
|
223
|
+
|
224
|
+
if !connection.instance_variable_get(:@winssh_patched)
|
225
|
+
open_chan = connection.method(:open_channel)
|
226
|
+
connection.define_singleton_method(:open_channel) do |*args, &chan_block|
|
227
|
+
open_chan.call(*args) do |ch|
|
228
|
+
exec = ch.method(:exec)
|
229
|
+
ch.define_singleton_method(:exec) do |command, &block|
|
230
|
+
command = Base64.strict_encode64(command.encode("UTF-16LE", "UTF-8"))
|
231
|
+
command = "powershell -NoLogo -NonInteractive -ExecutionPolicy Bypass " \
|
232
|
+
"-NoProfile -EncodedCommand #{command}"
|
233
|
+
exec.call(command, &block)
|
234
|
+
end
|
235
|
+
chan_block.call(ch)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
connection.instance_variable_set(:@winssh_patched, true)
|
239
|
+
end
|
240
|
+
|
241
|
+
if block_given?
|
242
|
+
yield connection
|
243
|
+
else
|
244
|
+
connection
|
245
|
+
end
|
246
|
+
end
|
159
247
|
end
|
160
248
|
end
|
161
249
|
end
|