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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -0
- data/Gemfile.lock +2 -2
- data/bin/vagrant +5 -0
- data/lib/vagrant/action/builtin/box_check_outdated.rb +3 -0
- data/lib/vagrant/errors.rb +16 -4
- data/lib/vagrant/machine.rb +13 -1
- data/lib/vagrant/plugin/v2/command.rb +1 -1
- data/lib/vagrant/plugin/v2/trigger.rb +242 -0
- data/lib/vagrant/plugin/v2.rb +1 -0
- data/lib/vagrant/util/downloader.rb +15 -5
- data/lib/vagrant/util/platform.rb +7 -4
- data/lib/vagrant/util/powershell.rb +21 -0
- data/lib/vagrant/vagrantfile.rb +14 -1
- data/plugins/commands/login/middleware/add_authentication.rb +10 -4
- data/plugins/communicators/ssh/communicator.rb +7 -2
- data/plugins/communicators/winrm/command_filters/rm.rb +2 -2
- data/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb +25 -10
- data/plugins/hosts/linux/cap/rdp.rb +16 -1
- data/plugins/hosts/windows/cap/smb.rb +46 -2
- data/plugins/hosts/windows/plugin.rb +1 -1
- data/plugins/kernel_v2/config/trigger.rb +201 -0
- data/plugins/kernel_v2/config/vm_trigger.rb +204 -0
- data/plugins/kernel_v2/plugin.rb +24 -0
- data/plugins/providers/docker/command/exec.rb +14 -9
- data/plugins/providers/hyperv/action/import.rb +6 -6
- data/plugins/providers/hyperv/scripts/get_network_config.ps1 +35 -21
- data/plugins/providers/hyperv/scripts/get_switches.ps1 +1 -1
- data/plugins/providers/hyperv/scripts/import_vm_vmcx.ps1 +4 -2
- data/plugins/providers/virtualbox/driver/base.rb +12 -1
- data/plugins/provisioners/chef/provisioner/chef_solo.rb +4 -3
- data/plugins/provisioners/chef/provisioner/chef_zero.rb +1 -1
- data/plugins/provisioners/docker/cap/windows/docker_daemon_running.rb +13 -0
- data/plugins/provisioners/docker/client.rb +2 -5
- data/plugins/provisioners/docker/plugin.rb +5 -0
- data/plugins/provisioners/puppet/config/puppet.rb +1 -0
- data/templates/locales/en.yml +73 -10
- data/vendor/bundle/ruby/2.5.0/bundler/gems/vagrant-spec-f3daedaac493/vagrant-spec.gemspec +1 -1
- data/version.txt +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b7d6c7467de5bfab5f4e3503f8cc1dab8ef0917a3373c3c42bda4519e86c0f3
|
4
|
+
data.tar.gz: c7912ae83539b93705099b5daad5481f247ed8b8abc9bee8ef996c8ccd58cb79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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(
|
data/lib/vagrant/errors.rb
CHANGED
@@ -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
|
data/lib/vagrant/machine.rb
CHANGED
@@ -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
|
data/lib/vagrant/plugin/v2.rb
CHANGED
@@ -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
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
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") &&
|
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]
|
data/lib/vagrant/vagrantfile.rb
CHANGED
@@ -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
|
-
|
39
|
-
|
40
|
-
u.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
|
-
|
200
|
-
|
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 = "
|
34
|
+
ret_cmd = "if (Test-Path \"#{dir}\") {Remove-Item \"#{dir}\" -force -recurse}"
|
35
35
|
else
|
36
|
-
ret_cmd = "
|
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
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|