vagrant-unbundled 2.2.14.0 → 2.2.16.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 +52 -0
- data/bin/vagrant +27 -1
- data/contrib/README.md +1 -1
- data/lib/vagrant.rb +3 -1
- data/lib/vagrant/action/builtin/box_add.rb +13 -3
- data/lib/vagrant/action/builtin/box_check_outdated.rb +2 -1
- data/lib/vagrant/bundler.rb +15 -5
- data/lib/vagrant/environment.rb +1 -0
- data/lib/vagrant/errors.rb +12 -0
- data/lib/vagrant/machine_index.rb +1 -1
- data/lib/vagrant/patches/net-ssh.rb +186 -0
- data/lib/vagrant/plugin/manager.rb +20 -2
- data/lib/vagrant/util.rb +1 -0
- data/lib/vagrant/util/curl_helper.rb +7 -6
- data/lib/vagrant/util/guest_hosts.rb +1 -1
- data/lib/vagrant/util/numeric.rb +20 -0
- data/lib/vagrant/util/powershell.rb +30 -14
- data/lib/vagrant/vagrantfile.rb +1 -1
- data/plugins/commands/cloud/auth/middleware/add_authentication.rb +60 -31
- data/plugins/commands/cloud/auth/middleware/add_downloader_authentication.rb +34 -27
- data/plugins/commands/cloud/client/client.rb +10 -3
- data/plugins/commands/cloud/locales/en.yml +5 -1
- data/plugins/commands/cloud/provider/upload.rb +10 -0
- data/plugins/commands/cloud/publish.rb +10 -0
- data/plugins/commands/cloud/util.rb +10 -2
- data/plugins/commands/destroy/command.rb +1 -5
- data/plugins/guests/alpine/cap/configure_networks.rb +1 -1
- data/plugins/guests/fedora/guest.rb +4 -4
- data/plugins/guests/linux/cap/mount_smb_shared_folder.rb +1 -1
- data/plugins/guests/linux/cap/persist_mount_shared_folder.rb +1 -2
- data/plugins/guests/linux/cap/reboot.rb +21 -3
- 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/providers/docker/driver.rb +2 -2
- data/plugins/providers/virtualbox/action/network.rb +12 -5
- data/plugins/providers/virtualbox/cap/mount_options.rb +5 -0
- data/plugins/providers/virtualbox/plugin.rb +5 -0
- data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +1 -1
- data/plugins/provisioners/salt/bootstrap-salt.sh +7 -4
- data/plugins/synced_folders/smb/cap/mount_options.rb +2 -2
- data/templates/commands/init/Vagrantfile.min.erb +3 -0
- data/templates/guests/nixos/network.erb +5 -6
- data/templates/locales/en.yml +21 -4
- data/vagrant.gemspec +5 -11
- data/version.txt +1 -1
- metadata +2921 -29
@@ -179,8 +179,26 @@ module Vagrant
|
|
179
179
|
result
|
180
180
|
rescue Gem::GemNotFoundException
|
181
181
|
raise Errors::PluginGemNotFound, name: name
|
182
|
-
rescue Gem::Exception =>
|
183
|
-
|
182
|
+
rescue Gem::Exception => err
|
183
|
+
@logger.warn("Failed to install plugin: #{err}")
|
184
|
+
@logger.debug("#{err.class}: #{err}\n#{err.backtrace.join("\n")}")
|
185
|
+
# Try and determine a cause for the failure
|
186
|
+
case err.message
|
187
|
+
when /install development tools first/
|
188
|
+
raise Errors::PluginNeedsDeveloperTools
|
189
|
+
when /library not found in default locations/
|
190
|
+
lib = err.message.match(/(\w+) library not found in default locations/)
|
191
|
+
if lib.nil?
|
192
|
+
raise Errors::BundlerError, message: err.message
|
193
|
+
end
|
194
|
+
raise Errors::PluginMissingLibrary,
|
195
|
+
library: lib.captures.first,
|
196
|
+
name: name
|
197
|
+
when /find header files for ruby/
|
198
|
+
raise Errors::PluginMissingRubyDev
|
199
|
+
else
|
200
|
+
raise Errors::BundlerError, message: err.message
|
201
|
+
end
|
184
202
|
end
|
185
203
|
|
186
204
|
# Uninstalls the plugin with the given name.
|
data/lib/vagrant/util.rb
CHANGED
@@ -11,6 +11,7 @@ module Vagrant
|
|
11
11
|
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
12
12
|
autoload :GuestInspection, 'vagrant/util/guest_inspection'
|
13
13
|
autoload :LoggingFormatter, 'vagrant/util/logging_formatter'
|
14
|
+
autoload :Numeric, 'vagrant/util/numeric'
|
14
15
|
autoload :Platform, 'vagrant/util/platform'
|
15
16
|
autoload :Retryable, 'vagrant/util/retryable'
|
16
17
|
autoload :SafeExec, 'vagrant/util/safe_exec'
|
@@ -4,6 +4,7 @@ module Vagrant
|
|
4
4
|
|
5
5
|
# Hosts that do not require notification on redirect
|
6
6
|
SILENCED_HOSTS = [
|
7
|
+
"vagrantcloud-files-production.s3-accelerate.amazonaws.com".freeze,
|
7
8
|
"vagrantcloud.com".freeze,
|
8
9
|
"vagrantup.com".freeze
|
9
10
|
].freeze
|
@@ -21,6 +22,7 @@ module Vagrant
|
|
21
22
|
# Accumulate progress_data
|
22
23
|
progress_data << data
|
23
24
|
|
25
|
+
redirect_notify = false
|
24
26
|
while true
|
25
27
|
# If the download has been redirected and we are no longer downloading
|
26
28
|
# from the original host, notify the user that the target host has
|
@@ -30,16 +32,15 @@ module Vagrant
|
|
30
32
|
if !location.empty?
|
31
33
|
location_uri = URI.parse(location)
|
32
34
|
|
33
|
-
|
34
|
-
redirect_notify = false
|
35
|
+
if !location_uri.host.nil? && !redirect_notify
|
35
36
|
logger.info("download redirected to #{location}")
|
36
37
|
source_uri = URI.parse(source)
|
37
38
|
source_host = source_uri.host.to_s.split(".", 2).last
|
38
39
|
location_host = location_uri.host.to_s.split(".", 2).last
|
39
|
-
if
|
40
|
-
ui.rewriting do |
|
41
|
-
|
42
|
-
|
40
|
+
if location_host != source_host && !SILENCED_HOSTS.include?(location_host) && !SILENCED_HOSTS.include?(location_uri.host.to_s)
|
41
|
+
ui.rewriting do |_ui|
|
42
|
+
_ui.clear_line
|
43
|
+
_ui.detail "Download redirected to host: #{location_uri.host}"
|
43
44
|
end
|
44
45
|
end
|
45
46
|
redirect_notify = true
|
@@ -17,7 +17,7 @@ module Vagrant
|
|
17
17
|
basename = name.split(".", 2)[0]
|
18
18
|
comm.sudo <<-EOH.gsub(/^ {14}/, '')
|
19
19
|
grep -w '#{name}' /etc/hosts || {
|
20
|
-
for i in {1
|
20
|
+
for i in #{[*1..loop_bound].join(' ')}; do
|
21
21
|
grep -w "127.0.${i}.1" /etc/hosts || {
|
22
22
|
echo "127.0.${i}.1 #{name} #{basename}" >> /etc/hosts
|
23
23
|
break
|
data/lib/vagrant/util/numeric.rb
CHANGED
@@ -49,6 +49,26 @@ module Vagrant
|
|
49
49
|
bytes
|
50
50
|
end
|
51
51
|
|
52
|
+
# Convert bytes to a user friendly string representation
|
53
|
+
#
|
54
|
+
# @param [Numeric] bytes Number of bytes to represent
|
55
|
+
# @return [String] user friendly output
|
56
|
+
def bytes_to_string(bytes)
|
57
|
+
# We want to locate the size that will return the
|
58
|
+
# smallest whole value number
|
59
|
+
BYTES_CONVERSION_MAP.sort { |a, b|
|
60
|
+
b.last <=> a.last
|
61
|
+
}.each do |suffix, size|
|
62
|
+
val = bytes.to_f / size
|
63
|
+
next if val < 1
|
64
|
+
val = sprintf("%.2f", val)
|
65
|
+
val.slice!(-1, 1) while val.end_with?("0")
|
66
|
+
val.slice!(-1, 1) if val.end_with?(".")
|
67
|
+
return "#{val}#{suffix}"
|
68
|
+
end
|
69
|
+
"#{bytes} byte#{"s" if bytes > 1}"
|
70
|
+
end
|
71
|
+
|
52
72
|
# Rounds actual value to two decimal places
|
53
73
|
#
|
54
74
|
# @param [Integer] bytes
|
@@ -14,28 +14,44 @@ module Vagrant
|
|
14
14
|
MINIMUM_REQUIRED_VERSION = 3
|
15
15
|
# Number of seconds to wait while attempting to get powershell version
|
16
16
|
DEFAULT_VERSION_DETECTION_TIMEOUT = 30
|
17
|
+
# Names of the powershell executable
|
18
|
+
POWERSHELL_NAMES = ["powershell", "pwsh"].map(&:freeze).freeze
|
19
|
+
# Paths to powershell executable
|
20
|
+
POWERSHELL_PATHS = [
|
21
|
+
"%WINDIR%/WindowsPowerShell/v1.0",
|
22
|
+
"%PROGRAMFILES%/PowerShell/7",
|
23
|
+
"%PROGRAMFILES%/PowerShell/6"
|
24
|
+
].map(&:freeze).freeze
|
25
|
+
|
17
26
|
LOGGER = Log4r::Logger.new("vagrant::util::powershell")
|
18
27
|
|
19
28
|
# @return [String|nil] a powershell executable, depending on environment
|
20
29
|
def self.executable
|
21
30
|
if !defined?(@_powershell_executable)
|
22
|
-
|
31
|
+
# First start with detecting executable on configured path
|
32
|
+
POWERSHELL_NAMES.detect do |psh|
|
33
|
+
return @_powershell_executable = psh if Which.which(psh)
|
34
|
+
psh += ".exe"
|
35
|
+
return @_powershell_executable = psh if Which.which(psh)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Now attempt with paths
|
39
|
+
paths = POWERSHELL_PATHS.map do |ppath|
|
40
|
+
result = Util::Subprocess.execute("cmd.exe", "/c", "echo #{ppath}")
|
41
|
+
result.stdout.gsub("\"", "").strip if result.exit_code == 0
|
42
|
+
end.compact
|
23
43
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@_powershell_executable += ".exe"
|
44
|
+
paths.each do |psh_path|
|
45
|
+
POWERSHELL_NAMES.each do |psh|
|
46
|
+
path = File.join(psh_path, psh)
|
47
|
+
return @_powershell_executable = path if Which.which(path)
|
29
48
|
|
30
|
-
|
31
|
-
|
49
|
+
path += ".exe"
|
50
|
+
return @_powershell_executable = path if Which.which(path)
|
32
51
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
else
|
38
|
-
@_powershell_executable = nil
|
52
|
+
# Finally test the msys2 style path
|
53
|
+
path = path.sub(/^([A-Za-z]):/, "/mnt/\\1")
|
54
|
+
return @_powershell_executable = path if Which.which(path)
|
39
55
|
end
|
40
56
|
end
|
41
57
|
end
|
data/lib/vagrant/vagrantfile.rb
CHANGED
@@ -241,7 +241,7 @@ module Vagrant
|
|
241
241
|
# configuration and attempt to load that
|
242
242
|
if box.nil?
|
243
243
|
@logger.warn("Failed to locate #{config.vm.box} with version #{config.vm.box_version}")
|
244
|
-
@logger.warn("Performing lookup with
|
244
|
+
@logger.warn("Performing lookup with initial values #{initial_box} with version #{initial_version}")
|
245
245
|
config.vm.box = original_box = initial_box
|
246
246
|
config.vm.box_version = original_box = initial_version
|
247
247
|
load_box_proc.call
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "cgi"
|
2
2
|
require "uri"
|
3
|
+
require "log4r"
|
3
4
|
|
4
5
|
require Vagrant.source_root.join("plugins/commands/cloud/client/client")
|
5
6
|
|
@@ -27,55 +28,83 @@ module VagrantPlugins
|
|
27
28
|
|
28
29
|
def initialize(app, env)
|
29
30
|
@app = app
|
31
|
+
@logger = Log4r::Logger.new("vagrant::cloud::auth::authenticate-box-url")
|
30
32
|
CloudCommand::Plugin.init!
|
31
33
|
end
|
32
34
|
|
33
35
|
def call(env)
|
34
|
-
|
35
|
-
|
36
|
+
if ENV["VAGRANT_SERVER_ACCESS_TOKEN_BY_URL"]
|
37
|
+
@logger.warn("Adding access token as GET parameter by user request")
|
38
|
+
client = Client.new(env[:env])
|
39
|
+
token = client.token
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
env[:box_urls].map! do |url|
|
42
|
+
begin
|
43
|
+
u = URI.parse(url)
|
44
|
+
if u.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(u.host)
|
45
|
+
u.host = TARGET_HOST
|
46
|
+
u.to_s
|
47
|
+
else
|
48
|
+
url
|
49
|
+
end
|
50
|
+
rescue URI::Error
|
44
51
|
url
|
45
52
|
end
|
46
|
-
rescue URI::Error
|
47
|
-
url
|
48
53
|
end
|
49
|
-
end
|
50
54
|
|
51
|
-
|
55
|
+
server_uri = URI.parse(Vagrant.server_url.to_s)
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
if token && !server_uri.host.to_s.empty?
|
58
|
+
env[:box_urls].map! do |url|
|
59
|
+
begin
|
60
|
+
u = URI.parse(url)
|
56
61
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
if u.host == server_uri.host
|
63
|
+
if server_uri.host != TARGET_HOST && !self.class.custom_host_notified?
|
64
|
+
env[:ui].warn(I18n.t("cloud_command.middleware.authentication.different_target",
|
65
|
+
custom_host: server_uri.host, known_host: TARGET_HOST) + "\n")
|
66
|
+
sleep CUSTOM_HOST_NOTIFY_WAIT
|
67
|
+
self.class.custom_host_notified!
|
68
|
+
end
|
64
69
|
|
65
|
-
|
70
|
+
q = CGI.parse(u.query || "")
|
66
71
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
72
|
+
current = q["access_token"]
|
73
|
+
if current && current.empty?
|
74
|
+
q["access_token"] = token
|
75
|
+
end
|
71
76
|
|
72
|
-
|
77
|
+
u.query = URI.encode_www_form(q)
|
78
|
+
end
|
79
|
+
|
80
|
+
u.to_s
|
81
|
+
rescue URI::Error
|
82
|
+
url
|
83
|
+
end
|
73
84
|
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
env[:box_urls].map! do |url|
|
88
|
+
begin
|
89
|
+
u = URI.parse(url)
|
90
|
+
q = CGI.parse(u.query || "")
|
91
|
+
if q["access_token"]
|
92
|
+
@logger.warn("Removing access token from URL parameter.")
|
93
|
+
q.delete("access_token")
|
94
|
+
if q.empty?
|
95
|
+
u.query = nil
|
96
|
+
else
|
97
|
+
u.query = URI.encode_www_form(q)
|
98
|
+
end
|
99
|
+
end
|
74
100
|
|
75
|
-
|
101
|
+
u.to_s
|
102
|
+
rescue URI::Error
|
103
|
+
url
|
104
|
+
end
|
76
105
|
end
|
106
|
+
@logger.warn("Authentication token not added as GET parameter.")
|
77
107
|
end
|
78
|
-
|
79
108
|
@app.call(env)
|
80
109
|
end.freeze
|
81
110
|
end
|
@@ -7,47 +7,54 @@ require_relative "./add_authentication"
|
|
7
7
|
require Vagrant.source_root.join("plugins/commands/cloud/client/client")
|
8
8
|
|
9
9
|
# Similar to AddAuthentication this middleware will add authentication for interacting
|
10
|
-
# with Vagrant cloud. It does this by adding Authentication headers to a
|
11
|
-
# Vagrant::Util::Downloader object.
|
10
|
+
# with Vagrant cloud. It does this by adding Authentication headers to a
|
11
|
+
# Vagrant::Util::Downloader object.
|
12
12
|
module VagrantPlugins
|
13
13
|
module CloudCommand
|
14
14
|
class AddDownloaderAuthentication < AddAuthentication
|
15
15
|
|
16
|
-
|
16
|
+
def initialize(app, env)
|
17
|
+
super
|
18
|
+
@logger = Log4r::Logger.new("vagrant::cloud::auth::add-download-authentication")
|
19
|
+
end
|
17
20
|
|
18
21
|
def call(env)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
if ENV["VAGRANT_SERVER_ACCESS_TOKEN_BY_URL"]
|
23
|
+
@logger.warn("Authentication header not added due to user requested access token URL parameter")
|
24
|
+
else
|
25
|
+
client = Client.new(env[:env])
|
26
|
+
token = client.token
|
27
|
+
Vagrant::Util::CredentialScrubber.sensitive(token)
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
begin
|
30
|
+
target_url = URI.parse(env[:downloader].source)
|
31
|
+
if target_url.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(target_url.host)
|
26
32
|
target_url.host = TARGET_HOST
|
27
33
|
env[:downloader].source = target_url.to_s
|
34
|
+
end
|
35
|
+
rescue URI::Error
|
36
|
+
# if there is an error, use current target_url
|
28
37
|
end
|
29
|
-
rescue URI::Error
|
30
|
-
# if there is an error, use current target_url
|
31
|
-
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
server_uri = URI.parse(Vagrant.server_url.to_s)
|
40
|
+
if token && !server_uri.host.to_s.empty?
|
41
|
+
if target_url.host == server_uri.host
|
42
|
+
if server_uri.host != TARGET_HOST && !self.class.custom_host_notified?
|
43
|
+
env[:ui].warn(I18n.t("cloud_command.middleware.authentication.different_target",
|
44
|
+
custom_host: server_uri.host, known_host: TARGET_HOST) + "\n")
|
45
|
+
sleep CUSTOM_HOST_NOTIFY_WAIT
|
46
|
+
self.class.custom_host_notified!
|
47
|
+
end
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
if Array(env[:downloader].headers).any? { |h| h.include?("Authorization") }
|
50
|
+
@logger.info("Not adding an authentication header, one already found")
|
51
|
+
else
|
52
|
+
env[:downloader].headers << "Authorization: Bearer #{token}"
|
53
|
+
end
|
47
54
|
end
|
48
|
-
end
|
49
55
|
|
50
|
-
|
56
|
+
env[:downloader]
|
57
|
+
end
|
51
58
|
end
|
52
59
|
|
53
60
|
@app.call(env)
|
@@ -18,6 +18,7 @@ module VagrantPlugins
|
|
18
18
|
######################################################################
|
19
19
|
APP = "app".freeze
|
20
20
|
|
21
|
+
include Util
|
21
22
|
include Vagrant::Util::Presence
|
22
23
|
|
23
24
|
attr_accessor :client
|
@@ -32,7 +33,10 @@ module VagrantPlugins
|
|
32
33
|
def initialize(env)
|
33
34
|
@logger = Log4r::Logger.new("vagrant::cloud::client")
|
34
35
|
@env = env
|
35
|
-
@client = VagrantCloud::Client.new(
|
36
|
+
@client = VagrantCloud::Client.new(
|
37
|
+
access_token: token,
|
38
|
+
url_base: api_server_url
|
39
|
+
)
|
36
40
|
end
|
37
41
|
|
38
42
|
# Removes the token, effectively logging the user out.
|
@@ -72,7 +76,10 @@ module VagrantPlugins
|
|
72
76
|
password: password, description: description, code: code)
|
73
77
|
|
74
78
|
Vagrant::Util::CredentialScrubber.sensitive(r[:token])
|
75
|
-
@client = VagrantCloud::Client.new(
|
79
|
+
@client = VagrantCloud::Client.new(
|
80
|
+
access_token: r[:token],
|
81
|
+
url_base: api_server_url
|
82
|
+
)
|
76
83
|
r[:token]
|
77
84
|
end
|
78
85
|
end
|
@@ -106,7 +113,7 @@ module VagrantPlugins
|
|
106
113
|
end
|
107
114
|
|
108
115
|
# Reset after we store the token since this is now _our_ token
|
109
|
-
@client = VagrantCloud::Client.new(access_token: token)
|
116
|
+
@client = VagrantCloud::Client.new(access_token: token, url_base: api_server_url)
|
110
117
|
|
111
118
|
nil
|
112
119
|
end
|
@@ -75,6 +75,10 @@ en:
|
|
75
75
|
Updated provider %{provider} on %{org}/%{box_name} for version %{version}
|
76
76
|
not_found: |-
|
77
77
|
Failed to locate %{provider_name} provider for %{org}/%{box_name} on version %{version}
|
78
|
+
direct_disable: |-
|
79
|
+
Vagrant is automatically disabling direct upload to backend storage.
|
80
|
+
Uploads directly to backend storage are currently only supported for
|
81
|
+
files 5G in size or smaller. Box file to upload is: %{size}
|
78
82
|
version:
|
79
83
|
create_success: |-
|
80
84
|
Created version %{version} on %{org}/%{box_name} for version %{version}
|
@@ -112,7 +116,7 @@ en:
|
|
112
116
|
Failed to update box %{org}/%{box_name}
|
113
117
|
whoami:
|
114
118
|
read_error: |-
|
115
|
-
Failed to
|
119
|
+
Failed to locate account information
|
116
120
|
provider:
|
117
121
|
create_fail: |-
|
118
122
|
Failed to create provider %{provider} on box %{org}/%{box_name} for version %{version}
|