vagrant-unbundled 2.2.6.2 → 2.2.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hashibot.hcl +14 -0
- data/CHANGELOG.md +213 -2
- data/Gemfile +1 -1
- data/README.md +9 -51
- data/RELEASE.md +1 -1
- data/bin/vagrant +23 -0
- data/contrib/README.md +1 -0
- data/contrib/bash/completion.sh +13 -1
- 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 +25 -4
- data/lib/vagrant/action.rb +8 -0
- data/lib/vagrant/action/builder.rb +184 -38
- data/lib/vagrant/action/builtin/box_add.rb +20 -8
- data/lib/vagrant/action/builtin/box_check_outdated.rb +12 -15
- 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 +52 -0
- 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 +20 -1
- 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/ssh_run.rb +21 -3
- 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 -22
- data/lib/vagrant/box.rb +11 -4
- data/lib/vagrant/box_collection.rb +1 -1
- data/lib/vagrant/box_metadata.rb +17 -3
- data/lib/vagrant/bundler.rb +298 -59
- data/lib/vagrant/cli.rb +4 -2
- data/lib/vagrant/errors.rb +61 -1
- data/lib/vagrant/machine.rb +64 -11
- data/lib/vagrant/machine_index.rb +28 -1
- data/lib/vagrant/plugin/manager.rb +25 -14
- 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 +51 -5
- data/lib/vagrant/util.rb +1 -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 +8 -5
- data/lib/vagrant/util/directory.rb +19 -0
- data/lib/vagrant/util/downloader.rb +10 -5
- data/lib/vagrant/util/file_checksum.rb +6 -2
- 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 -20
- 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 +69 -0
- data/lib/vagrant/util/platform.rb +10 -2
- data/lib/vagrant/util/powershell.rb +1 -1
- 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 +1 -1
- 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/box/command/outdated.rb +14 -2
- 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_downloader_authentication.rb +57 -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 +50 -81
- data/plugins/commands/cloud/list.rb +3 -4
- data/plugins/commands/cloud/locales/en.yml +10 -10
- 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 +44 -34
- data/plugins/commands/cloud/publish.rb +185 -108
- data/plugins/commands/cloud/search.rb +34 -21
- data/plugins/commands/cloud/util.rb +266 -162
- 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 +6 -2
- data/plugins/commands/login/plugin.rb +0 -13
- data/plugins/commands/snapshot/command/save.rb +13 -8
- 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/rsync.rb +1 -1
- data/plugins/guests/alpine/plugin.rb +16 -0
- 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 +109 -13
- 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/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 +75 -0
- data/plugins/guests/linux/cap/reboot.rb +53 -0
- data/plugins/guests/linux/plugin.rb +20 -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/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/nfs_client.rb +2 -2
- 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/cap/nfs.rb +11 -0
- data/plugins/hosts/darwin/plugin.rb +15 -0
- data/plugins/hosts/linux/cap/fs_iso.rb +49 -0
- data/plugins/hosts/linux/cap/nfs.rb +21 -2
- 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 +221 -0
- data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
- data/plugins/kernel_v2/config/vm.rb +230 -15
- data/plugins/kernel_v2/config/vm_provisioner.rb +17 -3
- 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 +73 -10
- data/plugins/providers/docker/errors.rb +4 -0
- data/plugins/providers/docker/executor/local.rb +7 -1
- 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 +14 -1
- data/plugins/providers/virtualbox/action/clean_machine_folder.rb +10 -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/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 +35 -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 +17 -2
- data/plugins/providers/virtualbox/driver/version_5_0.rb +217 -2
- data/plugins/providers/virtualbox/driver/version_6_1.rb +39 -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 +38 -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/arch/ansible_install.rb +20 -3
- data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +4 -5
- data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +2 -2
- data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +2 -2
- data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +8 -4
- data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +2 -2
- data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +2 -1
- data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
- 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/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.erb +1 -1
- 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/locales/en.yml +235 -6
- data/templates/locales/providers_docker.yml +6 -0
- data/templates/nfs/exports_darwin.erb +7 -0
- data/vagrant.gemspec +14 -15
- data/version.txt +1 -1
- metadata +3577 -3855
- 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,8 +51,7 @@ 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
|
|
@@ -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
|
@@ -15,6 +15,9 @@ module VagrantPlugins
|
|
15
15
|
o.separator "can be restored via `vagrant snapshot restore` at any point in the"
|
16
16
|
o.separator "future to get back to this exact machine state."
|
17
17
|
o.separator ""
|
18
|
+
o.separator "If no vm-name is given, Vagrant will take a snapshot of"
|
19
|
+
o.separator "the entire environment with the same snapshot name."
|
20
|
+
o.separator ""
|
18
21
|
o.separator "Snapshots are useful for experimenting in a machine and being able"
|
19
22
|
o.separator "to rollback quickly."
|
20
23
|
|
@@ -31,20 +34,22 @@ module VagrantPlugins
|
|
31
34
|
help: opts.help.chomp
|
32
35
|
end
|
33
36
|
|
34
|
-
|
35
|
-
# If there is a name given, we need to remove it and save it as `name`. Otherwise
|
36
|
-
# `with_target_vms` will treat the snapshot name as a guest name.
|
37
|
-
if argv.size < 2
|
38
|
-
name = argv.first
|
39
|
-
else
|
40
|
-
name = argv.pop
|
41
|
-
end
|
37
|
+
name = argv.pop
|
42
38
|
|
43
39
|
with_target_vms(argv) do |vm|
|
44
40
|
if !vm.provider.capability?(:snapshot_list)
|
45
41
|
raise Vagrant::Errors::SnapshotNotSupported
|
46
42
|
end
|
47
43
|
|
44
|
+
# In this case, no vm name was given, and we are iterating over the
|
45
|
+
# entire environment. If a vm hasn't been created yet, we can't list
|
46
|
+
# its snapshots
|
47
|
+
if vm.id.nil?
|
48
|
+
@env.ui.warn(I18n.t("vagrant.commands.snapshot.save.vm_not_created",
|
49
|
+
name: vm.name))
|
50
|
+
next
|
51
|
+
end
|
52
|
+
|
48
53
|
snapshot_list = vm.provider.capability(:snapshot_list)
|
49
54
|
|
50
55
|
if !snapshot_list.include? name
|
@@ -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
|