forked from denisbrodbeck/machineid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathid_linux.go
80 lines (64 loc) · 1.92 KB
/
id_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//go:build linux
// +build linux
package machineid
import (
"errors"
"regexp"
"strings"
)
const (
// dbusPath is the default path for dbus machine id.
dbusPath = "/var/lib/dbus/machine-id"
// dbusPathEtc is the default path for dbus machine id located in /etc.
// Some systems (like Fedora 20) only know this path.
// Sometimes it's the other way round.
dbusPathEtc = "/etc/machine-id"
// For older docker versions
cgroupPath = "/proc/self/cgroup"
// Modern docker versions should contain this information and
// can be used as the machine-id
mountInfoPath = "/proc/self/mountinfo"
)
// machineID returns the uuid specified at `/var/lib/dbus/machine-id` or `/etc/machine-id`.
// In case of Docker, it also checks for `/proc/self/cgroup` and `/proc/self/mountinfo`.
// If there is an error reading the files an empty string is returned.
// See https://unix.stackexchange.com/questions/144812/generate-consistent-machine-unique-id
func machineID() (string, error) {
id, err := getFirstValidValue(
getIDFromFile(dbusPath),
getIDFromFile(dbusPathEtc),
getCGroup,
getMountInfo,
)
if err != nil {
return "", err
}
return trim(id), nil
}
func getCGroup() (string, error) {
cgroup, err := readFile(cgroupPath)
if err != nil {
return "", nil
}
groups := strings.Split(string(cgroup), "/")
if len(groups) < 3 {
return "", errors.New("cgroup is not complete")
}
return groups[2], nil
}
var containerIDRegex = regexp.MustCompile(`\/docker\/containers/([a-f0-9]+)/hostname`)
func getMountInfo() (string, error) {
mountInfoBytes, err := readFile(mountInfoPath)
if err != nil {
return "", err
}
mountInfo := string(mountInfoBytes)
if !strings.Contains(mountInfo, "docker") {
return "", errors.New("environment is not a docker container")
}
foundGroups := containerIDRegex.FindStringSubmatch(mountInfo)
if len(foundGroups) < 2 {
return "", errors.New("no docker mountinfo found")
}
return foundGroups[1], nil
}