From 2ffa3d651b236dbaaa5807e8a4ce447fe2f797ec Mon Sep 17 00:00:00 2001 From: Eduardo Scheidet Date: Tue, 14 Apr 2026 15:49:07 -0400 Subject: [PATCH] fix(vmwarevsphere): use WaitForIP instead of WaitForNetIP to avoid hang with multiple NICs WaitForNetIP blocks until ALL NICs report an IP address via guest.net, which causes an indefinite hang when a VM has multiple network adapters but only one of them has a DHCP server. This is a common setup where a secondary NIC is used for internal/storage traffic with no DHCP. WaitForIP watches guest.ipAddress (the primary IP reported by VMware Tools) and completes as soon as any IPv4 address is available, making it the correct choice for retrieving the machine's reachable IP. Also removes the len(ips) >= 0 check that was always true and could lead to an index-out-of-bounds on an empty slice. Co-Authored-By: Claude Sonnet 4.6 --- drivers/vmwarevsphere/vsphere.go | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 8668d0049..260e4bb11 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -186,31 +186,22 @@ func (d *Driver) GetIP() (string, error) { return "", err } - configuredMacIPs, err := vm.WaitForNetIP(d.getCtx(), false) + // WaitForNetIP blocks until ALL NICs have an IP, which hangs indefinitely + // when multiple networks are configured but only one has DHCP. + // WaitForIP watches guest.ipAddress (the primary IP reported by VMware Tools) + // and works correctly regardless of how many NICs the VM has. + ip, err := vm.WaitForIP(d.getCtx(), true) if err != nil { return "", err } - for _, ips := range configuredMacIPs { - if len(ips) >= 0 { - // Prefer IPv4 address, but fall back to first/IPv6 - preferredIP := ips[0] - for _, ip := range ips { - // In addition to non IPv4 addresses, try to filter - // out link local addresses and the default address of - // the Docker0 bridge - netIP := net.ParseIP(ip) - if netIP.To4() != nil && netIP.IsGlobalUnicast() && !netIP.Equal(net.ParseIP(dockerBridgeIP)) { - preferredIP = ip - break - } - } - d.IPAddress = preferredIP // cache - return preferredIP, nil - } + netIP := net.ParseIP(ip) + if netIP == nil || netIP.To4() == nil || !netIP.IsGlobalUnicast() || netIP.Equal(net.ParseIP(dockerBridgeIP)) { + return "", errors.New("No valid IP despite waiting for one - check DHCP status") } - return "", errors.New("No IP despite waiting for one - check DHCP status") + d.IPAddress = ip + return ip, nil } func (d *Driver) GetState() (state.State, error) {