vagrant-unbundled 2.2.0.0 → 2.2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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