From 9226ccae31d1416fab3ec090fa3d629c68561a16 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Mon, 21 Nov 2022 16:01:14 -0700 Subject: [PATCH] system: more detailed system information --- router/router_system.go | 20 ++++++- system/system.go | 130 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 138 insertions(+), 12 deletions(-) diff --git a/router/router_system.go b/router/router_system.go index 0ab6585..013abfc 100644 --- a/router/router_system.go +++ b/router/router_system.go @@ -21,11 +21,27 @@ func getSystemInformation(c *gin.Context) { i, err := system.GetSystemInformation() if err != nil { NewTrackedError(err).Abort(c) - return } - c.JSON(http.StatusOK, i) + if c.Query("v") == "2" { + c.JSON(http.StatusOK, i) + return + } + + c.JSON(http.StatusOK, struct { + Architecture string `json:"architecture"` + CPUCount int `json:"cpu_count"` + KernelVersion string `json:"kernel_version"` + OS string `json:"os"` + Version string `json:"version"` + }{ + Architecture: i.System.Architecture, + CPUCount: i.System.CPUThreads, + KernelVersion: i.System.KernelVersion, + OS: i.System.OSType, + Version: i.Version, + }) } // Returns all the servers that are registered and configured correctly on diff --git a/system/system.go b/system/system.go index 5a9a3cb..a8d8006 100644 --- a/system/system.go +++ b/system/system.go @@ -1,17 +1,57 @@ package system import ( + "context" "runtime" + "github.com/acobaugh/osrelease" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" "github.com/docker/docker/pkg/parsers/kernel" ) type Information struct { - Version string `json:"version"` - KernelVersion string `json:"kernel_version"` + Version string `json:"version"` + Docker DockerInformation `json:"docker"` + System System `json:"system"` +} + +type DockerInformation struct { + Version string `json:"version"` + Cgroups DockerCgroups `json:"cgroups"` + Containers DockerContainers `json:"containers"` + Storage DockerStorage `json:"storage"` + Runc DockerRunc `json:"runc"` +} + +type DockerCgroups struct { + Driver string `json:"driver"` + Version string `json:"version"` +} + +type DockerContainers struct { + Total int `json:"total"` + Running int `json:"running"` + Paused int `json:"paused"` + Stopped int `json:"stopped"` +} + +type DockerStorage struct { + Driver string `json:"driver"` + Filesystem string `json:"filesystem"` +} + +type DockerRunc struct { + Version string `json:"version"` +} + +type System struct { Architecture string `json:"architecture"` + CPUThreads int `json:"cpu_threads"` + MemoryBytes int64 `json:"memory_bytes"` + KernelVersion string `json:"kernel_version"` OS string `json:"os"` - CpuCount int `json:"cpu_count"` + OSType string `json:"os_type"` } func GetSystemInformation() (*Information, error) { @@ -20,13 +60,83 @@ func GetSystemInformation() (*Information, error) { return nil, err } - s := &Information{ - Version: Version, - KernelVersion: k.String(), - Architecture: runtime.GOARCH, - OS: runtime.GOOS, - CpuCount: runtime.NumCPU(), + version, info, err := GetDockerInfo(context.Background()) + if err != nil { + return nil, err } - return s, nil + release, err := osrelease.Read() + if err != nil { + return nil, err + } + + var os string + if release["PRETTY_NAME"] != "" { + os = release["PRETTY_NAME"] + } else if release["NAME"] != "" { + os = release["NAME"] + } else { + os = info.OperatingSystem + } + + var filesystem string + for _, v := range info.DriverStatus { + if v[0] != "Backing Filesystem" { + continue + } + filesystem = v[1] + break + } + + return &Information{ + Version: Version, + Docker: DockerInformation{ + Version: version.Version, + Cgroups: DockerCgroups{ + Driver: info.CgroupDriver, + Version: info.CgroupVersion, + }, + Containers: DockerContainers{ + Total: info.Containers, + Running: info.ContainersRunning, + Paused: info.ContainersPaused, + Stopped: info.ContainersStopped, + }, + Storage: DockerStorage{ + Driver: info.Driver, + Filesystem: filesystem, + }, + Runc: DockerRunc{ + Version: info.RuncCommit.ID, + }, + }, + System: System{ + Architecture: runtime.GOARCH, + CPUThreads: runtime.NumCPU(), + MemoryBytes: info.MemTotal, + KernelVersion: k.String(), + OS: os, + OSType: runtime.GOOS, + }, + }, nil +} + +func GetDockerInfo(ctx context.Context) (types.Version, types.Info, error) { + // TODO: find a way to re-use the client from the docker environment. + c, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return types.Version{}, types.Info{}, err + } + + dockerVersion, err := c.ServerVersion(ctx) + if err != nil { + return types.Version{}, types.Info{}, err + } + + dockerInfo, err := c.Info(ctx) + if err != nil { + return types.Version{}, types.Info{}, err + } + + return dockerVersion, dockerInfo, nil }