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
data/lib/vagrant/box.rb
CHANGED
@@ -57,12 +57,15 @@ module Vagrant
|
|
57
57
|
# @param [Symbol] provider The provider that this box implements.
|
58
58
|
# @param [Pathname] directory The directory where this box exists on
|
59
59
|
# disk.
|
60
|
-
|
60
|
+
# @param [String] metadata_url Metadata URL for box
|
61
|
+
# @param [Hook] hook A hook to apply to the box downloader, for example, for authentication
|
62
|
+
def initialize(name, provider, version, directory, metadata_url: nil, hook: nil)
|
61
63
|
@name = name
|
62
64
|
@version = version
|
63
65
|
@provider = provider
|
64
66
|
@directory = directory
|
65
|
-
@metadata_url =
|
67
|
+
@metadata_url = metadata_url
|
68
|
+
@hook = hook
|
66
69
|
|
67
70
|
metadata_file = directory.join("metadata.json")
|
68
71
|
raise Errors::BoxMetadataFileNotFound, name: @name if !metadata_file.file?
|
@@ -120,7 +123,7 @@ module Vagrant
|
|
120
123
|
#
|
121
124
|
# @param [Hash] download_options Options to pass to the downloader.
|
122
125
|
# @return [BoxMetadata]
|
123
|
-
def load_metadata(
|
126
|
+
def load_metadata(download_options={})
|
124
127
|
tf = Tempfile.new("vagrant-load-metadata")
|
125
128
|
tf.close
|
126
129
|
|
@@ -132,7 +135,11 @@ module Vagrant
|
|
132
135
|
end
|
133
136
|
|
134
137
|
opts = { headers: ["Accept: application/json"] }.merge(download_options)
|
135
|
-
Util::Downloader.new(url, tf.path,
|
138
|
+
d = Util::Downloader.new(url, tf.path, opts)
|
139
|
+
if @hook
|
140
|
+
@hook.call(:authenticate_box_downloader, downloader: d)
|
141
|
+
end
|
142
|
+
d.download!
|
136
143
|
BoxMetadata.new(File.open(tf.path, "r"))
|
137
144
|
rescue Errors::DownloaderError => e
|
138
145
|
raise Errors::BoxMetadataDownloadError,
|
data/lib/vagrant/bundler.rb
CHANGED
@@ -18,6 +18,155 @@ module Vagrant
|
|
18
18
|
# Bundler as a way to properly resolve all dependencies of Vagrant and
|
19
19
|
# all Vagrant-installed plugins.
|
20
20
|
class Bundler
|
21
|
+
class SolutionFile
|
22
|
+
# @return [Pathname] path to plugin file
|
23
|
+
attr_reader :plugin_file
|
24
|
+
# @return [Pathname] path to solution file
|
25
|
+
attr_reader :solution_file
|
26
|
+
# @return [Array<Gem::Resolver::DependencyRequest>] list of required dependencies
|
27
|
+
attr_reader :dependency_list
|
28
|
+
|
29
|
+
# @param [Pathname] plugin_file Path to plugin file
|
30
|
+
# @param [Pathname] solution_file Custom path to solution file
|
31
|
+
def initialize(plugin_file:, solution_file: nil)
|
32
|
+
@logger = Log4r::Logger.new("vagrant::bundler::solution_file")
|
33
|
+
@plugin_file = Pathname.new(plugin_file.to_s)
|
34
|
+
if solution_file
|
35
|
+
@solution_file = Pathname.new(solution_file.to_s)
|
36
|
+
else
|
37
|
+
@solution_file = Pathname.new(@plugin_file.to_s + ".sol")
|
38
|
+
end
|
39
|
+
@valid = false
|
40
|
+
@dependency_list = [].freeze
|
41
|
+
@logger.debug("new solution file instance plugin_file=#{plugin_file} " \
|
42
|
+
"solution_file=#{solution_file}")
|
43
|
+
load
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set the list of dependencies for this solution
|
47
|
+
#
|
48
|
+
# @param [Array<Gem::Dependency>] dependency_list List of dependencies for the solution
|
49
|
+
# @return [Array<Gem::Resolver::DependencyRequest>]
|
50
|
+
def dependency_list=(dependency_list)
|
51
|
+
Array(dependency_list).each do |d|
|
52
|
+
if !d.is_a?(Gem::Dependency)
|
53
|
+
raise TypeError, "Expected `Gem::Dependency` but received `#{d.class}`"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
@dependency_list = dependency_list.map do |d|
|
57
|
+
Gem::Resolver::DependencyRequest.new(d, nil).freeze
|
58
|
+
end.freeze
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Boolean] contained solution is valid
|
62
|
+
def valid?
|
63
|
+
@valid
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [FalseClass] invalidate this solution file
|
67
|
+
def invalidate!
|
68
|
+
@valid = false
|
69
|
+
@logger.debug("manually invalidating solution file #{self}")
|
70
|
+
@valid
|
71
|
+
end
|
72
|
+
|
73
|
+
# Delete the solution file
|
74
|
+
#
|
75
|
+
# @return [Boolean] true if file was deleted
|
76
|
+
def delete!
|
77
|
+
if !solution_file.exist?
|
78
|
+
@logger.debug("solution file does not exist. nothing to delete.")
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
@logger.debug("deleting solution file - #{solution_file}")
|
82
|
+
solution_file.delete
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
# Store the solution file
|
87
|
+
def store!
|
88
|
+
if !plugin_file.exist?
|
89
|
+
@logger.debug("plugin file does not exist, not storing solution")
|
90
|
+
return
|
91
|
+
end
|
92
|
+
if !solution_file.dirname.exist?
|
93
|
+
@logger.debug("creating directory for solution file: #{solution_file.dirname}")
|
94
|
+
solution_file.dirname.mkpath
|
95
|
+
end
|
96
|
+
@logger.debug("writing solution file contents to disk")
|
97
|
+
solution_file.write({
|
98
|
+
dependencies: dependency_list.map { |d|
|
99
|
+
[d.dependency.name, d.dependency.requirements_list]
|
100
|
+
},
|
101
|
+
checksum: plugin_file_checksum,
|
102
|
+
vagrant_version: Vagrant::VERSION
|
103
|
+
}.to_json)
|
104
|
+
@valid = true
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_s # :nodoc:
|
108
|
+
"<Vagrant::Bundler::SolutionFile:#{plugin_file}:" \
|
109
|
+
"#{solution_file}:#{valid? ? "valid" : "invalid"}>"
|
110
|
+
end
|
111
|
+
|
112
|
+
protected
|
113
|
+
|
114
|
+
# Load the solution file for the plugin path provided
|
115
|
+
# if it exists. Validate solution is still applicable
|
116
|
+
# before injecting dependencies.
|
117
|
+
def load
|
118
|
+
if !plugin_file.exist? || !solution_file.exist?
|
119
|
+
@logger.debug("missing file so skipping loading")
|
120
|
+
return
|
121
|
+
end
|
122
|
+
solution = read_solution || return
|
123
|
+
return if !valid_solution?(
|
124
|
+
checksum: solution[:checksum],
|
125
|
+
version: solution[:vagrant_version]
|
126
|
+
)
|
127
|
+
@logger.debug("loading solution dependency list")
|
128
|
+
@dependency_list = Array(solution[:dependencies]).map do |name, requirements|
|
129
|
+
gd = Gem::Dependency.new(name, requirements)
|
130
|
+
Gem::Resolver::DependencyRequest.new(gd, nil).freeze
|
131
|
+
end.freeze
|
132
|
+
@logger.debug("solution dependency list: #{dependency_list}")
|
133
|
+
@valid = true
|
134
|
+
end
|
135
|
+
|
136
|
+
# Validate the given checksum matches the plugin file
|
137
|
+
# checksum
|
138
|
+
#
|
139
|
+
# @param [String] checksum Checksum value to validate
|
140
|
+
# @return [Boolean]
|
141
|
+
def valid_solution?(checksum:, version:)
|
142
|
+
file_checksum = plugin_file_checksum
|
143
|
+
@logger.debug("solution validation check CHECKSUM #{file_checksum} <-> #{checksum}" \
|
144
|
+
" VERSION #{Vagrant::VERSION} <-> #{version}")
|
145
|
+
plugin_file_checksum == checksum &&
|
146
|
+
Vagrant::VERSION == version
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [String] checksum of plugin file
|
150
|
+
def plugin_file_checksum
|
151
|
+
digest = Digest::SHA256.new
|
152
|
+
digest.file(plugin_file.to_s)
|
153
|
+
digest.hexdigest
|
154
|
+
end
|
155
|
+
|
156
|
+
# Read contents of solution file and parse
|
157
|
+
#
|
158
|
+
# @return [Hash]
|
159
|
+
def read_solution
|
160
|
+
@logger.debug("reading solution file - #{solution_file}")
|
161
|
+
begin
|
162
|
+
hash = JSON.load(solution_file.read)
|
163
|
+
Vagrant::Util::HashWithIndifferentAccess.new(hash)
|
164
|
+
rescue => err
|
165
|
+
@logger.warn("failed to load solution file, ignoring (error: #{err})")
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
21
170
|
|
22
171
|
# Location of HashiCorp gem repository
|
23
172
|
HASHICORP_GEMSTORE = "https://gems.hashicorp.com/".freeze
|
@@ -34,26 +183,19 @@ module Vagrant
|
|
34
183
|
|
35
184
|
# @return [Pathname] Global plugin path
|
36
185
|
attr_reader :plugin_gem_path
|
186
|
+
# @return [Pathname] Global plugin solution set path
|
187
|
+
attr_reader :plugin_solution_path
|
37
188
|
# @return [Pathname] Vagrant environment specific plugin path
|
38
189
|
attr_reader :env_plugin_gem_path
|
190
|
+
# @return [Pathname] Vagrant environment data path
|
191
|
+
attr_reader :environment_data_path
|
192
|
+
# @return [Array<Gem::Specification>, nil] List of builtin specs
|
193
|
+
attr_accessor :builtin_specs
|
39
194
|
|
40
195
|
def initialize
|
196
|
+
@builtin_specs = []
|
41
197
|
@plugin_gem_path = Vagrant.user_data_path.join("gems", RUBY_VERSION).freeze
|
42
198
|
@logger = Log4r::Logger.new("vagrant::bundler")
|
43
|
-
|
44
|
-
# TODO: Remove fix when https://github.com/rubygems/rubygems/pull/2735
|
45
|
-
# gets merged and released
|
46
|
-
#
|
47
|
-
# Because of a rubygems bug, we need to set the gemrc file path
|
48
|
-
# through this method rather than relying on the environment varible
|
49
|
-
# GEMRC. On windows, that path gets split on `:`: and `;`, which means
|
50
|
-
# the drive letter gets treated as its own path. If that path exists locally,
|
51
|
-
# (like having a random folder called `c` where the library was invoked),
|
52
|
-
# it fails thinking the folder `c` is a gemrc file.
|
53
|
-
gemrc_val = ENV["GEMRC"]
|
54
|
-
ENV["GEMRC"] = ""
|
55
|
-
Gem.configuration = Gem::ConfigFile.new(["--config-file", gemrc_val])
|
56
|
-
ENV["GEMRC"] = gemrc_val
|
57
199
|
end
|
58
200
|
|
59
201
|
# Enable Vagrant environment specific plugins at given data path
|
@@ -61,12 +203,39 @@ module Vagrant
|
|
61
203
|
# @param [Pathname] Path to Vagrant::Environment data directory
|
62
204
|
# @return [Pathname] Path to environment specific gem directory
|
63
205
|
def environment_path=(env_data_path)
|
206
|
+
if !env_data_path.is_a?(Pathname)
|
207
|
+
raise TypeError, "Expected `Pathname` but received `#{env_data_path.class}`"
|
208
|
+
end
|
64
209
|
@env_plugin_gem_path = env_data_path.join("plugins", "gems", RUBY_VERSION).freeze
|
210
|
+
@environment_data_path = env_data_path
|
211
|
+
end
|
212
|
+
|
213
|
+
# Use the given options to create a solution file instance
|
214
|
+
# for use during initialization. When a Vagrant environment
|
215
|
+
# is in use, solution files will be stored within the environment's
|
216
|
+
# data directory. This is because the solution for loading global
|
217
|
+
# plugins is dependent on any solution generated for local plugins.
|
218
|
+
# When no Vagrant environment is in use (running Vagrant without a
|
219
|
+
# Vagrantfile), the Vagrant user data path will be used for solution
|
220
|
+
# storage since only the global plugins will be used.
|
221
|
+
#
|
222
|
+
# @param [Hash] opts Options passed to #init!
|
223
|
+
# @return [SolutionFile]
|
224
|
+
def load_solution_file(opts={})
|
225
|
+
return if !opts[:local] && !opts[:global]
|
226
|
+
return if opts[:local] && opts[:global]
|
227
|
+
return if opts[:local] && environment_data_path.nil?
|
228
|
+
solution_path = (environment_data_path || Vagrant.user_data_path) + "bundler"
|
229
|
+
solution_path += opts[:local] ? "local.sol" : "global.sol"
|
230
|
+
SolutionFile.new(
|
231
|
+
plugin_file: opts[:local] || opts[:global],
|
232
|
+
solution_file: solution_path
|
233
|
+
)
|
65
234
|
end
|
66
235
|
|
67
236
|
# Initializes Bundler and the various gem paths so that we can begin
|
68
237
|
# loading gems.
|
69
|
-
def init!(plugins, repair=false)
|
238
|
+
def init!(plugins, repair=false, **opts)
|
70
239
|
if !@initial_specifications
|
71
240
|
@initial_specifications = Gem::Specification.find_all{true}
|
72
241
|
else
|
@@ -74,45 +243,83 @@ module Vagrant
|
|
74
243
|
Gem::Specification.reset
|
75
244
|
end
|
76
245
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
246
|
+
solution_file = load_solution_file(opts)
|
247
|
+
@logger.debug("solution file in use for init: #{solution_file}")
|
248
|
+
|
249
|
+
solution = nil
|
250
|
+
composed_set = generate_vagrant_set
|
251
|
+
|
252
|
+
# Force the composed set to allow prereleases
|
253
|
+
if Vagrant.allow_prerelease_dependencies?
|
254
|
+
@logger.debug("enabling prerelease dependency matching due to user request")
|
255
|
+
composed_set.prerelease = true
|
81
256
|
end
|
82
257
|
|
83
|
-
|
84
|
-
|
85
|
-
|
258
|
+
if solution_file&.valid?
|
259
|
+
@logger.debug("loading cached solution set")
|
260
|
+
solution = solution_file.dependency_list.map do |dep|
|
261
|
+
spec = composed_set.find_all(dep).first
|
262
|
+
if !spec
|
263
|
+
@logger.warn("failed to locate specification for dependency - #{dep}")
|
264
|
+
@logger.warn("invalidating solution file - #{solution_file}")
|
265
|
+
solution_file.invalidate!
|
266
|
+
break
|
267
|
+
end
|
268
|
+
dep_r = Gem::Resolver::DependencyRequest.new(dep, nil)
|
269
|
+
Gem::Resolver::ActivationRequest.new(spec, dep_r)
|
270
|
+
end
|
86
271
|
end
|
87
272
|
|
88
|
-
|
273
|
+
if !solution_file&.valid?
|
274
|
+
@logger.debug("generating solution set for configured plugins")
|
275
|
+
# Add HashiCorp RubyGems source
|
276
|
+
if !Gem.sources.include?(HASHICORP_GEMSTORE)
|
277
|
+
sources = [HASHICORP_GEMSTORE] + Gem.sources.sources
|
278
|
+
Gem.sources.replace(sources)
|
279
|
+
end
|
89
280
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
281
|
+
# Generate dependencies for all registered plugins
|
282
|
+
plugin_deps = plugins.map do |name, info|
|
283
|
+
Gem::Dependency.new(name, info['installed_gem_version'].to_s.empty? ? '> 0' : info['installed_gem_version'])
|
284
|
+
end
|
94
285
|
|
95
|
-
|
96
|
-
|
97
|
-
#
|
98
|
-
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@
|
107
|
-
|
108
|
-
|
109
|
-
|
286
|
+
@logger.debug("Current generated plugin dependency list: #{plugin_deps}")
|
287
|
+
|
288
|
+
# Load dependencies into a request set for resolution
|
289
|
+
request_set = Gem::RequestSet.new(*plugin_deps)
|
290
|
+
# Never allow dependencies to be remotely satisfied during init
|
291
|
+
request_set.remote = false
|
292
|
+
|
293
|
+
begin
|
294
|
+
@logger.debug("resolving solution from available specification set")
|
295
|
+
# Resolve the request set to ensure proper activation order
|
296
|
+
solution = request_set.resolve(composed_set)
|
297
|
+
@logger.debug("solution set for configured plugins has been resolved")
|
298
|
+
rescue Gem::UnsatisfiableDependencyError => failure
|
299
|
+
if repair
|
300
|
+
raise failure if @init_retried
|
301
|
+
@logger.debug("Resolution failed but attempting to repair. Failure: #{failure}")
|
302
|
+
install(plugins)
|
303
|
+
@init_retried = true
|
304
|
+
retry
|
305
|
+
else
|
306
|
+
raise
|
307
|
+
end
|
110
308
|
end
|
111
309
|
end
|
112
310
|
|
113
311
|
# Activate the gems
|
312
|
+
@logger.debug("activating solution set")
|
114
313
|
activate_solution(solution)
|
115
314
|
|
315
|
+
if solution_file && !solution_file.valid?
|
316
|
+
solution_file.dependency_list = solution.map do |activation|
|
317
|
+
activation.request.dependency
|
318
|
+
end
|
319
|
+
solution_file.store!
|
320
|
+
@logger.debug("solution set stored to - #{solution_file}")
|
321
|
+
end
|
322
|
+
|
116
323
|
full_vagrant_spec_list = @initial_specifications +
|
117
324
|
solution.map(&:full_spec)
|
118
325
|
|
@@ -287,7 +494,7 @@ module Vagrant
|
|
287
494
|
if update[:gems] == true || (update[:gems].respond_to?(:include?) && update[:gems].include?(name))
|
288
495
|
if Gem::Requirement.new(gem_version).exact?
|
289
496
|
gem_version = "> 0"
|
290
|
-
@logger.debug("Detected exact version match for `#{name}` plugin update. Reset to
|
497
|
+
@logger.debug("Detected exact version match for `#{name}` plugin update. Reset to loosen constraint #{gem_version.inspect}.")
|
291
498
|
end
|
292
499
|
skips << name
|
293
500
|
end
|
@@ -309,6 +516,9 @@ module Vagrant
|
|
309
516
|
@logger.debug("Enabling strict dependency enforcement")
|
310
517
|
plugin_deps += vagrant_internal_specs.map do |spec|
|
311
518
|
next if system_plugins.include?(spec.name)
|
519
|
+
# If this spec is for a default plugin included in
|
520
|
+
# the ruby stdlib, ignore it
|
521
|
+
next if spec.default_gem?
|
312
522
|
# If we are not running within the installer and
|
313
523
|
# we are not within a bundler environment then we
|
314
524
|
# only want activated specs
|
@@ -363,17 +573,25 @@ module Vagrant
|
|
363
573
|
generate_builtin_set(system_plugins),
|
364
574
|
generate_plugin_set(skips)
|
365
575
|
)
|
576
|
+
|
577
|
+
if Vagrant.allow_prerelease_dependencies?
|
578
|
+
@logger.debug("enabling prerelease dependency matching based on user request")
|
579
|
+
request_set.prerelease = true
|
580
|
+
installer_set.prerelease = true
|
581
|
+
end
|
582
|
+
|
366
583
|
@logger.debug("Generating solution set for installation.")
|
367
584
|
|
368
585
|
# Generate the required solution set for new plugins
|
369
586
|
solution = request_set.resolve(installer_set)
|
587
|
+
|
370
588
|
activate_solution(solution)
|
371
589
|
|
372
590
|
# Remove gems which are already installed
|
373
|
-
request_set.sorted_requests.delete_if do |
|
374
|
-
|
375
|
-
if vagrant_internal_specs.detect{|
|
376
|
-
@logger.debug("Removing activation request from install. Already installed. (#{
|
591
|
+
request_set.sorted_requests.delete_if do |act_req|
|
592
|
+
rs = act_req.spec
|
593
|
+
if vagrant_internal_specs.detect{ |i| i.name == rs.name && i.version == rs.version }
|
594
|
+
@logger.debug("Removing activation request from install. Already installed. (#{rs.spec.full_name})")
|
377
595
|
true
|
378
596
|
end
|
379
597
|
end
|
@@ -387,9 +605,11 @@ module Vagrant
|
|
387
605
|
install_path = extra[:env_local] ? env_plugin_gem_path : plugin_gem_path
|
388
606
|
result = request_set.install_into(install_path.to_s, true,
|
389
607
|
ignore_dependencies: true,
|
390
|
-
prerelease: Vagrant.prerelease?,
|
391
|
-
wrappers: true
|
608
|
+
prerelease: Vagrant.prerelease? || Vagrant.allow_prerelease_dependencies?,
|
609
|
+
wrappers: true,
|
610
|
+
document: []
|
392
611
|
)
|
612
|
+
|
393
613
|
result = result.map(&:full_spec)
|
394
614
|
result.each do |spec|
|
395
615
|
existing_paths = $LOAD_PATH.find_all{|s| s.include?(spec.full_name) }
|
@@ -421,15 +641,35 @@ module Vagrant
|
|
421
641
|
def vagrant_internal_specs
|
422
642
|
# activate any dependencies up front so we can always
|
423
643
|
# pin them when resolving
|
424
|
-
Gem::Specification.find { |s| s.name == "vagrant-unbundled" && s.activated? }
|
425
|
-
|
644
|
+
self_spec = Gem::Specification.find { |s| s.name == "vagrant-unbundled" && s.activated? }
|
645
|
+
if !self_spec
|
646
|
+
@logger.warn("Failed to locate activated vagrant specification. Activating...")
|
647
|
+
self_spec = Gem::Specification.find { |s| s.name == "vagrant-unbundled" }
|
648
|
+
if !self_spec
|
649
|
+
@logger.error("Failed to locate Vagrant RubyGem specification")
|
650
|
+
raise Vagrant::Errors::SourceSpecNotFound
|
651
|
+
end
|
652
|
+
self_spec.activate
|
653
|
+
@logger.info("Activated vagrant specification version - #{self_spec.version}")
|
654
|
+
end
|
426
655
|
# discover all the gems we have available
|
427
656
|
list = {}
|
428
|
-
|
429
|
-
|
430
|
-
|
657
|
+
if Gem.respond_to?(:default_specifications_dir)
|
658
|
+
spec_dir = Gem.default_specifications_dir
|
659
|
+
else
|
660
|
+
spec_dir = Gem::Specification.default_specifications_dir
|
431
661
|
end
|
432
|
-
|
662
|
+
directories = [spec_dir]
|
663
|
+
if Vagrant.in_bundler?
|
664
|
+
Gem::Specification.find_all{true}.each do |spec|
|
665
|
+
list[spec.full_name] = spec
|
666
|
+
end
|
667
|
+
else
|
668
|
+
builtin_specs.each do |spec|
|
669
|
+
list[spec.full_name] = spec
|
670
|
+
end
|
671
|
+
end
|
672
|
+
if Vagrant.in_installer?
|
433
673
|
directories += Gem::Specification.dirs.find_all do |path|
|
434
674
|
!path.start_with?(Gem.user_dir)
|
435
675
|
end
|
@@ -528,7 +768,6 @@ module Vagrant
|
|
528
768
|
request.name == matcher["gem_name"]
|
529
769
|
end
|
530
770
|
if desired_activation_request && !desired_activation_request.full_spec.activated?
|
531
|
-
activation_request = desired_activation_request
|
532
771
|
@logger.warn("Found misordered activation request for #{desired_activation_request.full_name}. Moving to solution HEAD.")
|
533
772
|
solution.delete(desired_activation_request)
|
534
773
|
solution.unshift(desired_activation_request)
|
@@ -600,12 +839,22 @@ module Vagrant
|
|
600
839
|
end
|
601
840
|
|
602
841
|
def find_all(req)
|
603
|
-
@specs.select do |spec|
|
604
|
-
|
605
|
-
|
842
|
+
r = @specs.select do |spec|
|
843
|
+
# When matching requests against builtin specs, we _always_ enable
|
844
|
+
# prerelease matching since any prerelease that's found in this
|
845
|
+
# set has been added explicitly and should be available for all
|
846
|
+
# plugins to resolve against. This includes Vagrant itself since
|
847
|
+
# it is considered a prerelease when in development mode
|
848
|
+
req.match?(spec, true)
|
606
849
|
end.map do |spec|
|
607
850
|
Gem::Resolver::InstalledSpecification.new(self, spec)
|
608
851
|
end
|
852
|
+
# If any of the results are a prerelease, we need to mark the request
|
853
|
+
# to allow prereleases so the solution can be properly fulfilled
|
854
|
+
if r.any? { |x| x.version.prerelease? }
|
855
|
+
req.dependency.prerelease = true
|
856
|
+
end
|
857
|
+
r
|
609
858
|
end
|
610
859
|
end
|
611
860
|
|
@@ -639,7 +888,7 @@ module Vagrant
|
|
639
888
|
# DependencyRequest +req+.
|
640
889
|
def find_all(req)
|
641
890
|
@specs.values.flatten.select do |spec|
|
642
|
-
req.match?(spec)
|
891
|
+
req.match?(spec, prerelease)
|
643
892
|
end.map do |spec|
|
644
893
|
source = Gem::Source::Vendor.new(@directories[spec])
|
645
894
|
Gem::Resolver::VendorSpecification.new(self, spec, source)
|
@@ -649,7 +898,7 @@ module Vagrant
|
|
649
898
|
##
|
650
899
|
# Loads a spec with the given +name+. +version+, +platform+ and +source+ are
|
651
900
|
# ignored.
|
652
|
-
def load_spec
|
901
|
+
def load_spec(name, version, platform, source)
|
653
902
|
version = Gem::Version.new(version) if !version.is_a?(Gem::Version)
|
654
903
|
@specs.fetch(name, []).detect{|s| s.name == name && s.version == version}
|
655
904
|
end
|