package common import ( "bytes" "errors" "os" "os/exec" "regexp" ) // IfconfigIPFinder finds the host IP based on the output of `ifconfig`. type IfconfigIPFinder struct { Devices []string } // HostIP returns the host's IP address or an error if it could not be found // from the `ifconfig` output. func (f *IfconfigIPFinder) HostIP() (string, error) { var ifconfigPath string // On some systems, ifconfig is in /sbin which is generally not // on the PATH for a standard user, so we just check that first. if _, err := os.Stat("/sbin/ifconfig"); err == nil { ifconfigPath = "/sbin/ifconfig" } if ifconfigPath == "" { var err error ifconfigPath, err = exec.LookPath("ifconfig") if err != nil { return "", err } } for _, device := range f.Devices { stdout := new(bytes.Buffer) cmd := exec.Command(ifconfigPath, device) // Force LANG=C so that the output is what we expect it to be // despite the locale. cmd.Env = append(cmd.Env, "LANG=C") cmd.Env = append(cmd.Env, os.Environ()...) cmd.Stdout = stdout cmd.Stderr = new(bytes.Buffer) if err := cmd.Run(); err == nil { re := regexp.MustCompile(`inet\s+(?:addr:)?(.+?)\s`) matches := re.FindStringSubmatch(stdout.String()) if matches != nil { return matches[1], nil } } } return "", errors.New("IP not found in ifconfig output") }