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 }