Merge pull request #8951 from briancain/RETRYABLE-COMMANDS

Improving resilience of some VirtualBox commands fixup
This commit is contained in:
Brian Cain 2017-09-06 14:51:02 -07:00 committed by GitHub
commit b2f34a6ea9
5 changed files with 194 additions and 97 deletions

View File

@ -85,12 +85,19 @@ module VagrantPlugins
execute("list", "vms").split("\n").each do |line|
if vm_name = line[/^".+?"\s+\{(.+?)\}$/, 1]
begin
info = execute("showvminfo", vm_name, "--machinereadable", retryable: true)
info.split("\n").each do |line|
if network_name = line[/^hostonlyadapter\d+="(.+?)"$/, 1]
networks.delete(network_name)
end
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -422,9 +429,16 @@ module VagrantPlugins
# Ignore our own used ports
next if uuid == @uuid
begin
read_forwarded_ports(uuid, true).each do |_, _, hostport, _|
ports << hostport
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end

View File

@ -176,12 +176,19 @@ module VagrantPlugins
execute("list", "vms").split("\n").each do |line|
if vm = line[/^".+?"\s+\{(.+?)\}$/, 1]
begin
info = execute("showvminfo", vm, "--machinereadable", retryable: true)
info.split("\n").each do |line|
if adapter = line[/^hostonlyadapter\d+="(.+?)"$/, 1]
networks.delete(adapter)
end
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -525,9 +532,16 @@ module VagrantPlugins
# Ignore our own used ports
next if uuid == @uuid
begin
read_forwarded_ports(uuid, true).each do |_, _, hostport, _|
ports << hostport
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end

View File

@ -83,12 +83,19 @@ module VagrantPlugins
execute("list", "vms").split("\n").each do |line|
if line =~ /^".+?"\s+\{(.+?)\}$/
begin
info = execute("showvminfo", $1.to_s, "--machinereadable", retryable: true)
info.split("\n").each do |inner_line|
if inner_line =~ /^hostonlyadapter\d+="(.+?)"$/
networks.delete($1.to_s)
end
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -458,9 +465,16 @@ module VagrantPlugins
# Ignore our own used ports
next if uuid == @uuid
begin
read_forwarded_ports(uuid, true).each do |_, _, hostport, _|
ports << hostport
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end

View File

@ -180,12 +180,19 @@ module VagrantPlugins
execute("list", "vms", retryable: true).split("\n").each do |line|
if line =~ /^".+?"\s+\{(.+?)\}$/
begin
info = execute("showvminfo", $1.to_s, "--machinereadable", retryable: true)
info.split("\n").each do |inner_line|
if inner_line =~ /^hostonlyadapter\d+="(.+?)"$/
networks.delete($1.to_s)
end
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -569,9 +576,16 @@ module VagrantPlugins
# Ignore our own used ports
next if uuid == @uuid
begin
read_forwarded_ports(uuid, true).each do |_, _, hostport, _|
ports << hostport
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end

View File

@ -17,6 +17,7 @@ module VagrantPlugins
end
def clear_forwarded_ports
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
args = []
read_forwarded_ports(@uuid).each do |nic, name, _, _|
args.concat(["--natpf#{nic}", "delete", name])
@ -24,8 +25,10 @@ module VagrantPlugins
execute("modifyvm", @uuid, *args) if !args.empty?
end
end
def clear_shared_folders
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
info = execute("showvminfo", @uuid, "--machinereadable", retryable: true)
info.split("\n").each do |line|
if line =~ /^SharedFolderNameMachineMapping\d+="(.+?)"$/
@ -33,6 +36,7 @@ module VagrantPlugins
end
end
end
end
def clonevm(master_id, snapshot_name)
machine_name = "temp_clone_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}"
@ -41,22 +45,29 @@ module VagrantPlugins
args += ["--snapshot", snapshot_name, "--options", "link"]
end
execute("clonevm", master_id, *args)
execute("clonevm", master_id, *args, retryable: true)
return get_machine_id(machine_name)
end
def create_dhcp_server(network, options)
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
begin
execute("dhcpserver", "add", "--ifname", network,
"--ip", options[:dhcp_ip],
"--netmask", options[:netmask],
"--lowerip", options[:dhcp_lower],
"--upperip", options[:dhcp_upper],
"--enable")
rescue Vagrant::Errors::VBoxManageError => e
return if e.extra_data[:stderr] == 'VBoxManage: error: DHCP server already exists'
raise
end
end
end
def create_host_only_network(options)
# Create the interface
execute("hostonlyif", "create") =~ /^Interface '(.+?)' was successfully created$/
execute("hostonlyif", "create", retryable: true) =~ /^Interface '(.+?)' was successfully created$/
name = $1.to_s
# Get the IP so we can determine v4 vs v6
@ -66,11 +77,13 @@ module VagrantPlugins
if ip.ipv4?
execute("hostonlyif", "ipconfig", name,
"--ip", options[:adapter_ip],
"--netmask", options[:netmask])
"--netmask", options[:netmask],
retryable: true)
elsif ip.ipv6?
execute("hostonlyif", "ipconfig", name,
"--ipv6", options[:adapter_ip],
"--netmasklengthv6", options[:netmask].to_s)
"--netmasklengthv6", options[:netmask].to_s,
retryable: true)
else
raise "BUG: Unknown IP type: #{ip.inspect}"
end
@ -85,7 +98,7 @@ module VagrantPlugins
end
def create_snapshot(machine_id, snapshot_name)
execute("snapshot", machine_id, "take", snapshot_name)
execute("snapshot", machine_id, "take", snapshot_name, retryable: true)
end
def delete_snapshot(machine_id, snapshot_name)
@ -95,7 +108,7 @@ module VagrantPlugins
yield 0 if block_given?
# Snapshot and report the % progress
execute("snapshot", machine_id, "delete", snapshot_name) do |type, data|
execute("snapshot", machine_id, "delete", snapshot_name, retryable: true) do |type, data|
if type == :stderr
# Append the data so we can see the full view
total << data.gsub("\r", "")
@ -142,7 +155,7 @@ module VagrantPlugins
total = ""
yield 0 if block_given?
execute("snapshot", machine_id, "restore", snapshot_name) do |type, data|
execute("snapshot", machine_id, "restore", snapshot_name, retryable: true) do |type, data|
if type == :stderr
# Append the data so we can see the full view
total << data.gsub("\r", "")
@ -165,7 +178,7 @@ module VagrantPlugins
end
def delete
execute("unregistervm", @uuid, "--delete")
execute("unregistervm", @uuid, "--delete", retryable: true)
end
def delete_unused_host_only_networks
@ -176,12 +189,19 @@ module VagrantPlugins
execute("list", "vms", retryable: true).split("\n").each do |line|
if line =~ /^".+?"\s+\{(.+?)\}$/
begin
info = execute("showvminfo", $1.to_s, "--machinereadable", retryable: true)
info.split("\n").each do |inner_line|
if inner_line =~ /^hostonlyadapter\d+="(.+?)"$/
networks.delete($1.to_s)
end
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -192,12 +212,12 @@ module VagrantPlugins
raw("dhcpserver", "remove", "--ifname", name)
# Delete the actual host only network interface.
execute("hostonlyif", "remove", name)
execute("hostonlyif", "remove", name, retryable: true)
end
end
def discard_saved_state
execute("discardstate", @uuid)
execute("discardstate", @uuid, retryable: true)
end
def enable_adapters(adapters)
@ -230,7 +250,7 @@ module VagrantPlugins
end
end
execute("modifyvm", @uuid, *args)
execute("modifyvm", @uuid, *args, retryable: true)
end
def execute_command(command)
@ -238,7 +258,17 @@ module VagrantPlugins
end
def export(path)
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
begin
execute("export", @uuid, "--output", path.to_s)
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VERR_E_FILE_ERROR")
# If the file already exists we'll throw a custom error
raise Vagrant::Errors::VirtualBoxFileExists,
stderr: e.extra_data[:stderr]
end
end
end
def forward_ports(ports)
@ -255,7 +285,7 @@ module VagrantPlugins
pf_builder.join(",")])
end
execute("modifyvm", @uuid, *args) if !args.empty?
execute("modifyvm", @uuid, *args, retryable: true) if !args.empty?
end
def get_machine_id(machine_name)
@ -266,7 +296,7 @@ module VagrantPlugins
end
def halt
execute("controlvm", @uuid, "poweroff")
execute("controlvm", @uuid, "poweroff", retryable: true)
end
def import(ovf)
@ -315,7 +345,7 @@ module VagrantPlugins
end
end
execute("import", ovf , *name_params, *disk_params) do |type, data|
execute("import", ovf , *name_params, *disk_params, retryable: true) do |type, data|
if type == :stdout
# Keep track of the stdout so that we can get the VM name
output << data
@ -567,10 +597,17 @@ module VagrantPlugins
# Ignore our own used ports
next if uuid == @uuid
begin
read_forwarded_ports(uuid, true).each do |_, _, hostport, _, hostip|
hostip = '*' if hostip.nil? || hostip.empty?
used_ports[hostport].add?(hostip)
end
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VBOX_E_OBJECT_NOT_FOUND")
# VirtualBox could not find the vm. It may have been deleted
# by another process after we called 'vboxmanage list vms'? Ignore this error.
end
end
end
@ -590,19 +627,21 @@ module VagrantPlugins
def reconfig_host_only(interface)
execute("hostonlyif", "ipconfig", interface[:name],
"--ipv6", interface[:ipv6])
"--ipv6", interface[:ipv6], retryable: true)
end
def remove_dhcp_server(network_name)
execute("dhcpserver", "remove", "--netname", network_name)
execute("dhcpserver", "remove", "--netname", network_name, retryable: true)
end
def set_mac_address(mac)
execute("modifyvm", @uuid, "--macaddress1", mac)
execute("modifyvm", @uuid, "--macaddress1", mac, retryable: true)
end
def set_name(name)
execute("modifyvm", @uuid, "--name", name, retryable: true)
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
begin
execute("modifyvm", @uuid, "--name", name)
rescue Vagrant::Errors::VBoxManageError => e
raise if !e.extra_data[:stderr].include?("VERR_ALREADY_EXISTS")
@ -611,6 +650,8 @@ module VagrantPlugins
raise Vagrant::Errors::VirtualBoxNameExists,
stderr: e.extra_data[:stderr]
end
end
end
def share_folders(folders)
is_solaris = begin
@ -633,10 +674,10 @@ module VagrantPlugins
args << "--transient" if folder.key?(:transient) && folder[:transient]
# Enable symlinks on the shared folder
execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1")
execute("setextradata", @uuid, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{folder[:name]}", "1", retryable: true)
# Add the shared folder
execute("sharedfolder", "add", @uuid, *args)
execute("sharedfolder", "add", @uuid, *args, retryable: true)
end
end
@ -658,6 +699,7 @@ module VagrantPlugins
def start(mode)
command = ["startvm", @uuid, "--type", mode.to_s]
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
r = raw(*command)
if r.exit_code == 0 || r.stdout =~ /VM ".+?" has been successfully started/
@ -671,13 +713,15 @@ module VagrantPlugins
command: command.inspect,
stderr: r.stderr
end
end
def suspend
execute("controlvm", @uuid, "savestate")
execute("controlvm", @uuid, "savestate", retryable: true)
end
def unshare_folders(names)
names.each do |name|
retryable(on: Vagrant::Errors::VBoxManageError, tries: 3, sleep: 1) do
begin
execute(
"sharedfolder", "remove", @uuid,
@ -688,10 +732,7 @@ module VagrantPlugins
"setextradata", @uuid,
"VBoxInternal2/SharedFoldersEnableSymlinksCreate/#{name}")
rescue Vagrant::Errors::VBoxManageError => e
if e.extra_data[:stderr].include?("VBOX_E_FILE_ERROR")
# The folder doesn't exist. ignore.
else
raise
raise if !e.extra_data[:stderr].include?("VBOX_E_FILE_ERROR")
end
end
end