vagrant-unbundled 2.2.0.0 → 2.2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -4
  3. data/CHANGELOG.md +49 -0
  4. data/lib/vagrant/action/builtin/box_check_outdated.rb +1 -0
  5. data/lib/vagrant/action/builtin/config_validate.rb +1 -1
  6. data/lib/vagrant/box.rb +27 -0
  7. data/lib/vagrant/bundler.rb +7 -2
  8. data/lib/vagrant/cli.rb +4 -0
  9. data/lib/vagrant/config/v2/root.rb +6 -2
  10. data/lib/vagrant/plugin/v2/communicator.rb +7 -0
  11. data/lib/vagrant/plugin/v2/trigger.rb +5 -1
  12. data/lib/vagrant/util/network_ip.rb +1 -26
  13. data/lib/vagrant/util/platform.rb +19 -7
  14. data/lib/vagrant/util/powershell.rb +23 -25
  15. data/lib/vagrant/util/ssh.rb +18 -5
  16. data/lib/vagrant/vagrantfile.rb +13 -2
  17. data/plugins/commands/login/plugin.rb +0 -1
  18. data/plugins/commands/validate/command.rb +17 -2
  19. data/plugins/communicators/ssh/communicator.rb +22 -12
  20. data/plugins/communicators/winrm/communicator.rb +5 -1
  21. data/plugins/communicators/winrm/shell.rb +25 -1
  22. data/plugins/guests/debian/cap/change_host_name.rb +66 -10
  23. data/plugins/guests/windows/cap/change_host_name.rb +4 -12
  24. data/plugins/guests/windows/cap/reboot.rb +36 -6
  25. data/plugins/guests/windows/plugin.rb +5 -0
  26. data/plugins/kernel_v2/config/vm.rb +8 -4
  27. data/plugins/providers/docker/action/host_machine_sync_folders.rb +2 -3
  28. data/plugins/providers/hyperv/provider.rb +15 -3
  29. data/plugins/providers/hyperv/scripts/delete_vm.ps1 +3 -0
  30. data/plugins/providers/hyperv/scripts/get_network_config.ps1 +1 -1
  31. data/plugins/providers/hyperv/scripts/set_network_vlan.ps1 +0 -6
  32. data/plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1 +1 -1
  33. data/plugins/providers/virtualbox/action.rb +2 -0
  34. data/plugins/providers/virtualbox/action/network.rb +33 -42
  35. data/plugins/providers/virtualbox/action/set_default_nic_type.rb +69 -0
  36. data/plugins/providers/virtualbox/config.rb +10 -0
  37. data/plugins/providers/virtualbox/driver/meta.rb +1 -0
  38. data/plugins/providers/virtualbox/driver/version_5_0.rb +17 -6
  39. data/plugins/providers/virtualbox/driver/version_5_2.rb +2 -2
  40. data/plugins/providers/virtualbox/driver/version_6_0.rb +105 -0
  41. data/plugins/providers/virtualbox/plugin.rb +1 -0
  42. data/plugins/providers/virtualbox/synced_folder.rb +2 -1
  43. data/plugins/provisioners/docker/cap/linux/docker_configure_vagrant_user.rb +1 -0
  44. data/plugins/provisioners/shell/config.rb +4 -1
  45. data/plugins/provisioners/shell/provisioner.rb +6 -0
  46. data/plugins/synced_folders/smb/synced_folder.rb +18 -5
  47. data/templates/locales/en.yml +19 -3
  48. data/vagrant.gemspec +3 -1
  49. data/version.txt +1 -1
  50. metadata +407 -12
@@ -14,7 +14,6 @@ module VagrantPlugins
14
14
  command(:login) do
15
15
  require File.expand_path("../../cloud/auth/login", __FILE__)
16
16
  init!
17
- $stderr.puts "WARNING: This command has been deprecated in favor of `vagrant cloud auth login`"
18
17
  VagrantPlugins::CloudCommand::AuthCommand::Command::Login
19
18
  end
20
19
 
@@ -8,17 +8,32 @@ module VagrantPlugins
8
8
  end
9
9
 
10
10
  def execute
11
+ options = {}
12
+
11
13
  opts = OptionParser.new do |o|
12
- o.banner = "Usage: vagrant validate"
14
+ o.banner = "Usage: vagrant validate [options]"
15
+ o.separator ""
16
+ o.separator "Validates a Vagrantfile config"
17
+ o.separator ""
18
+ o.separator "Options:"
19
+ o.separator ""
20
+
21
+ o.on("-p", "--ignore-provider", "Ignores provider config options") do |p|
22
+ options[:ignore_provider] = p
23
+ end
13
24
  end
14
25
 
15
26
  # Parse the options
16
27
  argv = parse_options(opts)
17
28
  return if !argv
18
29
 
30
+ action_env = {}
31
+ if options[:ignore_provider]
32
+ action_env[:ignore_provider] = true
33
+ end
19
34
  # Validate the configuration of all machines
20
35
  with_target_vms() do |machine|
21
- machine.action_raw(:config_validate, Vagrant::Action::Builtin::ConfigValidate)
36
+ machine.action_raw(:config_validate, Vagrant::Action::Builtin::ConfigValidate, action_env)
22
37
  end
23
38
 
24
39
  @env.ui.info(I18n.t("vagrant.commands.validate.success"))
@@ -69,14 +69,16 @@ module VagrantPlugins
69
69
  end
70
70
 
71
71
  # Got it! Let the user know what we're connecting to.
72
- @machine.ui.detail("SSH address: #{ssh_info[:host]}:#{ssh_info[:port]}")
73
- @machine.ui.detail("SSH username: #{ssh_info[:username]}")
74
- ssh_auth_type = "private key"
75
- ssh_auth_type = "password" if ssh_info[:password]
76
- @machine.ui.detail("SSH auth method: #{ssh_auth_type}")
77
-
78
- last_message = nil
79
- last_message_repeat_at = 0
72
+ if !@ssh_info_notification
73
+ @machine.ui.detail("SSH address: #{ssh_info[:host]}:#{ssh_info[:port]}")
74
+ @machine.ui.detail("SSH username: #{ssh_info[:username]}")
75
+ ssh_auth_type = "private key"
76
+ ssh_auth_type = "password" if ssh_info[:password]
77
+ @machine.ui.detail("SSH auth method: #{ssh_auth_type}")
78
+ @ssh_info_notification = true
79
+ end
80
+
81
+ previous_messages = {}
80
82
  while true
81
83
  message = nil
82
84
  begin
@@ -123,14 +125,13 @@ module VagrantPlugins
123
125
  if message
124
126
  message_at = Time.now.to_f
125
127
  show_message = true
126
- if last_message == message
127
- show_message = (message_at - last_message_repeat_at) > 10.0
128
+ if previous_messages[message]
129
+ show_message = (message_at - previous_messages[message]) > 10.0
128
130
  end
129
131
 
130
132
  if show_message
131
133
  @machine.ui.detail("Warning: #{message} Retrying...")
132
- last_message = message
133
- last_message_repeat_at = message_at
134
+ previous_messages[message] = message_at
134
135
  end
135
136
  end
136
137
  end
@@ -311,6 +312,15 @@ module VagrantPlugins
311
312
  to: to.to_s
312
313
  end
313
314
 
315
+ def reset!
316
+ if @connection
317
+ @connection.close
318
+ @connection = nil
319
+ end
320
+ @ssh_info_notification = true # suppress ssh info output
321
+ wait_for_ready(5)
322
+ end
323
+
314
324
  protected
315
325
 
316
326
  # Opens an SSH connection and yields it to a block.
@@ -109,7 +109,7 @@ module VagrantPlugins
109
109
 
110
110
  @logger.info("WinRM is ready!")
111
111
  return true
112
- rescue Errors::TransientError => e
112
+ rescue Errors::TransientError, VagrantPlugins::CommunicatorWinRM::Errors::WinRMNotReady => e
113
113
  # We catch a `TransientError` which would signal that something went
114
114
  # that might work if we wait and retry.
115
115
  @logger.info("WinRM not up: #{e.inspect}")
@@ -121,6 +121,10 @@ module VagrantPlugins
121
121
  return false
122
122
  end
123
123
 
124
+ def reset!
125
+ shell(true)
126
+ end
127
+
124
128
  def shell(reload=false)
125
129
  @shell = nil if reload
126
130
  @shell ||= create_shell
@@ -71,7 +71,13 @@ module VagrantPlugins
71
71
  def elevated(command, opts = {}, &block)
72
72
  connection.shell(:elevated) do |shell|
73
73
  shell.interactive_logon = opts[:interactive] || false
74
- execute_with_rescue(shell, command, &block)
74
+ uname = shell.username
75
+ begin
76
+ shell.username = elevated_username
77
+ execute_with_rescue(shell, command, &block)
78
+ ensure
79
+ shell.username = uname
80
+ end
75
81
  end
76
82
  end
77
83
 
@@ -216,6 +222,24 @@ module VagrantPlugins
216
222
  retry_delay: @config.retry_delay,
217
223
  retry_limit: @config.max_tries }
218
224
  end
225
+
226
+ def elevated_username
227
+ if @elevated_username
228
+ return @elevated_username
229
+ end
230
+ if username.include?("\\")
231
+ return @elevated_username = username
232
+ end
233
+ computername = ""
234
+ powershell("Write-Output $env:computername") do |type, data|
235
+ computername << data if type == :stdout
236
+ end
237
+ computername.strip!
238
+ if computername.empty?
239
+ return @elevated_username = username
240
+ end
241
+ @elevated_username = "#{computername}\\#{username}"
242
+ end
219
243
  end #WinShell class
220
244
  end
221
245
  end
@@ -1,8 +1,15 @@
1
+ require "log4r"
2
+ require_relative "../../linux/cap/network_interfaces"
3
+
1
4
  module VagrantPlugins
2
5
  module GuestDebian
3
6
  module Cap
4
7
  class ChangeHostName
8
+
9
+ extend Vagrant::Util::GuestInspection::Linux
10
+
5
11
  def self.change_host_name(machine, name)
12
+ @logger = Log4r::Logger.new("vagrant::guest::debian::changehostname")
6
13
  comm = machine.communicate
7
14
 
8
15
  if !comm.test("hostname -f | grep '^#{name}$'", sudo: false)
@@ -10,11 +17,6 @@ module VagrantPlugins
10
17
  comm.sudo <<-EOH.gsub(/^ {14}/, '')
11
18
  # Set the hostname
12
19
  echo '#{basename}' > /etc/hostname
13
- hostname -F /etc/hostname
14
-
15
- if command -v hostnamectl; then
16
- hostnamectl set-hostname '#{basename}'
17
- fi
18
20
 
19
21
  # Prepend ourselves to /etc/hosts
20
22
  grep -w '#{name}' /etc/hosts || {
@@ -28,6 +30,13 @@ module VagrantPlugins
28
30
  # Update mailname
29
31
  echo '#{name}' > /etc/mailname
30
32
 
33
+ EOH
34
+
35
+ if hostnamectl?(comm)
36
+ comm.sudo("hostnamectl set-hostname '#{basename}'")
37
+ else
38
+ comm.sudo <<-EOH.gsub(/^ {14}/, '')
39
+ hostname -F /etc/hostname
31
40
  # Restart hostname services
32
41
  if test -f /etc/init.d/hostname; then
33
42
  /etc/init.d/hostname start || true
@@ -36,11 +45,58 @@ module VagrantPlugins
36
45
  if test -f /etc/init.d/hostname.sh; then
37
46
  /etc/init.d/hostname.sh start || true
38
47
  fi
39
- if test -x /sbin/dhclient ; then
40
- /sbin/dhclient -r
41
- /sbin/dhclient -nw
42
- fi
43
- EOH
48
+ EOH
49
+ end
50
+
51
+ restart_command = nil
52
+ if systemd?(comm)
53
+ if systemd_networkd?(comm)
54
+ @logger.debug("Attempting to restart networking with systemd-networkd")
55
+ restart_command = "systemctl restart systemd-networkd.service"
56
+ elsif systemd_controlled?(comm, "NetworkManager.service")
57
+ @logger.debug("Attempting to restart networking with NetworkManager")
58
+ restart_command = "systemctl restart NetworkManager.service"
59
+ end
60
+ end
61
+
62
+ if restart_command
63
+ comm.sudo(restart_command)
64
+ else
65
+ restart_each_interface(machine, @logger)
66
+ end
67
+ end
68
+ end
69
+
70
+ protected
71
+
72
+ # Due to how most Debian systems and older Ubuntu systems handle restarting
73
+ # networking, we cannot simply run the networking init script or use the ifup/down
74
+ # tools to restart all interfaces to renew the machines DHCP lease when setting
75
+ # its hostname. This method is a workaround for those older systems that
76
+ # cannoy reliably restart networking. It restarts each individual interface
77
+ # on its own instead.
78
+ #
79
+ # @param [Vagrant::Machine] machine
80
+ # @param [Log4r::Logger] logger
81
+ def self.restart_each_interface(machine, logger)
82
+ comm = machine.communicate
83
+ interfaces = VagrantPlugins::GuestLinux::Cap::NetworkInterfaces.network_interfaces(machine)
84
+ nettools = true
85
+ if systemd?(comm)
86
+ @logger.debug("Attempting to restart networking with systemctl")
87
+ nettools = false
88
+ else
89
+ @logger.debug("Attempting to restart networking with ifup/down nettools")
90
+ end
91
+
92
+ interfaces.each do |iface|
93
+ logger.debug("Restarting interface #{iface} on guest #{machine.name}")
94
+ if nettools
95
+ restart_command = "ifdown #{iface};ifup #{iface}"
96
+ else
97
+ restart_command = "systemctl stop ifup@#{iface}.service;systemctl start ifup@#{iface}.service"
98
+ end
99
+ comm.sudo(restart_command)
44
100
  end
45
101
  end
46
102
  end
@@ -1,8 +1,9 @@
1
+ require "log4r"
2
+
1
3
  module VagrantPlugins
2
4
  module GuestWindows
3
5
  module Cap
4
6
  module ChangeHostName
5
-
6
7
  def self.change_host_name(machine, name)
7
8
  change_host_name_and_wait(machine, name, machine.config.vm.graceful_halt_timeout)
8
9
  end
@@ -11,14 +12,11 @@ module VagrantPlugins
11
12
  # If the configured name matches the current name, then bail
12
13
  # We cannot use %ComputerName% because it truncates at 15 chars
13
14
  return if machine.communicate.test("if ([System.Net.Dns]::GetHostName() -eq '#{name}') { exit 0 } exit 1")
14
-
15
+
15
16
  # Rename and reboot host if rename succeeded
16
17
  script = <<-EOH
17
18
  $computer = Get-WmiObject -Class Win32_ComputerSystem
18
19
  $retval = $computer.rename("#{name}").returnvalue
19
- if ($retval -eq 0) {
20
- shutdown /r /t 5 /f /d p:4:1 /c "Vagrant Rename Computer"
21
- }
22
20
  exit $retval
23
21
  EOH
24
22
 
@@ -27,13 +25,7 @@ module VagrantPlugins
27
25
  error_class: Errors::RenameComputerFailed,
28
26
  error_key: :rename_computer_failed)
29
27
 
30
- # Don't continue until the machine has shutdown and rebooted
31
- if machine.guest.capability?(:wait_for_reboot)
32
- machine.guest.capability(:wait_for_reboot)
33
- else
34
- # use graceful_halt_timeout only if guest cannot wait for reboot
35
- sleep(sleep_timeout)
36
- end
28
+ machine.guest.capability(:reboot)
37
29
  end
38
30
  end
39
31
  end
@@ -1,21 +1,51 @@
1
+ require "log4r"
2
+
1
3
  module VagrantPlugins
2
4
  module GuestWindows
3
5
  module Cap
4
6
  class Reboot
5
- def self.wait_for_reboot(machine)
6
- # Technically it should be possible to make it work with SSH
7
- # too, but we don't yet.
8
- return if machine.config.vm.communicator != :winrm
7
+ MAX_REBOOT_RETRY_DURATION = 120
8
+
9
+ def self.reboot(machine)
10
+ @logger = Log4r::Logger.new("vagrant::windows::reboot")
11
+ reboot_script = "shutdown /r /t 5 /f /d p:4:1 /c \"Vagrant Reboot Computer\""
12
+
13
+ comm = machine.communicate
14
+
15
+ script = File.expand_path("../../scripts/reboot_detect.ps1", __FILE__)
16
+ script = File.read(script)
17
+ if comm.test(script, error_check: false, shell: :powershell)
18
+ @logger.debug("Issuing reboot command for guest")
19
+ comm.execute(reboot_script, shell: :powershell)
20
+ else
21
+ @logger.debug("A reboot is already in progress")
22
+ end
23
+
24
+ @logger.debug("Waiting for machine to finish rebooting")
9
25
 
26
+ wait_remaining = MAX_REBOOT_RETRY_DURATION
27
+ begin
28
+ wait_for_reboot(machine)
29
+ rescue Vagrant::Errors::MachineGuestNotReady, WinRM::WinRMHTTPTransportError => e
30
+ raise if wait_remaining < 0
31
+ @logger.warn("Machine not ready, cannot start reboot yet. Trying again")
32
+ sleep(5)
33
+ wait_remaining -= 5
34
+ retry
35
+ end
36
+ end
37
+
38
+ def self.wait_for_reboot(machine)
10
39
  script = File.expand_path("../../scripts/reboot_detect.ps1", __FILE__)
11
40
  script = File.read(script)
12
- while machine.communicate.execute(script, error_check: false) != 0
41
+
42
+ while machine.guest.ready? && machine.communicate.execute(script, error_check: false, shell: :powershell) != 0
13
43
  sleep 10
14
44
  end
15
45
 
16
46
  # This re-establishes our symbolic links if they were
17
47
  # created between now and a reboot
18
- machine.communicate.execute("net use", error_check: false)
48
+ machine.communicate.execute("net use", error_check: false, shell: :powershell)
19
49
  end
20
50
  end
21
51
  end
@@ -64,6 +64,11 @@ module VagrantPlugins
64
64
  Cap::Reboot
65
65
  end
66
66
 
67
+ guest_capability(:windows, :reboot) do
68
+ require_relative "cap/reboot"
69
+ Cap::Reboot
70
+ end
71
+
67
72
  guest_capability(:windows, :choose_addressable_ip_addr) do
68
73
  require_relative "cap/choose_addressable_ip_addr"
69
74
  Cap::ChooseAddressableIPAddr
@@ -582,7 +582,7 @@ module VagrantPlugins
582
582
  @__synced_folders
583
583
  end
584
584
 
585
- def validate(machine)
585
+ def validate(machine, ignore_provider=nil)
586
586
  errors = _detected_errors
587
587
 
588
588
  if !box && !clone && !machine.provider_options[:box_optional]
@@ -737,9 +737,13 @@ module VagrantPlugins
737
737
 
738
738
  # Validate only the _active_ provider
739
739
  if machine.provider_config
740
- provider_errors = machine.provider_config.validate(machine)
741
- if provider_errors
742
- errors = Vagrant::Config::V2::Util.merge_errors(errors, provider_errors)
740
+ if !ignore_provider
741
+ provider_errors = machine.provider_config.validate(machine)
742
+ if provider_errors
743
+ errors = Vagrant::Config::V2::Util.merge_errors(errors, provider_errors)
744
+ end
745
+ else
746
+ machine.ui.warn(I18n.t("vagrant.config.vm.ignore_provider_config"))
743
747
  end
744
748
  end
745
749
 
@@ -45,7 +45,7 @@ module VagrantPlugins
45
45
 
46
46
  def setup_synced_folders(host_machine, env)
47
47
  # Write the host machine SFID if we have one
48
- id_path = env[:machine].data_dir.join("host_machine_sfid")
48
+ id_path = env[:machine].data_dir.join("host_machine_sfid")
49
49
  if !id_path.file?
50
50
  host_sfid = SecureRandom.uuid
51
51
  id_path.open("w") do |f|
@@ -109,8 +109,7 @@ module VagrantPlugins
109
109
 
110
110
  # If we specify exact then we know what we're doing
111
111
  if !data[:docker__exact]
112
- data[:guestpath] =
113
- "/var/lib/docker/docker_#{Time.now.to_i}_#{rand(100000)}"
112
+ data[:guestpath] = "/var/lib/docker/docker_#{id}"
114
113
  end
115
114
 
116
115
  # Add this synced folder onto the new config if we haven't
@@ -38,6 +38,7 @@ module VagrantPlugins
38
38
  # This method will load in our driver, so we call it now to
39
39
  # initialize it.
40
40
  machine_id_changed
41
+ @logger = Log4r::Logger.new("vagrant::hyperv::provider")
41
42
  end
42
43
 
43
44
  def action(name)
@@ -83,16 +84,27 @@ module VagrantPlugins
83
84
  "Hyper-V (#{id})"
84
85
  end
85
86
 
87
+ # @return [Hash]
86
88
  def ssh_info
87
89
  # We can only SSH into a running machine
88
90
  return nil if state.id != :running
89
91
 
90
92
  # Read the IP of the machine using Hyper-V APIs
91
- network = @driver.read_guest_ip
92
- return nil if !network["ip"]
93
+ guest_ip = nil
94
+
95
+ begin
96
+ network_info = @driver.read_guest_ip
97
+ guest_ip = network_info["ip"]
98
+ rescue Errors::PowerShellError
99
+ @logger.warn("Failed to read guest IP.")
100
+ end
101
+
102
+ return nil if !guest_ip
103
+
104
+ @logger.debug("IP: #{guest_ip}")
93
105
 
94
106
  {
95
- host: network["ip"],
107
+ host: guest_ip,
96
108
  port: 22,
97
109
  }
98
110
  end