mirror of https://github.com/containers/podman.git
197 lines
6.4 KiB
Go
197 lines
6.4 KiB
Go
package generic
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
goRuntime "runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/containers/libpod/libpod"
|
|
"github.com/containers/libpod/libpod/config"
|
|
"github.com/containers/libpod/libpod/define"
|
|
"github.com/containers/libpod/pkg/api/handlers"
|
|
"github.com/containers/libpod/pkg/api/handlers/utils"
|
|
"github.com/containers/libpod/pkg/rootless"
|
|
"github.com/containers/libpod/pkg/sysinfo"
|
|
docker "github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"github.com/google/uuid"
|
|
"github.com/pkg/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func GetInfo(w http.ResponseWriter, r *http.Request) {
|
|
// 200 ok
|
|
// 500 internal
|
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
|
|
|
infoData, err := runtime.Info()
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain system memory info"))
|
|
return
|
|
}
|
|
hostInfo := infoData[0].Data
|
|
storeInfo := infoData[1].Data
|
|
|
|
configInfo, err := runtime.GetConfig()
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain runtime config"))
|
|
return
|
|
}
|
|
versionInfo, err := define.GetVersion()
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain podman versions"))
|
|
return
|
|
}
|
|
stateInfo := getContainersState(runtime)
|
|
sysInfo := sysinfo.New(true)
|
|
|
|
// FIXME: Need to expose if runtime supports Checkpoint'ing
|
|
// liveRestoreEnabled := criu.CheckForCriu() && configInfo.RuntimeSupportsCheckpoint()
|
|
|
|
info := &handlers.Info{Info: docker.Info{
|
|
Architecture: goRuntime.GOARCH,
|
|
BridgeNfIP6tables: !sysInfo.BridgeNFCallIP6TablesDisabled,
|
|
BridgeNfIptables: !sysInfo.BridgeNFCallIPTablesDisabled,
|
|
CPUCfsPeriod: sysInfo.CPUCfsPeriod,
|
|
CPUCfsQuota: sysInfo.CPUCfsQuota,
|
|
CPUSet: sysInfo.Cpuset,
|
|
CPUShares: sysInfo.CPUShares,
|
|
CgroupDriver: configInfo.CgroupManager,
|
|
ClusterAdvertise: "",
|
|
ClusterStore: "",
|
|
ContainerdCommit: docker.Commit{},
|
|
Containers: storeInfo["ContainerStore"].(map[string]interface{})["number"].(int),
|
|
ContainersPaused: stateInfo[define.ContainerStatePaused],
|
|
ContainersRunning: stateInfo[define.ContainerStateRunning],
|
|
ContainersStopped: stateInfo[define.ContainerStateStopped] + stateInfo[define.ContainerStateExited],
|
|
Debug: log.IsLevelEnabled(log.DebugLevel),
|
|
DefaultRuntime: configInfo.OCIRuntime,
|
|
DockerRootDir: storeInfo["GraphRoot"].(string),
|
|
Driver: storeInfo["GraphDriverName"].(string),
|
|
DriverStatus: getGraphStatus(storeInfo),
|
|
ExperimentalBuild: true,
|
|
GenericResources: nil,
|
|
HTTPProxy: getEnv("http_proxy"),
|
|
HTTPSProxy: getEnv("https_proxy"),
|
|
ID: uuid.New().String(),
|
|
IPv4Forwarding: !sysInfo.IPv4ForwardingDisabled,
|
|
Images: storeInfo["ImageStore"].(map[string]interface{})["number"].(int),
|
|
IndexServerAddress: "",
|
|
InitBinary: "",
|
|
InitCommit: docker.Commit{},
|
|
Isolation: "",
|
|
KernelMemory: sysInfo.KernelMemory,
|
|
KernelMemoryTCP: false,
|
|
KernelVersion: hostInfo["kernel"].(string),
|
|
Labels: nil,
|
|
LiveRestoreEnabled: false,
|
|
LoggingDriver: "",
|
|
MemTotal: hostInfo["MemTotal"].(int64),
|
|
MemoryLimit: sysInfo.MemoryLimit,
|
|
NCPU: goRuntime.NumCPU(),
|
|
NEventsListener: 0,
|
|
NFd: getFdCount(),
|
|
NGoroutines: goRuntime.NumGoroutine(),
|
|
Name: hostInfo["hostname"].(string),
|
|
NoProxy: getEnv("no_proxy"),
|
|
OSType: goRuntime.GOOS,
|
|
OSVersion: hostInfo["Distribution"].(map[string]interface{})["version"].(string),
|
|
OomKillDisable: sysInfo.OomKillDisable,
|
|
OperatingSystem: hostInfo["Distribution"].(map[string]interface{})["distribution"].(string),
|
|
PidsLimit: sysInfo.PidsLimit,
|
|
Plugins: docker.PluginsInfo{},
|
|
ProductLicense: "Apache-2.0",
|
|
RegistryConfig: nil,
|
|
RuncCommit: docker.Commit{},
|
|
Runtimes: getRuntimes(configInfo),
|
|
SecurityOptions: getSecOpts(sysInfo),
|
|
ServerVersion: versionInfo.Version,
|
|
SwapLimit: sysInfo.SwapLimit,
|
|
Swarm: swarm.Info{
|
|
LocalNodeState: swarm.LocalNodeStateInactive,
|
|
},
|
|
SystemStatus: nil,
|
|
SystemTime: time.Now().Format(time.RFC3339Nano),
|
|
Warnings: []string{},
|
|
},
|
|
BuildahVersion: hostInfo["BuildahVersion"].(string),
|
|
CPURealtimePeriod: sysInfo.CPURealtimePeriod,
|
|
CPURealtimeRuntime: sysInfo.CPURealtimeRuntime,
|
|
CgroupVersion: hostInfo["CgroupVersion"].(string),
|
|
Rootless: rootless.IsRootless(),
|
|
SwapFree: hostInfo["SwapFree"].(int64),
|
|
SwapTotal: hostInfo["SwapTotal"].(int64),
|
|
Uptime: hostInfo["uptime"].(string),
|
|
}
|
|
utils.WriteResponse(w, http.StatusOK, info)
|
|
}
|
|
|
|
func getGraphStatus(storeInfo map[string]interface{}) [][2]string {
|
|
var graphStatus [][2]string
|
|
for k, v := range storeInfo["GraphStatus"].(map[string]string) {
|
|
graphStatus = append(graphStatus, [2]string{k, v})
|
|
}
|
|
return graphStatus
|
|
}
|
|
|
|
func getSecOpts(sysInfo *sysinfo.SysInfo) []string {
|
|
var secOpts []string
|
|
if sysInfo.AppArmor {
|
|
secOpts = append(secOpts, "name=apparmor")
|
|
}
|
|
if sysInfo.Seccomp {
|
|
// FIXME: get profile name...
|
|
secOpts = append(secOpts, fmt.Sprintf("name=seccomp,profile=%s", "default"))
|
|
}
|
|
return secOpts
|
|
}
|
|
|
|
func getRuntimes(configInfo *config.Config) map[string]docker.Runtime {
|
|
var runtimes = map[string]docker.Runtime{}
|
|
for name, paths := range configInfo.OCIRuntimes {
|
|
runtimes[name] = docker.Runtime{
|
|
Path: paths[0],
|
|
Args: nil,
|
|
}
|
|
}
|
|
return runtimes
|
|
}
|
|
|
|
func getFdCount() (count int) {
|
|
count = -1
|
|
if entries, err := ioutil.ReadDir("/proc/self/fd"); err == nil {
|
|
count = len(entries)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Just ignoring Container errors here...
|
|
func getContainersState(r *libpod.Runtime) map[define.ContainerStatus]int {
|
|
var states = map[define.ContainerStatus]int{}
|
|
ctnrs, err := r.GetAllContainers()
|
|
if err == nil {
|
|
for _, ctnr := range ctnrs {
|
|
state, err := ctnr.State()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
states[state] += 1
|
|
}
|
|
}
|
|
return states
|
|
}
|
|
|
|
func getEnv(value string) string {
|
|
if v, exists := os.LookupEnv(strings.ToUpper(value)); exists {
|
|
return v
|
|
}
|
|
if v, exists := os.LookupEnv(strings.ToLower(value)); exists {
|
|
return v
|
|
}
|
|
return ""
|
|
}
|