vagrant-unbundled 2.2.6.0 → 2.2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +14 -0
  3. data/CHANGELOG.md +93 -2
  4. data/README.md +1 -3
  5. data/bin/vagrant +23 -0
  6. data/contrib/bash/completion.sh +13 -1
  7. data/lib/vagrant.rb +25 -0
  8. data/lib/vagrant/action.rb +5 -0
  9. data/lib/vagrant/action/builder.rb +145 -24
  10. data/lib/vagrant/action/builtin/box_add.rb +11 -4
  11. data/lib/vagrant/action/builtin/box_check_outdated.rb +12 -15
  12. data/lib/vagrant/action/builtin/cleanup_disks.rb +56 -0
  13. data/lib/vagrant/action/builtin/delayed.rb +26 -0
  14. data/lib/vagrant/action/builtin/disk.rb +52 -0
  15. data/lib/vagrant/action/builtin/handle_box.rb +2 -0
  16. data/lib/vagrant/action/builtin/handle_forwarded_port_collisions.rb +28 -9
  17. data/lib/vagrant/action/builtin/mixin_provisioners.rb +19 -1
  18. data/lib/vagrant/action/builtin/ssh_run.rb +21 -3
  19. data/lib/vagrant/action/builtin/trigger.rb +36 -0
  20. data/lib/vagrant/action/hook.rb +20 -2
  21. data/lib/vagrant/action/runner.rb +11 -26
  22. data/lib/vagrant/action/warden.rb +4 -18
  23. data/lib/vagrant/box_metadata.rb +17 -3
  24. data/lib/vagrant/bundler.rb +260 -53
  25. data/lib/vagrant/cli.rb +4 -2
  26. data/lib/vagrant/errors.rb +24 -0
  27. data/lib/vagrant/machine.rb +9 -6
  28. data/lib/vagrant/plugin/manager.rb +25 -14
  29. data/lib/vagrant/plugin/v2/command.rb +1 -1
  30. data/lib/vagrant/plugin/v2/manager.rb +53 -0
  31. data/lib/vagrant/plugin/v2/plugin.rb +1 -0
  32. data/lib/vagrant/plugin/v2/trigger.rb +64 -26
  33. data/lib/vagrant/shared_helpers.rb +28 -0
  34. data/lib/vagrant/ui.rb +50 -4
  35. data/lib/vagrant/util.rb +1 -0
  36. data/lib/vagrant/util/curl_helper.rb +8 -5
  37. data/lib/vagrant/util/downloader.rb +5 -1
  38. data/lib/vagrant/util/file_checksum.rb +6 -2
  39. data/lib/vagrant/util/guest_inspection.rb +9 -1
  40. data/lib/vagrant/util/io.rb +7 -27
  41. data/lib/vagrant/util/is_port_open.rb +1 -2
  42. data/lib/vagrant/util/map_command_options.rb +33 -0
  43. data/lib/vagrant/util/numeric.rb +69 -0
  44. data/lib/vagrant/util/platform.rb +8 -1
  45. data/plugins/commands/box/command/outdated.rb +14 -2
  46. data/plugins/commands/cloud/locales/en.yml +1 -1
  47. data/plugins/commands/cloud/publish.rb +1 -1
  48. data/plugins/commands/snapshot/command/save.rb +13 -8
  49. data/plugins/commands/ssh_config/command.rb +1 -1
  50. data/plugins/communicators/ssh/communicator.rb +18 -23
  51. data/plugins/communicators/winrm/config.rb +1 -1
  52. data/plugins/communicators/winrm/shell.rb +1 -1
  53. data/plugins/communicators/winssh/communicator.rb +126 -38
  54. data/plugins/communicators/winssh/config.rb +3 -7
  55. data/plugins/guests/alpine/cap/rsync.rb +1 -1
  56. data/plugins/guests/alpine/plugin.rb +16 -0
  57. data/plugins/guests/centos/cap/flavor.rb +24 -0
  58. data/plugins/guests/centos/guest.rb +9 -0
  59. data/plugins/guests/centos/plugin.rb +20 -0
  60. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +99 -13
  61. data/plugins/guests/darwin/plugin.rb +5 -0
  62. data/plugins/guests/debian/cap/configure_networks.rb +14 -6
  63. data/plugins/guests/linux/cap/halt.rb +9 -1
  64. data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +16 -0
  65. data/plugins/guests/linux/cap/reboot.rb +48 -0
  66. data/plugins/guests/linux/plugin.rb +10 -0
  67. data/plugins/guests/redhat/cap/flavor.rb +3 -1
  68. data/plugins/guests/redhat/cap/nfs_client.rb +2 -2
  69. data/plugins/guests/redhat/cap/smb.rb +20 -0
  70. data/plugins/guests/redhat/plugin.rb +5 -0
  71. data/plugins/guests/suse/cap/change_host_name.rb +2 -2
  72. data/plugins/guests/windows/cap/public_key.rb +3 -3
  73. data/plugins/guests/windows/cap/reboot.rb +2 -1
  74. data/plugins/hosts/darwin/cap/nfs.rb +11 -0
  75. data/plugins/hosts/darwin/plugin.rb +5 -0
  76. data/plugins/hosts/linux/cap/nfs.rb +21 -2
  77. data/plugins/kernel_v2/config/disk.rb +199 -0
  78. data/plugins/kernel_v2/config/ssh_connect.rb +24 -0
  79. data/plugins/kernel_v2/config/vm.rb +109 -4
  80. data/plugins/kernel_v2/config/vm_provisioner.rb +4 -1
  81. data/plugins/kernel_v2/config/vm_trigger.rb +2 -5
  82. data/plugins/providers/docker/driver.rb +38 -10
  83. data/plugins/providers/docker/errors.rb +4 -0
  84. data/plugins/providers/docker/executor/local.rb +7 -1
  85. data/plugins/providers/hyperv/action/export.rb +4 -2
  86. data/plugins/providers/hyperv/driver.rb +10 -9
  87. data/plugins/providers/hyperv/scripts/set_vm_integration_services.ps1 +3 -3
  88. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +6 -6
  89. data/plugins/providers/virtualbox/action.rb +2 -0
  90. data/plugins/providers/virtualbox/action/clean_machine_folder.rb +10 -1
  91. data/plugins/providers/virtualbox/action/export.rb +4 -2
  92. data/plugins/providers/virtualbox/action/import.rb +8 -4
  93. data/plugins/providers/virtualbox/action/prepare_clone_snapshot.rb +4 -2
  94. data/plugins/providers/virtualbox/action/snapshot_delete.rb +4 -2
  95. data/plugins/providers/virtualbox/action/snapshot_restore.rb +4 -2
  96. data/plugins/providers/virtualbox/cap/cleanup_disks.rb +54 -0
  97. data/plugins/providers/virtualbox/cap/configure_disks.rb +287 -0
  98. data/plugins/providers/virtualbox/cap/validate_disk_ext.rb +27 -0
  99. data/plugins/providers/virtualbox/driver/base.rb +15 -0
  100. data/plugins/providers/virtualbox/driver/meta.rb +14 -2
  101. data/plugins/providers/virtualbox/driver/version_5_0.rb +142 -2
  102. data/plugins/providers/virtualbox/driver/version_6_1.rb +39 -0
  103. data/plugins/providers/virtualbox/plugin.rb +21 -0
  104. data/plugins/provisioners/ansible/cap/guest/alpine/ansible_install.rb +44 -0
  105. data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +20 -3
  106. data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +4 -5
  107. data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +2 -2
  108. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +2 -2
  109. data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +8 -4
  110. data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +2 -2
  111. data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +2 -1
  112. data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
  113. data/plugins/provisioners/ansible/plugin.rb +5 -0
  114. data/plugins/provisioners/ansible/provisioner/base.rb +1 -1
  115. data/plugins/provisioners/container/client.rb +203 -0
  116. data/plugins/provisioners/container/config.rb +83 -0
  117. data/plugins/provisioners/container/installer.rb +13 -0
  118. data/plugins/provisioners/container/plugin.rb +23 -0
  119. data/plugins/provisioners/container/provisioner.rb +28 -0
  120. data/plugins/provisioners/docker/cap/{redhat → centos}/docker_install.rb +10 -7
  121. data/plugins/provisioners/docker/cap/centos/docker_start_service.rb +24 -0
  122. data/plugins/provisioners/docker/client.rb +4 -175
  123. data/plugins/provisioners/docker/config.rb +2 -72
  124. data/plugins/provisioners/docker/installer.rb +3 -5
  125. data/plugins/provisioners/docker/plugin.rb +6 -6
  126. data/plugins/provisioners/docker/provisioner.rb +4 -10
  127. data/plugins/provisioners/podman/cap/centos/podman_install.rb +35 -0
  128. data/plugins/provisioners/podman/cap/linux/podman_installed.rb +13 -0
  129. data/plugins/provisioners/podman/cap/redhat/podman_install.rb +26 -0
  130. data/plugins/provisioners/podman/client.rb +12 -0
  131. data/plugins/provisioners/podman/config.rb +28 -0
  132. data/plugins/provisioners/podman/installer.rb +33 -0
  133. data/plugins/provisioners/podman/plugin.rb +38 -0
  134. data/plugins/provisioners/podman/provisioner.rb +52 -0
  135. data/plugins/provisioners/salt/provisioner.rb +4 -0
  136. data/plugins/provisioners/shell/config.rb +1 -6
  137. data/plugins/provisioners/shell/provisioner.rb +54 -25
  138. data/plugins/synced_folders/smb/synced_folder.rb +1 -1
  139. data/templates/commands/init/Vagrantfile.erb +1 -1
  140. data/templates/locales/en.yml +123 -4
  141. data/templates/locales/providers_docker.yml +2 -0
  142. data/templates/nfs/exports_darwin.erb +7 -0
  143. data/vagrant.gemspec +8 -9
  144. data/version.txt +1 -1
  145. metadata +3731 -3663
  146. data/lib/vagrant/action/builtin/after_trigger.rb +0 -31
  147. data/lib/vagrant/action/builtin/before_trigger.rb +0 -28
  148. data/plugins/provisioners/docker/cap/redhat/docker_start_service.rb +0 -16
@@ -1,7 +1,5 @@
1
1
  require "log4r"
2
2
  require 'vagrant/util/experimental'
3
- require 'vagrant/action/builtin/before_trigger'
4
- require 'vagrant/action/builtin/after_trigger'
5
3
 
6
4
  module Vagrant
7
5
  module Action
@@ -50,9 +48,9 @@ module Vagrant
50
48
  @stack.unshift(action).first.call(env)
51
49
  raise Errors::VagrantInterrupt if env[:interrupted]
52
50
  @logger.info("Calling OUT action: #{action}")
53
- rescue SystemExit
54
- # This means that an "exit" or "abort" was called. In these cases,
55
- # we just exit immediately.
51
+ rescue SystemExit, NoMemoryError
52
+ # This means that an "exit" or "abort" was called, or we have run out
53
+ # of memory. In these cases, we just exit immediately.
56
54
  raise
57
55
  rescue Exception => e
58
56
  # We guard this so that the Warden only outputs this once for
@@ -101,19 +99,7 @@ module Vagrant
101
99
  args ||= []
102
100
 
103
101
  if klass.is_a?(Class)
104
- # A action klass which is to be instantiated with the
105
- # app, env, and any arguments given
106
-
107
- # We wrap the action class in two Trigger method calls so that
108
- # action triggers can fire before and after each given action in the stack.
109
- klass_name = klass.name
110
- [Vagrant::Action::Builtin::BeforeTriggerAction.new(self, env,
111
- klass_name,
112
- @triggers),
113
- klass.new(self, env, *args, &block),
114
- Vagrant::Action::Builtin::AfterTriggerAction.new(self, env,
115
- klass_name,
116
- @triggers)]
102
+ klass.new(self, env, *args, &block)
117
103
  elsif klass.respond_to?(:call)
118
104
  # Make it a lambda which calls the item then forwards
119
105
  # up the chain
@@ -68,11 +68,25 @@ module Vagrant
68
68
 
69
69
  # Returns all the versions supported by this metadata. These
70
70
  # versions are sorted so the last element of the list is the
71
- # latest version.
71
+ # latest version. Optionally filter versions by a matching
72
+ # provider.
72
73
  #
73
74
  # @return[Array<String>]
74
- def versions
75
- @version_map.keys.sort.map(&:to_s)
75
+ def versions(**opts)
76
+ provider = nil
77
+ provider = opts[:provider].to_sym if opts[:provider]
78
+
79
+ if provider
80
+ @version_map.select do |version, raw|
81
+ if raw["providers"]
82
+ raw["providers"].detect do |p|
83
+ p["name"].to_sym == provider
84
+ end
85
+ end
86
+ end.keys.sort.map(&:to_s)
87
+ else
88
+ @version_map.keys.sort.map(&:to_s)
89
+ end
76
90
  end
77
91
 
78
92
  # Represents a single version within the metadata.
@@ -18,6 +18,149 @@ 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::Dependency>] 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::signature_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
+ def dependency_list=(dependency_list)
50
+ Array(dependency_list).each do |d|
51
+ if !d.is_a?(Gem::Dependency)
52
+ raise TypeError, "Expected `Gem::Dependency` but received `#{d.class}`"
53
+ end
54
+ end
55
+ @dependency_list = dependency_list.map(&:freeze).freeze
56
+ end
57
+
58
+ # @return [Boolean] contained solution is valid
59
+ def valid?
60
+ @valid
61
+ end
62
+
63
+ # @return [FalseClass] invalidate this solution file
64
+ def invalidate!
65
+ @logger.debug("manually invalidating solution file")
66
+ @valid = false
67
+ end
68
+
69
+ # Delete the solution file
70
+ #
71
+ # @return [Boolean] true if file was deleted
72
+ def delete!
73
+ if !solution_file.exist?
74
+ @logger.debug("solution file does not exist. nothing to delete.")
75
+ return false
76
+ end
77
+ @logger.debug("deleting solution file - #{solution_file}")
78
+ solution_file.delete
79
+ true
80
+ end
81
+
82
+ # Store the solution file
83
+ def store!
84
+ if !plugin_file.exist?
85
+ @logger.debug("plugin file does not exist, not storing solution")
86
+ return
87
+ end
88
+ if !solution_file.dirname.exist?
89
+ @logger.debug("creating directory for solution file: #{solution_file.dirname}")
90
+ solution_file.dirname.mkpath
91
+ end
92
+ @logger.debug("writing solution file contents to disk")
93
+ solution_file.write({
94
+ dependencies: dependency_list.map { |d|
95
+ [d.name, d.requirements_list]
96
+ },
97
+ checksum: plugin_file_checksum,
98
+ vagrant_version: Vagrant::VERSION
99
+ }.to_json)
100
+ @valid = true
101
+ end
102
+
103
+ def to_s # :nodoc:
104
+ "<Vagrant::Bundler::SolutionFile:#{plugin_file}:" \
105
+ "#{solution_file}:#{valid? ? "valid" : "invalid"}>"
106
+ end
107
+
108
+ protected
109
+
110
+ # Load the solution file for the plugin path provided
111
+ # if it exists. Validate solution is still applicable
112
+ # before injecting dependencies.
113
+ def load
114
+ if !plugin_file.exist? || !solution_file.exist?
115
+ @logger.debug("missing file so skipping loading")
116
+ return
117
+ end
118
+ solution = read_solution || return
119
+ return if !valid_solution?(
120
+ checksum: solution[:checksum],
121
+ version: solution[:vagrant_version]
122
+ )
123
+ @logger.debug("loading solution dependency list")
124
+ @dependency_list = solution[:dependencies].map do |name, requirements|
125
+ Gem::Dependency.new(name, requirements)
126
+ end
127
+ @logger.debug("solution dependency list: #{dependency_list}")
128
+ @valid = true
129
+ end
130
+
131
+ # Validate the given checksum matches the plugin file
132
+ # checksum
133
+ #
134
+ # @param [String] checksum Checksum value to validate
135
+ # @return [Boolean]
136
+ def valid_solution?(checksum:, version:)
137
+ file_checksum = plugin_file_checksum
138
+ @logger.debug("solution validation check CHECKSUM #{file_checksum} <-> #{checksum}" \
139
+ " VERSION #{Vagrant::VERSION} <-> #{version}")
140
+ plugin_file_checksum == checksum &&
141
+ Vagrant::VERSION == version
142
+ end
143
+
144
+ # @return [String] checksum of plugin file
145
+ def plugin_file_checksum
146
+ digest = Digest::SHA256.new
147
+ digest.file(plugin_file.to_s)
148
+ digest.hexdigest
149
+ end
150
+
151
+ # Read contents of solution file and parse
152
+ #
153
+ # @return [Hash]
154
+ def read_solution
155
+ @logger.debug("reading solution file - #{solution_file}")
156
+ begin
157
+ hash = JSON.load(solution_file.read)
158
+ Vagrant::Util::HashWithIndifferentAccess.new(hash)
159
+ rescue => err
160
+ @logger.warn("failed to load solution file, ignoring (error: #{err})")
161
+ end
162
+ end
163
+ end
21
164
 
22
165
  # Location of HashiCorp gem repository
23
166
  HASHICORP_GEMSTORE = "https://gems.hashicorp.com/".freeze
@@ -34,26 +177,16 @@ module Vagrant
34
177
 
35
178
  # @return [Pathname] Global plugin path
36
179
  attr_reader :plugin_gem_path
180
+ # @return [Pathname] Global plugin solution set path
181
+ attr_reader :plugin_solution_path
37
182
  # @return [Pathname] Vagrant environment specific plugin path
38
183
  attr_reader :env_plugin_gem_path
184
+ # @return [Pathname] Vagrant environment data path
185
+ attr_reader :environment_data_path
39
186
 
40
187
  def initialize
41
188
  @plugin_gem_path = Vagrant.user_data_path.join("gems", RUBY_VERSION).freeze
42
189
  @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
190
  end
58
191
 
59
192
  # Enable Vagrant environment specific plugins at given data path
@@ -61,12 +194,39 @@ module Vagrant
61
194
  # @param [Pathname] Path to Vagrant::Environment data directory
62
195
  # @return [Pathname] Path to environment specific gem directory
63
196
  def environment_path=(env_data_path)
197
+ if !env_data_path.is_a?(Pathname)
198
+ raise TypeError, "Expected `Pathname` but received `#{env_data_path.class}`"
199
+ end
64
200
  @env_plugin_gem_path = env_data_path.join("plugins", "gems", RUBY_VERSION).freeze
201
+ @environment_data_path = env_data_path
202
+ end
203
+
204
+ # Use the given options to create a solution file instance
205
+ # for use during initialization. When a Vagrant environment
206
+ # is in use, solution files will be stored within the environment's
207
+ # data directory. This is because the solution for loading global
208
+ # plugins is dependent on any solution generated for local plugins.
209
+ # When no Vagrant environment is in use (running Vagrant without a
210
+ # Vagrantfile), the Vagrant user data path will be used for solution
211
+ # storage since only the global plugins will be used.
212
+ #
213
+ # @param [Hash] opts Options passed to #init!
214
+ # @return [SolutionFile]
215
+ def load_solution_file(opts={})
216
+ return if !opts[:local] && !opts[:global]
217
+ return if opts[:local] && opts[:global]
218
+ return if opts[:local] && environment_data_path.nil?
219
+ solution_path = (environment_data_path || Vagrant.user_data_path) + "bundler"
220
+ solution_path += opts[:local] ? "local.sol" : "global.sol"
221
+ SolutionFile.new(
222
+ plugin_file: opts[:local] || opts[:global],
223
+ solution_file: solution_path
224
+ )
65
225
  end
66
226
 
67
227
  # Initializes Bundler and the various gem paths so that we can begin
68
228
  # loading gems.
69
- def init!(plugins, repair=false)
229
+ def init!(plugins, repair=false, **opts)
70
230
  if !@initial_specifications
71
231
  @initial_specifications = Gem::Specification.find_all{true}
72
232
  else
@@ -74,45 +234,78 @@ module Vagrant
74
234
  Gem::Specification.reset
75
235
  end
76
236
 
77
- # Add HashiCorp RubyGems source
78
- if !Gem.sources.include?(HASHICORP_GEMSTORE)
79
- sources = [HASHICORP_GEMSTORE] + Gem.sources.sources
80
- Gem.sources.replace(sources)
81
- end
237
+ solution_file = load_solution_file(opts)
238
+ @logger.debug("solution file in use for init: #{solution_file}")
82
239
 
83
- # Generate dependencies for all registered plugins
84
- plugin_deps = plugins.map do |name, info|
85
- Gem::Dependency.new(name, info['installed_gem_version'].to_s.empty? ? '> 0' : info['installed_gem_version'])
240
+ solution = nil
241
+ composed_set = generate_vagrant_set
242
+
243
+ if solution_file&.valid?
244
+ @logger.debug("loading cached solution set")
245
+ solution = solution_file.dependency_list.map do |dep|
246
+ spec = composed_set.find_all(dep).first
247
+ if !spec
248
+ @logger.warn("failed to locate specification for dependency - #{dep}")
249
+ @logger.warn("invalidating solution file - #{solution_file}")
250
+ solution_file.invalidate!
251
+ break
252
+ end
253
+ dep_r = Gem::Resolver::DependencyRequest.new(dep, nil)
254
+ Gem::Resolver::ActivationRequest.new(spec, dep_r)
255
+ end
86
256
  end
87
257
 
88
- @logger.debug("Current generated plugin dependency list: #{plugin_deps}")
258
+ if !solution_file&.valid?
259
+ @logger.debug("generating solution set for configured plugins")
260
+ # Add HashiCorp RubyGems source
261
+ if !Gem.sources.include?(HASHICORP_GEMSTORE)
262
+ sources = [HASHICORP_GEMSTORE] + Gem.sources.sources
263
+ Gem.sources.replace(sources)
264
+ end
89
265
 
90
- # Load dependencies into a request set for resolution
91
- request_set = Gem::RequestSet.new(*plugin_deps)
92
- # Never allow dependencies to be remotely satisfied during init
93
- request_set.remote = false
266
+ # Generate dependencies for all registered plugins
267
+ plugin_deps = plugins.map do |name, info|
268
+ Gem::Dependency.new(name, info['installed_gem_version'].to_s.empty? ? '> 0' : info['installed_gem_version'])
269
+ end
94
270
 
95
- repair_result = nil
96
- begin
97
- # Compose set for resolution
98
- composed_set = generate_vagrant_set
99
- # Resolve the request set to ensure proper activation order
100
- solution = request_set.resolve(composed_set)
101
- rescue Gem::UnsatisfiableDependencyError => failure
102
- if repair
103
- raise failure if @init_retried
104
- @logger.debug("Resolution failed but attempting to repair. Failure: #{failure}")
105
- install(plugins)
106
- @init_retried = true
107
- retry
108
- else
109
- raise
271
+ @logger.debug("Current generated plugin dependency list: #{plugin_deps}")
272
+
273
+ # Load dependencies into a request set for resolution
274
+ request_set = Gem::RequestSet.new(*plugin_deps)
275
+ # Never allow dependencies to be remotely satisfied during init
276
+ request_set.remote = false
277
+
278
+ repair_result = nil
279
+ begin
280
+ @logger.debug("resolving solution from available specification set")
281
+ # Resolve the request set to ensure proper activation order
282
+ solution = request_set.resolve(composed_set)
283
+ @logger.debug("solution set for configured plugins has been resolved")
284
+ rescue Gem::UnsatisfiableDependencyError => failure
285
+ if repair
286
+ raise failure if @init_retried
287
+ @logger.debug("Resolution failed but attempting to repair. Failure: #{failure}")
288
+ install(plugins)
289
+ @init_retried = true
290
+ retry
291
+ else
292
+ raise
293
+ end
110
294
  end
111
295
  end
112
296
 
113
297
  # Activate the gems
298
+ @logger.debug("activating solution set")
114
299
  activate_solution(solution)
115
300
 
301
+ if solution_file && !solution_file.valid?
302
+ solution_file.dependency_list = solution.map do |activation|
303
+ activation.request.dependency
304
+ end
305
+ solution_file.store!
306
+ @logger.debug("solution set stored to - #{solution_file}")
307
+ end
308
+
116
309
  full_vagrant_spec_list = @initial_specifications +
117
310
  solution.map(&:full_spec)
118
311
 
@@ -287,7 +480,7 @@ module Vagrant
287
480
  if update[:gems] == true || (update[:gems].respond_to?(:include?) && update[:gems].include?(name))
288
481
  if Gem::Requirement.new(gem_version).exact?
289
482
  gem_version = "> 0"
290
- @logger.debug("Detected exact version match for `#{name}` plugin update. Reset to loose constraint #{gem_version.inspect}.")
483
+ @logger.debug("Detected exact version match for `#{name}` plugin update. Reset to loosen constraint #{gem_version.inspect}.")
291
484
  end
292
485
  skips << name
293
486
  end
@@ -357,6 +550,7 @@ module Vagrant
357
550
 
358
551
  # Create the request set for the new plugins
359
552
  request_set = Gem::RequestSet.new(*plugin_deps)
553
+ request_set.prerelease = Vagrant.prerelease?
360
554
 
361
555
  installer_set = Gem::Resolver.compose_sets(
362
556
  installer_set,
@@ -367,13 +561,14 @@ module Vagrant
367
561
 
368
562
  # Generate the required solution set for new plugins
369
563
  solution = request_set.resolve(installer_set)
564
+
370
565
  activate_solution(solution)
371
566
 
372
567
  # Remove gems which are already installed
373
- request_set.sorted_requests.delete_if do |activation_req|
374
- rs_spec = activation_req.spec
375
- if vagrant_internal_specs.detect{|ispec| ispec.name == rs_spec.name && ispec.version == rs_spec.version }
376
- @logger.debug("Removing activation request from install. Already installed. (#{rs_spec.spec.full_name})")
568
+ request_set.sorted_requests.delete_if do |act_req|
569
+ rs = act_req.spec
570
+ if vagrant_internal_specs.detect{ |i| i.name == rs.name && i.version == rs.version }
571
+ @logger.debug("Removing activation request from install. Already installed. (#{rs.spec.full_name})")
377
572
  true
378
573
  end
379
574
  end
@@ -388,8 +583,10 @@ module Vagrant
388
583
  result = request_set.install_into(install_path.to_s, true,
389
584
  ignore_dependencies: true,
390
585
  prerelease: Vagrant.prerelease?,
391
- wrappers: true
586
+ wrappers: true,
587
+ document: []
392
588
  )
589
+
393
590
  result = result.map(&:full_spec)
394
591
  result.each do |spec|
395
592
  existing_paths = $LOAD_PATH.find_all{|s| s.include?(spec.full_name) }
@@ -421,15 +618,25 @@ module Vagrant
421
618
  def vagrant_internal_specs
422
619
  # activate any dependencies up front so we can always
423
620
  # pin them when resolving
424
- Gem::Specification.find { |s| s.name == "vagrant" && s.activated? }.
425
- runtime_dependencies.each { |d| gem d.name, *d.requirement.as_list }
621
+ self_spec = Gem::Specification.find { |s| s.name == "vagrant-unbundled" && s.activated? }
622
+ if !self_spec
623
+ @logger.warn("Failed to locate activated vagrant specification. Activating...")
624
+ self_spec = Gem::Specification.find { |s| s.name == "vagrant-unbundled" }
625
+ if !self_spec
626
+ @logger.error("Failed to locate Vagrant RubyGem specification")
627
+ raise Vagrant::Errors::SourceSpecNotFound
628
+ end
629
+ self_spec.activate
630
+ @logger.info("Activated vagrant specification version - #{self_spec.version}")
631
+ end
632
+ self_spec.runtime_dependencies.each { |d| gem d.name, *d.requirement.as_list }
426
633
  # discover all the gems we have available
427
634
  list = {}
428
635
  directories = [Gem::Specification.default_specifications_dir]
429
636
  Gem::Specification.find_all{true}.each do |spec|
430
637
  list[spec.full_name] = spec
431
638
  end
432
- if(!defined?(::Bundler))
639
+ if(!Object.const_defined?(:Bundler))
433
640
  directories += Gem::Specification.dirs.find_all do |path|
434
641
  !path.start_with?(Gem.user_dir)
435
642
  end
@@ -601,7 +808,7 @@ module Vagrant
601
808
 
602
809
  def find_all(req)
603
810
  @specs.select do |spec|
604
- allow_prerelease = spec.name == "vagrant" && Vagrant.prerelease?
811
+ allow_prerelease = spec.name == "vagrant-unbundled" && Vagrant.prerelease?
605
812
  req.match?(spec, allow_prerelease)
606
813
  end.map do |spec|
607
814
  Gem::Resolver::InstalledSpecification.new(self, spec)