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