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] = ®istry.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 ®istry.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 }