From b71a7dceca0fbf03d4b0797604bd9e7480cb170b Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Mon, 3 Aug 2020 14:40:59 -0700 Subject: [PATCH] use cached hostinfo instead --- cmd/minikube/cmd/start.go | 45 ++++++++++++++++---------- cmd/minikube/cmd/start_flags.go | 3 +- pkg/minikube/machine/info.go | 56 +++++++++++++++++++++++++++++---- pkg/minikube/machine/start.go | 2 +- 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index ff17a4f225..62a54d3f05 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -37,7 +37,6 @@ import ( "github.com/pkg/errors" "github.com/shirou/gopsutil/cpu" gopshost "github.com/shirou/gopsutil/host" - "github.com/shirou/gopsutil/mem" "github.com/spf13/cobra" "github.com/spf13/viper" cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" @@ -764,13 +763,13 @@ func validateUser(drvName string) { } } -// memoryLimits returns the amount of memory allocated to the system and hypervisor +// memoryLimits returns the amount of memory allocated to the system and hypervisor , the return value is in MB func memoryLimits(drvName string) (int, int, error) { - v, err := mem.VirtualMemory() + info, err := machine.CachedHostInfo() if err != nil { return -1, -1, err } - sysLimit := int(v.Total / 1024 / 1024) + sysLimit := int(info.Memory) containerLimit := 0 if driver.IsKIC(drvName) { @@ -822,6 +821,29 @@ func suggestMemoryAllocation(sysLimit int, containerLimit int, nodes int) int { return suggested } +// validateMemoryHardLimit checks if the user system has enough memory at all ! +func validateMemoryHardLimit(drvName string) { + s, c, err := memoryLimits(drvName) + if err != nil { + glog.Warningf("Unable to query memory limits: %v", err) + out.T(out.Conflict, "Failed to verify system memory limits.") + } + if s < 2200 { + out.WarningT("Your system has only {{.memory_amount}}MB memory. This might not work minimum required is 2000MB.", out.V{"memory_amount": s}) + } + if driver.IsDockerDesktop(drvName) { + // in Docker Desktop if you allocate 2 GB the docker info shows: Total Memory: 1.945GiB which becomes 1991 when we calculate the MBs + // thats why it is not same number as other drivers which is 2 GB + if c < 1991 { + out.WarningT(`Increase Docker for Desktop memory to at least 2.5GB or more: + + Docker for Desktop > Settings > Resources > Memory + +`) + } + } +} + // validateMemorySize validates the memory size matches the minimum recommended func validateMemorySize(req int, drvName string) { sysLimit, containerLimit, err := memoryLimits(drvName) @@ -843,22 +865,12 @@ func validateMemorySize(req int, drvName string) { out.V{"requested": req, "recommended": minRecommendedMem}) } - if driver.IsDockerDesktop(drvName) { - // in Docker Desktop if you allocate 2 GB the docker info shows: Total Memory: 1.945GiB which becomes 1991 when we calculate the MBs - // thats why it is not same number as other drivers which is 2 GB - if containerLimit < 1991 { - out.WarningT(`Increase Docker for Desktop memory to at least 2.5GB or more: - - Docker for Desktop > Settings > Resources > Memory - -`) - } else if containerLimit < 2997 && sysLimit > 8000 { // for users with more than 8 GB advice 3 GB - out.WarningT(`Your system has {{.system_limit}}MB memory but Docker has only {{.container_limit}}MB. For a better performance increase to at least 3GB. + if driver.IsDockerDesktop(drvName) && containerLimit < 2997 && sysLimit > 8000 { // for users with more than 8 GB advice 3 GB + out.WarningT(`Your system has {{.system_limit}}MB memory but Docker has only {{.container_limit}}MB. For a better performance increase to at least 3GB. Docker for Desktop > Settings > Resources > Memory `, out.V{"container_limit": containerLimit, "system_limit": sysLimit}) - } } if req > sysLimit && !viper.GetBool(force) { @@ -945,6 +957,7 @@ func validateFlags(cmd *cobra.Command, drvName string) { } } validateCPUCount(drvName) + validateMemoryHardLimit(drvName) if cmd.Flags().Changed(memory) { if !driver.HasResourceLimits(drvName) { diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index 18c48f4e60..bb06d392c1 100644 --- a/cmd/minikube/cmd/start_flags.go +++ b/cmd/minikube/cmd/start_flags.go @@ -236,9 +236,8 @@ func generateClusterConfig(cmd *cobra.Command, existing *config.ClusterConfig, k exit.UsageT("{{.driver_name}} has only {{.container_limit}}MB memory but you specified {{.specified_memory}}MB", out.V{"container_limit": containerLimit, "specified_memory": mem, "driver_name": driver.FullName(drvName)}) } - validateMemorySize(mem, drvName) - } else { + validateMemorySize(mem, drvName) glog.Infof("Using suggested %dMB memory alloc based on sys=%dMB, container=%dMB", mem, sysLimit, containerLimit) } diff --git a/pkg/minikube/machine/info.go b/pkg/minikube/machine/info.go index ee505c2952..020e227c24 100644 --- a/pkg/minikube/machine/info.go +++ b/pkg/minikube/machine/info.go @@ -30,7 +30,7 @@ import ( "k8s.io/minikube/pkg/minikube/out/register" ) -type hostInfo struct { +type HostInfo struct { Memory int64 CPUs int DiskSize int64 @@ -40,24 +40,26 @@ func megs(bytes uint64) int64 { return int64(bytes / 1024 / 1024) } -func getHostInfo() (*hostInfo, error) { - i, err := cpu.Info() +// CachedHostInfo returns system information such as memory,CPU, DiskSize +func CachedHostInfo() (*HostInfo, error) { + i, err := cachedCPUInfo() if err != nil { glog.Warningf("Unable to get CPU info: %v", err) return nil, err } - v, err := mem.VirtualMemory() + v, err := cachedSysMemLimit() if err != nil { glog.Warningf("Unable to get mem info: %v", err) return nil, err } - d, err := disk.Usage("/") + + d, err := cachedDisInfo() if err != nil { glog.Warningf("Unable to get disk info: %v", err) return nil, err } - var info hostInfo + var info HostInfo info.CPUs = len(i) info.Memory = megs(v.Total) info.DiskSize = megs(d.Total) @@ -97,3 +99,45 @@ func logRemoteOsRelease(r command.Runner) { glog.Infof("Remote host: %s", osReleaseInfo.PrettyName) } + +var cachedSystemMemoryLimit *mem.VirtualMemoryStat +var cachedSystemMemoryErr *error + +// cachedSysMemLimit will return a chaced limit for the system's virtual memory. +func cachedSysMemLimit() (*mem.VirtualMemoryStat, error) { + if cachedSystemMemoryLimit == nil { + v, err := mem.VirtualMemory() + cachedSystemMemoryLimit = v + cachedSystemMemoryErr = &err + } + return cachedSystemMemoryLimit, *cachedSystemMemoryErr +} + +var cachedDiskInfo *disk.UsageStat +var cachedDiskInfoeErr *error + +// cachedSysMemLimit will return a cached disk usage info +func cachedDisInfo() (disk.UsageStat, error) { + if cachedDiskInfo == nil { + d, err := disk.Usage("/") + cachedDiskInfo = d + cachedDiskInfoeErr = &err + } + return *cachedDiskInfo, *cachedDiskInfoeErr +} + +var cachedCPU *[]cpu.InfoStat +var cachedCPUErr *error + +// cachedCPUInfo will return a cached cpu info +func cachedCPUInfo() ([]cpu.InfoStat, error) { + if cachedCPU == nil { + i, err := cpu.Info() + cachedCPU = &i + cachedCPUErr = &err + if err != nil { + return nil, *cachedCPUErr + } + } + return *cachedCPU, *cachedCPUErr +} diff --git a/pkg/minikube/machine/start.go b/pkg/minikube/machine/start.go index 291f34662f..a52e2481f3 100644 --- a/pkg/minikube/machine/start.go +++ b/pkg/minikube/machine/start.go @@ -251,7 +251,7 @@ func acquireMachinesLock(name string) (mutex.Releaser, error) { func showHostInfo(cfg config.ClusterConfig) { machineType := driver.MachineType(cfg.Driver) if driver.BareMetal(cfg.Driver) { - info, err := getHostInfo() + info, err := CachedHostInfo() if err == nil { register.Reg.SetStep(register.RunningLocalhost) out.T(out.StartingNone, "Running on localhost (CPUs={{.number_of_cpus}}, Memory={{.memory_size}}MB, Disk={{.disk_size}}MB) ...", out.V{"number_of_cpus": info.CPUs, "memory_size": info.Memory, "disk_size": info.DiskSize})