podman
191 строка · 4.8 Кб
1package buildah
2
3import (
4"bufio"
5"bytes"
6"fmt"
7"os"
8"runtime"
9"strconv"
10"strings"
11
12internalUtil "github.com/containers/buildah/internal/util"
13putil "github.com/containers/buildah/pkg/util"
14"github.com/containers/buildah/util"
15"github.com/containers/common/pkg/cgroups"
16"github.com/containers/storage"
17"github.com/containers/storage/pkg/system"
18"github.com/containers/storage/pkg/unshare"
19v1 "github.com/opencontainers/image-spec/specs-go/v1"
20"github.com/sirupsen/logrus"
21)
22
23// InfoData holds the info type, i.e store, host etc and the data for each type
24type InfoData struct {
25Type string
26Data map[string]interface{}
27}
28
29// Info returns the store and host information
30func Info(store storage.Store) ([]InfoData, error) {
31info := []InfoData{}
32// get host information
33hostInfo := hostInfo()
34info = append(info, InfoData{Type: "host", Data: hostInfo})
35
36// get store information
37storeInfo, err := storeInfo(store)
38if err != nil {
39logrus.Error(err, "error getting store info")
40}
41info = append(info, InfoData{Type: "store", Data: storeInfo})
42return info, nil
43}
44
45func hostInfo() map[string]interface{} {
46info := map[string]interface{}{}
47ps := internalUtil.NormalizePlatform(v1.Platform{OS: runtime.GOOS, Architecture: runtime.GOARCH})
48info["os"] = ps.OS
49info["arch"] = ps.Architecture
50info["variant"] = ps.Variant
51info["cpus"] = runtime.NumCPU()
52info["rootless"] = unshare.IsRootless()
53
54unified, err := cgroups.IsCgroup2UnifiedMode()
55if err != nil {
56logrus.Error(err, "err reading cgroups mode")
57}
58cgroupVersion := "v1"
59ociruntime := util.Runtime()
60if unified {
61cgroupVersion = "v2"
62}
63info["CgroupVersion"] = cgroupVersion
64info["OCIRuntime"] = ociruntime
65
66mi, err := system.ReadMemInfo()
67if err != nil {
68logrus.Error(err, "err reading memory info")
69info["MemTotal"] = ""
70info["MemFree"] = ""
71info["SwapTotal"] = ""
72info["SwapFree"] = ""
73} else {
74info["MemTotal"] = mi.MemTotal
75info["MemFree"] = mi.MemFree
76info["SwapTotal"] = mi.SwapTotal
77info["SwapFree"] = mi.SwapFree
78}
79hostDistributionInfo := getHostDistributionInfo()
80info["Distribution"] = map[string]interface{}{
81"distribution": hostDistributionInfo["Distribution"],
82"version": hostDistributionInfo["Version"],
83}
84
85kv, err := putil.ReadKernelVersion()
86if err != nil {
87logrus.Error(err, "error reading kernel version")
88}
89info["kernel"] = kv
90
91upDuration, err := putil.ReadUptime()
92if err != nil {
93logrus.Error(err, "error reading up time")
94}
95
96hoursFound := false
97var timeBuffer bytes.Buffer
98var hoursBuffer bytes.Buffer
99for _, elem := range upDuration.String() {
100timeBuffer.WriteRune(elem)
101if elem == 'h' || elem == 'm' {
102timeBuffer.WriteRune(' ')
103if elem == 'h' {
104hoursFound = true
105}
106}
107if !hoursFound {
108hoursBuffer.WriteRune(elem)
109}
110}
111
112info["uptime"] = timeBuffer.String()
113if hoursFound {
114hours, err := strconv.ParseFloat(hoursBuffer.String(), 64)
115if err == nil {
116days := hours / 24
117info["uptime"] = fmt.Sprintf("%s (Approximately %.2f days)", info["uptime"], days)
118}
119}
120
121host, err := os.Hostname()
122if err != nil {
123logrus.Error(err, "error getting hostname")
124}
125info["hostname"] = host
126
127return info
128}
129
130// top-level "store" info
131func storeInfo(store storage.Store) (map[string]interface{}, error) {
132// lets say storage driver in use, number of images, number of containers
133info := map[string]interface{}{}
134info["GraphRoot"] = store.GraphRoot()
135info["RunRoot"] = store.RunRoot()
136info["GraphDriverName"] = store.GraphDriverName()
137info["GraphOptions"] = store.GraphOptions()
138statusPairs, err := store.Status()
139if err != nil {
140return nil, err
141}
142status := map[string]string{}
143for _, pair := range statusPairs {
144status[pair[0]] = pair[1]
145}
146info["GraphStatus"] = status
147images, err := store.Images()
148if err != nil {
149logrus.Error(err, "error getting number of images")
150}
151info["ImageStore"] = map[string]interface{}{
152"number": len(images),
153}
154
155containers, err := store.Containers()
156if err != nil {
157logrus.Error(err, "error getting number of containers")
158}
159info["ContainerStore"] = map[string]interface{}{
160"number": len(containers),
161}
162
163return info, nil
164}
165
166// getHostDistributionInfo returns a map containing the host's distribution and version
167func getHostDistributionInfo() map[string]string {
168dist := make(map[string]string)
169
170// Populate values in case we cannot find the values
171// or the file
172dist["Distribution"] = "unknown"
173dist["Version"] = "unknown"
174
175f, err := os.Open("/etc/os-release")
176if err != nil {
177return dist
178}
179defer f.Close()
180
181l := bufio.NewScanner(f)
182for l.Scan() {
183if strings.HasPrefix(l.Text(), "ID=") {
184dist["Distribution"] = strings.TrimPrefix(l.Text(), "ID=")
185}
186if strings.HasPrefix(l.Text(), "VERSION_ID=") {
187dist["Version"] = strings.Trim(strings.TrimPrefix(l.Text(), "VERSION_ID="), "\"")
188}
189}
190return dist
191}
192