diff --git a/client/fingerprint/network.go b/client/fingerprint/network.go index 19b4ec5a4..ebea7bc9c 100644 --- a/client/fingerprint/network.go +++ b/client/fingerprint/network.go @@ -3,13 +3,8 @@ package fingerprint import ( "errors" "fmt" - "io/ioutil" "log" "net" - "os/exec" - "regexp" - "strconv" - "strings" "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/nomad/structs" @@ -78,7 +73,7 @@ func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) newNetwork.IP = ip newNetwork.CIDR = newNetwork.IP + "/32" - f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP %v during fingerprinting", intf.Name, ip) + f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP %v during fingerprinting", intf.Name, ip) if throughput := f.linkSpeed(intf.Name); throughput > 0 { newNetwork.MBits = throughput @@ -97,74 +92,6 @@ func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) return true, nil } -// linkSpeed returns link speed in Mb/s, or 0 when unable to determine it. -func (f *NetworkFingerprint) linkSpeed(device string) int { - // Use LookPath to find the ethtool in the systems $PATH - // If it's not found or otherwise errors, LookPath returns and empty string - // and an error we can ignore for our purposes - ethtoolPath, _ := exec.LookPath("ethtool") - if ethtoolPath != "" { - if speed := f.linkSpeedEthtool(ethtoolPath, device); speed > 0 { - return speed - } - } - - // Fall back on checking a system file for link speed. - return f.linkSpeedSys(device) -} - -// linkSpeedSys parses link speed in Mb/s from /sys. -func (f *NetworkFingerprint) linkSpeedSys(device string) int { - path := fmt.Sprintf("/sys/class/net/%s/speed", device) - - // Read contents of the device/speed file - content, err := ioutil.ReadFile(path) - if err != nil { - f.logger.Printf("[WARN] fingerprint.network: Unable to read link speed from %s", path) - return 0 - } - - lines := strings.Split(string(content), "\n") - mbs, err := strconv.Atoi(lines[0]) - if err != nil || mbs <= 0 { - f.logger.Printf("[WARN] fingerprint.network: Unable to parse link speed from %s", path) - return 0 - } - - return mbs -} - -// linkSpeedEthtool determines link speed in Mb/s with 'ethtool'. -func (f *NetworkFingerprint) linkSpeedEthtool(path, device string) int { - outBytes, err := exec.Command(path, device).Output() - if err != nil { - f.logger.Printf("[WARN] fingerprint.network: Error calling ethtool (%s %s): %v", path, device, err) - return 0 - } - - output := strings.TrimSpace(string(outBytes)) - re := regexp.MustCompile("Speed: [0-9]+[a-zA-Z]+/s") - m := re.FindString(output) - if m == "" { - // no matches found, output may be in a different format - f.logger.Printf("[WARN] fingerprint.network: Unable to parse Speed in output of '%s %s'", path, device) - return 0 - } - - // Split and trim the Mb/s unit from the string output - args := strings.Split(m, ": ") - raw := strings.TrimSuffix(args[1], "Mb/s") - - // convert to Mb/s - mbs, err := strconv.Atoi(raw) - if err != nil || mbs <= 0 { - f.logger.Printf("[WARN] fingerprint.network: Unable to parse Mb/s in output of '%s %s'", path, device) - return 0 - } - - return mbs -} - // Gets the ipv4 addr for a network interface func (f *NetworkFingerprint) ipAddress(intf *net.Interface) (string, error) { var addrs []net.Addr diff --git a/client/fingerprint/network_default.go b/client/fingerprint/network_default.go new file mode 100644 index 000000000..f24479b85 --- /dev/null +++ b/client/fingerprint/network_default.go @@ -0,0 +1,8 @@ +// +build !linux + +package fingerprint + +// linkSpeed returns the default link speed +func (f *NetworkFingerprint) linkSpeed(device string) int { + return 0 +} diff --git a/client/fingerprint/network_linux.go b/client/fingerprint/network_linux.go new file mode 100644 index 000000000..34827364f --- /dev/null +++ b/client/fingerprint/network_linux.go @@ -0,0 +1,78 @@ +package fingerprint + +import ( + "fmt" + "io/ioutil" + "os/exec" + "regexp" + "strconv" + "strings" +) + +// linkSpeedSys parses link speed in Mb/s from /sys. +func (f *NetworkFingerprint) linkSpeedSys(device string) int { + path := fmt.Sprintf("/sys/class/net/%s/speed", device) + + // Read contents of the device/speed file + content, err := ioutil.ReadFile(path) + if err != nil { + f.logger.Printf("[WARN] fingerprint.network: Unable to read link speed from %s", path) + return 0 + } + + lines := strings.Split(string(content), "\n") + mbs, err := strconv.Atoi(lines[0]) + if err != nil || mbs <= 0 { + f.logger.Printf("[WARN] fingerprint.network: Unable to parse link speed from %s", path) + return 0 + } + + return mbs +} + +// linkSpeed returns link speed in Mb/s, or 0 when unable to determine it. +func (f *NetworkFingerprint) linkSpeed(device string) int { + // Use LookPath to find the ethtool in the systems $PATH + // If it's not found or otherwise errors, LookPath returns and empty string + // and an error we can ignore for our purposes + ethtoolPath, _ := exec.LookPath("ethtool") + if ethtoolPath != "" { + if speed := f.linkSpeedEthtool(ethtoolPath, device); speed > 0 { + return speed + } + } + + // Fall back on checking a system file for link speed. + return f.linkSpeedSys(device) +} + +// linkSpeedEthtool determines link speed in Mb/s with 'ethtool'. +func (f *NetworkFingerprint) linkSpeedEthtool(path, device string) int { + outBytes, err := exec.Command(path, device).Output() + if err != nil { + f.logger.Printf("[WARN] fingerprint.network: Error calling ethtool (%s %s): %v", path, device, err) + return 0 + } + + output := strings.TrimSpace(string(outBytes)) + re := regexp.MustCompile("Speed: [0-9]+[a-zA-Z]+/s") + m := re.FindString(output) + if m == "" { + // no matches found, output may be in a different format + f.logger.Printf("[WARN] fingerprint.network: Unable to parse Speed in output of '%s %s'", path, device) + return 0 + } + + // Split and trim the Mb/s unit from the string output + args := strings.Split(m, ": ") + raw := strings.TrimSuffix(args[1], "Mb/s") + + // convert to Mb/s + mbs, err := strconv.Atoi(raw) + if err != nil || mbs <= 0 { + f.logger.Printf("[WARN] fingerprint.network: Unable to parse Mb/s in output of '%s %s'", path, device) + return 0 + } + + return mbs +}