vagrant-unbundled 2.0.4.0 → 2.1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/Gemfile.lock +2 -2
  4. data/bin/vagrant +5 -0
  5. data/lib/vagrant/action/builtin/box_check_outdated.rb +3 -0
  6. data/lib/vagrant/errors.rb +16 -4
  7. data/lib/vagrant/machine.rb +13 -1
  8. data/lib/vagrant/plugin/v2/command.rb +1 -1
  9. data/lib/vagrant/plugin/v2/trigger.rb +242 -0
  10. data/lib/vagrant/plugin/v2.rb +1 -0
  11. data/lib/vagrant/util/downloader.rb +15 -5
  12. data/lib/vagrant/util/platform.rb +7 -4
  13. data/lib/vagrant/util/powershell.rb +21 -0
  14. data/lib/vagrant/vagrantfile.rb +14 -1
  15. data/plugins/commands/login/middleware/add_authentication.rb +10 -4
  16. data/plugins/communicators/ssh/communicator.rb +7 -2
  17. data/plugins/communicators/winrm/command_filters/rm.rb +2 -2
  18. data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +25 -10
  19. data/plugins/hosts/linux/cap/rdp.rb +16 -1
  20. data/plugins/hosts/windows/cap/smb.rb +46 -2
  21. data/plugins/hosts/windows/plugin.rb +1 -1
  22. data/plugins/kernel_v2/config/trigger.rb +201 -0
  23. data/plugins/kernel_v2/config/vm_trigger.rb +204 -0
  24. data/plugins/kernel_v2/plugin.rb +24 -0
  25. data/plugins/providers/docker/command/exec.rb +14 -9
  26. data/plugins/providers/hyperv/action/import.rb +6 -6
  27. data/plugins/providers/hyperv/scripts/get_network_config.ps1 +35 -21
  28. data/plugins/providers/hyperv/scripts/get_switches.ps1 +1 -1
  29. data/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +4 -2
  30. data/plugins/providers/virtualbox/driver/base.rb +12 -1
  31. data/plugins/provisioners/chef/provisioner/chef_solo.rb +4 -3
  32. data/plugins/provisioners/chef/provisioner/chef_zero.rb +1 -1
  33. data/plugins/provisioners/docker/cap/windows/docker_daemon_running.rb +13 -0
  34. data/plugins/provisioners/docker/client.rb +2 -5
  35. data/plugins/provisioners/docker/plugin.rb +5 -0
  36. data/plugins/provisioners/puppet/config/puppet.rb +1 -0
  37. data/templates/locales/en.yml +73 -10
  38. data/vendor/bundle/ruby/2.5.0/bundler/gems/vagrant-spec-f3daedaac493/vagrant-spec.gemspec +1 -1
  39. data/version.txt +1 -1
  40. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f05389ae1ff4023e08b4a240e16afc13f24fb766254196f09ce91cf0f0c70b4
4
- data.tar.gz: e76853469f4db645991f1b98bebca28cffc1cbfbe4d29f4c11033dc1e1099ce4
3
+ metadata.gz: 7b7d6c7467de5bfab5f4e3503f8cc1dab8ef0917a3373c3c42bda4519e86c0f3
4
+ data.tar.gz: c7912ae83539b93705099b5daad5481f247ed8b8abc9bee8ef996c8ccd58cb79
5
5
  SHA512:
6
- metadata.gz: 499aa7f81c240e7b9e313ffc2dc2f6c9d85a8d0b06d8582e16fb05e5b6b762a56b35ba3c738bfb506fb7f085048a4c239dd47861b25cd1c949d214618e68e43a
7
- data.tar.gz: e1dede9125879c569429a21d1c4f698f2d13c8cbad9bc84616a5a784ddfb30dce10ade705bbc1a0bf408fbe2ea23ae97ede54b44de71c942b4f1c8c1c004a131
6
+ metadata.gz: b0374c64f53956fff0665b76baf2ff155f299b60d87664b7eb6d9f7cbae9fb53b6e1cd3f1a02d04a98555de4a4e708d70b21ea12a31a7c0a8530d050be6c9000
7
+ data.tar.gz: 8be3443a6d1a51a4f8c7ddd86aeb6deb839dfe5f63dde7fe209a6dcd9c5ab2884fe2ebc193d2d3706702a3a0d22d2af1253294eb9f8a72921c31d0e9f875be09
data/CHANGELOG.md CHANGED
@@ -1,3 +1,46 @@
1
+ ## 2.1.1 (May 7, 2018)
2
+
3
+ IMPROVEMENTS:
4
+
5
+ - guest/linux: Support builtin vboxsf module for shared folders [GH-9800]
6
+ - host/windows: Update SMB capability to work without Get-SmbShare cmdlet [GH-9785]
7
+
8
+ BUG FIXES:
9
+
10
+ - core/triggers: Initialize internal trigger object for machine before initializing provider [GH-9784]
11
+ - core/triggers: Ensure internal trigger fire does not get called if plugin installed [GH-9799]
12
+ - provider/hyperv: Call import script with switchid instead of switchname [GH-9781]
13
+
14
+ ## 2.1.0 (May 3, 2018)
15
+
16
+ FEATURES:
17
+
18
+ - core: Integrate vagrant-triggers plugin functionality into core Vagrant [GH-9713]
19
+
20
+ IMPROVEMENTS:
21
+
22
+ - core: Improve messaging around not finding requested provider [GH-9735]
23
+ - core: Disable exception reports by default [GH-9738]
24
+ - core: Continue on if vagrant fails to parse metadata box for update [GH-9760]
25
+ - hosts/linux: Support RDP capability within WSL [GH-9758]
26
+ - hosts/windows: Add SMB default mount options capability and set default version to 2.0 [GH-9734]
27
+ - provider/hyperv: Include neighbor check for MAC on guest IP detection [GH-9737]
28
+ - provider/virtualbox: Do not require VirtualBox availability within WSL [GH-9759]
29
+ - provisioner/chef_zero: Support arrays for data_bags_path [GH-9669]
30
+ - util/downloader: Don't raise error if response is HTTP 416 [GH-9729]
31
+ - util/platform: Update Hyper-V enabled check [GH-9746]
32
+
33
+ BUG FIXES:
34
+
35
+ - communicators/ssh: Log error and proceed on Windows private key permissions [GH-9769]
36
+ - middleware/authentication: Prevent URL modification when no changes are required [GH-9730]
37
+ - middleware/authentication: Ignore URLs which cannot be parsed [GH-9739]
38
+ - provider/hyperv: Reference switches by ID instead of name [GH-9747]
39
+ - provider/docker: Use Util::SafeExec if docker-exec is run with `-t` option [GH-9761]
40
+ - provisioner/chef: Trim drive letter from path on Windows [GH-9766]
41
+ - provisioner/puppet: Properly finalize structured_facts config option [GH-9720]
42
+ - util/platform: Fix original WSL to Windows path for "root" directory [GH-9696]
43
+
1
44
  ## 2.0.4 (April 20, 2018)
2
45
 
3
46
  FEATURES:
data/Gemfile.lock CHANGED
@@ -11,7 +11,7 @@ GIT
11
11
  PATH
12
12
  remote: .
13
13
  specs:
14
- vagrant-unbundled (2.0.4.0)
14
+ vagrant-unbundled (2.1.1.0)
15
15
  childprocess (~> 0.6.0)
16
16
  erubis (~> 2.7.0)
17
17
  hashicorp-checkpoint (~> 0.1.5)
@@ -160,4 +160,4 @@ DEPENDENCIES
160
160
  webmock (~> 2.3.1)
161
161
 
162
162
  BUNDLED WITH
163
- 1.16.1
163
+ 1.16.2
data/bin/vagrant CHANGED
@@ -5,6 +5,11 @@
5
5
  # initializing which have historically resulted in stack traces.
6
6
  Signal.trap("INT") { abort }
7
7
 
8
+ # Disable exception reporting by default if available
9
+ if Thread.respond_to?(:report_on_exception=)
10
+ Thread.report_on_exception = false
11
+ end
12
+
8
13
  # Split arguments by "--" if its there, we'll recombine them later
9
14
  argv = ARGV.dup
10
15
  argv_extra = []
@@ -58,6 +58,9 @@ module Vagrant
58
58
  env[:ui].warn(I18n.t(
59
59
  "vagrant.box_outdated_metadata_download_error",
60
60
  message: e.extra_data[:message]))
61
+ rescue Errors::BoxMetadataMalformed => e
62
+ @logger.warn(e.to_s)
63
+ env[:ui].warn(I18n.t("vagrant.box_malformed_continue_on_update"))
61
64
  rescue Errors::VagrantError => e
62
65
  raise if !env[:box_outdated_ignore_errors]
63
66
  env[:ui].detail(I18n.t(
@@ -580,6 +580,10 @@ module Vagrant
580
580
  error_key(:provider_not_found)
581
581
  end
582
582
 
583
+ class ProviderNotFoundSuggestion < VagrantError
584
+ error_key(:provider_not_found_suggestion)
585
+ end
586
+
583
587
  class ProviderNotUsable < VagrantError
584
588
  error_key(:provider_not_usable)
585
589
  end
@@ -776,6 +780,18 @@ module Vagrant
776
780
  error_key(:synced_folder_unusable)
777
781
  end
778
782
 
783
+ class TriggersGuestNotRunning < VagrantError
784
+ error_key(:triggers_guest_not_running)
785
+ end
786
+
787
+ class TriggersNoBlockGiven < VagrantError
788
+ error_key(:triggers_no_block_given)
789
+ end
790
+
791
+ class TriggersNoStageGiven < VagrantError
792
+ error_key(:triggers_no_stage_given)
793
+ end
794
+
779
795
  class UIExpectsTTY < VagrantError
780
796
  error_key(:ui_expects_tty)
781
797
  end
@@ -828,10 +844,6 @@ module Vagrant
828
844
  error_key(:vboxmanage_not_found_error)
829
845
  end
830
846
 
831
- class VBoxManageNotFoundWSLError < VagrantError
832
- error_key(:vboxmanage_not_found_wsl_error)
833
- end
834
-
835
847
  class VirtualBoxBrokenVersion040214 < VagrantError
836
848
  error_key(:virtualbox_broken_version_040214)
837
849
  end
@@ -110,6 +110,7 @@ module Vagrant
110
110
  @ui = Vagrant::UI::Prefixed.new(@env.ui, @name)
111
111
  @ui_mutex = Mutex.new
112
112
  @state_mutex = Mutex.new
113
+ @triggers = Vagrant::Plugin::V2::Trigger.new(@env, @config.trigger, self)
113
114
 
114
115
  # Read the ID, which is usually in local storage
115
116
  @id = nil
@@ -159,6 +160,11 @@ module Vagrant
159
160
  # as extra data set on the environment hash for the middleware
160
161
  # runner.
161
162
  def action(name, opts=nil)
163
+ plugins = Vagrant::Plugin::Manager.instance.installed_plugins
164
+ if !plugins.keys.include?("vagrant-triggers")
165
+ @triggers.fire_triggers(name, :before, @name.to_s)
166
+ end
167
+
162
168
  @logger.info("Calling action: #{name} on provider #{@provider}")
163
169
 
164
170
  opts ||= {}
@@ -185,7 +191,7 @@ module Vagrant
185
191
  locker = @env.method(:lock) if lock && !name.to_s.start_with?("ssh")
186
192
 
187
193
  # Lock this machine for the duration of this action
188
- locker.call("machine-action-#{id}") do
194
+ return_env = locker.call("machine-action-#{id}") do
189
195
  # Get the callable from the provider.
190
196
  callable = @provider.action(name)
191
197
 
@@ -203,6 +209,12 @@ module Vagrant
203
209
  ui.machine("action", name.to_s, "end")
204
210
  action_result
205
211
  end
212
+
213
+ if !plugins.keys.include?("vagrant-triggers")
214
+ @triggers.fire_triggers(name, :after, @name.to_s)
215
+ end
216
+ # preserve returning environment after machine action runs
217
+ return return_env
206
218
  rescue Errors::EnvironmentLockedError
207
219
  raise Errors::MachineActionLockedError,
208
220
  action: name,
@@ -45,7 +45,7 @@ module Vagrant
45
45
  def parse_options(opts=nil)
46
46
  # make sure optparse doesn't use POSIXLY_CORRECT parsing
47
47
  ENV["POSIXLY_CORRECT"] = nil
48
-
48
+
49
49
  # Creating a shallow copy of the arguments so the OptionParser
50
50
  # doesn't destroy the originals.
51
51
  argv = @argv.dup
@@ -0,0 +1,242 @@
1
+ require 'fileutils'
2
+ require 'log4r'
3
+ require 'shellwords'
4
+
5
+ require Vagrant.source_root.join("plugins/provisioners/shell/provisioner")
6
+ require "vagrant/util/subprocess"
7
+ require "vagrant/util/platform"
8
+ require "vagrant/util/powershell"
9
+
10
+ module Vagrant
11
+ module Plugin
12
+ module V2
13
+ class Trigger
14
+ # @return [Kernel_V2::Config::Trigger]
15
+ attr_reader :config
16
+
17
+ # This class is responsible for setting up basic triggers that were
18
+ # defined inside a Vagrantfile.
19
+ #
20
+ # @param [Vagrant::Environment] env Vagrant environment
21
+ # @param [Kernel_V2::TriggerConfig] config Trigger configuration
22
+ # @param [Vagrant::Machine] machine Active Machine
23
+ def initialize(env, config, machine)
24
+ @env = env
25
+ @config = config
26
+ @machine = machine
27
+
28
+ @logger = Log4r::Logger.new("vagrant::trigger::#{self.class.to_s.downcase}")
29
+ end
30
+
31
+ # Fires all triggers, if any are defined for the action and guest
32
+ #
33
+ # @param [Symbol] action Vagrant command to fire trigger on
34
+ # @param [Symbol] stage :before or :after
35
+ # @param [String] guest_name The guest that invoked firing the triggers
36
+ def fire_triggers(action, stage, guest_name)
37
+ # get all triggers matching action
38
+ triggers = []
39
+ if stage == :before
40
+ triggers = config.before_triggers.select do |t|
41
+ t.command == action || (t.command == :all && !t.ignore.include?(action))
42
+ end
43
+ elsif stage == :after
44
+ triggers = config.after_triggers.select do |t|
45
+ t.command == action || (t.command == :all && !t.ignore.include?(action))
46
+ end
47
+ else
48
+ raise Errors::TriggersNoStageGiven,
49
+ action: action,
50
+ stage: stage,
51
+ guest_name: guest_name
52
+ end
53
+
54
+ triggers = filter_triggers(triggers, guest_name)
55
+
56
+ if !triggers.empty?
57
+ @logger.info("Firing trigger for action #{action} on guest #{guest_name}")
58
+ @machine.ui.info(I18n.t("vagrant.trigger.start", stage: stage, action: action))
59
+ fire(triggers, guest_name)
60
+ end
61
+ end
62
+
63
+ protected
64
+
65
+ #-------------------------------------------------------------------
66
+ # Internal methods, don't call these.
67
+ #-------------------------------------------------------------------
68
+
69
+ # Filters triggers to be fired based on configured restraints
70
+ #
71
+ # @param [Array] triggers An array of triggers to be filtered
72
+ # @param [String] guest_name The name of the current guest
73
+ # @return [Array] The filtered array of triggers
74
+ def filter_triggers(triggers, guest_name)
75
+ # look for only_on trigger constraint and if it doesn't match guest
76
+ # name, throw it away also be sure to preserve order
77
+ filter = triggers.dup
78
+
79
+ filter.each do |trigger|
80
+ index = nil
81
+ match = false
82
+ if trigger.only_on
83
+ trigger.only_on.each do |o|
84
+ if o.match(guest_name)
85
+ # trigger matches on current guest, so we're fine to use it
86
+ match = true
87
+ break
88
+ end
89
+ end
90
+ # no matches found, so don't use trigger for guest
91
+ index = triggers.index(trigger) unless match == true
92
+ end
93
+
94
+ if index
95
+ @logger.debug("Trigger #{trigger.id} will be ignored for #{guest_name}")
96
+ triggers.delete_at(index)
97
+ end
98
+ end
99
+
100
+ return triggers
101
+ end
102
+
103
+ # Fires off all triggers in the given array
104
+ #
105
+ # @param [Array] triggers An array of triggers to be fired
106
+ def fire(triggers, guest_name)
107
+ # ensure on_error is respected by exiting or continuing
108
+
109
+ triggers.each do |trigger|
110
+ @logger.debug("Running trigger #{trigger.id}...")
111
+
112
+ if trigger.name
113
+ @machine.ui.info(I18n.t("vagrant.trigger.fire_with_name",
114
+ name: trigger.name))
115
+ else
116
+ @machine.ui.info(I18n.t("vagrant.trigger.fire"))
117
+ end
118
+
119
+ if trigger.info
120
+ info(trigger.info)
121
+ end
122
+
123
+ if trigger.warn
124
+ warn(trigger.warn)
125
+ end
126
+
127
+ if trigger.run
128
+ run(trigger.run, trigger.on_error)
129
+ end
130
+
131
+ if trigger.run_remote
132
+ run_remote(trigger.run_remote, trigger.on_error)
133
+ end
134
+ end
135
+ end
136
+
137
+ # Prints the given message at info level for a trigger
138
+ #
139
+ # @param [String] message The string to be printed
140
+ def info(message)
141
+ @machine.ui.info(message)
142
+ end
143
+
144
+ # Prints the given message at warn level for a trigger
145
+ #
146
+ # @param [String] message The string to be printed
147
+ def warn(message)
148
+ @machine.ui.warn(message)
149
+ end
150
+
151
+ # Runs a script on a guest
152
+ #
153
+ # @param [Provisioners::Shell::Config] config A Shell provisioner config
154
+ def run(config, on_error)
155
+ if config.inline
156
+ cmd = Shellwords.split(config.inline)
157
+
158
+ @machine.ui.detail(I18n.t("vagrant.trigger.run.inline", command: config.inline))
159
+ else
160
+ cmd = File.expand_path(config.path, @env.root_path)
161
+ cmd << " #{config.args.join(' ' )}" if config.args
162
+ cmd = Shellwords.split(cmd)
163
+
164
+ @machine.ui.detail(I18n.t("vagrant.trigger.run.script", path: config.path))
165
+ end
166
+
167
+ # Pick an execution method to run the script or inline string with
168
+ # Default to Subprocess::Execute
169
+ exec_method = Vagrant::Util::Subprocess.method(:execute)
170
+
171
+ if Vagrant::Util::Platform.windows?
172
+ if config.inline
173
+ exec_method = Vagrant::Util::PowerShell.method(:execute_inline)
174
+ else
175
+ exec_method = Vagrant::Util::PowerShell.method(:execute)
176
+ end
177
+ end
178
+
179
+ begin
180
+ result = exec_method.call(*cmd, :notify => [:stdout, :stderr]) do |type,data|
181
+ options = {}
182
+ case type
183
+ when :stdout
184
+ options[:color] = :green if !config.keep_color
185
+ when :stderr
186
+ options[:color] = :red if !config.keep_color
187
+ end
188
+
189
+ @machine.ui.detail(data, options)
190
+ end
191
+ rescue => e
192
+ @machine.ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
193
+ @machine.ui.error(e.message)
194
+
195
+ if on_error == :halt
196
+ @logger.debug("Trigger run encountered an error. Halting on error...")
197
+ raise e
198
+ else
199
+ @logger.debug("Trigger run encountered an error. Continuing on anyway...")
200
+ @machine.ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
201
+ end
202
+ end
203
+ end
204
+
205
+ # Runs a script on the guest
206
+ #
207
+ # @param [ShellProvisioner/Config] config A Shell provisioner config
208
+ def run_remote(config, on_error)
209
+ unless @machine.state.id == :running
210
+ if on_error == :halt
211
+ raise Errors::TriggersGuestNotRunning,
212
+ machine_name: @machine.name,
213
+ state: @machine.state.id
214
+ else
215
+ @machine.ui.error(I18n.t("vagrant.errors.triggers_guest_not_running",
216
+ machine_name: @machine.name,
217
+ state: @machine.state.id))
218
+ @machine.ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
219
+ return
220
+ end
221
+ end
222
+
223
+ prov = VagrantPlugins::Shell::Provisioner.new(@machine, config)
224
+
225
+ begin
226
+ prov.provision
227
+ rescue => e
228
+ @machine.ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
229
+
230
+ if on_error == :halt
231
+ @logger.debug("Trigger run encountered an error. Halting on error...")
232
+ raise e
233
+ else
234
+ @logger.debug("Trigger run encountered an error. Continuing on anyway...")
235
+ @machine.ui.error(e.message)
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
@@ -19,6 +19,7 @@ module Vagrant
19
19
  autoload :Push, "vagrant/plugin/v2/push"
20
20
  autoload :Provisioner, "vagrant/plugin/v2/provisioner"
21
21
  autoload :SyncedFolder, "vagrant/plugin/v2/synced_folder"
22
+ autoload :Trigger, "vagrant/plugin/v2/trigger"
22
23
  end
23
24
  end
24
25
  end
@@ -292,11 +292,21 @@ module Vagrant
292
292
  # show an error message.
293
293
  if result.exit_code != 0
294
294
  @logger.warn("Downloader exit code: #{result.exit_code}")
295
- parts = result.stderr.split(/\n*curl:\s+\(\d+\)\s*/, 2)
296
- parts[1] ||= ""
297
- raise Errors::DownloaderError,
298
- code: result.exit_code,
299
- message: parts[1].chomp
295
+ check = result.stderr.match(/\n*curl:\s+\((?<code>\d+)\)\s*(?<error>.*)$/)
296
+ if check && check[:code] == "416"
297
+ # All good actually. 416 means there is no more bytes to download
298
+ @logger.warn("Downloader got a 416, but is likely fine. Continuing on...")
299
+ else
300
+ if !check
301
+ err_msg = result.stderr
302
+ else
303
+ err_msg = check[:error]
304
+ end
305
+
306
+ raise Errors::DownloaderError,
307
+ code: result.exit_code,
308
+ message: err_msg
309
+ end
300
310
  end
301
311
 
302
312
  result
@@ -107,9 +107,12 @@ module Vagrant
107
107
  return @_windows_hyperv_enabled if defined?(@_windows_hyperv_enabled)
108
108
 
109
109
  @_windows_hyperv_enabled = -> {
110
- ps_cmd = "$(Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All -Online).State"
111
- output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
112
- return output == 'Enabled'
110
+ ["Get-WindowsOptionalFeature", "Get-WindowsFeature"].each do |cmd_name|
111
+ ps_cmd = "$(#{cmd_name} -FeatureName Microsoft-Hyper-V-Hypervisor).State"
112
+ output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
113
+ return true if output == "Enabled"
114
+ end
115
+ return false
113
116
  }.call
114
117
 
115
118
  return @_windows_hyperv_enabled
@@ -396,7 +399,7 @@ module Vagrant
396
399
  root_path = wsl_rootfs
397
400
  # lxrun splits home separate so we need to account
398
401
  # for it's specialness here when we build the path
399
- if root_path.end_with?("lxss") && parts.first != "home"
402
+ if root_path.end_with?("lxss") && !(["root", "home"].include?(parts.first))
400
403
  root_path = "#{root_path}\\rootfs"
401
404
  end
402
405
  [root_path, *parts].join("\\")
@@ -87,6 +87,27 @@ module Vagrant
87
87
  return r.stdout.chomp
88
88
  end
89
89
 
90
+ # Execute a powershell command and return a result
91
+ #
92
+ # @param [String] command PowerShell command to execute.
93
+ # @param [Hash] opts A collection of options for subprocess::execute
94
+ # @param [Block] block Ruby block
95
+ def self.execute_inline(*command, **opts, &block)
96
+ validate_install!
97
+ c = [
98
+ executable,
99
+ "-NoLogo",
100
+ "-NoProfile",
101
+ "-NonInteractive",
102
+ "-ExecutionPolicy", "Bypass",
103
+ "-Command",
104
+ command
105
+ ].flatten.compact
106
+ c << opts
107
+
108
+ Subprocess.execute(*c, &block)
109
+ end
110
+
90
111
  # Returns the version of PowerShell that is installed.
91
112
  #
92
113
  # @return [String]
@@ -125,8 +125,21 @@ module Vagrant
125
125
  if provider != nil
126
126
  provider_plugin = Vagrant.plugin("2").manager.providers[provider]
127
127
  if !provider_plugin
128
+ providers = Vagrant.plugin("2").manager.providers.to_hash.keys
129
+ if providers
130
+ providers_str = providers.join(', ')
131
+ else
132
+ providers_str = "N/A"
133
+ end
134
+
135
+ if providers.include? provider.downcase
136
+ raise Errors::ProviderNotFoundSuggestion,
137
+ machine: name, provider: provider,
138
+ suggestion: provider.downcase, providers: providers_str
139
+ end
140
+
128
141
  raise Errors::ProviderNotFound,
129
- machine: name, provider: provider
142
+ machine: name, provider: provider, providers: providers_str
130
143
  end
131
144
 
132
145
  provider_cls = provider_plugin[0]
@@ -35,11 +35,17 @@ module VagrantPlugins
35
35
  token = client.token
36
36
 
37
37
  env[:box_urls].map! do |url|
38
- u = URI.parse(url)
39
- if u.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(u.host)
40
- u.host = TARGET_HOST
38
+ begin
39
+ u = URI.parse(url)
40
+ if u.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(u.host)
41
+ u.host = TARGET_HOST
42
+ u.to_s
43
+ else
44
+ url
45
+ end
46
+ rescue URI::Error
47
+ url
41
48
  end
42
- u.to_s
43
49
  end
44
50
 
45
51
  server_uri = URI.parse(Vagrant.server_url.to_s)
@@ -196,8 +196,13 @@ module VagrantPlugins
196
196
 
197
197
  # Adjust private key file permissions
198
198
  if Vagrant::Util::Platform.windows?
199
- priv_path = @machine.data_dir.join("private_key").to_s
200
- File.set_permissions(priv_path, Etc.getlogin => File::FULL)
199
+ begin
200
+ priv_path = @machine.data_dir.join("private_key").to_s
201
+ File.set_permissions(priv_path, Etc.getlogin => File::FULL)
202
+ rescue => e
203
+ @logger.warn("Error encountered during private key permissions set - " \
204
+ "#{e.class}: #{e.message}")
205
+ end
201
206
  else
202
207
  @machine.data_dir.join("private_key").chmod(0600)
203
208
  end
@@ -31,9 +31,9 @@ module VagrantPlugins
31
31
 
32
32
  ret_cmd = ''
33
33
  if recurse
34
- ret_cmd = "rm \"#{dir}\" -recurse -force"
34
+ ret_cmd = "if (Test-Path \"#{dir}\") {Remove-Item \"#{dir}\" -force -recurse}"
35
35
  else
36
- ret_cmd = "rm \"#{dir}\" -force"
36
+ ret_cmd = "if (Test-Path \"#{dir}\") {Remove-Item \"#{dir}\" -force}"
37
37
  end
38
38
  return ret_cmd
39
39
  end
@@ -11,6 +11,9 @@ module VagrantPlugins
11
11
 
12
12
  @@logger.debug("Mounting #{name} (#{options[:hostpath]} to #{guestpath})")
13
13
 
14
+ builtin_mount_type = "-cit vboxsf"
15
+ addon_mount_type = "-t vboxsf"
16
+
14
17
  mount_options = options.fetch(:mount_options, [])
15
18
  detected_ids = detect_owner_group_ids(machine, guest_path, mount_options, options)
16
19
  mount_uid = detected_ids[:uid]
@@ -19,21 +22,33 @@ module VagrantPlugins
19
22
  mount_options << "uid=#{mount_uid}"
20
23
  mount_options << "gid=#{mount_gid}"
21
24
  mount_options = mount_options.join(',')
22
- mount_command = "mount -t vboxsf -o #{mount_options} #{name} #{guest_path}"
25
+ mount_command = "mount #{addon_mount_type} -o #{mount_options} #{name} #{guest_path}"
23
26
 
24
27
  # Create the guest path if it doesn't exist
25
28
  machine.communicate.sudo("mkdir -p #{guest_path}")
26
29
 
27
- # Attempt to mount the folder. We retry here a few times because
28
- # it can fail early on.
29
30
  stderr = ""
30
- retryable(on: Vagrant::Errors::VirtualBoxMountFailed, tries: 3, sleep: 5) do
31
- machine.communicate.sudo(mount_command,
32
- error_class: Vagrant::Errors::VirtualBoxMountFailed,
33
- error_key: :virtualbox_mount_failed,
34
- command: mount_command,
35
- output: stderr,
36
- ) { |type, data| stderr = data if type == :stderr }
31
+ result = machine.communicate.sudo(mount_command, error_check: false) do |type, data|
32
+ stderr << data if type == :stderr
33
+ end
34
+
35
+ if result != 0
36
+ if stderr.include?("-cit")
37
+ @@logger.info("Detected builtin vboxsf module, modifying mount command")
38
+ mount_command.sub!(addon_mount_type, builtin_mount_type)
39
+ end
40
+
41
+ # Attempt to mount the folder. We retry here a few times because
42
+ # it can fail early on.
43
+ stderr = ""
44
+ retryable(on: Vagrant::Errors::VirtualBoxMountFailed, tries: 3, sleep: 5) do
45
+ machine.communicate.sudo(mount_command,
46
+ error_class: Vagrant::Errors::VirtualBoxMountFailed,
47
+ error_key: :virtualbox_mount_failed,
48
+ command: mount_command,
49
+ output: stderr,
50
+ ) { |type, data| stderr = data if type == :stderr }
51
+ end
37
52
  end
38
53
 
39
54
  # Chown the directory to the proper user. We skip this if the