github.com/mitchellh/packer@v1.3.2/builder/vmware/common/host_ip_ifconfig.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"os"
     7  	"os/exec"
     8  	"regexp"
     9  )
    10  
    11  // IfconfigIPFinder finds the host IP based on the output of `ip address` or `ifconfig`.
    12  type IfconfigIPFinder struct {
    13  	Device string
    14  }
    15  
    16  func (f *IfconfigIPFinder) HostIP() (string, error) {
    17  	ip, err := ipaddress(f.Device)
    18  	if err != nil || ip == "" {
    19  		return ifconfig(f.Device)
    20  	}
    21  	return ip, err
    22  }
    23  
    24  func ipaddress(device string) (string, error) {
    25  	var ipPath string
    26  
    27  	// On some systems, ip is in /sbin which is generally not
    28  	// on the PATH for a standard user, so we just check that first.
    29  	if _, err := os.Stat("/sbin/ip"); err == nil {
    30  		ipPath = "/sbin/ip"
    31  	}
    32  
    33  	if ipPath == "" {
    34  		var err error
    35  		ipPath, err = exec.LookPath("ip")
    36  		if err != nil {
    37  			return "", err
    38  		}
    39  	}
    40  
    41  	stdout := new(bytes.Buffer)
    42  	cmd := exec.Command(ipPath, "address", "show", "dev", device)
    43  	// Force LANG=C so that the output is what we expect it to be
    44  	// despite the locale.
    45  	cmd.Env = append(cmd.Env, "LANG=C")
    46  	cmd.Env = append(cmd.Env, os.Environ()...)
    47  
    48  	cmd.Stdout = stdout
    49  	cmd.Stderr = new(bytes.Buffer)
    50  	if err := cmd.Run(); err != nil {
    51  		return "", err
    52  	}
    53  
    54  	re := regexp.MustCompile(`inet[^\d]+([\d\.]+)/`)
    55  	matches := re.FindStringSubmatch(stdout.String())
    56  	if matches == nil {
    57  		return "", errors.New("IP not found in ip a output...")
    58  	}
    59  
    60  	return matches[1], nil
    61  }
    62  
    63  func ifconfig(device string) (string, error) {
    64  	var ifconfigPath string
    65  
    66  	// On some systems, ifconfig is in /sbin which is generally not
    67  	// on the PATH for a standard user, so we just check that first.
    68  	if _, err := os.Stat("/sbin/ifconfig"); err == nil {
    69  		ifconfigPath = "/sbin/ifconfig"
    70  	}
    71  
    72  	if ifconfigPath == "" {
    73  		var err error
    74  		ifconfigPath, err = exec.LookPath("ifconfig")
    75  		if err != nil {
    76  			return "", err
    77  		}
    78  	}
    79  
    80  	stdout := new(bytes.Buffer)
    81  
    82  	cmd := exec.Command(ifconfigPath, device)
    83  	// Force LANG=C so that the output is what we expect it to be
    84  	// despite the locale.
    85  	cmd.Env = append(cmd.Env, "LANG=C")
    86  	cmd.Env = append(cmd.Env, os.Environ()...)
    87  
    88  	cmd.Stdout = stdout
    89  	cmd.Stderr = new(bytes.Buffer)
    90  	if err := cmd.Run(); err != nil {
    91  		return "", err
    92  	}
    93  
    94  	re := regexp.MustCompile(`inet[^\d]+([\d\.]+)\s`)
    95  	matches := re.FindStringSubmatch(stdout.String())
    96  	if matches == nil {
    97  		return "", errors.New("IP not found in ifconfig output...")
    98  	}
    99  
   100  	return matches[1], nil
   101  }