agent/util/osutil/platform_unix.go (199 lines of code) (raw):
//go:build darwin || freebsd || linux || netbsd || openbsd
// +build darwin freebsd linux netbsd openbsd
package osutil
import (
"runtime"
"strings"
ini "gopkg.in/ini.v1"
"github.com/aliyun/aliyun_assist_client/agent/log"
"github.com/aliyun/aliyun_assist_client/common/executil"
)
const (
osReleaseFile = "/etc/os-release"
systemReleaseFile = "/etc/system-release"
centosReleaseFile = "/etc/centos-release"
redhatReleaseFile = "/etc/redhat-release"
unameCommand = "/usr/bin/uname"
lsbReleaseCommand = "lsb_release"
fetchingDetailsMessage = "fetching platform details from %v"
errorOccurredMessage = "There was an error running %v, err: %v"
)
var osArch string
type osRelease struct {
NAME string
VERSION_ID string
}
func getPlatformName() (value string, err error) {
value, _, err = getPlatformDetails()
return
}
func getPlatformType() (value string, err error) {
return "linux", nil
}
func getPlatformVersion() (value string, err error) {
_, value, err = getPlatformDetails()
return
}
func getPlatformDetails() (name string, version string, err error) {
contents := ""
var contentsBytes []byte
name = notAvailableMessage
version = notAvailableMessage
if Exists(centosReleaseFile) {
// CentOS has incomplete information in the osReleaseFile
// and there fore needs to be before osReleaseFile exist check
log.GetLogger().Debugf(fetchingDetailsMessage, centosReleaseFile)
contents, err = ReadFile(centosReleaseFile)
log.GetLogger().Debugf(commandOutputMessage, contents)
if err != nil {
log.GetLogger().Debugf(errorOccurredMessage, centosReleaseFile, err)
return
}
if strings.Contains(contents, "CentOS") || strings.Contains(contents, "Aliyun") || strings.Contains(contents, "Alibaba") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
versionData := strings.Split(data[1], "(")
version = strings.TrimSpace(versionData[0])
}
}
} else if Exists(osReleaseFile) {
log.GetLogger().Debugf(fetchingDetailsMessage, osReleaseFile)
contents := new(osRelease)
err = ini.MapTo(contents, osReleaseFile)
log.GetLogger().Debugf(commandOutputMessage, contents)
if err != nil {
log.GetLogger().Debugf(errorOccurredMessage, osReleaseFile, err)
return
}
name = contents.NAME
version = contents.VERSION_ID
} else if Exists(systemReleaseFile) {
// We want to fall back to legacy behaviour in case some older versions of
// linux distributions do not have the or-release file
log.GetLogger().Debugf(fetchingDetailsMessage, systemReleaseFile)
contents, err = ReadFile(systemReleaseFile)
log.GetLogger().Debugf(commandOutputMessage, contents)
if err != nil {
log.GetLogger().Debugf(errorOccurredMessage, systemReleaseFile, err)
return
}
if strings.Contains(contents, "Aliyun") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "Alibaba") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "Red Hat") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "CentOS") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "SLES") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "Raspbian") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if strings.Contains(contents, "Oracle") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
}
} else if Exists(redhatReleaseFile) {
log.GetLogger().Debugf(fetchingDetailsMessage, redhatReleaseFile)
contents, err = ReadFile(redhatReleaseFile)
log.GetLogger().Debugf(commandOutputMessage, contents)
if err != nil {
log.GetLogger().Debugf(errorOccurredMessage, redhatReleaseFile, err)
return
}
if strings.Contains(contents, "Red Hat") {
data := strings.Split(contents, "release")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
versionData := strings.Split(data[1], "(")
version = strings.TrimSpace(versionData[0])
}
}
} else if runtime.GOOS == "freebsd" {
log.GetLogger().Debugf(fetchingDetailsMessage, unameCommand)
if contentsBytes, err = executil.Command(unameCommand, "-sr").Output(); err != nil {
log.GetLogger().Debugf(errorOccurredMessage, unameCommand, err)
return
}
log.GetLogger().Debugf(commandOutputMessage, contentsBytes)
data := strings.Split(string(contentsBytes), " ")
name = strings.TrimSpace(data[0])
if len(data) >= 2 {
version = strings.TrimSpace(data[1])
}
} else if runtime.GOOS == "darwin" {
version = "1.0.0"
name = "MacOS"
} else {
log.GetLogger().Debugf(fetchingDetailsMessage, lsbReleaseCommand)
// platform name
if contentsBytes, err = executil.Command(lsbReleaseCommand, "-i").Output(); err != nil {
log.GetLogger().Debugf(errorOccurredMessage, lsbReleaseCommand, err)
return
}
name = strings.TrimSpace(string(contentsBytes))
log.GetLogger().Debugf(commandOutputMessage, name)
name = strings.TrimSpace(string(contentsBytes))
name = strings.TrimLeft(name, "Distributor ID:")
name = strings.TrimSpace(name)
log.GetLogger().Debugf("platform name %v", name)
// platform version
if contentsBytes, err = executil.Command(lsbReleaseCommand, "-r").Output(); err != nil {
log.GetLogger().Debugf(errorOccurredMessage, lsbReleaseCommand, err)
return
}
version = strings.TrimSpace(string(contentsBytes))
log.GetLogger().Debugf(commandOutputMessage, version)
version = strings.TrimLeft(version, "Release:")
version = strings.TrimSpace(version)
log.GetLogger().Debugf("platform version %v", version)
}
return
}
func getArch() (formatArch string) {
if osArch != "" {
return osArch
}
defer func() {
osArch = formatArch
}()
formatArch = ARCH_UNKNOWN
arch, err := GetUnameMachine()
if err != nil {
log.GetLogger().Errorln("Get Arch: GetUnameMachine err: ", err.Error())
return ARCH_UNKNOWN
}
arch = strings.TrimSpace(arch)
arch = strings.ToLower(arch)
if strings.Contains(arch, "aarch") || strings.Contains(arch, "arm") { // arm: aarch arm
formatArch = ARCH_ARM
} else if strings.Contains(arch, "386") || strings.Contains(arch, "686") { // x86: i386 i686
formatArch = ARCH_32
} else if arch == "x86_64" || arch == "amd64" { // x64: x86_64
formatArch = ARCH_64
} else {
log.GetLogger().Errorln("Get Arch: unknown arch: ", arch)
formatArch = ARCH_UNKNOWN
}
return
}