diff --git a/info/v1/machine.go b/info/v1/machine.go index d880372c27a0a..719a3eac1bcd0 100644 --- a/info/v1/machine.go +++ b/info/v1/machine.go @@ -122,6 +122,12 @@ type MachineInfo struct { // The amount of memory (in bytes) in this machine MemoryCapacity int64 `json:"memory_capacity"` + // The machine id + MachineID string `json:"machine_id"` + + // The system uuid + SystemUUID string `json:"system_uuid"` + // Filesystems on this machine. Filesystems []FsInfo `json:"filesystems"` diff --git a/manager/machine.go b/manager/machine.go index bbb36c9955fc2..a3d840dcc9d55 100644 --- a/manager/machine.go +++ b/manager/machine.go @@ -16,6 +16,7 @@ package manager import ( "bytes" + "flag" "fmt" "io/ioutil" "regexp" @@ -24,6 +25,7 @@ import ( "syscall" dclient "github.com/fsouza/go-dockerclient" + "github.com/golang/glog" "github.com/google/cadvisor/container/docker" "github.com/google/cadvisor/fs" info "github.com/google/cadvisor/info/v1" @@ -39,6 +41,8 @@ var nodeRegExp = regexp.MustCompile("physical id\\t*: +([0-9]+)") var CpuClockSpeedMHz = regexp.MustCompile("cpu MHz\\t*: +([0-9]+.[0-9]+)") var memoryCapacityRegexp = regexp.MustCompile("MemTotal: *([0-9]+) kB") +var machineIdFilePath = flag.String("machine_id_file", "/etc/machine-id", "File containing the machine-id") + func getClockSpeed(procInfo []byte) (uint64, error) { // First look through sys to find a max supported cpu frequency. const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" @@ -205,6 +209,15 @@ func getTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) { return nodes, numCores, nil } +func getMachineID() string { + id, err := ioutil.ReadFile(*machineIdFilePath) + if err != nil { + glog.Error("Couldn't collect machine-id: ", err) + return "" + } + return strings.TrimSpace(string(id)) +} + func getMachineInfo(sysFs sysfs.SysFs) (*info.MachineInfo, error) { cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo") clockSpeed, err := getClockSpeed(cpuinfo) @@ -247,6 +260,11 @@ func getMachineInfo(sysFs sysfs.SysFs) (*info.MachineInfo, error) { return nil, err } + system_uuid, err := sysinfo.GetSystemUUID(sysFs) + if err != nil { + return nil, err + } + machineInfo := &info.MachineInfo{ NumCores: numCores, CpuFrequency: clockSpeed, @@ -254,6 +272,8 @@ func getMachineInfo(sysFs sysfs.SysFs) (*info.MachineInfo, error) { DiskMap: diskMap, NetworkDevices: netDevices, Topology: topology, + MachineID: getMachineID(), + SystemUUID: system_uuid, } for _, fs := range filesystems { diff --git a/utils/sysfs/fakesysfs/fake.go b/utils/sysfs/fakesysfs/fake.go index 9c7db1fec69a4..963fc61eff88f 100644 --- a/utils/sysfs/fakesysfs/fake.go +++ b/utils/sysfs/fakesysfs/fake.go @@ -108,3 +108,7 @@ func (self *FakeSysFs) SetCacheInfo(cache sysfs.CacheInfo) { func (self *FakeSysFs) SetEntryName(name string) { self.info.EntryName = name } + +func (self *FakeSysFs) GetSystemUUID() (string, error) { + return "1F862619-BA9F-4526-8F85-ECEAF0C97430", nil +} diff --git a/utils/sysfs/sysfs.go b/utils/sysfs/sysfs.go index 61b19db517611..d33b9d0091f24 100644 --- a/utils/sysfs/sysfs.go +++ b/utils/sysfs/sysfs.go @@ -27,6 +27,7 @@ const ( blockDir = "/sys/block" cacheDir = "/sys/devices/system/cpu/cpu" netDir = "/sys/class/net" + dmiDir = "/sys/class/dmi" ) type CacheInfo struct { @@ -61,6 +62,8 @@ type SysFs interface { GetCaches(id int) ([]os.FileInfo, error) // Get information for a cache accessible from the given cpu. GetCacheInfo(cpu int, cache string) (CacheInfo, error) + + GetSystemUUID() (string, error) } type realSysFs struct{} @@ -228,3 +231,11 @@ func (self *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) { Cpus: cpuCount, }, nil } + +func (self *realSysFs) GetSystemUUID() (string, error) { + id, err := ioutil.ReadFile(path.Join(dmiDir, "id", "product_uuid")) + if err != nil { + return "", err + } + return strings.TrimSpace(string(id)), nil +} diff --git a/utils/sysinfo/sysinfo.go b/utils/sysinfo/sysinfo.go index 98de336b0bbd3..9d6a6208d88c4 100644 --- a/utils/sysinfo/sysinfo.go +++ b/utils/sysinfo/sysinfo.go @@ -204,3 +204,7 @@ func getNetworkStats(name string, sysFs sysfs.SysFs) (info.NetworkStats, error) } return stats, nil } + +func GetSystemUUID(sysFs sysfs.SysFs) (string, error) { + return sysFs.GetSystemUUID() +}