@@ -652,6 +652,67 @@ func (d *Driver) GetState() (state.State, error) {
652652 return state .None , nil
653653}
654654
655+ func (d * Driver ) getHostOnlyMACAddress () (string , error ) {
656+ // Return the MAC address of the host-only adapter
657+ // assigned to this machine. The returned address
658+ // is lower-cased and does not contain colons.
659+
660+ stdout , stderr , err := d .vbmOutErr ("showvminfo" , d .MachineName , "--machinereadable" )
661+ if err != nil {
662+ if reMachineNotFound .FindString (stderr ) != "" {
663+ return "" , ErrMachineNotExist
664+ }
665+ return "" , err
666+ }
667+
668+ // First, we get the number of the host-only interface
669+ re := regexp .MustCompile (`(?m)^hostonlyadapter([\d]+)` )
670+ groups := re .FindStringSubmatch (stdout )
671+ if len (groups ) < 2 {
672+ return "" , errors .New ("Machine does not have a host-only adapter" )
673+ }
674+
675+ // Then we grab the MAC address based on that number
676+ adapterNumber := groups [1 ]
677+ re = regexp .MustCompile (fmt .Sprintf ("(?m)^macaddress%s=\" (.*)\" " , adapterNumber ))
678+ groups = re .FindStringSubmatch (stdout )
679+ if len (groups ) < 2 {
680+ return "" , fmt .Errorf ("Could not find MAC address for adapter %v" , adapterNumber )
681+ }
682+
683+ return strings .ToLower (groups [1 ]), nil
684+ }
685+
686+ func (d * Driver ) parseIPForMACFromIPAddr (ipAddrOutput string , macAddress string ) (string , error ) {
687+ // Given the output of "ip addr show" on the VM, return the IPv4 address
688+ // of the interface with the given MAC address.
689+
690+ lines := strings .Split (ipAddrOutput , "\n " )
691+ returnNextIP := false
692+
693+ for _ , line := range lines {
694+ line = strings .TrimSpace (line )
695+
696+ if strings .HasPrefix (line , "link" ) { // line contains MAC address
697+ vals := strings .Split (line , " " )
698+ if len (vals ) >= 2 {
699+ macBlock := vals [1 ]
700+ macWithoutColons := strings .Replace (macBlock , ":" , "" , - 1 )
701+ if macWithoutColons == macAddress { // we are in the correct device block
702+ returnNextIP = true
703+ }
704+ }
705+ } else if strings .HasPrefix (line , "inet" ) && ! strings .HasPrefix (line , "inet6" ) && returnNextIP {
706+ vals := strings .Split (line , " " )
707+ if len (vals ) >= 2 {
708+ return vals [1 ][:strings .Index (vals [1 ], "/" )], nil
709+ }
710+ }
711+ }
712+
713+ return "" , fmt .Errorf ("Could not find matching IP for MAC address %v" , macAddress )
714+ }
715+
655716func (d * Driver ) GetIP () (string , error ) {
656717 // DHCP is used to get the IP, so virtualbox hosts don't have IPs unless
657718 // they are running
@@ -663,23 +724,26 @@ func (d *Driver) GetIP() (string, error) {
663724 return "" , drivers .ErrHostIsNotRunning
664725 }
665726
666- output , err := drivers .RunSSHCommandFromDriver (d , "ip addr show dev eth1" )
727+ macAddress , err := d .getHostOnlyMACAddress ()
728+ if err != nil {
729+ return "" , err
730+ }
731+
732+ log .Debugf ("Host-only MAC: %s\n " , macAddress )
733+
734+ output , err := drivers .RunSSHCommandFromDriver (d , "ip addr show" )
667735 if err != nil {
668736 return "" , err
669737 }
670738
671739 log .Debugf ("SSH returned: %s\n END SSH\n " , output )
672740
673- // parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1
674- lines := strings .Split (output , "\n " )
675- for _ , line := range lines {
676- vals := strings .Split (strings .TrimSpace (line ), " " )
677- if len (vals ) >= 2 && vals [0 ] == "inet" {
678- return vals [1 ][:strings .Index (vals [1 ], "/" )], nil
679- }
741+ ipAddress , err := d .parseIPForMACFromIPAddr (output , macAddress )
742+ if err != nil {
743+ return "" , err
680744 }
681745
682- return "" , fmt . Errorf ( "No IP address found %s" , output )
746+ return ipAddress , nil
683747}
684748
685749func (d * Driver ) publicSSHKeyPath () string {
0 commit comments