//go:build linux package utils import ( "git.jmbit.de/jmb/patchman/common" "log" "os" "os/exec" "runtime" "strings" ) var OSInfoCache common.OSInfo // GetOSInfo() parses /etc/os-release and uname for OS information func GetOSInfo() common.OSInfo { if OSInfoCache.OS != "" { return OSInfoCache } var distribution string var version string var distributionLike []string var kernelRelease string var packageManager string data, err := os.ReadFile("/etc/os-release") if err != nil { log.Fatalf("Could not read /etc/os-release: %w", err) } lines := strings.Split(string(data), "\n") for _, line := range lines { if strings.HasPrefix(line, "ID=") { // Extract distribution ID distribution = strings.Trim(strings.SplitN(line, "=", 2)[1], "\"") } if strings.HasPrefix(line, "ID_LIKE=") { // Extract ID_Like distributionLike = strings.Split(strings.Trim(strings.SplitN(line, "=", 2)[1], "\""), " ") } if strings.HasPrefix(line, "VERSION_ID=") { // Extract Version string version = strings.Trim(strings.SplitN(line, "=", 2)[1], "\"") } } unameRelease := exec.Command("/usr/bin/uname", "-r") unameReleaseOutput, err := unameRelease.Output() if err != nil { log.Printf("Could not determine Kernel release: %w", err) } else { kernelRelease = strings.TrimRight(string(unameReleaseOutput), "\n") } //determine package manager packageManager = getPackageManager(distribution, distributionLike) return common.OSInfo{ OS: runtime.GOOS, Distribution: distribution, DistributionLike: distributionLike, Version: version, KernelRelease: kernelRelease, Architecture: runtime.GOARCH, PackageManager: packageManager, } } // getPackageManager determines the Package Manager used by the system. // TODO support multiple Package Managers at once. func getPackageManager(distribution string, distributionLike []string) string { distroLike := append(distributionLike, distribution) if IsStringInSlice("debian", distroLike) { return "apt" } if IsStringInSlice("suse", distroLike) { return "zypper" } if IsStringInSlice("fedora", distroLike) { return "dnf" } else { return "" } }