From b375e4d5b6ffb5565824afaf3aa729ba15f710f7 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Tue, 5 Nov 2024 16:02:51 -0800 Subject: [PATCH] Remove activation at startup, add helper This removes the gem activation from the startup and adds a helper for properly activating gems based on the defined runtime constraints of the vagrant specification at loading time. --- bin/vagrant | 11 ---- lib/vagrant/shared_helpers.rb | 66 ++++++++++++++++++- .../linux/cap/mount_smb_shared_folder_test.rb | 1 + 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/bin/vagrant b/bin/vagrant index aad4c0436ef..198078b2ced 100755 --- a/bin/vagrant +++ b/bin/vagrant @@ -10,16 +10,6 @@ if Thread.respond_to?(:report_on_exception=) Thread.report_on_exception = false end -# Activate all the runtime dependencies before -# moving on. -begin - Gem::Specification.find_by_name("vagrant").runtime_dependencies.each do |dep| - gem(dep.name, dep.requirement.as_list) - end -rescue Gem::MissingSpecError - $stderr.puts "WARN: Failed to locate vagrant specification for dependency loading" -end - # Split arguments by "--" if its there, we'll recombine them later argv = ARGV.dup argv_extra = [] @@ -117,7 +107,6 @@ end env = nil begin - require 'log4r' require 'vagrant' require 'vagrant/bundler' require 'vagrant/cli' diff --git a/lib/vagrant/shared_helpers.rb b/lib/vagrant/shared_helpers.rb index 45ebff2e0f4..be0baa31323 100644 --- a/lib/vagrant/shared_helpers.rb +++ b/lib/vagrant/shared_helpers.rb @@ -168,7 +168,7 @@ def self.enable_resolv_replace if ENV["VAGRANT_ENABLE_RESOLV_REPLACE"] if !ENV["VAGRANT_DISABLE_RESOLV_REPLACE"] begin - require "resolv-replace" + Vagrant.require "resolv-replace" true rescue false @@ -192,7 +192,7 @@ def self.global_logger=(log) # @return [Logger] def self.global_logger if @_global_logger.nil? - require "log4r" + Vagrant.require "log4r" @_global_logger = Log4r::Logger.new("vagrant::global") end @_global_logger @@ -226,6 +226,68 @@ def self.default_cli_options @_default_cli_options.dup end + # Loads the provided path. If the base of the path + # is a Vagrant runtime dependency, the gem will be + # activated with the proper constraint first. + # + # NOTE: This is currently disabled by default and + # will transition to enabled by default as more + # non-installer based environments are tested. + # + # @return [nil] + def self.require(path) + catch(:activation_complete) do + # If activation is not enabled, don't attempt activation + throw :activation_complete if ENV["VAGRANT_ENABLE_GEM_ACTIVATION"].nil? + + # If it's a vagrant path, don't do anything. + throw :activation_complete if path.to_s.start_with?("vagrant/") + + # Attempt to fetch the vagrant specification + if @_vagrant_spec.nil? + @_vagrant_activated_dependencies = {} + begin + @_vagrant_spec = Gem::Specification.find_by_name("vagrant") + rescue Gem::MissingSpecError + # If it couldn't be found, print a warning to stderr and bail + if !@_spec_load_failure_warning + $stderr.puts "WARN: Failed to locate vagrant specification for dependency loading" + @_spec_load_failure_warning = true + end + + throw :activation_complete + end + end + + # Attempt to get the name of the gem by the given path + dep_name = Gem::Specification.find_by_path(path)&.name + + # Bail if a dependency name cannot be determined + throw :activation_complete if dep_name.nil? + + # Bail if already activated + throw :activation_complete if @_vagrant_activated_dependencies[dep_name] + + # Extract the dependency from the runtime dependency list + dependency = @_vagrant_spec.runtime_dependencies.detect do |d| + d.name == dep_name + end + + # If the dependency isn't found, bail + throw :activation_complete if dependency.nil? + + # Activate the gem + gem(dependency.name, dependency.requirement.as_list) +puts "Activated: #{dependency.name}" + @_vagrant_activated_dependencies[dependency.name] = true + end + + # Finally, require the provided path. + ::Kernel.require(path) + + nil + end + # Check if Vagrant is running in server mode # # @return [Boolean] diff --git a/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder_test.rb b/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder_test.rb index 467cb863889..1c5e03a39b5 100644 --- a/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder_test.rb +++ b/test/unit/plugins/guests/linux/cap/mount_smb_shared_folder_test.rb @@ -59,6 +59,7 @@ allow(comm).to receive(:execute).with(any_args) allow(machine).to receive(:guest).and_return(guest) allow(guest).to receive(:capability).with(:shell_expand_guest_path, mount_guest_path).and_return(mount_guest_path) + allow(ENV).to receive(:[]).and_call_original allow(ENV).to receive(:[]).with("VAGRANT_DISABLE_SMBMFSYMLINKS").and_return(false) allow(ENV).to receive(:[]).with("GEM_SKIP").and_return(false) allow(cap).to receive(:display_mfsymlinks_warning)