github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/api/handlers/compat/info.go (about)

     1  package compat
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"os"
     8  	goRuntime "runtime"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/containers/common/pkg/config"
    13  	"github.com/containers/libpod/libpod"
    14  	"github.com/containers/libpod/libpod/define"
    15  	"github.com/containers/libpod/pkg/api/handlers"
    16  	"github.com/containers/libpod/pkg/api/handlers/utils"
    17  	"github.com/containers/libpod/pkg/rootless"
    18  	"github.com/containers/libpod/pkg/sysinfo"
    19  	docker "github.com/docker/docker/api/types"
    20  	"github.com/docker/docker/api/types/swarm"
    21  	"github.com/google/uuid"
    22  	"github.com/pkg/errors"
    23  	log "github.com/sirupsen/logrus"
    24  )
    25  
    26  func GetInfo(w http.ResponseWriter, r *http.Request) {
    27  	// 200 ok
    28  	// 500 internal
    29  	runtime := r.Context().Value("runtime").(*libpod.Runtime)
    30  
    31  	infoData, err := runtime.Info()
    32  	if err != nil {
    33  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain system memory info"))
    34  		return
    35  	}
    36  
    37  	configInfo, err := runtime.GetConfig()
    38  	if err != nil {
    39  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain runtime config"))
    40  		return
    41  	}
    42  	versionInfo, err := define.GetVersion()
    43  	if err != nil {
    44  		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to obtain podman versions"))
    45  		return
    46  	}
    47  	stateInfo := getContainersState(runtime)
    48  	sysInfo := sysinfo.New(true)
    49  
    50  	// FIXME: Need to expose if runtime supports Checkpoint'ing
    51  	// liveRestoreEnabled := criu.CheckForCriu() && configInfo.RuntimeSupportsCheckpoint()
    52  
    53  	info := &handlers.Info{Info: docker.Info{
    54  		Architecture:       goRuntime.GOARCH,
    55  		BridgeNfIP6tables:  !sysInfo.BridgeNFCallIP6TablesDisabled,
    56  		BridgeNfIptables:   !sysInfo.BridgeNFCallIPTablesDisabled,
    57  		CPUCfsPeriod:       sysInfo.CPUCfsPeriod,
    58  		CPUCfsQuota:        sysInfo.CPUCfsQuota,
    59  		CPUSet:             sysInfo.Cpuset,
    60  		CPUShares:          sysInfo.CPUShares,
    61  		CgroupDriver:       configInfo.Engine.CgroupManager,
    62  		ClusterAdvertise:   "",
    63  		ClusterStore:       "",
    64  		ContainerdCommit:   docker.Commit{},
    65  		Containers:         infoData.Store.ContainerStore.Number,
    66  		ContainersPaused:   stateInfo[define.ContainerStatePaused],
    67  		ContainersRunning:  stateInfo[define.ContainerStateRunning],
    68  		ContainersStopped:  stateInfo[define.ContainerStateStopped] + stateInfo[define.ContainerStateExited],
    69  		Debug:              log.IsLevelEnabled(log.DebugLevel),
    70  		DefaultRuntime:     configInfo.Engine.OCIRuntime,
    71  		DockerRootDir:      infoData.Store.GraphRoot,
    72  		Driver:             infoData.Store.GraphDriverName,
    73  		DriverStatus:       getGraphStatus(infoData.Store.GraphStatus),
    74  		ExperimentalBuild:  true,
    75  		GenericResources:   nil,
    76  		HTTPProxy:          getEnv("http_proxy"),
    77  		HTTPSProxy:         getEnv("https_proxy"),
    78  		ID:                 uuid.New().String(),
    79  		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
    80  		Images:             infoData.Store.ImageStore.Number,
    81  		IndexServerAddress: "",
    82  		InitBinary:         "",
    83  		InitCommit:         docker.Commit{},
    84  		Isolation:          "",
    85  		KernelMemory:       sysInfo.KernelMemory,
    86  		KernelMemoryTCP:    false,
    87  		KernelVersion:      infoData.Host.Kernel,
    88  		Labels:             nil,
    89  		LiveRestoreEnabled: false,
    90  		LoggingDriver:      "",
    91  		MemTotal:           infoData.Host.MemTotal,
    92  		MemoryLimit:        sysInfo.MemoryLimit,
    93  		NCPU:               goRuntime.NumCPU(),
    94  		NEventsListener:    0,
    95  		NFd:                getFdCount(),
    96  		NGoroutines:        goRuntime.NumGoroutine(),
    97  		Name:               infoData.Host.Hostname,
    98  		NoProxy:            getEnv("no_proxy"),
    99  		OSType:             goRuntime.GOOS,
   100  		OSVersion:          infoData.Host.Distribution.Version,
   101  		OomKillDisable:     sysInfo.OomKillDisable,
   102  		OperatingSystem:    infoData.Host.Distribution.Distribution,
   103  		PidsLimit:          sysInfo.PidsLimit,
   104  		Plugins:            docker.PluginsInfo{},
   105  		ProductLicense:     "Apache-2.0",
   106  		RegistryConfig:     nil,
   107  		RuncCommit:         docker.Commit{},
   108  		Runtimes:           getRuntimes(configInfo),
   109  		SecurityOptions:    getSecOpts(sysInfo),
   110  		ServerVersion:      versionInfo.Version,
   111  		SwapLimit:          sysInfo.SwapLimit,
   112  		Swarm: swarm.Info{
   113  			LocalNodeState: swarm.LocalNodeStateInactive,
   114  		},
   115  		SystemStatus: nil,
   116  		SystemTime:   time.Now().Format(time.RFC3339Nano),
   117  		Warnings:     []string{},
   118  	},
   119  		BuildahVersion:     infoData.Host.BuildahVersion,
   120  		CPURealtimePeriod:  sysInfo.CPURealtimePeriod,
   121  		CPURealtimeRuntime: sysInfo.CPURealtimeRuntime,
   122  		CgroupVersion:      infoData.Host.CGroupsVersion,
   123  		Rootless:           rootless.IsRootless(),
   124  		SwapFree:           infoData.Host.SwapFree,
   125  		SwapTotal:          infoData.Host.SwapTotal,
   126  		Uptime:             infoData.Host.Uptime,
   127  	}
   128  	utils.WriteResponse(w, http.StatusOK, info)
   129  }
   130  
   131  func getGraphStatus(storeInfo map[string]string) [][2]string {
   132  	var graphStatus [][2]string
   133  	for k, v := range storeInfo {
   134  		graphStatus = append(graphStatus, [2]string{k, v})
   135  	}
   136  	return graphStatus
   137  }
   138  
   139  func getSecOpts(sysInfo *sysinfo.SysInfo) []string {
   140  	var secOpts []string
   141  	if sysInfo.AppArmor {
   142  		secOpts = append(secOpts, "name=apparmor")
   143  	}
   144  	if sysInfo.Seccomp {
   145  		// FIXME: get profile name...
   146  		secOpts = append(secOpts, fmt.Sprintf("name=seccomp,profile=%s", "default"))
   147  	}
   148  	return secOpts
   149  }
   150  
   151  func getRuntimes(configInfo *config.Config) map[string]docker.Runtime {
   152  	var runtimes = map[string]docker.Runtime{}
   153  	for name, paths := range configInfo.Engine.OCIRuntimes {
   154  		runtimes[name] = docker.Runtime{
   155  			Path: paths[0],
   156  			Args: nil,
   157  		}
   158  	}
   159  	return runtimes
   160  }
   161  
   162  func getFdCount() (count int) {
   163  	count = -1
   164  	if entries, err := ioutil.ReadDir("/proc/self/fd"); err == nil {
   165  		count = len(entries)
   166  	}
   167  	return
   168  }
   169  
   170  // Just ignoring Container errors here...
   171  func getContainersState(r *libpod.Runtime) map[define.ContainerStatus]int {
   172  	var states = map[define.ContainerStatus]int{}
   173  	ctnrs, err := r.GetAllContainers()
   174  	if err == nil {
   175  		for _, ctnr := range ctnrs {
   176  			state, err := ctnr.State()
   177  			if err != nil {
   178  				continue
   179  			}
   180  			states[state] += 1
   181  		}
   182  	}
   183  	return states
   184  }
   185  
   186  func getEnv(value string) string {
   187  	if v, exists := os.LookupEnv(strings.ToUpper(value)); exists {
   188  		return v
   189  	}
   190  	if v, exists := os.LookupEnv(strings.ToLower(value)); exists {
   191  		return v
   192  	}
   193  	return ""
   194  }