github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/util/system/version_linux.go (about)

     1  // +build linux
     2  
     3  package system
     4  
     5  import (
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os/exec"
     9  	"strings"
    10  
    11  	"github.com/olli-ai/jx/v2/pkg/util"
    12  )
    13  
    14  // ReleaseFileGetter defines the interface for read system file
    15  type ReleaseFileGetter interface {
    16  	GetFileContents(string) (string, error)
    17  }
    18  
    19  // DefaultReleaseFileGetter is the default implementation of ReleaseFileGetter
    20  type DefaultReleaseFileGetter struct{}
    21  
    22  // GetFileContents returns the file contents
    23  func (r *DefaultReleaseFileGetter) GetFileContents(file string) (string, error) {
    24  	buf, err := ioutil.ReadFile(file)
    25  	if err != nil {
    26  		return "", err
    27  	}
    28  	return strings.Trim(string(buf), "\n"), nil
    29  }
    30  
    31  // SetReleaseGetter sets the current releaseFileGetter
    32  func SetReleaseGetter(r ReleaseFileGetter) {
    33  	releaseGetter = r
    34  }
    35  
    36  var releaseGetter ReleaseFileGetter = &DefaultReleaseFileGetter{}
    37  
    38  // GetOsVersion returns a human friendly string of the current OS
    39  // in the case of an error this still returns a valid string for the details that can be found.
    40  func GetOsVersion() (string, error) {
    41  	output, err := releaseGetter.GetFileContents("/etc/os-release")
    42  	if err == nil {
    43  		release, err := util.ExtractKeyValuePairs(strings.Split(strings.TrimSpace(output), "\n"), "=")
    44  		if err == nil && len(release["PRETTY_NAME"]) != 0 {
    45  			return strings.ReplaceAll(release["PRETTY_NAME"], "\"", ""), nil
    46  		}
    47  	}
    48  	// fallback
    49  	output, err = runCommand("lsb_release", "-d", "-s")
    50  	if err == nil {
    51  		return output, nil
    52  	}
    53  	// procfs will tell us the kernel version
    54  	output, err = releaseGetter.GetFileContents("/proc/version")
    55  	if err == nil {
    56  		return fmt.Sprintf("Unknown Linux distribution %s", output), nil
    57  	}
    58  	return "Unknown Linux version", fmt.Errorf("Unknown Linux version")
    59  }
    60  
    61  func runCommand(command string, args ...string) (string, error) {
    62  	e := exec.Command(command, args...)
    63  	data, err := e.CombinedOutput()
    64  	text := string(data)
    65  	text = strings.TrimSpace(text)
    66  	if err != nil {
    67  		return "", fmt.Errorf("command failed '%s %s': %s %s\n", command, strings.Join(args, " "), text, err)
    68  	}
    69  	return text, err
    70  }