package os import ( "fmt" "log" "os" "os/exec" "strings" ) type OS struct { ID string Name string Version string PackageManager string } func GetLinuxDistribution() (*OS, error) { _, err := os.Stat("/etc/os-release") if os.IsNotExist(err) { return nil, fmt.Errorf("unable to read system information") } osRelease, _ := os.ReadFile("/etc/os-release") return parseOsRelease(string(osRelease)), nil } func parseOsRelease(osRelease string) *OS { var result OS result.ID = "Unknown" result.Name = "Unknown" result.Version = "Unknown" lines := strings.Split(osRelease, "\n") for _, line := range lines { splitLine := strings.SplitN(line, "=", 2) if len(splitLine) != 2 { continue } switch splitLine[0] { case "ID": result.ID = strings.ToLower(strings.Trim(splitLine[1], "\"")) case "NAME": result.Name = strings.Trim(splitLine[1], "\"") case "VERSION_ID": result.Version = strings.Trim(splitLine[1], "\"") } } err := result.getPackageManager() if err != nil { log.Fatal(err) } return &result } func (os *OS) getPackageManager() error { switch os.ID { case "debian", "ubuntu", "linuxmint": os.PackageManager = "apt" return nil case "arch": os.PackageManager = "pacman" return nil case "fedora": os.PackageManager = "dnf" return nil default: pmcommands := []string{ "apt", "dnf", "pacman", } for _, pmname := range pmcommands { _, err := exec.LookPath(pmname) if err == nil { os.PackageManager = pmname return nil } } return fmt.Errorf("no packagemanager found for os: %s", os.Name) } }