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