github.com/aitjcize/Overlord@v0.0.0-20240314041920-104a804cf5e8/overlord/sysutils_linux.go (about)

     1  // Copyright 2015 The Chromium OS Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package overlord
     6  
     7  import (
     8  	"bufio"
     9  	"encoding/hex"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"strings"
    14  
    15  	uuid "github.com/satori/go.uuid"
    16  )
    17  
    18  // GetGateWayIP return the IPs of the gateways.
    19  func GetGateWayIP() ([]string, error) {
    20  	f, err := os.Open("/proc/net/route")
    21  	if err != nil {
    22  		return nil, nil
    23  	}
    24  	defer f.Close()
    25  
    26  	var ips []string
    27  	reader := bufio.NewReader(f)
    28  	for {
    29  		line, err := reader.ReadString('\n')
    30  		if err != nil {
    31  			break
    32  		}
    33  		fields := strings.Split(line, "\t")
    34  		if len(fields) >= 3 {
    35  			gatewayHex := fields[2]
    36  			if gatewayHex != "00000000" {
    37  				h, err := hex.DecodeString(gatewayHex)
    38  				if err != nil {
    39  					continue
    40  				}
    41  				ip := fmt.Sprintf("%d.%d.%d.%d", h[3], h[2], h[1], h[0])
    42  				ips = append(ips, ip)
    43  			}
    44  		}
    45  	}
    46  
    47  	return ips, nil
    48  }
    49  
    50  // GetMachineID generates machine-dependent ID string for a machine.
    51  // There are many ways to generate a machine ID:
    52  // 1. /sys/class/dmi/id/product_uuid (only available on intel machines)
    53  // 2. MAC address
    54  // We follow the listed order to generate machine ID, and fallback to the next
    55  // alternative if the previous doesn't work.
    56  func GetMachineID() (string, error) {
    57  	buf := make([]byte, 64)
    58  	f, err := os.Open("/sys/class/dmi/id/product_uuid")
    59  	if err == nil {
    60  		if n, err := f.Read(buf); err == nil {
    61  			return strings.TrimSpace(string(buf[:n])), nil
    62  		}
    63  	}
    64  
    65  	interfaces, err := ioutil.ReadDir("/sys/class/net")
    66  	if err == nil {
    67  		mid := ""
    68  		for _, iface := range interfaces {
    69  			if iface.Name() == "lo" {
    70  				continue
    71  			}
    72  			addrPath := fmt.Sprintf("/sys/class/net/%s/address", iface.Name())
    73  			f, err := os.Open(addrPath)
    74  			if err != nil {
    75  				break
    76  			}
    77  			if n, err := f.Read(buf); err == nil {
    78  				mid += strings.TrimSpace(string(buf[:n])) + ";"
    79  			}
    80  		}
    81  		mid = strings.Trim(mid, ";")
    82  
    83  		if mid == "" {
    84  			mid = uuid.NewV4().String()
    85  		}
    86  		return mid, nil
    87  	}
    88  
    89  	// Fallback to a random UUID.
    90  	return uuid.NewV4().String(), nil
    91  }
    92  
    93  // GetProcessWorkingDirectory returns the current working directory of a process.
    94  func GetProcessWorkingDirectory(pid int) (string, error) {
    95  	return os.Readlink(fmt.Sprintf("/proc/%d/cwd", pid))
    96  }